SystemNamesFromYPImpl.mesa
Copyright Ó 1987, 1989, 1991 by Xerox Corporation. All rights reserved.
Doug Wyatt, January 24, 1987 7:03:35 pm PST
Willie-sue, March 15, 1989 5:09:02 pm PST
JKF December 20, 1988 11:01:09 am PST
Carl Hauser, December 9, 1988 5:41:01 pm PST
DIRECTORY
Arpa,
Convert USING [IntFromRope, Error],
IO USING [int, PutFR],
RefText USING [AppendChar, AppendRope, ObtainScratch, ReleaseScratch, TrustTextAsRope],
Rope USING [Cat, Concat, Flatten, FromRefText, IsEmpty, MapType, MoveType, ROPE],
SunYPAgent USING [Error, First, Handle, Match, Next, ObtainHandle, ReleaseHandle, TextSeq, TokenizeUsingSeparator],
SystemNames USING [Release, ReleaseOption, Server],
SystemVersion USING [release],
ThisMachine USING [Name],
UnixSysCalls USING [GetUID],
UnixTypes USING [UID];
SystemNamesFromYPImpl: CEDAR MONITOR
IMPORTS Convert, IO, RefText, Rope, SystemVersion, SunYPAgent, ThisMachine, UnixSysCalls
EXPORTS SystemNames ~ {
ROPE: TYPE ~ Rope.ROPE;
Release: TYPE ~ SystemNames.Release;
ReleaseOption: TYPE ~ SystemNames.ReleaseOption;
Server: TYPE ~ SystemNames.Server;
ReleaseArray: TYPE ~ ARRAY Release OF ROPE;
releaseNames: REF ReleaseArray ~ NEW[ReleaseArray ¬ ALL[NIL]];
ServerInfo: TYPE ~ RECORD [name, defaultHost: ROPE];
ServerArray: TYPE ~ ARRAY Server OF ServerInfo;
serverInfo: REF ServerArray ~ NEW[ServerArray ¬ ALL[[NIL, NIL]]];
Initialize: PROC ~ {
Version: TYPE ~ RECORD [major, minor: INT];
current: Version ~ [major: SystemVersion.release.major, minor: SystemVersion.release.minor];
previous: Version ~ IF current.minor>0 THEN [major: current.major, minor: current.minor-1]
ELSE [major: 0, minor: 0]; -- must edit this by hand each major release
versions: ARRAY Release OF Version ¬ [current: current, previous: previous];
FOR r: Release IN Release DO
v: Version ~ versions[r];
releaseNames[r] ¬ Rope.Flatten[IO.PutFR["%g.%g", IO.int[v.major], IO.int[v.minor]]];
ENDLOOP;
serverInfo­ ¬ [
Cedar: [name: "Cedar", defaultHost: "Cyan-STP"],
PCedar: [name: "PCedar", defaultHost: "Pixel-STP"],
User: [name: "User", defaultHost: "Ivy-STP"],
Fonts: [name: "Fonts", defaultHost: "Cyan-STP"]
];
};
ReleaseName: PUBLIC PROC [release: Release ¬ current] RETURNS [ROPE] ~ {
RETURN [releaseNames[release]];
};
ServerName: PUBLIC PROC [server: Server] RETURNS [ROPE] ~ {
RETURN [serverInfo[server].name];
};
DefaultHostName: PUBLIC PROC [server: Server] RETURNS [ROPE] ~ {
RETURN [serverInfo[server].defaultHost];
};
passwordMapName: ROPE ¬ "passwd.byname";
namePos: CARDINAL ~ 0;
uidPos: CARDINAL ~ 2;
homeDirPos: CARDINAL ~ 5;
UserName: PUBLIC ENTRY PROC RETURNS [name: ROPE] ~ {
ENABLE UNWIND => NULL;
name ¬ UserNameInternal[];
};
userName: ROPE ¬ NIL;
UserNameInternal: INTERNAL PROC RETURNS [name: ROPE] ~ {
IF userName#NIL THEN RETURN[userName];
{ ENABLE SunYPAgent.Error, Convert.Error => GOTO GiveUp;
h: SunYPAgent.Handle ¬ SunYPAgent.ObtainHandle[];
uid: UnixTypes.UID ¬ UnixSysCalls.GetUID[];
keyBefore: ROPE;
val: REF TEXT;
[keyBefore, val] ¬ SunYPAgent.First[h, passwordMapName];
DO
seq: SunYPAgent.TextSeq;
tuid: UnixTypes.UID;
seq ¬ SunYPAgent.TokenizeUsingSeparator[val, ':];
IF seq.length <= uidPos THEN {
SunYPAgent.ReleaseHandle[h];
GOTO GiveUp;
};
tuid ¬ Convert.IntFromRope[RefText.TrustTextAsRope[seq.refText[uidPos]]];
IF tuid = uid THEN {
SunYPAgent.ReleaseHandle[h];
RETURN[userName ¬ RefText.TrustTextAsRope[seq.refText[namePos]]];
};
[keyBefore, val] ¬ SunYPAgent.Next[h, passwordMapName, keyBefore];
ENDLOOP;
EXITS
GiveUp => RETURN[NIL];
};
};
homeDirectory: ROPE ¬ NIL;
GetHomeDirectory: ENTRY PROC RETURNS [wdir: Rope.ROPE] ~ {
IF homeDirectory#NIL THEN RETURN[homeDirectory];
{
ENABLE {
SunYPAgent.Error, Convert.Error => GOTO GiveUp;
UNWIND => NULL;
};
name: ROPE ¬ UserNameInternal[];
h: SunYPAgent.Handle ¬ SunYPAgent.ObtainHandle[];
val: REF TEXT;
seq: SunYPAgent.TextSeq;
IF name = NIL THEN ERROR; -- couldn't find entry in passwd file
val ¬ SunYPAgent.Match[h, passwordMapName, name];
seq ¬ SunYPAgent.TokenizeUsingSeparator[val, ':];
IF seq.length <= homeDirPos THEN GOTO GiveUp;
homeDirectory ¬ RefText.TrustTextAsRope[seq.refText[homeDirPos]];
SunYPAgent.ReleaseHandle[h];
RETURN[homeDirectory];
EXITS
GiveUp => NULL;
}
};
MachineName: PUBLIC PROC RETURNS [machine: ROPE ¬ NIL] ~ {
machine ¬ ThisMachine.Name[];
IF machine=NIL THEN machine ¬ "AnonymousMachine";
};
ReleaseDir: PUBLIC PROC [dir: ROPE, release: Release] RETURNS [ROPE] ~ {
releaseName: ROPE ~ releaseNames[release];
RETURN[Rope.Flatten[Rope.Concat[dir, releaseName]]];
};
ReleaseSubDir: PUBLIC PROC [subDirs: ROPE, release: Release] RETURNS [ROPE] ~ {
releaseName: ROPE ~ releaseNames[release];
IF Rope.IsEmpty[subDirs] THEN RETURN[releaseName]
ELSE RETURN[Rope.Flatten[Rope.Cat[releaseName, "/", subDirs]]];
};
ConstructDir: PUBLIC PROC [server, dir, subDirs: ROPE, option: ReleaseOption,
release: Release] RETURNS [ROPE] ~ {
SELECT option FROM
releaseDir => dir ¬ ReleaseDir[dir, release];
releaseSubDir => subDirs ¬ ReleaseSubDir[subDirs, release];
releaseOmitted => NULL;
ENDCASE => ERROR;
RETURN[ConstructFName[server: server, dir: dir, subDirs: subDirs]];
};
ConstructFName: PROC [server, dir, subDirs: ROPE ¬ NIL]
RETURNS [fName: ROPE] = {
GetTildeRope: PROC RETURNS [r: Rope.ROPE] = {
ie return something like: "/palain/wyatt/Cedar"
r ¬ GetHomeDirectory[];
IF r = NIL THEN ERROR -- can't happen. presumably the user logged on.
ELSE RETURN[Rope.Cat[r, "/Cedar"]];
};
scratch: REF TEXT ~ RefText.ObtainScratch[120];
text: REF TEXT ¬ scratch;
tilde: Rope.ROPE ¬ GetTildeRope[]; -- eg "/palain/wyatt/Cedar"
text ¬ RefText.AppendRope[text, tilde];
text ¬ RefText.AppendChar[text, '/ ];
IF NOT Rope.IsEmpty[server] THEN {
text ¬ RefText.AppendRope[text, server];
text ¬ RefText.AppendChar[text, '/ ];
};
IF NOT Rope.IsEmpty[dir] THEN {
text ¬ RefText.AppendRope[text, dir];
text ¬ RefText.AppendChar[text, '/ ];
};
IF NOT Rope.IsEmpty[subDirs] THEN {
text ¬ RefText.AppendRope[text, subDirs];
text ¬ RefText.AppendChar[text, '/ ];
};
fName ¬ Rope.FromRefText[text];
RefText.ReleaseScratch[scratch];
};
LocalDir: PUBLIC PROC [subDirs: ROPE, option: ReleaseOption,
release: Release ¬ current, volumeName: ROPE ¬ NIL] RETURNS [ROPE] ~ {
RETURN[ConstructDir[NIL, volumeName, subDirs, option, release]];
};
CedarDir: PUBLIC PROC [subDirs: ROPE,
release: Release, dir: ROPE] RETURNS [ROPE] ~ {
server: ROPE ~ serverInfo[Cedar].name;
IF dir=NIL THEN dir ¬ server;
RETURN[ConstructDir[server, dir, subDirs, $releaseDir, release]];
};
UserDir: PUBLIC PROC [subDirs: ROPE, option: ReleaseOption,
release: Release, userName: ROPE] RETURNS [ROPE] ~ {
server: ROPE ~ serverInfo[User].name;
IF userName=NIL THEN userName ¬ UserName[];
RETURN[ConstructDir[server, userName, subDirs, option, release]];
};
Initialize[];
}.