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];
Utilities
From dir.h:
typedef struct 𡤍irdesc {
int dd
long dd←loc;
long dd←size;
long ddse;
long dd𡤎ntno;
long dd𡤋size;
char *dd𡤋uf;
} DIR;
struct direct {
u←long d𡤏ileno; /* file number of entry */
u←short d←reclen; /* length of this record */
u←short d←namlen; /* length of string in d←name */
char d←name[MAXNAMLEN + 1]; /* name (up to MAXNAMLEN + 1) */
};
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];
};
};