File Coverage

blib/lib/Archive/Zip.pm
Criterion Covered Total %
statement 399 418 95.4
branch 38 78 48.7
condition 21 38 55.2
subroutine 118 120 98.3
pod 6 6 100.0
total 582 660 88.1


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