home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* GF.PAS *)
- (* (c) 1989 Thomas Kellerer & TOOLBOX *)
- PROGRAM GlobalFind;
-
- USES Dos, Crt;
-
- VAR DirEintrag : SearchRec;
-
- OldExit : POINTER;
- StartDir,
- AktDir,
- ZielDir,
- Such,
- Pfad, Test : String;
- FName : String;
- Anzahl : WORD;
- OK,Loesch,
- Ask,SubDir,
- Size,Remove : Boolean;
- Par : BYTE;
- FSize,FSlack : LONGINT;
- CLSize : WORD;
-
- {$F+}
- PROCEDURE Exit;
- BEGIN
- IF AktDir <> '' THEN ChDir(AktDir);
- ChDir(StartDir); (* Zum Startverzeichnis zurück *)
- ExitProc := OldExit;
- END;
- {$f-}
-
- PROCEDURE DeleteFile(Name : String);
- (* Löscht eine Datei auf Diskette/Platte *)
- (* Schneller als Turbo's Assign/Erase Gespann *)
- VAR regs : Registers;
-
- BEGIN
- Name := Name + Chr(0); (* 0 als Stringabschluss *)
- regs.ax := $4100;
- regs.ds := Seg(Name);
- regs.dx := Ofs(Name) + 1; (* Längenbyte übergehen *)
- MsDos(regs);
- END;
-
- FUNCTION HoleCLSize : WORD;
- (* Hole Cluster-Size. Gibt die Anzahl der *)
- (* Sektoren pro Cluster zurück. Wird benötigt *)
- (* um den Physikalischen Platz auf der Platte *)
- (* zu berechnen *)
- VAR regs : Registers;
- BEGIN
- regs.ax := $1c00; (* Information über beliebiges *)
- (* Laufwerk holen *)
- regs.dl := $0; (* 0 = aktuelles Laufwerk *)
- MsDos(regs);
- HoleClSize := regs.al * regs.cx;
- END;
-
- FUNCTION HoleJN(Text : String) : CHAR;
- VAR ch : CHAR;
- BEGIN
- Write(Text,' (J/N)');
- REPEAT
- ch := UpCase(ReadKey);
- UNTIL (ch = 'J') OR (ch = 'N');
- HoleJN := ch;
- END;
-
- PROCEDURE WriteDateTime(Datum : DateTime);
- (* Schreibt Zeit/Datum formatiert als 01.01.1989 12:10 *)
-
- PROCEDURE Put(i : WORD);
- BEGIN
- IF i < 10 THEN Write('0', i)
- ELSE Write(i);
- END;
-
- BEGIN
- Put(Datum.Day); Write('.');
- Put(Datum.Month); Write('.');
- Put(Datum.Year); Write(' ');
- Put(Datum.Hour); Write(':');
- Put(Datum.Min);
- END;
-
- PROCEDURE WriteF(s : String);
- (* Gibt Zeichenkette linksbündig auf 14 Zeichen Länge aus *)
- BEGIN
- REPEAT
- s := s + ' ';
- UNTIL Length(s) = 14;
- Write(s);
- END;
-
- PROCEDURE TrenneName(angabe : String; VAR pfad : String;
- VAR name : String);
- (* Trennt einen übergebenen Namen in *)
- (* Pfad und Dateinamen auf *)
- VAR k, len : BYTE;
- BEGIN
- k := Length(angabe);
- WHILE (angabe[k] <> '\') AND (angabe[k] <> ':')
- AND (k <> 0) DO BEGIN
- Dec(k);
- END;
- IF k = 0 THEN Pfad := ''
- ELSE Pfad := Copy(angabe, 1, k-1);
- IF angabe[k] = ':' THEN Pfad := Pfad + ':';
- IF (angabe[k] = '\') AND (Length(Pfad) = 2)
- AND (Pfad[2] = ':') THEN
- pfad := pfad + '\';
- Name := Copy(angabe, k+1, len-k);
- IF (Name = '') AND (Pfad <> '') THEN Name := '*.*';
- END;
-
- PROCEDURE ToUpper(VAR arg : String);
- (* 'UpCase' für eine Zeichenkette *)
- VAR k : Integer;
- BEGIN
- FOR k := 1 TO Length(arg) DO arg[k] := UpCase(arg[k]);
- END;
-
- PROCEDURE LoescheDateien(Name : String; VAR zahl : WORD;
- VAR Groesse, Slack : LONGINT);
- (* Zeigt alle Dateien mit der Bezeichnung Name im *)
- (* aktuellen Directory an. Falls sie gelöscht werden *)
- (* sollen, wird dies auch getan. *)
- VAR lauf : WORD;
- datei : FILE;
- DirInfo : SearchRec;
- AktDir : String;
- Del : BOOLEAN;
- FDatum : DateTime;
- y : Byte;
- h : LongInt;
- DelName : String;
-
- BEGIN
- GetDir(0, AktDir);
- FindFirst(Name, 7, DirInfo);
- IF DOSError = 0 THEN WriteLn(#13,#10,AktDir);
- WHILE (DOSError=0) DO BEGIN
- IF Loesch THEN BEGIN
- IF Ask THEN BEGIN
- Write(DirInfo.Name);
- Del := (HoleJN(' Löschen?') = 'J');
- DelLine; Write(#13);
- END ELSE
- Del := TRUE;
- IF Del THEN BEGIN
- DeleteFile(DirInfo.Name);
- Inc(Zahl);
- END;
- END;
- Write(' ');
- WriteF(DirInfo.Name);
- IF Del AND Loesch THEN
- WriteLn(' Gelöscht...')
- ELSE BEGIN
- UnpackTime(DirInfo.Time, FDatum);
- Write(' ');
- WriteDateTime(FDatum);
- WriteLn(DirInfo.Size:8, ' Bytes');
- Groesse := Groesse + DirInfo.Size;
- h := DirInfo.Size DIV CLSize;
- IF h * CLSize = DirInfo.Size THEN
- slack := slack + h * CLSize
- ELSE
- slack := slack + (h + 1) * CLSize;
- END;
- IF NOT Loesch THEN Inc(Zahl);
- FindNext(DirInfo);
- END;
- END;
-
- PROCEDURE BearbeiteDir(Datei : String; VAR Zahl : WORD;
- VAR gr, sl : LONGINT);
- (* Durchsucht das aktuelle Directory nach Sub-Directories *)
- VAR DirInfo : SearchRec;
- BEGIN
- LoescheDateien(Datei, Zahl, gr, sl);
- (* Alle Dateien anzeigen/Löschen *)
- FindFirst('*.*', Directory, DirInfo); (* SubDir ??? *)
-
- WITH DirInfo DO
- WHILE DOSError = 0 DO BEGIN
- IF (Attr = Directory) AND (Name[1] <> '.') THEN BEGIN
- (* Falls es das Attribut 'Directory' hat und nicht *)
- (* 'nach oben zeigt' so wird gewechselt. Die *)
- (* Funktion FindFirst liefert nämlich das '.' und *)
- (* '..' am Anfang eines Unterverzeichnisses auch *)
- (* zurück... *)
- ChDir(DirInfo.Name); (* SubDir bearbeiten *)
- BearbeiteDir(Datei,Zahl,gr,sl); (* Rekursion *)
- ChDir('..'); (* Und zurück zum Ausgang *)
- IF Remove THEN BEGIN
- (* Soll das Directory gelöschte werden ?? *)
- {$I-}
- RmDir(DirInfo.Name);
- {$I+}
- IF IOResult <> 0 THEN
- WriteLn('Directory ', DirInfo.Name,
- 'nicht leer. Nicht gelöscht')
- ELSE
- WriteLn('Directory ', DirInfo.Name,
- ' gelöscht');
- END;
- END;
- FindNext(DirInfo); (* Weitersuchen bis Ende *)
- END;
- END;
-
- BEGIN
- OldExit := ExitProc;
- (* Exit Pointer verbiegen, damit bei Ctrl&Break *)
- ExitProc := @Exit;
- (* wieder das ursprüngliche Verzeichnis eingestellt *)
- FSize := 0; FSlack := 0; (* wird *)
- GetDir(0, StartDir);
- (* Aktuelles Verzeichnis holen und merken *)
- CheckBreak := TRUE;
-
- (* Falls eine Umleitung auf Dos-Ebene mit '>' gewünscht *)
- (* ist z.B.: gf *.* > prn, so müssen die Standard- *)
- (* Ein/Ausgaberoutinen von DOS verwendet werden. Dabei *)
- (* ist dann aber ein Abbruch mit CTRL & BREAK nicht *)
- (* mehr möglich. *)
- (* Assign(Input, ''); Reset(Input); *)
- (* Assign(Output, ''); Rewrite(Output); *)
- (* DirectVideo := FALSE; *)
-
- IF (ParamCount = 0) OR (ParamStr(1) = '?') THEN BEGIN
- (* Hilfe Ausgeben *)
- WriteLn('Gebrauch: gf name [/d] [/s] [/f] [/n] [/r]');
- WriteLn;
- WriteLn('/d Löschen der gefunden Dateien');
- WriteLn('/f Löschen ohne zu fragen');
- WriteLn('/s Gesamtgröße der Dateien');
- WriteLn('/n Sub-Directories NICHT durchsuchen');
- WriteLn('/r Sub-Directiores löschen');
- WriteLn;
- WriteLn('Name : Beliebieger MS-DOS Datei-Name ',
- '(mit Wildcard)');
- END ELSE BEGIN
- (* Parameter wurde übergeben also kanns losgehen *)
- Such := ParamStr(1); (* Dateiname *)
- TrenneName(Such, Pfad, FName);
- AktDir := '';
- IF Pfad <> '' THEN BEGIN
- (* Soll in einem anderem Pfad gesucht werden ? *)
- IF Pfad[1] <> StartDir[1] THEN (* Laufwerkswechsel *)
- GetDir(Ord(UpCase(Pfad[1])) - 64, AktDir);
- {$I-}
- ChDir(Pfad); (* versuche Verzeichnis zu wechseln *)
- {$I+}
- END;
- Anzahl := 0;
- IF IOResult = 0 THEN BEGIN
- (* Verzeichniswechsel war erfolgreich... *)
- CLSize := HoleCLSize;
- Ask := TRUE; (* Standardeinstellungen *)
- SubDir := TRUE;
- Loesch := FALSE;
- Size := FALSE;
- Remove := FALSE;
- FOR Par := 2 TO ParamCount DO BEGIN
- (* Schalter auswerten *)
- Test := ParamStr(par);
- IF (Test[1] = '\') OR (Test[1] = '/') THEN BEGIN
- ToUpper(Test);
- CASE Test[2] OF
- 'F' : Ask := FALSE;
- 'S' : Size := TRUE;
- 'D' : Loesch := TRUE;
- 'N' : SubDir := FALSE;
- 'R' : Remove := TRUE;
- END;
- END;
- END;
- IF SubDir THEN
- BearbeiteDir(FName, Anzahl, FSize, FSlack)
- ELSE (* Nur aktuelles Verzeichnis bearbeiten *)
- LoescheDateien(FName, Anzahl, FSize, FSlack);
- IF AktDir <> '' THEN
- ChDir(AktDir);
- ChDir(StartDir);
- IF Loesch THEN
- WriteLn(Anzahl,' Datei(en) gelöscht')
- ELSE BEGIN
- WriteLn(Anzahl,' Datei(en) gefunden');
- IF Size THEN BEGIN
- Writeln('Gesamt: ',FSize:8,
- ' Bytes');
- WriteLn('Tatsächlicher Platzbedarf: ',FSlack:8,
- ' Bytes');
- WriteLn('Verschwendet: ',
- FSlack-FSize:8,' Bytes');
- END;
- END;
- END ELSE
- WriteLn('Pfad nicht gefunden');
- END;
- END.
- (* ------------------------------------------------------ *)
- (* Ende von GF.PAS *)