2a31f73f8c553d700d2f78919e0a744079018d07
[p5sagit/p5-mst-13.2.git] / ext / IO_Compress_Zlib / lib / IO / Uncompress / Unzip.pm
1 package IO::Uncompress::Unzip;
2
3 require 5.004 ;
4
5 # for RFC1952
6
7 use strict ;
8 use warnings;
9 use bytes;
10
11 use IO::Uncompress::RawInflate  2.010 ;
12 use IO::Compress::Base::Common  2.010 qw(:Status createSelfTiedObject);
13 use IO::Uncompress::Adapter::Identity 2.010 ;
14 use IO::Compress::Zlib::Extra 2.010 ;
15 use IO::Compress::Zip::Constants 2.010 ;
16
17 use Compress::Raw::Zlib  2.010 qw(crc32) ;
18
19 BEGIN
20 {
21     eval { require IO::Uncompress::Adapter::Bunzip2 ;
22            import  IO::Uncompress::Adapter::Bunzip2 } ;
23 }
24
25
26 require Exporter ;
27
28 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnzipError, %headerLookup);
29
30 $VERSION = '2.010';
31 $UnzipError = '';
32
33 @ISA    = qw(Exporter IO::Uncompress::RawInflate);
34 @EXPORT_OK = qw( $UnzipError unzip );
35 %EXPORT_TAGS = %IO::Uncompress::RawInflate::EXPORT_TAGS ;
36 push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
37 Exporter::export_ok_tags('all');
38
39 %headerLookup = (
40         ZIP_CENTRAL_HDR_SIG,            \&skipCentralDirectory,
41         ZIP_END_CENTRAL_HDR_SIG,        \&skipEndCentralDirectory,
42         ZIP64_END_CENTRAL_REC_HDR_SIG,  \&skipCentralDirectory64Rec,
43         ZIP64_END_CENTRAL_LOC_HDR_SIG,  \&skipCentralDirectory64Loc,
44         ZIP64_ARCHIVE_EXTRA_SIG,        \&skipArchiveExtra,
45         ZIP64_DIGITAL_SIGNATURE_SIG,    \&skipDigitalSignature,
46         );
47
48 sub new
49 {
50     my $class = shift ;
51     my $obj = createSelfTiedObject($class, \$UnzipError);
52     $obj->_create(undef, 0, @_);
53 }
54
55 sub unzip
56 {
57     my $obj = createSelfTiedObject(undef, \$UnzipError);
58     return $obj->_inf(@_) ;
59 }
60
61 sub getExtraParams
62 {
63     use IO::Compress::Base::Common  2.010 qw(:Parse);
64
65     
66     return (
67 #            # Zip header fields
68             'Name'      => [1, 1, Parse_any,       undef],
69
70 #            'Streaming' => [1, 1, Parse_boolean,   1],
71         );    
72 }
73
74 sub ckParams
75 {
76     my $self = shift ;
77     my $got = shift ;
78
79     # unzip always needs crc32
80     $got->value('CRC32' => 1);
81
82     *$self->{UnzipData}{Name} = $got->value('Name');
83
84     return 1;
85 }
86
87
88 sub ckMagic
89 {
90     my $self = shift;
91
92     my $magic ;
93     $self->smartReadExact(\$magic, 4);
94
95     *$self->{HeaderPending} = $magic ;
96
97     return $self->HeaderError("Minimum header size is " . 
98                               4 . " bytes") 
99         if length $magic != 4 ;                                    
100
101     return $self->HeaderError("Bad Magic")
102         if ! _isZipMagic($magic) ;
103
104     *$self->{Type} = 'zip';
105
106     return $magic ;
107 }
108
109
110
111 sub readHeader
112 {
113     my $self = shift;
114     my $magic = shift ;
115
116     my $name =  *$self->{UnzipData}{Name} ;
117     my $hdr = $self->_readZipHeader($magic) ;
118
119     while (defined $hdr)
120     {
121         if (! defined $name || $hdr->{Name} eq $name)
122         {
123             return $hdr ;
124         }
125
126         # skip the data
127         my $buffer;
128         if (*$self->{ZipData}{Streaming}) {
129
130             while (1) {
131
132                 my $b;
133                 my $status = $self->smartRead(\$b, 1024 * 16);
134                 return undef
135                     if $status <= 0 ;
136
137                 my $temp_buf;
138                 my $out;
139                 $status = *$self->{Uncomp}->uncompr(\$b, \$temp_buf, 0, $out);
140
141                 return $self->saveErrorString(undef, *$self->{Uncomp}{Error}, 
142                                                      *$self->{Uncomp}{ErrorNo})
143                     if $self->saveStatus($status) == STATUS_ERROR;                
144
145                 if ($status == STATUS_ENDSTREAM) {
146                     *$self->{Uncomp}->reset();
147                     $self->pushBack($b)  ;
148                     last;
149                 }
150             }
151
152             # skip the trailer
153             $self->smartReadExact(\$buffer, $hdr->{TrailerLength})
154                 or return $self->saveErrorString(undef, "Truncated file");
155         }
156         else {
157             my $c = $hdr->{CompressedLength}->get32bit();
158             $self->smartReadExact(\$buffer, $c)
159                 or return $self->saveErrorString(undef, "Truncated file");
160             $buffer = '';
161         }
162
163         $self->chkTrailer($buffer) == STATUS_OK
164             or return $self->saveErrorString(undef, "Truncated file");
165
166         $hdr = $self->_readFullZipHeader();
167
168         return $self->saveErrorString(undef, "Cannot find '$name'")
169             if $self->smartEof();
170     }
171
172     return undef;
173 }
174
175 sub chkTrailer
176 {
177     my $self = shift;
178     my $trailer = shift;
179
180     my ($sig, $CRC32, $cSize, $uSize) ;
181     my ($cSizeHi, $uSizeHi) = (0, 0);
182     if (*$self->{ZipData}{Streaming}) {
183         $sig   = unpack ("V", substr($trailer, 0, 4));
184         $CRC32 = unpack ("V", substr($trailer, 4, 4));
185
186         if (*$self->{ZipData}{Zip64} ) {
187             $cSize = U64::newUnpack_V64 substr($trailer,  8, 8);
188             $uSize = U64::newUnpack_V64 substr($trailer, 16, 8);
189         }
190         else {
191             $cSize = U64::newUnpack_V32 substr($trailer,  8, 4);
192             $uSize = U64::newUnpack_V32 substr($trailer, 12, 4);
193         }
194
195         return $self->TrailerError("Data Descriptor signature, got $sig")
196             if $sig != ZIP_DATA_HDR_SIG;
197     }
198     else {
199         ($CRC32, $cSize, $uSize) = 
200             (*$self->{ZipData}{Crc32},
201              *$self->{ZipData}{CompressedLen},
202              *$self->{ZipData}{UnCompressedLen});
203     }
204
205     if (*$self->{Strict}) {
206         return $self->TrailerError("CRC mismatch")
207             if $CRC32  != *$self->{ZipData}{CRC32} ;
208
209         return $self->TrailerError("CSIZE mismatch.")
210             if ! $cSize->equal(*$self->{CompSize});
211
212         return $self->TrailerError("USIZE mismatch.")
213             if ! $uSize->equal(*$self->{UnCompSize});
214     }
215
216     my $reachedEnd = STATUS_ERROR ;
217     # check for central directory or end of central directory
218     while (1)
219     {
220         my $magic ;
221         my $got = $self->smartRead(\$magic, 4);
222
223         return $self->saveErrorString(STATUS_ERROR, "Truncated file")
224             if $got != 4 && *$self->{Strict};
225
226         if ($got == 0) {
227             return STATUS_EOF ;
228         }
229         elsif ($got < 0) {
230             return STATUS_ERROR ;
231         }
232         elsif ($got < 4) {
233             $self->pushBack($magic)  ;
234             return STATUS_OK ;
235         }
236
237         my $sig = unpack("V", $magic) ;
238
239         my $hdr;
240         if ($hdr = $headerLookup{$sig})
241         {
242             if (&$hdr($self, $magic) != STATUS_OK ) {
243                 if (*$self->{Strict}) {
244                     return STATUS_ERROR ;
245                 }
246                 else {
247                     $self->clearError();
248                     return STATUS_OK ;
249                 }
250             }
251
252             if ($sig == ZIP_END_CENTRAL_HDR_SIG)
253             {
254                 return STATUS_OK ;
255                 last;
256             }
257         }
258         elsif ($sig == ZIP_LOCAL_HDR_SIG)
259         {
260             $self->pushBack($magic)  ;
261             return STATUS_OK ;
262         }
263         else
264         {
265             # put the data back
266             $self->pushBack($magic)  ;
267             last;
268         }
269     }
270
271     return $reachedEnd ;
272 }
273
274 sub skipCentralDirectory
275 {
276     my $self = shift;
277     my $magic = shift ;
278
279     my $buffer;
280     $self->smartReadExact(\$buffer, 46 - 4)
281         or return $self->TrailerError("Minimum header size is " . 
282                                      46 . " bytes") ;
283
284     my $keep = $magic . $buffer ;
285     *$self->{HeaderPending} = $keep ;
286
287    #my $versionMadeBy      = unpack ("v", substr($buffer, 4-4,  2));
288    #my $extractVersion     = unpack ("v", substr($buffer, 6-4,  2));
289    #my $gpFlag             = unpack ("v", substr($buffer, 8-4,  2));
290    #my $compressedMethod   = unpack ("v", substr($buffer, 10-4, 2));
291    #my $lastModTime        = unpack ("V", substr($buffer, 12-4, 4));
292    #my $crc32              = unpack ("V", substr($buffer, 16-4, 4));
293     my $compressedLength   = unpack ("V", substr($buffer, 20-4, 4));
294     my $uncompressedLength = unpack ("V", substr($buffer, 24-4, 4));
295     my $filename_length    = unpack ("v", substr($buffer, 28-4, 2)); 
296     my $extra_length       = unpack ("v", substr($buffer, 30-4, 2));
297     my $comment_length     = unpack ("v", substr($buffer, 32-4, 2));
298    #my $disk_start         = unpack ("v", substr($buffer, 34-4, 2));
299    #my $int_file_attrib    = unpack ("v", substr($buffer, 36-4, 2));
300    #my $ext_file_attrib    = unpack ("V", substr($buffer, 38-4, 2));
301    #my $lcl_hdr_offset     = unpack ("V", substr($buffer, 42-4, 2));
302
303     
304     my $filename;
305     my $extraField;
306     my $comment ;
307     if ($filename_length)
308     {
309         $self->smartReadExact(\$filename, $filename_length)
310             or return $self->TruncatedTrailer("filename");
311         $keep .= $filename ;
312     }
313
314     if ($extra_length)
315     {
316         $self->smartReadExact(\$extraField, $extra_length)
317             or return $self->TruncatedTrailer("extra");
318         $keep .= $extraField ;
319     }
320
321     if ($comment_length)
322     {
323         $self->smartReadExact(\$comment, $comment_length)
324             or return $self->TruncatedTrailer("comment");
325         $keep .= $comment ;
326     }
327
328     return STATUS_OK ;
329 }
330
331 sub skipArchiveExtra
332 {
333     my $self = shift;
334     my $magic = shift ;
335
336     my $buffer;
337     $self->smartReadExact(\$buffer, 4)
338         or return $self->TrailerError("Minimum header size is " . 
339                                      4 . " bytes") ;
340
341     my $keep = $magic . $buffer ;
342
343     my $size = unpack ("V", $buffer);
344
345     $self->smartReadExact(\$buffer, $size)
346         or return $self->TrailerError("Minimum header size is " . 
347                                      $size . " bytes") ;
348
349     $keep .= $buffer ;
350     *$self->{HeaderPending} = $keep ;
351
352     return STATUS_OK ;
353 }
354
355
356 sub skipCentralDirectory64Rec
357 {
358     my $self = shift;
359     my $magic = shift ;
360
361     my $buffer;
362     $self->smartReadExact(\$buffer, 8)
363         or return $self->TrailerError("Minimum header size is " . 
364                                      8 . " bytes") ;
365
366     my $keep = $magic . $buffer ;
367
368     my ($sizeLo, $sizeHi)  = unpack ("V V", $buffer);
369
370     # TODO - take SizeHi into account
371     $self->smartReadExact(\$buffer, $sizeLo)
372         or return $self->TrailerError("Minimum header size is " . 
373                                      $sizeLo . " bytes") ;
374
375     $keep .= $buffer ;
376     *$self->{HeaderPending} = $keep ;
377
378    #my $versionMadeBy      = unpack ("v",   substr($buffer,  0, 2));
379    #my $extractVersion     = unpack ("v",   substr($buffer,  2, 2));
380    #my $diskNumber         = unpack ("V",   substr($buffer,  4, 4));
381    #my $cntrlDirDiskNo     = unpack ("V",   substr($buffer,  8, 4));
382    #my $entriesInThisCD    = unpack ("V V", substr($buffer, 12, 8));
383    #my $entriesInCD        = unpack ("V V", substr($buffer, 20, 8));
384    #my $sizeOfCD           = unpack ("V V", substr($buffer, 28, 8));
385    #my $offsetToCD         = unpack ("V V", substr($buffer, 36, 8));
386
387     return STATUS_OK ;
388 }
389
390 sub skipCentralDirectory64Loc
391 {
392     my $self = shift;
393     my $magic = shift ;
394
395     my $buffer;
396     $self->smartReadExact(\$buffer, 20 - 4)
397         or return $self->TrailerError("Minimum header size is " . 
398                                      20 . " bytes") ;
399
400     my $keep = $magic . $buffer ;
401     *$self->{HeaderPending} = $keep ;
402
403    #my $startCdDisk        = unpack ("V",   substr($buffer,  4-4, 4));
404    #my $offsetToCD         = unpack ("V V", substr($buffer,  8-4, 8));
405    #my $diskCount          = unpack ("V",   substr($buffer, 16-4, 4));
406
407     return STATUS_OK ;
408 }
409
410 sub skipEndCentralDirectory
411 {
412     my $self = shift;
413     my $magic = shift ;
414
415     my $buffer;
416     $self->smartReadExact(\$buffer, 22 - 4)
417         or return $self->TrailerError("Minimum header size is " . 
418                                      22 . " bytes") ;
419
420     my $keep = $magic . $buffer ;
421     *$self->{HeaderPending} = $keep ;
422
423    #my $diskNumber         = unpack ("v", substr($buffer, 4-4,  2));
424    #my $cntrlDirDiskNo     = unpack ("v", substr($buffer, 6-4,  2));
425    #my $entriesInThisCD    = unpack ("v", substr($buffer, 8-4,  2));
426    #my $entriesInCD        = unpack ("v", substr($buffer, 10-4, 2));
427    #my $sizeOfCD           = unpack ("V", substr($buffer, 12-4, 2));
428    #my $offsetToCD         = unpack ("V", substr($buffer, 16-4, 2));
429     my $comment_length     = unpack ("v", substr($buffer, 20-4, 2));
430
431     
432     my $comment ;
433     if ($comment_length)
434     {
435         $self->smartReadExact(\$comment, $comment_length)
436             or return $self->TruncatedTrailer("comment");
437         $keep .= $comment ;
438     }
439
440     return STATUS_OK ;
441 }
442
443
444 sub _isZipMagic
445 {
446     my $buffer = shift ;
447     return 0 if length $buffer < 4 ;
448     my $sig = unpack("V", $buffer) ;
449     return $sig == ZIP_LOCAL_HDR_SIG ;
450 }
451
452
453 sub _readFullZipHeader($)
454 {
455     my ($self) = @_ ;
456     my $magic = '' ;
457
458     $self->smartReadExact(\$magic, 4);
459
460     *$self->{HeaderPending} = $magic ;
461
462     return $self->HeaderError("Minimum header size is " . 
463                               30 . " bytes") 
464         if length $magic != 4 ;                                    
465
466
467     return $self->HeaderError("Bad Magic")
468         if ! _isZipMagic($magic) ;
469
470     my $status = $self->_readZipHeader($magic);
471     delete *$self->{Transparent} if ! defined $status ;
472     return $status ;
473 }
474
475 sub _readZipHeader($)
476 {
477     my ($self, $magic) = @_ ;
478     my ($HeaderCRC) ;
479     my ($buffer) = '' ;
480
481     $self->smartReadExact(\$buffer, 30 - 4)
482         or return $self->HeaderError("Minimum header size is " . 
483                                      30 . " bytes") ;
484
485     my $keep = $magic . $buffer ;
486     *$self->{HeaderPending} = $keep ;
487
488     my $extractVersion     = unpack ("v", substr($buffer, 4-4,  2));
489     my $gpFlag             = unpack ("v", substr($buffer, 6-4,  2));
490     my $compressedMethod   = unpack ("v", substr($buffer, 8-4,  2));
491     my $lastModTime        = unpack ("V", substr($buffer, 10-4, 4));
492     my $crc32              = unpack ("V", substr($buffer, 14-4, 4));
493     my $compressedLength   = new U64 unpack ("V", substr($buffer, 18-4, 4));
494     my $uncompressedLength = new U64 unpack ("V", substr($buffer, 22-4, 4));
495     my $filename_length    = unpack ("v", substr($buffer, 26-4, 2)); 
496     my $extra_length       = unpack ("v", substr($buffer, 28-4, 2));
497
498     my $filename;
499     my $extraField;
500     my @EXTRA = ();
501     my $streamingMode = ($gpFlag & ZIP_GP_FLAG_STREAMING_MASK) ? 1 : 0 ;
502
503     return $self->HeaderError("Streamed Stored content not supported")
504         if $streamingMode && $compressedMethod == 0 ;
505
506     return $self->HeaderError("Encrypted content not supported")
507         if $gpFlag & (ZIP_GP_FLAG_ENCRYPTED_MASK|ZIP_GP_FLAG_STRONG_ENCRYPTED_MASK);
508
509     return $self->HeaderError("Patch content not supported")
510         if $gpFlag & ZIP_GP_FLAG_PATCHED_MASK;
511
512     *$self->{ZipData}{Streaming} = $streamingMode;
513
514
515     if ($filename_length)
516     {
517         $self->smartReadExact(\$filename, $filename_length)
518             or return $self->TruncatedHeader("Filename");
519         $keep .= $filename ;
520     }
521
522     my $zip64 = 0 ;
523
524     if ($extra_length)
525     {
526         $self->smartReadExact(\$extraField, $extra_length)
527             or return $self->TruncatedHeader("Extra Field");
528
529         my $bad = IO::Compress::Zlib::Extra::parseRawExtra($extraField,
530                                                 \@EXTRA, 1, 0);
531         return $self->HeaderError($bad)
532             if defined $bad;
533
534         $keep .= $extraField ;
535
536         my %Extra ;
537         for (@EXTRA)
538         {
539             $Extra{$_->[0]} = \$_->[1];
540         }
541         
542         if (defined $Extra{ZIP_EXTRA_ID_ZIP64()})
543         {
544             $zip64 = 1 ;
545
546             my $buff = ${ $Extra{ZIP_EXTRA_ID_ZIP64()} };
547
548             # TODO - This code assumes that all the fields in the Zip64
549             # extra field aren't necessarily present. The spec says that
550             # they only exist if the equivalent local headers are -1.
551             # Need to check that info-zip fills out -1 in the local header
552             # correctly.
553
554             if (! $streamingMode) {
555                 my $offset = 0 ;
556
557                 $uncompressedLength = U64::newUnpack_V64 substr($buff,  0, 8)
558                     if $uncompressedLength == 0xFFFF ;
559
560                 $offset += 8 ;
561
562                 $compressedLength = U64::newUnpack_V64 substr($buff, $offset, 8)
563                     if $compressedLength == 0xFFFF ;
564
565                 $offset += 8 ;
566
567                 #my $cheaderOffset = U64::newUnpack_V64 substr($buff, 16, 8);
568                 #my $diskNumber = unpack ("V", substr($buff, 24, 4));
569            }
570         }
571     }
572
573     *$self->{ZipData}{Zip64} = $zip64;
574
575     if (! $streamingMode) {
576         *$self->{ZipData}{Streaming} = 0;
577         *$self->{ZipData}{Crc32} = $crc32;
578         *$self->{ZipData}{CompressedLen} = $compressedLength;
579         *$self->{ZipData}{UnCompressedLen} = $uncompressedLength;
580         *$self->{CompressedInputLengthRemaining} =
581             *$self->{CompressedInputLength} = $compressedLength->get32bit();
582     }
583
584     *$self->{ZipData}{Method} = $compressedMethod;
585     if ($compressedMethod == ZIP_CM_DEFLATE)
586     {
587         *$self->{Type} = 'zip-deflate';
588     }
589     elsif ($compressedMethod == ZIP_CM_BZIP2)
590     {
591     #if (! defined $IO::Uncompress::Adapter::Bunzip2::VERSION)
592         
593         *$self->{Type} = 'zip-bzip2';
594         
595         my $obj = IO::Uncompress::Adapter::Bunzip2::mkUncompObject(
596                                                               );
597
598         *$self->{Uncomp} = $obj;
599         *$self->{ZipData}{CRC32} = crc32(undef);
600
601     }
602     elsif ($compressedMethod == ZIP_CM_STORE)
603     {
604         # TODO -- add support for reading uncompressed
605
606         *$self->{Type} = 'zip-stored';
607         
608         my $obj = IO::Uncompress::Adapter::Identity::mkUncompObject(# $got->value('CRC32'),
609                                                              # $got->value('ADLER32'),
610                                                               );
611
612         *$self->{Uncomp} = $obj;
613
614     }
615     else
616     {
617         return $self->HeaderError("Unsupported Compression format $compressedMethod");
618     }
619
620     return {
621         'Type'               => 'zip',
622         'FingerprintLength'  => 4,
623         #'HeaderLength'       => $compressedMethod == 8 ? length $keep : 0,
624         'HeaderLength'       => length $keep,
625         'Zip64'              => $zip64,
626         'TrailerLength'      => ! $streamingMode ? 0 : $zip64 ? 24 : 16,
627         'Header'             => $keep,
628         'CompressedLength'   => $compressedLength ,
629         'UncompressedLength' => $uncompressedLength ,
630         'CRC32'              => $crc32 ,
631         'Name'               => $filename,
632         'Time'               => _dosToUnixTime($lastModTime),
633         'Stream'             => $streamingMode,
634
635         'MethodID'           => $compressedMethod,
636         'MethodName'         => $compressedMethod == ZIP_CM_DEFLATE 
637                                  ? "Deflated" 
638                                  : $compressedMethod == ZIP_CM_BZIP2
639                                      ? "Bzip2"
640                                      : $compressedMethod == ZIP_CM_STORE
641                                          ? "Stored"
642                                          : "Unknown" ,
643
644 #        'TextFlag'      => $flag & GZIP_FLG_FTEXT ? 1 : 0,
645 #        'HeaderCRCFlag' => $flag & GZIP_FLG_FHCRC ? 1 : 0,
646 #        'NameFlag'      => $flag & GZIP_FLG_FNAME ? 1 : 0,
647 #        'CommentFlag'   => $flag & GZIP_FLG_FCOMMENT ? 1 : 0,
648 #        'ExtraFlag'     => $flag & GZIP_FLG_FEXTRA ? 1 : 0,
649 #        'Comment'       => $comment,
650 #        'OsID'          => $os,
651 #        'OsName'        => defined $GZIP_OS_Names{$os} 
652 #                                 ? $GZIP_OS_Names{$os} : "Unknown",
653 #        'HeaderCRC'     => $HeaderCRC,
654 #        'Flags'         => $flag,
655 #        'ExtraFlags'    => $xfl,
656         'ExtraFieldRaw' => $extraField,
657         'ExtraField'    => [ @EXTRA ],
658
659
660       }
661 }
662
663 sub filterUncompressed
664 {
665     my $self = shift ;
666
667     if (*$self->{ZipData}{Method} == 12) {
668         *$self->{ZipData}{CRC32} = crc32(${$_[0]}, *$self->{ZipData}{CRC32});
669     }
670     else {
671         *$self->{ZipData}{CRC32} = *$self->{Uncomp}->crc32() ;
672     }
673 }    
674
675
676 # from Archive::Zip
677 sub _dosToUnixTime
678 {
679     #use Time::Local 'timelocal_nocheck';
680     use Time::Local 'timelocal';
681
682         my $dt = shift;
683
684         my $year = ( ( $dt >> 25 ) & 0x7f ) + 80;
685         my $mon  = ( ( $dt >> 21 ) & 0x0f ) - 1;
686         my $mday = ( ( $dt >> 16 ) & 0x1f );
687
688         my $hour = ( ( $dt >> 11 ) & 0x1f );
689         my $min  = ( ( $dt >> 5 ) & 0x3f );
690         my $sec  = ( ( $dt << 1 ) & 0x3e );
691
692         # catch errors
693         my $time_t =
694           eval { timelocal( $sec, $min, $hour, $mday, $mon, $year ); };
695         return 0 
696         if $@;
697         return $time_t;
698 }
699
700
701 1;
702
703 __END__
704
705
706 =head1 NAME
707
708 IO::Uncompress::Unzip - Read zip files/buffers
709
710 =head1 SYNOPSIS
711
712     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
713
714     my $status = unzip $input => $output [,OPTS]
715         or die "unzip failed: $UnzipError\n";
716
717     my $z = new IO::Uncompress::Unzip $input [OPTS] 
718         or die "unzip failed: $UnzipError\n";
719
720     $status = $z->read($buffer)
721     $status = $z->read($buffer, $length)
722     $status = $z->read($buffer, $length, $offset)
723     $line = $z->getline()
724     $char = $z->getc()
725     $char = $z->ungetc()
726     $char = $z->opened()
727
728     $status = $z->inflateSync()
729
730     $data = $z->trailingData()
731     $status = $z->nextStream()
732     $data = $z->getHeaderInfo()
733     $z->tell()
734     $z->seek($position, $whence)
735     $z->binmode()
736     $z->fileno()
737     $z->eof()
738     $z->close()
739
740     $UnzipError ;
741
742     # IO::File mode
743
744     <$z>
745     read($z, $buffer);
746     read($z, $buffer, $length);
747     read($z, $buffer, $length, $offset);
748     tell($z)
749     seek($z, $position, $whence)
750     binmode($z)
751     fileno($z)
752     eof($z)
753     close($z)
754
755 =head1 DESCRIPTION
756
757 This module provides a Perl interface that allows the reading of
758 zlib files/buffers.
759
760 For writing zip files/buffers, see the companion module IO::Compress::Zip.
761
762 =head1 Functional Interface
763
764 A top-level function, C<unzip>, is provided to carry out
765 "one-shot" uncompression between buffers and/or files. For finer
766 control over the uncompression process, see the L</"OO Interface">
767 section.
768
769     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
770
771     unzip $input => $output [,OPTS] 
772         or die "unzip failed: $UnzipError\n";
773
774 The functional interface needs Perl5.005 or better.
775
776 =head2 unzip $input => $output [, OPTS]
777
778 C<unzip> expects at least two parameters, C<$input> and C<$output>.
779
780 =head3 The C<$input> parameter
781
782 The parameter, C<$input>, is used to define the source of
783 the compressed data. 
784
785 It can take one of the following forms:
786
787 =over 5
788
789 =item A filename
790
791 If the C<$input> parameter is a simple scalar, it is assumed to be a
792 filename. This file will be opened for reading and the input data
793 will be read from it.
794
795 =item A filehandle
796
797 If the C<$input> parameter is a filehandle, the input data will be
798 read from it.
799 The string '-' can be used as an alias for standard input.
800
801 =item A scalar reference 
802
803 If C<$input> is a scalar reference, the input data will be read
804 from C<$$input>.
805
806 =item An array reference 
807
808 If C<$input> is an array reference, each element in the array must be a
809 filename.
810
811 The input data will be read from each file in turn. 
812
813 The complete array will be walked to ensure that it only
814 contains valid filenames before any data is uncompressed.
815
816 =item An Input FileGlob string
817
818 If C<$input> is a string that is delimited by the characters "<" and ">"
819 C<unzip> will assume that it is an I<input fileglob string>. The
820 input is the list of files that match the fileglob.
821
822 If the fileglob does not match any files ...
823
824 See L<File::GlobMapper|File::GlobMapper> for more details.
825
826 =back
827
828 If the C<$input> parameter is any other type, C<undef> will be returned.
829
830 =head3 The C<$output> parameter
831
832 The parameter C<$output> is used to control the destination of the
833 uncompressed data. This parameter can take one of these forms.
834
835 =over 5
836
837 =item A filename
838
839 If the C<$output> parameter is a simple scalar, it is assumed to be a
840 filename.  This file will be opened for writing and the uncompressed
841 data will be written to it.
842
843 =item A filehandle
844
845 If the C<$output> parameter is a filehandle, the uncompressed data
846 will be written to it.
847 The string '-' can be used as an alias for standard output.
848
849 =item A scalar reference 
850
851 If C<$output> is a scalar reference, the uncompressed data will be
852 stored in C<$$output>.
853
854 =item An Array Reference
855
856 If C<$output> is an array reference, the uncompressed data will be
857 pushed onto the array.
858
859 =item An Output FileGlob
860
861 If C<$output> is a string that is delimited by the characters "<" and ">"
862 C<unzip> will assume that it is an I<output fileglob string>. The
863 output is the list of files that match the fileglob.
864
865 When C<$output> is an fileglob string, C<$input> must also be a fileglob
866 string. Anything else is an error.
867
868 =back
869
870 If the C<$output> parameter is any other type, C<undef> will be returned.
871
872 =head2 Notes
873
874 When C<$input> maps to multiple compressed files/buffers and C<$output> is
875 a single file/buffer, after uncompression C<$output> will contain a
876 concatenation of all the uncompressed data from each of the input
877 files/buffers.
878
879 =head2 Optional Parameters
880
881 Unless specified below, the optional parameters for C<unzip>,
882 C<OPTS>, are the same as those used with the OO interface defined in the
883 L</"Constructor Options"> section below.
884
885 =over 5
886
887 =item C<< AutoClose => 0|1 >>
888
889 This option applies to any input or output data streams to 
890 C<unzip> that are filehandles.
891
892 If C<AutoClose> is specified, and the value is true, it will result in all
893 input and/or output filehandles being closed once C<unzip> has
894 completed.
895
896 This parameter defaults to 0.
897
898 =item C<< BinModeOut => 0|1 >>
899
900 When writing to a file or filehandle, set C<binmode> before writing to the
901 file.
902
903 Defaults to 0.
904
905 =item C<< Append => 0|1 >>
906
907 TODO
908
909 =item C<< MultiStream => 0|1 >>
910
911 If the input file/buffer contains multiple compressed data streams, this
912 option will uncompress the whole lot as a single data stream.
913
914 Defaults to 0.
915
916 =item C<< TrailingData => $scalar >>
917
918 Returns the data, if any, that is present immediately after the compressed
919 data stream once uncompression is complete. 
920
921 This option can be used when there is useful information immediately
922 following the compressed data stream, and you don't know the length of the
923 compressed data stream.
924
925 If the input is a buffer, C<trailingData> will return everything from the
926 end of the compressed data stream to the end of the buffer.
927
928 If the input is a filehandle, C<trailingData> will return the data that is
929 left in the filehandle input buffer once the end of the compressed data
930 stream has been reached. You can then use the filehandle to read the rest
931 of the input file. 
932
933 Don't bother using C<trailingData> if the input is a filename.
934
935 If you know the length of the compressed data stream before you start
936 uncompressing, you can avoid having to use C<trailingData> by setting the
937 C<InputLength> option.
938
939 =back
940
941 =head2 Examples
942
943 To read the contents of the file C<file1.txt.zip> and write the
944 compressed data to the file C<file1.txt>.
945
946     use strict ;
947     use warnings ;
948     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
949
950     my $input = "file1.txt.zip";
951     my $output = "file1.txt";
952     unzip $input => $output
953         or die "unzip failed: $UnzipError\n";
954
955 To read from an existing Perl filehandle, C<$input>, and write the
956 uncompressed data to a buffer, C<$buffer>.
957
958     use strict ;
959     use warnings ;
960     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
961     use IO::File ;
962
963     my $input = new IO::File "<file1.txt.zip"
964         or die "Cannot open 'file1.txt.zip': $!\n" ;
965     my $buffer ;
966     unzip $input => \$buffer 
967         or die "unzip failed: $UnzipError\n";
968
969 To uncompress all files in the directory "/my/home" that match "*.txt.zip" and store the compressed data in the same directory
970
971     use strict ;
972     use warnings ;
973     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
974
975     unzip '</my/home/*.txt.zip>' => '</my/home/#1.txt>'
976         or die "unzip failed: $UnzipError\n";
977
978 and if you want to compress each file one at a time, this will do the trick
979
980     use strict ;
981     use warnings ;
982     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
983
984     for my $input ( glob "/my/home/*.txt.zip" )
985     {
986         my $output = $input;
987         $output =~ s/.zip// ;
988         unzip $input => $output 
989             or die "Error compressing '$input': $UnzipError\n";
990     }
991
992 =head1 OO Interface
993
994 =head2 Constructor
995
996 The format of the constructor for IO::Uncompress::Unzip is shown below
997
998     my $z = new IO::Uncompress::Unzip $input [OPTS]
999         or die "IO::Uncompress::Unzip failed: $UnzipError\n";
1000
1001 Returns an C<IO::Uncompress::Unzip> object on success and undef on failure.
1002 The variable C<$UnzipError> will contain an error message on failure.
1003
1004 If you are running Perl 5.005 or better the object, C<$z>, returned from
1005 IO::Uncompress::Unzip can be used exactly like an L<IO::File|IO::File> filehandle.
1006 This means that all normal input file operations can be carried out with
1007 C<$z>.  For example, to read a line from a compressed file/buffer you can
1008 use either of these forms
1009
1010     $line = $z->getline();
1011     $line = <$z>;
1012
1013 The mandatory parameter C<$input> is used to determine the source of the
1014 compressed data. This parameter can take one of three forms.
1015
1016 =over 5
1017
1018 =item A filename
1019
1020 If the C<$input> parameter is a scalar, it is assumed to be a filename. This
1021 file will be opened for reading and the compressed data will be read from it.
1022
1023 =item A filehandle
1024
1025 If the C<$input> parameter is a filehandle, the compressed data will be
1026 read from it.
1027 The string '-' can be used as an alias for standard input.
1028
1029 =item A scalar reference 
1030
1031 If C<$input> is a scalar reference, the compressed data will be read from
1032 C<$$output>.
1033
1034 =back
1035
1036 =head2 Constructor Options
1037
1038 The option names defined below are case insensitive and can be optionally
1039 prefixed by a '-'.  So all of the following are valid
1040
1041     -AutoClose
1042     -autoclose
1043     AUTOCLOSE
1044     autoclose
1045
1046 OPTS is a combination of the following options:
1047
1048 =over 5
1049
1050 =item C<< AutoClose => 0|1 >>
1051
1052 This option is only valid when the C<$input> parameter is a filehandle. If
1053 specified, and the value is true, it will result in the file being closed once
1054 either the C<close> method is called or the IO::Uncompress::Unzip object is
1055 destroyed.
1056
1057 This parameter defaults to 0.
1058
1059 =item C<< MultiStream => 0|1 >>
1060
1061 Treats the complete zip file/buffer as a single compressed data
1062 stream. When reading in multi-stream mode each member of the zip
1063 file/buffer will be uncompressed in turn until the end of the file/buffer
1064 is encountered.
1065
1066 This parameter defaults to 0.
1067
1068 =item C<< Prime => $string >>
1069
1070 This option will uncompress the contents of C<$string> before processing the
1071 input file/buffer.
1072
1073 This option can be useful when the compressed data is embedded in another
1074 file/data structure and it is not possible to work out where the compressed
1075 data begins without having to read the first few bytes. If this is the
1076 case, the uncompression can be I<primed> with these bytes using this
1077 option.
1078
1079 =item C<< Transparent => 0|1 >>
1080
1081 If this option is set and the input file/buffer is not compressed data,
1082 the module will allow reading of it anyway.
1083
1084 In addition, if the input file/buffer does contain compressed data and
1085 there is non-compressed data immediately following it, setting this option
1086 will make this module treat the whole file/bufffer as a single data stream.
1087
1088 This option defaults to 1.
1089
1090 =item C<< BlockSize => $num >>
1091
1092 When reading the compressed input data, IO::Uncompress::Unzip will read it in
1093 blocks of C<$num> bytes.
1094
1095 This option defaults to 4096.
1096
1097 =item C<< InputLength => $size >>
1098
1099 When present this option will limit the number of compressed bytes read
1100 from the input file/buffer to C<$size>. This option can be used in the
1101 situation where there is useful data directly after the compressed data
1102 stream and you know beforehand the exact length of the compressed data
1103 stream. 
1104
1105 This option is mostly used when reading from a filehandle, in which case
1106 the file pointer will be left pointing to the first byte directly after the
1107 compressed data stream.
1108
1109 This option defaults to off.
1110
1111 =item C<< Append => 0|1 >>
1112
1113 This option controls what the C<read> method does with uncompressed data.
1114
1115 If set to 1, all uncompressed data will be appended to the output parameter
1116 of the C<read> method.
1117
1118 If set to 0, the contents of the output parameter of the C<read> method
1119 will be overwritten by the uncompressed data.
1120
1121 Defaults to 0.
1122
1123 =item C<< Strict => 0|1 >>
1124
1125 This option controls whether the extra checks defined below are used when
1126 carrying out the decompression. When Strict is on, the extra tests are
1127 carried out, when Strict is off they are not.
1128
1129 The default for this option is off.
1130
1131 =back
1132
1133 =head2 Examples
1134
1135 TODO
1136
1137 =head1 Methods 
1138
1139 =head2 read
1140
1141 Usage is
1142
1143     $status = $z->read($buffer)
1144
1145 Reads a block of compressed data (the size the the compressed block is
1146 determined by the C<Buffer> option in the constructor), uncompresses it and
1147 writes any uncompressed data into C<$buffer>. If the C<Append> parameter is
1148 set in the constructor, the uncompressed data will be appended to the
1149 C<$buffer> parameter. Otherwise C<$buffer> will be overwritten.
1150
1151 Returns the number of uncompressed bytes written to C<$buffer>, zero if eof
1152 or a negative number on error.
1153
1154 =head2 read
1155
1156 Usage is
1157
1158     $status = $z->read($buffer, $length)
1159     $status = $z->read($buffer, $length, $offset)
1160
1161     $status = read($z, $buffer, $length)
1162     $status = read($z, $buffer, $length, $offset)
1163
1164 Attempt to read C<$length> bytes of uncompressed data into C<$buffer>.
1165
1166 The main difference between this form of the C<read> method and the
1167 previous one, is that this one will attempt to return I<exactly> C<$length>
1168 bytes. The only circumstances that this function will not is if end-of-file
1169 or an IO error is encountered.
1170
1171 Returns the number of uncompressed bytes written to C<$buffer>, zero if eof
1172 or a negative number on error.
1173
1174 =head2 getline
1175
1176 Usage is
1177
1178     $line = $z->getline()
1179     $line = <$z>
1180
1181 Reads a single line. 
1182
1183 This method fully supports the use of of the variable C<$/> (or
1184 C<$INPUT_RECORD_SEPARATOR> or C<$RS> when C<English> is in use) to
1185 determine what constitutes an end of line. Paragraph mode, record mode and
1186 file slurp mode are all supported. 
1187
1188 =head2 getc
1189
1190 Usage is 
1191
1192     $char = $z->getc()
1193
1194 Read a single character.
1195
1196 =head2 ungetc
1197
1198 Usage is
1199
1200     $char = $z->ungetc($string)
1201
1202 =head2 inflateSync
1203
1204 Usage is
1205
1206     $status = $z->inflateSync()
1207
1208 TODO
1209
1210 =head2 getHeaderInfo
1211
1212 Usage is
1213
1214     $hdr  = $z->getHeaderInfo();
1215     @hdrs = $z->getHeaderInfo();
1216
1217 This method returns either a hash reference (in scalar context) or a list
1218 or hash references (in array context) that contains information about each
1219 of the header fields in the compressed data stream(s).
1220
1221 =head2 tell
1222
1223 Usage is
1224
1225     $z->tell()
1226     tell $z
1227
1228 Returns the uncompressed file offset.
1229
1230 =head2 eof
1231
1232 Usage is
1233
1234     $z->eof();
1235     eof($z);
1236
1237 Returns true if the end of the compressed input stream has been reached.
1238
1239 =head2 seek
1240
1241     $z->seek($position, $whence);
1242     seek($z, $position, $whence);
1243
1244 Provides a sub-set of the C<seek> functionality, with the restriction
1245 that it is only legal to seek forward in the input file/buffer.
1246 It is a fatal error to attempt to seek backward.
1247
1248 The C<$whence> parameter takes one the usual values, namely SEEK_SET,
1249 SEEK_CUR or SEEK_END.
1250
1251 Returns 1 on success, 0 on failure.
1252
1253 =head2 binmode
1254
1255 Usage is
1256
1257     $z->binmode
1258     binmode $z ;
1259
1260 This is a noop provided for completeness.
1261
1262 =head2 opened
1263
1264     $z->opened()
1265
1266 Returns true if the object currently refers to a opened file/buffer. 
1267
1268 =head2 autoflush
1269
1270     my $prev = $z->autoflush()
1271     my $prev = $z->autoflush(EXPR)
1272
1273 If the C<$z> object is associated with a file or a filehandle, this method
1274 returns the current autoflush setting for the underlying filehandle. If
1275 C<EXPR> is present, and is non-zero, it will enable flushing after every
1276 write/print operation.
1277
1278 If C<$z> is associated with a buffer, this method has no effect and always
1279 returns C<undef>.
1280
1281 B<Note> that the special variable C<$|> B<cannot> be used to set or
1282 retrieve the autoflush setting.
1283
1284 =head2 input_line_number
1285
1286     $z->input_line_number()
1287     $z->input_line_number(EXPR)
1288
1289 Returns the current uncompressed line number. If C<EXPR> is present it has
1290 the effect of setting the line number. Note that setting the line number
1291 does not change the current position within the file/buffer being read.
1292
1293 The contents of C<$/> are used to to determine what constitutes a line
1294 terminator.
1295
1296 =head2 fileno
1297
1298     $z->fileno()
1299     fileno($z)
1300
1301 If the C<$z> object is associated with a file or a filehandle, C<fileno>
1302 will return the underlying file descriptor. Once the C<close> method is
1303 called C<fileno> will return C<undef>.
1304
1305 If the C<$z> object is is associated with a buffer, this method will return
1306 C<undef>.
1307
1308 =head2 close
1309
1310     $z->close() ;
1311     close $z ;
1312
1313 Closes the output file/buffer. 
1314
1315 For most versions of Perl this method will be automatically invoked if
1316 the IO::Uncompress::Unzip object is destroyed (either explicitly or by the
1317 variable with the reference to the object going out of scope). The
1318 exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In
1319 these cases, the C<close> method will be called automatically, but
1320 not until global destruction of all live objects when the program is
1321 terminating.
1322
1323 Therefore, if you want your scripts to be able to run on all versions
1324 of Perl, you should call C<close> explicitly and not rely on automatic
1325 closing.
1326
1327 Returns true on success, otherwise 0.
1328
1329 If the C<AutoClose> option has been enabled when the IO::Uncompress::Unzip
1330 object was created, and the object is associated with a file, the
1331 underlying file will also be closed.
1332
1333 =head2 nextStream
1334
1335 Usage is
1336
1337     my $status = $z->nextStream();
1338
1339 Skips to the next compressed data stream in the input file/buffer. If a new
1340 compressed data stream is found, the eof marker will be cleared and C<$.>
1341 will be reset to 0.
1342
1343 Returns 1 if a new stream was found, 0 if none was found, and -1 if an
1344 error was encountered.
1345
1346 =head2 trailingData
1347
1348 Usage is
1349
1350     my $data = $z->trailingData();
1351
1352 Returns the data, if any, that is present immediately after the compressed
1353 data stream once uncompression is complete. It only makes sense to call
1354 this method once the end of the compressed data stream has been
1355 encountered.
1356
1357 This option can be used when there is useful information immediately
1358 following the compressed data stream, and you don't know the length of the
1359 compressed data stream.
1360
1361 If the input is a buffer, C<trailingData> will return everything from the
1362 end of the compressed data stream to the end of the buffer.
1363
1364 If the input is a filehandle, C<trailingData> will return the data that is
1365 left in the filehandle input buffer once the end of the compressed data
1366 stream has been reached. You can then use the filehandle to read the rest
1367 of the input file. 
1368
1369 Don't bother using C<trailingData> if the input is a filename.
1370
1371 If you know the length of the compressed data stream before you start
1372 uncompressing, you can avoid having to use C<trailingData> by setting the
1373 C<InputLength> option in the constructor.
1374
1375 =head1 Importing 
1376
1377 No symbolic constants are required by this IO::Uncompress::Unzip at present. 
1378
1379 =over 5
1380
1381 =item :all
1382
1383 Imports C<unzip> and C<$UnzipError>.
1384 Same as doing this
1385
1386     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1387
1388 =back
1389
1390 =head1 EXAMPLES
1391
1392 =head2 Working with Net::FTP
1393
1394 See L<IO::Uncompress::Unzip::FAQ|IO::Uncompress::Unzip::FAQ/"Compressed files and Net::FTP">
1395
1396 =head2 Walking through a zip file
1397
1398 The code below can be used to traverse a zip file, one compressed data
1399 stream at a time.
1400
1401     use IO::Uncompress::Unzip qw($UnzipError);
1402
1403     my $zipfile = "somefile.zip";
1404     my $u = new IO::Uncompress::Unzip $zipfile
1405         or die "Cannot open $filefile: $UnzipError";
1406
1407     for (my $status = 1; ! $u->eof(); $status = $u->nextStream())
1408  
1409         my $name = $u->getHeaderInfo()->{Name};
1410         warn "Processing member $name\n" ;
1411
1412         my $buff;
1413         while (($status = $u->read($buff)) > 0) {
1414             # Do something here
1415         }
1416
1417         last unless $status == 0;
1418     }
1419
1420     die "Error processing $zipfile: $!\n"
1421         if $status < 0 ;
1422
1423 Each individual compressed data stream is read until the logical
1424 end-of-file is reached. Then C<nextStream> is called. This will skip to the
1425 start of the next compressed data stream and clear the end-of-file flag.
1426
1427 It is also worth noting that C<nextStream> can be called at any time -- you
1428 don't have to wait until you have exhausted a compressed data stream before
1429 skipping to the next one.
1430
1431 =head1 SEE ALSO
1432
1433 L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Compress::Bzip2>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
1434
1435 L<Compress::Zlib::FAQ|Compress::Zlib::FAQ>
1436
1437 L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>,
1438 L<Archive::Tar|Archive::Tar>,
1439 L<IO::Zlib|IO::Zlib>
1440
1441 For RFC 1950, 1951 and 1952 see 
1442 F<http://www.faqs.org/rfcs/rfc1950.html>,
1443 F<http://www.faqs.org/rfcs/rfc1951.html> and
1444 F<http://www.faqs.org/rfcs/rfc1952.html>
1445
1446 The I<zlib> compression library was written by Jean-loup Gailly
1447 F<gzip@prep.ai.mit.edu> and Mark Adler F<madler@alumni.caltech.edu>.
1448
1449 The primary site for the I<zlib> compression library is
1450 F<http://www.zlib.org>.
1451
1452 The primary site for gzip is F<http://www.gzip.org>.
1453
1454 =head1 AUTHOR
1455
1456 This module was written by Paul Marquess, F<pmqs@cpan.org>. 
1457
1458 =head1 MODIFICATION HISTORY
1459
1460 See the Changes file.
1461
1462 =head1 COPYRIGHT AND LICENSE
1463
1464 Copyright (c) 2005-2008 Paul Marquess. All rights reserved.
1465
1466 This program is free software; you can redistribute it and/or
1467 modify it under the same terms as Perl itself.
1468