home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / ARCHIVE / HYPER25.ZIP / HYPTV.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1990-09-27  |  12.2 KB  |  437 lines

  1. {$A+,B-,F-,I-,O-,R-,S-,V-}
  2. {$M 16384,0,0}
  3. Program HypTv;
  4. { HypTv - view directory of HYP archives
  5.   <your copyright>
  6.   portions copyright (c) 1990 P. Sawatzki and K.P. Nischke
  7.                          BitNet: IN307@DHAFEU11
  8. }
  9. Uses
  10.   Dos;
  11.  
  12. Type
  13.   LH = Record
  14.          L, H : Word
  15.        End;
  16.   Header_Pointer = ^Header;
  17.   CompressionId = Word;
  18.   Header_Name = (Only_Name, Expanded);
  19.   {-Definition of the Hyper Archive Header}
  20.   Header = Record
  21.              CtrlZ : Char;
  22.              id : CompressionId;
  23.              Version : Byte;
  24.              ArchiveSize,         {Size of Archive including the header}
  25.              OriginSize,          {Size of origin file}
  26.              FDateTime,           {Date and Time of origin file}
  27.              ChkSum : LongInt;    {CheckSum of origin data file}
  28.              FAttr : Byte;        {Attributes of origin file}
  29.              fn: String;          {dynamic!}
  30.            End;
  31.  
  32. Const
  33.   {-undynamic size of every header}
  34.   FixHeaderSize = SizeOf(Char)
  35.                  +SizeOf(CompressionId)
  36.                  +SizeOf(Byte)
  37.                  +4*SizeOf(LongInt)
  38.                  +SizeOf(Byte)
  39.                  +1;
  40.  
  41. Const
  42.   ThisVersion = $25;
  43.   CRLF = #13#10;
  44.   Attention = '! ';
  45.   Name = 'HypTV';
  46.   DefaultArchiveExtension = '.HYP';
  47.   VersionName = Name+' - Utility '+Char(ThisVersion Shr 4+Ord('0'))+
  48.                                '.'+Char(ThisVersion And $F+Ord('0'));
  49.   CopyRight = '<your copyright>'+CRLF+
  50.               'Copyright (c) 1990 P. Sawatzki and K.P. Nischke';
  51.  
  52.   UsageText =
  53.   'Usage: '+Name+' HYP-file'+CRLF+
  54.   CRLF+
  55.   '  fn     = HYP archive.  Default extension is '+DefaultArchiveExtension+CRLF;
  56. Type
  57.   StringPtr = ^String;
  58.   CompressionType = (Stored, Hyper, UnKnown);
  59. Const
  60.   StoredId = Byte('S')+Swap(Byte('T'));
  61.   HyperId  = Byte('H')+Swap(Byte('P'));
  62.  
  63.   {-messages}
  64.   NothingToDo = 'nothing to do!';
  65.   SayError = 'Error';
  66.   SayNothing = '';
  67.  
  68. Const
  69.   normal_exit   = 0;
  70.   nothing_to_do = 1;
  71.   ArchiveError  = 2;
  72.   eCompression  = 3;
  73.   Memory_Error  = 4;
  74.   eCheckSum     = 5;
  75.   eDiskFull     = 14;
  76.   eCreatArc     = 98;
  77.   Input_Error   = 101;
  78. { output_error  = 102; !!! used in Hyper}
  79.   ctrlc_pressed = 255;
  80.  
  81.   wUsage = 10;
  82.  
  83.   ArchiveName : PathStr = '';
  84.   ArchiveOffset : LongInt = 0;
  85. Var
  86.   Hyperfile: File;
  87.  
  88.   CurrentDrive : Char;
  89.  
  90.   Procedure OpenArchive(fname : String);
  91.   Begin
  92.     Assign(Hyperfile, fname);
  93.     Reset(Hyperfile, 1);
  94.     If IoResult <> 0 Then Halt(ArchiveError)
  95.   End;
  96.  
  97.   Procedure CloseArchive;
  98.   Begin
  99.     Close(Hyperfile);
  100.     If IoResult <> 0 Then Halt(Input_Error)
  101.   End;
  102.  
  103.   Function L2S(L : LongInt; size : Byte) : String;
  104.   Var
  105.     s : String;
  106.   Begin
  107.     Str(L:size, s); L2S := s
  108.   End;
  109.  
  110.   Procedure Hypermessage(MsgType : String; Msg : String);
  111.   Begin
  112.     Write(CRLF+#13+Name+': ');
  113.     If MsgType <> SayNothing Then Write(Attention, MsgType, ' ');
  114.     WriteLn(Msg)
  115.   End;
  116.  
  117.   Function CompressionRatio(OriginSize, ArchiveSize : LongInt) : Integer;
  118.   Begin
  119.     If (OriginSize = 0) Or (OriginSize = ArchiveSize) Then
  120.       CompressionRatio := 0
  121.     Else
  122.       If LH(ArchiveSize).H > 327 Then {ArchiveSize > 2^31/100}
  123.         CompressionRatio := 100-ArchiveSize Div (OriginSize Div 100)
  124.     Else
  125.       CompressionRatio := 100-(ArchiveSize*100) Div OriginSize
  126.   End;
  127.  
  128.   Function GetCompression(Var H : Header) : CompressionType;
  129.   Begin
  130.     Case H.id Of
  131.       StoredId : GetCompression := Stored;
  132.       HyperId : GetCompression := Hyper;
  133.     Else
  134.       Halt(eCompression)
  135.     End
  136.   End;
  137.  
  138. Const
  139.   CompressionMethod : Array[CompressionType] Of Array[1..6] Of Char =
  140.   ('Stored','Hyper ','??????');
  141.  
  142.   Function StUpCase(s : String) : String;
  143.   Var
  144.     i : Byte;
  145.   Begin
  146.     For i := 1 To Length(s) Do
  147.       StUpCase[i] := Upcase(s[i]);
  148.     StUpCase[0] := s[0]
  149.   End;
  150.  
  151.   Procedure CheckSfx(SfxName : PathStr);
  152.   {-check for self-extracting archive}
  153.   {-if Sfx Exe: set ArchiveName and ArchiveOffset}
  154.   Var ImageInfo : Record
  155.                     ExeId : Array[0..1] Of Char;
  156.                     Remainder,
  157.                     size : Word
  158.                   End;
  159.     SfxExe : File;
  160.     H : Header;
  161.     rd : Word;
  162.     Err : Boolean;
  163.     AOffset : LongInt;
  164.     ExeId : Array[0..1] Of Char;
  165.  
  166.   Begin Assign(SfxExe, SfxName); Reset(SfxExe, 1);
  167.     If IoResult > 0 Then Exit;
  168.  
  169.     BlockRead(SfxExe, ImageInfo, SizeOf(ImageInfo));
  170.     If ImageInfo.ExeId <> 'MZ' Then Exit;
  171.     AOffset := LongInt(ImageInfo.size-1)*512+ImageInfo.Remainder;
  172.     Seek(SfxExe, AOffset);
  173.     If IoResult > 0 Then Exit;
  174.  
  175.     BlockRead(SfxExe, H, SizeOf(H), rd);
  176.     Err := (IoResult > 0) Or (rd < SizeOf(Header));
  177.     Close(SfxExe);
  178.     If Err Then Exit;
  179.     If H.CtrlZ <> ^Z Then Exit;
  180.  
  181.     ArchiveName := SfxName;
  182.     ArchiveOffset := AOffset
  183.   End;
  184.  
  185.   {  Primitiva für Datei-Header  }
  186.  
  187.   Function Header_Size(Var H : Header) : Word;
  188.   Begin
  189.     With H Do
  190.       Header_Size := FixHeaderSize+Length(fn)
  191.   End;
  192.  
  193.   Procedure Read_Header(Var H : Header; Var f : File);
  194.   Var
  195.     rd : Integer;
  196.   Begin
  197.     BlockRead(f, H, FixHeaderSize, rd);
  198.     If rd <> FixHeaderSize Then Halt(Input_Error);
  199.     With H Do Begin
  200.       BlockRead(f,fn[1], Length(fn), rd);
  201.       If rd <> Length(fn) Then Halt(Input_Error)
  202.     End
  203.   End;
  204.  
  205.   {-Allozieren von Speicherplatz  }
  206. Var
  207.   Low_Address, High_Address : LongInt;
  208.  
  209.   Procedure MemCheck(nBytes : LongInt);
  210.   Begin
  211.     If High_Address-Low_Address < nBytes Then Halt(Memory_Error)
  212.   End;                            (* MemCheck *)
  213.  
  214.   Function lPtr(L : LongInt) : Pointer;
  215.   { Ptr(l Shr 4,l And $F) }
  216.   Inline(
  217.     $58/                          {  pop ax}
  218.     $89/$C2/                      {  mov dx,ax}
  219.     $25/$0F/$00/                  {  and ax,$F}
  220.     $B1/$04/                      {  mov cl,4}
  221.     $D3/$EA/                      {  shr dx,cl}
  222.     $5B/                          {  pop bx}
  223.     $D2/$E3/                      {  shl bl,cl}
  224.     $00/$DE);                     {  add dh,bl}
  225.  
  226.   Function GetHighMem(nBytes : Word) : Pointer;
  227.   Begin
  228.     Dec(High_Address, nBytes);
  229.     MemCheck(0);
  230.     GetHighMem := lPtr(High_Address)
  231.   End;
  232.  
  233.   Procedure Alloc_Mem;
  234.   Const
  235.     seg0 : Word = 0;
  236.     nSegs : Word = 0;
  237.   Begin
  238.     Inline($BB/$FF/$FF/       { mov bx,$FFFF    }
  239.            $B4/$48/           { mov ah,$48      }
  240.            $CD/$21/           { int $21         }
  241.            $89/$1E/>nSegs/    { mov [>nsegs],bx }
  242.            $B4/$48/           { mov ah,$48      }
  243.            $CD/$21/           { int $21         }
  244.            $A3/>seg0);        { mov [>seg0],ax  }
  245.     Low_Address := 16*LongInt(seg0+2*4096);
  246.     High_Address := 16*LongInt(seg0+nSegs);
  247.     MemCheck(0)
  248.   End;                            (* Alloc_Mem *)
  249.  
  250. Var
  251.   archive_header_base : LongInt;
  252.   archive_header_number : Integer;
  253.  
  254.   Procedure Initialize_Archive_Headers;
  255.   Begin
  256.     archive_header_base := High_Address;
  257.     archive_header_number := 0
  258.   End;
  259.  
  260.   Procedure Get_Archive_Headers(Var archive : File);
  261.   Var
  262.     hPtr : Header_Pointer;
  263.     HeadPos : LongInt;
  264.   Begin
  265.     HeadPos := FilePos(archive);
  266.     While Not EoF(archive) Do Begin
  267.       hPtr := GetHighMem(SizeOf(Header));
  268.       Read_Header(hPtr^, archive);
  269.       Inc(HeadPos, hPtr^.ArchiveSize+Header_Size(hPtr^));
  270.       Seek(archive, HeadPos);
  271.       Dec(archive_header_number) (* !!! *)
  272.     End
  273.   End;
  274.  
  275.   Function archive_header_address(hNumber : Integer) : Header_Pointer;
  276.     {-Gibt einen Zeiger auf den "hnumber"-ten Archive-Header zurück.  }
  277.     {-Vorbedingung: archive_header_number ≤ hnumber ≤ -1              }
  278.   Begin
  279.     archive_header_address := lPtr(archive_header_base+LongInt(hNumber)*SizeOf(Header))
  280.   End;                            (* archive_header_address *)
  281.  
  282.   Procedure Free_Archive_Headers;
  283.  
  284.   Begin High_Address := archive_header_base;
  285.     archive_header_number := 0
  286.   End;                            (* Free_Archive_Headers *)
  287.  
  288.   Procedure ViewFilesInArchive(ArchiveName : String);
  289.   Var
  290.     Fcnt : Word;
  291.     SOriginSize, SArchiveSize : LongInt;
  292.     hn : Integer;
  293.     p : Header_Pointer;
  294.  
  295.     Procedure WriteByte(b : Byte);
  296.     Begin
  297.       If b < 10 Then Write('0');
  298.       Write(b)
  299.     End;
  300.  
  301.     Procedure WriteDateTime(dt : LongInt);
  302.       {-Write Date&Time to Output}
  303.     Begin
  304.       With LH(dt) Do Begin
  305.         WriteByte(H And $1F);
  306.         Write('-'); WriteByte((H And $1FF) Shr 5);
  307.         Write('-'); WriteByte((H Shr 9+80));
  308.         Write(' '); WriteByte(L Shr 11);
  309.         Write(':'); WriteByte((L And $7FF) Shr 5);
  310.         Write(' ')
  311.       End
  312.     End;
  313.  
  314.     Procedure WriteAttr(Attr : Byte);
  315.     Const
  316.       AttrSign : Array[0..2] Of Array[Boolean] Of Char = (' r', ' h', ' s');
  317.     Begin
  318.       Write(AttrSign[0, Attr And ReadOnly > 0],
  319.             AttrSign[1, Attr And Hidden > 0],
  320.             AttrSign[2, Attr And SysFile > 0],
  321.             ' ')
  322.     End;
  323.  
  324.   Begin
  325.     If archive_header_number = 0 Then
  326.       WriteLn('No files in archive.')
  327.     Else Begin
  328.       SOriginSize := 0;
  329.       SArchiveSize := 0;
  330.       Fcnt := 0;
  331.  
  332.       WriteLn(CRLF+'Archive: '+ArchiveName+
  333.               CRLF+'Length   Method   Size   Ratio   Date   Time      Name'+
  334.               CRLF+'-------  ------   ------ -----   ----   ----      ----');
  335.  
  336.       For hn := -1 Downto archive_header_number Do
  337.         Begin
  338.           p := archive_header_address(hn);
  339.           With p^ Do Begin
  340.               Inc(Fcnt);
  341.               Inc(SOriginSize, OriginSize);
  342.               Inc(SArchiveSize, ArchiveSize);
  343.  
  344.               Write(OriginSize:7,
  345.                     '  ', CompressionMethod[GetCompression(p^)],
  346.                     ArchiveSize:9,
  347.                     CompressionRatio(OriginSize, ArchiveSize):4, '%  ');
  348.               WriteDateTime(FDateTime);
  349.               WriteAttr(FAttr);
  350.               WriteLn(fn)
  351.             End;
  352.         End;
  353.       WriteLn('-------          -------  ---                     --------');
  354.       WriteLn(SOriginSize:7,
  355.               SArchiveSize:17,
  356.               CompressionRatio(SOriginSize, SArchiveSize):4, '%',
  357.               '':22, Fcnt:3);
  358.       WriteLn;
  359.     End
  360.   End;
  361.  
  362.   Procedure DoIt;
  363.   Var
  364.     sr : SearchRec;
  365.     Cdir : DirStr;
  366.     Cname : NameStr;
  367.     Cext : ExtStr;
  368.   Begin
  369.     Fsplit(StUpCase(ArchiveName), Cdir, Cname, Cext);
  370.     If Cext = '' Then Cext := DefaultArchiveExtension;
  371.     FindFirst(Cdir+Cname+Cext, ReadOnly Or Hidden Or SysFile Or archive, sr);
  372.     If DosError <> 0 Then Halt(nothing_to_do);
  373.  
  374.     While DosError = 0 Do Begin
  375.       ArchiveName := FExpand(Cdir+sr.Name);
  376.       CheckSfx(ArchiveName);      {-Check for EXE-archive}
  377.       OpenArchive(ArchiveName);
  378.       If ArchiveOffset <> 0 Then Seek(Hyperfile, ArchiveOffset);
  379.       Get_Archive_Headers(Hyperfile);
  380.       CloseArchive;
  381.  
  382.       ViewFilesInArchive(ArchiveName);
  383.       Free_Archive_Headers;
  384.       FindNext(sr)
  385.     End
  386.   End;
  387.  
  388. Var
  389.   ExitSave : Pointer;
  390.  
  391.   (*$F+*)
  392.   Procedure ErrorExit;
  393.   Begin ExitProc := ExitSave;
  394.     Case ExitCode Of
  395.       normal_exit : ;
  396.       wUsage : WriteLn(CRLF+UsageText);
  397.       ArchiveError : Hypermessage(SayError, 'in archive, use '+Name+'fix');
  398.       Input_Error : Hypermessage(SayError, 'reading input file');
  399.       eDiskFull : Hypermessage(SayError, 'writing output file. Disk full?');
  400.       Memory_Error : Hypermessage(SayError, 'not enough memory');
  401.       {-------}
  402.       eCompression : Hypermessage(SayError, 'unknown compression method');
  403.       eCreatArc : Hypermessage(SayError, 'creating archive');
  404.       {-------}
  405.       nothing_to_do : Begin Hypermessage(SayNothing, NothingToDo);
  406.                         ExitCode := 0
  407.                       End;
  408.       eCheckSum : Hypermessage(SayError, 'bad checksum');
  409.       ctrlc_pressed : Hypermessage('^C', 'CTRL-C pressed');
  410.     Else Hypermessage(SayError, 'unknown error (code '+L2S(ExitCode, 0)+')')
  411.     End;
  412.     ErrorAddr := Nil
  413.   End;
  414.   (*$F-*)
  415.  
  416.   Procedure Get_Drive;
  417.   Var
  418.     st : String;
  419.   Begin
  420.     GetDir(0, st); CurrentDrive := st[1]
  421.   End;
  422.  
  423. Begin
  424.   ExitSave:= ExitProc;
  425.   ExitProc := @ErrorExit;
  426.   Alloc_Mem;
  427.   Initialize_Archive_Headers;
  428.   Get_Drive;
  429.   ArchiveName:= ParamStr(1);
  430.  
  431.   WriteLn(VersionName+CRLF+
  432.           CopyRight);
  433.   If ArchiveName = '' Then
  434.     Halt(wUsage);
  435.   DoIt
  436. End.
  437.