home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Current Shareware 1994 January
/
SHAR194.ISO
/
dos_util
/
4utils76.zip
/
SCANARJF.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-10-31
|
10KB
|
270 lines
UNIT ScanARJFiles;
{$V-}
(* ----------------------------------------------------------------------
Part of 4DESC - A Simple 4DOS File Description Editor
and 4FF - 4DOS File Finder
(c) 1992, 1993 Copyright by David Frey,
Urdorferstrasse 30
8952 Schlieren ZH
Switzerland
DISCLAIMER: This unit is freeware: you are allowed to use, copy
and change it free of charge, but you may not sell or hire
this part of 4DESC. The copyright remains in our hands.
If you make any (considerable) changes to the source code,
please let us know. (send a copy or a listing).
We would like to see what you have done.
We, David Frey and Tom Bowden, the authors, provide absolutely
no warranty of any kind. The user of this software takes the
entire risk of damages, failures, data losses or other
incidents.
Code created using Turbo Pascal 6.0 (c) Borland International 1990
This unit provides the extraction of file names in .ARJ files.
----------------------------------------------------------------------- *)
INTERFACE USES Dos, Globals;
PROCEDURE SearchInARJFile(FileSpec: FileSpecArrayType; FileSpecs: BYTE;
VAR Dir: PathStr; VAR arjsearch: SearchRec);
PROCEDURE ShowCompARJFileData(VAR search,arjsearch: SearchRec;VAR Path: PathStr;
csize: LONGINT);
VAR OldARJFileName: PathStr;
IMPLEMENTATION USES Objects, Drivers, StringDateHandling;
CONST ARJMagicHeader = $EA60;
VAR ARJFile : FILE;
PROCEDURE SearchInARJFile(FileSpec: FileSpecArrayType; FileSpecs: BYTE;
VAR Dir: PathStr; VAR arjsearch: SearchRec);
VAR i : WORD;
k, dummy : BYTE;
ARJFileName: NameExtStr;
sig : LONGINT;
hsize : WORD;
flags : BYTE;
c : CHAR;
BEGIN (* SearchInARJFile *)
Assign(ARJFile,arjsearch.Name); Reset(ARJFile,1);
BlockRead(ARJFile,Buffer^,BufSize,BytesRead); BufPtr := 0; FilePtr := 0;
sig := LONGINT(ReadByte) SHL 8 + LONGINT(ReadByte);
(* header id (main and local file) = 0xEA60 or 60000U *)
IF sig <> ARJMagicHeader THEN
BEGIN
WriteLn(output,'ARJ file error: magic file header signature missing!');
WriteLn(output);
END;
hsize := 1;
REPEAT
(* header id (main and local file) = 0xEA60 or 60000U *)
REPEAT
REPEAT
sig := ReadByte;
IF BufPtr > BufSize THEN
BEGIN
BlockRead(ARJFile,Buffer^,BufSize,BytesRead); BufPtr := 0;
END;
UNTIL (sig = Lo(ARJMagicHeader)) OR (BufPtr > BytesRead);
REPEAT
sig := ReadByte;
IF BufPtr > BufSize THEN
BEGIN
BlockRead(ARJFile,Buffer^,BufSize,BytesRead); BufPtr := 0;
END;
UNTIL (sig = Hi(ARJMagicHeader)) OR (BufPtr > BytesRead);
UNTIL (sig = Hi(ARJMagicHeader)) OR (BufPtr > BytesRead);
IF sig = Hi(ARJMagicHeader) THEN
BEGIN
hsize := LONGINT(ReadByte) SHL 8 + LONGINT(ReadByte);
(* 2 basic header size (from 'first_hdr_size' thru 'comment' below)
= first_hdr_size + strlen(filename) + 1 + strlen(comment) + 1
= 0 if end of archive *)
IF hsize > 0 THEN
BEGIN
FOR i := 1 TO 4 DO dummy := ReadByte;
(* 1 first_hdr_size (size up to and including 'extra data')
1 archiver version number
1 minimum archiver version to extract
1 host OS (0 = MSDOS, 1 = PRIMOS, 2 = UNIX, 3 = AMIGA, 4 = MAC-OS)
(5 = OS/2, 6 = APPLE GS, 7 = ATARI ST, 8 = NEXT)
(9 = VAX VMS) *)
flags := ReadByte;
(* 1 arj flags (0x01 = GARBLED_FLAG) indicates passworded file
(0x02 = RESERVED)
(0x04 = VOLUME_FLAG) indicates continued file to next
volume (file is split)
(0x08 = EXTFILE_FLAG) indicates file starting position
field (for split files)
(0x10 = PATHSYM_FLAG) indicates filename translated
("\" changed to "/")
(0x20 = BACKUP_FLAG) indicates file marked as backup *)
FOR i := 1 TO 3 DO dummy := ReadByte;
(* 1 method (0 = stored, 1 = compressed most ... 4 compressed fastest)
1 file type (0 = binary, 1 = 7-bit text)
(3 = directory, 4 = volume label)
1 reserved *)
Search.time := LONGINT(ReadByte) SHL 24 + LONGINT(ReadByte) SHL 16 + LONGINT(ReadByte) SHL 8 + ReadByte;
(* 4 date time modified *)
csize := LONGINT(ReadByte) SHL 24 + LONGINT(ReadByte) SHL 16 + LONGINT(ReadByte) SHL 8 + ReadByte;
(* 4 compressed size *)
Search.size := LONGINT(ReadByte) SHL 24 + LONGINT(ReadByte) SHL 16 + LONGINT(ReadByte) SHL 8 + ReadByte;
(* 4 original size (this will be different for text mode compression) *)
FOR i := 1 TO 5 DO dummy := ReadByte;
(* 4 original file's CRC
2 filespec position in filename *)
Search.Attr := ReadByte; (* dummy := ReadByte; *)
(* 2 file access mode
2 host data (currently not used) *)
IF flags AND $08 <> $08 THEN
FOR i := 1 TO 4 DO dummy := ReadByte;
(* ? extra data
4 bytes for extended file starting position when used
(this is present when EXTFILE_FLAG is set) *)
WITH Search DO
BEGIN
name := ''; c := 'x';
WHILE c <> #0 DO
BEGIN
c := Chr(ReadByte); name := name+DownCase(c);
END;
k := Length(Name); IF Name[k] = #0 THEN Delete(Name,k,1);
END;
(* ? filename (null-terminated string) *)
(* ? comment (null-terminated string) ... *)
FOR k := 1 TO FileSpecs DO
BEGIN
FSplit(FileSpec[k],Path,name,ext);
WHILE Length(name) < 8 DO name := name+' ';
IF Ext = '' THEN Ext := '. '
ELSE
WHILE Length(ext) < 4 DO ext := ext+' ';
i := Pos('*',name);
IF i > 0 THEN
WHILE i <= 8 DO
BEGIN
name[i] := '?'; INC(i);
END;
i := Pos('*',ext);
IF i > 0 THEN
WHILE i <= 4 DO
BEGIN
ext[i] := '?'; INC(i);
END;
FileSpec[k] := Path+name+ext;
FSplit(Search.Name,Path,name,ext);
WHILE Length(name) < 8 DO name := name +' ';
IF Ext = '' THEN Ext := '. '
ELSE
WHILE Length(ext) < 4 DO ext := ext+' ';
ARJFileName:= Path+name+ext;
i := 1;
WHILE ((FileSpec[k][i] = '?') OR (FileSpec[k][i] = ARJFileName[i])) AND
(i<12) DO
INC(i);
IF ((ExactAttr AND (Search.Attr = Attr)) OR (NOT ExactAttr)) AND
(FileSpec[k][i] = '?') OR (FileSpec[k][i] = ARJFileName[i]) THEN
ShowCompARJFileData(search,arjsearch,Dir,csize);
END;
INC(BufPtr,csize); INC(FilePtr,csize);
IF BufPtr > BufSize THEN
BEGIN
Seek(ARJFile,FilePtr);
BlockRead(ARJFile,Buffer^,BufSize,BytesRead); BufPtr := 0;
END;
END;
END;
UNTIL hsize = 0;
Close(ARJFile);
END; (* SearchInARJFile *)
PROCEDURE ShowCompARJFileData(VAR search,arjsearch: SearchRec;VAR Path: PathStr;
csize: LONGINT);
BEGIN
IF BareOutput THEN
Write(Output,Path,arjsearch.Name,' ')
ELSE
BEGIN
IF FileCount = 0 THEN
BEGIN
WriteLn(Output); IF DoPage THEN TestForMoreMsg;
WriteLn(Output,Path); IF DoPage THEN TestForMoreMsg;
END;
IF arjsearch.Name <> OldARJFileName THEN
BEGIN
DownString(arjsearch.Name); OldARJFileName := arjsearch.Name;
InfoArray[0] := LONGINT(@arjsearch.Name);
SizeStr := FormattedLongIntStr(arjsearch.Size,8);
InfoArray[1] := LONGINT(@SizeStr);
UnpackTime(arjsearch.Time,DateRec);
Date := FormDate(DateRec); Time := FormTime(DateRec);
InfoArray[2] := LONGINT(@Date);
InfoArray[3] := LONGINT(@Time);
AttrStr := '....';
IF arjSearch.Attr AND Archive = Archive THEN AttrStr[1] := 'a';
IF arjSearch.Attr AND Hidden = Hidden THEN AttrStr[2] := 'h';
IF arjSearch.Attr AND SysFile = SysFile THEN AttrStr[3] := 's';
IF arjSearch.Attr AND ReadOnly = ReadOnly THEN AttrStr[4] := 'r';
InfoArray[4] := LONGINT(@AttrStr);
FormatStr(s,'(%-12s %8s '+DateTempl+' '+TimeTempl+' %4s)',InfoArray);
WriteLn(Output,s); IF DoPage THEN TestForMoreMsg;
END;
InfoArray[0] := LONGINT(@search.Name);
SizeStr := FormattedLongIntStr(search.Size,8);
InfoArray[1] := LONGINT(@SizeStr);
UnpackTime(search.Time,DateRec);
Date := FormDate(DateRec); Time := FormTime(DateRec);
InfoArray[2] := LONGINT(@Date);
InfoArray[3] := LONGINT(@Time);
(* AttrStr := '----';
IF Search.Attr AND Archive = Archive THEN AttrStr[1] := 'a';
IF Search.Attr AND Hidden = Hidden THEN AttrStr[2] := 'h';
IF Search.Attr AND SysFile = SysFile THEN AttrStr[3] := 's';
IF Search.Attr AND ReadOnly = ReadOnly THEN AttrStr[4] := 'o'
ELSE AttrStr[4] := 'w';
InfoArray[4] := LONGINT(@AttrStr);
FormatStr(s,'+ %-12s %8s '+DateTempl+' '+TimeTempl+' %4s',InfoArray); *)
FormatStr(s,'+ %-12s %8s '+DateTempl+' '+TimeTempl,InfoArray);
WriteLn(Output,s); IF DoPage THEN TestForMoreMsg;
INC(TotalSize,csize); INC(DirSize,csize);
INC(TotalFileCount); INC(FileCount);
END;
END; (* ShowFileData *)
END.