#!/usr/bin/perl
    eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
	if $running_under_some_shell;
#!/usr/bin/perl

# zipdetails
#
# Display info on the contents of a Zip file
#

BEGIN { pop @INC if $INC[-1] eq '.' }
use strict;
use warnings ;

use IO::File;
use Encode;

# Compression types 
use constant ZIP_CM_STORE                      => 0 ;
use constant ZIP_CM_IMPLODE                    => 6 ;
use constant ZIP_CM_DEFLATE                    => 8 ;
use constant ZIP_CM_BZIP2                      => 12 ;
use constant ZIP_CM_LZMA                       => 14 ;
use constant ZIP_CM_PPMD                       => 98 ; 

# General Purpose Flag
use constant ZIP_GP_FLAG_ENCRYPTED_MASK        => (1 << 0) ;
use constant ZIP_GP_FLAG_STREAMING_MASK        => (1 << 3) ;
use constant ZIP_GP_FLAG_PATCHED_MASK          => (1 << 5) ;
use constant ZIP_GP_FLAG_STRONG_ENCRYPTED_MASK => (1 << 6) ;
use constant ZIP_GP_FLAG_LZMA_EOS_PRESENT      => (1 << 1) ;
use constant ZIP_GP_FLAG_LANGUAGE_ENCODING     => (1 << 11) ;

# Internal File Attributes
use constant ZIP_IFA_TEXT_MASK                 => 1;

# Signatures for each of the headers
use constant ZIP_LOCAL_HDR_SIG                 => 0x04034b50;
use constant ZIP_DATA_HDR_SIG                  => 0x08074b50;
use constant ZIP_CENTRAL_HDR_SIG               => 0x02014b50;
use constant ZIP_END_CENTRAL_HDR_SIG           => 0x06054b50;
use constant ZIP64_END_CENTRAL_REC_HDR_SIG     => 0x06064b50;
use constant ZIP64_END_CENTRAL_LOC_HDR_SIG     => 0x07064b50;
use constant ZIP64_ARCHIVE_EXTRA_SIG           => 0x08064b50;
use constant ZIP64_DIGITAL_SIGNATURE_SIG       => 0x05054b50;

use constant ZIP_ARCHIVE_EXTRA_DATA_RECORD_SIG => 0x08064b50;

# Extra sizes
use constant ZIP_EXTRA_HEADER_SIZE          => 2 ;
use constant ZIP_EXTRA_MAX_SIZE             => 0xFFFF ;
use constant ZIP_EXTRA_SUBFIELD_ID_SIZE     => 2 ;
use constant ZIP_EXTRA_SUBFIELD_LEN_SIZE    => 2 ;
use constant ZIP_EXTRA_SUBFIELD_HEADER_SIZE => ZIP_EXTRA_SUBFIELD_ID_SIZE +
                                               ZIP_EXTRA_SUBFIELD_LEN_SIZE;
use constant ZIP_EXTRA_SUBFIELD_MAX_SIZE    => ZIP_EXTRA_MAX_SIZE - 
                                               ZIP_EXTRA_SUBFIELD_HEADER_SIZE;

my %ZIP_CompressionMethods =
    (
          0 => 'Stored',
          1 => 'Shrunk',
          2 => 'Reduced compression factor 1',
          3 => 'Reduced compression factor 2',
          4 => 'Reduced compression factor 3',
          5 => 'Reduced compression factor 4',
          6 => 'Imploded',
          7 => 'Reserved for Tokenizing compression algorithm',
          8 => 'Deflated',
          9 => 'Enhanced Deflating using Deflate64(tm)',
         10 => 'PKWARE Data Compression Library Imploding',
         11 => 'Reserved by PKWARE',
         12 => 'BZIP2 ',
         13 => 'Reserved by PKWARE',
         14 => 'LZMA',
         15 => 'Reserved by PKWARE',
         16 => 'Reserved by PKWARE',
         17 => 'Reserved by PKWARE',
         18 => 'File is compressed using IBM TERSE (new)',
         19 => 'IBM LZ77 z Architecture (PFS)',
         95 => 'XZ',         
         96 => 'WinZip JPEG Compression',
         97 => 'WavPack compressed data',
         98 => 'PPMd version I, Rev 1',
         99 => 'AES Encryption',
     );

my %OS_Lookup = (
    0   => "MS-DOS",
    1   => "Amiga",
    2   => "OpenVMS",
    3   => "Unix",
    4   => "VM/CMS",
    5   => "Atari ST",
    6   => "HPFS (OS/2, NT 3.x)",
    7   => "Macintosh",
    8   => "Z-System",
    9   => "CP/M",
    10  => "Windoxs NTFS or TOPS-20",
    11  => "MVS or NTFS",
    12  => "VSE or SMS/QDOS",
    13  => "Acorn RISC OS",
    14  => "VFAT",
    15  => "alternate MVS",
    16  => "BeOS",
    17  => "Tandem",
    18  => "OS/400",
    19  => "OS/X (Darwin)",
    30  => "AtheOS/Syllable",
    );


my %Lookup = (
    ZIP_LOCAL_HDR_SIG,             \&LocalHeader,
    ZIP_DATA_HDR_SIG,              \&DataHeader,
    ZIP_CENTRAL_HDR_SIG,           \&CentralHeader,
    ZIP_END_CENTRAL_HDR_SIG,       \&EndCentralHeader,
    ZIP64_END_CENTRAL_REC_HDR_SIG, \&Zip64EndCentralHeader,
    ZIP64_END_CENTRAL_LOC_HDR_SIG, \&Zip64EndCentralLocator,
    
    # TODO - Archive Encryption Headers
    #ZIP_ARCHIVE_EXTRA_DATA_RECORD_SIG
);

my %Extras = (
      0x0001,  ['ZIP64', \&decode_Zip64],
      0x0007,  ['AV Info', undef],
      0x0008,  ['Extended Language Encoding', undef],
      0x0009,  ['OS/2 extended attributes', undef],
      0x000a,  ['NTFS FileTimes', \&decode_NTFS_Filetimes],
      0x000c,  ['OpenVMS', undef],
      0x000d,  ['Unix', undef],
      0x000e,  ['Stream & Fork Descriptors', undef],
      0x000f,  ['Patch Descriptor', undef],
      0x0014,  ['PKCS#7 Store for X.509 Certificates', undef],
      0x0015,  ['X.509 Certificate ID and Signature for individual file', undef],
      0x0016,  ['X.509 Certificate ID for Central Directory', undef],
      0x0017,  ['Strong Encryption Header', undef],
      0x0018,  ['Record Management Controls', undef],
      0x0019,  ['PKCS#7 Encryption Recipient Certificate List', undef],
      

      # The Header ID mappings defined by Info-ZIP and third parties are:

      0x0065,  ['IBM S/390 attributes - uncompressed', \&decodeMVS],
      0x0066,  ['IBM S/390 attributes - compressed', undef],
      0x07c8,  ['Info-ZIP Macintosh (old, J. Lee)', undef],
      0x2605,  ['ZipIt Macintosh (first version)', undef],
      0x2705,  ['ZipIt Macintosh v 1.3.5 and newer (w/o full filename)', undef],
      0x2805,  ['ZipIt Macintosh v 1.3.5 and newer ', undef],
      0x334d,  ["Info-ZIP Macintosh (new, D. Haase's 'Mac3' field)", undef],
      0x4154,  ['Tandem NSK', undef],
      0x4341,  ['Acorn/SparkFS (David Pilling)', undef],
      0x4453,  ['Windows NT security descriptor', \&decode_NT_security],
      0x4690,  ['POSZIP 4690', undef],
      0x4704,  ['VM/CMS', undef],
      0x470f,  ['MVS', undef],
      0x4854,  ['Theos, old inofficial port', undef],
      0x4b46,  ['FWKCS MD5 (see below)', undef],
      0x4c41,  ['OS/2 access control list (text ACL)', undef],
      0x4d49,  ['Info-ZIP OpenVMS (obsolete)', undef],
      0x4d63,  ['Macintosh SmartZIP, by Macro Bambini', undef],
      0x4f4c,  ['Xceed original location extra field', undef],
      0x5356,  ['AOS/VS (binary ACL)', undef],
      0x5455,  ['Extended Timestamp', \&decode_UT],
      0x554e,  ['Xceed unicode extra field', \&decode_Xceed_unicode],
      0x5855,  ['Info-ZIP Unix (original; also OS/2, NT, etc.)', \&decode_UX],
      0x5a4c,  ['ZipArchive Unicode Filename', undef],
      0x5a4d,  ['ZipArchive Offsets Array', undef],
      0x6375,  ['Info-ZIP Unicode Comment', \&decode_up ],
      0x6542,  ['BeOS (BeBox, PowerMac, etc.)', undef],
      0x6854,  ['Theos', undef],
      0x7075,  ['Info-ZIP Unicode Path', \&decode_up ],
      0x756e,  ['ASi Unix', undef],
      0x7441,  ['AtheOS (AtheOS/Syllable attributes)', undef],
      0x7855,  ['Unix Extra type 2', \&decode_Ux],
      0x7875,  ['Unix Extra Type 3', \&decode_ux],
      0x9901,  ['AES Encryption', \&decode_AES],
      0xa11e,  ['Data Stream Alignment', undef],
      0xA220,  ['Open Packaging Growth Hint', undef ],
      0xCAFE,  ['Java Executable', \&decode_Java_exe],
      0xfb4a,  ['SMS/QDOS', undef],

       );

my $VERSION = "1.11" ;

my $FH;

my $ZIP64 = 0 ;
my $NIBBLES = 8;
my $LocalHeaderCount = 0;
my $CentralHeaderCount = 0;

my $START;
my $OFFSET = new U64 0;
my $TRAILING = 0 ;
my $PAYLOADLIMIT = 256; #new U64 256;
my $ZERO = new U64 0 ;

sub prOff
{
    my $offset = shift;
    my $s = offset($OFFSET);
    $OFFSET->add($offset);
    return $s;
}

sub offset
{
    my $v = shift ;

    if (ref $v eq 'U64') {
        my $hi = $v->getHigh();
        my $lo = $v->getLow();

        if ($hi)
        {
            my $hiNib = $NIBBLES - 8 ;
            sprintf("%0${hiNib}X", $hi) .
            sprintf("%08X", $lo);
        }
        else
        {
            sprintf("%0${NIBBLES}X", $lo);
        }
    }
    else {
        sprintf("%0${NIBBLES}X", $v);
    }

}

my ($OFF,  $LENGTH,  $CONTENT, $TEXT, $VALUE) ;

my $FMT1 ;
my $FMT2 ;

sub setupFormat
{
    my $wantVerbose = shift ;
    my $nibbles = shift;
    
    my $width = '@' . ('>' x ($nibbles -1));
    my $space = " " x length($width);

    my $fmt ;
    
    if ($wantVerbose) {
        
        $FMT1 = "
        format STDOUT =
$width $width ^<<<<<<<<<<<^<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
\$OFF,     \$LENGTH,  \$CONTENT, \$TEXT,               \$VALUE
$space $space ^<<<<<<<<<<<^<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
                    \$CONTENT, \$TEXT,               \$VALUE
.                    
";
                    
        $FMT2 = "
        format STDOUT =
$width $width ^<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
\$OFF,     \$LENGTH,  \$CONTENT, \$TEXT,               \$VALUE
$space $space ^<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
              \$CONTENT, \$TEXT,               \$VALUE
.  " ;

    }
    else {

        $FMT1 = "
        format STDOUT =
$width ^<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
\$OFF,      \$TEXT,               \$VALUE
$space ^<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
                    \$TEXT,               \$VALUE
.
";

        $FMT2 = "
    format STDOUT =
$width   ^<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
\$OFF,     \$TEXT,               \$VALUE
$space   ^<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
                    \$TEXT,               \$VALUE
.
" ;
    }

    eval "$FMT1";
    
    $| = 1;

}

sub mySpr
{    
    my $format = shift ;
    
    return "" if ! defined $format;
    return $format unless @_ ;
    return sprintf $format, @_ ;
}

sub out0
{
    my $size = shift;
    my $text = shift;
    my $format = shift;
    
    $OFF     = prOff($size);
    $LENGTH  = offset($size) ;
    $CONTENT = '...';
    $TEXT    = $text;
    $VALUE   = mySpr $format,  @_;
       
    write;

    skip($FH, $size);
}

sub xDump
{
    my $input = shift;

    $input =~ tr/\0-\37\177-\377/./;
    return $input;
}

sub hexDump
{
    my $input = shift;

    my $out = unpack('H*', $input) ;   
    $out =~ s#(..)# $1#g ;
    $out =~ s/^ //;
    $out = uc $out;  

    return $out;
}

sub out
{
    my $data = shift;
    my $text = shift;
    my $format = shift;
    
    my $size = length($data) ;

    $OFF     = prOff($size);
    $LENGTH  = offset($size) ;
    $CONTENT = hexDump($data);
    $TEXT    = $text;
    $VALUE   = mySpr $format,  @_;
       
    no warnings;

    write;
}

sub out1
{
    my $text = shift;
    my $format = shift;
      
    $OFF     = '';
    $LENGTH  = '' ;
    $CONTENT = '';
    $TEXT    = $text;    
    $VALUE   = mySpr $format,  @_; 

    write;
}

sub out2
{
    my $data = shift ;
    my $text = shift ;
    my $format = shift;
      
    my $size = length($data) ;
    $OFF     = prOff($size);
    $LENGTH  = offset($size);
    $CONTENT = hexDump($data);
    $TEXT    = $text;    
    $VALUE   = mySpr $format,  @_; 

    no warnings;
    eval "$FMT2";
    write ;
    eval "$FMT1";
}

sub Value
{
    my $letter = shift;
    my @value = @_;

    if ($letter eq 'C')
      { return Value_C(@value) }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       