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