
(**********************************************************************

    :Program.    Showlink
    :Contents.   Shows AmigaDos file links
    :Author.     Christoph Teuber
    :Address.    Rheinstr. 65, 5600 Wuppertal 1, West-Germany
    :Copyright.  Freeware
    :Language.   Oberon
    :Translator. Amiga-Oberon-Compiler V 2.12e
    :History.    V1.0, 11.11.1991
    :History.    V1.1, 18.08.1992 (cht)
    :Kickstart   2.04 or higher

**********************************************************************)


MODULE ShowLink;

IMPORT Exec,
       io,
       SYSTEM,
       Dos,
       u : Utility,
       Strings,
       a : Arguments;

TYPE ArgDummy = ARRAY 1 OF LONGINT;

CONST LinkNameLength = 20;

VAR Pfad : Dos.FileLockPtr;
    ok : BOOLEAN;
    vstring : ARRAY 40 OF CHAR;

PROCEDURE ParseArgs (VAR Lock : Dos.FileLockPtr) : BOOLEAN;

VAR rdargs : Dos.RDArgsPtr;
    str : Exec.STRPTR;
    oldLock : Dos.FileLockPtr;

BEGIN

 str := NIL;
 rdargs := Dos.ReadArgs ("Dir", SYSTEM.VAL (ArgDummy, str), NIL);
 IF rdargs = NIL THEN
   RETURN (FALSE)
 ELSE
   IF str = NIL THEN
     Lock := Dos.DupLock(a.oldCurrentDir);
   ELSE
     Lock := Dos.Lock (str^, Dos.sharedLock);
     IF Lock = NIL THEN
       RETURN (FALSE);
     ELSE
       oldLock := Dos.CurrentDir(Lock);
     END;
   END;
 END;
 RETURN (TRUE);

END ParseArgs;


PROCEDURE ReadListe (MyLock : Dos.FileLockPtr);

VAR MyFib : Dos.FileInfoBlockPtr;
    LinkLock : Dos.FileLockPtr;
    NameLink : ARRAY 108 OF CHAR;
    allesInButter, ok, onlyFile : BOOLEAN;
    oldErr : LONGINT;

PROCEDURE Ausgabe (Fib : Dos.FileInfoBlockPtr; MyLock : Dos.FileLockPtr);

VAR Laenge : INTEGER;
    ok : BOOLEAN;
    RealName : ARRAY 108 OF CHAR;


PROCEDURE FollowLink (VAR RealName : ARRAY OF CHAR; Name : ARRAY OF CHAR)
                      : BOOLEAN;

VAR LinkLock : Dos.FileLockPtr;
    dummyName : ARRAY 108 OF CHAR;
    ok : BOOLEAN;


BEGIN

  LinkLock := Dos.Lock(Name, Dos.sharedLock);
  IF LinkLock = NIL THEN
    RETURN (FALSE);
  END;

  ok := Dos.NameFromLock(LinkLock, dummyName, SYSTEM.SIZE(dummyName));
  Dos.UnLock(LinkLock);
  IF ok THEN
    COPY (dummyName, RealName);
    RETURN (TRUE);
  ELSE
    RETURN (FALSE);
  END;

END FollowLink;


BEGIN

 io.WriteString (Fib^.fileName);
 Laenge := Strings.Length (Fib.fileName);
 IF Laenge<LinkNameLength THEN
   REPEAT
    io.WriteString (" ");
    INC(Laenge);
   UNTIL Laenge=LinkNameLength;
 END;

 ok := FollowLink (RealName, Fib^.fileName);
 IF ok THEN
   CASE Fib.dirEntryType OF
     Dos.linkFile : io.WriteString (" Hardlink TO  "); |
     Dos.linkDir  : io.WriteString ("  Dirlink TO  ");
   END;
   io.WriteString (RealName);
   io.WriteLn;
 END;

END Ausgabe;


BEGIN  (* ReadListe() *)

 MyFib := Dos.AllocDosObjectTags (Dos.fib, u.done);
 IF MyFib = NIL THEN
  oldErr := Dos.SetIoErr (Dos.noFreeStore);
  HALT (5);
 END;

 allesInButter := Dos.Examine (MyLock, MyFib^);

 IF allesInButter THEN
   onlyFile := MyFib^.dirEntryType<0;
   REPEAT
     IF ((MyFib.dirEntryType = Dos.linkFile) OR
         (MyFib.dirEntryType = Dos.linkDir))
     THEN
       Ausgabe (MyFib, MyLock);
     END;
     allesInButter := Dos.ExNext(MyLock, MyFib^);
   UNTIL (NOT allesInButter OR onlyFile);
 IF Dos.IoErr() = Dos.noMoreEntries THEN
   oldErr := Dos.SetIoErr (0);
 ELSE
   HALT (5);
 END;
 END;

 IF MyFib#NIL THEN Dos.FreeDosObject (Dos.fib, MyFib) END;

END ReadListe;


BEGIN (* Hauptprogramm *)

 vstring := "$VER: Showlink 1.1 (18.01.1992)";
 IF Exec.exec.softVer>=37 THEN
   IF ParseArgs(Pfad) THEN
     ReadListe (Pfad);
   END;
 ELSE
   io.WriteString("Requires Kickstart 2.04 or higher\n");
 END;

CLOSE

 ok := Dos.PrintFault (Dos.IoErr(), "Showlink");
 IF Pfad#NIL THEN Dos.UnLock(Pfad) END;

END ShowLink.
