<> <> <> <<>> <<>> <> <<>> DIRECTORY Basics USING [ByteBlt], Random USING [Create, NextInt, RandomStream], RefText USING [AppendChar, AppendRope, New], Rope USING [Equal, Find, FromRefText, Length, ROPE], YggDID USING [DID, ValidateDID], YggDIDPrivate USING [DIDRep], YggEnvironment USING [Outcome, TransID], YggIndex USING [], YggNav USING [ErrorDesc, LinkList], YggRep USING [AccurateGMT, AccurateGMTRep, Attribute, Bits, BitsRep, BytesFromBits, BytesToBits, date, DocType, float, int, lastReservedDocType, rope, shortRope, SetSizeOfBits, TypedPrimitiveElement, uninterpretedBytes, VDoc, VolatizeFromDID], YggTransaction USING [Check, Create, Finish]; UnixFSFromYggNavImpl: CEDAR MONITOR IMPORTS Basics, Random, RefText, Rope, YggDID, YggRep, YggTransaction EXPORTS YggDID, YggNav ~ BEGIN <> ROPE: TYPE = Rope.ROPE; <> <> <> DIR: TYPE ~ PACKED RECORD [ ddFd: INT, ddLoc: INT, ddSize: INT, ddBbase: INT, ddEntno: INT, ddBsize: INT, ddBuf: LONG POINTER TO ARRAY [0..0] OF CHAR ]; direct: TYPE ~ PACKED RECORD [ dFileno: CARD32, dReclen: CARD16, dNamlen: CARD16, dName: LONG POINTER TO ARRAY [0..0] OF CHAR ]; UnixStringFromRope: PROC [rope: ROPE] RETURNS [REF TEXT] ~ { len: INT _ rope.Length[]; rtn: REF TEXT _ RefText.New[len+1]; [] _ RefText.AppendRope[to: rtn, from: rope]; [] _ RefText.AppendChar[to: rtn, from: '\000]; RETURN[rtn]; }; EnumerateSymbolicLinksInDirectory: PROC [directory: ROPE, proc: PROC [localName, symbolicName: ROPE] RETURNS [continue: BOOL _ TRUE]] ~ { dirStream: LONG POINTER TO DIR; cont: BOOL; unixDirName: REF TEXT ~ UnixStringFromRope[directory]; dirStream _ Opendir[LOOPHOLE[unixDirName, CARD]+UNITS[TEXT[0]]]; IF dirStream # NIL THEN { symLinkBuff: REF TEXT _ RefText.New[256]; symLinkResult: REF TEXT _ RefText.New[1024]; resetLen: INT; [] _ RefText.AppendRope[to: symLinkBuff, from: directory]; [] _ RefText.AppendChar[to: symLinkBuff, from: '/]; resetLen _ symLinkBuff.length; DO dirp: LONG POINTER TO direct; cc: INT; symLinkName: ROPE; localName: ROPE; localNameLength: INT; dirp _ Readdir[dirStream]; IF dirp = NIL THEN EXIT; symLinkBuff.length _ resetLen; TRUSTED { localNameLength _ dirp.dNamlen; FOR charNo: INT IN [0..localNameLength] DO [] _ RefText.AppendChar[to: symLinkBuff, from: dirp.dName[charNo]]; ENDLOOP; }; [] _ RefText.AppendChar[to: symLinkBuff, from: '\000]; cc _ Readlink[path: LOOPHOLE[symLinkBuff, CARD] +UNITS[TEXT[0]], buf: LOOPHOLE[symLinkResult, CARD]+UNITS[TEXT[0]], bufsiz: 1023]; IF cc <= 0 THEN LOOP; symLinkResult.length _ cc; symLinkName _ Rope.FromRefText[s: symLinkResult, start: 0, len: cc]; localName _ Rope.FromRefText[s: symLinkBuff, start: 0, len: resetLen + localNameLength]; cont _ proc[localName, symLinkName]; IF ~cont THEN EXIT; ENDLOOP; [] _ Closedir[dirStream]; }; }; <> Symlink: PROC [name1: CARD, name2: CARD] RETURNS [INT] ~ TRUSTED MACHINE CODE { "symlink" }; Opendir: PROC [name: CARD] RETURNS [LONG POINTER TO DIR] ~ TRUSTED MACHINE CODE { "opendir" }; Readdir: PROC [LONG POINTER TO DIR] RETURNS [LONG POINTER TO direct] ~ TRUSTED MACHINE CODE { "readdir" }; Closedir: PROC [LONG POINTER TO DIR] RETURNS [trash: INT] ~ TRUSTED MACHINE CODE { "closedir" }; Readlink: PROC [path: CARD, buf: CARD, bufsiz: INT] RETURNS [cc: INT] ~ TRUSTED MACHINE CODE { "readlink" }; Unlink: PROC [path: CARD] RETURNS [cc: INT] ~ TRUSTED MACHINE CODE { "unlink" }; <> randomCharStream _ Random.Create[range: 26]; END.