~ubuntu-branches/ubuntu/utopic/spamassassin/utopic-proposed

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Noah Meyerhans
  • Date: 2010-01-26 22:53:12 UTC
  • mfrom: (1.1.13 upstream) (5.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100126225312-wkftb10idc1kz2aq
Tags: 3.3.0-1
* New upstream version.
* Switch to dpkg-source 3.0 (quilt) format

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
use File::Spec;
39
39
use File::Path;
40
40
use File::Basename;
 
41
use Mail::SpamAssassin::Logger;
41
42
 
42
43
use strict;
43
44
use warnings;
 
45
use re 'taint';
 
46
use Errno qw(EBADF);
44
47
 
45
48
=item new()
46
49
 
69
72
                File::Spec->rel2abs($self->{path}),
70
73
                '.spamassassin_cache');
71
74
 
72
 
    $self->{cache_mtime} = (stat($self->{cache_file}))[9] || 0;
 
75
    my @stat = stat($self->{cache_file});
 
76
    @stat  or dbg("AIcache: no access to %s: %s", $self->{cache_file}, $!);
 
77
    $self->{cache_mtime} = $stat[9] || 0;
73
78
  }
74
79
  else {
75
80
    my @split = File::Spec->splitpath($self->{path});
78
83
                File::Spec->rel2abs($split[1]),
79
84
                join('_', '.spamassassin_cache', $self->{type}, $split[2]));
80
85
 
81
 
    $self->{cache_mtime} = (stat($self->{cache_file}))[9] || 0;
 
86
    my @stat = stat($self->{cache_file});
 
87
    @stat  or dbg("AIcache: no access to %s: %s", $self->{cache_file}, $!);
 
88
    $self->{cache_mtime} = $stat[9] || 0;
82
89
 
83
90
    # for mbox and mbx, verify whether mtime on cache file is >= mtime of
84
91
    # messages file.  if it is, use it, otherwise don't.
85
 
    if ((stat($self->{path}))[9] > $self->{cache_mtime}) {
 
92
    @stat = stat($self->{path});
 
93
    @stat  or dbg("AIcache: no access to %s: %s", $self->{path}, $!);
 
94
    if ($stat[9] > $self->{cache_mtime}) {
86
95
      $use_cache = 0;
87
96
    }
88
97
  }
89
98
  $self->{cache_file} = File::Spec->canonpath($self->{cache_file});
90
99
 
91
100
  # go ahead and read in the cache information
92
 
  if ($use_cache && open(CACHE, $self->{cache_file})) {
93
 
    while(defined($_=<CACHE>)) {
 
101
  local *CACHE;
 
102
  if (!$use_cache) {
 
103
    # not in use
 
104
  } elsif (!open(CACHE, $self->{cache_file})) {
 
105
    dbg("AIcache: cannot open AI cache file (%s): %s", $self->{cache_file},$!);
 
106
  } else {
 
107
    for ($!=0; defined($_=<CACHE>); $!=0) {
94
108
      my($k,$v) = split(/\t/, $_);
95
109
      next unless (defined $k && defined $v);
96
110
      $self->{cache}->{$k} = $v;
97
111
    }
98
 
    close(CACHE);
 
112
    defined $_ || $!==0  or
 
113
      $!==EBADF ? dbg("AIcache: error reading from AI cache file: $!")
 
114
                : warn "error reading from AI cache file: $!";
 
115
    close CACHE
 
116
      or die "error closing AI cache file (".$self->{cache_file}."): $!";
99
117
  }
100
118
 
101
119
  bless($self,$class);
112
130
 
113
131
  return $self->{cache} unless $name;
114
132
 
115
 
  return if ($self->{type} eq 'dir' && (stat($name))[9] > $self->{cache_mtime});
 
133
  # for dir collections: just use the info on a file, if an entry
 
134
  # exists for that file.  it's very unlikely that a file will be
 
135
  # changed to contain a different Date header, and it's slow to check.
 
136
  # return if ($self->{type} eq 'dir' && (stat($name))[9] > $self->{cache_mtime});
116
137
 
117
138
  $name = $self->canon($name);
118
139
  return $self->{cache}->{$name};
134
155
sub finish {
135
156
  my ($self) = @_;
136
157
 
 
158
  return undef unless $self->{dirty};
 
159
 
137
160
  # Cache is dirty, so write out new file
138
 
  if ($self->{dirty})
 
161
 
 
162
  # create enclosing dir tree, if required
 
163
  eval {
 
164
    mkpath(dirname($self->{cache_file}));
 
165
    1;
 
166
  } or do {
 
167
    my $eval_stat = $@ ne '' ? $@ : "errno=$!";  chomp $eval_stat;
 
168
    warn "cannot mkpath for AI cache file ($self->{cache_file}): $eval_stat\n";
 
169
  };
 
170
 
 
171
  my $towrite = '';
 
172
  while(my($k,$v) = each %{$self->{cache}}) {
 
173
    $towrite .= "$k\t$v\n";
 
174
  }
 
175
 
139
176
  {
140
 
    # create enclosing dir tree, if required
141
 
    eval {
142
 
      mkpath(dirname($self->{cache_file}));
143
 
    };
144
 
    if ($@) {
145
 
      warn "Can't mkpath for AI cache file (".$self->{cache_file}."): $@ $!";
146
 
    }
 
177
    # ignore signals while we're writing this file
 
178
    local $SIG{'INT'} = 'IGNORE';
 
179
    local $SIG{'TERM'} = 'IGNORE';
147
180
 
148
 
    if (open(CACHE, ">" . $self->{cache_file})) {
149
 
      while(my($k,$v) = each %{$self->{cache}}) {
150
 
        print CACHE "$k\t$v\n";
151
 
      }
152
 
      close(CACHE);
 
181
    if (!open(CACHE, ">".$self->{cache_file}))
 
182
    {
 
183
      warn "creating AI cache file failed (".$self->{cache_file}."): $!";
 
184
      # TODO: should we delete it/clean it up?
153
185
    }
154
186
    else {
155
 
      warn "Can't write AI cache file (".$self->{cache_file}."): $!";
 
187
      print CACHE $towrite
 
188
        or warn "error writing to AI cache file: $!";
 
189
      close CACHE
 
190
        or warn "error closing AI cache file (".$self->{cache_file}."): $!";
156
191
    }
157
192
  }
158
193