const
  LOCAL   = $04034B50;
  CENTRAL = $02014B50;
  END_OF  = $06054B50;
{THE following three structures are found in the zip file }
{A signature WILL tell you WHICH follows the signature in the file}
type ZLOCALtype = record       {Zip File Header}
  VerReqd : Word;              {..Version reqd to unzip}
  BitFlag : Word;              {..Bit Flag}
  Method  : Word;              {..Compress Method}
  LModTime: Word;              {..Last Mod Time}
  LModDate: Word;              {..Last Mod Date}
  CRC32   : LongInt;           {..File CRC}
  CmpSize : LongInt;           {..Compressed Size}
  UncmpSz : LongInt;           {..Uncompressed Size}
  FNLen   : Word;              {..File Name Length}
  EFLen   : Word;              {..Extra Field Length}
end;
type ZCENTRALtype = record     {Zip File Header}
  MadeBy  : Word;
  VerReqd : Word;              {..Version reqd to unzip}
  BitFlag : Word;              {..Bit Flag}
  Method  : Word;              {..Compress Method}
  LModTime: Word;              {..Last Mod Time}
  LModDate: Word;              {..Last Mod Date}
  CRC32   : LongInt;           {..File CRC}
  CmpSize : LongInt;           {..Compressed Size}
  UncmpSz : LongInt;           {..Uncompressed Size}
  FNLen   : Word;              {..File Name Length}
  EFLen   : Word;              {..Extra Field Length}
end;
type zCENTRAL2type = record
  DiskNo  : Word;              {..Starting Disk Number}
  IFAttr  : Word;              {..Internal File Attributes}
  EFAttr  : LongInt;           {..External File Attributes}
  LHOff   : LongInt;           {..Offset of local header}
end;
type zENDType = record         {Directory End Record}
  DiskNo  : Word;              {..Number of this disk}
  ZDDisk  : Word;              {..Disk w/ start of dir}
  ZDETD   : Word;              {..Dir ents this disk}
  ZDEnts  : Word;              {..Total dir ents}
  ZDSize  : LongInt;           {..Dir size}
  ZDStart : LongInt;           {..Offset to start of Dir}
  CmtLen  : Word;              {..Zip Comment Length}
end;

var
  zLOCAL   : zLOCALtype;
  zCENTRAL : zCENTRALtype;
  zCENTRAL2: zCENTRAL2type;
  zEND     : zENDtype;
  Fi       : file;
  FIlename : string[12];
  temp     : array[1..16] of char;
  zSignature:longInt;
  I        : integer;
{$I files.inc}  {for opening files easy}
{$I buffer.inc} {Using a full buffer and fake disk reads}
                {Nice when you don't know what structure follows}
                {Fill the buffer and move the info to the structure that fits}
function num2Hex(L : LongInt) : string;
const
  HexChar : array [0..15] of Char = '0123456789ABCDEF';
var
  hexs       : string;
  tByte, I,J : byte;
  start      : boolean;
begin
  HexS := '';
  HexS := HexChar[(L and $F0000000) shr 28] +
          HexChar[(L and $0F000000) shr 24] +
          HexChar[(L and $00F00000) shr 20] +
          HexChar[(L and $000F0000) shr 16] +
          HexChar[(L and $0000F000) shr 12] +
          HexChar[(L and $00000F00) shr  8] +
          HexChar[(L and $000000F0) shr  4] +
          HexChar[(L and $0000000F)       ];
  Start:=False;                 {init}
  j:=0;
  for I:=1 to 8 do
  begin        {rid of leading zeros}
    if hexS[i]<>'0' then Start:=true;
    if start then
    begin
       Inc(j,1);
       HexS[j]:=HexS[i];
    end;
  end;
  move(j,hexS[0],1);            {reset string to new size}
  num2Hex:=HexS;
end; {HexLInt}

begin  {main}
  {Open the file if it exists; else OpenFile returns FALSE}
  if not OpenFile(fi, paramStr(1)) then
  begin
    Writeln('File ', paramStr(1) ,' not found. Check syntax');
    halt;
  end;
  BRead(Fi, Zsignature, 4); {Fills the buffer} {Moves 4 bytes into zSignature}
  if (Zsignature<>LOCAL) and (zSignature<>CENTRAL) then
  begin
     Writeln('File ',ParamStr(1),' does not appear to be a ZIP file.');
     halt;
  end;
  repeat
    {Read the structure that fits the zSignature}
    case zSignature of
     LOCAL :   begin
                 Bread(fi,Zlocal,SizeOf(Zlocal) );
                 Writeln('LOCAL');
               end;
     CENTRAL : begin
                 Bread(fi,ZCentral,SizeOf(Zlocal) );
                 WriteLN('CENTRAL');
               end;
     END_OF  : begin
                 Bread(fi,zEnd,SizeOf(zEnd) );
                 WriteLN('END');
               end;
    end;
    {ALL three have a signature}
    {Writeln('long test ',num2hex(981347578));}
    write('Pksignature:        ');
    write(      ((Zsignature and $F0000000) shr 28) );
    write(' ',  ((Zsignature and $0F000000) shr 24) );
    write(' ',  ((Zsignature and $00F00000) shr 20) );
    write(' ',  ((Zsignature and $000F0000) shr 16) );
    write(' ',  ((Zsignature and $0000F000) shr 12) );
    write(' ',  ((Zsignature and $00000F00) shr 8) );
    write(' ',  ((Zsignature and $000000F0) shr 4) );
    write(' ',  ((Zsignature and $0000000F) ) );
    writeln;
    case zSignature of
     LOCAL :   with zLOCAL DO
               begin
                 write('Version Required:   ',(verReqd div 10),'.' );
                 writeln(VerReqd mod 10);
                 writeln('BitFlag [?]:        ',(bitflag) );
                 writeln('Method Used:        ',(method)  );
                 writeln('Last mod Time:      ',num2hex(LmodTime));
                 writeln('Last mod Date:      ',num2hex(LmodDate));
                 writeln('CRC32:              ',num2hex(Crc32)); {Correct}
                 writeln('Compressed Size:    ',CmpSize);  {correct}
                 writeln('Original Size:      ',UnCmpSz);  {correct}
                 writeln('File name Length:   ',FNlen);    {correct}
                 writeln('Extra field Length: ',EFlen);
                 BRead(Fi,Filename[1],FNlen);
                 move(FNlen,FileName[0],1);     {init the string length}
                 writeln('FileName:           ',FileName); {correct}
                 Bskip(fi,CmpSize);                    {skip the actual zipped part}
               end;
     CENTRAL : begin
                 with zCENTRAL do
                 begin
                   writeln('MAde by version :   ',madeBy);
                   write('Version Required:   ',(verReqd div 10),'.' );
                   writeln(VerReqd mod 10);
                   writeln('BitFlag [?]:        ',(bitflag) );
                   writeln('Method Used:        ',(method)  );
                   writeln('Last mod Time:      ',num2hex(LmodTime));
                   writeln('Last mod Date:      ',num2hex(LmodDate));
                   writeln('CRC32:              ',num2hex(Crc32));
                   writeln('Compressed Size:    ',CmpSize);
                   writeln('Original Size:      ',UnCmpSz);
                   writeln('File name Length:   ',FNlen);
                   writeln('Extra field Length: ',EFlen);
                 end;
                 with zCENTRAL2 do
                 begin
                   BSkip(fi,4); {There's blanks?? why?}
                   Bread(Fi,zCentral2,SizeOf(zCentral2));
                   writeln('Starting Disk #:      ',DiskNo);
                   writeln('Internal File Attr:   ',IFAttr);
                   writeln('External File Attr:   ',EFAttr);
                   writeln('Local header offset:  ',LHoff);
                   BRead(Fi,Filename[1],zCENTRAL.FNlen);
                   move(zCENTRAL.FNlen,FileName[0],1);
                   writeln('FileName:           ',FileName);
                 end;
               end;
     END_OF :  with zEND do
               begin
                 writeln('Disk Number:         ',DiskNo);
                 writeln('Start of directory:  ',ZDDisk);
                 writeln('Total entries, disk: ',ZDETD);
                 writeln('Total Entries:       ',ZDEnts);
                 writeln('Directory Size:      ',ZDSize);
                 writeln('Directory Offset:    ',ZDStart);
                 writeln('Zip Comment Length:  ',CmtLen);
                 break;
               end;
    end;
    readln;
    Bread(fi,zSignature,4);               {read next Zsignature}
  until false;  {WHILE NOT EOF}
  close(fi);
End.

