SunYPOpsImpl.mesa
Demers, September 9, 1987 0:02:40 am PDT
DIRECTORY
Arpa USING [Address],
Basics USING [HFromCard16],
Convert USING [CardFromRope],
RefText USING [ObtainScratch, ReleaseScratch],
Rope USING [FromRefText, Index, ROPE, Substr, ToRefText],
SunPMap USING [ipProtocolUDP, udpPort],
SunPMapClient USING [GetPort],
SunRPC USING [Create, Destroy, Error, Handle, SetRemote],
SunRPCAuth USING [Conversation, Initiate, Terminate],
SunYP USING [program, programVersion, ResponseVal],
SunYPClient USING [Match],
SunYPOps USING [],
UserCredentials USING [Get]
;
SunYPOpsImpl: CEDAR MONITOR
IMPORTS Basics, Convert, RefText, Rope, SunPMapClient, SunRPC, SunRPCAuth, SunYPClient, UserCredentials
EXPORTS SunYPOps
~ {
Types
ROPE: TYPE ~ Rope.ROPE;
RopeSeq: TYPE ~ REF RopeSeqObject;
RopeSeqObject: TYPE ~ RECORD [
length: CARDINAL,
rope: SEQUENCE maxLength: CARDINAL OF ROPE
];
uidPosInPasswdLine: CARDINAL ← 2;
gidPosInPasswdLine: CARDINAL ← 3;
domainName: ROPE ← "SCL";
mapName: ROPE ← "passwd";
Procedures
ypServerAddress: Arpa.Address ← [13, 1, 100, 175];
pMapServerPort: CARD ~ SunPMap.udpPort;
cachedYPServerPort: CARD ← 0;
GetCachedYPServerPort: ENTRY PROC RETURNS [CARD] ~ {
RETURN [cachedYPServerPort] };
SetCachedYPServerPort: ENTRY PROC [port: CARD] ~ {
cachedYPServerPort ← port };
OpenConnectionToYPServer: PROC [domainName: ROPE]
RETURNS [h: SunRPC.Handle, c: SunRPCAuth.Conversation] ~ {
port: CARD;
h ← SunRPC.Create[];
c ← SunRPCAuth.Initiate[];
IF (port ← GetCachedYPServerPort[]) # 0 THEN {
h ← SunRPC.SetRemote[h, ypServerAddress, Basics.HFromCard16[port]];
RETURN;
};
h ← SunRPC.SetRemote[h, ypServerAddress, Basics.HFromCard16[pMapServerPort]];
port ← SunPMapClient.GetPort[h, c, SunYP.program, SunYP.programVersion, SunPMap.ipProtocolUDP ! SunRPC.Error => { port ← 0; CONTINUE }];
IF port # 0 THEN {
SetCachedYPServerPort[port];
h ← SunRPC.SetRemote[h, ypServerAddress, Basics.HFromCard16[port]];
RETURN;
};
SunRPC.Destroy[h]; h ← NIL;
SunRPCAuth.Terminate[c]; c ← NIL;
};
cacheOK: BOOLFALSE;
cachedUid: CARDCARD.LAST;
cachedGid: CARDCARD.LAST;
CheckUIDCache: ENTRY PROC [name: ROPE] RETURNS [ok: BOOL, uid, gid: CARD] ~ {
ENABLE UNWIND => NULL;
RETURN [cacheOK, cachedUid, cachedGid];
};
SetUIDCache: ENTRY PROC [name: ROPE, uid, gid: CARD] ~ {
ENABLE UNWIND => NULL;
cachedUid ← uid;
cachedGid ← gid;
cacheOK ← TRUE;
};
MyUID: PUBLIC PROC RETURNS [ok: BOOL, uid, gid: CARD] ~ {
h: SunRPC.Handle;
c: SunRPCAuth.Conversation;
myName: ROPE ← UserCredentials.Get[].name;
myName ← Rope.Substr[myName, 0, Rope.Index[myName, 0, "."]];
[ok, uid, gid] ← CheckUIDCache[myName];
IF ok THEN RETURN;
[h, c] ← OpenConnectionToYPServer[domainName];
IF h = NIL THEN RETURN [FALSE, CARD.LAST, CARD.LAST];
{ resp: SunYP.ResponseVal ~ SunYPClient.Match[h, c, [domainName, mapName, Rope.ToRefText[myName]] ];
SELECT resp.status FROM
true => {
seq: RopeSeq ~ ParseRefText[resp.val];
uid ← Convert.CardFromRope[seq.rope[uidPosInPasswdLine]];
gid ← Convert.CardFromRope[seq.rope[gidPosInPasswdLine]];
ok ← TRUE;
SetUIDCache[myName, uid, gid];
};
ENDCASE => {
uid ← gid ← CARD.LAST;
ok ← FALSE;
};
};
SunRPC.Destroy[h];
SunRPCAuth.Terminate[c];
};
ParseRefText: PROC [r: REF TEXT] RETURNS [seq: RopeSeq] ~ {
i, iTo: CARDINAL;
scratch: REF TEXT ← RefText.ObtainScratch[r.length];
seq ← NEW[RopeSeqObject[20]];
seq.length ← 0;
i ← 0;
DO
IF i >= r.length THEN EXIT;
iTo ← 0;
DO
IF i >= r.length THEN EXIT;
IF r[i] = ': THEN EXIT;
scratch[iTo] ← r[i];
i ← i + 1;
iTo ← iTo + 1;
ENDLOOP;
scratch.length ← iTo;
IF seq.length >= seq.maxLength THEN ERROR;
seq.rope[seq.length] ← Rope.FromRefText[scratch];
seq.length ← seq.length + 1;
i ← i + 1;
ENDLOOP;
RefText.ReleaseScratch[scratch];
};
}...