Disketteninhaltsverzeichnis (Pascal)

Bild 1.: So meldet sich unser Programm. Es kann dann ein Name für die Liste angegeben werden

Wer hat sich wohl noch nicht gewünscht, das komplette Inhaltsverzeichnis einer Diskette (oder Partition einer Harddisk) komplett auslesen zu können und als ASCII-Datei weiterzuverwenden? Das hier vorgestellte Programm löst das Problem.

Zuerst ein paar Worte zur Bedienung. Am Anfang steht das eigene Programm, denn bei Diskinhalt handelt es sich nur um eine Include-Datei, die für ST Pascal Plus-Programme geeignet ist. Das Demoprogramm kann man allerdings normal starten. Als Eingabe sind das gewünschte Laufwerk, der Name der Ausgabedatei, Sortierform und Ausgabeart anzugeben. Sortiert werden kann nach Dateinamen (N), Extension (E), Größe (G), Datum (D) und auch nicht (), als Ausgabeform kann man Label (L), erweitert (E) und normal () wählen. Hat man alle Eingaben erledigt, so geht's los, d.h. das Programm arbeitet so richtig, und nach kurzer Zeit ist (in dem Beispiel) das Inhaltsverzeichnis der im Laufwerk A befindlichen Diskette in der Datei INH_A.TXT abgespeichert. Wer das Programm mit einem Command-Line-Interpreter aufrufen möchte, der kann auch dieses machen. Zusätzlich zum Programmnamen (DI.TOS) sind das Laufwerk und die Ausgabedatei anzugeben. Analog natürlich auch bei einer TTP-Anwendung (hier muß das Programm auf .TTP enden): DI.TOS A E:\INH_A.TXT (siehe Bild).

Ein (erweitertes) Inhaltsverzeichnis könnte dann wie in Tab. 1 aussehen. Die Bedienung war doch einfach, oder? Aber auch ein paar Erklärungen zum Listing sollen nicht fehlen. Das Programm wurde mit ST Pascal Plus 2.0 entwickelt. Es werden die drei Betriebssystemroutinen FSETDTA (Gemdos 26), FSFIRST (Gemdos 76) und FSNEXT (Gemdos 79) benutzt. Fsetdta wird benötigt, um die Disket-ten-Transfer-Adresse zu setzen. Dies ist ein Puffer, der jeweils die nötigen Daten zu den Dateien enthält. Die ersten 20 Bytes sind reserviert, d.h. eigentlich sind es 21. Das 22. Byte enthält das Datei-Attribut. Damit es zu keinen Problemen beim Einlesen kommt, wurde das 21. reservierte Byte mit dem 22. zu einem Wort zusammengezogen. Es folgen zwei Integer-Zahlen für Uhrzeit und Datum (als Bit-Muster verschlüsselt) und eine Long_Integer-Zahl für die Dateilänge. Die letzten 14 Bytes enthalten den Dateinamen. Zusammen machts also 44 Bytes. Fsfirst dient nun dazu, eine bestimmte Datei zu finden. Hierzu wird ein Dateiname (in diesem Programm '.’, da auch Wildcards erlaubt sind) und das entsprechende Attribut übergeben. Das Attribut $08 (Bit 3 gesetzt) steht für den Diskettennamen und $10 (Bit 4 gesetzt) für die restlichen Dateien. Obwohl Bit 4 eigentlich aussagt, daß es sich um ein Teilverzeichnis, also um einen Ordner, handeln soll, werden mit dem Attribut $ 10 alle Dateien herausgesucht. Eine nachträgliche Überprüfung des Bytes 22 aus dem Puffer stellt aber klar, ob es nun ein Ordner oder eine normale Datei ist. Wird mit Fsfirst eine Datei gefunden, so finden sich die entsprechenden Daten in dem oben genannten Puffer wieder. Fsnext schließlich dient dazu, die nächste Datei zu finden. Sollte mit Fsnext ein negativer Wert (-49) ermittelt werden, sind keine weiteren Dateien vorhanden.

Bild 2: Tabelle 2 bildlich dargestellt

Die Routine arbeitet folgendermaßen: Nach Übergabe der notwendigen Werte (Laufwerk, Sortiermodus, Ausgabeform, Ausgabedatei) wird der Titel der Diskette gesucht (PRO-CEDURE TITEL). Dieser wird nur dann ausgegeben, wenn er auch wirklich vorhanden ist. Erst jetzt werden die einzelnen Dateien ermittelt. Die Suche beginnt auf der obersten Ebene. Gleichzeitig mit Ausgabe der Dateinamen etc. werden die Ordner erkannt und in eine Liste eingetragen. Sind auf einer Ebene in einem Ordner alle Dateien ausgegeben, wird mit der Suche in den in der Liste eingetragenen Teilverzeichnissen fortgefahren bis die Liste keine Ordnernamen mehr enthält. Flier wird die Möglichkeit des rekursiven Aufrufes ausgenutzt. Die Prozedur SUCHEN ruft sich selbst solange auf, bis keine Liste mehr mit Ordnernamen verfügbar ist. Dann wird eine Ebene zurückgesprungen und dort weitergesucht. Es entsteht eine Baumstruktur. Ein paar weitere Erklärungen sind im Listing eingearbeitet.

Jeweils wenn ein Ordnerinhalt ausgelesen wurde, kann sortiert werden. Die Sortierung erfolgt nicht nur nach einem Kriterium, sondern vielmehr nach allen. Diese Kriterien erhalten eine Rangordnung. Sortiert man etwa nach Dateinamen, wird als sekundäres Kriterium die Extension herangezogen und danach die anderen.

Hier noch etwas zur Baumstruktur. Angenommen, wir haben eine (relativ) extreme Verschachtelung auf der Diskette, etwa wie sie in Tabelle 2 zu sehen ist.

Außer dem Programm DI.TTP ist kein weiteres File auf der Diskette zu finden, aber mengenweise Ordner. Diesen Ordnern kann man einer Baumstruktur zuordnen, wie sie in Bild 2 zu sehen ist.

Deutlich zu erkennen ist, wo sich welcher Ordner befindet und welche Ordner wiederum darin enthalten sind.


    Inhalt von: LINKER.CCD

    ----- A:\*.* ------

    O   DEMOS            0 16-11-87 19:06
        DESKTOP .INF   483 16-11-87 19:07
        DRUCKER .PRG 29059 16-11-87 19:07
        EDITOR  .PRG 33394 16-11-87 19:08
        EDITOR  .RSC  5562 16-11-87 19:08
        ERRORS  .TXT  5844 16-11-87 19:08
        GEMCONST.PAS  5452 16-11-87 19:08
        GEMSUBS .PAS  9507 16-11-87 19:08
        GEMTYPE .PAS  6508 16-11-87 19:08
        K1MB1354.INF  1321 16-11-87 19:08
        K512K354.INF  1321 16-11-87 19:08
        LINKER  .PRG  4712 16-11-87 19:08
        LISTPAS .PRG 27466 16-11-87 19:09
        LISTPAS .PRT  3472 16-11-87 19:09
        MANAGER .PRG 73306 16-11-87 19:09
        MANAGER .TXT  1405 16-11-87 19:09
        PASCAL  .INF  1317 16-11-87 19:09
        TRIXCONS.PAS   845 16-11-87 19:10
        TRIXSUBS.PAS  5088 16-11-87 19:10
        TRIXTYPE.PAS  1035 16-11-87 19:10

    Ordner : 1 
    Dateien: 19 
    Bytes  : 217097

    ----- A:\DEMOS\*.* ------
    O   BITBLT            0 16-11-87 19:07
        ACCDEMO .PAS   6267 16-11-87 19:07
        DCOS    .PAS   3150 16-11-87 19:07
        DIALOG  .PAS   1254 16-11-87 19:06
        GEM_DEMO.PAS   2061 16-11-87 19:07
        QXLINES .PAS   2595 16-11-87 19:06
        SAMPLE  .PAS   3540 16-11-87 19:07
        WINDTEST.PAS   3218 16-11-87 19:06

    Ordner : 1 
    Dateien: 7 
    Bytes  : 22085

    ----- A:\DEMOS\BITBLT\*.* ------
        BITBLT .DOC   1100 16-11-87 19:07
        BITBLT .PAS  17810 16-11-87 19:07

    Ordner : 0 
    Dateien: 2 
    Bytes : 18910

    Ordner insgesamt       : 2
    Dateien insgesamt      : 28
    Datei-Bytes insgesamt  : 258092
    freier Speicherplatz   : 79872 Bytes
    belegter Speicherplatz : 279552 Bytes 
    Speicherplatz insgesamt: 359424 Bytes

Tabelle 1: So könnte ein erweitertes Inhaltsverzeichnis aussehen

----- A:\*.* -----
O   ORDNER          0 29-12-87 10:39
    DI      .TTP 9955 29-12-87 10:44

----- A:\ORDNER\*.* —-—
O   ORDNER_A    0 29-12-87 10:39
O   ORDNER_B    0 29-12-87 10:39
O   ORDNER_C    0 29-12-87 10:40
O   ORDNER_D    0 29-12-87 10:40

----- A:\ORDNER\ORDNER_A\*.* -----
O   ORDNER_A.1  0 29-12-87 10:40
O   ORDNER_A.2  0 29-12-87 10:40
O   ORDNER_A.3  0 29-12-87 10:40

----- A:\ORDNER\ORDNER_A\ORDNER_A.1\*.* -----

----- A:\ORDNER\ORDNER_A\ORDNER_A.2\*.* -----
O   ORDNER_A.2_1 0 29-12-87 10:42
O   ORDNER_A.2_2 0 29-12-87 10:43

----- A:\ORDNER\ORDNER_A\ORDNER_A.2\ORDNER_A.2_1\*.* -----

----- A:\ORDNER\ORDNER_A\ORDNER_A.2\ORDNER_A.2_2\*.* -----

----- A:\ORDNER\ORDNER_A\ORDNER_A.3\*.* -----

----- A:\ORDNER\ORDNER_B\*.* -----
O   ORDNER_B.1    0 29-12-87 10:41

----- A:\ORDNER\ORDNER_B\ORDNER_B.1\*.* -----
O   ORDNER_B.1_1  0 29-12-87 10:42

----- A:\ORDNER\ORDNER_B\ORDNER_B.1\ORDNER_B.1_1\*.* -----

----- A:\ORDNER\ORDNER_C\*.* -----
O   ORDNER_C.1    0 29-12-87 10:41
O   ORDNER_C.2    0 29-12-87 10:41

----- A:\ORDNER\ORDNER_C\ORDNER_C.l\*.* -----
O   ORDNER_C.1_1  0 29-12-87 10:41
O   ORDNER_C.1_2  0 29-12-87 10:41

----- A:\ORDNER\ORDNER_C\ORDNER_C.l\ORDNER_C.1_1\*.* -----

----- A:\ORDNER\ORDNER_C\ORDNER_C.l\ORDNER_C.1_2\*.* -----

----- A:\ORDNER\ORDNER_C\ORDNER_C.2\*.* -----

----- A:\ORDNER\ORDNER_D\*.* -----

Tabelle 2: Eine extrem verschachtelte Baumstruktur

Das war’s schon.

Im eigenen Programm muß man allerdings darauf achten, daß auch das Laufwerk, welches man abfragen möchte, existiert. Eine Überprüfung, ob die Ausgabedatei existiert, ist auch ratsam, damit nicht versehentlich eine Datei überschrieben wird.

Die Existenz eines Laufwerkes ist mit der BIOS-Funktion DRVMAP (BIOS 10) zu überprüfen. Bei Aufruf der Funktion erhält man einen Bitvektor zurück, der Auskunft über die vorhandenen Laufwerke gibt. Hierbei bedeutet A: Bit 0, B: Bit 1, usw..

Ob eine Datei vorhanden ist, kann man beispielsweise mit FSFIRST (GEMDOS 78) überprüfen. Diese Funktion haben wir ja bereits in der obigen Includedatei benutzt. Statt des Dateinamens mit Wildcards (.) übergibt man zum Suchen einer speziellen Datei einfach den konkreten Namen, eventuell mit Pfad.

Möchte man eine Verbindung zu anderen Programmen herstellen, bietet es sich an. die SCRP-Funktionen aus dem AES zu verwenden. Mit SCRP_WRITE (AES 81) könnte unser Diskinhalt-Programm den gerade verwandten Dateinamen für die Ausgabedatei in einer internen Zwischenablage abspeichern. Diese Zwischenablage könnte dann von einem beliebigen anderen Programm mittels SCRP_READ (AES 80) abgefragt werden.

Ich wünsche Ihnen viel Freude beim Eingeben und Ausprobieren.

Literatur:

[1] Anleitung ST Pascal Plus (CCD), 1. Auflage, 1986

[2] Atari ST Profibuch, Sybex, Jankowski/Reschke Rabich. 2. Auflage, 1987

(*******************************************************)
(* Komplettes Oisketteninhaltsverzeichnis in Textfile  *)
(* schreiben Version 1.82                              *)
(* --------------------------------------------------- *)
(* Entwickelt mit ST Pascal Plus 2.02 von CCD.         *)
(* Autor: Dietmar Rabich, Döuelingsweg 2, 4408 Dülmen  *) 
(* Datum: 2. Januar 1988                               *)
(* Letztes Editierdatum: 18. Januar 1988               *)
(*                                                     *)
(* Literatur: ATARI ST Profibuch, Sybex-Verlag         *)
(*******************************************************)

(* Ausgaberoutine für den Inhalt einer Diskette (oder harddiskpartition) *) 
procedure ausgabe_diskinhalt ( ausgform, sortmod, 
                               laufwerk : char;
                               ausgdat : string );

(* * * * Typendeklarationen * * * *)

type cstring     = packed array [1..255] of char:
     cstr14      = packed array [1..14] of char:
     str12       = string[12];
     ordn_array  = array [1..50] of str12;
     datei_daten = record (* Record für *)
                   reserviert : packed array [0..19]
                                of byte:(* Filedaten *) 
                     attribut : short_integer;
                (* Attribut-Information im Low-Byte *)
                     zeit     : short_integer;
                     datum    : short_integer;
                     groesse  : long_integer;
                     filename : cstr14
                   end;
     speicher_info = array [1..4] of long_integer;

(* * Variablendeklarationen * * *)

var dat          : text;        (* Textfile *)
    such         : string;      (* Suchmaske *)
    laenge_such,                (* Länge Suchmaske *)
    glob_ord_anz,               (* Global-Anzahl Ordner *)
    glob_dat_anz : short_integer; (* Global-Anzahl Dateien *)
    glob_dat_gr,                (* Global-Große Dateien *)
    frei,ins     : long_integer; (* Speicherplatz *)

(* * * * GEMDOS - Routinen * * * *)

(* Setzen der Disketten-Transfer-Adresse *) 
procedure fsetdta (var file_daten : datei_daten):
 GEMDOS($1A):

(* Freier Speicherplatz *) 
function dfree (var sp : speicher_info: lfwerk : short_integer) : short_integer;
 GEMDOS($36);

(* Feststellen, ob Datei vorhanden *) 
function fsfirst (var pfad : cstring; attribut : short_integer) : short_integer;
 GEMDOS($4E)!

(* Nächste Datei, falls vorhanden, aufrufen *) 
function fsnext : short_integer;
 GEMDOS($4F);

(* Umwandlung cstr14 in string *) 
procedure c14topstr (str1 : cstr14; var str2 : string);

    var i : short_integer;

    begin { Begin of C14TOPSTR }
        i :=1; 
        str2:='';
        while (str1[i]<>chr(0)) and (i<=14) do 
        begin
            str2:=concat(str2,str1[i]);
            i:=i+1
        end
    end; { End of C14TOPSTR }

(* Umwandlung string in c s t r i n g *) 
procedure ptocstr (str1 : string; var str2 : cstring);

    var i : short_integer;

    begin { Begin of PTOCSTR } 
        str1:=concat(str1,chr(0)); 
        for i:=1 to length(str1) do 
            str2[i] :=str1[i] 
    end; { End of PTOCSTR }

(* Umwandlung in Großbuchstaben *) 
procedure big.letter (var l : char);

    begin { Begin of BIG_LETTER }
     if l in ['a'..'z'] then    (* Kennung mit großem *)
      l:=chr(ord(l))-32);       (* Buchstaben *)
    end; { End of BIG_LETTER }

(* Ausgabe des belegten und freien Speicherplatzes *) 
procedure Speicherplatz (var fre_speicher,ins_speicher: long_integer);

    var sp_inf  : speicher_info; 
        dfr     : short_integer;

    begin { Begin of SPEICHERPLATZ } 
        dfr:=dfree(sp_inf,ord(laufwerk)-64);
        (* sp_inf[1] : Anzahl der freien Cluster    *)
        (* sp_inf[2] : Gesamtzahl der Cluster       *)
        (* sp_inf[3] : Bytes pro Sektor             *)
        (* sp_inf[4] : Sektoren pro Cluster         *)

        (* Bei einer leeren Diskette entsteht eine Differenz *)
        (* von 2 kB zwischenfreiem und Gesamtspeicherplatz.  *) 
        ins_speicher:=sp_inf[2]*sp_inf[3]*sp_inf[4];
        (* Speicherplatz insgesamt *) 
        fre_speicher:=sp_inf[1]]*sp_inf(3)*sp_inf[4]
        (* freier Speicherplatz *) 
    end; { End of SPEICHERPLATZ }

(* Diskettennamen ermitteln und ausgeben *) 
procedure titel;

 var file_daten : datei_daten; 
     dateiname  : string; 
     path       : cstring;
     l          : short_integer;

    begin { Begin of TITEL } 
        fsetdta(file_daten);
        ptocstr(concat(laufwerk,':',such),path); 
        if fsfirst(path,$08)>=0 then 
        (* Diskettenname vorhanden ? *) 
         begin
            c14topstr(file_daten.filename,dateiname); 
            writeln(dat,'Inhalt von: ',dateiname); 
            writeln(dat) 
         end
    end; { End of TITEL >

(* Inhalt eines Ordners ausgeben und darin vorhandene Ordnernamen zurückgeben *) 
procedure Inhalt (path : cstring;
                  var neue_dat : ordn_array; 
                  var anz,
                      glob_ord,
                      glob_dat : short_integer; 
                  var dat_size : long_integer);

type array_datinf = array [1..200] of string;

var next_file,
    tag,monat,jahr, (* Zeitangaben *)
    stunden,minuten,
    punkt,
    dat_anz, (* lokale Oateienanzahl *)
    i           : short_integer:
    lok_groesse : long_integer: (* lokale Dateigesamtgröße *)
    file_daten  : datei_daten;
    dateiname,
    date,time,
    datn,ext,
    pre         : string;
    dat_str     : array_datinf;
    (* Datei Informationen *)

(* Sortieren der Dateidaten *)

procedure sortiere (var dat_str : array_datinf; anz : short_integer);

type str35 = string[35];
     kennarray = array [1..200] of str35;

var i,inc   : short_integer;
    kennung : kennarray; (* Array für Kennungen *)
    sort    : boolean;
    hk      : str35;
    h       : string;

(* Suchkennung erzeugen *)

procedure erzeuge_kennung(dat_str   : array_datinf;
                          var kenn  : kennarray;
                          n         : short_integer);


 type flg_array =  array CI. .83 of short_integer;  
 var i : short_integer;   
     f : fig.array; (* Array für Rangfolge der *)    
                    (* Suchkriterien *)  
 (* Kennung zusammenstellen *)    
 procedure stelle_zusammen (rflge : flg_array; s : string; var k : str35);
     
 var i short_integer;   
    
 (* notwendige Characters anfügen *)    
 procedure fuege_an (var k : str35; s : string; p1,p2 : short_integer);   
    
 var i : short_integer;   
    
 begin { Begin of FUEGE_AN } 
    for :=p1 to p2 do   
     k:=concat(k,s[i]);    
 end; { End of FUEGE_AN } 
    
 begin { Begin of STELLE_ZUSAMMEN }  
    for i:=1 to 8 do
     case rflge[i] of  
        1 : fuege_an(k,s,4,11);  (* Dateiname *)   
        2 : fuege_an(k,s,13,15); (* Extension *)   
        3 : fuege_an(k,s,33,34): (* Jahr   *)   
        4 : fuege_an(k,s,30,31); (* Monat  *)  
        5 : fuege_an(k,s,27,28); (* Tag    *)
        6 : fuege_an(k,s,37,38); (* Stunde *)  
        7 : fuege_an(k,s,40,41); (* Minute *)  
        8 : fuege_an(k,s,17,24)  (* GröBe  *)  
 end; { End of STELLE_ZUSAMMEN } 
    
 begin { Begin of ERZEUGE_KENNUNG }
    for i:=1 to n do
    begin
    (* Damit die Ordner zuerst ausgegeben werden (chr(32)<chr(33)). *)    
    if dat_str[i,2]='0' then (* Ordner *)    
        kenn[i]:=chr(32)
    else
        kenn:=chr(33);
    (* Die Sortierung erfolgt nicht(!) nur nach dem angegebenen Kriterium, *)
    (* sondern in Rangordnung nach allen Kriterien. #)  
     case sortmod of
     'N' :  begin
             f[1]:=1; (* Sortieren nach Dateiname *)  
             f[2]:=2;
             f[3]:=3;
             f[4]:=4:  
             f[5]:=5i  
             f[6]:=6:  
             f[7]:=7;  
             f[8]:=8  
            end;   
     'E' : begin
             f[1]:=2; (* Sortieren nach Extension *)  
             f[2]:=1; 
             f[3]:=3; 
             f[4]:=4;  
             f[5]:=5;  
             f[6]:=6;  
             f[7]:=7;  
             f[8]:=8  
            end;
     'G' : begin
             f[1]:=8; (* Sortieren nach GröBe *)  
             f[2]:=1;  
             f[3]:=2;  
             f[4]:=3;  
             f[5]:=4;  
             f[6]:=5;  
             f[7]:=6;  
             f[8]:=7  
            end;   
     'D' : begin  
             f[1]:=3; (* Sortieren nach Datum *)  
             f[2]:=4;  
             f[3]:=5;  
             f[4]:=6;  
             f[5]:=7;  
             f[6]:=1;  
             f[7]:=2;  
             f[8]:=8  
            end
        end;
    stelle_zusammen(f,dat_strCiJ.kennm)    
  end; { End of ERZEUGE.KENNUNG }

 begin { Begin of SORTIERE }
    erzeuge_kennung(dat_str,kennung,anz);   
    inc:=1;
    repeat
        sort:=true; (* Sortierroutine (Bubble-Sort reicht hier) *)
        for i:=1 to anz-inc do
            if kennung[i]>kennung[i+1] then
            begin
                hk          :=kennung[i]; (* Vertauschen der Kennung *)
                kennung[i]  :=kennung[i+1];
                kennung[i+1]:=hk;
                h           :=dat_str[i];
                dat_str[i]  :=dat_str[i+1];(* Vertauschen der Dateiinformation *)
                dat_str[i+1]:=h;
                sort        :=false
            end;
        inc:=inc+1
    until sort
 end; { End of SORTIERE }

(* Sortieren der Ordnernamen *)
procedure sortiere_ord (var ordner : ordn_array; anz : short_integer);

var i,inc   : short_integer;
    sort    : boolean;
    h       : str12;

begin { Begin of SORTIERE_ORD } 
 inc:=1:
 repeat
  sort:=true; (* Sortierroutine #)
  for i:=1 to anz-inc do
   if ordner[i]>ordner[i+1] then
    begin
     h          :=ordner[i];
     ordner[i]  :=ordner[i+1]; 
     ordner[i+1]:=h;            (* Vertauschen der Ordnernamen *)
     sort       :=false
    end;
  inc:=inc+1
 until sort
end; { End of SORTIERE_ORD }

begin { Begin of INHALT }
 fsetdta(file_daten):
 anz        :=0;
 dat_anz    :=0:
 lok_groesse:=8;
 i:=0;
 if fsfirst(path,$0)>=0 then (* Auf geht's mit der *)
  repeat                     (* Suche *)
   with file_daten do
    begin
     c14topstr(filename,dateiname);
     if (dateiname<>'.') and (dateiname<>'..') then
     (* Ausgabe Daten *)
      begin
       if attribut&$10>0 then (* Falls Ordner, merken *)
        begin
         anz            :=anz+1:
         neue_dat[anz)  :=dateiname;
         pre            :=' 0 ' (* Ordner kennzeichnen *)
        end
     else
      begin
        dat_anz:=dat_anz+1;
        pre :='   '
      end;
    punkt:=pos('.',dateiname); (* Extension ? *)
    if punkt>0 then
      begin
        (* Dateiname und Extension linksbündig *)
        datn    :=dateiname; 
        delete(datn,punkt,length(datn)-punkt+1);
        datn    :=concat(datn,'       '):
        datn[0] :=chr(8);
        ext     :=dateiname;
        delete(ext,1,punkt);
        ext     :=concat('.',ext,'      ');
        ext[0]  :=chr(4)
      end
    else
     begin
      (* Dateiname linksbündig *)
      datn   :=concat(dateiname,'            ');
      datn[0]:=chr(8):
     end;
      jahr   :=shr(datum,9); (* Datum und Uhrzeit *) 
      monat  :=shr(datum-shl(jahr,9),5); (* auswerten *)
      tag    :=datum-shl(monat,5)-shl(jahr,9);
      jahr   :=jahr+80;
      stunden:=shr(zeit,11): 
      minuten:=shr((zeit-shl(stunden,11)),5): 
      writev(date,tag:2,'-',monat:2,'-',jahr:2); 
      if minuten>9 then 
        writev(time,stunden:2,':',minuten:2)
        (* Stunden, Minuten *) 
      else
        writev(time, stunden:2,':0',minuten:1);
      lok_groesse   :=lok_groesse*groesse;
      i             :=i+1;
      writev(dat_str[i],pre,                (* Vortext *)
                        datn,               (* Dateiname *)
                        ext,'   ',          (* Extension *)
                        groesse:7,'   ',    (* Größe *)
                        date:8,'  ',        (* Datum *)
                        time:5)             (* Uhrzeit *)
     end
   end;
  next_fi1e:=fsnext (* Und weiter ... *) 
 until next_fi1e<0;
glob_ord:=glob_ord*anz; (* Werte erhöhen *) 
glob_dat:=glob_dat+dat_anz; 
dat_size;=dat_size+lok_groesse; 
if sortmod in ['N','E','G','D'] then 
 begin
    sortiere(dat_str,anz+dat_anz); (* Sortieren *) 
    sortiere_ord(neue_dat,anz) 
 end;
for i:=1 to anz+dat_anz do          (* Ausgabe *)
 writeln(dat,dat_str[i]);
if ausgform='E' then                (* Zusatzausgabe *)
 begin
    writeln(dat);
    writeln(dat,'Ordner : ',anz); 
    writeln(dat,'Dateien: ',dat_anz); 
    writeln(dat,'Bytes  : ',lok_groesse) 
 end
end; { End of INHALT }

(* * * * Dateinamen suchen * * * *) 
procedure suchen (such_str : string;
                  var global_ord,global_dat
                            : short_integer; 
                  var global_gr : long_integer);

 var noch_ordner : ordn_array; 
     i,anzneu    : short_integer; 
     search_path : cstring;

 begin { Begin of SUCHEN }
  if such_str<>such then 
   writeln(dat);
  if ausgform<>'L' then (* bei 'Nichtlabel' *)
   writeln(dat,'----- ',laufwerk,':',such_str,' -----'); (* Titel (bzw. Pfad) ausgeben *)
  ptocstr(concat(laufwerk,':',such_str),search_path); 
  inhalt(search_path,noch_ordner,anzneu, global_ord,global_dat,global_gr); (* Inhalt ausgeben *)
  such_str[0]:=chr(ord(such_str[0])-laenge_such);
  (* Die Rekursion läßt grüßen!! *) 
  if ausgform<>'L' then (* nur, falls keine Labelausgabe *)
   for i:=1 to anzneu do
    suchen(concat(such_str,noch_ordner[i],such), global_ord,global_dat,global_gr)
    (* weitersuchen *) 
  end; { End of SUCHEN }

begin { Begin of AUSGABE_INHALT } 
 big_letter(ausgform); (* Umsetzung auf große *) 
 big_letter(sortmod);  (* Buchstaben *) 
 big_letter(laufwerk); 
 rewrite(dat,ausgdat);
 such:='\*.*'; (* Suchmaske für alle Dateien *)
 (* Bei Veränderung der Suchmaske werden natürlich auch nur noch die Ordner *)
 (* nach dieser Maske gesucht. Somit fallen auch Subdirectories weg!!! *) 
 laenge_such:=length(such)-1;   (* Länge der Suchmaske *) 
 titel;                         (* Titel *)
 glob_ord_anz:=0;               (* Globale Wert auf 0 setzen *)
 glob_dat_anz:=0: 
 glob_dat_gr :=0;
 suchen(such,                  (* Suche auf oberster Ebene *)
        glob_ord_anz,          (* beginnen. *)
        glob_dat_anz, 
        glob_dat_gr);
 speicherplatz(frei,ins); (* Speicherplatz ermitteln *) 
 case ausgform of
   'E' : begin                 (* Schlußausgabe 'erweitert' *)
          writeln(dat);
          writeln(dat,'Ordner insgesamt  : ',
                                glob_ord_anz); 
          writeln(dat,'Dateien insgesamt : ', 
                                glob_dat_anz); 
          writeln(dat, Datei-Bytes insgesamt : ', 
                                glob_dat_gr);
          writeln(dat,'freier Speicherplatz : ', 
                                frei,' Bytes'): 
          writeln(dat,'belegter Speicherplatz : ',
                                ins-frei,' Bytes'); 
          writelnldat,'Speicherplatz insgesamt: ',
                                ins,'Bytes')
         end;
   'L' : begin (* Schlußausgabe 'Label' *) 
          writeln(dat);
          writeln(dat,'Objekte: ',glob_ord_anz+
                                  glob_dat_anz,
                    ', davon ',glob_ord_anz,’ Ordner'); 
          writeln(dat,'Speicherplatz: ',ins div 1024, 
                    'kB',
                    ', davon belegt ',(ins-frei) div 1024,' kB')
         end
   end;
 close(dat)
end; { End of AUSGABE.INHALT }

(* * * * * * * Ende der Include-Routine * * * * * * *)

  
  
  
  
  
(******************************************************)
(* Demoprogramm zur Benutzung des Include-Files       *)
(* DISKINHALT       Version 1.80                      *)
(* -------------------------------------------------- *)
(* Entwickelt mit ST Pascal Plus 2.02 von CCD.        *)
(* Autor; Dietmar Rabich, Döuelingsweg 2, 4408 Dülmen *) 
(* Datum ; 2. Januar 1988                             *)
(* Letztes Editierdatum; 18. Januar 1988              *)
(******************************************************)

program DiskInhalt;

var laufwerk,               (* Laufwerkkennung          *)
    ausgabeform,            (* Form der Ausgabe         *)
    sortiermodus : char;    (* Sortiermodus             *)
    cmd_string,             (* String für Commandline   *)
    ausgabedatei : string;  (* Name der Ausgabedatei    *)

{$1 DISKINH.INC }

(* * * * * * Hauptprogramm * * * * * *) 
begin { Begin of DISKINHALT } 
 writeln('*** Disk-Inhalt / Uersion 1.00 ***'); 
 writeln(' (c) Jan. 1988 by Dietmar Rabich.'); 
 writeln('  Entw. mit ST Pascal Plus 2.02.'); 
 writeln;
 if cmd_args>=2 then        (* Command-Line ?           *)
   begin
    cmd_getarg(1,cmd_string); (* Laufwerkkennung lesen  *) 
    laufwerk:=cmd_string[1];
    (* Achtung!!! Existenz des Laufwerkes wird nicht geprüft! *)
    cmd_getarg(2,ausgabedatei); (* Ausgabedateinamen lesen *)
    if cmd_args>=3 then 
     begin
      cmd_getarg(3,cmd_string); (* Sortiermodus bestimmen     *)
      sortiermodus:=cmd_string[1]; 
     end;
    if cmd_args=4 then 
     begin
      cmd_getarg(4,cmd_string); (* Ausgabeform bestimmen    *)
      ausgabeform:=cmd_string[1]; 
     end;
    (* Ausgabe der übermittelten Ausgabewünsche             *)
    writeln('Laufwerk    : ',laufwerk); 
    writelnl'Ausgabedatei: ',ausgabedatei); 
    write('Sortieren : '); 
    case sortiermodus of
      'N' : writeln('Dateinamen');
      'E' : writeln('Extension');
      'G' : writeln('Größe');
      'D' : writeln('Datum'); 
      otherwise : writeln(' - ') 
     end;
    write('Ausgabeform : '); 
    case ausgabeform of
      'E' : writeln('erweitert');
      'L' : writeln('Label'); 
      otherwise : writelnl'normal') 
     end 
   end 
  else 
   begin
    write('Laufwerk (A..Z): '); (* Laufwerk eingeben *) 
    repeat
     read(laufwerk)
    until laufwerk in ['A'..'Z']+['a'..'z'];
    (* Achtung!!! Existenz des Laufwerkes wird nicht geprüft! *)
    writeln;
    write('Ausgabedatei (mit Pfad): '); (* Ausgabedatei eingeben *)
    readln(ausgabedatei):
    write('Sortiermodus (N=Dateiname,', (* Sortiermodus eingeben *) 
        'E=Extension, G=Größe, D=Oatum,X=nicht); ');
    repeat
     read(sortiermodus)
    until sortiermodus in ['n','e','g','d','x','N','E','G','D','X']; 
    writeln;
    write('Ausgabeform (E=erweitert, L=Label, X=normal): '): 
    repeat                  (* Ausgabeform eingeben *)
     read(ausgabeform) 
    until ausgabeform in ['e','l','x','E','L','X'];
    writeln 
   end;
 ausgabe_diskinhalt(ausgabeform,sortiermodus,laufwerk,ausgabedatei): 
 end. { End of DISKINHALT }

Dietmar Rabich
Aus: ST-Computer 06 / 1988, Seite 119

Links

Copyright-Bestimmungen: siehe Über diese Seite