You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by jm...@apache.org on 2004/02/01 05:37:30 UTC
svn commit: rev 6398 - in incubator/spamassassin/trunk: lib/Mail/SpamAssassin t
Author: jm
Date: Sat Jan 31 20:37:29 2004
New Revision: 6398
Modified:
incubator/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStore.pm
incubator/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStoreDBM.pm
incubator/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStoreSQL.pm
incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm
incubator/spamassassin/trunk/lib/Mail/SpamAssassin/SQLBasedAddrList.pm
incubator/spamassassin/trunk/t/ (props changed)
Log:
Michael Parker: Fixing up the license in several files, also moves over to the new key/value
Conf stuff and makes it so BayesStoreSQL no longer returns undef in new.
Modified: incubator/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStore.pm
==============================================================================
--- incubator/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStore.pm (original)
+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStore.pm Sat Jan 31 20:37:29 2004
@@ -154,7 +154,7 @@
=head2 calculate_expire_delta
-public instance (\%) calculate_expire_delta (Integer $newest_atime,
+public instance (%) calculate_expire_delta (Integer $newest_atime,
Integer $start,
Integer $max_expire_mult)
@@ -227,6 +227,7 @@
This methods does the actual token expiration.
XXX More docs here about the methodology and what not
+
=cut
sub expire_old_tokens_trapped {
Modified: incubator/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStoreDBM.pm
==============================================================================
--- incubator/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStoreDBM.pm (original)
+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStoreDBM.pm Sat Jan 31 20:37:29 2004
@@ -1,60 +1,17 @@
# <@LICENSE>
-# ====================================================================
-# The Apache Software License, Version 1.1
+# Copyright 2004 Apache Software Foundation
#
-# Copyright (c) 2000 The Apache Software Foundation. All rights
-# reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-#
-# 3. The end-user documentation included with the redistribution,
-# if any, must include the following acknowledgment:
-# "This product includes software developed by the
-# Apache Software Foundation (http://www.apache.org/)."
-# Alternately, this acknowledgment may appear in the software itself,
-# if and wherever such third-party acknowledgments normally appear.
-#
-# 4. The names "Apache" and "Apache Software Foundation" must
-# not be used to endorse or promote products derived from this
-# software without prior written permission. For written
-# permission, please contact apache@apache.org.
-#
-# 5. Products derived from this software may not be called "Apache",
-# nor may "Apache" appear in their name, without prior written
-# permission of the Apache Software Foundation.
-#
-# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
-# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
-# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-# ====================================================================
-#
-# This software consists of voluntary contributions made by many
-# individuals on behalf of the Apache Software Foundation. For more
-# information on the Apache Software Foundation, please see
-# <http://www.apache.org/>.
-#
-# Portions of this software are based upon public domain software
-# originally written at the National Center for Supercomputing Applications,
-# University of Illinois, Urbana-Champaign.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
# </...@LICENSE>
package Mail::SpamAssassin::BayesStoreDBM;
Modified: incubator/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStoreSQL.pm
==============================================================================
--- incubator/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStoreSQL.pm (original)
+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStoreSQL.pm Sat Jan 31 20:37:29 2004
@@ -1,60 +1,17 @@
# <@LICENSE>
-# ====================================================================
-# The Apache Software License, Version 1.1
+# Copyright 2004 Apache Software Foundation
#
-# Copyright (c) 2000 The Apache Software Foundation. All rights
-# reserved.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-#
-# 3. The end-user documentation included with the redistribution,
-# if any, must include the following acknowledgment:
-# "This product includes software developed by the
-# Apache Software Foundation (http://www.apache.org/)."
-# Alternately, this acknowledgment may appear in the software itself,
-# if and wherever such third-party acknowledgments normally appear.
-#
-# 4. The names "Apache" and "Apache Software Foundation" must
-# not be used to endorse or promote products derived from this
-# software without prior written permission. For written
-# permission, please contact apache@apache.org.
-#
-# 5. Products derived from this software may not be called "Apache",
-# nor may "Apache" appear in their name, without prior written
-# permission of the Apache Software Foundation.
-#
-# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
-# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
-# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-# ====================================================================
-#
-# This software consists of voluntary contributions made by many
-# individuals on behalf of the Apache Software Foundation. For more
-# information on the Apache Software Foundation, please see
-# <http://www.apache.org/>.
-#
-# Portions of this software are based upon public domain software
-# originally written at the National Center for Supercomputing Applications,
-# University of Illinois, Urbana-Champaign.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
# </...@LICENSE>
=head1 NAME
@@ -74,8 +31,6 @@
use strict;
use bytes;
-use DBI;
-
use Mail::SpamAssassin::BayesStore;
use vars qw( @ISA );
@@ -115,21 +70,26 @@
my $dbuser = $self->{bayes}->{conf}->{bayes_sql_username};
my $dbpass = $self->{bayes}->{conf}->{bayes_sql_password};
- my $dbh = DBI->connect($dsn, $dbuser, $dbpass, {'PrintError' => 1});
+ my $dbh;
+ if (!eval {
+ require DBI;
+ # TODO: not sure about "PrintError" here
+ $dbh = DBI->connect($dsn, $dbuser, $dbpass, {'PrintError' => 1});
- if (!$dbh) {
- dbg("bayes: Unable to connect to database: ".DBI->errstr());
+ if (!$dbh) {
+ dbg("bayes: Unable to connect to database: ".DBI->errstr());
+ }
+ else {
+ dbg("bayes: Database connection established");
+ }
+ 1;
- ## TODO! This is not appropriate -- $bayes->{store} must alwasy
- ## be a valid object. returning undef from a constructor is bad
- ## news.
- return undef;
+ }) {
+ dbg("bayes: Unable to connect to database: DBI module not available: $!");
}
$self->{_dbh} = $dbh;
- dbg("bayes: Database connection established");
-
if ($self->{bayes}->{conf}->{bayes_sql_override_username}) {
$self->{_username} = $self->{bayes}->{conf}->{bayes_sql_override_username};
}
@@ -178,6 +138,9 @@
sub tie_db_writable {
my ($self) = @_;
+
+ return 0 unless (defined($self->{_dbh}));
+
my $main = $self->{bayes}->{main};
$self->read_db_configs();
@@ -219,7 +182,7 @@
=head2 calculate_expire_delta
-public instance (\%) calculate_expire_delta (Integer $newest_atime,
+public instance (%) calculate_expire_delta (Integer $newest_atime,
Integer $start,
Integer $max_expire_mult)
@@ -233,6 +196,8 @@
my ($self, $newest_atime, $start, $max_expire_mult) = @_;
my %delta = (); # use a hash since an array is going to be very sparse
+
+ return %delta unless (defined($self->{_dbh}));
my $sql = "SELECT count(*)
FROM bayes_token
@@ -339,6 +304,8 @@
sub seen_get {
my ($self, $msgid) = @_;
+
+ return undef unless (defined($self->{_dbh}));
my $sql = "SELECT flag FROM bayes_seen WHERE username = ? AND msgid = ?";
@@ -379,6 +346,8 @@
return 0 if (!$msgid);
return 0 if (!$flag);
+ return 0 unless (defined($self->{_dbh}));
+
my $sql = "INSERT INTO bayes_seen (username, msgid, flag) VALUES (?,?,?)";
my $sth = $self->{_dbh}->prepare_cached($sql);
@@ -415,6 +384,8 @@
return 0 if (!$msgid);
+ return 0 unless (defined($self->{_dbh}));
+
my $sql = "DELETE FROM bayes_seen WHERE username = ? AND msgid = ?";
my $sth = $self->{_dbh}->prepare_cached($sql);
@@ -474,6 +445,8 @@
my ($self) = @_;
my @values;
+ return (0,0,0,0,0,0,0,0,0,0,0) unless (defined($self->{_dbh}));
+
my $sql = "SELECT spam_count, ham_count, last_expire,
last_atime_delta, last_expire_reduce
FROM bayes_vars
@@ -537,6 +510,8 @@
sub dump_db_toks {
my ($self, $template, $regex, @vars) = @_;
+ return unless (defined($self->{_dbh}));
+
# 0/0 tokens don't count
# since ordering is check here, order the tokens
my $sql = "SELECT token, spam_count, ham_count, atime
@@ -587,6 +562,8 @@
return 0 unless (defined($time));
+ return 0 unless (defined($self->{_dbh}));
+
my $sql = "UPDATE bayes_vars SET last_expire = ? WHERE username = ?";
my $sth = $self->{_dbh}->prepare_cached($sql);
@@ -624,6 +601,8 @@
sub get_running_expire_tok {
my ($self) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
my $sql = "SELECT max(runtime) from bayes_expire WHERE username = ?";
my $sth = $self->{_dbh}->prepare_cached($sql);
@@ -659,6 +638,8 @@
sub set_running_expire_tok {
my ($self) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
my $sql = "INSERT INTO bayes_expire (username,runtime) VALUES (?,?)";
my $sth = $self->{_dbh}->prepare_cached($sql);
@@ -688,14 +669,9 @@
sub remove_running_expire_tok {
my ($self) = @_;
- my $sql = "DELETE from bayes_expire WHERE username = ?";
+ return 0 unless (defined($self->{_dbh}));
- my $sth = $self->{_dbh}->prepare_cached($sql);
-
- unless (defined($sth)) {
- dbg("bayes: remove_running_expire_tok: SQL Error: ".$self->{_dbh}->errstr());
- return 0;
- }
+ my $sql = "DELETE from bayes_expire WHERE username = ?";
my $rows = $self->{_dbh}->do($sql, undef, $self->{_username});
@@ -719,6 +695,8 @@
sub tok_get {
my ($self, $token) = @_;
+ return (0,0,0) unless (defined($self->{_dbh}));
+
my $sql = "SELECT spam_count, ham_count, atime
FROM bayes_token
WHERE username = ?
@@ -783,6 +761,8 @@
sub nspam_nham_get {
my ($self) = @_;
+ return (0,0) unless (defined($self->{_dbh}));
+
my $sql = "SELECT ham_count, spam_count FROM bayes_vars WHERE username = ?";
my $sth = $self->{_dbh}->prepare_cached($sql);
@@ -819,6 +799,8 @@
sub nspam_nham_change {
my ($self, $num_spam, $num_ham) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
my $sql = "UPDATE bayes_vars
SET spam_count = spam_count + ?,
ham_count = ham_count + ?
@@ -858,6 +840,8 @@
sub tok_touch {
my ($self, $token, $atime) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
# shortcut, will only update atime for the token if the atime is less than
# what we are updating to
my $sql = "UPDATE bayes_token
@@ -984,6 +968,8 @@
sub _get_db_version {
my ($self) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
my $sql = "SELECT value FROM bayes_global_vars WHERE variable = 'VERSION'";
my $sth = $self->{_dbh}->prepare_cached($sql);
@@ -1020,6 +1006,8 @@
sub _initialize_db {
my ($self) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
return 0 if (!$self->{_username});
my $sql = "SELECT count(*) FROM bayes_vars WHERE username = ?";
@@ -1082,6 +1070,8 @@
sub _token_atime {
my ($self, $token) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
return undef unless (defined($token));
my $sql = "SELECT atime
@@ -1122,6 +1112,8 @@
sub _delete_token {
my ($self, $token) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
return 0 unless (defined($token));
my $sql = "DELETE FROM bayes_token WHERE username = ? AND token = ?";
@@ -1161,6 +1153,8 @@
sub _put_token {
my ($self, $token, $spam_count, $ham_count, $atime) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
$spam_count ||= 0;
$ham_count ||= 0;
@@ -1252,6 +1246,8 @@
sub _get_token_count {
my ($self) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
my $sql = "SELECT count(*)
FROM bayes_token
WHERE username = ?
@@ -1290,6 +1286,8 @@
sub _get_oldest_token_age {
my ($self) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
my $sql = "SELECT min(atime) FROM bayes_token WHERE username = ?";
my $sth = $self->{_dbh}->prepare_cached($sql);
@@ -1325,6 +1323,8 @@
sub _get_newest_token_age {
my ($self) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
my $sql = "SELECT max(atime) FROM bayes_token WHERE username = ?";
my $sth = $self->{_dbh}->prepare_cached($sql);
@@ -1360,6 +1360,8 @@
sub _set_last_atime_delta {
my ($self, $newdelta) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
return 0 unless (defined($newdelta));
my $sql = "UPDATE bayes_vars SET last_atime_delta = ? WHERE username = ?";
@@ -1395,6 +1397,8 @@
sub _set_last_expire_reduce {
my ($self, $deleted) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
return 0 unless (defined($deleted));
my $sql = "UPDATE bayes_vars SET last_expire_reduce = ? WHERE username = ?";
@@ -1431,6 +1435,8 @@
sub _get_num_hapaxes {
my ($self) = @_;
+ return 0 unless (defined($self->{_dbh}));
+
my $sql = "SELECT count(*)
FROM bayes_token
WHERE username = ?
@@ -1470,6 +1476,8 @@
sub _get_num_lowfreq {
my ($self) = @_;
+
+ return 0 unless (defined($self->{_dbh}));
my $sql = "SELECT count(*)
FROM bayes_token
Modified: incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm
==============================================================================
--- incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm (original)
+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm Sat Jan 31 20:37:29 2004
@@ -2425,8 +2425,8 @@
=cut
- if (/^bayes_store_module\s+(.*)$/) {
- my $module = $1;
+ if ( $key eq 'bayes_store_module' ) {
+ my $module = $value;
$module =~ /^([_A-Za-z0-9:]+)$/;
$self->{bayes_store_module} = $1;
next;
@@ -2440,8 +2440,8 @@
=cut
- if (/^bayes_sql_dsn\s+(\S+)$/) {
- $self->{bayes_sql_dsn} = $1; next;
+ if ( $key eq 'bayes_sql_dsn' ) {
+ $self->{bayes_sql_dsn} = $value; next;
}
=item bayes_sql_username
@@ -2452,8 +2452,8 @@
=cut
- if (/^bayes_sql_username\s+(\S+)$/) {
- $self->{bayes_sql_username} = $1; next;
+ if ( $key eq 'bayes_sql_username' ) {
+ $self->{bayes_sql_username} = $value; next;
}
=item bayes_sql_password
@@ -2464,8 +2464,8 @@
=cut
- if (/^bayes_sql_password\s+(\S+)$/) {
- $self->{bayes_sql_password} = $1; next;
+ if ( $key eq 'bayes_sql_password' ) {
+ $self->{bayes_sql_password} = $value; next;
}
=item user_scores_dsn DBI:databasetype:databasename:hostname:port
@@ -2504,29 +2504,14 @@
# user_scores_sql_table here. All just take \S+ and set the string of the
# same name on $self.
-=item loadplugin PluginModuleName /path/to/module.pm
-
-Load a SpamAssassin plugin module. The C<PluginModuleName> is the perl module
-name, used to create the plugin object itself; C</path/to/module.pm> is the
-file to load, containing the module's perl code.
-
-See C<Mail::SpamAssassin::Plugin> for more details on writing plugins.
-
-=cut
-
- # leave as RE right now
- if (/^loadplugin\s+(\S+)\s+(\S+)$/) {
- $self->load_plugin ($1, $2); next;
- }
-
=item user_awl_dsn DBI:databasetype:databasename:hostname:port
If you load user auto-whitelists from an SQL database, this will set the DSN
used to connect. Example: C<DBI:mysql:spamassassin:localhost>
=cut
- if (/^user_awl_dsn\s+(\S+)$/) {
- $self->{user_awl_dsn} = $1; next;
+ if ( $key eq 'user_awl_dsn' ) {
+ $self->{user_awl_dsn} = $value; next;
}
=item user_awl_sql_username username
@@ -2534,8 +2519,8 @@
The authorized username to connect to the above DSN.
=cut
- if(/^user_awl_sql_username\s+(\S+)$/) {
- $self->{user_awl_sql_username} = $1; next;
+ if ( $key eq 'user_awl_sql_username' ) {
+ $self->{user_awl_sql_username} = $value; next;
}
=item user_awl_sql_password password
@@ -2543,8 +2528,8 @@
The password for the database username, for the above DSN.
=cut
- if(/^user_awl_sql_password\s+(\S+)$/) {
- $self->{user_awl_sql_password} = $1; next;
+ if ( $key eq 'user_awl_sql_password' ) {
+ $self->{user_awl_sql_password} = $value; next;
}
=item user_awl_sql_table tablename
@@ -2552,8 +2537,23 @@
The table user auto-whitelists are stored in, for the above DSN.
=cut
- if(/^user_awl_sql_table\s+(\S+)$/) {
- $self->{user_awl_sql_table} = $1; next;
+ if ( $key eq 'user_awl_sql_table' ) {
+ $self->{user_awl_sql_table} = $value; next;
+ }
+
+=item loadplugin PluginModuleName /path/to/module.pm
+
+Load a SpamAssassin plugin module. The C<PluginModuleName> is the perl module
+name, used to create the plugin object itself; C</path/to/module.pm> is the
+file to load, containing the module's perl code.
+
+See C<Mail::SpamAssassin::Plugin> for more details on writing plugins.
+
+=cut
+
+ # leave as RE right now
+ if (/^loadplugin\s+(\S+)\s+(\S+)$/) {
+ $self->load_plugin ($1, $2); next;
}
###########################################################################
Modified: incubator/spamassassin/trunk/lib/Mail/SpamAssassin/SQLBasedAddrList.pm
==============================================================================
--- incubator/spamassassin/trunk/lib/Mail/SpamAssassin/SQLBasedAddrList.pm (original)
+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin/SQLBasedAddrList.pm Sat Jan 31 20:37:29 2004
@@ -1,60 +1,17 @@
# <@LICENSE>
-# ====================================================================
-# The Apache Software License, Version 1.1
+# Copyright 2004 Apache Software Foundation
#
-# Copyright (c) 2000 The Apache Software Foundation. All rights
-# reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-#
-# 3. The end-user documentation included with the redistribution,
-# if any, must include the following acknowledgment:
-# "This product includes software developed by the
-# Apache Software Foundation (http://www.apache.org/)."
-# Alternately, this acknowledgment may appear in the software itself,
-# if and wherever such third-party acknowledgments normally appear.
-#
-# 4. The names "Apache" and "Apache Software Foundation" must
-# not be used to endorse or promote products derived from this
-# software without prior written permission. For written
-# permission, please contact apache@apache.org.
-#
-# 5. Products derived from this software may not be called "Apache",
-# nor may "Apache" appear in their name, without prior written
-# permission of the Apache Software Foundation.
-#
-# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
-# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
-# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-# ====================================================================
-#
-# This software consists of voluntary contributions made by many
-# individuals on behalf of the Apache Software Foundation. For more
-# information on the Apache Software Foundation, please see
-# <http://www.apache.org/>.
-#
-# Portions of this software are based upon public domain software
-# originally written at the National Center for Supercomputing Applications,
-# University of Illinois, Urbana-Champaign.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
# </...@LICENSE>
=head1 NAME