69
72
File::Spec->rel2abs($self->{path}),
70
73
'.spamassassin_cache');
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;
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]));
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;
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}) {
89
98
$self->{cache_file} = File::Spec->canonpath($self->{cache_file});
91
100
# go ahead and read in the cache information
92
if ($use_cache && open(CACHE, $self->{cache_file})) {
93
while(defined($_=<CACHE>)) {
104
} elsif (!open(CACHE, $self->{cache_file})) {
105
dbg("AIcache: cannot open AI cache file (%s): %s", $self->{cache_file},$!);
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;
112
defined $_ || $!==0 or
113
$!==EBADF ? dbg("AIcache: error reading from AI cache file: $!")
114
: warn "error reading from AI cache file: $!";
116
or die "error closing AI cache file (".$self->{cache_file}."): $!";
101
119
bless($self,$class);
113
131
return $self->{cache} unless $name;
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});
117
138
$name = $self->canon($name);
118
139
return $self->{cache}->{$name};
158
return undef unless $self->{dirty};
137
160
# Cache is dirty, so write out new file
162
# create enclosing dir tree, if required
164
mkpath(dirname($self->{cache_file}));
167
my $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat;
168
warn "cannot mkpath for AI cache file ($self->{cache_file}): $eval_stat\n";
172
while(my($k,$v) = each %{$self->{cache}}) {
173
$towrite .= "$k\t$v\n";
140
# create enclosing dir tree, if required
142
mkpath(dirname($self->{cache_file}));
145
warn "Can't mkpath for AI cache file (".$self->{cache_file}."): $@ $!";
177
# ignore signals while we're writing this file
178
local $SIG{'INT'} = 'IGNORE';
179
local $SIG{'TERM'} = 'IGNORE';
148
if (open(CACHE, ">" . $self->{cache_file})) {
149
while(my($k,$v) = each %{$self->{cache}}) {
150
print CACHE "$k\t$v\n";
181
if (!open(CACHE, ">".$self->{cache_file}))
183
warn "creating AI cache file failed (".$self->{cache_file}."): $!";
184
# TODO: should we delete it/clean it up?
155
warn "Can't write AI cache file (".$self->{cache_file}."): $!";
188
or warn "error writing to AI cache file: $!";
190
or warn "error closing AI cache file (".$self->{cache_file}."): $!";