home *** CD-ROM | disk | FTP | other *** search
- (*----------------------------------------------------------------------*)
- (* Display_Archive_Contents --- Display contents of archive file *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Display_Archive_Contents( ArcFileName : AnyStr );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Display_Archive_Contents *)
- (* *)
- (* Purpose: Displays contents of an archive (.ARC file) *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Display_Archive_Contents( ArcFileName : AnyStr ); *)
- (* *)
- (* ArcFileName --- name of archive file whose contents *)
- (* are to be listed. *)
- (* *)
- (* Calls: *)
- (* *)
- (* Aside from internal subroutines, these routines are required: *)
- (* *)
- (* Long_To_Real --- convert long (32 bit) INTEGER to real *)
- (* Dir_Convert_Date_And_Time *)
- (* --- convert DOS packed date/time to string*)
- (* Display_File_Info --- display information about a file *)
- (* Open_File --- open a file *)
- (* Close_File --- close a file *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- (*----------------------------------------------------------------------*)
- (* Map of Archive file entry header *)
- (*----------------------------------------------------------------------*)
-
- TYPE
- Archive_Entry_Type = RECORD
- Marker : BYTE (* Flags beginning of entry *);
- Version : BYTE (* Compression method *);
- Filename : ARRAY[1..13] OF CHAR (* file and extension *);
- Size : LONGINT (* Compressed size *);
- Date : WORD (* Packed date *);
- Time : WORD (* Packed time *);
- CRC : WORD (* Cyclic Redundancy Check *);
- OLength : LONGINT (* Original length *);
- END;
-
- CONST
- Archive_Header_Length = 29 (* Length of an archive header entry *);
- Archive_Marker = 26 (* Marks start of an archive header *);
-
- VAR
- ArcFile : FILE (* Archive file to be read *);
- Archive_Entry : Archive_Entry_Type (* Header for one file in archive *);
- Archive_Pos : LONGINT (* Current byte offset in archive *);
- Bytes_Read : INTEGER (* # bytes read from archive file *);
- Ierr : INTEGER (* Error flag *);
- Do_Blank_Line : BOOLEAN (* TRUE to print blank line *);
-
- (*----------------------------------------------------------------------*)
- (* Get_Next_Archive_Entry --- Get next header entry in archive *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Get_Next_Archive_Entry( VAR ArcEntry : Archive_Entry_Type;
- VAR Error : INTEGER ) : BOOLEAN;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Function: Get_Next_Archive_Entry *)
- (* *)
- (* Purpose: Gets header information for next file in archive *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* OK := Get_Next_Archive_Entry( VAR ArcEntry : *)
- (* Archive_Entry_Type; *)
- (* VAR Error : INTEGER ); *)
- (* *)
- (* ArcEntry --- Header data for next file in archive *)
- (* Error --- Error flag *)
- (* OK --- TRUE if header successfully found, else FALSE *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Get_Next_Archive_Entry *)
- (* Assume no error to start *)
- Error := 0;
- (* Except first time, move to *)
- (* next supposed header record in *)
- (* archive. *)
-
- IF ( Archive_Pos <> 0 ) THEN
- Seek( ArcFile, Archive_Pos );
-
- (* Read in the file header entry. *)
-
- BlockRead( ArcFile, ArcEntry, Archive_Header_Length, Bytes_Read );
- Error := 0;
- (* If wrong size read, or header marker *)
- (* byte is incorrect, report archive *)
- (* format error. *)
-
- IF ( ( Bytes_Read < Archive_Header_Length ) OR
- ( ArcEntry.Marker <> Archive_Marker ) ) THEN
- Error := Format_Error
- ELSE (* Header looks ok -- see if it *)
- (* is the end of file marker. *)
-
- IF ( ArcEntry.Version = 0 ) THEN
- Error := End_Of_File
- ELSE (* Not end of file marker -- get entry data. *)
- WITH ArcEntry DO
- BEGIN
- (* Get position of next archive header *)
-
- Archive_Pos := Archive_Pos + Size +
- Archive_Header_Length;
-
- (* Adjust for older archives *)
-
- IF ( Version = 1 ) THEN
- BEGIN
- OLength := Size;
- Version := 2;
- Archive_Pos := Archive_Pos - 2;
- END;
-
- END;
- (* Report success/failure to calling *)
- (* routine. *)
-
- Get_Next_Archive_Entry := ( Error = 0 );
-
- END (* Get_Next_Archive_Entry *);
-
- (*----------------------------------------------------------------------*)
- (* Display_Archive_Entry --- Display archive header entry *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Display_Archive_Entry( Archive_Entry : Archive_Entry_Type );
-
- VAR
- SDate : STRING[10];
- STime : STRING[12];
- I : INTEGER;
- FName : AnyStr;
- RLength : LONGINT;
- TimeDate : LONGINT;
- TimeDateW : ARRAY[1..2] OF WORD ABSOLUTE TimeDate;
-
- BEGIN (* Display_Archive_Entry *)
-
- WITH Archive_Entry DO
- BEGIN
- (* Pick up file name *)
-
- Fname := COPY( FileName, 1, POS( #0 , FileName ) - 1 );
-
- (* See if this file matches the *)
- (* entry spec wildcard. Exit if *)
- (* not. *)
-
- IF Use_Entry_Spec THEN
- IF ( NOT Entry_Matches( Fname ) ) THEN
- EXIT;
- (* Make sure room on current page *)
- (* for this entry name. *)
- (* If enough room, print blank *)
- (* line if requested. This will *)
- (* only happen for first file. *)
- IF Do_Blank_Line THEN
- BEGIN
- IF ( Lines_Left < 2 ) THEN
- Display_Page_Titles
- ELSE
- BEGIN
- WRITELN( Output_File );
- Lines_left := Lines_Left - 1;
- END;
- Do_Blank_Line := FALSE;
- END
- ELSE
- IF ( Lines_Left < 1 ) THEN
- Display_Page_Titles;
-
- (* Add '. ' to front if we're *)
- (* expanding ARCs in main listing *)
- IF Expand_Arcs_In THEN
- Fname := '. ' + Fname;
-
- (* Get original file size *)
-
- RLength := Olength;
-
- (* Get date and time of creation *)
-
- TimeDateW[1] := Time;
- TimeDateW[2] := Date;
-
- Dir_Convert_Date_And_Time( TimeDate , SDate , STime );
-
- (* Write out file name, length, date, time *)
-
- WRITE( Output_File , Left_Margin_String, ' ' , FName );
-
- FOR I := LENGTH( FName ) TO 14 DO
- WRITE( Output_File , ' ' );
-
- WRITE ( Output_File , RLength:8, ' ' );
- WRITE ( Output_File , SDate, ' ' );
- WRITE ( Output_File , STime );
- WRITELN( Output_File );
-
- (* Count lines left on page *)
- IF Do_Printer_Format THEN
- Lines_Left := Lines_Left - 1;
-
- (* Increment total entry count *)
-
- Total_Entries := Total_Entries + 1;
-
- (* Increment total space used *)
-
- Total_ESpace := Total_ESpace + RLength;
-
- END;
-
- END (* Display_Archive_Entry *);
-
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Display_Archive_Contents *)
-
- (* Set left margin spacing *)
-
- Left_Margin_String := Left_Margin_String + DUPL( ' ' , ArcLbr_Indent );
-
- (* Set file title *)
-
- File_Title := Left_Margin_String + ' Archive file: ' + ArcFileName;
-
- (* Display archive file's name *)
- IF Do_Printer_Format THEN
- IF ( Lines_Left < 3 ) THEN
- Display_Page_Titles;
- (* If we're listing contents at end *)
- (* of directory, print archive name. *)
- (* Do_Blank_Line flags whether we *)
- (* need to print blank line in entry *)
- (* lister subroutine. If listing *)
- (* inline, then it's true for the *)
- (* first file; otherwise it's false. *)
- (* This is to prevent unnecessary *)
- (* blank lines in output listing *)
- (* when no files are selected from *)
- (* a given archive. *)
- IF ( NOT Expand_Arcs_In ) THEN
- BEGIN
- WRITELN( Output_File ) ;
- WRITE ( Output_File , File_Title );
- Lines_Left := Lines_Left - 2;
- Do_Blank_Line := FALSE;
- END
- ELSE
- Do_Blank_Line := TRUE;
- (* Try opening archive file for processing *)
-
- Open_File( ArcFileName , ArcFile, Archive_Pos, Ierr );
-
- (* Issue error message if open fails *)
- IF ( Ierr <> 0 ) THEN
- BEGIN
- WRITELN( Output_File ,
- DUPL( ' ' , MAX( 0 , MIN( 12 , 13 - LENGTH( ArcFileName ) ) ) ),
- ' Can''t open archive file ',ArcFileName );
- IF Do_Printer_Format THEN
- BEGIN
- Lines_Left := Lines_Left - 1;
- IF ( Lines_Left < 1 ) THEN
- Display_Page_Titles;
- END;
- EXIT;
- END
- ELSE IF ( NOT Expand_Arcs_In ) THEN
- BEGIN
-
- WRITELN( Output_File );
- WRITELN( Output_File );
- (* Count lines left on page *)
- IF Do_Printer_Format THEN
- Lines_Left := Lines_Left - 1;
-
- END;
- (* Loop over entries in archive file *)
-
- WHILE( Get_Next_Archive_Entry( Archive_Entry , Ierr ) ) DO
- Display_Archive_Entry( Archive_Entry );
-
- (* Print blank line after last entry *)
- (* in archive, if we're expanding *)
- (* archives right after listing them, *)
- (* but only if archive had any entries *)
- (* listed. *)
-
- IF ( Expand_Arcs_In AND ( NOT Do_Blank_Line ) ) THEN
- BEGIN
- WRITELN( Output_File );
- IF Do_Printer_Format THEN
- Lines_Left := Lines_Left - 1;
- END;
- (* Close archive file *)
- Close_File( ArcFile );
- (* Restore previous left margin spacing *)
-
- Left_Margin_String := DUPL( ' ' , Left_Margin );
-
- (* No file title *)
- File_Title := '';
-
- END (* Display_Archive_Contents *);