File Coverage

blib/lib/Archive/Zip.pm
Criterion Covered Total %
statement 398 425 93.6
branch 36 80 45.0
condition 21 38 55.2
subroutine 118 122 96.7
pod 6 6 100.0
total 579 671 86.2


line stmt bran cond sub pod time code
1             package Archive::Zip;
2              
3 28     28   1835639 use 5.006;
  28         327  
4 28     28   150 use strict;
  28         46  
  28         649  
5 28     28   175 use Carp ();
  28         57  
  28         577  
6 28     28   157 use Cwd ();
  28         59  
  28         504  
7 28     28   12400 use IO::File ();
  28         201383  
  28         620  
8 28     28   213 use IO::Seekable ();
  28         52  
  28         389  
9 28     28   16866 use Compress::Raw::Zlib ();
  28         141234  
  28         725  
10 28     28   193 use File::Spec ();
  28         51  
  28         376  
11 28     28   18576 use File::Temp ();
  28         332531  
  28         716  
12 28     28   11604 use FileHandle ();
  28         23482  
  28         793  
13              
14 28     28   176 use vars qw( $VERSION @ISA );
  28         47  
  28         1638  
15              
16             BEGIN {
17 28     28   93 $VERSION = '1.68';
18              
19 28         116 require Exporter;
20 28         1020 @ISA = qw( Exporter );
21             }
22              
23 28     28   150 use vars qw( $ChunkSize $ErrorHandler );
  28         55  
  28         1374  
24              
25             BEGIN {
26             # This is the size we'll try to read, write, and (de)compress.
27             # You could set it to something different if you had lots of memory
28             # and needed more speed.
29 28   50 28   242 $ChunkSize ||= 32768;
30              
31 28         533 $ErrorHandler = \&Carp::carp;
32             }
33              
34             # BEGIN block is necessary here so that other modules can use the constants.
35 28     28   137 use vars qw( @EXPORT_OK %EXPORT_TAGS );
  28         56  
  28         5498  
36              
37             BEGIN {
38 28     28   128 @EXPORT_OK = ('computeCRC32');
39 28         608 %EXPORT_TAGS = (
40             CONSTANTS => [
41             qw(
42             ZIP64_SUPPORTED
43             FA_MSDOS
44             FA_UNIX
45             GPBF_ENCRYPTED_MASK
46             GPBF_DEFLATING_COMPRESSION_MASK
47             GPBF_HAS_DATA_DESCRIPTOR_MASK
48             COMPRESSION_STORED
49             COMPRESSION_DEFLATED
50             COMPRESSION_LEVEL_NONE
51             COMPRESSION_LEVEL_DEFAULT
52             COMPRESSION_LEVEL_FASTEST
53             COMPRESSION_LEVEL_BEST_COMPRESSION
54             IFA_TEXT_FILE_MASK
55             IFA_TEXT_FILE
56             IFA_BINARY_FILE
57             ZIP64_AS_NEEDED
58             ZIP64_EOCD
59             ZIP64_HEADERS
60             )
61             ],
62              
63             MISC_CONSTANTS => [
64             qw(
65             FA_AMIGA
66             FA_VAX_VMS
67             FA_VM_CMS
68             FA_ATARI_ST
69             FA_OS2_HPFS
70             FA_MACINTOSH
71             FA_Z_SYSTEM
72             FA_CPM
73             FA_TOPS20
74             FA_WINDOWS_NTFS
75             FA_QDOS
76             FA_ACORN
77             FA_VFAT
78             FA_MVS
79             FA_BEOS
80             FA_TANDEM
81             FA_THEOS
82             GPBF_IMPLODING_8K_SLIDING_DICTIONARY_MASK
83             GPBF_IMPLODING_3_SHANNON_FANO_TREES_MASK
84             GPBF_IS_COMPRESSED_PATCHED_DATA_MASK
85             COMPRESSION_SHRUNK
86             DEFLATING_COMPRESSION_NORMAL
87             DEFLATING_COMPRESSION_MAXIMUM
88             DEFLATING_COMPRESSION_FAST
89             DEFLATING_COMPRESSION_SUPER_FAST
90             COMPRESSION_REDUCED_1
91             COMPRESSION_REDUCED_2
92             COMPRESSION_REDUCED_3
93             COMPRESSION_REDUCED_4
94             COMPRESSION_IMPLODED
95             COMPRESSION_TOKENIZED
96             COMPRESSION_DEFLATED_ENHANCED
97             COMPRESSION_PKWARE_DATA_COMPRESSION_LIBRARY_IMPLODED
98             )
99             ],
100              
101             ERROR_CODES => [
102             qw(
103             AZ_OK
104             AZ_STREAM_END
105             AZ_ERROR
106             AZ_FORMAT_ERROR
107             AZ_IO_ERROR
108             )
109             ],
110              
111             # For Internal Use Only
112             PKZIP_CONSTANTS => [
113             qw(
114             SIGNATURE_FORMAT
115             SIGNATURE_LENGTH
116              
117             LOCAL_FILE_HEADER_SIGNATURE
118             LOCAL_FILE_HEADER_FORMAT
119             LOCAL_FILE_HEADER_LENGTH
120              
121             DATA_DESCRIPTOR_SIGNATURE
122             DATA_DESCRIPTOR_FORMAT
123             DATA_DESCRIPTOR_LENGTH
124             DATA_DESCRIPTOR_ZIP64_FORMAT
125             DATA_DESCRIPTOR_ZIP64_LENGTH
126              
127             DATA_DESCRIPTOR_FORMAT_NO_SIG
128             DATA_DESCRIPTOR_LENGTH_NO_SIG
129             DATA_DESCRIPTOR_ZIP64_FORMAT_NO_SIG
130             DATA_DESCRIPTOR_ZIP64_LENGTH_NO_SIG
131              
132             CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE
133             CENTRAL_DIRECTORY_FILE_HEADER_FORMAT
134             CENTRAL_DIRECTORY_FILE_HEADER_LENGTH
135              
136             ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIGNATURE
137             ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_FORMAT
138             ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_LENGTH
139              
140             ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE
141             ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_FORMAT
142             ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LENGTH
143              
144             END_OF_CENTRAL_DIRECTORY_SIGNATURE
145             END_OF_CENTRAL_DIRECTORY_FORMAT
146             END_OF_CENTRAL_DIRECTORY_LENGTH
147              
148             ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIGNATURE_STRING
149             ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE_STRING
150             END_OF_CENTRAL_DIRECTORY_SIGNATURE_STRING
151             )
152             ],
153              
154             # For Internal Use Only
155             UTILITY_METHODS => [
156             qw(
157             _error
158             _printError
159             _ioError
160             _formatError
161             _zip64NotSupported
162             _subclassResponsibility
163             _binmode
164             _isSeekable
165             _newFileHandle
166             _readSignature
167             _asZipDirName
168             )
169             ],
170             );
171              
172             # Add all the constant names and error code names to @EXPORT_OK
173 28         3046 Exporter::export_ok_tags(
174             qw(
175             CONSTANTS
176             ERROR_CODES
177             PKZIP_CONSTANTS
178             UTILITY_METHODS
179             MISC_CONSTANTS
180             ));
181              
182             }
183              
184             # Zip64 format support status
185 28     28   186 use constant ZIP64_SUPPORTED => !! eval { pack("Q<", 1) };
  28         64  
  28         60  
  28         2233  
186              
187             # Error codes
188 28     28   174 use constant AZ_OK => 0;
  28         71  
  28         1423  
189 28     28   154 use constant AZ_STREAM_END => 1;
  28         83  
  28         1280  
190 28     28   149 use constant AZ_ERROR => 2;
  28         57  
  28         1302  
191 28     28   155 use constant AZ_FORMAT_ERROR => 3;
  28         52  
  28         1106  
192 28     28   138 use constant AZ_IO_ERROR => 4;
  28         77  
  28         1941  
193              
194             # File types
195             # Values of Archive::Zip::Member->fileAttributeFormat()
196              
197 28     28   188 use constant FA_MSDOS => 0;
  28         54  
  28         1183  
198 28     28   136 use constant FA_AMIGA => 1;
  28         45  
  28         1169  
199 28     28   151 use constant FA_VAX_VMS => 2;
  28         44  
  28         1468  
200 28     28   155 use constant FA_UNIX => 3;
  28         50  
  28         1343  
201 28     28   170 use constant FA_VM_CMS => 4;
  28         54  
  28         1298  
202 28     28   163 use constant FA_ATARI_ST => 5;
  28         44  
  28         1218  
203 28     28   151 use constant FA_OS2_HPFS => 6;
  28         54  
  28         1130  
204 28     28   134 use constant FA_MACINTOSH => 7;
  28         47  
  28         1197  
205 28     28   147 use constant FA_Z_SYSTEM => 8;
  28         65  
  28         1154  
206 28     28   139 use constant FA_CPM => 9;
  28         43  
  28         1375  
207 28     28   157 use constant FA_TOPS20 => 10;
  28         46  
  28         1270  
208 28     28   149 use constant FA_WINDOWS_NTFS => 11;
  28         51  
  28         1193  
209 28     28   151 use constant FA_QDOS => 12;
  28         63  
  28         1514  
210 28     28   170 use constant FA_ACORN => 13;
  28         55  
  28         1278  
211 28     28   146 use constant FA_VFAT => 14;
  28         54  
  28         1236  
212 28     28   161 use constant FA_MVS => 15;
  28         62  
  28         1286  
213 28     28   153 use constant FA_BEOS => 16;
  28         45  
  28         1102  
214 28     28   146 use constant FA_TANDEM => 17;
  28         50  
  28         1192  
215 28     28   149 use constant FA_THEOS => 18;
  28         42  
  28         1377  
216              
217             # general-purpose bit flag masks
218             # Found in Archive::Zip::Member->bitFlag()
219              
220 28     28   149 use constant GPBF_ENCRYPTED_MASK => 1 << 0;
  28         47  
  28         1315  
221 28     28   155 use constant GPBF_DEFLATING_COMPRESSION_MASK => 3 << 1;
  28         71  
  28         1482  
222 28     28   154 use constant GPBF_HAS_DATA_DESCRIPTOR_MASK => 1 << 3;
  28         86  
  28         1346  
223              
224             # deflating compression types, if compressionMethod == COMPRESSION_DEFLATED
225             # ( Archive::Zip::Member->bitFlag() & GPBF_DEFLATING_COMPRESSION_MASK )
226              
227 28     28   140 use constant DEFLATING_COMPRESSION_NORMAL => 0 << 1;
  28         51  
  28         1265  
228 28     28   142 use constant DEFLATING_COMPRESSION_MAXIMUM => 1 << 1;
  28         41  
  28         1338  
229 28     28   157 use constant DEFLATING_COMPRESSION_FAST => 2 << 1;
  28         43  
  28         1302  
230 28     28   153 use constant DEFLATING_COMPRESSION_SUPER_FAST => 3 << 1;
  28         46  
  28         1325  
231              
232             # compression method
233              
234             # these two are the only ones supported in this module
235 28     28   155 use constant COMPRESSION_STORED => 0; # file is stored (no compression)
  28         42  
  28         1162  
236 28     28   149 use constant COMPRESSION_DEFLATED => 8; # file is Deflated
  28         48  
  28         1364  
237 28     28   168 use constant COMPRESSION_LEVEL_NONE => 0;
  28         56  
  28         1421  
238 28     28   151 use constant COMPRESSION_LEVEL_DEFAULT => -1;
  28         53  
  28         1209  
239 28     28   189 use constant COMPRESSION_LEVEL_FASTEST => 1;
  28         48  
  28         1260  
240 28     28   157 use constant COMPRESSION_LEVEL_BEST_COMPRESSION => 9;
  28         48  
  28         1436  
241              
242             # internal file attribute bits
243             # Found in Archive::Zip::Member::internalFileAttributes()
244              
245 28     28   159 use constant IFA_TEXT_FILE_MASK => 1;
  28         53  
  28         1240  
246 28     28   163 use constant IFA_TEXT_FILE => 1;
  28         62  
  28         1562  
247 28     28   232 use constant IFA_BINARY_FILE => 0;
  28         56  
  28         1177  
248              
249             # desired zip64 structures for archive creation
250              
251 28     28   144 use constant ZIP64_AS_NEEDED => 0;
  28         65  
  28         1508  
252 28     28   181 use constant ZIP64_EOCD => 1;
  28         68  
  28         1356  
253 28     28   153 use constant ZIP64_HEADERS => 2;
  28         48  
  28         1189  
254              
255             # PKZIP file format miscellaneous constants (for internal use only)
256 28     28   145 use constant SIGNATURE_FORMAT => "V";
  28         54  
  28         1205  
257 28     28   151 use constant SIGNATURE_LENGTH => 4;
  28         43  
  28         1185  
258              
259             # these lengths are without the signature.
260 28     28   163 use constant LOCAL_FILE_HEADER_SIGNATURE => 0x04034b50;
  28         47  
  28         1197  
261 28     28   152 use constant LOCAL_FILE_HEADER_FORMAT => "v3 V4 v2";
  28         57  
  28         1392  
262 28     28   177 use constant LOCAL_FILE_HEADER_LENGTH => 26;
  28         854  
  28         1310  
263              
264             # PKZIP docs don't mention the signature, but Info-Zip writes it.
265 28     28   161 use constant DATA_DESCRIPTOR_SIGNATURE => 0x08074b50;
  28         42  
  28         1112  
266 28     28   160 use constant DATA_DESCRIPTOR_FORMAT => "V3";
  28         44  
  28         1213  
267 28     28   141 use constant DATA_DESCRIPTOR_LENGTH => 12;
  28         49  
  28         1499  
268 28     28   151 use constant DATA_DESCRIPTOR_ZIP64_FORMAT => "L< Q<2";
  28         46  
  28         2081  
269 28     28   179 use constant DATA_DESCRIPTOR_ZIP64_LENGTH => 20;
  28         47  
  28         1395  
270              
271             # but the signature is apparently optional.
272 28     28   154 use constant DATA_DESCRIPTOR_FORMAT_NO_SIG => "V2";
  28         45  
  28         1083  
273 28     28   142 use constant DATA_DESCRIPTOR_LENGTH_NO_SIG => 8;
  28         42  
  28         1385  
274 28     28   133 use constant DATA_DESCRIPTOR_ZIP64_FORMAT_NO_SIG => "Q<2";
  28         40  
  28         1413  
275 28     28   185 use constant DATA_DESCRIPTOR_ZIP64_LENGTH_NO_SIG => 16;
  28         80  
  28         1292  
276              
277 28     28   153 use constant CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE => 0x02014b50;
  28         77  
  28         1428  
278 28     28   183 use constant CENTRAL_DIRECTORY_FILE_HEADER_FORMAT => "C2 v3 V4 v5 V2";
  28         53  
  28         1270  
279 28     28   153 use constant CENTRAL_DIRECTORY_FILE_HEADER_LENGTH => 42;
  28         68  
  28         1192  
280              
281             # zip64 support
282 28     28   139 use constant ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIGNATURE => 0x06064b50;
  28         45  
  28         1575  
283 28         1378 use constant ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIGNATURE_STRING =>
284 28     28   165 pack("V", ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIGNATURE);
  28         43  
285 28     28   153 use constant ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_FORMAT => "Q< S<2 L<2 Q<4";
  28         61  
  28         1243  
286 28     28   142 use constant ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_LENGTH => 52;
  28         39  
  28         1401  
287              
288 28     28   152 use constant ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE => 0x07064b50;
  28         52  
  28         1484  
289 28         1691 use constant ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE_STRING =>
290 28     28   157 pack("V", ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE);
  28         63  
291 28     28   170 use constant ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_FORMAT => "L< Q< L<";
  28         48  
  28         1384  
292 28     28   158 use constant ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LENGTH => 16;
  28         45  
  28         1161  
293              
294 28     28   141 use constant END_OF_CENTRAL_DIRECTORY_SIGNATURE => 0x06054b50;
  28         42  
  28         1399  
295 28         1657 use constant END_OF_CENTRAL_DIRECTORY_SIGNATURE_STRING =>
296 28     28   153 pack("V", END_OF_CENTRAL_DIRECTORY_SIGNATURE);
  28         42  
297 28     28   156 use constant END_OF_CENTRAL_DIRECTORY_FORMAT => "v4 V2 v";
  28         50  
  28         1158  
298 28     28   136 use constant END_OF_CENTRAL_DIRECTORY_LENGTH => 18;
  28         43  
  28         1302  
299              
300 28     28   153 use constant GPBF_IMPLODING_8K_SLIDING_DICTIONARY_MASK => 1 << 1;
  28         40  
  28         1367  
301 28     28   157 use constant GPBF_IMPLODING_3_SHANNON_FANO_TREES_MASK => 1 << 2;
  28         47  
  28         1464  
302 28     28   158 use constant GPBF_IS_COMPRESSED_PATCHED_DATA_MASK => 1 << 5;
  28         53  
  28         1333  
303              
304             # the rest of these are not supported in this module
305 28     28   155 use constant COMPRESSION_SHRUNK => 1; # file is Shrunk
  28         58  
  28         1418  
306 28     28   182 use constant COMPRESSION_REDUCED_1 => 2; # file is Reduced CF=1
  28         58  
  28         1299  
307 28     28   158 use constant COMPRESSION_REDUCED_2 => 3; # file is Reduced CF=2
  28         47  
  28         1151  
308 28     28   142 use constant COMPRESSION_REDUCED_3 => 4; # file is Reduced CF=3
  28         55  
  28         1159  
309 28     28   142 use constant COMPRESSION_REDUCED_4 => 5; # file is Reduced CF=4
  28         53  
  28         1244  
310 28     28   148 use constant COMPRESSION_IMPLODED => 6; # file is Imploded
  28         56  
  28         1160  
311 28     28   190 use constant COMPRESSION_TOKENIZED => 7; # reserved for Tokenizing compr.
  28         45  
  28         1321  
312 28     28   160 use constant COMPRESSION_DEFLATED_ENHANCED => 9; # reserved for enh. Deflating
  28         63  
  28         1193  
313 28     28   148 use constant COMPRESSION_PKWARE_DATA_COMPRESSION_LIBRARY_IMPLODED => 10;
  28         45  
  28         47126  
314              
315             # Load the various required classes
316             require Archive::Zip::Archive;
317             require Archive::Zip::Member;
318             require Archive::Zip::FileMember;
319             require Archive::Zip::DirectoryMember;
320             require Archive::Zip::ZipFileMember;
321             require Archive::Zip::NewFileMember;
322             require Archive::Zip::StringMember;
323              
324             # Convenience functions
325              
326             sub _ISA ($$) {
327              
328             # Can't rely on Scalar::Util, so use the next best way
329 434     434   623 local $@;
330 434 50       620 !!eval { ref $_[0] and $_[0]->isa($_[1]) };
  434         4375  
331             }
332              
333             sub _CAN ($$) {
334 563     563   829 local $@;
335 563 50       1075 !!eval { ref $_[0] and $_[0]->can($_[1]) };
  563         6270  
336             }
337              
338             #####################################################################
339             # Methods
340              
341             sub new {
342 70     70 1 1118237 my $class = shift;
343 70         791 return Archive::Zip::Archive->new(@_);
344             }
345              
346             sub computeCRC32 {
347 386     386 1 115653 my ($data, $crc);
348              
349 386 50       1403 if (ref($_[0]) eq 'HASH') {
350 0         0 $data = $_[0]->{string};
351 0         0 $crc = $_[0]->{checksum};
352             } else {
353 386         650 $data = shift;
354 386 100       1071 $data = shift if ref($data);
355 386         626 $crc = shift;
356             }
357              
358 386         5390 return Compress::Raw::Zlib::crc32($data, $crc);
359             }
360              
361             # Report or change chunk size used for reading and writing.
362             # Also sets Zlib's default buffer size (eventually).
363             sub setChunkSize {
364 0 0   0 1 0 shift if ref($_[0]) eq 'Archive::Zip::Archive';
365 0 0       0 my $chunkSize = (ref($_[0]) eq 'HASH') ? shift->{chunkSize} : shift;
366 0         0 my $oldChunkSize = $Archive::Zip::ChunkSize;
367 0 0       0 $Archive::Zip::ChunkSize = $chunkSize if ($chunkSize);
368 0         0 return $oldChunkSize;
369             }
370              
371             sub chunkSize {
372 16     16 1 54 return $Archive::Zip::ChunkSize;
373             }
374              
375             sub setErrorHandler {
376 0 0   0 1 0 my $errorHandler = (ref($_[0]) eq 'HASH') ? shift->{subroutine} : shift;
377 0 0       0 $errorHandler = \&Carp::carp unless defined($errorHandler);
378 0         0 my $oldErrorHandler = $Archive::Zip::ErrorHandler;
379 0         0 $Archive::Zip::ErrorHandler = $errorHandler;
380 0         0 return $oldErrorHandler;
381             }
382              
383             ######################################################################
384             # Private utility functions (not methods).
385              
386             sub _printError {
387 12     12   59 my $string = join(' ', @_, "\n");
388 12         23 my $oldCarpLevel = $Carp::CarpLevel;
389 12         29 $Carp::CarpLevel += 2;
390 12         17 &{$ErrorHandler}($string);
  12         62  
391 12         2839 $Carp::CarpLevel = $oldCarpLevel;
392             }
393              
394             # This is called on format errors.
395             sub _formatError {
396 7 50   7   33 shift if ref($_[0]);
397 7         29 _printError('format error:', @_);
398 7         49 return AZ_FORMAT_ERROR;
399             }
400              
401             # This is called on IO errors.
402             sub _ioError {
403 2 50   2   6 shift if ref($_[0]);
404 2         6 _printError('IO error:', @_, ':', $!);
405 2         5 return AZ_IO_ERROR;
406             }
407              
408             # This is called on generic errors.
409             sub _error {
410 3 50   3   11 shift if ref($_[0]);
411 3         12 _printError('error:', @_);
412 3         15 return AZ_ERROR;
413             }
414              
415             # This is called if zip64 format is not supported but would be
416             # required.
417             sub _zip64NotSupported {
418 0 0   0   0 shift if ref($_[0]);
419 0         0 _printError('zip64 format not supported on this Perl interpreter');
420 0         0 return AZ_ERROR;
421             }
422              
423             # Called when a subclass should have implemented
424             # something but didn't
425             sub _subclassResponsibility {
426 0     0   0 Carp::croak("subclass Responsibility\n");
427             }
428              
429             # Try to set the given file handle or object into binary mode.
430             sub _binmode {
431 563     563   985 my $fh = shift;
432 563 50       1179 return _CAN($fh, 'binmode') ? $fh->binmode() : binmode($fh);
433             }
434              
435             # Attempt to guess whether file handle is seekable.
436             # Because of problems with Windows, this only returns true when
437             # the file handle is a real file.
438             sub _isSeekable {
439 103     103   242 my $fh = shift;
440 103 50       610 return 0 unless ref $fh;
441 103 50       497 _ISA($fh, "IO::Scalar") # IO::Scalar objects are brokenly-seekable
442             and return 0;
443 103 50       5922 _ISA($fh, "IO::String")
444             and return 1;
445 103 50       348 if (_ISA($fh, "IO::Seekable")) {
446              
447             # Unfortunately, some things like FileHandle objects
448             # return true for Seekable, but AREN'T!!!!!
449 103 100       260 _ISA($fh, "FileHandle")
450             and return 0;
451 63         275 return 1;
452             }
453              
454             # open my $fh, "+<", \$data;
455 0 0 0     0 ref $fh eq "GLOB" && eval { seek $fh, 0, 1 } and return 1;
  0         0  
456 0 0       0 _CAN($fh, "stat")
457             and return -f $fh;
458 0 0 0     0 return (_CAN($fh, "seek") and _CAN($fh, "tell")) ? 1 : 0;
459             }
460              
461             # Print to the filehandle, while making sure the pesky Perl special global
462             # variables don't interfere.
463             sub _print {
464 3885     3885   8022 my ($self, $fh, @data) = @_;
465              
466 3885         8615 local $\;
467              
468 3885         8508 return $fh->print(@data);
469             }
470              
471             # Return an opened IO::Handle
472             # my ( $status, fh ) = _newFileHandle( 'fileName', 'w' );
473             # Can take a filename, file handle, or ref to GLOB
474             # Or, if given something that is a ref but not an IO::Handle,
475             # passes back the same thing.
476             sub _newFileHandle {
477 524     524   912 my $fd = shift;
478 524         820 my $status = 1;
479 524         714 my $handle;
480              
481 524 100       952 if (ref($fd)) {
482 1 50 33     3 if (_ISA($fd, 'IO::Scalar') or _ISA($fd, 'IO::String')) {
    50 33        
483 0         0 $handle = $fd;
484             } elsif (_ISA($fd, 'IO::Handle') or ref($fd) eq 'GLOB') {
485 1         7 $handle = IO::File->new;
486 1         42 $status = $handle->fdopen($fd, @_);
487             } else {
488 0         0 $handle = $fd;
489             }
490             } else {
491 523         2976 $handle = IO::File->new;
492 523         20682 $status = $handle->open($fd, @_);
493             }
494              
495 524         44469 return ($status, $handle);
496             }
497              
498             # Returns next signature from given file handle, leaves
499             # file handle positioned afterwards.
500             #
501             # In list context, returns ($status, $signature)
502             # ( $status, $signature ) = _readSignature( $fh, $fileName );
503             #
504             # This function returns one of AZ_OK, AZ_IO_ERROR, or
505             # AZ_FORMAT_ERROR and calls the respective error handlers in the
506             # latter two cases. If optional $noFormatError is true, it does
507             # not call the error handler on format error, but only returns
508             # AZ_FORMAT_ERROR.
509             sub _readSignature {
510 359     359   697 my $fh = shift;
511 359         501 my $fileName = shift;
512 359         447 my $expectedSignature = shift; # optional
513 359         448 my $noFormatError = shift; # optional
514              
515 359         439 my $signatureData;
516 359         910 my $bytesRead = $fh->read($signatureData, SIGNATURE_LENGTH);
517 359 50       5130 if ($bytesRead != SIGNATURE_LENGTH) {
518 0         0 return _ioError("reading header signature");
519             }
520 359         1001 my $signature = unpack(SIGNATURE_FORMAT, $signatureData);
521 359         558 my $status = AZ_OK;
522              
523             # compare with expected signature, if any, or any known signature.
524 359 100 100     2750 if (
      100        
      66        
      100        
      66        
      66        
      33        
      66        
525             (defined($expectedSignature) && $signature != $expectedSignature)
526             || ( !defined($expectedSignature)
527             && $signature != CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE
528             && $signature != LOCAL_FILE_HEADER_SIGNATURE
529             && $signature != END_OF_CENTRAL_DIRECTORY_SIGNATURE
530             && $signature != DATA_DESCRIPTOR_SIGNATURE
531             && $signature != ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIGNATURE
532             && $signature != ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE
533             )
534             ) {
535 56 50       128 if (! $noFormatError ) {
536 0         0 my $errmsg = sprintf("bad signature: 0x%08x", $signature);
537 0 0       0 if (_isSeekable($fh)) {
538 0         0 $errmsg .= sprintf(" at offset %d", $fh->tell() - SIGNATURE_LENGTH);
539             }
540              
541 0         0 $status = _formatError("$errmsg in file $fileName");
542             }
543             else {
544 56         84 $status = AZ_FORMAT_ERROR;
545             }
546             }
547              
548 359         1236 return ($status, $signature);
549             }
550              
551             # Utility method to make and open a temp file.
552             # Will create $temp_dir if it does not exist.
553             # Returns file handle and name:
554             #
555             # my ($fh, $name) = Archive::Zip::tempFile();
556             # my ($fh, $name) = Archive::Zip::tempFile('mytempdir');
557             #
558              
559             sub tempFile {
560 1 50   1 1 89 my $dir = (ref($_[0]) eq 'HASH') ? shift->{tempDir} : shift;
561 1 50       20 my ($fh, $filename) = File::Temp::tempfile(
562             SUFFIX => '.zip',
563             UNLINK => 1,
564             $dir ? (DIR => $dir) : ());
565 1 50       507 return (undef, undef) unless $fh;
566 1         4 my ($status, $newfh) = _newFileHandle($fh, 'w+');
567 1         17 $fh->close();
568 1         22 return ($newfh, $filename);
569             }
570              
571             # Return the normalized directory name as used in a zip file (path
572             # separators become slashes, etc.).
573             # Will translate internal slashes in path components (i.e. on Macs) to
574             # underscores. Discards volume names.
575             # When $forceDir is set, returns paths with trailing slashes (or arrays
576             # with trailing blank members).
577             #
578             # If third argument is a reference, returns volume information there.
579             #
580             # input output
581             # . ('.') '.'
582             # ./a ('a') a
583             # ./a/b ('a','b') a/b
584             # ./a/b/ ('a','b') a/b
585             # a/b/ ('a','b') a/b
586             # /a/b/ ('','a','b') a/b
587             # c:\a\b\c.doc ('','a','b','c.doc') a/b/c.doc # on Windows
588             # "i/o maps:whatever" ('i_o maps', 'whatever') "i_o maps/whatever" # on Macs
589             sub _asZipDirName {
590 387     387   779 my $name = shift;
591 387         595 my $forceDir = shift;
592 387         586 my $volReturn = shift;
593 387         6455 my ($volume, $directories, $file) =
594             File::Spec->splitpath(File::Spec->canonpath($name), $forceDir);
595 387 50       1588 $$volReturn = $volume if (ref($volReturn));
596 387         1827 my @dirs = map { $_ =~ y{/}{_}; $_ } File::Spec->splitdir($directories);
  1138         1635  
  1138         2265  
597 387 100       1053 if (@dirs > 0) { pop(@dirs) unless $dirs[-1] } # remove empty component
  382 100       828  
598 387 50       981 push(@dirs, defined($file) ? $file : '');
599              
600             #return wantarray ? @dirs : join ( '/', @dirs );
601              
602 387         1034 my $normalised_path = join '/', @dirs;
603              
604             # Leading directory separators should not be stored in zip archives.
605             # Example:
606             # C:\a\b\c\ a/b/c
607             # C:\a\b\c.txt a/b/c.txt
608             # /a/b/c/ a/b/c
609             # /a/b/c.txt a/b/c.txt
610 387         853 $normalised_path =~ s{^/}{}; # remove leading separator
611              
612 387         1197 return $normalised_path;
613             }
614              
615             # Return an absolute local name for a zip name.
616             # Assume a directory if zip name has trailing slash.
617             # Takes an optional volume name in FS format (like 'a:').
618             #
619             sub _asLocalName {
620 121     121   221 my $name = shift; # zip format
621 121         221 my $volume = shift;
622 121 50       309 $volume = '' unless defined($volume); # local FS format
623              
624 121         390 my @paths = split(/\//, $name);
625 121         296 my $filename = pop(@paths);
626 121 50       244 $filename = '' unless defined($filename);
627 121 50       839 my $localDirs = @paths ? File::Spec->catdir(@paths) : '';
628 121         821 my $localName = File::Spec->catpath($volume, $localDirs, $filename);
629 121 50       285 unless ($volume) {
630 121         3023 $localName = File::Spec->rel2abs($localName, Cwd::getcwd());
631             }
632 121         565 return $localName;
633             }
634              
635             1;
636              
637             __END__