home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / podstawy / dos / 4dos / 4uzytki / 4utils86.exe / 4FF.PAS < prev    next >
Pascal/Delphi Source File  |  1995-07-09  |  18KB  |  555 lines

  1. PROGRAM FileFind;
  2. {$A+,B-,D-,E-,F-,G+,I-,L+,N-,O-,R-,S-,V-,X-}
  3. {$M 16384,0,655360}
  4. (* ----------------------------------------------------------------------
  5.    A 4DOS-aware file finder. It searches in various archives too.
  6.  
  7.    (c) 1992, 1994 Copyright by David Frey,
  8.                                Urdorferstrasse 30
  9.                                8952 Schlieren ZH
  10.                                Switzerland
  11.  
  12.        Code created using Turbo Pascal 6.0 (c) Borland International 1990
  13.  
  14.    DISCLAIMER:   This program is freeware: you are allowed to use, copy
  15.                  and change it free of charge, but you may not sell or hire
  16.                  4FF. The copyright remains in my hands.
  17.  
  18.                  If you make any (considerable) changes to the source code,
  19.                  please let me know. (send me a copy or a listing).
  20.                  I would like to see what you have done.
  21.  
  22.                  I, David Frey, the author, provide absolutely no warranty of
  23.                  any kind. The user of this software takes the entire risk of
  24.                  damages, failures, data losses or other incidents.
  25.  
  26.    NOTES:        Turbo Pascal 6.0 required for compiling. (sorry, but I'm
  27.                  using FormatStr for output)
  28.  
  29.    ENHANCEMENTS: adapted to 4DOS 4.01 - when redirecting into files,
  30.                  full descriptions will be shown, otherwise the
  31.                  descriptions will be truncated at the right screen margin.
  32.  
  33.                  paging switch (/p) added.
  34.                  Fast screen output when no redirected output has been used.
  35.  
  36.                  Searches for Read Only / Hidden directories, too.
  37.  
  38.                  ARJ File scanning added.
  39.  
  40.                  Supports now 4DOS 5.0, i.e. 200 characters description
  41.                  length.
  42.  
  43.                  Old /d switch renamed to /f. /d stands now for description.
  44.    ----------------------------------------------------------------------- *)
  45.  
  46. USES {$IFOPT G+} Test286, {$ENDIF}
  47.      Fix, Crt, Dos, Objects, Memory, Drivers,
  48.      StringDateHandling, DisplayKeyboardAndCursor, DescriptionHandling,
  49.      HandleINIFile,
  50.      ScanLZHFiles, ScanZIPFiles, ScanARJFiles, Globals;
  51.  
  52. CONST Header= '4FF 4DOS File Find 1.86 -- (c) David Frey 1992, 1995';
  53.  
  54. VAR   ActDir, StartDir            : STRING;
  55.       FileSpecArray               : FileSpecArrayType;
  56.  
  57.       DescFile                    : TEXT;
  58.       DescLine                    : STRING;
  59.       DescLineNr                  : WORD;
  60.       Desc                        : DescStr;
  61.       DescStart                   : BYTE;
  62.       DescEnd                     : BYTE;
  63.       DescFound                   : BOOLEAN;
  64.  
  65.       i,l                         : WORD;
  66.       k                           : BYTE;
  67.       FileSpecs                   : BYTE;
  68.       ps,fs                       : STRING;
  69.       IORes                       : INTEGER;
  70.  
  71.       Templ                       : STRING;
  72.       FormatTemplate              : STRING;
  73.  
  74.       OldCtrlBreakHandler         : POINTER;
  75.       OldCtrlBreakState           : BOOLEAN;
  76.       BrokeOut                    : BOOLEAN;
  77.  
  78. PROCEDURE MyCtrlBreakHandler; FAR;
  79.  
  80. BEGIN
  81.  ExitProc := OldCtrlBreakHandler; SetCBreak(OldCtrlBreakState);
  82.  {$I-}
  83.  ChDir(ActDir); IORes := IOResult;
  84.  IF BrokeOut THEN
  85.   BEGIN
  86.    WriteLn(Output);
  87.    WriteLn(Output,' EXITING - User broke out of program.');
  88.    WriteLn(Output);
  89.   END;
  90.  Close(Output);
  91.  IF NOT Redirected THEN NormVideo;
  92. END;
  93.  
  94. PROCEDURE ShowFileData(Item: PFileData; VAR Path: PathStr);
  95.  
  96. VAR Index: INTEGER;
  97.     Date : DateStr;
  98.     Time : TimeStr;
  99.  
  100. BEGIN
  101.  IF BareOutput THEN
  102.   WriteLn(Output,Path,'\',Item^.Name)
  103.  ELSE
  104.   BEGIN
  105.    IF FileCount = 0 THEN
  106.     BEGIN
  107.      WriteLn(Output); IF DoPage THEN TestForMoreMsg;
  108.      WriteLn(Output,Path,'\'); IF DoPage THEN TestForMoreMsg;
  109.     END;
  110.  
  111.    InfoArray[0] := @Item^.Name;
  112.    InfoArray[1] := @Item^.Ext;
  113.    IF Item^.Attr AND Directory = Directory THEN SizeStr := '<DIR>'
  114.    ELSE
  115.     SizeStr := FormattedLongIntStr(Item^.Size,10);
  116.                                                   InfoArray[2] := @SizeStr;
  117.    Date := FormDate(Item^.DateRec);               InfoArray[3] := @Date;
  118.    Time := FormTime(Item^.DateRec);               InfoArray[4] := @Time;
  119.  
  120.    AttrStr := '....';
  121.    IF Item^.Attr AND ReadOnly = ReadOnly THEN AttrStr[1] := 'r';
  122.    IF Item^.Attr AND Hidden   = Hidden   THEN AttrStr[2] := 'h';
  123.    IF Item^.Attr AND SysFile  = SysFile  THEN AttrStr[3] := 's';
  124.    IF Item^.Attr AND Archive  = Archive  THEN AttrStr[4] := 'a';
  125.    InfoArray[5] := @AttrStr;
  126.  
  127.    InfoArray[6] := Item^.Desc;
  128.  
  129.    FormatStr(s,FormatTemplate,InfoArray);
  130.    WriteLn(Output,s); IF DoPage THEN TestForMoreMsg;
  131.  
  132.    INC(TotalSize,Item^.Size); INC(DirSize,Item^.Size);
  133.    INC(TotalFileCount); INC(FileCount);
  134.   END;
  135. END; (* ShowFileData *)
  136.  
  137. PROCEDURE BuildList(Dir: DirStr; VAR FileSpec: FileSpecArrayType; FileSpecs: BYTE;
  138.                     Attr: BYTE);
  139. (* The starting point, dir, includes the drive *)
  140.  
  141.  
  142. VAR Search: SearchRec;
  143.     DescFileExists: BOOLEAN;
  144.     DescFileList  : PFileList;
  145.     l,i,k         : BYTE;
  146.  
  147.     PROCEDURE ExamineFile(Item: POINTER); FAR;
  148.     (* Print the file data, if the Attributes match *)
  149.  
  150.     BEGIN
  151.      IF (((searchdesc = '') AND
  152.            (NOT ExactAttr  OR
  153.             (ExactAttr AND (PFileData(Item)^.Attr = Attr)))) OR
  154.         (Pos(searchdesc,PFileData(Item)^.Desc^) > 0)) THEN
  155.       ShowFileData(PFileData(Item),Dir);
  156.     END;
  157.  
  158. BEGIN (* BuildList *)
  159.  FileCount := 0; DirSize := 0;
  160.  Attr := Attr AND NOT Directory AND NOT VolumeId;
  161.  OldLHFileName := ''; OldZipFileName := '';
  162.  
  163.  s := Dir; l := Length(s);
  164.  IF (l>3) AND (s[l] = '\') THEN Delete(s,l,1);
  165.  
  166.  l := Length(Dir); IF (s[l] = '\') THEN Delete(Dir,l,1);
  167.  
  168.  {$I-}
  169.  ChDir(s); IORes := IOResult;
  170.  {$I+}
  171.  
  172.  FOR k := 1 TO FileSpecs DO
  173.   BEGIN
  174.    DescFileList := NIL; DescFileList := New(PFileList,Init(Dir,FileSpec[k],0));
  175.    IF DescFileList = NIL THEN Abort('Unable to allocate DescFileList');
  176.  
  177.    IF (FileList^.Status = ListTooManyFiles) OR
  178.       (FileList^.Status = ListOutofMem) THEN
  179.     BEGIN
  180.      IF FileList^.Status = ListTooManyFiles THEN
  181.       WriteLn('Warning! Too many files in directory, description file will be truncated!')
  182.      ELSE
  183.       WriteLn('Warning! Out of memory, description file will be truncated!');
  184.     END;
  185.  
  186.    IF DescLong THEN
  187.     WriteLn('Warning! Some descriptions are too long; they will be truncated.');
  188.  
  189.    DescFileList^.ForEach(@ExamineFile);
  190.    Dispose(DescFileList,Done);
  191.   END;
  192.  
  193.  IF ScanLZHArchives THEN
  194.   BEGIN
  195.    FindFirst('????????.LZH',ReadOnly+Archive,Search);
  196.    WHILE DosError = 0 DO
  197.     BEGIN
  198.      SearchInLZHFile(FileSpec,FileSpecs,Dir,Search);
  199.      FindNext(Search);
  200.     END;
  201.   END;
  202.  
  203.  IF ScanZIPArchives THEN
  204.   BEGIN
  205.    FindFirst('????????.ZIP',ReadOnly+Archive,Search);
  206.    WHILE DosError = 0 DO
  207.     BEGIN
  208.      SearchInZIPFile(FileSpec,FileSpecs,Dir,Search);
  209.      FindNext(Search);
  210.     END;
  211.   END;
  212.  
  213.  IF ScanARJArchives THEN
  214.   BEGIN
  215.    FindFirst('????????.ARJ',ReadOnly+Archive,Search);
  216.    WHILE DosError = 0 DO
  217.     BEGIN
  218.      SearchInARJFile(FileSpec,FileSpecs,Dir,Search);
  219.      FindNext(Search);
  220.     END;
  221.   END;
  222.  
  223.  IF NOT BareOutput AND (FileCount > 0) THEN
  224.   BEGIN
  225.    Templ := '%-4s entr';
  226.    IF FileCount = 1 THEN Templ := Templ + 'y,  '
  227.                     ELSE Templ := Templ + 'ies,';
  228.    Templ := Templ+' %10s Bytes';
  229.  
  230.    FileStr := FormattedIntStr(FileCount,4);    InfoArray[0] := @FileStr;
  231.    SizeStr := FormattedLongIntStr(DirSize,10); InfoArray[1] := @SizeStr;
  232.    FormatStr(s,Templ,InfoArray);
  233.    WriteLn(Output,s); IF DoPage THEN TestForMoreMsg;
  234.   END;
  235.  
  236.  FindFirst('????????.???',Directory+ReadOnly+Hidden+SysFile,Search);
  237.  WHILE DosError = 0 DO
  238.   BEGIN
  239.    IF (Search.Attr AND Directory = Directory) AND
  240.       (Search.Name <> '.') AND (Search.Name <> '..') THEN
  241.     BuildList(Dir+'\'+Search.Name+'\',FileSpec,FileSpecs,Attr);
  242.    FindNext(Search);
  243.   END;
  244.  {$I-}
  245.  ChDir('..'); IORes := IOResult;
  246.  {$I+}
  247. END; (* BuildList *)
  248.  
  249.  
  250. FUNCTION DriveValid(C: CHAR): BOOLEAN; ASSEMBLER;
  251. ASM
  252.   MOV   DL,C
  253.   SUB   DL,'A'-1
  254.   MOV   AH,36H
  255.   Int   21H
  256.   INC   AX
  257.   JE    @@2
  258.   MOV   AL,1
  259. @@2:
  260. END; (* DriveValid *)
  261.  
  262. FUNCTION DiskInDrive(C: CHAR): BOOLEAN; ASSEMBLER;
  263.  
  264. ASM
  265.   PUSH  DS
  266.   MOV   DL,C
  267.   SUB   DL,'A'-1
  268.   MOV   AH,1cH    (* Get Drive Data, AL: Sec/Cluster, FF=drive empty ... *)
  269.   Int   21H
  270.   INC   AX
  271.   JZ   @@1
  272.   MOV  AL,1
  273. @@1:
  274.   POP  DS
  275. END;
  276.  
  277. FUNCTION DskExist(CONST D : CHAR) : BOOLEAN;
  278. (* True if (physical) diskette drive D is present *)
  279. (* BIOS numbering: 0=A:  1=B:                     *)
  280.  
  281. VAR Regs: Registers;
  282.     BB : Word;
  283.  
  284. BEGIN
  285.  Intr($11, Regs);
  286.  BB := 1 + (Byte(D)-65) SHL 6;
  287.  IF (Regs.AX AND BB) = BB THEN DskExist := True
  288.  ELSE                          DskExist := False;
  289. END; (* DskExist *)
  290.  
  291. FUNCTION A_ReMapped: BOOLEAN;
  292. (* True if A: is remapped to B: *)
  293.  
  294. VAR Regs: Registers;
  295.  
  296. BEGIN
  297.  WITH Regs DO
  298.    BEGIN
  299.      AX := $440E;
  300.      BL := 1;
  301.      MsDos(Regs);
  302.      IF ((Flags AND fCarry) = 0) AND (AL = 2) THEN A_ReMapped := True
  303.      ELSE                                          A_ReMapped := False;
  304.    END;
  305. END; (* A_ReMapped *)
  306.  
  307. PROCEDURE GiveHelp;
  308.  
  309. BEGIN
  310.  WriteLn(Output);
  311.  WriteLn(Output,Header);
  312.  WriteLn(Output);
  313.  WriteLn(Output,'This program is freeware: you are allowed to use, copy it free');
  314.  WriteLn(Output,'of charge, but you may not sell or hire 4FF.');
  315.  WriteLn(Output);
  316.  WriteLn(Output,'usage: 4FF [/a:[-]rash][/zx][/s][/b][/ddesc][/f][/m:nn][/?] [start dir\]{filenames}');
  317.  WriteLn(Output);
  318.  WriteLn(Output,' /a:rash search for files with these attributes set.');
  319.  WriteLn(Output,' /zx     archive type x, x is one of the following:');
  320.  WriteLn(Output,'           : all archives');
  321.  WriteLn(Output,'         - : no  archives');
  322.  WriteLn(Output,'         a : add ARJ archives.');
  323.  WriteLn(Output,'         l : add LZH archives.');
  324.  WriteLn(Output,'         z : add ZIP archives.');
  325.  WriteLn(Output,' /s      scan only subdirectories of given path `start-dir''');
  326.  WriteLn(Output,' /b      bare listing (omits size, date, and descriptions)');
  327.  WriteLn(Output,' /ddesc  list files with description desc');
  328.  WriteLn(Output,' /f      scan all drives (floppy drives included)');
  329.  WriteLn(Output,' /x      scan all fixed drives');
  330.  WriteLn(Output,' /m:nn   set right margin to nn');
  331.  WriteLn(Output,' /p      page output');
  332.  WriteLn(Output,' /?      this help display.');
  333.  HALT;
  334. END; (* GiveHelp *)
  335.  
  336. BEGIN
  337.  GetCBreak(OldCtrlBreakState); SetCBreak(FALSE);
  338.  OldCtrlBreakHandler := ExitProc; ExitProc := @MyCtrlBreakHandler;
  339.  BrokeOut := FALSE;
  340.  
  341.  GetDir(0,ActDir);
  342.  
  343.  ps := DownStr(ParamStr(1));
  344.  IF  ps[1] = '/' THEN ps[1]:= '-';
  345.  
  346.  IF (ps = '-?') OR (ps = '-h') THEN GiveHelp;
  347.  
  348.  IF TextRec(Output).Name[0] <> #0 THEN
  349.   BEGIN
  350.    Str(DescLen,DescTempl); DescTempl := '%-'+DescTempl+'s';
  351.   END;
  352.  
  353.  BareOutput      := FALSE; ExactAttr  := FALSE;
  354.  SubDirectories  := FALSE; AllDrives  := FALSE;
  355.  ScanARJArchives := TRUE;  ScanLZHArchives := TRUE; ScanZIPArchives := TRUE;
  356.  FileSpecArray[1]:= '*.*'; FileSpecs := 1; StartDir := ''; searchdesc := '';
  357.  
  358.  FormatTemplate := '%-8s%4s  %10s '+DateTempl+' '+TimeTempl+' %4s '+DescTempl;
  359.  
  360.  i := 1; l := 0; k := 0;
  361.  REPEAT
  362.   ps := ParamStr(i);
  363.   IF ps[1] = '/' THEN ps[1] := '-';
  364.   IF ps[1] = '-' THEN
  365.    BEGIN
  366.     s := Copy(ps,2,255);
  367.  
  368.     (* Case sensitive options: *)
  369.     IF (s[1] = 'd') THEN
  370.      BEGIN
  371.       searchdesc := Copy(s,2,255);
  372.       ScanARJArchives := FALSE; ScanLZHArchives := FALSE; ScanZIPArchives := FALSE;
  373.      END;
  374.  
  375.     (* Case insensitive options: *)
  376.     DownString(s);
  377.  
  378.     IF NOT SubDirectories    THEN SubDirectories    := (s='s');
  379.     IF NOT BareOutput        THEN BareOutput        := (s='b');
  380.     IF NOT FixedDrives       THEN FixedDrives       := (s='x');
  381.     IF NOT AllDrives         THEN AllDrives         := (s='f');
  382.     IF NOT DoPage AND NOT Redirected THEN DoPage    := (s='p');
  383.  
  384.     IF s[1] = 'a' THEN
  385.      BEGIN
  386.       s := Copy(s,Pos(':',s)+1,255);
  387.       Attr := 0; AttrStr := '....'; ExactAttr := TRUE;
  388.  
  389.       IF (Pos('r',s) > 0) AND (Pos('-r',s) = 0) THEN BEGIN INC(Attr,ReadOnly); AttrStr[1] := 'r'; END;
  390.       IF (Pos('h',s) > 0) AND (Pos('-h',s) = 0) THEN BEGIN INC(Attr,Hidden  ); AttrStr[2] := 'h'; UseHidden := TRUE; END;
  391.       IF (Pos('s',s) > 0) AND (Pos('-s',s) = 0) THEN BEGIN INC(Attr,SysFile ); AttrStr[3] := 's'; END;
  392.       IF (Pos('a',s) > 0) AND (Pos('-a',s) = 0) THEN BEGIN INC(Attr,Archive ); AttrStr[4] := 'a'; END;
  393.  
  394.       ScanARJArchives := FALSE; ScanLZHArchives := FALSE; ScanZIPArchives := FALSE;
  395.      END;
  396.  
  397.     IF s[1] = 'm' THEN
  398.      BEGIN
  399.       Delete(ps,1,3); Val(ps,k,IORes);
  400.       MaxViewLength := k-31-Length(DateFormat)-Length(TimeFormat);
  401.       Str(MaxViewLength,DescTempl); DescTempl := '%-'+DescTempl+'s';
  402.      END;
  403.  
  404.     IF (s[1] = 'z') AND (Length(s) > 1) THEN
  405.      FOR k := 1 TO Length(s)-1 DO
  406.       IF s[1+k] = '-' THEN
  407.        BEGIN
  408.         ScanARJArchives := FALSE;
  409.         ScanLZHArchives := FALSE;
  410.         ScanZIPArchives := FALSE;
  411.        END
  412.       ELSE
  413.        IF (s[1+k] = 'a') THEN ScanARJArchives := TRUE
  414.        ELSE
  415.         IF (s[1+k] = 'l') THEN ScanLZHArchives := TRUE
  416.         ELSE
  417.          IF (s[1+k] = 'z') THEN ScanZIPArchives := TRUE;
  418.     INC(l);
  419.    END;
  420.    INC(i);
  421.   UNTIL (i>ParamCount) OR (ps[1] <> '-');
  422.  
  423.  (* Read the .INI files *)
  424.  InitMemory;
  425.  
  426.  INIStrings := New(PINIStrings,Init); (* Read in the .INI file(s) *)
  427.  
  428.  IF INIFileExists THEN StringDateHandling.EvaluateINIFileSettings;
  429.  (* The Date & Time Formats are country-specific and are pre-initialized
  430.     in the StringDateHandling initialize-section. Re-Initializing it
  431.     with "our" defaults is not what the users wants.                     *)
  432.  
  433.  DescriptionHandling.EvaluateINIFileSettings;
  434.  DisplayKeyboardAndCursor.EvaluateINIFileSettings;
  435.  
  436.  StartDir := '';
  437.  IF l < ParamCount THEN
  438.   BEGIN
  439.    FOR i := l+1 TO ParamCount DO
  440.     BEGIN
  441.      FSplit(ParamStr(i),Path,Name,Ext);
  442.      IF (Path <> '') AND (StartDir = '') THEN
  443.        BEGIN StartDir := UpStr(Path); SubDirectories := TRUE; END;
  444.      IF Name = '' THEN Name := '*';
  445.      IF Ext  = '' THEN Ext  := '.*';
  446.  
  447.      FileSpecArray[i-l] := Name+Ext; DownString(FileSpecArray[i-l]);
  448.     END;
  449.     FileSpecs := ParamCount-l;
  450.   END;
  451.  
  452.  IF StartDir = ''      THEN StartDir := ActDir;
  453.  IF NOT SubDirectories THEN StartDir := Copy(StartDir,1,3);
  454.  
  455.  IF NOT BareOutput THEN
  456.   BEGIN
  457.    WriteLn(Output,Header);
  458.    WriteLn(Output);
  459.    WriteLn(Output,'This program is freeware: you are allowed to use,');
  460.    WriteLn(Output,'copy it free of charge, but you may not sell or hire 4FF.');
  461.    WriteLn(Output);
  462.    IF FileSpecs = 1 THEN WriteLn(Output,'Filename  = ',FileSpecArray[1],'.')
  463.    ELSE
  464.     BEGIN
  465.      Write(Output, 'Filenames = ');
  466.      FOR i := 1 TO FileSpecs DO
  467.       BEGIN
  468.        Write(Output,FileSpecArray[i]);
  469.        IF i < FileSpecs THEN Write(Output,', ')
  470.                         ELSE WriteLn(Output,'.');
  471.       END;
  472.     END;
  473.    IF AllDrives THEN WriteLn(Output,'Scanning all drives.')
  474.    ELSE
  475.     BEGIN
  476.       IF FixedDrives THEN WriteLn(Output,'Scanning fixed drives.')
  477.       ELSE
  478.         BEGIN
  479.           Write(Output,'Path     ');
  480.           IF Filespecs > 1 THEN Write(Output, ' ');
  481.           WriteLn('= ',StartDir);
  482.         END;
  483.     END;
  484.  
  485.    IF searchdesc <> '' THEN
  486.      WriteLn(Output,'Searching for descriptions containing the string ''',searchdesc,'''');
  487.  
  488.    Line := 7;
  489.    IF ExactAttr THEN
  490.     BEGIN
  491.      WriteLn(Output,'Attributes= ',AttrStr); INC(Line);
  492.     END;
  493.   END;
  494.  
  495.  IF ScanLZHArchives OR ScanZIPArchives OR ScanARJArchives THEN InstallBuffer;
  496.  IF BareOutput THEN Justify := Left;
  497.  
  498.  TotalFileCount := 0; TotalSize := 0; BrokeOut := TRUE;
  499.  
  500.  IF (NOT AllDrives) AND (NOT FixedDrives) THEN
  501.   BEGIN
  502.    l := Length(StartDir);
  503.    IF (l > 3) AND (StartDir[l] = '\') THEN Delete(StartDir,l,1);
  504.    BuildList(StartDir,FileSpecArray,FileSpecs,Attr)
  505.   END
  506.  ELSE
  507.   BEGIN
  508.    IF AllDrives THEN
  509.     BEGIN
  510.      IF DskExist('B') THEN
  511.       BEGIN
  512.        FOR Drive := 'A' TO 'B' DO
  513.          IF DiskInDrive(Drive) THEN
  514.            BuildList(Drive+':\',FileSpecArray,FileSpecs,Attr)
  515.       END
  516.      ELSE
  517.       BEGIN
  518.        IF A_ReMapped THEN Drive := 'B'
  519.                      ELSE Drive := 'A';
  520.        IF DiskInDrive(Drive) THEN
  521.          BuildList(Drive+':\',FileSpecArray,FileSpecs,Attr)
  522.       END;
  523.     END;
  524.  
  525.    IF FixedDrives OR AllDrives THEN
  526.     FOR Drive := 'C' TO 'Z' DO
  527.      IF DriveValid(Drive) AND DiskInDrive(Drive) THEN
  528.       BuildList(Drive+':\',FileSpecArray,FileSpecs,Attr);
  529.   END;
  530.  BrokeOut := FALSE;
  531.  
  532.  IF NOT BareOutput THEN
  533.   BEGIN
  534.    IF TotalFileCount = 0 THEN s := 'no files found.'
  535.    ELSE
  536.     BEGIN
  537.      Templ := '%6s file';
  538.      IF TotalFileCount = 1 THEN Templ := Templ +', '
  539.                            ELSE Templ := Templ +'s,';
  540.      Templ := Templ+'%11s Bytes';
  541.  
  542.      FileStr := FormattedIntStr(TotalFileCount,6); InfoArray[0] := @FileStr;
  543.      SizeStr := FormattedLongIntStr(TotalSize,11); InfoArray[1] := @SizeStr;
  544.      FormatStr(s,Templ,InfoArray);
  545.     END;
  546.  
  547.    WriteLn(Output,'------------------------------------------------'); IF DoPage THEN TestForMoreMsg;
  548.    WriteLn(Output,s); IF DoPage THEN TestForMoreMsg;
  549.   END;
  550.  
  551.  IF ScanLZHArchives OR ScanZIPArchives OR ScanARJArchives THEN FreeBuffer;
  552.  
  553.  DoneMemory;
  554. END.
  555.