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 2006/11/15 21:40:37 UTC

svn commit: r475409 [2/2] - in /spamassassin/branches/jm_re2c_hacks: ./ build/ build/buildbot/ build/mkupdates/ debian/ lib/Mail/ lib/Mail/SpamAssassin/ lib/Mail/SpamAssassin/Conf/ lib/Mail/SpamAssassin/Locker/ lib/Mail/SpamAssassin/Message/ lib/Mail/S...

Copied: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Check.pm (from r475396, spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Check.pm)
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Check.pm?view=diff&rev=475409&p1=spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Check.pm&r1=475396&p2=spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Check.pm&r2=475409
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Check.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Check.pm Wed Nov 15 12:40:35 2006
@@ -146,7 +146,6 @@
 sub run_rbl_eval_tests {
   my ($self, $pms) = @_;
   my ($rulename, $pat, @args);
-  local ($_);
 
   # XXX - possible speed up, moving this check out of the subroutine into Check->new()
   if ($self->{main}->{local_tests_only}) {
@@ -177,7 +176,6 @@
 
 sub do_meta_tests {
   my ($self, $pms, $priority) = @_;
-  local ($_);
   
   # XXX - why not just make the plugin call?
   return if $self->shortcircuited_p($pms);
@@ -392,7 +390,7 @@
   my $tflags = $conf->{tflags};
   my $use_rule_subs = $self->{main}->{use_rule_subs};
 
-  my $evalstr = $self->start_rules_plugin_code("header");
+  my $evalstr = $self->start_rules_plugin_code("header", $priority);
   my $evalstr2 = '';
 
   # hash to hold the rules, "header\tdefault value" => rulename
@@ -429,7 +427,7 @@
 	    while ($text '.$testtype.'~ '.$pat.'g) {
             $self->got_hit(q#'.$rulename.'#, "", ruletype => "header");
             '. $self->hit_rule_plugin_code($pms, $rulename, "header", "last") . '
-			 }
+            }
         }
       ';
       push (@TEMPORARY_METHODS, $rulename.'_head_test');
@@ -525,15 +523,15 @@
 
 sub do_body_tests {
   my ($self, $pms, $priority, $textary) = @_;
-  local ($_);
 
   # XXX - why not just make the plugin call directly?
   return if $self->shortcircuited_p($pms);
 
   dbg("rules: running body-text per-line regexp tests; score so far=".$pms->{score});
 
+  my $conf = $self->{conf};
   my $doing_user_rules = 
-    $pms->{conf}->{user_rules_to_compile}->{$Mail::SpamAssassin::Conf::TYPE_BODY_TESTS};
+    $conf->{user_rules_to_compile}->{$Mail::SpamAssassin::Conf::TYPE_BODY_TESTS};
 
   # clean up priority value so it can be used in a subroutine name
   my $clean_priority;
@@ -557,13 +555,29 @@
   my $use_rule_subs = $self->{main}->{use_rule_subs};
 
   # build up the eval string...
-  my $evalstr = $self->start_rules_plugin_code("body");
+  my $evalstr = $self->start_rules_plugin_code("body", $priority);
   my $evalstr2 = '';
   my $loopid = 0;
 
-  while (my($rulename, $pat) = each %{$pms->{conf}{body_tests}->{$priority}}) {
+  $evalstr .= '
+
+        $self->{main}->call_plugins("run_body_hack", {
+                permsgstatus => $self, ruletype => "body",
+                priority => '.$priority.', lines => \@_
+              });
+
+  ';
+
+  while (my($rulename, $pat) = each %{$conf->{body_tests}->{$priority}}) {
     my $sub;
-    if (($pms->{conf}->{tflags}->{$rulename}||'') =~ /\bmultiple\b/)
+    my $sub_one_line;
+
+    my $need_one_line;
+    if ($conf->{generate_body_one_line_sub}->{$rulename}) {
+      $need_one_line = 1;
+    }
+
+    if (($conf->{tflags}->{$rulename}||'') =~ /\bmultiple\b/)
     {
       # support multiple matches
       $loopid++;
@@ -578,6 +592,19 @@
         }
       }
       ';
+
+      if ($need_one_line) {
+        $sub_one_line = '
+        pos $_[1] = 0;
+        '.$self->hash_line_for_rule($rulename).'
+        while ($_[1] =~ '.$pat.'g) {
+          my $self = $_[0];
+          $self->got_hit(q{'.$rulename.'}, "BODY: ", ruletype => "body");
+          '. $self->hit_rule_plugin_code($rulename, "body", "return 1") . '
+        }
+        ';
+      }
+
     }
     else {
       # omitting the "pos" call, "body_loopid" label, use of while()
@@ -591,6 +618,18 @@
         }
       }
       ';
+
+      if ($need_one_line) {
+        $sub_one_line = '
+        '.$self->hash_line_for_rule($rulename).'
+        if ($_[1] =~ '.$pat.') {
+          my $self = $_[0];
+          $self->got_hit(q{'.$rulename.'}, "BODY: ", ruletype => "body");
+          '. $self->hit_rule_plugin_code($rulename, "body", "return 1") . '
+        }
+        ';
+      }
+
     }
 
     if ($use_rule_subs) {
@@ -620,6 +659,14 @@
       ';
       push (@TEMPORARY_METHODS, $rulename.'_body_test');
     }
+
+    if ($need_one_line) {
+      $evalstr2 .= '
+        sub '.$rulename.'_one_line_body_test { '.$sub_one_line.' }
+      ';
+      push (@TEMPORARY_METHODS, $rulename.'_one_line_body_test');
+    }
+
   }
 
   # clear out a previous version of this fn
@@ -661,7 +708,6 @@
 
 sub do_body_uri_tests {
   my ($self, $pms, $priority, @uris) = @_;
-  local ($_);
 
   # XXX - why not just do the direct plugin call?
   return if $self->shortcircuited_p($pms);
@@ -690,7 +736,7 @@
   my $use_rule_subs = $self->{main}->{use_rule_subs};
 
   # otherwise build up the eval string...
-  my $evalstr = $self->start_rules_plugin_code("uri");
+  my $evalstr = $self->start_rules_plugin_code("uri", $priority);
   my $evalstr2 = '';
   my $loopid = 0;
 
@@ -791,7 +837,6 @@
 
 sub do_rawbody_tests {
   my ($self, $pms, $priority, $textary) = @_;
-  local ($_);
 
   # XXX - why not just do the plugin call here??
   return if $self->shortcircuited_p($pms);
@@ -820,7 +865,7 @@
   my $use_rule_subs = $self->{main}->{use_rule_subs};
 
   # build up the eval string...
-  my $evalstr = $self->start_rules_plugin_code("rawbody");
+  my $evalstr = $self->start_rules_plugin_code("rawbody", $priority);
   my $evalstr2 = '';
   my $loopid = 0;
 
@@ -922,8 +967,7 @@
 
 sub do_full_tests {
   my ($self, $pms, $priority, $fullmsgref) = @_;
-  local ($_);
-  
+
   # XXX - why not just do the plugin call directly?
   return if $self->shortcircuited_p($pms);
 
@@ -949,7 +993,7 @@
   }
 
   # build up the eval string...
-  my $evalstr = $self->start_rules_plugin_code("full");
+  my $evalstr = $self->start_rules_plugin_code("full", $priority);
 
   while (my($rulename, $pat) = each %{$pms->{conf}{full_tests}->{$priority}}) {
     $evalstr .= '
@@ -1032,18 +1076,18 @@
 
 sub run_eval_tests {
   my ($self, $pms, $testtype, $evalhash, $prepend2desc, $priority, @extraevalargs) = @_;
-  local ($_);
   
   # XXX - why not just call the plugin directly?
   return if $self->shortcircuited_p($pms);
 
-  my $doing_user_rules = $self->{conf}->{user_rules_to_compile}->{$testtype};
+  my $conf = $pms->{conf};
+  my $doing_user_rules = $conf->{user_rules_to_compile}->{$testtype};
 
   # clean up priority value so it can be used in a subroutine name 
   my $clean_priority;
   ($clean_priority = $priority) =~ s/-/neg/;
 
-  my $scoreset = $pms->{conf}->get_score_set();
+  my $scoreset = $conf->get_score_set();
 
   my $package_name = __PACKAGE__;
 
@@ -1063,7 +1107,8 @@
   }
 
   # look these up once in advance to save repeated lookups in loop below
-  my $tflagsref = $pms->{conf}->{tflags};
+  my $tflagsref = $conf->{tflags};
+  my $eval_pluginsref = $conf->{eval_plugins};
   my $have_start_rules = $self->{main}->have_plugin("start_rules");
   my $have_ran_rule = $self->{main}->have_plugin("ran_rule");
 
@@ -1103,7 +1148,7 @@
     ';
  
     # only need to set current_rule_name for plugin evals
-    if ($pms->{conf}->{eval_plugins}->{$function}) {
+    if ($eval_pluginsref->{$function}) {
       # let plugins get the name of the rule that is currently being run,
       # and ensure their eval functions exist
       $evalstr .= '
@@ -1121,7 +1166,7 @@
       $evalstr .= '
 
         $self->{main}->call_plugins("start_rules", {
-                permsgstatus => $self, ruletype => "eval"
+                permsgstatus => $self, ruletype => "eval", priority => $priority
               });
 
       ';
@@ -1225,7 +1270,7 @@
 }
 
 sub start_rules_plugin_code {
-  my ($self, $ruletype) = @_;
+  my ($self, $ruletype, $pri) = @_;
 
   my $evalstr = '
 
@@ -1238,7 +1283,8 @@
     $evalstr .= '
 
       $self->{main}->call_plugins ("start_rules", { permsgstatus => $self,
-                                                    ruletype => \''.$ruletype.'\' });
+                                                    ruletype => \''.$ruletype.'\',
+                                                    priority => $pri });
 
     ';
   }

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DKIM.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DKIM.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DKIM.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DKIM.pm Wed Nov 15 12:40:35 2006
@@ -256,8 +256,8 @@
   }
 
   # headers, line-by-line with \r\n endings, as per Mail::DKIM API
-  foreach my $line (split(/\n/s, $header)) {
-    $line =~ s/\r?$/\r\n/s;         # ensure \r\n ending
+  foreach my $line (split(/\r?\n/s, $header)) {  # split lines, deleting endings and final empty line
+    $line =~ s/$/\r\n/s;  # add back a standard \r\n ending
     $message->PRINT($line);
   }
   $message->PRINT("\r\n");

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm Wed Nov 15 12:40:35 2006
@@ -23,7 +23,26 @@
 
  loadplugin Mail::SpamAssassin::Plugin::DomainKeys [/path/to/DomainKeys.pm]
 
- full DOMAINKEY_DOMAIN eval:check_domainkeys_verified()
+Signature:
+ header DK_SIGNED                eval:check_domainkeys_signed()
+ header DK_VERIFIED              eval:check_domainkeys_verified()
+
+Policy:
+   Note that DK policy record is only fetched if DK_VERIFIED is false
+   to save signing domain from unnecessary DNS queries,
+   as recommended (SHOULD) by draft-delany-domainkeys-base.
+   Rules DK_POLICY_* should preferably not be relied upon when DK_VERIFIED
+   is true, although they will return false in current implementation
+   when a policy record is not fetched, except for DK_POLICY_TESTING,
+   which is true if t=y appears in a public key record OR in a policy
+   record (when available).
+ header DK_POLICY_TESTING        eval:check_domainkeys_testing()
+ header DK_POLICY_SIGNSOME       eval:check_domainkeys_signsome()
+ header DK_POLICY_SIGNALL        eval:check_domainkeys_signall()
+
+Whitelisting based on verified signature:
+ header USER_IN_DK_WHITELIST     eval:check_for_dk_whitelist_from()
+ header USER_IN_DEF_DK_WL        eval:check_for_def_dk_whitelist_from()
 
 =head1 DESCRIPTION
 
@@ -241,8 +260,11 @@
 
   my $header = $scan->{msg}->get_pristine_header();
   my $body = $scan->{msg}->get_body();
+  my $dksighdr = $scan->{msg}->get_header("DomainKey-Signature");
+  dbg("dk: signature: $dksighdr")  if defined $dksighdr;
 
-  $self->sanitize_header_for_dk(\$header);
+  $self->sanitize_header_for_dk(\$header)
+    if defined $dksighdr && $dksighdr !~ /(?:^|;)[ \t]*h=/;  # case sensitive
 
   my $message = Mail::DomainKeys::Message->load(HeadString => $header,
 						 BodyReference => $body);
@@ -315,20 +337,29 @@
       $scan->{domainkeys_verified} = 1;
     }
   }
-
-  my $policy = Mail::DomainKeys::Policy->fetch(Protocol => 'dns',
-					       Domain => $domain);
-
+  # testing flag in signature
+  if ($message->testing()) {
+    $scan->{domainkeys_testing} = 1;
+  }
+  my $policy;
+  if (!$scan->{domainkeys_verified}) {
+    # Recipient systems SHOULD not retrieve a policy TXT record
+    # for email that successfully verifies.
+    $policy = Mail::DomainKeys::Policy->fetch(Protocol => 'dns',
+					      Domain => $domain);
+    my($fetched_policy) = $policy ? $policy->as_string : 'NONE';
+    $fetched_policy = ''  if !defined $fetched_policy;
+    dbg ("dk: fetched policy for domain $domain: $fetched_policy");
+  }
   return unless $policy;
-  dbg ("dk: fetched policy");
 
   # not signed and domain doesn't sign all
   if ($policy->signsome()) {
     $scan->{domainkeys_signsome} = 1;
   }
 
-  # domain or key testing
-  if ($message->testing() || $policy->testing()) {
+  # testing flag in policy
+  if ($policy->testing()) {
     $scan->{domainkeys_testing} = 1;
   }
 
@@ -346,10 +377,15 @@
   my ($self, $message) = @_;
   # try to use the signature() API if it exists (post-0.80)
   if ($message->can("signature")) {
+    my($sts,$msg);
     if (!$message->signed) {
-      return "no signature";
+      $sts = "no signature";
+    } else {
+      $sts = $message->signature->status;
+      $msg = $message->signature->errorstr;
     }
-    return $message->signature->status;
+    dbg("dk: $sts" . (defined $msg ? " ($msg)" : ''));
+    return $sts;
   } else {
     return $message->header->value;
   }
@@ -366,7 +402,8 @@
     return $message->signature->domain;
   } else {
     # otherwise parse it ourself
-    if ($scan->{msg}->get_header("DomainKey-Signature") =~ /d=(\S+);/) {
+    if ($scan->{msg}->get_header("DomainKey-Signature") =~
+        /(?: ^|; ) [ \t]* d= [ \t]* ([^;]*?) [ \t]* (?: ;|$ )/x) {
       return $1;
     }
     return undef;
@@ -376,6 +413,7 @@
 sub sanitize_header_for_dk {
   my ($self, $ref) = @_;
 
+  dbg("dk: sanitizing header, no \"h\" tag in signature");
   # remove folding, in a HTML-escape data-preserving style, so we can
   # strip headers easily
   $$ref =~ s/!/!ex;/gs;

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm Wed Nov 15 12:40:35 2006
@@ -55,6 +55,7 @@
 sub are_more_high_bits_set {
   my ($self, $str) = @_;
 
+  # TODO: I suspect a tr// trick may be faster here
   my $numhis = () = ($str =~ /[\200-\377]/g);
   my $numlos = length($str) - $numhis;
 
@@ -81,7 +82,7 @@
     # number of 8-bit chars in the body text first.
 
     $body = join("\n", @$body);
-    if ($pms->are_more_high_bits_set ($body)) {
+    if ($self->are_more_high_bits_set ($body)) {
       return 1;
     }
   }

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEHeader.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEHeader.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEHeader.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEHeader.pm Wed Nov 15 12:40:35 2006
@@ -64,9 +64,11 @@
 use warnings;
 use bytes;
 
-use vars qw(@ISA);
+use vars qw(@ISA @TEMPORARY_METHODS);
 @ISA = qw(Mail::SpamAssassin::Plugin);
 
+@TEMPORARY_METHODS = (); 
+
 # ---------------------------------------------------------------------------
 
 # constructor
@@ -146,8 +148,7 @@
 
       $pluginobj->register_eval_rule($evalfn);
 
-      $pluginobj->register_generated_rule_method(
-        'Mail::SpamAssassin::Plugin::MIMEHeader::'.$evalfn);
+      push @TEMPORARY_METHODS, "Mail::SpamAssassin::Plugin::MIMEHeader::${evalfn}";
     }
   });
 
@@ -188,6 +189,17 @@
   }
 
   return ($negated ? 1 : 0);
+}
+
+# ---------------------------------------------------------------------------
+
+sub finish_tests {
+  my ($self, $params) = @_;
+
+  foreach my $method (@TEMPORARY_METHODS) {
+    undef &{$method};
+  }
+  @TEMPORARY_METHODS = ();      # clear for next time
 }
 
 # ---------------------------------------------------------------------------

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/ReplaceTags.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/ReplaceTags.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/ReplaceTags.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/ReplaceTags.pm Wed Nov 15 12:40:35 2006
@@ -78,15 +78,16 @@
 
   dbg("replacetags: replacing tags");
 
-  my $start = $opts->{conf}->{replace_start};
-  my $end = $opts->{conf}->{replace_end};
+  my $conf = $opts->{conf};
+  my $start = $conf->{replace_start};
+  my $end = $conf->{replace_end};
 
   # this is the version-specific code
   for my $type (qw|body_tests rawbody_tests head_tests full_tests uri_tests|) {
-    for my $priority (keys %{$opts->{conf}->{$type}}) {
-      while (my ($rule, $re) = each %{$opts->{conf}->{$type}->{$priority}}) {
+    for my $priority (keys %{$conf->{$type}}) {
+      while (my ($rule, $re) = each %{$conf->{$type}->{$priority}}) {
 	# skip if not listed by replace_rules
-	next unless $opts->{conf}->{rules_to_replace}{$rule};
+	next unless $conf->{rules_to_replace}{$rule};
 
 	if (would_log('dbg', 'replacetags') > 1) {
 	  dbg("replacetags: replacing $rule: $re");
@@ -112,19 +113,19 @@
 	my @re = split(/(<.+?>)/, $re);
 
 	if ($pre_name) {
-	  my $pre = $opts->{conf}->{replace_pre}->{$pre_name};
+	  my $pre = $conf->{replace_pre}->{$pre_name};
 	  if ($pre) {
 	    @re = map { s|($start.+?$end)|$pre$1|; $_; } @re;
 	  }
         }
 	if ($post_name) {
-	  my $post = $opts->{conf}->{replace_post}->{$post_name};
+	  my $post = $conf->{replace_post}->{$post_name};
 	  if ($post) {
 	    @re = map { s|($start.+?$end)|$1$post|g; $_; } @re;
 	  }
 	}
 	if ($inter_name) {
-	  my $inter = $opts->{conf}->{replace_inter}->{$inter_name};
+	  my $inter = $conf->{replace_inter}->{$inter_name};
 	  if ($inter) {
 	    @re = map { s|^$|$inter|; $_; } @re;
 	  }
@@ -134,7 +135,7 @@
 	    my $tag_name = $1;
 	    # if the tag exists, replace it with the corresponding phrase
 	    if ($tag_name) {
-	      my $replacement = $opts->{conf}->{replace_tag}->{$tag_name};
+	      my $replacement = $conf->{replace_tag}->{$tag_name};
 	      if ($replacement) {
 		$re[$i] =~ s|$start$tag_name$end|$replacement|g;
 	      }
@@ -145,13 +146,18 @@
         $re = join('', @re);
 
 	# do the actual replacement
-	$opts->{conf}->{$type}->{$priority}->{$rule} = $re;
+	$conf->{$type}->{$priority}->{$rule} = $re;
 
 	if (would_log('dbg', 'replacetags') > 1) {
 	  dbg("replacetags: replaced $rule: $re");
 	}
       }
     }
+  }
+
+  # free this up, if possible
+  if (!$conf->{allow_user_rules}) {
+    delete $conf->{rules_to_replace};
   }
 
   dbg("replacetags: done replacing tags");

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/SpamdForkScaling.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/SpamdForkScaling.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/SpamdForkScaling.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/SpamdForkScaling.pm Wed Nov 15 12:40:35 2006
@@ -187,9 +187,16 @@
 ###########################################################################
 
 sub set_server_fh {
-  my ($self, $fh) = @_;
-  $self->{server_fh} = $fh;
-  $self->{server_fileno} = $fh->fileno();
+  my ($self, @fhs) = @_;
+
+  $self->{server_fh} = [];
+  $self->{server_fileno} = [];
+
+  foreach my $fh (@fhs) {
+    next unless defined $fh;
+    push @{$self->{server_fh}}, $fh;
+    push @{$self->{server_fileno}}, $fh->fileno();
+  }
 }
 
 sub main_server_poll {
@@ -199,7 +206,7 @@
   if ($self->{overloaded}) {
     # don't select on the server fh -- we already KNOW that's ready,
     # since we're overloaded
-    vec($rin, $self->{server_fileno}, 1) = 0;
+    $self->vec_all(\$rin, $self->{server_fileno}, 0);
   }
 
   my ($rout, $eout, $nfound, $timeleft, $selerr);
@@ -265,7 +272,7 @@
 
   # errors on the handle?
   # return them immediately, they may be from a SIGHUP restart signal
-  if (vec ($eout, $self->{server_fileno}, 1)) {
+  if ($self->vec_all(\$eout, $self->{server_fileno})) {
     warn "prefork: select returned error on server filehandle: $selerr $!\n";
     return;
   }
@@ -283,7 +290,7 @@
   }
 
   # were the kids ready, or did we get signal?
-  if (vec ($rout, $self->{server_fileno}, 1)) {
+  if ($self->vec_all(\$rout, $self->{server_fileno})) {
     # dbg("prefork: server fh ready");
     # the server socket: new connection from a client
     if (!$self->order_idle_child_to_accept()) {
@@ -765,6 +772,20 @@
   kill 'INT' => $pid;
 
   dbg("prefork: adjust: decreasing, too many idle children ($num_idle > $self->{max_idle}), killed $pid");
+}
+
+sub vec_all {
+  my ($self, $bitsref, $fhs, $value) = @_;
+  my $ret = 0;
+  foreach my $fh (@{$fhs}) {
+    next unless defined $fh;
+    if (defined $value) {
+      vec($$bitsref, $fh, 1) = $value;
+    } else {
+      $ret |= vec($$bitsref, $fh, 1);
+    }
+  }
+  return $ret;
 }
 
 1;

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Util.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Util.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Util.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Util.pm Wed Nov 15 12:40:35 2006
@@ -535,7 +535,16 @@
   # There's a die() in there which "shouldn't happen", but better be
   # paranoid.  We'll return the unwrapped string if anything went wrong.
   my $text = $_[0] || "";
+
+  # Text::Wrap produces spurious warnings:
+  # [23409] warn: (?:(?<=[\s,]))* matches null string many times in regex; marked by <-- HERE in m/\G(?:(?<=[\s,]))* <-- HERE \Z/ at /usr/local/perl594/lib/5.9.4/Text/Wrap.pm line 46.
+  # trap and ignore them.  Why do so many of the core modules do this
+  # kind of crap? :(  use a $SIG{__WARN__} to trap it.
+
   eval {
+    local $SIG{__WARN__} = sub {
+      ($_[0] =~ /matches null string many times/) or CORE::warn(@_);
+    };
     $text = Text::Wrap::wrap($_[2] || "", $_[1] || "", $text);
   };
   return $text;

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Util/DependencyInfo.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Util/DependencyInfo.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Util/DependencyInfo.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Util/DependencyInfo.pm Wed Nov 15 12:40:35 2006
@@ -40,6 +40,18 @@
   'desc' => 'HTML is used for an ever-increasing amount of email so this dependency
   is unavoidable.  Run "perldoc -q html" for additional information.',
 },
+{
+  module => 'Net::DNS',
+  version => ($^O =~ /^(mswin|dos|os2)/oi ? '0.46' : '0.34'),
+  desc => 'Used for all DNS-based tests (SBL, XBL, SpamCop, DSBL, etc.),
+  perform MX checks, and is also used when manually reporting spam to
+  SpamCop.
+
+  You need to make sure the Net::DNS version is sufficiently up-to-date:
+
+  - version 0.34 or higher on Unix systems
+  - version 0.46 or higher on Windows systems',
+},
 );
 
 my @OPTIONAL_MODULES = (
@@ -55,20 +67,6 @@
   desc => 'Used to store data on-disk, for the Bayes-style logic and
   auto-whitelist.  *Much* more efficient than the other standard Perl
   database packages.  Strongly recommended.',
-},
-{
-  module => 'Net::DNS',
-  version => ($^O =~ /^(mswin|dos|os2)/oi ? '0.46' : '0.34'),
-  desc => 'Used for all DNS-based tests (SBL, XBL, SpamCop, DSBL, etc.),
-  perform MX checks, and is also used when manually reporting spam to
-  SpamCop.  Recommended.
-
-  If this is installed and you are using network tests of any variety
-  (which is the default), then you need to make sure the Net::DNS
-  version is sufficiently up-to-date:
-
-  - version 0.34 or higher on Unix systems
-  - version 0.46 or higher on Windows systems',
 },
 {
   module => 'Net::SMTP',

Modified: spamassassin/branches/jm_re2c_hacks/masses/hit-frequencies
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/masses/hit-frequencies?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/masses/hit-frequencies (original)
+++ spamassassin/branches/jm_re2c_hacks/masses/hit-frequencies Wed Nov 15 12:40:35 2006
@@ -716,7 +716,7 @@
   foreach my $full (sort { $b <=> $a } keys %$hash) {
     my $ratio = $full * 100;
 
-    last if ($ratio < 30);     # 30% cutoff
+    last if ($ratio < 20);     # 20% cutoff
     my $rules = _prettify_overlap_rules($r1, $hash->{$full});
     next if ($rules eq '');
 

Modified: spamassassin/branches/jm_re2c_hacks/masses/mass-check
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/masses/mass-check?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/masses/mass-check (original)
+++ spamassassin/branches/jm_re2c_hacks/masses/mass-check Wed Nov 15 12:40:35 2006
@@ -741,13 +741,6 @@
   undef $ma;		# clean 'em up
   undef $status;
 
-  # uncomment these lines to get a Data::Dumper dump of the Mail::SpamAssassin
-  # module, written to a file after each message is scanned.  This is a
-  # great way to find memory leaks...
-  ## use Data::Dumper;
-  ## open (D, ">dump.$$.$total_count"); print D Dumper($spamtest); close D;
-  ## warn "wrote memory dump: dump.$$.$total_count";
-
   showdots_blip();
 #  print ">>>> out = $out\n";
   return $out;

Modified: spamassassin/branches/jm_re2c_hacks/masses/rule-qa/automc/gen_info_xml
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/masses/rule-qa/automc/gen_info_xml?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/masses/rule-qa/automc/gen_info_xml (original)
+++ spamassassin/branches/jm_re2c_hacks/masses/rule-qa/automc/gen_info_xml Wed Nov 15 12:40:35 2006
@@ -42,10 +42,12 @@
   my $fastinfo = get_fastinfo($dr, $drdir);
   if (!defined $fastinfo) { next; }
 
-  open (OUT, ">$drdir/fastinfo.xml") or die "cannot write $drdir/fastinfo.xml";
-  print OUT $fastinfo;
-  close OUT or die "failed to write to $drdir/fastinfo.xml";
-  chmod 0666, "$drdir/fastinfo.xml"; # or warn "failed to chmod $drdir/fastinfo.xml";
+  if (!-e "$drdir/fastinfo.xml" || -s "$drdir/fastinfo.xml" == 0) {
+    open (OUT, ">$drdir/fastinfo.xml") or die "cannot write $drdir/fastinfo.xml";
+    print OUT $fastinfo;
+    close OUT or die "failed to write to $drdir/fastinfo.xml";
+    chmod 0666, "$drdir/fastinfo.xml"; # or warn "failed to chmod $drdir/fastinfo.xml";
+  }
 
   # this one is only built if it doesn't already exist, because
   # it's quite expensive to build
@@ -54,12 +56,14 @@
     next;
   }
 
-  print "$drdir/info.xml: creating...\n";
-  my $info = get_info($dr, $drdir);
-  open (OUT, ">$drdir/info.xml") or die "cannot write $drdir/info.xml";
-  print OUT $info;
-  close OUT or die "failed to write to $drdir/info.xml";
-  chmod 0666, "$drdir/info.xml"; # or warn "failed to chmod $drdir/info.xml";
+  if (!-e "$drdir/info.xml" || -s "$drdir/info.xml" == 0) {
+    print "$drdir/info.xml: creating...\n";
+    my $info = get_info($dr, $drdir);
+    open (OUT, ">$drdir/info.xml") or die "cannot write $drdir/info.xml";
+    print OUT $info;
+    close OUT or die "failed to write to $drdir/info.xml";
+    chmod 0666, "$drdir/info.xml"; # or warn "failed to chmod $drdir/info.xml";
+  }
 }
 
 sub get_info {

Modified: spamassassin/branches/jm_re2c_hacks/masses/rule-qa/automc/ruleqa.cgi
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/masses/rule-qa/automc/ruleqa.cgi?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/masses/rule-qa/automc/ruleqa.cgi (original)
+++ spamassassin/branches/jm_re2c_hacks/masses/rule-qa/automc/ruleqa.cgi Wed Nov 15 12:40:35 2006
@@ -52,6 +52,7 @@
 use constant DATEREV_ADJ => - (8 * 60 * 60);
 
 my $FREQS_LINE_TEMPLATE;
+my $FREQS_LINE_TEXT_TEMPLATE;
 my $FREQS_EXTRA_TEMPLATE;
 our %AUTOMC_CONF;
 
@@ -475,11 +476,16 @@
 
     <br/>
 
+<!-- 
+
+    (This has been pretty much superceded by the --net mass-checks)
+
     <h4> Which Corpus? </h4>
     <input type=checkbox name=s_defcorpus !s_defcorpus!> Show default non-net ruleset and corpus, set 0<br/>
     <input type=checkbox name=s_net !s_net!> Show frequencies from network tests, set 1<br/>
     <input type=checkbox name=s_html !s_html!> Show frequencies for mails containing HTML only, set 0<br/>
     <br/>
+-->
 
     <h4> Which Rules?</h4>
     Show only these rules (space separated, or regexp with '/' prefix):<br/>
@@ -488,9 +494,9 @@
     Show only rules from files whose paths contain this string:<br/>
     <input type=textfield size=60 name=srcpath value="!srcpath!"><br/>
     <br/>
-    <input type=checkbox name=s_zero !s_zero!> Display rules with no hits<br/>
+    <input type=checkbox name=s_zero !s_zero!> Show rules with zero hits<br/>
+    <input type=checkbox name=s_detail !s_detail!> Display full details: message age in weeks, by contributor, as score-map, overlaps with other rules, freshness graphs<br/>
     <br/>
-    <input type=hidden name=s_detail value="!s_detail!" />
 
     <input type=submit name=g value="Change"><br/>
 
@@ -945,8 +951,15 @@
     <pre class=head>$heads</pre>
     </div>
 
+    <div id="txt_$headers_id" class=headdiv style='display: none'>
+    <p class=headclosep align=right><a
+          href="javascript:hide_header('txt_$headers_id')">[close]</a></p>
+    <pre class=head><<<TEXTS>>></pre>
+    </div>
+
     <br clear="all"/>
     <p class=showfreqslink><a
+      href="javascript:show_header('txt_$headers_id')">(pasteable)</a><a
       href="javascript:show_header('$headers_id')">(source details)</a>
       <a name='$titleplink' href='#$titleplink' class=title_permalink>(#)</a>
     </p>
@@ -969,6 +982,14 @@
   $ruleslist ||= '';
   my @rules = split (' ', $ruleslist);
 
+  if (ref $self->{freqs_ordr}{$key} ne 'ARRAY') {
+    print qq(
+      <h3 class=freqs_title>$desc</h3>
+      <table><p><i>('$key' not yet available)</i></p></table>
+    );
+    return;
+  }
+
   if ($self->{rules_all}) {
     push @rules, @{$self->{freqs_ordr}{$key}};
   }
@@ -1020,10 +1041,15 @@
     $FREQS_LINE_TEMPLATE =~ s/<!--\s+<rule>.*?-->//gs;
   }
 
+  my $texts = '';
   foreach my $rule (@rules) {
     if ($rule && defined $self->{freqs_data}{$key}{$rule}) {
       $comment .= $self->rule_anchor($key,$rule);
       $comment .= $self->output_freqs_data_line($self->{freqs_data}{$key}{$rule},
+                \$FREQS_LINE_TEMPLATE,
+                $header_context);
+      $texts .= $self->output_freqs_data_line($self->{freqs_data}{$key}{$rule},
+                \$FREQS_LINE_TEXT_TEMPLATE,
                 $header_context);
     }
     else {
@@ -1033,8 +1059,12 @@
         (no data found)
       </td></tr>
       ";
+      $texts .= "(no data found)\n";
     }
   }
+
+  # insert the text into that template
+  $comment =~ s/<<<TEXTS>>>/$texts/gs;
   
   print $comment;
   print "</table>";
@@ -1074,6 +1104,13 @@
 
   };
 
+  $FREQS_LINE_TEXT_TEMPLATE =
+       qq{[% USE format %][% fmt = format('%7s') %][% fm6 = format('%6s') %]}.
+       qq{[% fmt(MSECS) %]  [% fmt(SPAMPC) %]  [% fmt(HAMPC) %]  }.
+       qq{[% fm6(SO) %]  [% fm6(RANK) %]  [% fm6(SCORE) %]  }.
+       qq{[% NAME %] [% USERNAME %] [% AGE %] }.
+       "\n";
+
   $FREQS_EXTRA_TEMPLATE = qq{
 
   <tr class=freqsextra>
@@ -1161,7 +1198,7 @@
 }
 
 sub output_freqs_data_line {
-  my ($self, $obj, $header_context) = @_;
+  my ($self, $obj, $template, $header_context) = @_;
 
   # normal freqs lines, with optional subselector after rule name
   my $out = '';
@@ -1183,7 +1220,7 @@
       $score = '(n/a)';
     }
 
-    $self->{ttk}->process(\$FREQS_LINE_TEMPLATE, {
+    $self->{ttk}->process($template, {
         RULEDETAIL => $detailurl,
         MSECS => $line->{msecs},
         SPAMPC => $line->{spampc},

Modified: spamassassin/branches/jm_re2c_hacks/rules/20_dnsbl_tests.cf
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/rules/20_dnsbl_tests.cf?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/rules/20_dnsbl_tests.cf (original)
+++ spamassassin/branches/jm_re2c_hacks/rules/20_dnsbl_tests.cf Wed Nov 15 12:40:35 2006
@@ -139,6 +139,8 @@
 #
 # Spamhaus XBL contains both the Abuseat CBL (cbl.abuseat.org) and Blitzed
 # OPM (opm.blitzed.org) lists so it's not necessary to query those as well.
+# TODO: replace with ZEN from rulesrc/sandbox/jm/20_zen.cf.  For now,
+# allow both to run for 1 weekend to verify sanity of results...
 
 header __RCVD_IN_SBL_XBL	eval:check_rbl('sblxbl', 'sbl-xbl.spamhaus.org.')
 describe __RCVD_IN_SBL_XBL	Received via a relay in Spamhaus SBL+XBL
@@ -167,25 +169,23 @@
 tflags DNS_FROM_RFC_DSN		net
 #reuse DNS_FROM_RFC_DSN
 
-header DNS_FROM_RFC_POST	eval:check_rbl_sub('rfci_envfrom', '127.0.0.3')
-describe DNS_FROM_RFC_POST	Envelope sender in postmaster.rfc-ignorant.org
-tflags DNS_FROM_RFC_POST	net
-#reuse DNS_FROM_RFC_POST
-
-header DNS_FROM_RFC_ABUSE       eval:check_rbl_sub('rfci_envfrom', '127.0.0.4')
-describe DNS_FROM_RFC_ABUSE     Envelope sender in whois.rfc-ignorant.org
-tflags DNS_FROM_RFC_ABUSE       net
-#reuse DNS_FROM_RFC_ABUSE
-
-header DNS_FROM_RFC_WHOIS	eval:check_rbl_sub('rfci_envfrom', '127.0.0.5')
-describe DNS_FROM_RFC_WHOIS	Envelope sender in whois.rfc-ignorant.org
-tflags DNS_FROM_RFC_WHOIS	net
-#reuse DNS_FROM_RFC_WHOIS
-
 header DNS_FROM_RFC_BOGUSMX	eval:check_rbl_sub('rfci_envfrom', '127.0.0.8')
 describe DNS_FROM_RFC_BOGUSMX	Envelope sender in bogusmx.rfc-ignorant.org
 tflags DNS_FROM_RFC_BOGUSMX	net
 #reuse DNS_FROM_RFC_BOGUSMX
+
+# bug 4628: these rules are too unreliable to assign scores to
+header __DNS_FROM_RFC_POST      eval:check_rbl_sub('rfci_envfrom', '127.0.0.3')
+tflags __DNS_FROM_RFC_POST      net
+#reuse __DNS_FROM_RFC_POST DNS_FROM_RFC_POST
+
+header __DNS_FROM_RFC_ABUSE     eval:check_rbl_sub('rfci_envfrom', '127.0.0.4')
+tflags __DNS_FROM_RFC_ABUSE     net
+#reuse __DNS_FROM_RFC_ABUSE DNS_FROM_RFC_ABUSE
+
+header __DNS_FROM_RFC_WHOIS     eval:check_rbl_sub('rfci_envfrom', '127.0.0.5')
+tflags __DNS_FROM_RFC_WHOIS     net
+#reuse __DNS_FROM_RFC_WHOIS DNS_FROM_RFC_WHOIS
 
 # ---------------------------------------------------------------------------
 # CompleteWhois blacklists

Modified: spamassassin/branches/jm_re2c_hacks/rules/20_head_tests.cf
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/rules/20_head_tests.cf?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/rules/20_head_tests.cf (original)
+++ spamassassin/branches/jm_re2c_hacks/rules/20_head_tests.cf Wed Nov 15 12:40:35 2006
@@ -137,7 +137,11 @@
 
 header __MSGID_BEFORE_RECEIVED	ALL =~ /\nMessage-Id:.*\nReceived:/si
 header __MSGID_BEFORE_OKAY	Message-Id =~ /\@[a-z0-9.-]+\.(?:yahoo|wanadoo)(?:\.[a-z]{2,3}){1,2}>/
-meta MSGID_FROM_MTA_HEADER	(__MSGID_BEFORE_RECEIVED && !__MSGID_BEFORE_OKAY)
+
+# bug 4342: thanks Bob
+header   __FROM_HOTMAIL_COM     From =~ /\@hotmail\.com\b/i
+
+meta MSGID_FROM_MTA_HEADER	(__MSGID_BEFORE_RECEIVED && !__MSGID_BEFORE_OKAY && !__FROM_HOTMAIL_COM)
 describe MSGID_FROM_MTA_HEADER	Message-Id was added by a relay
 
 header MSGID_FROM_MTA_HOTMAIL	Message-Id =~ /<MC\d{1,2}-F{1,2}\w{21,22}\@\S*hotmail\.com>/

Modified: spamassassin/branches/jm_re2c_hacks/rules/30_text_de.cf
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/rules/30_text_de.cf?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/rules/30_text_de.cf (original)
+++ spamassassin/branches/jm_re2c_hacks/rules/30_text_de.cf Wed Nov 15 12:40:35 2006
@@ -97,8 +97,6 @@
 lang de describe RCVD_IN_SBL Transportiert via Rechner in SBL-Liste (http://www.spamhaus.org/sbl/)
 lang de describe RCVD_IN_XBL Transportiert via Rechner in XBL-Liste (http://www.spamhaus.org/xbl/)
 lang de describe DNS_FROM_RFC_DSN Absender in dsn-Liste von www.rfc-ignorant.org
-lang de describe DNS_FROM_RFC_POST Absender in postmaster-Liste von www.rfc-ignorant.org
-lang de describe DNS_FROM_RFC_WHOIS Absender in whois-Liste von www.rfc-ignorant.org
 lang de describe DNS_FROM_RFC_BOGUSMX Absender in bogusmx-Liste von www.rfc-ignorant.org
 lang de describe RCVD_IN_DSBL Transportiert via Rechner in Liste von list.dsbl.org
 lang de describe DNS_FROM_AHBL_RHSBL Absenderadresse in Liste von dnsbl.ahbl.org

Modified: spamassassin/branches/jm_re2c_hacks/rules/50_scores.cf
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/rules/50_scores.cf?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/rules/50_scores.cf (original)
+++ spamassassin/branches/jm_re2c_hacks/rules/50_scores.cf Wed Nov 15 12:40:35 2006
@@ -419,8 +419,6 @@
 score DNS_FROM_AHBL_RHSBL 0.001 0.306 0.001 0.231
 score DNS_FROM_RFC_BOGUSMX 0.001 2.034 0.001 1.945
 score DNS_FROM_RFC_DSN 0.001 2.872 0.001 2.597
-score DNS_FROM_RFC_POST 0.001 1.440 0.001 1.708
-score DNS_FROM_RFC_WHOIS 0.001 0.879 0.001 1.447
 score DNS_FROM_SECURITYSAGE 0.001 2.001 0.001 1.513
 
 score NO_DNS_FOR_FROM 0.001 2.603 0.001 3.200

Modified: spamassassin/branches/jm_re2c_hacks/rules/active.list
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/rules/active.list?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/rules/active.list (original)
+++ spamassassin/branches/jm_re2c_hacks/rules/active.list Wed Nov 15 12:40:35 2006
@@ -1,5 +1,5 @@
 # active ruleset list, automatically generated from http://ruleqa.spamassassin.org/
-# with results from: cthielen daf parkerm zmi
+# with results from: bb-doc bb-jm bb-zmi cthielen dos parkerm theo zmi
 
 # tflags userconf
 ALL_TRUSTED
@@ -11,6 +11,9 @@
 AXB_FAKETZ
 
 # good enough
+AXB_XMID_OEGOESNULL
+
+# good enough
 AXB_XR_STULDAP
 
 # good enough
@@ -55,8 +58,17 @@
 # good enough
 BROKEN_RATWARE_BOM
 
+# tflags userconf
+CHARSET_FARAWAY
+
+# tflags userconf
+CHARSET_FARAWAY_HEADER
+
+# tflags userconf
+CORRUPT_FROM_LINE_IN_HDRS
+
 # good enough
-CTYPE_1SPACE_GIF
+CTYPE_8SPACE_GIF
 
 # good enough
 DC_GIF_MULTI_LARGO
@@ -89,40 +101,40 @@
 DNS_FROM_AHBL_RHSBL
 
 # tflags net
-DNS_FROM_RFC_ABUSE
+DNS_FROM_DOB
 
 # tflags net
-DNS_FROM_RFC_BOGUSMX
+DNS_FROM_OPENWHOIS
 
 # tflags net
-DNS_FROM_RFC_DSN
-
-# tflags net
-DNS_FROM_RFC_POST
+DNS_FROM_RFC_BOGUSMX
 
 # tflags net
-DNS_FROM_RFC_WHOIS
+DNS_FROM_RFC_DSN
 
 # tflags net
 DNS_FROM_SECURITYSAGE
 
 # good enough
-DOS_LET_GO_JOB
+DOS_MORTGAGE
 
 # good enough
-DOS_MORTGAGE
+DOS_TO_READ_STOCK
 
 # good enough
-DOS_STOCK_O_PRICE
+DOS_YOUR_PLACE
 
 # good enough
-DOS_TWO_MIS_STOCK
+DRUGS_HDIA
 
 # good enough
-DOS_YOUR_PLACE
+DRUGS_STOCK_MIMEOLE
 
 # good enough
-DRUGS_HDIA
+DYN_RDNS_AND_INLINE_IMAGE
+
+# good enough
+DYN_RDNS_SHORT_HELO_HTML
 
 # tflags userconf
 ENV_AND_HDR_SPF_MATCH
@@ -134,24 +146,12 @@
 FB_OBFU_URI_COM
 
 # good enough
-FB_SAVE_LEO
-
-# good enough
-FB_THOUS_PERSONAL
-
-# good enough
 FB_VALIUM_LEO2
 
 # good enough
-FB_VIAGRA_LEO2
-
-# good enough
 FB_VIAGRA_LEO3
 
 # good enough
-FB_YOURSELF_MASTER
-
-# good enough
 FH_DATE_PAST_20XX
 
 # good enough
@@ -161,13 +161,10 @@
 FH_FROM_TO_PERC
 
 # good enough
-FH_RCVD_WITHSMTPFOR
-
-# good enough
 FM_CUSTOMLOGODSGNc
 
-# good enough
-FS_START_DOYOU
+# tflags userconf
+FRAGMENTED_MESSAGE
 
 # good enough
 FS_START_DOYOU2
@@ -176,20 +173,14 @@
 FUZZY_MERIDIA
 
 # good enough
-FUZZY_SPRM
-
-# good enough
-FUZZY_STOCK
-
-# good enough
-FU_HOODIA
-
-# good enough
 GEO_QUERY_STRING
 
 # good enough
 GMD_FAKETZ
 
+# tflags userconf
+GTUBE
+
 # tflags net
 HABEAS_ACCREDITED_COI
 
@@ -223,37 +214,49 @@
 # tflags userconf
 HASHCASH_HIGH
 
+# good enough
+HDR_ORDER_FTSDMCXX
+
 # tflags userconf
 HEAD_LONG
 
+# tflags userconf
+HIGH_CODEPAGE_URI
+
 # good enough
-HS_EXTRA
+HS_DRUG_DOLLAR_1
 
 # good enough
-HS_GETMEOFF
+HS_DRUG_DOLLAR_2
 
 # good enough
-HS_INDEX_PARAM
+HS_DRUG_DOLLAR_3
 
 # good enough
-HS_MEETUP_FOR_SEX
+HS_DRUG_DOLLAR_MANY
 
 # good enough
-HS_NO_FLOWERS
+HS_FORGED_OE_FW
 
 # good enough
-HS_PHARMA_1
+HS_GETMEOFF
 
 # good enough
-HS_SUBJ_ONLINE_PHARMACEUTICAL
+HS_MEETUP_FOR_SEX
 
 # good enough
-HS_SYNDICATE_P2
+HS_PHARMA_1
+
+# good enough
+HS_SUBJ_ONLINE_PHARMACEUTICAL
 
 # tflags userconf
 HTML_CHARSET_FARAWAY
 
 # good enough
+HTTPS_HTTP_MISMATCH
+
+# good enough
 JM_RCVD_QMAILV1
 
 # good enough
@@ -266,28 +269,25 @@
 KAM_STOCKTIP15
 
 # good enough
-KAM_STOCKTIP2
-
-# good enough
 KAM_STOCKTIP21
 
 # good enough
-KAM_STOCKTIP3
-
-# good enough
 KAM_STOCKTIP6
 
 # good enough
 KAM_STOCKTIP8
 
 # good enough
+MID_14DIGITS_HEX
+
+# good enough
 MID_DEGREES
 
 # good enough
 MID_MJW_STOX
 
-# good enough
-MID_OUTLOOK_ZZZNN
+# tflags userconf
+MIME_CHARSET_FARAWAY
 
 # tflags userconf
 MISSING_HB_SEP
@@ -296,12 +296,18 @@
 NO_DNS_FOR_FROM
 
 # tflags userconf
+NO_RECEIVED
+
+# tflags userconf
 NO_RELAYS
 
 # good enough
 NULL_IN_BODY
 
 # good enough
+OUTLOOK_3416
+
+# good enough
 PART_CID_STOCK
 
 # good enough
@@ -335,9 +341,93 @@
 RCVD_IN_BSP_TRUSTED
 
 # tflags net
+RCVD_IN_DOB
+
+# tflags net
 RCVD_IN_DSBL
 
 # tflags net
+RCVD_IN_IADB_DK
+
+# tflags net
+RCVD_IN_IADB_DOPTIN
+
+# tflags net
+RCVD_IN_IADB_DOPTIN_GT50
+
+# tflags net
+RCVD_IN_IADB_DOPTIN_LT50
+
+# tflags net
+RCVD_IN_IADB_EDDB
+
+# tflags net
+RCVD_IN_IADB_EPIA
+
+# tflags net
+RCVD_IN_IADB_GOODMAIL
+
+# tflags net
+RCVD_IN_IADB_LISTED
+
+# tflags net
+RCVD_IN_IADB_LOOSE
+
+# tflags net
+RCVD_IN_IADB_MI_CPEAR
+
+# tflags net
+RCVD_IN_IADB_MI_CPR_30
+
+# tflags net
+RCVD_IN_IADB_MI_CPR_MAT
+
+# tflags net
+RCVD_IN_IADB_ML_DOPTIN
+
+# tflags net
+RCVD_IN_IADB_NOCONTROL
+
+# tflags net
+RCVD_IN_IADB_OOO
+
+# tflags net
+RCVD_IN_IADB_OPTIN
+
+# tflags net
+RCVD_IN_IADB_OPTIN_GT50
+
+# tflags net
+RCVD_IN_IADB_OPTIN_LT50
+
+# tflags net
+RCVD_IN_IADB_OPTOUTONLY
+
+# tflags net
+RCVD_IN_IADB_RDNS
+
+# tflags net
+RCVD_IN_IADB_SENDERID
+
+# tflags net
+RCVD_IN_IADB_SPF
+
+# tflags net
+RCVD_IN_IADB_UNVERIFIED_1
+
+# tflags net
+RCVD_IN_IADB_UNVERIFIED_2
+
+# tflags net
+RCVD_IN_IADB_UT_CPEAR
+
+# tflags net
+RCVD_IN_IADB_UT_CPR_30
+
+# tflags net
+RCVD_IN_IADB_UT_CPR_MAT
+
+# tflags net
 RCVD_IN_IADB_VOUCHED
 
 # tflags net
@@ -415,6 +505,9 @@
 # tflags net
 ROUND_THE_WORLD
 
+# good enough
+SHORT_HELO_AND_INLINE_IMAGE
+
 # tflags net
 SPF_FAIL
 
@@ -464,27 +557,15 @@
 TVD_APP_LOAN
 
 # good enough
-TVD_BODY_END_STAR
-
-# good enough
 TVD_DEAR_HOMEOWNER
 
 # good enough
 TVD_EB_PHISH
 
 # good enough
-TVD_ENHANCE
-
-# good enough
-TVD_FINGER_01
-
-# good enough
 TVD_FLOAT_GENERAL
 
 # good enough
-TVD_FROM_1
-
-# good enough
 TVD_FUZZY_DEGREE
 
 # good enough
@@ -494,31 +575,22 @@
 TVD_FUZZY_FIXED_RATE
 
 # good enough
-TVD_FUZZY_MICROCAP
-
-# good enough
 TVD_FUZZY_PHARMACEUTICAL
 
 # good enough
-TVD_FUZZY_SECURITIES
-
-# good enough
 TVD_FUZZY_SYMBOL
 
 # good enough
-TVD_FW_GRAPHIC_ID1
+TVD_FW_GRAPHIC_ID3
 
 # good enough
-TVD_FW_GRAPHIC_ID2
+TVD_FW_GRAPHIC_ID3_2
 
 # good enough
-TVD_FW_MESG1
+TVD_FW_GRAPHIC_NAME_LONG
 
 # good enough
-TVD_FW_MESG2
-
-# good enough
-TVD_GET_STOCK
+TVD_FW_GRAPHIC_NAME_MID
 
 # good enough
 TVD_HEAD_KERNEL
@@ -530,13 +602,16 @@
 TVD_NOT_SATISFIED
 
 # good enough
-TVD_PH_BODY_META
+TVD_PH_7
 
 # good enough
-TVD_PH_FR5
+TVD_PH_REC
 
 # good enough
-TVD_PH_REC
+TVD_PH_SUBJ_META
+
+# good enough
+TVD_PH_SUBJ_META_ALL
 
 # good enough
 TVD_PH_SUBJ_UPDATE
@@ -545,6 +620,9 @@
 TVD_PH_SUBJ_URGENT
 
 # good enough
+TVD_PP_PHISH
+
+# good enough
 TVD_QUAL_MEDS
 
 # good enough
@@ -554,9 +632,6 @@
 TVD_RATWARE_CB_2
 
 # good enough
-TVD_RATWARE_MSGID_01
-
-# good enough
 TVD_RATWARE_MSGID_02
 
 # good enough
@@ -569,12 +644,6 @@
 TVD_SPACED_SUBJECT_WORD3
 
 # good enough
-TVD_SPACED_SUBJECT_WORD5
-
-# good enough
-TVD_SPACED_WORDS
-
-# good enough
 TVD_STOCK1
 
 # good enough
@@ -590,40 +659,76 @@
 TVD_SUBJ_FINGER_03
 
 # good enough
-TVD_SUBJ_OWE
+TVD_UA_FOSTERING
 
 # good enough
-TVD_SUBJ_WIPE_DEBT
+TVD_VISIT_PHARMA
 
 # good enough
-TVD_UA_FOSTERING
+TVD_VIS_HIDDEN
 
 # good enough
-TVD_UNDER_VALUED
+DC_IMAGE001_GIF
 
 # good enough
-TVD_VIS_HIDDEN
+DOS_DOUBLE_SOTCK
 
 # good enough
-DOS_TO_READ_STOCK
+DOS_LET_GO_JOB
 
 # good enough
-DRUGS_STOCK_MIMEOLE
+DOS_STOCK_O_PRICE
 
 # good enough
-DRUGS_STOCK_MIMEOLE2
+DOS_TWO_MIS_STOCK
 
 # good enough
-FB_CIALIS_LEO2
+FH_DATE_IS_19XX
 
 # good enough
-FH_DATE_IS_19XX
+HS_BODY_UPLOADED_SOFTWARE
 
 # good enough
-FR_WWW_DOMAIN_23SUBDIR
+HS_SUBJ_NEW_SOFTWARE
 
 # good enough
-KAM_STOCKTIP20
+HS_UPLOADED_SOFTWARE
+
+# good enough
+KAM_STOCKTIP4
+
+# tflags net
+RCVD_IN_DSBL
+
+# tflags net
+RCVD_IN_MAPS_DUL
+
+# tflags net
+RCVD_IN_NJABL_DUL
+
+# tflags net
+RCVD_IN_SORBS_DUL
+
+# tflags net
+RCVD_IN_WHOIS_INVALID
+
+# tflags net
+RCVD_IN_XBL
+
+# good enough
+RCVD_LSO_SND
+
+# good enough
+RDNS_DYNAMIC
+
+# good enough
+SB_GIF_AND_NO_URIS
+
+# good enough
+TVD_DOLLARS_US
+
+# good enough
+TVD_FINGER_02
 
 # good enough
 TVD_LINK_SAVE
@@ -631,6 +736,84 @@
 # good enough
 TVD_PH_SUBJ_SEC_MEASURES
 
+# good enough
+TVD_SPACED_SUBJECT_WORD5
+
+# good enough
+TVD_SUBJ_FINGER_04
+
+# good enough
+TVD_SUBJ_OWE
+
+# good enough
+TVD_SUBJ_WIPE_DEBT
+
+# good enough
+XMAILER_MIMEOLE_OL_09BB4
+
+# good enough
+XMAILER_MIMEOLE_OL_20C99
+
+# good enough
+XMAILER_MIMEOLE_OL_3D61D
+
+# good enough
+XMAILER_MIMEOLE_OL_4B815
+
+# good enough
+XMAILER_MIMEOLE_OL_56DF6
+
+# good enough
+XMAILER_MIMEOLE_OL_58CB5
+
+# good enough
+XMAILER_MIMEOLE_OL_61ABB
+
+# good enough
+XMAILER_MIMEOLE_OL_62E6A
+
+# good enough
+XMAILER_MIMEOLE_OL_7533E
+
+# good enough
+XMAILER_MIMEOLE_OL_83BF7
+
+# good enough
+XMAILER_MIMEOLE_OL_91287
+
+# good enough
+XMAILER_MIMEOLE_OL_95A76
+
+# good enough
+XMAILER_MIMEOLE_OL_9B607
+
+# good enough
+XMAILER_MIMEOLE_OL_AA207
+
+# good enough
+XMAILER_MIMEOLE_OL_B4A6F
+
+# good enough
+XMAILER_MIMEOLE_OL_BC7E6
+
+# good enough
+XMAILER_MIMEOLE_OL_CAC8F
+
+# good enough
+XMAILER_MIMEOLE_OL_CE8A4
+
+# good enough
+XMAILER_MIMEOLE_OL_F3B05
+
+# good enough
+XMAILER_MIMEOLE_OL_F8BA4
+
+# good enough
+XM_OL_48072300
+
+# good enough
+XM_OL_49631700
+
 # tflags userconf
 UNPARSEABLE_RELAY
 
@@ -656,6 +839,9 @@
 URIBL_RED
 
 # tflags net
+URIBL_RHS_DOB
+
+# tflags net
 URIBL_SBL
 
 # tflags net
@@ -697,32 +883,281 @@
 # good enough
 VERTICAL_DRUGS_1
 
+# tflags net
+WHOIS_1AND1PR
+
+# tflags net
+WHOIS_AITPRIV
+
+# tflags net
+WHOIS_CONTACTPRIV
+
+# tflags net
+WHOIS_DMNBYPROXY
+
+# tflags net
+WHOIS_DOMESCROW
+
+# tflags net
+WHOIS_DOMPRIVCORP
+
+# tflags net
+WHOIS_DREAMPRIV
+
+# tflags net
+WHOIS_DROA
+
+# tflags net
+WHOIS_DYNADOT
+
+# tflags net
+WHOIS_FINEXE
+
+# tflags net
+WHOIS_GKGPROXY
+
+# tflags net
+WHOIS_IDSHIELD
+
+# tflags net
+WHOIS_IDTHEFTPROT
+
+# tflags net
+WHOIS_KATZ
+
+# tflags net
+WHOIS_LISTINGAG
+
+# tflags net
+WHOIS_LNOA
+
+# tflags net
+WHOIS_MAPNAME
+
+# tflags net
+WHOIS_MONIKER_PRIV
+
+# tflags net
+WHOIS_MYPRIVREG
+
+# tflags net
+WHOIS_NAMEKING
+
+# tflags net
+WHOIS_NAMESECURE
+
+# tflags net
+WHOIS_NETID
+
+# tflags net
+WHOIS_NETSOLPR
+
+# tflags net
+WHOIS_NOLDC
+
+# tflags net
+WHOIS_NOMINET
+
+# tflags net
+WHOIS_PRIVACYPOST
+
+# tflags net
+WHOIS_PRIVDOMAIN
+
+# tflags net
+WHOIS_PRIVPROT
+
+# tflags net
+WHOIS_REGISTER4LESS
+
+# tflags net
+WHOIS_REGISTERFLY
+
+# tflags net
+WHOIS_REGTEK
+
+# tflags net
+WHOIS_SAFENAMES
+
+# tflags net
+WHOIS_SECINFOSERV
+
+# tflags net
+WHOIS_SECUREWHOIS
+
+# tflags net
+WHOIS_SPAMFREE
+
+# tflags net
+WHOIS_SRSPLUS
+
+# tflags net
+WHOIS_UNLISTED
+
+# tflags net
+WHOIS_WHOISGUARD
+
+# tflags net
+WHOIS_WHOISPROT
+
 # good enough
-VERTICAL_WORDS_1
+XMAILER_MIMEOLE_OL_015D5
 
 # good enough
-ZMIde_EBAYJOBSURI
+XMAILER_MIMEOLE_OL_07794
 
 # good enough
-ZMIde_GIRLSRCH1
+XMAILER_MIMEOLE_OL_12589
 
 # good enough
-ZMIde_GIRLSRCH2
+XMAILER_MIMEOLE_OL_1ECD5
 
 # good enough
-ZMIde_LOVEGALX1
+XMAILER_MIMEOLE_OL_20CC2
 
 # good enough
-ZMIde_LOVEGALX2
+XMAILER_MIMEOLE_OL_22B61
 
 # good enough
-ZMIde_LOVEGALXURI
+XMAILER_MIMEOLE_OL_25340
 
 # good enough
-ZMIde_SEXUALEXPL1
+XMAILER_MIMEOLE_OL_2B374
+
+# good enough
+XMAILER_MIMEOLE_OL_32D97
+
+# good enough
+XMAILER_MIMEOLE_OL_3857F
+
+# good enough
+XMAILER_MIMEOLE_OL_3AC1D
+
+# good enough
+XMAILER_MIMEOLE_OL_465CD
+
+# good enough
+XMAILER_MIMEOLE_OL_4BF4C
 
 # good enough
-ZMIde_URIPORNWEB
+XMAILER_MIMEOLE_OL_4EEDB
+
+# good enough
+XMAILER_MIMEOLE_OL_4F240
+
+# good enough
+XMAILER_MIMEOLE_OL_5B79A
+
+# good enough
+XMAILER_MIMEOLE_OL_5E7ED
+
+# good enough
+XMAILER_MIMEOLE_OL_5EDD4
+
+# good enough
+XMAILER_MIMEOLE_OL_60256
+
+# good enough
+XMAILER_MIMEOLE_OL_6554A
+
+# good enough
+XMAILER_MIMEOLE_OL_681AD
+
+# good enough
+XMAILER_MIMEOLE_OL_72641
+
+# good enough
+XMAILER_MIMEOLE_OL_812FF
+
+# good enough
+XMAILER_MIMEOLE_OL_8627E
+
+# good enough
+XMAILER_MIMEOLE_OL_8E893
+
+# good enough
+XMAILER_MIMEOLE_OL_9B90B
+
+# good enough
+XMAILER_MIMEOLE_OL_A50F8
+
+# good enough
+XMAILER_MIMEOLE_OL_A842E
+
+# good enough
+XMAILER_MIMEOLE_OL_ADFF7
+
+# good enough
+XMAILER_MIMEOLE_OL_B30D1
+
+# good enough
+XMAILER_MIMEOLE_OL_B4B40
+
+# good enough
+XMAILER_MIMEOLE_OL_B9B11
+
+# good enough
+XMAILER_MIMEOLE_OL_C65FA
+
+# good enough
+XMAILER_MIMEOLE_OL_C7C33
+
+# good enough
+XMAILER_MIMEOLE_OL_C9068
+
+# good enough
+XMAILER_MIMEOLE_OL_CF0C0
+
+# good enough
+XMAILER_MIMEOLE_OL_D03AB
+
+# good enough
+XMAILER_MIMEOLE_OL_EF20B
+
+# good enough
+XMAILER_MIMEOLE_OL_EF222
+
+# good enough
+XMAILER_MIMEOLE_OL_F475E
+
+# good enough
+XMAILER_MIMEOLE_OL_F6D01
+
+# good enough
+XMAILER_MIMEOLE_OL_FF5C8
+
+# good enough
+XM_OL_28001441
+
+# good enough
+XM_OL_29196600
+
+# good enough
+XM_OL_29196700
+
+# good enough
+XM_OL_41332400
+
+# good enough
+XM_OL_48071700
+
+# good enough
+ZMIde_EBAYJOBSURI
+
+# good enough
+ZMIde_SEXUALEXPL1
+
+# tflags net
+__DNS_FROM_RFC_ABUSE
+
+# tflags net
+__DNS_FROM_RFC_POST
+
+# tflags net
+__DNS_FROM_RFC_WHOIS
+
+# tflags net
+__RCVD_IN_DOB
 
 # tflags net
 __RCVD_IN_IADB

Modified: spamassassin/branches/jm_re2c_hacks/rules/v320.pre
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/rules/v320.pre?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/rules/v320.pre (original)
+++ spamassassin/branches/jm_re2c_hacks/rules/v320.pre Wed Nov 15 12:40:35 2006
@@ -11,6 +11,9 @@
 #
 ###########################################################################
 
+# Check - Provides main check functionality
+loadplugin Mail::SpamAssassin::Plugin::Check
+
 # HTTPSMismatch - find URI mismatches between href and anchor text
 #
 loadplugin Mail::SpamAssassin::Plugin::HTTPSMismatch
@@ -36,8 +39,10 @@
 loadplugin Mail::SpamAssassin::Plugin::WLBLEval
 
 # Rule2XSBody - speedup by compilation of ruleset to native code
-loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody
+# loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody
 
 # RabinKarpBody - EXPERIMENTAL speedup plugin, requires RabinKarpAccel module
 # loadplugin Mail::SpamAssassin::Plugin::RabinKarpBody
 
+# P595Body - EXPERIMENTAL speedup plugin, using bleadperl RE optimizations
+# loadplugin Mail::SpamAssassin::Plugin::P595Body

Modified: spamassassin/branches/jm_re2c_hacks/sa-update.raw
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/sa-update.raw?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/sa-update.raw (original)
+++ spamassassin/branches/jm_re2c_hacks/sa-update.raw Wed Nov 15 12:40:35 2006
@@ -146,6 +146,7 @@
   'debug|D:s'                           => \$opt{'debug'},
   'version|V'                           => \$opt{'version'},
   'help|h|?'                            => \$opt{'help'},
+  'checkonly'                           => \$opt{'checkonly'},
 
   # allow multiple of these on the commandline
   'gpgkey=s'				=> $opt{'gpgkey'},
@@ -442,6 +443,13 @@
     next;
   }
 
+  # If we are only checking for update availability, exit now
+  if ( defined $opt{'checkonly'} ) {            
+    dbg("channel: $channel: update available, not downloading in checkonly mode");
+    $exit = 0;
+    next;
+  }
+
   # Read in the MIRRORED.BY file if it exists
   if (open(MIRBY, $mirby_path)) {
     local $/ = undef;
@@ -663,7 +671,7 @@
 Perhaps you need to import the channel's GPG key?  For example:
 
     wget http://spamassassin.apache.org/updates/GPG.KEY
-    gpg --import GPG.KEY
+    sa-update --import GPG.KEY
 
 ENDOFVALIDATIONERR
 
@@ -1278,12 +1286,10 @@
   --updatedir path		Directory to place updates, defaults to the
 				SpamAssassin site rules directory (def:
 				/var/lib/spamassassin/<version>)
-
   --channel channel		Retrieve updates from this channel
   				Use multiple times for multiple channels
   --channelfile file		Retrieve updates from the channels in the file
-
-
+  --checkonly		        Check for update availability, do not install
   --gpgkey key			Trust the key id to sign releases
   				Use multiple times for multiple keys
   --gpgkeyfile file		Trust the key ids in the file to sign releases
@@ -1293,7 +1299,6 @@
 				--gpgkey and --gpgkeyfile options)
   --import file			Import GPG key(s) from file into sa-update's
 				keyring. Use multiple times for multiple files
-
   -D, --debug [area=n,...]	Print debugging messages
   -V, --version			Print version
   -h, --help			Print usage message
@@ -1334,6 +1339,11 @@
 file instead of on the commandline.  This is extremely useful when there are a
 lot of additional channels.
 
+=item B<--checkonly>
+
+Only check if an update is available, don't actually download and install it.
+The exit code will be C<0> or C<1> as described below.
+
 =item B<--gpg>, B<--nogpg>
 
 sa-update by default will verify update archives by use of a SHA1 checksum
@@ -1423,7 +1433,7 @@
 =head1 EXIT CODES
 
 An exit code of C<0> means an update was available, and was downloaded and
-installed successfully.
+installed successfully if --checkonly was not specified.
 
 An exit code of C<1> means no fresh updates were available.
 

Modified: spamassassin/branches/jm_re2c_hacks/spamassassin.spec
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/spamassassin.spec?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/spamassassin.spec (original)
+++ spamassassin/branches/jm_re2c_hacks/spamassassin.spec Wed Nov 15 12:40:35 2006
@@ -64,8 +64,8 @@
 %package -n perl-Mail-SpamAssassin
 Summary:        %{pdir}::%{pnam} -- SpamAssassin e-mail filter Perl modules
 Summary(pl):    %{pdir}::%{pnam} -- modu³y Perla filtru poczty SpamAssassin
-Requires: perl >= 5.6.1 perl(HTML::Parser) perl(Digest::SHA1)
-BuildRequires: perl >= 5.6.1 perl(HTML::Parser) perl(Digest::SHA1)
+Requires: perl >= 5.6.1 perl(HTML::Parser) perl(Digest::SHA1) perl(Net::DNS)
+BuildRequires: perl >= 5.6.1 perl(HTML::Parser) perl(Digest::SHA1) perl(Net::DNS)
 Group:          Development/Libraries
 
 %description -n perl-Mail-SpamAssassin

Modified: spamassassin/branches/jm_re2c_hacks/spamd/spamd.raw
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/spamd/spamd.raw?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/spamd/spamd.raw (original)
+++ spamassassin/branches/jm_re2c_hacks/spamd/spamd.raw Wed Nov 15 12:40:35 2006
@@ -244,6 +244,7 @@
   'socketpath=s'             => \$opt{'socketpath'},
   'sql-config!'              => \$opt{'sql-config'},
   'ssl'                      => \$opt{'ssl'},
+  'ssl-port=s'               => \$opt{'ssl-port'},
   'syslog-socket=s'          => \$opt{'syslog-socket'},
   'syslog|s=s'               => \$opt{'syslog'},
   'timeout-tcp|T=i'          => \$opt{'timeout-tcp'},
@@ -311,20 +312,39 @@
   ) if ( $opt{$opt} );
 }
 
-# sanity checking on parameters: if --socketpath is used, it means that we're using
-# UNIX domain sockets, none of the IP params are allowed. The code would probably
-# work ok if we didn't check it, but it's better if we detect the error and report
-# it lest the admin find surprises.
+# sanity checking on parameters: if --socketpath is used, and --port or
+# --ssl-port is NOT specified, it means that we're using UNIX domain sockets,
+# none of the IP params are allowed. The code would probably work ok if we
+# didn't check it, but it's better if we detect the error and report it lest
+# the admin find surprises.
+
+my $listen_unix = 1;
+my $listen_inet = 1;
+my $listen_ssl  = 0;
+if (!defined $opt{'socketpath'}) {
+  $listen_unix = 0;
+} else {
+  $listen_inet = 0;
+}
 
 if (
-  defined $opt{'socketpath'}
-  and ( ( @{ $opt{'allowed-ip'} } > 0 )
-    or defined $opt{'ssl'}
+  ( @{ $opt{'allowed-ip'} } > 0 )
     or defined $opt{'auth-ident'}
-    or defined $opt{'port'} )
+    or defined $opt{'port'}
   )
 {
-  print_usage_and_exit("ERROR: --socketpath mutually exclusive with --allowed-ip/--ssl/--port params");
+  $listen_inet = 1;
+}
+
+if (
+    defined $opt{'ssl'}
+    or defined $opt{'ssl-port'}
+  )
+{
+  $listen_ssl = 1;
+  if (!defined $opt{'ssl-port'}) {
+    $listen_inet = 0;
+  }
 }
 
 if (
@@ -361,7 +381,7 @@
 # Check for server certs
 $opt{'server-key'}  ||= "$LOCAL_RULES_DIR/certs/server-key.pem";
 $opt{'server-cert'} ||= "$LOCAL_RULES_DIR/certs/server-cert.pem";
-if ( $opt{'ssl'} ) {
+if ( $listen_ssl ) {
   eval { require IO::Socket::SSL };
   die "spamd: SSL encryption requested, but IO::Socket::SSL is unavailable\n"
     if ($@);
@@ -549,13 +569,9 @@
 
 # Do whitelist later in tmp dir. Side effect: this will be done as -u user.
 
-my ( $port, $addr, $proto );
-my ($listeninfo);              # just for reporting
+my ( $sslport, $inetport, $addr, $proto );
 
-if ( defined $opt{'socketpath'} ) {
-  $listeninfo = "UNIX domain socket " . $opt{'socketpath'};
-}
-else {
+if ( $listen_inet || $listen_ssl ) {
   $proto = getprotobyname('tcp') or die "getprotobyname(tcp): $!";
 
   $addr = $opt{'listen-ip'};
@@ -571,16 +587,37 @@
   else {
     $addr = '127.0.0.1';
   }
+}
+
+my @listeninfo = ();
+
+if ( $listen_unix ) {
+  push @listeninfo, "UNIX domain socket " . $opt{'socketpath'};
+}
+
+if ( $listen_ssl ) {
+  $sslport = $opt{'ssl-port'} || $opt{'port'} || 783;
+  if ($sslport !~ /^(\d+)$/ ) {
+    $sslport = ( getservbyname($sslport, 'tcp') )[2];
+    die "spamd: invalid ssl-port: $opt{'port'}\n" unless $sslport;
+  }
+
+  push @listeninfo, "SSL port $sslport/tcp";
+}
 
-  $port = $opt{'port'} || 783;
-  if ($port !~ /^(\d+)$/ ) {
-    $port = ( getservbyname($port, 'tcp') )[2];
-    die "spamd: invalid port: $opt{'port'}\n" unless $port;
+if ( $listen_inet ) {
+  $inetport = $opt{'port'} || 783;
+  if ($inetport !~ /^(\d+)$/ ) {
+    $inetport = ( getservbyname($inetport, 'tcp') )[2];
+    die "spamd: invalid port: $opt{'port'}\n" unless $inetport;
   }
 
-  $listeninfo = "port $port/tcp";
+  push @listeninfo, "port $inetport/tcp";
 }
 
+# just for reporting at startup
+my $listeninfo = join ', ', @listeninfo;
+
 my $backchannel = Mail::SpamAssassin::SubProcBackChannel->new();
 my $scaling;
 if (!$opt{'round-robin'})
@@ -604,9 +641,13 @@
       });
 }
 
-# Be a well-behaved daemon
-my $server;
-if ( $opt{'socketpath'} ) {
+my ( $server_inet, $server_unix, $server_ssl );
+my ( $fd_inet, $fd_unix, $fd_ssl );
+my $have_multiple_server_socks;
+my $server_select_mask;
+
+# Create the sockets
+if ( $listen_unix ) {
   my $path = $opt{'socketpath'};
 
   #---------------------------------------------------------------------
@@ -642,15 +683,15 @@
     Listen => SOMAXCONN,
   );
   dbg("spamd: creating UNIX socket:\n" . join("\n", map { " $_: " . (defined $socket{$_} ? $socket{$_} : "(undef)") } sort keys %socket));
-  $server = IO::Socket::UNIX->new(%socket);
+  $server_unix = IO::Socket::UNIX->new(%socket);
   
   # sanity check!  cf. bug 3490
-  if (not $server or not -S $path) {
-    unless ($server) {
+  if (not $server_unix or not -S $path) {
+    unless ($server_unix) {
       dbg "spamd: socket path might have been truncated due to system limits\n";
       die "spamd: could not create UNIX socket on $path: $!\n";
     }
-    my $hostpath = $server->hostpath();
+    my $hostpath = $server_unix->hostpath();
     if ($hostpath ne $path) {
       warn "spamd: socket path was truncated at position " . length($hostpath) . "\n";
       warn "spamd: leaving stale socket at $hostpath\n" if -S $hostpath;
@@ -692,10 +733,11 @@
     die "spamd: could not chmod $path to $mode: $!";
   }
 }
-elsif ( $opt{'ssl'} ) {
+
+if ( $listen_ssl ) {
   my %socket = (
     LocalAddr       => $addr,
-    LocalPort       => $port,
+    LocalPort       => $sslport,
     Proto           => $proto,
     Type            => SOCK_STREAM,
     ReuseAddr       => 1,
@@ -705,23 +747,27 @@
     SSL_cert_file   => $opt{'server-cert'}
   );
   dbg("spamd: creating SSL socket:\n" . join("\n", map { " $_:  " . (defined $socket{$_} ? $socket{$_} : "(undef)") } sort keys %socket));
-  $server = new IO::Socket::SSL(%socket)
-       || die "spamd: could not create SSL socket on $addr:$port: $!\n";
+  $server_ssl = new IO::Socket::SSL(%socket)
+       || die "spamd: could not create SSL socket on $addr:$sslport: $!\n";
 }
-else {
+
+if ( $listen_inet ) {
   my %socket = (
     LocalAddr => $addr,
-    LocalPort => $port,
+    LocalPort => $inetport,
     Proto     => $proto,
     Type      => SOCK_STREAM,
     ReuseAddr => 1,
     Listen    => SOMAXCONN
   );
   dbg("spamd: creating INET socket:\n" . join("\n", map { " $_: " . (defined $socket{$_} ? $socket{$_} : "(undef)") } sort keys %socket));
-  $server = new_io_socket_inetx(%socket)
-       || die "spamd: could not create INET socket on $addr:$port: $!\n";
+  $server_inet = new_io_socket_inetx(%socket)
+       || die "spamd: could not create INET socket on $addr:$inetport: $!\n";
 }
 
+# for select() purposes: make a map of the server socket FDs
+map_server_sockets();
+
 if ( defined $opt{'pidfile'} ) {
   $opt{'pidfile'} =
     Mail::SpamAssassin::Util::untaint_file_path( $opt{'pidfile'} );
@@ -793,10 +839,6 @@
 my $current_msgid = "(none)";
 $SIG{USR2} = \&backtrace_handler;
 
-my $select_mask = '';
-vec($select_mask, $server->fileno, 1) = 1;
-$backchannel->set_selector(\$select_mask);
-
 # log server started, but processes watching the log to wait for connect
 # should wait until they see the pid, after signal handlers are in place
 # FIXME: two calls are one too much
@@ -826,7 +868,7 @@
 }
 
 if ($scaling) {
-  $scaling->set_server_fh($server);
+  $scaling->set_server_fh($server_inet, $server_unix, $server_ssl);
 }
 
 while (1) {
@@ -1020,8 +1062,37 @@
   }
 }
 
+sub accept_from_any_server_socket {
+
+  my $fdvec = $server_select_mask;
+
+  if ($have_multiple_server_socks) {
+    # determine which of our server FDs is ready using select().
+    # We only need to do this if we have more than one server
+    # socket supported, since otherwise there can only be one socket
+    # with a client waiting.
+    # (TODO: we could extend the prefork protocol to pass this data)
+    my $nfound = select($fdvec, undef, undef, 0.1);
+    die "oops? accept_a_conn: no fds ready" unless $nfound;
+  }
+
+  if ($fd_inet && vec $fdvec, $fd_inet, 1) {
+    $client = $server_inet->accept;
+  }
+  elsif ($fd_unix && vec $fdvec, $fd_unix, 1) {
+    $client = $server_unix->accept;
+  }
+  elsif ($fd_ssl && vec $fdvec, $fd_ssl, 1) {
+    $client = $server_ssl->accept;
+  }
+  else {
+    die "accept_a_conn: no fds ready by vec: $fdvec";
+  }
+  return $client;
+}
+
 sub accept_a_conn {
-  $client = $server->accept();
+  $client = accept_from_any_server_socket();
 
   if ($scaling) {
     $scaling->update_child_status_busy();
@@ -1035,7 +1106,7 @@
     if ( $! == &Errno::EINTR ) {
       return 0;
     }
-    elsif ( $! == 0 && $opt{'ssl'} ) {
+    elsif ( $! == 0 && $listen_ssl ) {
       warn("spamd: SSL failure: " . &IO::Socket::SSL::errstr());
       return 0;
     }
@@ -2023,7 +2094,9 @@
 sub kill_handler {
   my ($sig) = @_;
   info("spamd: server killed by SIG$sig, shutting down");
-  $server->close;
+  $server_inet and $server_inet->close;
+  $server_unix and $server_unix->close;
+  $server_ssl  and $server_ssl->close;
 
   if (defined($opt{'pidfile'})) {
     unlink($opt{'pidfile'}) || warn "spamd: cannot unlink $opt{'pidfile'}: $!\n";
@@ -2094,16 +2167,25 @@
   }
   %children = ();
 
-  unless ( $server->eof ) {
-    $server->shutdown(2);
-    $server->close;
+  unless ( !$server_inet || $server_inet->eof ) {
+    $server_inet->shutdown(2);
+    $server_inet->close;
+    info("spamd: server INET socket closed");
+  }
 
-    # the UNIX domain socket
+  unless ( !$server_unix || $server_unix->eof ) {
+    $server_unix->shutdown(2);
+    $server_unix->close;
     if (defined($opt{'socketpath'})) {
       unlink($opt{'socketpath'}) || warn "spamd: cannot unlink $opt{'socketpath'}: $!\n";
     }
+    info("spamd: server UNIX socket closed");
+  }
 
-    info("spamd: server socket closed");
+  unless ( !$server_ssl || $server_ssl->eof ) {
+    $server_ssl->shutdown(2);
+    $server_ssl->close;
+    info("spamd: server SSL socket closed");
   }
   $got_sighup = 1;
 }
@@ -2203,6 +2285,26 @@
   }
 }
 
+sub map_server_sockets {
+  $fd_inet = $server_inet ? $server_inet->fileno : undef;
+  $fd_unix = $server_unix ? $server_unix->fileno : undef;
+  $fd_ssl  = $server_ssl  ? $server_ssl->fileno  : undef;
+
+  $server_select_mask = '';
+  $server_inet and vec($server_select_mask, $fd_inet, 1) = 1;
+  $server_unix and vec($server_select_mask, $fd_unix, 1) = 1;
+  $server_ssl  and vec($server_select_mask, $fd_ssl,  1) = 1;
+
+  my $back_selector = $server_select_mask;
+  $backchannel->set_selector(\$back_selector);
+
+  # and set a boolean indicating whether or not we have > 1 server socket
+  $have_multiple_server_socks =
+      ((defined $fd_inet ? 1 : 0) +
+      (defined $fd_unix ? 1 : 0) +
+      (defined $fd_ssl  ? 1 : 0)) > 1;
+}
+
 __DATA__
 
 =head1 NAME
@@ -2257,6 +2359,7 @@
  -P, --paranoid                     Die upon user errors
  -H [dir], --helper-home-dir[=dir]  Specify a different HOME directory
  --ssl                              Run an SSL server
+ --ssl-port port                    Listen on port for SSL connections
  --server-key keyfile               Specify an SSL keyfile
  --server-cert certfile             Specify an SSL certificate
  --socketpath=path                  Listen on given UNIX domain socket
@@ -2349,6 +2452,13 @@
 
 Optionally specifies the port number for the server to listen on (default: 783).
 
+If the B<--ssl> switch is used, and B<--ssl-port> is not supplied, then this
+port will be used to accept SSL connections instead of unencrypted connections.
+If the B<--ssl> switch is used, and B<--ssl-port> is set, then unencrypted
+connections will be accepted on the B<--port> at the same time as encrypted
+connections are accepted at B<--ssl-port>.
+
+
 =item B<-q>, B<--sql-config>
 
 Turn on SQL lookups even when per-user config files have been disabled
@@ -2654,6 +2764,18 @@
 Accept only SSL connections.  The B<IO::Socket::SSL> perl module must be
 installed.
 
+If the B<--ssl> switch is used, and B<--ssl-port> is not supplied, then
+B<--port> port will be used to accept SSL connections instead of unencrypted
+connections.  If the B<--ssl> switch is used, and B<--ssl-port> is set, then
+unencrypted connections will be accepted on the B<--port>, at the same time as
+encrypted connections are accepted at B<--ssl-port>.
+
+=item B<--ssl-port>=I<port>
+
+Optionally specifies the port number for the server to listen on for
+SSL connections (default: whatever --port uses).  See B<--ssl> for
+more details.
+
 =item B<--server-key> I<keyfile>
 
 Specify the SSL key file to use for SSL connections.
@@ -2671,6 +2793,10 @@
 you see a 'could not find newly-created UNIX socket' error message, and the
 path appears truncated, this may be the cause.  Try using a shorter path
 to the socket.
+
+By default, use of B<--socketpath> will inhibit SSL connections and unencrypted
+TCP connections.  To enable them, specify B<--port> and/or B<--ssl-port>
+explicitly.
 
 =item B<--socketowner> I<name>
 

Modified: spamassassin/branches/jm_re2c_hacks/t/SATest.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/t/SATest.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/t/SATest.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/t/SATest.pm Wed Nov 15 12:40:35 2006
@@ -449,6 +449,12 @@
         # Yes, DO retry on this error. I'm getting test failures otherwise
         # /Address already in use/ and $retries = 0;
 	/server pid: (\d+)/ and $spamd_pid = $1;
+
+        if (/ERROR/) {
+          warn "spamd error! $_";
+          $retries = 0; last;
+        }
+
 	$spamdlog .= $_;
       }
       close IN;

Modified: spamassassin/branches/jm_re2c_hacks/t/get_headers.t
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/t/get_headers.t?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/t/get_headers.t (original)
+++ spamassassin/branches/jm_re2c_hacks/t/get_headers.t Wed Nov 15 12:40:35 2006
@@ -21,7 +21,7 @@
 
 use Mail::SpamAssassin;
 
-plan tests => 11;
+plan tests => 13;
 
 ##############################################
 
@@ -41,6 +41,10 @@
 To8: "'Foo Blah'" <jm...@foo>
 To9: "_$B!z8=6b$=$N>l$GEv$?$j!*!zEv_(B_$B$?$k!*!)$/$8!z7|>^%\%s%P!<!z_(B" <jm...@foo>
 To10: "Some User" <"Some User"@foo>
+Hdr1:    foo  
+  bar
+	baz 
+  
 To11: "Some User"@foo
 
 Blah!
@@ -67,7 +71,9 @@
   if ($expect eq $result) {
     return 1;
   } else {
-    warn "try: '$try' failed! expect: '$expect' got: '$result'\n";
+    my $le=$expect;$le=~s/\t/\\t/gs;$le =~s/\n/\\n/gs;
+    my $lr=$result;$lr=~s/\t/\\t/gs;$lr =~s/\n/\\n/gs;
+    warn "try: '$try' failed! expect: '$le' got: '$lr'\n";
     return 0;
   }
 }
@@ -83,4 +89,6 @@
 ok(try('To9:addr', 'jm@foo'));
 ok(try('To10:addr', '"Some User"@foo'));
 ok(try('To11:addr', '"Some User"@foo'));
+ok(try('Hdr1', "foo   bar baz\n"));
+ok(try('Hdr1:raw', "    foo  \n  bar\n\tbaz \n  \n"));
 

Modified: spamassassin/branches/jm_re2c_hacks/t/lang_pl_tests.t
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/t/lang_pl_tests.t?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/t/lang_pl_tests.t (original)
+++ spamassassin/branches/jm_re2c_hacks/t/lang_pl_tests.t Wed Nov 15 12:40:35 2006
@@ -8,7 +8,7 @@
 
 %patterns = (
 
-q{ X-Spam-Status: No, }, 'didnt_hang_at_least',
+q{ X-Spam-Status: }, 'didnt_hang_at_least',
 
 );
 

Modified: spamassassin/branches/jm_re2c_hacks/t/mkrules.t
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/t/mkrules.t?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/t/mkrules.t (original)
+++ spamassassin/branches/jm_re2c_hacks/t/mkrules.t Wed Nov 15 12:40:35 2006
@@ -2,7 +2,7 @@
 
 use lib '.'; use lib 't';
 use SATest; sa_t_init("mkrules");
-use Test; BEGIN { plan tests => 101 };
+use Test; BEGIN { plan tests => 81 };
 use File::Path;
 
 # ---------------------------------------------------------------------------
@@ -212,49 +212,6 @@
 save_tdir();
 
 # ---------------------------------------------------------------------------
-print " active plugin in core\n\n";
-
-%patterns = (
-  '70_sandbox.cf: WARNING: not listed in manifest file' => manif_found,
-  "loadplugin Good plugin.pm" => loadplugin_found,
-  "body GOOD eval:check_foo()"   => rule_line_1,
-  "describe GOOD desc_found"  => rule_line_2,
-  "ifplugin Good" => if1,
-  "endif" => endif_found,
-);
-%anti_patterns = (
-  "describe T_GOOD desc_found"  => rule_line_2,
-);
-
-mkpath ([ "$tdir/rulesrc/core", "$tdir/rules", ]);
-
-write_file("$tdir/MANIFEST", [ "rulesrc/core/20_foo.cf\n", "rulesrc/core/plugin.pm\n" ]);
-write_file("$tdir/MANIFEST.SKIP", [ "foo2\n" ]);
-write_file("$tdir/rules/active.list", [ "GOOD\n" ]);
-write_file("$tdir/rulesrc/core/20_foo.cf", [
-    "loadplugin Good plugin.pm\n",
-    "ifplugin Good\n",
-    "body GOOD eval:check_foo()\n",
-    "describe GOOD desc_found\n",
-    "endif\n",
-]);
-write_file("$tdir/rulesrc/core/plugin.pm", [
-    'package Good;',
-    'use Mail::SpamAssassin::Plugin; our @ISA = qw(Mail::SpamAssassin::Plugin);',
-    'sub new { my ($class, $m) = @_; $class = ref($class) || $class;',
-    'my $self = bless $class->SUPER::new($m), $class;',
-    '$self->register_eval_rule("check_foo"); return $self; }',
-    'sub check_foo { my ($self, $pms) = @_; return 1; }',
-]);
-
-ok (mkrun ("--src $tdir/rulesrc --out $tdir/rules --manifest $tdir/MANIFEST --manifestskip $tdir/MANIFEST.SKIP --active $tdir/rules/active.list 2>&1", \&patterns_run_cb));
-checkfile("$tdir/rules/72_active.cf", \&patterns_run_cb);
-# checkfile("$tdir/rules/70_sandbox.cf", \&patterns_run_cb);
-ok (-f "$tdir/rules/plugin.pm");
-ok ok_all_patterns();
-save_tdir();
-
-# ---------------------------------------------------------------------------
 print " inactive plugin\n\n";
 
 %patterns = (
@@ -298,51 +255,6 @@
 ok ok_all_patterns();
 save_tdir();
 
-
-# ---------------------------------------------------------------------------
-print " inactive plugin in non-sandbox\n\n";
-
-%patterns = (
-  '70_inactive.cf: WARNING: not listed in manifest file' => manif_found,
-  "loadplugin Good plugin.pm" => loadplugin_found,
-  "ifplugin Good" => if1,
-  "body GOOD eval:check_foo()" => rule_line_1,
-  "describe GOOD desc_found" => rule_line_2,
-  "endif" => endif_found,
-);
-%anti_patterns = (
-  "describe T_GOOD desc_found"  => rule_line_2,
-);
-
-rmtree([ $tdir ]);
-mkpath ([ "$tdir/rulesrc/core", "$tdir/rules" ]);
-
-write_file("$tdir/MANIFEST", [ "rulesrc/sandbox/foo/20_foo.cf\n", "rulesrc/sandbox/foo/plugin.pm\n" ]);
-write_file("$tdir/MANIFEST.SKIP", [ "foo2\n" ]);
-write_file("$tdir/rules/active.list", [ "NOT_GOOD\n" ]);
-write_file("$tdir/rulesrc/core/20_foo.cf", [
-    "loadplugin Good plugin.pm\n",
-    "ifplugin Good\n",
-    "body GOOD eval:check_foo()\n",
-    "describe GOOD desc_found\n",
-    "endif\n",
-]);
-write_file("$tdir/rulesrc/core/plugin.pm", [
-    'package Good;',
-    'use Mail::SpamAssassin::Plugin; our @ISA = qw(Mail::SpamAssassin::Plugin);',
-    'sub new { my ($class, $m) = @_; $class = ref($class) || $class;',
-    'my $self = bless $class->SUPER::new($m), $class;',
-    '$self->register_eval_rule("check_foo"); return $self; }',
-    'sub check_foo { my ($self, $pms) = @_; return 1; }',
-]);
-
-ok (mkrun ("--src $tdir/rulesrc --out $tdir/rules --manifest $tdir/MANIFEST --manifestskip $tdir/MANIFEST.SKIP --active $tdir/rules/active.list 2>&1", \&patterns_run_cb));
-# checkfile("$tdir/rules/70_sandbox.cf", \&patterns_run_cb);
-# checkfile("$tdir/rules/72_active.cf", \&patterns_run_cb);
-checkfile("$tdir/rules/70_inactive.cf", \&patterns_run_cb);
-ok (-f "$tdir/rules/plugin.pm");
-ok ok_all_patterns();
-save_tdir();
 
 # ---------------------------------------------------------------------------
 print " active plugin, but the .pm file is AWOL\n\n";