home *** CD-ROM | disk | FTP | other *** search
- {$A+} {word alignment}
- {$B-} {shortcircuit boolean eval}
- {$D-} {Debug information off (was +)}
- {$E-} {8087 emulation off}
- {$F-} {Force FAR calls as needed (was +)}
- {$I-} {I/O checking off}
- {$L-} {Local symbols off (was +)}
- {$N-} {Numeric coprocessing=software}
- {$O-} {No Overlays allowed (was +)}
- {$R-} {Range checking off}
- {$S-} {Stack overflow checking off (was on)}
- {$V-} {Var-string checking off}
- {$M 32767,32767,32767}
-
- PROGRAM A2Z;
-
- {
- Version 1.6
-
- This version represents minor changes in code structure. It will also be
- the last version released, unless some fatal flaw is uncovered. Enjoy.
-
- Ian McLean 404 428 7829 (voice)
- 3365 Timber Lake Road
- Kennesaw, GA
- 30144
- v1.6d Toad Hall, 12 Oct 89
- - Removing the -ex, -eb4, etc. for the newer PK v1.01 ZIP.
-
- v1.6c Toad Hall, 15 Jun 89
- - Tweaking a little
-
- v1.6b Toad Hall, 9 Apr 89
- - WHY are we messing with the horrendous error-trapping
- (during unarcing procedures), processing strings for error msgs?
- Just look for the ERRORLEVEL returned by the executing program!
- If it's not 0, there was a problem! THEN Die!
- - Why are we processing strings for file sizes, number of archive
- files, etc? All that is right there in the .ARC or .PAK file
- entry! Snarf it from the raw file.
- (Of course that means we must know header structures, how to
- reposition file pointers, snarf long integers from the headers,
- etc. .. but we can do that, ne?
-
- v1.6a Toad Hall Tweak, 7 Apr 89
- - Changed some switches (above)
- - Added Ascii file "-ex" switch
- - Tightened up the Convert code by consolidating
- common (shared) code.
- - Vastly tightened up the Log, StatFile and other reports
- by consolidating WriteLn, etc.
- - Enabled the F- (no FAR calls) switch
- with F+ switches only when absolutely required.
- - To Do:
- Figure how to read .PAK comments
-
- David Kirschbaum
- Toad Hall
- kirsch@braggvax.ARPA
- }
-
- Uses DOS, CRT;
-
- CONST
- MAXDIRENTRIES = 20; { Maximum number of directories that can be specified
- to search. This doesn't include those searched
- "below" ones specified. }
-
- DataNext: STRING[10]= 'CONFIGNEXT';
- PKZIP: PathStr= 'U:\PKZIP.EXE'; { 80 bytes }
- PKUNZIP: PathStr= 'U:\PKUNZIP.EXE'; { 80 bytes }
- PKUNPAK: PathStr= 'U:\PKXARC.EXE'; { 80 bytes }
- PAK: PathStr= 'U:\PAK.EXE'; { 80 bytes }
- (* v1.6d
- EASwitch : STRING[5] = ' -ex '; { 6 bytes v1.6a}
- EBSwitch : STRING[5] = ' -eb4'; { 6 bytes v1.6a}
- { --------- }
- { 334 bytes }
- *)
- { --------- }
- { 320 bytes }
- HDRLEN = 319; {v1.6d length of directory names - 1}
-
- TYPE
- FullNameStr = STRING[12]; { Type for storing name+dot+extension }
- DirSearchEntry = RECORD { This data type is used to store
- all the paths that will be searched }
- Dir : DirStr; { <-- Path to search }
- Name : FullNameStr; { <-- File spec to search }
- Below: BOOLEAN; { <-- TRUE=search directories
- below the specified one }
- END;
-
- VAR
- Dir : ARRAY[1..MAXDIRENTRIES] OF DirSearchEntry; { This holds all the
- directories specified
- to convert }
- numdirs: Byte; { The number of directories used in
- above array }
- SearchZips: BOOLEAN; { Search ZIP files for inclosed ARCs
- or PAKs }
- AppendLog: BOOLEAN; { TRUE=Append to log
- FALSE=rewrite log file }
- BatchMode: BOOLEAN; { TRUE=Don't wait for a keypress
- at beginning }
- SuppressLog: BOOLEAN; { TRUE=Don't make a log file }
- LogFile: TEXT; { Log file handle, A2Z.LOG }
- OldExitProc1: pointer; { Pointer to previous exit procedure
- routine. }
- oldSeg,oldOfs: word; { Old segment and offset
- for interrupt 29h handler }
- OldExitProc2: pointer; { Holder for old exit proc }
- Reg: Registers; { Register storage for DOS calls }
- cmdY: Byte; { Line the cursor's on
- in the bottom window }
- bufData: longint; { Pointer to the text buffer }
- bufferSeg: word; { Segment of the text buffer }
- bufferOfs: word; { Offset " " " " }
- BufferPtr: pointer; { Pointer to the text buffer,
- in pointer format }
- bufferlen: word; { Current length of text buffer }
-
- numfiles: word; { Number of files to convert }
- numBytes: longint; { Number of bytes to convert }
- filenum: word; { Current file number }
- ConvertingInside: BOOLEAN; { TRUE=Converting internal arc files }
- saved: longint; { Total bytes saved so far }
- TrickleUpError: BOOLEAN; { Error converting an internal file }
- internalcount: Byte;
- InterruptRequested: BOOLEAN;
- WorkDir: String;
- StatusFile: TEXT;
- StatusFileName: String;
- TStr: String; {v1.6a}
- execerror : Byte; {v1.6b}
- ExecErrStr : STRING[5]; {v1.6b}
-
- function File_Found(F: ComStr): BOOLEAN;
- {
- This returns TRUE if the file F exists, FALSE otherwise.
- F can contain wildcard characters.
- }
- VAR
- SRec : SearchRec;
- BEGIN
- SRec.Name := '*';
- FindFirst(F,0,SRec);
- File_Found := NOT (SRec.Name='*'); {v1.6a}
- END; {of File_Found}
-
-
- function Valid_Dir(D: String): BOOLEAN;
- VAR
- T: FILE;
- BEGIN
- Assign(T, D+'VALID!!!.A2Z');
- {$I-} REWRITE(T); {$I+}
- IF IOResult<>0 THEN Valid_Dir := FALSE
- ELSE BEGIN
- CLOSE(T);
- Erase(T);
- Valid_Dir := TRUE;
- END;
- END; {of Valid_Dir}
-
-
- PROCEDURE HaltWithMsg(M: String);
- {
- Displays the message in M to the user and halts program execution.
- Used with critical errors.
- }
- BEGIN
- WRITELN(M);
- HALT;
- END; {of HaltWithMsg}
-
-
- PROCEDURE DisplayProgramHeader;
- {
- Display program version number and credits.
- }
- BEGIN
- WRITELN;
- WRITELN('A2Z - ARC/PAK to ZIP converter');
- WRITELN('version 1.6d by Ian McLean (with a Toad Hall Tweak!)');
- WRITELN;
- END; {of DisplayProgramHeader}
-
-
- PROCEDURE InvokeConfiguration;
- {
- Configure A2Z by entering the paths for PKZIP, PKUNZIP, PKUNPAK, and PAK,
- as well as a compression level for ASCII and binary files. This information
- is then stored in the executable for A2Z for future use.
- }
- VAR
- A: FILE OF Byte; { Temp variable for referencing A2Z.EXE }
- l: longint; { Location of search }
- matchup: Byte; { Number of bytes currently matched }
- C: CHAR; { Character to match to }
-
- PROCEDURE Get_Name(VAR Name : PathStr; Pk : BOOLEAN);
- {v1.6c a common procedure.
- v1.6d Bug fixed.
- }
- VAR S,N : PathStr;
- BEGIN
- IF Pk THEN S := 'PKWare''s ' + Name + '.'
- ELSE S := 'NoGate Consulting''s ' + Name + '.';
-
- N := Name; {v1.6d}
- REPEAT
- WRITELN;
- WRITELN('Enter the name and path for ', S);
- WRITELN('Please be sure to enter a path, filename, and extension:');
- READLN(N);
- UNTIL File_Found(N); {v1.6d}
- Name := N; {post global v1.6d}
- END; {of Get_Name}
-
- TYPE
- Str4 = STRING[4];
-
- FUNCTION Get_Char(Query : String; CharSet : Str4) : CHAR;
- VAR Ch : CHAR;
- BEGIN
- WRITE(Query);
- REPEAT
- REPEAT UNTIL KeyPressed;
- Ch := UpCase(ReadKey);
- UNTIL POS(Ch,CharSet) <> 0;
- Get_Char := Ch;
- END; {of Get_Char}
-
-
- BEGIN {InvokeConfiguration}
- DisplayProgramHeader;
- IF NOT File_Found('A2Z.EXE')
- THEN HaltWithMsg(
- 'A2Z.EXE must be in the current directory when invoking configuration.');
-
- Get_Name(PKZIP,TRUE); {v1.6c get PKZIP.EXE's path and name}
-
- Get_Name(PKUNZIP,TRUE); {v1.6c get PKUNZIP.EXE's path and name}
-
- Get_Name(PKUNPAK,TRUE); {v1.6c get PKUNPAK.EXE's path and name}
-
- C := Get_Char('Do you have .PAK files to convert? [Y/N] ', 'YN');
-
- WRITELN(C); {display, new line}
- IF C = 'Y'
- THEN Get_Name(PAK,FALSE)
- ELSE PAK := '';
-
- WRITELN;
- (* v1.6d
- C := Get_Char('Compression level for binary files [1..4]: ', '1234');
-
- EBSwitch[5] := C; {v1.6a move into ' -eb%' string}
- WRITELN(EBSwitch); {v1.6a}
-
- { v1.6a Add 'ex' for ASCII files }
-
- C := Get_Char('Compression level for ASCII files [1..4,X]: ', '1234X');
-
- IF C = 'X' {v1.6a}
- THEN EASwitch := ' -ex' {v1.6a}
- ELSE EASwitch := ' -ea' + C; {v1.6a}
- WRITELN(EASwitch); {v1.6a}
-
- WRITELN;
- *)
- Assign(A, 'A2Z.EXE'); { Configuration information is written to A2Z.EXE, }
- RESET(A); { overlaying what was in the CONST block previously}
- l := FileSize(A)-1; { Search starting at EOF, as constants are usually
- found there }
- matchup := 10; { First character to match is the fifth of the
- string CONFIGNEXT }
- REPEAT
- Seek(A, l); { Read character from file }
- READ(A, Byte(C));
- Dec(l); { Decrement counter (search backwards) }
- CASE matchup OF
- 10: IF C=DataNext[matchup] { If the char matches,}
- THEN Dec(matchup); { we need to match the next one,
- otherwise we}
- ELSE IF C=DataNext[matchup] { need to match the tenth next }
- THEN Dec(matchup) ELSE matchup := 10; { (string wasn't correct)}
- END;
- UNTIL (matchup=0) OR (l=0); { Repeat this until string found (matchup=0)
- or we're at start of file }
- IF matchup <> 0
- THEN HaltWithMsg(
- 'Unable to find configuration data area. Corrupted A2Z.EXE!');
-
- Seek(A, l+12); { Seek the configuration information block }
- (* v1.6d
- for l := 0 TO 321 DO {Write the Directory/filenames}
- WRITE(A, Mem[Seg(PKZIP):Ofs(PKZIP)+l]); { and compression levels }
- *)
- FOR l := 0 TO HDRLEN DO {Write the Directory/filenames} {v1.6d}
- WRITE(A,Mem[Seg(PKZIP):Ofs(PKZIP)+l]);
-
- CLOSE(A);
- HaltWithMsg('A2Z is now configured for use.');
- END; { of InvokeConfiguration }
-
-
- PROCEDURE ShowInvokation;
- {
- Display program information and the invokation parameters for A2Z,
- then halt the program.
- }
- BEGIN
- DisplayProgramHeader;
- WRITELN(
- 'A2Z [/C] [/Z] [/A] [/B] [/S=device] [/W=dir] [filespec] [!filespec]');
- WRITELN;
- WRITELN(
- '/C Invoke configuration');
- WRITELN(
- '/Z Search ZIP files for imbedded ARC/PAK files and process');
- WRITELN(
- '/A Append to log file, if it exists, instead of overwriting');
- WRITELN(
- '/B Batch mode. Don''t pause for a keypress at beginning');
- WRITELN(
- '/N Create no log file.');
- WRITELN(
- '/S=[device] Set the status display device (eg: /S=COM1). Default is NUL');
- WRITELN(
- '/W=[dir] Set the work directory to [dir]. Default is current directory');
- WRITELN(
- ' or value set by the environment variable A2ZWORK.');
- WRITELN;
- WRITELN(
- '[filespec] Directory name or search specification of files to convert. If');
- WRITELN(
- ' there''s an ! before the name, subdirectories of the one specified');
- WRITELN(
- ' are searched. Up to twenty path names may be entered.');
- WRITELN;
- WRITELN('Examples:');
- WRITELN(
- 'A2Z !C:\ !D:\ /Z Convert all dirs on drives C: and D:, search ZIPs');
- WRITELN(
- ' for imbedded ARC/PAKs');
- WRITELN(
- 'A2Z FOOBAR.ARC Convert the file FOOBAR.ARC to a ZIP');
- WRITELN(
- 'A2Z C:\*.PAK Convert all PAK files in dir C:\ to ZIPs');
- HALT;
- END; {of ShowInvocation}
-
-
- PROCEDURE ReadCommandLine;
- {
- Read the parameters entered at the command line and build the list of
- directories to convert. Check for configuration and show invokation if
- necessary.
- }
-
- PROCEDURE ParseParameter(S: String);
- {
- Parse the parameter in S.
- }
- VAR
- D : DirStr; { Temp holders for path name, etc }
- N : NameStr;
- E : ExtStr;
- BEGIN
- IF S[1]='/' THEN
- CASE UpCase(S[2]) OF
- 'C': InvokeConfiguration;
- 'Z': SearchZips := TRUE;
- 'A': AppendLog := TRUE;
- 'B': BatchMode := TRUE;
- 'N': SuppressLog := TRUE;
- 'W': BEGIN
- IF (LENGTH(S)<5) OR (S[3]<>'=') THEN ShowInvokation;
- WorkDir := COPY(S,4,255);
- END;
- 'S': BEGIN
- IF (LENGTH(S)<4) OR (S[3]<>'=') THEN ShowInvokation;
- StatusFileName := COPY(S,4,255);
- END;
- ELSE ShowInvokation;
- END {case}
- ELSE BEGIN
- Inc(numdirs);
- WITH Dir[numdirs] DO BEGIN
- IF S[1]='!' THEN BEGIN
- S := COPY(S,2,255);
- Below := TRUE;
- END
- ELSE Below := FALSE;
- IF S[LENGTH(S)]<>'\' THEN
- IF (NOT File_Found(S)) AND (File_Found(S+'\*.*')) THEN S := S+'\';
- FSplit(FExpand(S), D,N,E);
- IF N='' THEN N := '*';
- IF (E='') OR (E='.') THEN E := '.*';
- Dir := D;
- Name := N+E;
- END;
- END;
- END; {of ParseParameter}
-
-
- VAR l : Byte; { Loop variable }
-
- BEGIN {ReadCommandLine}
- SearchZips := FALSE;
- AppendLog := FALSE;
- BatchMode := FALSE;
- SuppressLog := FALSE;
- WorkDir := GetEnv('A2ZWORK');
- StatusFileName := 'NUL';
- numdirs := 0;
- IF ParamCount=0 THEN ShowInvokation; {and die}
-
- for l := 1 TO ParamCount DO ParseParameter(ParamStr(l));
- IF numdirs=0 THEN ShowInvokation;
-
- IF WorkDir='' THEN GetDir(0,WorkDir);
- WorkDir := FExpand(WorkDir);
- IF WorkDir[LENGTH(WorkDir)]<>'\' THEN WorkDir := WorkDir+'\';
- IF NOT Valid_Dir(WorkDir)
- THEN HaltWithMsg('Invalid work directory specified.');
-
- Assign(StatusFile, StatusFileName);
- {$I-} REWRITE(StatusFile); {$I+}
- IF IOResult<>0 THEN BEGIN
- WRITELN('Unable to open specified status file.');
- Assign(StatusFile, 'NUL');
- REWRITE(StatusFile);
- END
- ELSE WRITELN(StatusFile, 'A2Z v1.6b by Ian McLean');
- END; { of ReadCommandLine }
-
-
- {$F+} {v1.6a Use FAR calls}
- PROCEDURE NewExitProc1;
- {
- This exit procedure closes the log file.
- }
- BEGIN
- IF NOT SuppressLog THEN CLOSE(LogFile);
- CLOSE(StatusFile);
- ExitProc := OldExitProc1;
- END; {of NewExitProc1}
- {$F-} {v1.6a No FAR calls}
-
-
- PROCEDURE CheckSubPrograms;
- BEGIN
- IF PKZIP='UNCONFIGURED' THEN InvokeConfiguration;
- IF NOT (File_Found(PKZIP) AND File_Found(PKUNZIP)
- AND File_Found(PKUNPAK)
- AND (File_Found(PAK)
- OR (PAK='')))
- THEN BEGIN
- WRITELN;
- WRITELN('** Invalid program paths in configuration **');
- InvokeConfiguration;
- END;
- END; {of CheckSubPrograms}
-
-
- PROCEDURE OpenLogFile;
- {
- Open the file A2Z.LOG in the current directory. If it exists, append to it.
- Place a date/time stamp on it, too, just for the heck of it. Also sets up
- an exit procedure to close the file. If AppendLog is true, we'll append
- to the log, otherwise we'll rewrite it.
- }
-
- function Date_String: String;
- {
- Returns the current date in a string of the form: MON ## YEAR.
- E.g, 21 Feb 1989 or 02 Jan 1988.
- }
- CONST
- Month: ARRAY[1..12] OF STRING[3]=
- ('Jan','Feb','Mar','Apr','May','Jun',
- 'Jul','Aug','Sep','Oct','Nov','Dec');
- VAR
- y,m,d,junk : word;
- DS,YS: STRING[5];
- BEGIN
- GetDate(y,m,d,junk);
- STR(y,YS);
- STR(d,DS);
- IF LENGTH(DS)<2 THEN DS := '0'+DS;
- Date_String := DS+' '+Month[m]+' '+YS;
- END;
-
- function Time_String: String;
- {
- Returns the current time in the form: HH:MM am/pm
- E.g, 12:00 am or 09:12 pm.
- }
- VAR
- h,m,junk: word;
- HS,MS: STRING[5];
- Am: BOOLEAN;
- BEGIN
- GetTime(h,m,junk,junk);
- CASE h OF
- 0: BEGIN
- Am := TRUE;
- h := 12;
- END;
- 1..11: Am := TRUE;
- 12: Am := FALSE;
- ELSE BEGIN
- Am := FALSE;
- h := h-12;
- END;
- END;
- STR(h,HS);
- STR(m,MS);
- IF LENGTH(HS)<2 THEN HS := '0'+HS;
- IF LENGTH(MS)<2 THEN MS := '0'+MS;
- IF Am THEN Time_String := HS+':'+MS+' am'
- ELSE Time_String := HS+':'+MS+' pm';
- END; {of Time_String}
-
- BEGIN {OpenLogFile}
- IF NOT SuppressLog THEN BEGIN
- Assign(LogFile, 'A2Z.LOG');
- {$I-}
- IF AppendLog THEN Append(LogFile) ELSE REWRITE(LogFile);
- {$I+}
- IF IOResult<>0 THEN REWRITE(LogFile);
- WRITELN(LogFile);
- WRITELN(LogFile, Date_String+' '+Time_String);
- WRITELN(LogFile, '--------------------');
- END;
- {$F+} {v1.6a Use FAR calls}
- OldExitProc1 := ExitProc;
- ExitProc := @NewExitProc1;
- {$F-} {v1.6a No FAR calls}
- END; { of OpenLogFile }
-
-
- function Indent_Spaces: String;
- {v1.6a moved this to be a global function,
- tightened up a bit.
- }
- VAR
- S: String;
- i : INTEGER; {v1.6b}
- BEGIN
- i := internalcount ShL 1; {v1.6b}
- S[0] := CHAR(i); {v1.6b}
- IF internalcount <> 0
- THEN FillChar(S[1], i,' '); {v1.6b}
- Indent_Spaces := S;
- END; {of Indent_Spaces}
-
-
- PROCEDURE LogError(E: String; Stat : BOOLEAN);
- {
- Write the message in string E to the screen and to the log file.
- v1.6a If Stat is TRUE, write it to the status file also.
- }
- BEGIN
- WRITELN(E);
- IF NOT SuppressLog THEN WRITELN(LogFile, E);
- IF Stat THEN WRITELN(StatusFile,Indent_Spaces + E); {v1.6a}
- END; {of LogError}
-
-
- PROCEDURE WriteStatus(M: String);
- {v1.6a We ALWAYS Write(M),
- and we ALWAYS indent .. so consolidating here.
- }
- BEGIN
- M := Indent_Spaces + M; {v1.6a}
- WRITE(M); {v1.6a}
- WRITE(StatusFile,M);
- END; {of WriteStatus}
-
-
- PROCEDURE WritelnStatFil(M: String; W : BOOLEAN);
- {
- Write the message in M to the status device, with linefeed.
- v1.6a IF W is TRUE, Writeln(M) also.
- }
- BEGIN
- IF W THEN WRITELN(M); {v1.6a}
- WRITELN(StatusFile,M);
- END; {of WritelnStatFil}
-
-
- {********* The following search engine routines are sneakly swiped *********
- ********* from Turbo Technix v1n6. See there for further details *********}
-
- {$F+} {v1.6a we need far calls for this ProcType business}
-
- TYPE
- ProcType= PROCEDURE(VAR S: SearchRec; P: PathStr);
-
- VAR
- EngineMask: FullNameStr;
- engineattr: Byte;
- EngineProc: ProcType;
- enginecode: Byte;
-
- {$F-}
- function Valid_Extension(VAR S: SearchRec): BOOLEAN;
- VAR
- Junk : String;
- E : ExtStr;
- BEGIN
- IF S.Attr AND Directory=Directory THEN BEGIN
- Valid_Extension := TRUE;
- Exit;
- END;
-
- FSplit(S.Name,Junk,Junk,E);
- Valid_Extension := {v1.6a}
- (E='.ARC') OR (E='.PAK')
- OR (SearchZips AND (E='.ZIP') );
- END; {of Valid_Extension}
-
- {$F+} {v1.6a Use FAR calls}
-
- PROCEDURE SearchEngine(Mask: PathStr; attr: Byte; Proc: ProcType;
- VAR errorcode: Byte);
- VAR
- S : SearchRec;
- P : PathStr;
- Ext : ExtStr;
- BEGIN
- FSplit(Mask, P, Mask, Ext);
- Mask := Mask+Ext;
- FindFirst(P+Mask,attr,S);
- IF DosError<>0 THEN BEGIN
- errorcode := DosError;
- Exit;
- END;
-
- WHILE DosError=0 DO BEGIN
- IF Valid_Extension(S) THEN Proc(S, P);
- FindNext(S);
- END;
- IF DosError=18 THEN errorcode := 0
- ELSE errorcode := DosError;
- END; {of SearchEngine}
-
- {$F-} {v1.6a No FAR calls}
-
- function Good_Directory(S: SearchRec): BOOLEAN;
- {1 call}
- BEGIN
- Good_Directory := (S.name<>'.') AND (S.Name<>'..')
- AND (S.attr AND Directory=Directory);
- END; {of Good_Directory}
-
- {$F+} {v1.6a Use FAR calls}
-
- PROCEDURE SearchOneDir(VAR S: SearchRec; P: PathStr);
- BEGIN
- IF Good_Directory(S) THEN BEGIN
- P := P+S.Name;
- SearchEngine(P+'\'+EngineMask,engineattr,EngineProc,enginecode);
- SearchEngine(P+'\*.*',Directory OR Archive, SearchOneDir,enginecode);
- END;
- END; {of SearchOneDir}
-
-
- PROCEDURE SearchEngineAll(Path: PathStr; Mask: FullNameStr; attr: Byte;
- Proc: ProcType; VAR errorcode: Byte);
- BEGIN
- EngineMask := Mask;
- EngineProc := Proc;
- engineattr := attr;
- SearchEngine(Path+Mask,attr,Proc,errorcode);
- SearchEngine(Path+'*.*',Directory OR Archive,SearchOneDir,errorcode);
- errorcode := enginecode;
- END; {of SearchEngineAll}
-
-
- {************** Thus ends the sneakly swiped code *************
- **** We now return you to our regularly scheduled program ****}
-
- PROCEDURE AddToEstimate(VAR S: SearchRec; P: PathStr);
-
- {$F-} {v1.6a and back to no Far calls}
- {
- Called by the search engine, adds the information in S to the file estimates
- numfiles and numBytes. Displays the filename temporarily, too.
- }
- VAR
- x : Byte;
- BEGIN
- Inc(numfiles); {bump nr of files processed}
- Inc(numBytes,S.size); {bump total bytes in all files
- by .ARC/.PAK file size}
- x := WhereX;
- ClrEol;
- WRITE(S.Name);
- GotoXY(x,WhereY);
- END; {of AddToEstimate}
-
-
- PROCEDURE GetFileEstimates;
- {
- Estimate the number of bytes and number of files to convert.
- }
- VAR
- l, errorcode : Byte;
- BEGIN
- DisplayProgramHeader;
- WRITELN('Searching directories...');
- WRITELN;
- numfiles := 0; {clear nr ARC/PAK files processed}
- numBytes := 0; {and total nr file bytes}
- for l := 1 TO numdirs DO
- WITH Dir[l] DO BEGIN
- WRITE(Dir);
- {$F+} {v1.6a Use Far calls}
- IF Below THEN SearchEngineAll(Dir,Name,Archive,AddToEstimate,errorcode)
- ELSE SearchEngine(Dir+Name,Archive,AddToEstimate,errorcode);
- {$F-} {v1.6a No Far calls}
-
- ClrEol;
- WRITELN;
- END;
- WRITELN;
- WRITE(numBytes,' bytes in ',numfiles,' file(s) to ');
- IF SearchZips THEN WRITELN('convert/examine.')
- ELSE WRITELN('convert.');
- WRITELN;
- IF numfiles=0 THEN HaltWithMsg('No files to convert!');
-
- IF NOT BatchMode THEN BEGIN
- WRITELN('Press any key...');
- REPEAT UNTIL KeyPressed;
- END;
- WHILE KeyPressed DO CHAR(l) := ReadKey;
- END; { of GetFileEstimates }
-
-
- PROCEDURE IPP;
- { Interrupt pre-processor. This is a new handler for interrupt 29h which
- provides special functions. See comments in IHAND.ASM}
- interrupt;
- BEGIN
- InLine(
- $06/ { push es }
- $1E/ { push ds }
- $53/ { push bx }
- $57/ { push di }
- $BB/$3F/$3F/ { mov bx, 3f3fh }
- $8E/$C3/ { mov es, bx }
- $BB/$3F/$3F/ { mov bx, 3f3fh }
- $26/$8B/$3F/ { mov di, word ptr [es:bx] }
- $26/$8E/$5F/$02/ { mov ds, word ptr [es:bx+2] }
- $88/$05/ { mov byte ptr [di], al }
- $26/$FF/$07/ { inc word ptr [es:bx] }
- $5F/ { pop di }
- $5B/ { pop bx }
- $1F/ { pop ds }
- $07/ { pop es }
- $3C/$0A/ { cmp al, 10 }
- $75/$28/ { jne looper }
- $50/ { push ax }
- $52/ { push dx }
- $51/ { push cx }
- $53/ { push bx }
- $B4/$03/ { mov ah, 3 }
- $B7/$00/ { mov bh, 0 }
- $CD/$10/ { int 10h }
- $80/$FE/$18/ { cmp dh, 24 }
- $75/$15/ { jne popper }
- $FE/$CE/ { dec dh }
- $B7/$00/ { mov bh, 0 }
- $B4/$02/ { mov ah, 2 }
- $CD/$10/ { int 10h }
- $B8/$01/$06/ { mov ax, 0601h }
- $B7/$07/ { mov bh, 7 }
- $B9/$00/$11/ { mov cx, 1100h }
- $BA/$4F/$18/ { mov dx, 184fh }
- $CD/$10/ { int 10h }
- {popper: }
- $5B/ { pop bx }
- $59/ { pop cx }
- $5A/ { pop dx }
- $58/ { pop ax }
- {looper: }
- $9C/ { pushf }
- $9A/$00/$00/$00/$00/ { call far [0:0] }
- $CF); { iret }
- END; {of IPP}
-
-
- {$F+} {v1.6a Use FAR calls}
-
- PROCEDURE NewExitProc2;
- { This exit procedure removes the interrupt 29h handler from memory
- and places the cursor at the bottom of the screen. }
- BEGIN
- Reg.AX := $2529; {v1.6a}
- Reg.DS := oldSeg;
- Reg.DX := oldOfs;
- MsDos(Reg);
- Window(1,1,80,25);
- GotoXY(1,24);
- TextAttr := $07;
- ClrEol;
- WRITELN('Thank you for using A2Z!');
- ExitProc := OldExitProc2;
- END; {of NewExitProc2}
-
- {$F-} {v1.6a No FAR calls}
-
-
- PROCEDURE ResetBuffer;
- { Reset pointers to the text buffer, effectively deleting any text in it }
- BEGIN
- MemW[Seg(bufData):Ofs(bufData)] := bufferOfs; { Set first 2 bytes
- of bufData to point to buffer offset }
- MemW[Seg(bufData):Ofs(bufData)+2] := bufferSeg; { And next two bytes
- to point to buffer segment }
- MemW[Seg(IPP):Ofs(IPP)+21] := Seg(bufData); { Now point the interrupt
- routine to bufData for pointer }
- MemW[Seg(IPP):Ofs(IPP)+26] := Ofs(bufData); { to the text buffer }
- END; {of ResetBuffer}
-
-
- function in_Buffer(S: String): INTEGER;
- { This searched the text buffer for the string S,
- and if it's found, returns the offset in the buffer.
- If it's not found, a -1 is returned.
- }
- VAR
- l,m : word;
- x : Byte;
- BEGIN
- x := 1;
- l := bufferOfs;
- m := MemW[Seg(bufData):Ofs(bufData)]-bufferOfs; {v1.6a}
- WHILE (x<=LENGTH(S)) AND (l<=m) DO BEGIN
- IF Mem[bufferSeg:l] = Byte(S[x]) THEN Inc(x)
- ELSE x := 1;
- Inc(l);
- END;
- IF x > LENGTH(S) THEN in_Buffer := l-LENGTH(S)
- ELSE in_Buffer := -1;
- END; {of in_Buffer}
-
-
- PROCEDURE InstallInterruptHandler;
- { Installs the int 29h handler }
- BEGIN
- bufferlen := $4000; { Set up a 16k buffer }
- GetMem(BufferPtr,bufferlen); { Allocate memory pointed at
- by BufferPtr }
- bufferSeg := Seg(BufferPtr^); { Read segment and offset
- of buffer for easy access }
- bufferOfs := Ofs(BufferPtr^);
- ResetBuffer; { Place these values in the IPP
- routine, resetting buffer }
- Reg.AX := $3529; {v1.6a DOS svc 35H,
- get Int 29H vector}
- MsDos(Reg);
- oldSeg := Reg.ES; { Store the segment and offset
- of the old vector for later use }
- oldOfs := Reg.BX;
- MemW[Seg(IPP):Ofs(IPP)+90] := Reg.BX; { And store them }
- MemW[Seg(IPP):Ofs(IPP)+92] := Reg.ES; { so IPP can call the routine }
-
- Reg.AX := $2529; {v1.6a DOS svc 25H,
- set Int 29H vector}
- Reg.DS := Seg(IPP); { Store segment and offset for IPP.
- The +16 is to skip TP stack }
- Reg.DX := Ofs(IPP)+16; { maintanence routines }
- MsDos(Reg);
-
- {$F+} {v1.6a use FAR calls}
- OldExitProc2 := ExitProc; { Set up new exit procedure to remove
- routine at program termination }
- ExitProc := @NewExitProc2;
- {$F-} {v1.6a No FAR calls}
-
- TextAttr := $07; { Clear the screen to white on black}
- ClrScr;
- GotoXY(1,15); { Go to line 15 and 16 and draw an
- inverse bar which will show the }
- TextAttr := $70; { current command being executed. }
- WRITE('DOS COMMAND:');
- ClrEol; WRITELN; ClrEol;
- TextAttr := $07; { Set text color back
- to white on black }
- Window(1,1,80,13); { Make active window at top of screen
- and home cursor }
- GotoXY(1,1);
- cmdY := 18; { Assume the cursor in the lower
- window's at the top of window }
- END; {of InstallInterruptHandler}
-
-
- PROCEDURE ExecCommand(Cmd,Parm: String);
- { Executes the command in Cmd with command line parameters in Parm.
- This is executed in the lower window }
- VAR
- ox,oy : Byte; { Upper window X and Y }
- BEGIN
- ResetBuffer; { Clear text buffer }
- ox := WhereX; { Store upper window X and Y }
- oy := WhereY;
- Window(1,1,80,25); { Make entire screen active window }
- GotoXY(14,15); { Go to line 14 (COMMAND bar) }
-
- TextAttr := $70;
- WRITE(Cmd,' ',Parm); { Write the command and parameters
- in inverse }
- GotoXY(1,cmdY); { Go to location in bottom window }
- TextAttr := $07; { Normal text color }
-
- Exec(Cmd,Parm); { Execute command }
- execerror := DosExitCode; {v1.6b remember child process
- exit codes}
- IF execerror <> 0 {v1.6b there was one!}
- THEN STR(execerror,ExecErrStr); {v1.6b so make the string now}
-
- cmdY := WhereY; { Store new Y location }
- GotoXY(14,15);
-
- TextAttr := $70; { Erase the COMMAND bar }
- ClrEol; WRITELN; ClrEol;
- TextAttr := $07;
-
- Window(1,1,80,13); { Reset the upper window }
- GotoXY(ox,oy); { Re-position cursor }
- END; {of ExecCommand}
-
-
- function Internal_In_Zip: BOOLEAN;
- {1 call}
- BEGIN
- IF (in_Buffer('.ARC')<>-1)
- OR (in_Buffer('.PAK')<>-1)
- OR (in_Buffer('.ZIP'#13#10' ')<>-1)
- OR (in_Buffer('.ZIP'#13#10'-')<>-1)
- THEN Internal_In_Zip := TRUE
- ELSE Internal_In_Zip := FALSE;
- END; {of Internal_In_Zip}
-
-
- VAR
- x: INTEGER;
- L: STRING[60];
- C: STRING[10];
- code: INTEGER;
- Okay: BOOLEAN;
- T: TEXT;
- SRec: SearchRec;
- Z: ComStr;
- ec: Byte;
- RC: CHAR;
- CurWork: String;
-
- {$F+}
- PROCEDURE Convert(VAR S: SearchRec; P: PathStr);
- {$F-}
-
-
- PROCEDURE ArchiveError(N: String);
- {
- Report an archive error if we're working with the top file, otherwise
- set an error flag.
- v1.6a Common code: We ALWAYS call WriteLnStatus right after
- ArchiveError (with an Indent_Str added to the front).
- Adding this common function right here.
- }
- BEGIN
- IF ConvertingInside THEN BEGIN
- WRITELN(Indent_Spaces + N); {v1.6a}
- TrickleUpError := TRUE;
- END
- ELSE LogError(N,TRUE); {v1.6 WriteLn to StatFile also}
- END; {of ArchiveError}
-
-
- PROCEDURE DeleteDir(P: String);
- {
- Delete all files in the directory named and remove it.
- }
- VAR
- SRec: SearchRec;
- errorcode: Byte;
- BEGIN
- FindFirst(P+'\*.*',0,SRec);
- WHILE DosError=0 DO BEGIN
- Assign(T, P+'\'+SRec.Name);
- {$I-} Erase(T); {$I+}
- errorcode := IOResult;
- FindNext(SRec);
- END;
- {$I-} RmDir(P); {$I+}
- errorcode := IOResult;
- END; {of DeleteDir}
-
-
- PROCEDURE CopyFile(SourceName,DestName: ComStr);
- {v1.6a Replacing length DIV and * instructions with shifts}
- VAR
- Source,Dest: FILE;
- recsread: word;
- buffer: pointer;
- bufsize: word;
- t: longint;
- BEGIN
- IF MaxAvail>65535 THEN bufsize := 65535 ELSE bufsize := MaxAvail;
-
- bufsize := bufsize ShR 10; {v1.6a}
- GetMem(buffer, bufsize ShL 10); {v1.6a}
- Assign(Source, SourceName);
- RESET(Source,1024);
- Assign(Dest,DestName);
- REWRITE(Dest,1024);
- for t := 1 TO FileSize(Source) DO BEGIN
- BlockRead(Source,buffer^,bufsize,recsread);
- BlockWrite(Dest,buffer^,recsread);
- END;
-
- t := FileSize(Source) ShL 10; {v1.6a}
- RESET(Source,1);
- RESET(Dest,1);
- Seek(Source,t);
- Seek(Dest,t);
-
- bufsize := bufsize ShL 10; {v1.6a}
- REPEAT
- BlockRead(Source, buffer^, bufsize, recsread); {v1.6a}
- BlockWrite(Dest,buffer^,recsread); {v1.6a}
- UNTIL recsread = 0; {v1.6a}
-
- GetFTime(Source, t);
- SetFTime(Dest, t);
- CLOSE(Source);
- CLOSE(Dest);
-
- FreeMem(buffer, bufsize); {v1.6a}
- Erase(Source);
- END; {of CopyFile}
-
-
- VAR {for Convert}
- N: NameStr;
- E: ExtStr;
- ArcComment: STRING[50];
- filesinarc: word;
- unarcedSize: longint;
- arcedSize: longint;
- OCI: BOOLEAN;
-
-
- PROCEDURE Comment_Common;
- {v1.6a Common code .. we do this twice}
- BEGIN
- ArcComment := '';
- REPEAT
- Inc(x);
- UNTIL CHAR(Mem[bufferSeg:x]) IN [' ',#13,#10];
- IF CHAR(Mem[bufferSeg:x])=' ' THEN BEGIN
- REPEAT
- Inc(x);
- UNTIL CHAR(Mem[bufferSeg:x])=' ';
- Inc(x);
- REPEAT
- ArcComment := ArcComment+CHAR(Mem[bufferSeg:x]);
- Inc(x);
- UNTIL CHAR(Mem[bufferSeg:x]) IN [#10,#13];
- END; {had a comment}
-
- WHILE ArcComment[LENGTH(ArcComment)]=' ' DO Dec(ArcComment[0]);
-
- END; {of Comment_Common}
-
-
- PROCEDURE Snarf_Digits;
- {v1.6a more common code}
- BEGIN
- C := '';
- REPEAT
- C := C+L[1];
- L := COPY(L,2,255);
- UNTIL L[1]=' ';
- WHILE L[1]=' ' DO L := COPY(L,2,255);
- END; {of Snarf_Digits}
-
-
- PROCEDURE Build_L;
- {v1.6a common code}
- BEGIN
- REPEAT
- L := L+CHAR(Mem[bufferSeg:x]);
- Inc(x);
- UNTIL CHAR(Mem[bufferSeg:x]) IN [#10,#13];
- END; {of Build_L}
-
- PROCEDURE Strip_Zeros;
- {v1.6a strips leading 0's from L (a filesinarc string)}
- BEGIN
- WHILE (LENGTH(L) <> 0)
- AND (L[1] = '0') DO
- DELETE(L,1,1);
- END; {of Strip_Zeros}
-
-
- BEGIN {Convert}
- IF TrickleUpError THEN Exit;
-
- IF KeyPressed THEN BEGIN
- RC := ReadKey;
- IF RC=#27 THEN BEGIN
- IF ConvertingInside THEN BEGIN
- TrickleUpError := TRUE;
- InterruptRequested := TRUE;
- Exit;
- END
-
- ELSE BEGIN
- TStr := '*** Conversion interrupted ***'; {v1.6a}
- LogError(TStr,TRUE); {v1.6a Writeln to StatFile also}
- HALT;
- END;
- END;
- END;
-
- FSplit(P+S.Name,P,N,E);
- WritelnStatFil(
- Indent_Spaces + 'Converting '+S.Name,
- TRUE); {v1.6a Writeln also}
-
- IF NOT ConvertingInside THEN BEGIN
- Inc(filenum); {bump file count}
- WritelnStatFil('', TRUE); {v1.6a Writeln also}
- TextAttr := $0F;
- WRITELN('Converting ',P+S.Name,
- ' Saved: ',saved,' bytes File: ',filenum,' of ',numfiles);
- TextAttr := $07;
- END
- ELSE BEGIN
- WRITE(Indent_Spaces); {v1.6a}
- TStr := 'Converting internal file ' + N + E; {v1.6a}
- TextAttr := $0F;
- WRITELN(TStr); {v1.6a}
- TextAttr := $07;
- WritelnStatFil(Indent_Spaces + TStr,FALSE); {v1.6a No Writeln}
- END;
-
- IF E='.ZIP' THEN BEGIN
- WriteStatus('Checking ' + S.Name
- + ' for internal files...'); {v1.6a Write also}
-
- ExecCommand(PKZIP,'/V '+P+N);
- IF execerror <> 0 THEN BEGIN {v1.6b Exec had child process error}
- WRITELN;
- ArchiveError('Error ' + ExecErrStr + ' in ZIPfile ' + P+N+E
- + '; file skipped.'); {v1.6b}
-
- Exit;
- END;
-
- arcedSize := S.size;
- IF Internal_In_Zip THEN BEGIN
- WritelnStatFil(' found.',TRUE); {v1.6a Writeln also}
-
- {v1.6a Common error string for two possible errors }
-
- TStr := 'Error in Zipfile ' + P+N+E+'; file skipped.'; {v1.6a}
-
- x := in_Buffer('Searching');
- IF x=-1 THEN BEGIN
- ArchiveError(TStr); {v1.6a}
- Exit;
- END;
-
- Inc(x,15);
- Comment_Common; {v1.6a do common code}
-
- L := '';
- x := in_Buffer('--------'#13#10); {v1.6a}
- IF x=-1 THEN BEGIN
- ArchiveError(TStr); {v1.6a unchanged from last error}
- Exit;
- END;
-
- REPEAT
- Inc(x);
- UNTIL CHAR(Mem[bufferSeg:x]) IN ['0'..'9'];
-
- Build_L; {v1.6a common code}
-
- Snarf_Digits; {v1.6a builds C}
- Z := C; {v1.6a save unarcedSize a sec}
-
- Snarf_Digits; {v1.6a builds C}
-
- WHILE L[1]<>' ' DO L := COPY(L,2,255);
- WHILE L[1]=' ' DO L := COPY(L,2,255);
-
- { v1.6a reminder:
- Z = unarcedSize string
- L = filesinarc string
- C = arcedSize string
- S.size := arcedSize word
- The only variable we'll use later is arcedSize,
- so no need to convert the other strings to numbers.
- The filesinarc string may be 0-padded, so we'll strip
- those leading 0's.
- }
- arcedSize := S.size; {v1.6a}
-
- Strip_Zeros; {v1.6a strip L's leading 0's}
-
- WritelnStatFil( {v1.6a}
- Indent_Spaces + L + 'FILE(s), ' {v1.6a}
- + C + ' bytes zipped, ' {v1.6a}
- + Z + ' bytes unzipped', TRUE); {v1.6a Writeln also}
-
- if ArcComment<>''
- THEN WritelnStatFil( {v1.6a}
- Indent_Spaces + 'Zipfile comment: :'
- + ArcComment + '"', TRUE); {v1.6a Writeln also}
-
- WriteStatus('Unzipping ' + N + E + '...'); {v1.6a Write also}
-
- CurWork := CurWork+'\A2Z.$$$';
- MkDir(CurWork);
- ExecCommand(PKUNZIP,P+N+' '+CurWork);
-
- IF execerror <> 0 THEN BEGIN {v1.6b}
- DeleteDir(CurWork);
- Dec(CurWork[0],8);
- ArchiveError(#$0D#$0A'Error ' + ExecErrStr {v1.6b}
- + ' unzipping ' + P + N + E
- + '; FILE skipped.'); {v1.6a}
- (* v1.6a didn't DO this quite right .. leaving it for now...
- WriteLnStatus(#$0D#$0A + Indent_Spaces + TStr); {v1.6a}
- *)
- Exit;
- END;
-
- WritelnStatFil(' done.', TRUE); {v1.6a Writeln also}
- END
-
- ELSE BEGIN
- WritelnStatFil(' none found.', TRUE); {v1.6a Writeln also}
- ArchiveError(N+E+' did not need to be modified.'); {v1.6a}
-
- TrickleUpError := FALSE;
- Exit;
- END;
-
- END
- ELSE BEGIN {PKPak file}
- WriteStatus('Analyzing ' + N + E + '...'); {v1.6a Write also}
-
- ExecCommand(PKUNPAK,'-V '+P+N+E);
- WritelnStatFil(' done.', TRUE); {v1.6a Writeln also}
-
- TStr := 'Error ' + ExecErrStr + ' in archive ' + P + N + E {v1.6b}
- + '; file skipped.'; {v1.6a}
-
- IF execerror <> 0 THEN BEGIN {v1.6b}
- ArchiveError(TStr); {v1.6a}
- Exit;
- END;
-
- x := in_Buffer('Searching');
- IF x=-1 THEN BEGIN
- ArchiveError(TStr); {v1.6a Same error msg}
- Exit;
- END;
-
- Inc(x,11); {v1.6c}
- Comment_Common; {v1.6a common code}
-
- L := '';
- x := in_Buffer(#13#10'---- '); {v1.6a}
-
- IF x=-1 THEN BEGIN
- ArchiveError(TStr); {v1.6a same error msg}
- Exit;
- END;
-
- Inc(x,52); {v1.6c}
- Build_L; {v1.6a read until CR/LF}
-
- Snarf_Digits; {v1.6a builds C}
- TStr := C; {v1.6a save filesinarc string}
-
- Snarf_Digits; {v1.6a builds C}
- Z := C; {v1.6a save unarcedSize string}
-
- C := '';
- REPEAT
- C := C+L[1];
- L := COPY(L,2,255);
- UNTIL L[1] IN [#13,#10,#32];
-
- L := TStr; {v1.6a restore filesinarc string}
-
- { v1.6a reminder:
- Z = unarcedSize string
- L = filesinarc string
- C = arcedSize string
- The only variable we'll need later is arcedSize,
- so that's the only one we'll convert.
- The filesinarc string may be 0-padded,
- so we'll strip those leading 0's.
- }
- Val(C,arcedSize,code); {v1.6a We'll need this later}
-
- Strip_Zeros; {v1.6a Strip L's leading 0's}
- WritelnStatFil( {v1.6a}
- Indent_Spaces + L + ' file(s), '{v1.6a}
- + C + ' bytes arced, '
- + Z + ' bytes unarced', TRUE); {v1.6a Writeln also}
-
- IF ArcComment<>''
- THEN WritelnStatFil(
- Indent_Spaces
- + 'Archive comment: "'
- + ArcComment + '"', TRUE); {v1.6a WriteLn also}
-
- WriteStatus('Extracting files...'); {v1.6a Write also}
-
- CurWork := CurWork+'\A2Z.$$$';
- MkDir(CurWork);
- IF E='.ARC' THEN BEGIN
- ExecCommand(PKUNPAK,P+N+' '+CurWork);
- Okay := (execerror = 0); {v1.6b}
- END;
-
- IF E='.PAK' THEN BEGIN
- ExecCommand(PAK,'e '+P+N+' '+CurWork);
- Okay := (execerror = 0); {v1.6b}
- END;
-
- WRITELN(' done.');
-
- IF NOT Okay THEN BEGIN
- ArchiveError('Error ' + ExecErrStr + ' extracting ' {v1.6b}
- + P + N + E
- + '; skipping.'); {v1.6a}
-
- DeleteDir(CurWork);
- Dec(CurWork[0],8);
- Exit;
- END;
-
- END;
-
- WritelnStatFil(
- Indent_Spaces
- + 'Checking internal files...', TRUE); {v1.6a Writeln also}
-
- OCI := ConvertingInside;
- ConvertingInside := TRUE;
- Inc(internalcount);
- {$F+} {v1.6a need Far calls for this}
- SearchEngine(CurWork+'\*.*',Archive,Convert,ec);
- {$F-}
- Dec(internalcount);
- ConvertingInside := OCI;
- IF TrickleUpError THEN BEGIN
- IF InterruptRequested THEN BEGIN
- DeleteDir(CurWork);
- Dec(CurWork[0],8);
- IF ConvertingInside THEN Exit;
-
- LogError('*** Conversion interrupted ***',
- TRUE); {v1.6a Status file also}
- HALT;
- END;
-
- IF NOT ConvertingInside THEN BEGIN
- TrickleUpError := FALSE;
- LogError('Unable to convert '
- + P + N + E
- + ' due to an internal file error.',
- TRUE); {v1.6a StatFile output also}
- END;
- DeleteDir(CurWork);
- Dec(CurWork[0],8);
- Exit;
- END;
-
- CopyFile(P+N+E,P+N+'.A2B');
- WriteStatus('Creating ZIP file '
- + N + '.ZIP...'); {v1.6a Write also}
-
- Z := P+N+'.ZIP';
- Assign(T, Z);
- {$I-} Erase(T); {$I+}
- code := IOResult;
-
- IF ArcComment='' THEN
- (* v1.6d
- ExecCommand(PKZIP,Z + EASwitch + EBSwitch + ' ' {v1.6a}
- + CurWork+'\*.*')
- *)
- ExecCommand(PKZIP,Z + ' ' + CurWork+'\*.*') {v1.6d}
- ELSE BEGIN
- Assign(T, WorkDir+'ZCOMMENT.A2Z');
- REWRITE(T);
- WRITELN(T, ArcComment);
- CLOSE(T);
- Reg.BX := 0;
- Reg.AH := $45;
- MsDos(Reg);
- code := Reg.AX;
- RESET(T);
- Reg.BX := TextRec(T).Handle;
- Reg.CX := 0;
- Reg.AH := $46;
- MsDos(Reg);
- (* v1.6d
- ExecCommand(PKZIP,Z + EASwitch + EBSwitch + ' -a ' {v1.6a}
- + CurWork+'\*.* -z');
- *)
- ExecCommand(PKZIP,Z + ' -a ' + CurWork+'\*.* -z'); {v1.6d}
-
- Reg.BX := code;
- Reg.CX := 0;
- Reg.AH := $46;
- MsDos(Reg);
- Reg.BX := code;
- Reg.AH := $3E;
- MsDos(Reg);
- CLOSE(T);
- Erase(T);
- END;
-
- WritelnStatFil(' done.', TRUE); {v1.6a Writeln also}
-
- IF execerror <> 0 THEN BEGIN {v1.6b}
- ArchiveError('Error ' + ExecErrStr {v1.6b}
- + ' Unable to create zip file: ' {v1.6b}
- + Z + '; file skipped.'); {v1.6a}
-
- DeleteDir(CurWork);
- Dec(CurWork[0],8);
- CopyFile(P+N+'.A2B',P+N+E);
- Exit;
- END;
-
- FindFirst(Z,0,SRec);
- Assign(T, P+N+'.A2B');
- {$I-} Erase(T); {$I+}
- code := IOResult;
- IF NOT ConvertingInside THEN saved := saved+(arcedSize-SRec.size);
- Assign(T, Z);
- RESET(T);
- SetFTime(T, S.Time);
- CLOSE(T);
- { v1.6a no need to do this yet .. it may NOT be needed:
- STR(arcedSize-SRec.size,C);
- }
- IF ConvertingInside
- THEN WritelnStatFil(
- Indent_Spaces
- + 'Internal file '
- + N + E
- + ' converted.',
- TRUE) {v1.6a Writeln also}
-
- ELSE BEGIN {v1.6a}
-
- STR(arcedSize-SRec.size,C); {v1.6a NOW do this}
- TStr := 'File ' + P + N + E; {v1.6a build first part}
-
- IF E = '.ZIP'
- THEN TStr := TStr + ' internally'; {v1.6a build first part}
-
- TStr := TStr + ' converted to ZIP, '
- + C + ' bytes saved.'; {v1.6a}
- LogError(TStr,TRUE); {v1.6a StatFile output also}
- END;
-
- DeleteDir(CurWork);
- Dec(CurWork[0],8);
- END; {of Convert}
-
-
- PROCEDURE ConvertFiles;
- {
- This is the main conversion loop of the program. It will call the convert
- arc routine from the search engine.
- }
- VAR
- l, errorcode : Byte;
- BEGIN
- filenum := 0;
- ConvertingInside := FALSE;
- internalcount := 0;
- InterruptRequested := FALSE;
- saved := 0;
- TrickleUpError := FALSE;
- CurWork := COPY(WorkDir,1,PRED(LENGTH(WorkDir)) ); {v1.6a}
- for l := 1 TO numdirs DO
- WITH Dir[l] DO
- {$F+} {v1.6a need FAR calls}
- IF Below THEN SearchEngineAll(Dir,Name,Archive,Convert,errorcode)
- ELSE SearchEngine(Dir+Name,Archive,Convert,errorcode);
- {$F-} {v1.6a No FAR calls}
- END; {of ConvertFiles}
-
-
- PROCEDURE SummarizeLog;
- VAR S : STRING[30];
- BEGIN
- STR(saved, S);
- LogError(S+' bytes saved total.', FALSE); {v1.6a no Stat File}
- END; {of SummarizeLog}
-
-
- BEGIN {main}
- ReadCommandLine;
- CheckSubPrograms;
- OpenLogFile;
- GetFileEstimates;
- CheckBreak := FALSE;
- InstallInterruptHandler;
- ConvertFiles;
- SummarizeLog;
- END.
-