UnixFSFromYggNavImpl.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Bob Hagmann July 13, 1988 9:31:58 am PDT
Top level navigational interface for Yggdrasil.
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
Types, variables, and constants
ROPE: TYPE = Rope.ROPE;
Utilities
From dir.h:
typedef struct 𡤍irdesc {
 int dd�
 long dd←loc;
 long dd←size;
 long dd�se;
 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];
};
};
Unix system calls
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"
};
Initialization
randomCharStream ← Random.Create[range: 26];
END.