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 ~ {
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];
}
};
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[];
}.