X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=dev%2Farm%2Flibarchive-zip-perl%2Flibarchive-zip-perl-1.18%2Fexamples%2Fzipinfo.pl;fp=dev%2Farm%2Flibarchive-zip-perl%2Flibarchive-zip-perl-1.18%2Fexamples%2Fzipinfo.pl;h=2f44d8bcb83128f604767a21e5e523e896ef1bcf;hb=f477fa73365d491991707e7ed9217b48d6994551;hp=0000000000000000000000000000000000000000;hpb=da95c414033799c3a62606f299c3c00b5c77ca11;p=dh-make-perl diff --git a/dev/arm/libarchive-zip-perl/libarchive-zip-perl-1.18/examples/zipinfo.pl b/dev/arm/libarchive-zip-perl/libarchive-zip-perl-1.18/examples/zipinfo.pl new file mode 100644 index 0000000..2f44d8b --- /dev/null +++ b/dev/arm/libarchive-zip-perl/libarchive-zip-perl-1.18/examples/zipinfo.pl @@ -0,0 +1,147 @@ +#! /usr/bin/perl -w +# Print out information about a ZIP file. +# Note that this buffers the entire file into memory! +# usage: +# perl examples/zipinfo.pl zipfile.zip + +use strict; + +use Data::Dumper (); +use FileHandle; +use Archive::Zip qw(:ERROR_CODES :CONSTANTS :PKZIP_CONSTANTS); +use Archive::Zip::BufferedFileHandle; + +$| = 1; + +### Workaround for a bug in version of Data::Dumper bundled +### with some versions of Perl, which causes warnings when +### calling ->Seen below. +if ( defined &Data::Dumper::init_refaddr_format ) { + Data::Dumper::init_refaddr_format(); +} + +# use constant END_OF_CENTRAL_DIRECTORY_SIGNATURE_STRING; +use constant CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE_STRING => pack( SIGNATURE_FORMAT, + CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE ); +use constant LOCAL_FILE_HEADER_SIGNATURE_STRING => pack( SIGNATURE_FORMAT, + LOCAL_FILE_HEADER_SIGNATURE ); + +$Data::Dumper::Useqq = 1; # enable double-quotes for string values +$Data::Dumper::Indent = 1; + +my $zip = Archive::Zip->new(); +my $zipFileName = shift(@ARGV); + +my $fh = Archive::Zip::BufferedFileHandle->new(); +$fh->readFromFile($zipFileName) or exit($!); + +my $status = $zip->_findEndOfCentralDirectory($fh); +die("can't find EOCD\n") if $status != AZ_OK; + +my $eocdPosition = $fh->tell( ); + +$status = $zip->_readEndOfCentralDirectory($fh); +die("can't read EOCD\n") if $status != AZ_OK; + +my $zipDumper = Data::Dumper->new([$zip], ['ZIP']); +$zipDumper->Seen({ ref($fh), $fh }); +print $zipDumper->Dump(), "\n"; + +my $expectedEOCDPosition = $zip->centralDirectoryOffsetWRTStartingDiskNumber() + + $zip->centralDirectorySize(); + +my $eocdOffset = $zip->{eocdOffset} = $eocdPosition - $expectedEOCDPosition; + +if ($eocdOffset) +{ + printf "Expected EOCD at %d (0x%x) but found it at %d (0x%x)\n", + ($expectedEOCDPosition) x 2, ($eocdPosition) x 2; +} +else +{ + printf("Found EOCD at %d (0x%x)\n\n", ($eocdPosition) x 2); +} + +my $contents = $fh->contents(); +my $offset = $eocdPosition + $eocdOffset - 1; +my $cdPos; +my @members; +my $numberOfMembers = $zip->numberOfCentralDirectoriesOnThisDisk(); +foreach my $n (0 .. $numberOfMembers - 1) +{ + my $index = $numberOfMembers - $n; + $cdPos = rindex($contents, + CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE_STRING, $offset); + if ($cdPos < 0) + { + print "No central directory found for member #$index\n"; + last; + } + else + { + print "Found central directory for member #$index at $cdPos\n"; + $fh->seek($cdPos + SIGNATURE_LENGTH, 0); # SEEK_SET + my $newMember = $zip->ZIPMEMBERCLASS->_newFromZipFile( + $fh, "($zipFileName)" ); + $status = $newMember->_readCentralDirectoryFileHeader(); + if ($status != AZ_OK and $status != AZ_STREAM_END) + { + printf "read CD header status=%d\n", $status; + last; + } + unshift(@members, $newMember); + + my $memberDumper = Data::Dumper->new([$newMember], ['CDMEMBER' . $index ]); + $memberDumper->Seen({ ref($fh), $fh }); + print $memberDumper->Dump(), "\n"; + } + $offset = $cdPos - 1; +} + +if ($cdPos >= 0 and + $cdPos != $zip->centralDirectoryOffsetWRTStartingDiskNumber()) +{ + printf "Expected to find central directory at %d (0x%x), but found it at %d (0x%x)\n", + ($zip->centralDirectoryOffsetWRTStartingDiskNumber()) x 2, + ($cdPos) x 2; +} + +print "\n"; + +# Now read the local headers + +foreach my $n (0 .. $#members) +{ + my $member = $members[$n]; + $fh->seek($member->localHeaderRelativeOffset() + $eocdOffset + SIGNATURE_LENGTH, 0); + $status = $member->_readLocalFileHeader(); + if ($status != AZ_OK and $status != AZ_STREAM_END) + { + printf "member %d read header status=%d\n", $n+1, $status; + last; + } + + my $memberDumper = Data::Dumper->new([$member], ['LHMEMBER' . ($n + 1)]); + $memberDumper->Seen({ ref($fh), $fh }); + print $memberDumper->Dump(), "\n"; + + my $endOfMember = $member->localHeaderRelativeOffset() + + $member->_localHeaderSize() + + $member->compressedSize(); + + if ($endOfMember > $cdPos + or ($n < $#members and + $endOfMember > $members[$n+1]->localHeaderRelativeOffset())) + { + print "Error: "; + } + printf("End of member: %d, CD at %d", $endOfMember, $cdPos); + if ( $n < $#members ) + { + printf(", next member starts at %d", + $members[$n+1]->localHeaderRelativeOffset()); + } + print("\n\n"); +} + +# vim: ts=4 sw=4