line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#================================ Entry.pm =================================== |
2
|
|
|
|
|
|
|
# Filename: Entry.pm |
3
|
|
|
|
|
|
|
# Description: Container for data about a file. |
4
|
|
|
|
|
|
|
# Original Author: Dale M. Amon |
5
|
|
|
|
|
|
|
# Revised by: $Author: amon $ |
6
|
|
|
|
|
|
|
# Date: $Date: 2008-08-28 23:35:28 $ |
7
|
|
|
|
|
|
|
# Version: $Revision: 1.8 $ |
8
|
|
|
|
|
|
|
# License: LGPL 2.1, Perl Artistic or BSD |
9
|
|
|
|
|
|
|
# |
10
|
|
|
|
|
|
|
#============================================================================= |
11
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
109
|
|
12
|
1
|
|
|
1
|
|
7
|
use File::Spec; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
21
|
|
13
|
1
|
|
|
1
|
|
6
|
use Digest::MD5; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
49
|
|
14
|
1
|
|
|
1
|
|
7
|
use Fault::Logger; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
19
|
|
15
|
1
|
|
|
1
|
|
805
|
use Fault::Notepad; |
|
1
|
|
|
|
|
648
|
|
|
1
|
|
|
|
|
21
|
|
16
|
1
|
|
|
1
|
|
540
|
use FileHash::FormatString; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
34
|
|
17
|
1
|
|
|
1
|
|
8712
|
use Data::Dumper; |
|
1
|
|
|
|
|
15651
|
|
|
1
|
|
|
|
|
112
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
package FileHash::Entry; |
20
|
1
|
|
|
1
|
|
10
|
use vars qw{@ISA}; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
2630
|
|
21
|
|
|
|
|
|
|
@ISA = qw( UNIVERSAL ); |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# Update this number if the format of the entry dump is changed. |
24
|
|
|
|
|
|
|
# |
25
|
|
|
|
|
|
|
my $FileHashEntryVersion = "0.05"; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
#============================================================================= |
28
|
|
|
|
|
|
|
# CLASS METHODS |
29
|
|
|
|
|
|
|
#============================================================================= |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub alloc ($$) { |
32
|
0
|
|
|
0
|
1
|
|
my ($class) = @_; |
33
|
0
|
|
|
|
|
|
my $self = bless {}, $class; |
34
|
0
|
|
|
|
|
|
@$self{'device','directory','file', |
35
|
|
|
|
|
|
|
'md5sum', |
36
|
|
|
|
|
|
|
'deviceNumber','inode','mode','hardlinks', |
37
|
|
|
|
|
|
|
'uid','uidName','gid','gidName', |
38
|
|
|
|
|
|
|
'deviceSpecialId','sizeBytes', |
39
|
|
|
|
|
|
|
'atime','mtime','ctime', |
40
|
|
|
|
|
|
|
'blocksizePreference','blocksAllocated','notepad'} = undef; |
41
|
0
|
|
|
|
|
|
return $self; |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
0
|
|
|
0
|
1
|
|
sub dumpversion ($) {$FileHashEntryVersion;} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
#============================================================================= |
47
|
|
|
|
|
|
|
# INSTANCE METHODS |
48
|
|
|
|
|
|
|
#============================================================================= |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub init ($$) { |
51
|
0
|
|
|
0
|
1
|
|
my ($self,$path) = @_; |
52
|
|
|
|
|
|
|
|
53
|
0
|
0
|
|
|
|
|
if ($::DEBUG) {Fault::Logger->arg_check_noref ($path,"path") |
|
0
|
0
|
|
|
|
|
|
54
|
|
|
|
|
|
|
or return undef;} |
55
|
|
|
|
|
|
|
|
56
|
0
|
|
|
|
|
|
my ($dev,$dir,$file) = File::Spec->splitpath ($path); |
57
|
|
|
|
|
|
|
|
58
|
0
|
|
|
|
|
|
@$self{'device','directory','file','notepad'} = |
59
|
|
|
|
|
|
|
($dev,$dir,$file,Fault::Notepad->new); |
60
|
|
|
|
|
|
|
|
61
|
0
|
|
|
|
|
|
return $self; |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
65
|
|
|
|
|
|
|
# Arg check responsibility is passed on to the init method. |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub initFromStat ($$) { |
68
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
69
|
0
|
|
|
|
|
|
$self->init(@_); |
70
|
0
|
|
|
|
|
|
my $filename = $self->path; |
71
|
|
|
|
|
|
|
|
72
|
0
|
|
|
|
|
|
my (@stat); |
73
|
0
|
0
|
|
|
|
|
if (@stat = lstat($filename)) { |
74
|
0
|
|
|
|
|
|
@$self{'deviceNumber','inode','mode','hardlinks', |
75
|
|
|
|
|
|
|
'uid','gid','deviceSpecialId','sizeBytes', |
76
|
|
|
|
|
|
|
'atime','mtime','ctime', |
77
|
|
|
|
|
|
|
'blocksizePreference','blocksAllocated'} = (@stat); |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# md5sum can only handle plain files, use 0 for md5sum otherwise. |
80
|
0
|
|
|
|
|
|
$self->{'md5sum'} = 0; |
81
|
0
|
0
|
|
|
|
|
if (-f $filename) { |
82
|
0
|
0
|
|
|
|
|
if (open(FILE, $filename)) { |
83
|
0
|
|
|
|
|
|
binmode FILE; |
84
|
0
|
|
|
|
|
|
$self->{'md5sum'} = Digest::MD5->new->addfile(*FILE)->hexdigest; |
85
|
0
|
|
|
|
|
|
close(FILE); |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
else { |
89
|
0
|
|
|
|
|
|
$self->{'notepad'}->add ("Can not open '$filename' for hashing: $!\n"); |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
else { |
93
|
0
|
|
|
|
|
|
$self->{'notepad'}->add ("Can not lstat '$filename': $!\n"); |
94
|
|
|
|
|
|
|
} |
95
|
0
|
|
|
|
|
|
return $self; |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
sub initFromLine ($$$) { |
101
|
0
|
|
|
0
|
1
|
|
my ($self,$format,$line) = @_; |
102
|
0
|
|
|
|
|
|
$self->{'notepad'} = Fault::Notepad->new; |
103
|
|
|
|
|
|
|
|
104
|
0
|
0
|
|
|
|
|
if ($::DEBUG) { |
105
|
0
|
0
|
|
|
|
|
Fault::Logger->arg_check_isa ($format,"FileHash::FormatString","format") |
106
|
|
|
|
|
|
|
or return undef; |
107
|
0
|
0
|
|
|
|
|
Fault::Logger->arg_check_noref ($line,"line") |
108
|
|
|
|
|
|
|
or return undef; |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
0
|
|
|
|
|
|
chomp $line; |
112
|
0
|
|
|
|
|
|
my @string = $self->_lexical_parse ($line,$format->fields); |
113
|
0
|
|
|
|
|
|
my $vals = $format->parse (@string); |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
# This way we can skip lines that do not match our format. It's a silly |
116
|
|
|
|
|
|
|
# cheat for working with files with headers and we'll need something |
117
|
|
|
|
|
|
|
# better. |
118
|
0
|
0
|
|
|
|
|
defined $vals or return undef; |
119
|
|
|
|
|
|
|
|
120
|
0
|
|
|
|
|
|
@$self{'device','directory','file', |
121
|
|
|
|
|
|
|
'md5sum', |
122
|
|
|
|
|
|
|
'deviceNumber','inode','mode','hardlinks', |
123
|
|
|
|
|
|
|
'uid','uidName','gid','gidName', |
124
|
|
|
|
|
|
|
'deviceSpecialId','sizeBytes', |
125
|
|
|
|
|
|
|
'atime','mtime','ctime', |
126
|
|
|
|
|
|
|
'blocksizePreference','blocksAllocated'} = |
127
|
|
|
|
|
|
|
(@$vals{'device','directory','file', |
128
|
|
|
|
|
|
|
'md5sum', |
129
|
|
|
|
|
|
|
'deviceNumber','inode','mode','hardlinks', |
130
|
|
|
|
|
|
|
'uid','uidName','gid','gidName', |
131
|
|
|
|
|
|
|
'deviceSpecialId','sizeBytes', |
132
|
|
|
|
|
|
|
'atime','mtime','ctime', |
133
|
|
|
|
|
|
|
'blocksizePreference','blocksAllocated'} |
134
|
|
|
|
|
|
|
); |
135
|
|
|
|
|
|
|
|
136
|
0
|
|
|
|
|
|
$self->{'notepad'}->merge ($vals->{'notepad'}); |
137
|
0
|
|
|
|
|
|
return $self; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
141
|
|
|
|
|
|
|
# NOTE: eval could fail if we opened the wrong file. Need to check it. |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
sub initFromDump ($\*) { |
144
|
0
|
|
|
0
|
1
|
|
my ($self,$fh) = @_; |
145
|
0
|
|
|
|
|
|
$self->{'notepad'} = Fault::Notepad->new; |
146
|
|
|
|
|
|
|
|
147
|
0
|
0
|
|
|
|
|
if ($::DEBUG) { |
148
|
0
|
0
|
|
|
|
|
Fault::Logger->arg_check_isa ($fh,"IO:Handle","filehandle") |
149
|
|
|
|
|
|
|
or return undef; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
# Lines are of the form: |
153
|
|
|
|
|
|
|
# $entry = bless( {'mode' => 33188, ... }, 'FileHash::Entry' ); |
154
|
|
|
|
|
|
|
# |
155
|
0
|
|
|
|
|
|
my $entry; |
156
|
0
|
|
|
|
|
|
my $line = readline $fh; |
157
|
0
|
0
|
|
|
|
|
defined $line or return undef; |
158
|
|
|
|
|
|
|
|
159
|
0
|
0
|
|
|
|
|
if (! eval $line) { |
160
|
0
|
|
|
|
|
|
Fault::Logger->log ("Eval on dump file line failed: $@"); |
161
|
0
|
|
|
|
|
|
return undef; |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
# Initiatlize self from the input data |
165
|
0
|
|
|
|
|
|
@$self{keys %$entry} = (values %$entry); |
166
|
0
|
|
|
|
|
|
return $self; |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub _lexical_parse ($$$) { |
172
|
0
|
|
|
0
|
|
|
my ($class,$string,$fields) = @_; |
173
|
0
|
|
|
|
|
|
my ($quote, @pass2); |
174
|
|
|
|
|
|
|
|
175
|
0
|
|
|
|
|
|
my @pass1 = split /((?
|
176
|
|
|
|
|
|
|
|
177
|
0
|
|
|
|
|
|
foreach my $i (@pass1) { |
178
|
0
|
|
|
|
|
|
my $needed = $fields - ($#pass2+1); |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# The rest of the line goes in the last lexeme. |
181
|
0
|
0
|
|
|
|
|
if ($needed == 0) {$pass2[$#pass2] .= $i;} |
|
0
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
else { |
183
|
0
|
0
|
|
|
|
|
if (!defined $quote) { |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
# Start a quoted section |
186
|
0
|
0
|
0
|
|
|
|
if (length $i == 1 and ($i eq '"' or $i eq "'")) { |
|
0
|
|
0
|
|
|
|
|
187
|
0
|
|
|
|
|
|
$quote = $i; |
188
|
0
|
|
|
|
|
|
push @pass2, (""); |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# Split nonquoted sections. |
192
|
|
|
|
|
|
|
else {push @pass2, (split " ", $i, $needed);} |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
# Append everything inside a quoted section. |
196
|
|
|
|
|
|
|
else { |
197
|
0
|
0
|
|
|
|
|
if ($quote eq $i) {$quote = undef;} |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
else {$pass2[$#pass2] .= $i; } |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
} |
202
|
0
|
|
|
|
|
|
return @pass2; |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
#============================================================================= |
206
|
|
|
|
|
|
|
|
207
|
0
|
|
|
0
|
1
|
|
sub print ($) {my $s = shift; $s->fprint (*STDOUT); $s;} |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
208
|
0
|
|
|
0
|
1
|
|
sub dump ($\*) {my $s = shift; $s->fprint (@_); $s;} |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
sub sprint ($) { |
213
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
214
|
0
|
|
|
|
|
|
my $dd = Data::Dumper->new ([$self], ["self"]); |
215
|
0
|
|
|
|
|
|
$dd->Indent(0); |
216
|
0
|
|
|
|
|
|
return $dd->dump; |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
sub fprint ($\*) { |
222
|
0
|
|
|
0
|
1
|
|
my ($self,$fh) = @_; |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
# NOTE: NEED A fault_check_isglob method |
225
|
|
|
|
|
|
|
|
226
|
0
|
|
|
|
|
|
my $dd = Data::Dumper->new ([$self], ["entry"]); |
227
|
0
|
|
|
|
|
|
$dd->Indent(0); |
228
|
|
|
|
|
|
|
|
229
|
0
|
|
|
|
|
|
my $ok = printf $fh "%s\n",$dd->Dump; |
230
|
0
|
0
|
|
|
|
|
$ok or Fault::Logger->log_once ("Failed to print to dumpfile: $!"); |
231
|
|
|
|
|
|
|
|
232
|
0
|
|
|
|
|
|
return $self; |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
#============================================================================= |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
sub path ($) { |
238
|
0
|
|
|
0
|
1
|
|
my $s = shift; |
239
|
0
|
|
|
|
|
|
return File::Spec->catpath (@$s{'device','directory','file'}); |
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
243
|
|
|
|
|
|
|
# Return values for printing or hashing: "" or 0 on undef for hashing. |
244
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
245
|
|
|
|
|
|
|
|
246
|
0
|
|
|
0
|
1
|
|
sub device ($) {my $s=shift; |
247
|
0
|
0
|
|
|
|
|
(defined $s->{'device'}) |
248
|
|
|
|
|
|
|
? $s->{'device'} : "";} |
249
|
|
|
|
|
|
|
|
250
|
0
|
|
|
0
|
1
|
|
sub directory ($) {my $s=shift; |
251
|
0
|
0
|
|
|
|
|
(defined $s->{'directory'}) |
252
|
|
|
|
|
|
|
? $s->{'device'} : "";} |
253
|
|
|
|
|
|
|
|
254
|
0
|
|
|
0
|
1
|
|
sub file ($) {my $s=shift; |
255
|
0
|
0
|
|
|
|
|
(defined $s->{'file'}) |
256
|
|
|
|
|
|
|
? $s->{'file'} : "";} |
257
|
|
|
|
|
|
|
|
258
|
0
|
|
|
0
|
1
|
|
sub md5sum ($) {my $s=shift; |
259
|
0
|
0
|
|
|
|
|
(defined $s->{'md5sum'}) |
260
|
|
|
|
|
|
|
? $s->{'md5sum'} : 0;} |
261
|
|
|
|
|
|
|
|
262
|
0
|
|
|
0
|
1
|
|
sub sizeBytes ($) {my $s=shift; |
263
|
0
|
0
|
|
|
|
|
(defined $s->{'sizeBytes'}) |
264
|
|
|
|
|
|
|
? $s->{'sizeBytes'} : 0;} |
265
|
|
|
|
|
|
|
|
266
|
0
|
|
|
0
|
1
|
|
sub atime ($) {my $s=shift; |
267
|
0
|
0
|
|
|
|
|
(defined $s->{'atime'}) |
268
|
|
|
|
|
|
|
? $s->{'atime'} : 0;} |
269
|
|
|
|
|
|
|
|
270
|
0
|
|
|
0
|
1
|
|
sub mtime ($) {my $s=shift; |
271
|
0
|
0
|
|
|
|
|
(defined $s->{'mtime'}) |
272
|
|
|
|
|
|
|
? $s->{'mtime'} : 0;} |
273
|
|
|
|
|
|
|
|
274
|
0
|
|
|
0
|
1
|
|
sub ctime ($) {my $s=shift; |
275
|
0
|
0
|
|
|
|
|
(defined $s->{'ctime'}) |
276
|
|
|
|
|
|
|
? $s->{'ctime'} : 0;} |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
279
|
|
|
|
|
|
|
# Values for printing, return "undef" string if undef. |
280
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
281
|
0
|
|
|
0
|
1
|
|
sub deviceNumber ($) {my $s=shift; |
282
|
0
|
0
|
|
|
|
|
(defined $s->{'deviceNumber'}) |
283
|
|
|
|
|
|
|
? $s->{'deviceNumber'} : "undef";} |
284
|
|
|
|
|
|
|
|
285
|
0
|
|
|
0
|
1
|
|
sub inode ($) {my $s=shift; |
286
|
0
|
0
|
|
|
|
|
(defined $s->{'inode'}) |
287
|
|
|
|
|
|
|
? $s->{'inode'} : "undef";} |
288
|
|
|
|
|
|
|
|
289
|
0
|
|
|
0
|
1
|
|
sub mode ($) {my $s=shift; |
290
|
0
|
0
|
|
|
|
|
(defined $s->{'mode'}) |
291
|
|
|
|
|
|
|
? $s->{'mode'} : "undef";} |
292
|
|
|
|
|
|
|
|
293
|
0
|
|
|
0
|
1
|
|
sub hardlinks ($) {my $s=shift; |
294
|
0
|
0
|
|
|
|
|
(defined $s->{'hardlinks'}) |
295
|
|
|
|
|
|
|
? $s->{'hardlinks'} : "undef";} |
296
|
|
|
|
|
|
|
|
297
|
0
|
|
|
0
|
1
|
|
sub uid ($) {my $s=shift; |
298
|
0
|
0
|
|
|
|
|
(defined $s->{'uid'}) |
299
|
|
|
|
|
|
|
? $s->{'uid'} : "undef";} |
300
|
|
|
|
|
|
|
|
301
|
0
|
|
|
0
|
1
|
|
sub uidName ($) {my $s=shift; |
302
|
0
|
0
|
|
|
|
|
(defined $s->{'uidName'}) |
303
|
|
|
|
|
|
|
? $s->{'uidName'} : "undef";} |
304
|
|
|
|
|
|
|
|
305
|
0
|
|
|
0
|
1
|
|
sub gid ($) {my $s=shift; |
306
|
0
|
0
|
|
|
|
|
(defined $s->{'gid'}) |
307
|
|
|
|
|
|
|
? $s->{'gid'} : "undef";} |
308
|
|
|
|
|
|
|
|
309
|
0
|
|
|
0
|
1
|
|
sub gidName ($) {my $s=shift; |
310
|
0
|
0
|
|
|
|
|
(defined $s->{'gidName'}) |
311
|
|
|
|
|
|
|
? $s->{'gidName'} : "undef";} |
312
|
|
|
|
|
|
|
|
313
|
0
|
|
|
0
|
1
|
|
sub deviceSpecialId ($) {my $s=shift; |
314
|
0
|
0
|
|
|
|
|
(defined $s->{'deviceSpecialId'}) |
315
|
|
|
|
|
|
|
? $s->{'deviceSpecialId'} : "undef";} |
316
|
|
|
|
|
|
|
|
317
|
0
|
|
|
0
|
1
|
|
sub blocksizePreference ($) {my $s=shift; |
318
|
0
|
0
|
|
|
|
|
(defined $s->{'blocksizePreference'}) |
319
|
|
|
|
|
|
|
? $s->{'blocksizePreference'} : "undef";} |
320
|
|
|
|
|
|
|
|
321
|
0
|
|
|
0
|
1
|
|
sub blocksAllocated ($) {my $s=shift; |
322
|
0
|
0
|
|
|
|
|
(defined $s->{'blocksAllocated'}) |
323
|
|
|
|
|
|
|
? $s->{'blocksAllocated'} : "undef";} |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
#============================================================================= |
326
|
|
|
|
|
|
|
# POD DOCUMENTATION |
327
|
|
|
|
|
|
|
#============================================================================= |
328
|
|
|
|
|
|
|
# You may extract and format the documention section with the 'perldoc' cmd. |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=head1 NAME |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
FileHash::Entry - Container for data about a file. |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=head1 SYNOPSIS |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
use FileHash::Entry; |
337
|
|
|
|
|
|
|
$obj = FileHash::Entry->alloc; |
338
|
|
|
|
|
|
|
$ver = FileHash::Entry->dumpversion; |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
$obj = $obj->init ($path); |
341
|
|
|
|
|
|
|
$obj = $obj->initFromStat ($path); |
342
|
|
|
|
|
|
|
$obj = $obj->initFromLine ($format,$line); |
343
|
|
|
|
|
|
|
$obj = $obj->initFromDump ($fh); |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
$str = $obj->sprint; |
347
|
|
|
|
|
|
|
$obj = $obj->print; |
348
|
|
|
|
|
|
|
$obj = $obj->fprint($fh); |
349
|
|
|
|
|
|
|
$obj = $obj->dump ($fh); |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
$path = $obj->path; |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
$atime = $obj->atime; |
354
|
|
|
|
|
|
|
$blocksizePreference = $obj->blocksizePreference; |
355
|
|
|
|
|
|
|
$blocksAllocated = $obj->blocksAllocated; |
356
|
|
|
|
|
|
|
$ctime = $obj->ctime; |
357
|
|
|
|
|
|
|
$device = $obj->device; |
358
|
|
|
|
|
|
|
$deviceNumber = $obj->deviceNumber; |
359
|
|
|
|
|
|
|
$deviceSpecialId = $obj->deviceSpecialId; |
360
|
|
|
|
|
|
|
$directory = $obj->directory; |
361
|
|
|
|
|
|
|
$file = $obj->file; |
362
|
|
|
|
|
|
|
$gid = $obj->gid; |
363
|
|
|
|
|
|
|
$gidName = $obj->gidName; |
364
|
|
|
|
|
|
|
$hardlinks = $obj->hardlinks; |
365
|
|
|
|
|
|
|
$inode = $obj->inode; |
366
|
|
|
|
|
|
|
$md5sum = $obj->md5sum; |
367
|
|
|
|
|
|
|
$mode = $obj->mode; |
368
|
|
|
|
|
|
|
$mtime = $obj->mtime; |
369
|
|
|
|
|
|
|
$sizeBytes = $obj->sizeBytes; |
370
|
|
|
|
|
|
|
$uid = $obj->uid; |
371
|
|
|
|
|
|
|
$uidName = $obj->uidName; |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=head1 Inheritance |
374
|
|
|
|
|
|
|
UNIVERSAL |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=head1 Description |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
This is an internal class used by FileHashes. |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
Entry objects are containers for information about files collected |
381
|
|
|
|
|
|
|
from various sources. |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=head1 Examples |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
use FileHash::Entry; |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
# Create an entry by collecting metadata about a live file. |
388
|
|
|
|
|
|
|
my $a = FileHash::Entry->alloc; |
389
|
|
|
|
|
|
|
$a->initFromStat ("/root/myfile"); |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
# Create another Entry by parsing a line of data. |
392
|
|
|
|
|
|
|
my $f = FileHash::FormatString->alloc; |
393
|
|
|
|
|
|
|
$f->init ("path md5sum sizeBytes"); |
394
|
|
|
|
|
|
|
my $b = FileHash::Entry->alloc; |
395
|
|
|
|
|
|
|
$b->initFromLine ($f, "/root/myfile 0bdebef6bc59cabe489442ef9ddecf5f 10050"); |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
# Dump the object data to a file. |
398
|
|
|
|
|
|
|
open $fh, ">mydump"; |
399
|
|
|
|
|
|
|
$b->dump ($fh); |
400
|
|
|
|
|
|
|
close $fh; |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
# Reload the dumped object data. |
403
|
|
|
|
|
|
|
my $c = FileHash::Entry->alloc; |
404
|
|
|
|
|
|
|
open $fh, "
|
405
|
|
|
|
|
|
|
$c->initFromDump ($fh); |
406
|
|
|
|
|
|
|
close $fh; |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
# print data on the console. |
409
|
|
|
|
|
|
|
$c->print; |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
=head1 Class Variables |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
None. |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
=head1 Instance Variables |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
In most cases an item will be undef if it is not available via the |
418
|
|
|
|
|
|
|
source of information used to create the FileHash::Entry. |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
device File device portion of file path, non Unix systems. |
421
|
|
|
|
|
|
|
directory File directory portion of file path. |
422
|
|
|
|
|
|
|
file File name portion of file path. |
423
|
|
|
|
|
|
|
deviceNumber Device number. |
424
|
|
|
|
|
|
|
sizeBytes Size of file in bytes. |
425
|
|
|
|
|
|
|
uid User id number. |
426
|
|
|
|
|
|
|
uidName User name in ascii. |
427
|
|
|
|
|
|
|
gid Group id number. |
428
|
|
|
|
|
|
|
gidName Group name in ascii. |
429
|
|
|
|
|
|
|
mode File access mode integer. |
430
|
|
|
|
|
|
|
atime Access time in nonleap seconds since 19700101 UTC. |
431
|
|
|
|
|
|
|
mtime Modify time in nonleap seconds since 19700101 UTC. |
432
|
|
|
|
|
|
|
ctime Create time in nonleap seconds since 19700101 UTC. |
433
|
|
|
|
|
|
|
inode File Inode number. |
434
|
|
|
|
|
|
|
hardlinks Number of hard links to file. |
435
|
|
|
|
|
|
|
deviceSpecialId Device special id, integer. |
436
|
|
|
|
|
|
|
blocksizePreference Preferred block size in bytes. |
437
|
|
|
|
|
|
|
blocksAllocated Number of blocks allocated to the file. |
438
|
|
|
|
|
|
|
md5sum md5sum of file content. |
439
|
|
|
|
|
|
|
notepad A Notepad object to record unusual events. |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
=head1 Class Methods |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=over 4 |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
=item B<$obj = FileHash::Entry-Ealloc> |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
Allocate an empty FileHash Entry object. |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
=item B<$ver = FileHash::Entry-Edumpversion> |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
Return the FileHash Entry dump format version id. |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
=back 4 |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
=head1 Instance Methods for printing |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
=over 4 |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=item B<$atime = $obj-Eatime> |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
Return the file atime or 0 if not known. |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
=item B<$blocksizePreference = $obj-EblocksizePreference> |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
Return the file blocksizePreference or "undef" if not known. |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
=item B<$blocksAllocated = $obj-EblocksAllocated> |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
Return the file blocksAllocated or "undef" if not known. |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
=item B<$ctime = $obj-Ectime> |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
Return the file ctime or 0 if not known. |
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
=item B<$device = $obj-Edevice> |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
Return the file device or "" if not known. |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
=item B<$deviceNumber = $obj-EdeviceNumber> |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
Return the file deviceNumber or "undef" if not known. |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
=item B<$deviceSpecialId = $obj-EdeviceSpecialId> |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
Return the file deviceSpecialId or "undef" if not known. |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=item B<$directory = $obj-Edirectory> |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
Return the file directory or "" if not known. |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
=item B<$file = $obj-Efile> |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
Return the file name or "" if not known. |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
=item B<$gid = $obj-Egid> |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
Return the file gid or "undef" if not known. |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
=item B<$gidName = $obj-EgidName> |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
return the file gidName or "undef" if not known. |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=item B<$hardlinks = $obj-Ehardlinks> |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
Return the file hardlinks or "undef" if not known. |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
=item B<$inode = $obj-Einode> |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
Return the file inodes or "undef" if not known. |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
=item B<$md5sum = $obj-Emd5sum> |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
Return the file md5sum or "undef" if not known. |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
=item B<$mode = $obj-Emode> |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
Return the file mode or "undef" if not known. |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
=item B<$mtime = $obj-Emtime> |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
Return the file mtime or 0 if not known. |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
=item B<$sizeBytes = $obj-EsizeBytes> |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
Return the file size in bytes or 0 if not known. |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
=item B<$uid = $obj-Euid> |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
Return the file uid or "undef" if not known. |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
=item B<$uidName = $obj-EuidName> |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
Return the file uidName or "undef" if not known. |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
=back 4 |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
=head1 Instance Methods |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
=over 4 |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
=item B<$obj = $obj-Edump($fh)> |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
Dump contents of the file data entry to one line in the specified file |
544
|
|
|
|
|
|
|
defined by the opened file handle $fh. |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
Synonym for fprint. |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
=item B<$obj = $obj-Efprint($fh)> |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
Dump contents of the file data entry to one line in the specified file |
551
|
|
|
|
|
|
|
defined by the opened file handle $fh. |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
Synonym for dump. |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
=item B<$obj = $obj-Einit ($path)> |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
Initialize a FileHash Entry object to contain the path name. |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
=item B<$obj = $obj-EinitFromDump ($fh)> |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
Replace the alloc'd object with one recreated from a line of dump |
562
|
|
|
|
|
|
|
file data. |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
=item B<$obj = $obj-EinitFromLine ($format,$line)> |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
Create a FileHash Entry from the information parsed out of a line |
567
|
|
|
|
|
|
|
of text. A format object defines what information is contained in |
568
|
|
|
|
|
|
|
that line. |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
=item B<$obj = $obj-EinitFromStat ($path)> |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
Initialized an object with metadata collected via a 'stat' and 'md5sum' |
573
|
|
|
|
|
|
|
applied to the file at $path. |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=item B<$obj = $obj-Epath> |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
Return the full path name. |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
=item B<$obj = $obj-Eprint> |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
Dump contents of the file data entry as one line on stdout. |
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
=item B<$str = $obj-Esprint> |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
Dump contents of the file data entry as a string. The string is |
586
|
|
|
|
|
|
|
not terminated by a newline. |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
=back 4 |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
=head1 Private Class Method |
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
None. |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
=head1 Private Instance Methods |
595
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
=item B<@lexemes = $obj-E_lexical_parse ($line,$fields)> |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
This is the point at which the field data is split it needs to handle a |
599
|
|
|
|
|
|
|
mix of blank delimited fields and quoted fields. If want to parse |
600
|
|
|
|
|
|
|
lines of code here, you'll just have to write your own subclass and |
601
|
|
|
|
|
|
|
override this method. |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
=head1 Errors and Warnings |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
Lots. |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
=head1 KNOWN BUGS |
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
See TODO. |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
=head1 SEE ALSO |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
File::Spec, Digest::MD5, Fault::Notepad, Fault::Logger, |
614
|
|
|
|
|
|
|
FileHash::FormatString, Data::Dumper. |
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
=head1 AUTHOR |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
Dale Amon |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
=cut |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
#============================================================================= |
623
|
|
|
|
|
|
|
# CVS HISTORY |
624
|
|
|
|
|
|
|
#============================================================================= |
625
|
|
|
|
|
|
|
# $Log: Entry.pm,v $ |
626
|
|
|
|
|
|
|
# Revision 1.8 2008-08-28 23:35:28 amon |
627
|
|
|
|
|
|
|
# perldoc section regularization. |
628
|
|
|
|
|
|
|
# |
629
|
|
|
|
|
|
|
# Revision 1.7 2008-08-09 12:56:42 amon |
630
|
|
|
|
|
|
|
# Added parens to fix math error. |
631
|
|
|
|
|
|
|
# |
632
|
|
|
|
|
|
|
# Revision 1.6 2008-07-27 15:16:17 amon |
633
|
|
|
|
|
|
|
# Wrote lexical parse for Entry; error checking on eval and other minor issues. |
634
|
|
|
|
|
|
|
# |
635
|
|
|
|
|
|
|
# Revision 1.5 2008-07-25 14:30:42 amon |
636
|
|
|
|
|
|
|
# Documentation improvements and corrections. |
637
|
|
|
|
|
|
|
# |
638
|
|
|
|
|
|
|
# Revision 1.4 2008-07-24 20:19:43 amon |
639
|
|
|
|
|
|
|
# Just in case I missed anything. |
640
|
|
|
|
|
|
|
# |
641
|
|
|
|
|
|
|
# Revision 1.3 2008-07-24 13:35:26 amon |
642
|
|
|
|
|
|
|
# switch to NeXT style alloc/init format for FileHash and Entry classes. |
643
|
|
|
|
|
|
|
# |
644
|
|
|
|
|
|
|
# Revision 1.2 2008-07-23 21:12:24 amon |
645
|
|
|
|
|
|
|
# Moved notes out of file headers; a few doc updates; added assertion checks; |
646
|
|
|
|
|
|
|
# minor bug fixes. |
647
|
|
|
|
|
|
|
# |
648
|
|
|
|
|
|
|
# 20080625 Dale Amon |
649
|
|
|
|
|
|
|
# Created. |
650
|
|
|
|
|
|
|
1; |