~ubuntu-branches/ubuntu/utopic/spamassassin/utopic-updates

« back to all changes in this revision

Viewing changes to lib/Mail/SpamAssassin/ArchiveIterator.pm

  • Committer: Package Import Robot
  • Author(s): Noah Meyerhans
  • Date: 2014-02-14 22:45:15 UTC
  • mfrom: (0.8.1) (0.6.2) (5.1.22 sid)
  • Revision ID: package-import@ubuntu.com-20140214224515-z1es2twos8xh7n2y
Tags: 3.4.0-1
* New upstream version! (Closes: 738963, 738872, 738867)
* Scrub the environment when switching to the debian-spamd user in
  postinst and cron.daily. (Closes: 738951)
* Enhancements to postinst to better manage ownership of
  /var/lib/spamassassin, via Iain Lane <iain.lane@canonical.com>
  (Closes: 738974)

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
use Mail::SpamAssassin::Logger;
31
31
use Mail::SpamAssassin::AICache;
32
32
 
33
 
use constant BIG_BYTES => 256*1024;     # 256k is a big email
34
 
use constant BIG_LINES => BIG_BYTES/65; # 65 bytes/line is a good approximation
 
33
# 256 KiB is a big email, unless stated otherwise
 
34
use constant BIG_BYTES => 256*1024;
35
35
 
36
36
use vars qw {
37
37
  $MESSAGES
50
50
 
51
51
  my $iter = new Mail::SpamAssassin::ArchiveIterator(
52
52
    { 
53
 
      'opt_all'   => 1,
 
53
      'opt_max_size' => 256 * 1024,  # 0 implies no limit
54
54
      'opt_cache' => 1,
55
55
    }
56
56
  );
90
90
 
91
91
=over 4
92
92
 
 
93
=item opt_max_size
 
94
 
 
95
A value of option I<opt_max_size> determines a limit (number of bytes)
 
96
beyond which a message is considered large and is skipped by ArchiveIterator.
 
97
 
 
98
A value 0 implies no size limit, all messages are examined. An undefined
 
99
value implies a default limit of 256 KiB.
 
100
 
93
101
=item opt_all
94
102
 
95
 
Typically messages over 250k are skipped by ArchiveIterator.  Use this option
96
 
to keep from skipping messages based on size.
 
103
Setting this option to true implicitly sets I<opt_max_size> to 0, i.e.
 
104
no limit of a message size, all messages are processes by ArchiveIterator.
 
105
For compatibility with SpamAssassin versions older than 3.4.0 which
 
106
lacked option I<opt_max_size>.
97
107
 
98
108
=item opt_scanprob
99
109
 
168
178
the 'scan' phase of the mass-check.  No guarantees are made as to
169
179
how frequently this may happen, mind you.
170
180
 
 
181
=item opt_from_regex
 
182
 
 
183
This setting allows for flexibility in specifying the mbox format From seperator.
 
184
 
 
185
It defaults to the regular expression:
 
186
 
 
187
/^From \S+  ?(\S\S\S \S\S\S .\d .\d:\d\d:\d\d \d{4}|.\d-\d\d-\d{4}_\d\d:\d\d:\d\d_)/
 
188
 
 
189
Some SpamAssassin programs such as sa-learn will use the configuration option 
 
190
'mbox_format_from_regex' to override the default regular expression.
 
191
 
171
192
=back
172
193
 
173
194
=cut
191
212
 
192
213
  $self->{access_problem} = 0;
193
214
 
 
215
  if ($self->{opt_all}) {
 
216
    $self->{opt_max_size} = 0;
 
217
  } elsif (!defined $self->{opt_max_size}) {
 
218
    $self->{opt_max_size} = BIG_BYTES;
 
219
  }
 
220
 
194
221
  $self;
195
222
}
196
223
 
343
370
    return;
344
371
  }
345
372
 
346
 
  if ($self->{opt_all}) {
 
373
  my $opt_max_size = $self->{opt_max_size};
 
374
  if (!$opt_max_size) {
347
375
    # process any size
348
376
  } elsif (!-f _) {
349
377
    # must check size while reading
350
 
  } elsif (-s _ > BIG_BYTES) {
 
378
  } elsif (-s _ > $opt_max_size) {
351
379
    # skip too-big mails
352
380
    # note that -s can only deal with files, it returns 0 on char.spec. STDIN
353
 
    info("archive-iterator: skipping large message\n");
 
381
    info("archive-iterator: skipping large message: ".
 
382
         "file size %d, limit %d bytes", -s _, $opt_max_size);
354
383
    close INPUT  or die "error closing input file: $!";
355
384
    return;
356
385
  }
362
391
  my($inbuf,$nread);
363
392
  while ( $nread=read(INPUT,$inbuf,16384) ) {
364
393
    $len += $nread;
365
 
    if (($len > BIG_BYTES) && !$self->{opt_all}) {
366
 
      info("archive-iterator: skipping large message\n");
 
394
    if ($opt_max_size && $len > $opt_max_size) {
 
395
      info("archive-iterator: skipping large message: read %d, limit %d bytes",
 
396
           $len, $opt_max_size);
367
397
      close INPUT  or die "error closing input file: $!";
368
398
      return;
369
399
    }
394
424
    $self->{access_problem} = 1;
395
425
    return;
396
426
  }
 
427
 
 
428
  my $opt_max_size = $self->{opt_max_size};
 
429
  dbg("archive-iterator: _run_mailbox %s, ofs %d, limit %d",
 
430
      $file, $offset, $opt_max_size||0);
 
431
 
397
432
  seek(INPUT,$offset,0)  or die "cannot reposition file to $offset: $!";
 
433
 
 
434
  my $size = 0;
398
435
  for ($!=0; <INPUT>; $!=0) {
399
 
    last if (substr($_,0,5) eq "From " && @msg && /^From \S+  ?\S\S\S \S\S\S .\d .\d:\d\d:\d\d \d{4}/);
 
436
    #Changed Regex to use option Per bug 6703
 
437
    last if (substr($_,0,5) eq "From " && @msg && /$self->{opt_from_regex}/o);
 
438
    $size += length($_);
400
439
    push (@msg, $_);
401
440
 
402
 
    # skip too-big mails
403
 
    if (! $self->{opt_all} && @msg > BIG_LINES) {
404
 
      info("archive-iterator: skipping large message\n");
 
441
    # skip mails that are too big
 
442
    if ($opt_max_size && $size > $opt_max_size) {
 
443
      info("archive-iterator: skipping large message: ".
 
444
           "%d lines, %d bytes, limit %d bytes",
 
445
           scalar @msg, $size, $opt_max_size);
405
446
      close INPUT  or die "error closing input file: $!";
406
447
      return;
407
448
    }
434
475
    return;
435
476
  }
436
477
 
 
478
  my $opt_max_size = $self->{opt_max_size};
 
479
  dbg("archive-iterator: _run_mbx %s, ofs %d, limit %d",
 
480
      $file, $offset, $opt_max_size||0);
 
481
 
437
482
  seek(INPUT,$offset,0)  or die "cannot reposition file to $offset: $!";
438
483
    
 
484
  my $size = 0;
439
485
  for ($!=0; <INPUT>; $!=0) {
440
486
    last if ($_ =~ MBX_SEPARATOR);
 
487
    $size += length($_);
441
488
    push (@msg, $_);
442
489
 
443
490
    # skip mails that are too big
444
 
    if (! $self->{opt_all} && @msg > BIG_LINES) {
445
 
      info("archive-iterator: skipping large message\n");
 
491
    if ($opt_max_size && $size > $opt_max_size) {
 
492
      info("archive-iterator: skipping large message: ".
 
493
           "%d lines, %d bytes, limit %d bytes",
 
494
           scalar @msg, $size, $opt_max_size);
446
495
      close INPUT  or die "error closing input file: $!";
447
496
      return;
448
497
    }
611
660
 
612
661
sub _set_default_message_selection_opts {
613
662
  my ($self) = @_;
 
663
 
614
664
  $self->{opt_scanprob} = 1.0 unless (defined $self->{opt_scanprob});
615
665
  $self->{opt_want_date} = 1 unless (defined $self->{opt_want_date});
616
666
  $self->{opt_cache} = 0 unless (defined $self->{opt_cache});
 
667
  #Changed Regex to include boundaries for Communigate Pro versions (5.2.x and later). per Bug 6413
 
668
  $self->{opt_from_regex} = '^From \S+  ?(\S\S\S \S\S\S .\d .\d:\d\d:\d\d \d{4}|.\d-\d\d-\d{4}_\d\d:\d\d:\d\d_)' unless (defined $self->{opt_from_regex});
 
669
 
 
670
  #STRIP LEADING AND TRAILING / FROM REGEX FOR OPTION
 
671
  $self->{opt_from_regex} =~ s/^\///;
 
672
  $self->{opt_from_regex} =~ s/\/$//;
 
673
 
 
674
  dbg("archive-iterator: _set_default_message_selection_opts After: Scanprob[$self->{opt_scanprob}], want_date[$self->{opt_want_date}], cache[$self->{opt_cache}], from_regex[$self->{opt_from_regex}]");
 
675
 
617
676
}
618
677
 
619
678
############################################################################
747
806
      warn "archive-iterator: $file is not a plain file or directory: $!";
748
807
    }
749
808
  }
750
 
  @files = ();  # release storage
 
809
  undef @files;  # release storage
751
810
 
752
811
  # recurse into directories
753
812
  foreach my $dir (@subdirs) {
908
967
              $header .= $_;
909
968
            }
910
969
          }
911
 
          if (substr($_,0,5) eq "From " &&
912
 
              /^From \S+  ?\S\S\S \S\S\S .\d .\d:\d\d:\d\d \d{4}/) {
 
970
          #Changed Regex to use option Per bug 6703
 
971
          if (substr($_,0,5) eq "From " && /$self->{opt_from_regex}/o) {
913
972
            $in_header = 1;
914
973
            $first = $_;
915
974
            $start = $where;