| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Date::LastModified; |
|
2
|
|
|
|
|
|
|
# ------ Return last-modified date from set of files, dirs, DBIs, etc. |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
# ------ pragmas |
|
6
|
1
|
|
|
1
|
|
87145
|
use 5.006; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
48
|
|
|
7
|
1
|
|
|
1
|
|
6
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
37
|
|
|
8
|
1
|
|
|
1
|
|
15
|
use warnings; |
|
|
1
|
|
|
|
|
12
|
|
|
|
1
|
|
|
|
|
40
|
|
|
9
|
1
|
|
|
1
|
|
2963
|
use AppConfig qw(:argcount); |
|
|
1
|
|
|
|
|
12345
|
|
|
|
1
|
|
|
|
|
186
|
|
|
10
|
1
|
|
|
1
|
|
1950
|
use Date::Parse; |
|
|
1
|
|
|
|
|
3619
|
|
|
|
1
|
|
|
|
|
141
|
|
|
11
|
1
|
|
|
1
|
|
7
|
use File::Find; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
79
|
|
|
12
|
1
|
|
|
1
|
|
7204
|
use File::stat; |
|
|
1
|
|
|
|
|
31765
|
|
|
|
1
|
|
|
|
|
8
|
|
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# ------ set up exported names |
|
16
|
|
|
|
|
|
|
require Exporter; |
|
17
|
|
|
|
|
|
|
our @ISA = qw(Exporter); # we are an Exporter |
|
18
|
|
|
|
|
|
|
our %EXPORT_TAGS # but we export nothing |
|
19
|
|
|
|
|
|
|
= ( 'all' => [ qw() ] ); |
|
20
|
|
|
|
|
|
|
our @EXPORT_OK # but we export nothing |
|
21
|
|
|
|
|
|
|
= ( @{ $EXPORT_TAGS{'all'} } ); |
|
22
|
|
|
|
|
|
|
our @EXPORT # but we export nothing |
|
23
|
|
|
|
|
|
|
= qw(); |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# ------ version information |
|
27
|
|
|
|
|
|
|
our $VERSION = '0.60'; # our version number |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# ------ define functions |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
# ------ return last-modified date for a file |
|
34
|
|
|
|
|
|
|
sub dlm_file { |
|
35
|
0
|
|
|
0
|
1
|
|
my $file = shift; # file to examine |
|
36
|
0
|
|
|
|
|
|
my $st = stat($file); # file status info |
|
37
|
|
|
|
|
|
|
|
|
38
|
0
|
|
|
|
|
|
return $st->mtime; |
|
39
|
|
|
|
|
|
|
} |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# ------ package for directory handling |
|
43
|
|
|
|
|
|
|
{ |
|
44
|
|
|
|
|
|
|
package Date::LastModified::Directory; |
|
45
|
1
|
|
|
1
|
|
218
|
use File::stat; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
4
|
|
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
my $last = 0; # last modification date |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# ------ reset last modification date |
|
50
|
|
|
|
|
|
|
sub reset_last { |
|
51
|
0
|
|
|
0
|
|
|
$last = 0; |
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# ------ return last modification date |
|
55
|
|
|
|
|
|
|
sub get_last { |
|
56
|
0
|
|
|
0
|
|
|
return $last; |
|
57
|
|
|
|
|
|
|
} |
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
# ------ File::Find "wanted" function |
|
60
|
|
|
|
|
|
|
sub wanted { |
|
61
|
0
|
|
|
0
|
|
|
my $st = stat($_); # file status info |
|
62
|
|
|
|
|
|
|
|
|
63
|
0
|
0
|
0
|
|
|
|
return if (m#/..$/# || m#^..$#); |
|
64
|
0
|
0
|
|
|
|
|
if ($st->mtime > $last) { |
|
65
|
0
|
|
|
|
|
|
$last = $st->mtime; |
|
66
|
|
|
|
|
|
|
} |
|
67
|
|
|
|
|
|
|
} |
|
68
|
|
|
|
|
|
|
} |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
# ------ return last-modified date for a directory |
|
72
|
|
|
|
|
|
|
sub dlm_dir { |
|
73
|
0
|
|
|
0
|
1
|
|
my $dir = shift; # directory to examine |
|
74
|
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# NOTE: "no_chdir" is friendly to Win32 |
|
76
|
0
|
|
|
|
|
|
Date::LastModified::Directory::reset_last(); |
|
77
|
0
|
|
|
|
|
|
find( |
|
78
|
|
|
|
|
|
|
{ wanted => \&Date::LastModified::Directory::wanted, |
|
79
|
|
|
|
|
|
|
no_chdir => 1 }, |
|
80
|
|
|
|
|
|
|
$dir); |
|
81
|
0
|
|
|
|
|
|
return Date::LastModified::Directory::get_last; |
|
82
|
|
|
|
|
|
|
} |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
# ------ phrasebook for extracting Unix time from database |
|
86
|
|
|
|
|
|
|
my $unix_time = |
|
87
|
|
|
|
|
|
|
{ "Oracle" => # Oracle database |
|
88
|
|
|
|
|
|
|
{ "time" # time extraction phrase |
|
89
|
|
|
|
|
|
|
=> "TO_CHAR(..., 'YYYY-MM-DD HH24:MI:SS')", |
|
90
|
|
|
|
|
|
|
"parse_date" # have to parse date to get Unix time |
|
91
|
|
|
|
|
|
|
=> 1 |
|
92
|
|
|
|
|
|
|
}, |
|
93
|
|
|
|
|
|
|
"mysql" => # MySQL database |
|
94
|
|
|
|
|
|
|
{ "time" # time extraction phrase |
|
95
|
|
|
|
|
|
|
=> "UNIX_TIMESTAMP(...)", |
|
96
|
|
|
|
|
|
|
"parse_date" # have to parse date to get Unix time |
|
97
|
|
|
|
|
|
|
=> 0 |
|
98
|
|
|
|
|
|
|
}, |
|
99
|
|
|
|
|
|
|
"SQLite" => # SQLite database |
|
100
|
|
|
|
|
|
|
{ "time" # time extraction phrase |
|
101
|
|
|
|
|
|
|
=> "...", # SQLite is typeless |
|
102
|
|
|
|
|
|
|
"parse_date" # have to parse date to get Unix time |
|
103
|
|
|
|
|
|
|
=> 1 |
|
104
|
|
|
|
|
|
|
}, |
|
105
|
|
|
|
|
|
|
"SQL92" => # pseudo-entry for SQL92 databases |
|
106
|
|
|
|
|
|
|
{ "time" # time extraction phrase |
|
107
|
|
|
|
|
|
|
=> "CAST(... AS CHAR)", |
|
108
|
|
|
|
|
|
|
"parse_date" # have to parse date to get Unix time |
|
109
|
|
|
|
|
|
|
=> 1 |
|
110
|
|
|
|
|
|
|
} |
|
111
|
|
|
|
|
|
|
}; |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# ------ DBI error handler |
|
115
|
|
|
|
|
|
|
sub dbi_error { |
|
116
|
0
|
|
|
0
|
0
|
|
my $err = ""; # error string |
|
117
|
|
|
|
|
|
|
|
|
118
|
0
|
0
|
0
|
|
|
|
if (defined($err) && $err !~ m/^\s*$/) { |
|
119
|
0
|
|
|
|
|
|
die "Database fatal error: $err\n"; |
|
120
|
|
|
|
|
|
|
} |
|
121
|
|
|
|
|
|
|
} |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# ------ return last-modified date from a database table via DBI |
|
125
|
|
|
|
|
|
|
sub dlm_dbi { |
|
126
|
0
|
|
|
0
|
1
|
|
my $dbi = shift; # DBI database connection info |
|
127
|
0
|
|
|
|
|
|
my $cfg = ""; # DB username/password config object |
|
128
|
0
|
|
|
|
|
|
my $column = ""; # column name for date |
|
129
|
0
|
|
|
|
|
|
my $dbh = ""; # database handle |
|
130
|
0
|
|
|
|
|
|
my $dbd = ""; # database driver |
|
131
|
0
|
|
|
|
|
|
my $connect = ""; # DBI database connect string |
|
132
|
0
|
|
|
|
|
|
my $last = ""; # last-modified date |
|
133
|
0
|
|
|
|
|
|
my $passfile = ""; # password filename |
|
134
|
0
|
|
|
|
|
|
my $password = ""; # database password |
|
135
|
0
|
|
|
|
|
|
my $sql = ""; # SQL template for extracting date |
|
136
|
0
|
|
|
|
|
|
my $sth = ""; # database statement handle |
|
137
|
0
|
|
|
|
|
|
my $table = ""; # table with last-modified date |
|
138
|
0
|
|
|
|
|
|
my $time_phrase = ""; # time extraction SQL phrase |
|
139
|
0
|
|
|
|
|
|
my @tokens = (); # tokens from DB extract-date string |
|
140
|
0
|
|
|
|
|
|
my $username = ""; # database username |
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# ------ extract database connection information |
|
143
|
0
|
|
|
|
|
|
@tokens = split(',', $dbi); |
|
144
|
0
|
0
|
|
|
|
|
if (scalar(@tokens) >= 5) { |
|
|
|
0
|
|
|
|
|
|
|
145
|
0
|
|
|
|
|
|
($connect,$username,$password,$table,$column) = @tokens; |
|
146
|
|
|
|
|
|
|
} elsif (scalar(@tokens) == 4) { |
|
147
|
0
|
|
|
|
|
|
($connect,$passfile,$table,$column) = @tokens; |
|
148
|
|
|
|
|
|
|
} else { |
|
149
|
0
|
|
|
|
|
|
die "Sorry, I can't find my database connection info in '$dbi'\n"; |
|
150
|
|
|
|
|
|
|
} |
|
151
|
0
|
0
|
|
|
|
|
if ($passfile !~ m/^\s*$/) { |
|
152
|
0
|
|
|
|
|
|
$cfg |
|
153
|
|
|
|
|
|
|
= new AppConfig( { |
|
154
|
|
|
|
|
|
|
CREATE => 1, |
|
155
|
|
|
|
|
|
|
ERROR => |
|
156
|
|
|
|
|
|
|
\&AppConfig_err, |
|
157
|
|
|
|
|
|
|
} ); |
|
158
|
0
|
|
|
|
|
|
$cfg->define("DbUsername", |
|
159
|
|
|
|
|
|
|
{ ARGCOUNT => ARGCOUNT_ONE } ); |
|
160
|
0
|
|
|
|
|
|
$cfg->define("DbPassword", |
|
161
|
|
|
|
|
|
|
{ ARGCOUNT => ARGCOUNT_ONE } ); |
|
162
|
0
|
0
|
|
|
|
|
if (!$cfg->file($passfile)) { |
|
163
|
0
|
|
|
|
|
|
die "can't read '$passfile'\n"; |
|
164
|
|
|
|
|
|
|
} |
|
165
|
0
|
|
|
|
|
|
$username = $cfg->get("DbUsername"); |
|
166
|
0
|
|
|
|
|
|
$password = $cfg->get("DbPassword"); |
|
167
|
|
|
|
|
|
|
} |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# ------ connect to specified database |
|
170
|
0
|
|
|
|
|
|
$dbh = DBI->connect($connect,$username,$password); |
|
171
|
0
|
0
|
|
|
|
|
if (!defined($dbh)) { |
|
172
|
0
|
|
|
|
|
|
die "cannot connect to '$connect' for $table/$column because: $DBI::errstr\n"; |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
# ------ extract last-modified date from specified table and column |
|
176
|
0
|
|
|
|
|
|
(undef,$dbd,undef) = split(':', $connect, 3); |
|
177
|
0
|
|
|
|
|
|
$time_phrase = $unix_time->{$dbd}->{"time"}; |
|
178
|
0
|
|
|
|
|
|
$time_phrase =~ s/\.\.\./$column/; |
|
179
|
0
|
|
|
|
|
|
$sql =<
|
|
180
|
|
|
|
|
|
|
SELECT |
|
181
|
|
|
|
|
|
|
$time_phrase |
|
182
|
|
|
|
|
|
|
FROM |
|
183
|
|
|
|
|
|
|
$table |
|
184
|
|
|
|
|
|
|
ORDER BY |
|
185
|
|
|
|
|
|
|
$column |
|
186
|
|
|
|
|
|
|
DESC |
|
187
|
|
|
|
|
|
|
endSQL |
|
188
|
0
|
|
|
|
|
|
$sth = $dbh->prepare($sql); |
|
189
|
0
|
|
|
|
|
|
dbi_error($DBI::errstr); |
|
190
|
0
|
|
|
|
|
|
$sth->execute(); |
|
191
|
0
|
|
|
|
|
|
dbi_error($DBI::errstr); |
|
192
|
0
|
|
|
|
|
|
($last) = $sth->fetchrow_array(); |
|
193
|
0
|
|
|
|
|
|
dbi_error($sth->errstr); |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
# ------ return last-modified data as a Unix time |
|
196
|
0
|
0
|
|
|
|
|
if ($unix_time->{$dbd}->{"parse_date"}) { |
|
197
|
0
|
|
|
|
|
|
$last = str2time($last); |
|
198
|
|
|
|
|
|
|
} |
|
199
|
0
|
|
|
|
|
|
return $last; |
|
200
|
|
|
|
|
|
|
} |
|
201
|
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
# ------ define private package variables |
|
205
|
|
|
|
|
|
|
my $strategy # date resources strategy |
|
206
|
|
|
|
|
|
|
= [ |
|
207
|
|
|
|
|
|
|
{ "name" => "file", # file handler |
|
208
|
|
|
|
|
|
|
"last_mod" => \&dlm_file, # return last-modified date |
|
209
|
|
|
|
|
|
|
}, |
|
210
|
|
|
|
|
|
|
{ "name" => "dir", # directory handler |
|
211
|
|
|
|
|
|
|
"last_mod" => \&dlm_dir, # return last-modified date |
|
212
|
|
|
|
|
|
|
}, |
|
213
|
|
|
|
|
|
|
{ "name" => "dbi", # DBI handler |
|
214
|
|
|
|
|
|
|
"last_mod" => \&dlm_dbi, # return last-modified date |
|
215
|
|
|
|
|
|
|
}, |
|
216
|
|
|
|
|
|
|
]; |
|
217
|
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
# ------ empty error function for AppConfig |
|
220
|
0
|
|
|
0
|
0
|
|
sub AppConfig_err { |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
# ------ constructor |
|
225
|
|
|
|
|
|
|
sub new { |
|
226
|
0
|
|
|
0
|
0
|
|
my $class = shift; # our classname |
|
227
|
0
|
|
|
|
|
|
my $resources = shift; # hashref of date resources |
|
228
|
|
|
|
|
|
|
# OR scalar with config filename |
|
229
|
0
|
|
|
|
|
|
my $cfg # configuration object |
|
230
|
|
|
|
|
|
|
= new AppConfig( { |
|
231
|
|
|
|
|
|
|
CREATE => 1, # create variables without predefinitions |
|
232
|
|
|
|
|
|
|
ERROR => |
|
233
|
|
|
|
|
|
|
\&AppConfig_err, # error handler (empty) |
|
234
|
|
|
|
|
|
|
} ); |
|
235
|
0
|
|
|
|
|
|
my $self = {}; # my blessed self |
|
236
|
0
|
|
|
|
|
|
my $tactic = ""; # tactic in resource handler strategy |
|
237
|
0
|
|
|
|
|
|
my $tactic_cnt = 0; # total # of tactics we use |
|
238
|
0
|
|
|
|
|
|
my $tactic_name = ""; # name of tactic in strategy |
|
239
|
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
# ------ bless ourself into our class |
|
241
|
0
|
|
|
|
|
|
bless $self, $class; |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
# ------ setup where last-modified came from |
|
244
|
0
|
|
|
|
|
|
$self->{"From"} = undef; |
|
245
|
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
# ------ use passed-in date resources |
|
247
|
0
|
0
|
|
|
|
|
if (ref($resources) eq "HASH") { |
|
248
|
0
|
|
|
|
|
|
foreach $tactic (@$strategy) { |
|
249
|
0
|
|
|
|
|
|
$self->{"Resources"}->{$tactic->{"name"}} |
|
250
|
|
|
|
|
|
|
= $resources->{$tactic->{"name"}}; |
|
251
|
|
|
|
|
|
|
} |
|
252
|
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
# ------ use date resources from config file |
|
254
|
|
|
|
|
|
|
} else { |
|
255
|
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
# ------ set up variables we know about |
|
257
|
0
|
|
|
|
|
|
foreach $tactic (@$strategy) { |
|
258
|
0
|
|
|
|
|
|
$cfg->define("dlm_$tactic->{name}", |
|
259
|
|
|
|
|
|
|
{ ARGCOUNT => ARGCOUNT_LIST } ); |
|
260
|
|
|
|
|
|
|
} |
|
261
|
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
# ------ read configuration file |
|
263
|
0
|
0
|
|
|
|
|
if (!$cfg->file($resources)) { |
|
264
|
0
|
|
|
|
|
|
die "can't read '$resources'\n"; |
|
265
|
|
|
|
|
|
|
} |
|
266
|
0
|
|
|
|
|
|
foreach $tactic (@$strategy) { |
|
267
|
0
|
|
|
|
|
|
$self->{"Resources"}->{$tactic->{"name"}} |
|
268
|
|
|
|
|
|
|
= $cfg->get("dlm_$tactic->{name}"); |
|
269
|
|
|
|
|
|
|
} |
|
270
|
|
|
|
|
|
|
} |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
# ------ ensure we got something to work with |
|
273
|
0
|
|
|
|
|
|
foreach $tactic_name (keys(%{$self->{"Resources"}})) { |
|
|
0
|
|
|
|
|
|
|
|
274
|
0
|
|
|
|
|
|
$tactic = $self->{"Resources"}->{$tactic_name}; |
|
275
|
0
|
0
|
|
|
|
|
if (ref($tactic) eq "ARRAY") { |
|
276
|
0
|
|
|
|
|
|
$tactic_cnt += scalar(@{$tactic}); |
|
|
0
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
} |
|
278
|
|
|
|
|
|
|
} |
|
279
|
0
|
0
|
|
|
|
|
if ($tactic_cnt < 1) { |
|
280
|
0
|
|
|
|
|
|
die "no resources to use by Date::LastModified\n"; |
|
281
|
|
|
|
|
|
|
} |
|
282
|
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
# ------ everything OK so return my blessed self |
|
284
|
0
|
|
|
|
|
|
return $self; |
|
285
|
|
|
|
|
|
|
} |
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
# ------ return last-modified date of one or more resources |
|
289
|
|
|
|
|
|
|
sub last { |
|
290
|
0
|
|
|
0
|
0
|
|
my $self = shift; # my blessed self |
|
291
|
0
|
|
|
|
|
|
my $current = 0; # current date from a resource |
|
292
|
0
|
|
|
|
|
|
my $func = undef; # function to find last-modified date |
|
293
|
0
|
|
|
|
|
|
my $latest = 0; # last-modified date of all resources |
|
294
|
0
|
|
|
|
|
|
my $resource = ""; # resource to examine |
|
295
|
0
|
|
|
|
|
|
my $tactic = ""; # tactic in resource handler strategy |
|
296
|
0
|
|
|
|
|
|
my $tactic_name = ""; # name of tactic in strategy |
|
297
|
|
|
|
|
|
|
|
|
298
|
0
|
|
|
|
|
|
$current = $latest = 0; |
|
299
|
0
|
|
|
|
|
|
$self->{"From"} = undef; |
|
300
|
0
|
|
|
|
|
|
foreach $tactic_name (keys(%{$self->{"Resources"}})) { |
|
|
0
|
|
|
|
|
|
|
|
301
|
0
|
|
|
|
|
|
$tactic = $self->{"Resources"}->{$tactic_name}; |
|
302
|
0
|
|
|
|
|
|
$func = undef; |
|
303
|
0
|
0
|
0
|
|
|
|
if (ref($tactic) eq "ARRAY" && scalar(@$tactic) > 0) { |
|
304
|
0
|
|
|
|
|
|
foreach $tactic (@$strategy) { |
|
305
|
0
|
0
|
|
|
|
|
if ($tactic->{"name"} eq $tactic_name) { |
|
306
|
0
|
|
|
|
|
|
$func = $tactic->{"last_mod"}; |
|
307
|
|
|
|
|
|
|
} |
|
308
|
|
|
|
|
|
|
} |
|
309
|
0
|
0
|
|
|
|
|
if (!defined($func)) { |
|
310
|
0
|
|
|
|
|
|
die "missing last_mod function for '$tactic_name'\n"; |
|
311
|
|
|
|
|
|
|
} |
|
312
|
0
|
|
|
|
|
|
foreach $resource (@{$tactic}) { |
|
|
0
|
|
|
|
|
|
|
|
313
|
0
|
|
|
|
|
|
$current = &$func($resource); |
|
314
|
0
|
0
|
|
|
|
|
if ($current > $latest) { |
|
315
|
0
|
|
|
|
|
|
$self->{"From"} = "$tactic_name: $resource"; |
|
316
|
0
|
|
|
|
|
|
$latest = $current; |
|
317
|
|
|
|
|
|
|
} |
|
318
|
|
|
|
|
|
|
} |
|
319
|
|
|
|
|
|
|
} |
|
320
|
|
|
|
|
|
|
} |
|
321
|
|
|
|
|
|
|
|
|
322
|
0
|
|
|
|
|
|
return $latest; |
|
323
|
|
|
|
|
|
|
} |
|
324
|
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# ------ return where last-modified date came from |
|
326
|
|
|
|
|
|
|
sub from { |
|
327
|
0
|
|
|
0
|
1
|
|
my $self = shift; # our blessed self |
|
328
|
|
|
|
|
|
|
|
|
329
|
0
|
|
|
|
|
|
return $self->{"From"}; |
|
330
|
|
|
|
|
|
|
} |
|
331
|
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
1; |
|
333
|
|
|
|
|
|
|
__END__ |