SunYPFindImplP.mesa
Copyright Ó 1989, 1991, 1992, 1993 by Xerox Corporation. All rights reserved.
Demers, July 2, 1990 4:41 pm PDT
Carl Hauser, November 28, 1988 4:51:19 pm PST
Willie-Sue, March 15, 1989 4:41:49 pm PST
Schilit, July 2, 1990 3:03 pm PDT
Willie-s, September 27, 1991 6:55 pm PDT
Chauser, January 3, 1992 11:04 am PST
Christian Jacobi, March 31, 1993 3:15 pm PST
DIRECTORY
Arpa,
ArpaUDP,
Basics,
Convert,
CStrings,
EnvironmentVariables,
Rope,
SunPMap,
SunPMapClient,
SunRPC,
SunRPCOnUDP,
SunRPCAuth,
SunYP,
SunYPBind,
SunYPBindClient,
SunYPClient,
SunYPFind,
UnixSysCalls,
UXStrings
;
SunYPFindImplP: CEDAR MONITOR
LOCKS lock USING lock: Lock
IMPORTS Basics, Convert, EnvironmentVariables, Rope, SunPMapClient, SunRPC, SunRPCOnUDP, SunRPCAuth, SunYPBindClient, SunYPClient, UnixSysCalls, UXStrings
EXPORTS SunYPFind
~ {
Types
Address: TYPE ~ Arpa.Address;
nullAddress: Address ~ Arpa.nullAddress;
Port: TYPE ~ ArpaUDP.Port;
nullPort: Port ~ ArpaUDP.nullPort;
ROPE: TYPE ~ Rope.ROPE;
Parameters
pMapPort: ArpaUDP.Port ¬ Basics.HFromCard16[Basics.LowHalf[SunPMap.udpPort]];
defaultRemoteAddressForYPBind: Address ¬ nullAddress; -- nullAddress => ME
maxDomainNameLength: CARD ¬ 255;
Locks
Lock: TYPE ~ REF LockObject;
LockObject: TYPE ~ MONITORED RECORD [];
Error
Error: PUBLIC ERROR [code: ATOM] ~ CODE;
Default Domain
defaultDomainName: ROPE ¬ NIL;
defaultDomainNameLock: Lock ~ NEW[LockObject];
GetDefaultDomain: PUBLIC PROC RETURNS [domainName: ROPE ¬ NIL] ~ {
GetDefaultDomainInner: ENTRY PROC [lock: Lock ¬ defaultDomainNameLock] ~ {
domainString: CStrings.CString ¬ UXStrings.CreateSpace[maxDomainNameLength+1];
domainName ¬ defaultDomainName;
IF Rope.IsEmpty[domainName] THEN TRUSTED {
IF UnixSysCalls.GetDomainName[domainString, maxDomainNameLength+1]#success THEN ERROR Error[$programmingError];
domainName ¬ defaultDomainName ¬ UXStrings.ToRope[domainString];
};
};
GetDefaultDomainInner[];
IF Rope.IsEmpty[domainName] THEN ERROR Error[$noDefaultDomain];
};
SetDefaultDomain: PUBLIC PROC [domainName: ROPE] ~ {
SetDefaultDomainInner: ENTRY PROC [lock: Lock ¬ defaultDomainNameLock] ~ {
defaultDomainName ¬ domainName;
};
SetDefaultDomainInner[];
};
Get YP Port on Server
LookupYPPort: PROC [address: Address, domain: ROPE] RETURNS [port: Port] ~ {
h: SunRPC.Handle ¬ NIL;
c: SunRPCAuth.Conversation ¬ NIL;
errorCode: ATOM ¬ NIL;
portNumber: CARD;
{
ENABLE {
SunRPC.Error, SunRPCAuth.Error => { errorCode ¬ code; CONTINUE };
};
h ¬ SunRPCOnUDP.Create[remoteAddress~address, remotePort~pMapPort];
c ¬ SunRPCAuth.Initiate[];
portNumber ¬ SunPMapClient.GetPort[h, c, SunYP.program, SunYP.programVersion, SunPMap.ipProtocolUDP];
IF portNumber = 0
THEN {
errorCode ¬ $noYP;
}
ELSE {
h ¬ SunRPCOnUDP.SetRemote[h, address, Basics.HFromCard16[Basics.LowHalf[portNumber]]];
IF NOT SunYPClient.Domain[h, c, domain] THEN errorCode ¬ $domainNotFound;
};
};
IF h # NIL THEN SunRPC.Destroy[h]; h ¬ NIL;
IF c # NIL THEN SunRPCAuth.Terminate[c]; c ¬ NIL;
IF errorCode # NIL THEN ERROR Error[errorCode];
port ¬ Basics.HFromCard16[Basics.LowHalf[portNumber]];
};
YPBind Client
GetServerAddressAndPortUsingYPBind: PROC [domainName: ROPE]
RETURNS [address: Address, port: Port] ~ {
h: SunRPC.Handle ¬ NIL;
c: SunRPCAuth.Conversation ¬ NIL;
errorCode: ATOM ¬ NIL;
ypBindPortNumber: CARD;
ypBindRemoteAddress: Address;
ypBindRemotePort: Port;
IF Rope.IsEmpty[domainName] THEN ERROR; -- can't happen
{
ENABLE {
SunRPC.Error => { errorCode ¬ code; GOTO Cant };
SunRPCAuth.Error => { errorCode ¬ code; GOTO Cant };
};
h ¬ SunRPCOnUDP.Create[defaultRemoteAddressForYPBind, pMapPort];
[ypBindRemoteAddress, ypBindRemotePort] ¬ SunRPCOnUDP.GetRemote[h];
c ¬ SunRPCAuth.Initiate[];
ypBindPortNumber ¬ SunPMapClient.GetPort[h, c, SunYPBind.program, SunYPBind.programVersion, SunPMap.ipProtocolUDP];
IF ypBindPortNumber = 0 THEN { errorCode ¬ $noYPBind; GOTO Cant };
ypBindRemotePort ¬ Basics.HFromCard16[Basics.LowHalf[ypBindPortNumber]];
h ¬ SunRPCOnUDP.SetRemote[h, ypBindRemoteAddress, ypBindRemotePort];
{
response: SunYPBind.ResponseBinding ~ SunYPBindClient.Domain[h, c, domainName];
WITH response SELECT FROM
successResp: success SunYPBind.ResponseBinding => {
address ¬ successResp.binding.address;
port ¬ Basics.HFromCard16[CARD16[successResp.binding.port]];
};
failureResp: failure SunYPBind.ResponseBinding => {
errorCode ¬ (SELECT failureResp.errorCode FROM
internalError => $failureYPBind,
noServer => $noYP,
resourceError => $resourceYPBind,
ENDCASE => $protocolYPBind);
};
ENDCASE => {
errorCode ¬ $protocolYPBind;
}
};
IF errorCode # NIL THEN GOTO Cant;
EXITS
Cant => NULL;
};
IF h # NIL THEN SunRPC.Destroy[h]; h ¬ NIL;
IF c # NIL THEN SunRPCAuth.Terminate[c]; c ¬ NIL;
IF errorCode # NIL THEN ERROR Error[errorCode];
};
Server Location
GetServerAddressAndPortForDomain: PUBLIC PROC [domainName: ROPE, addressHint: Address] RETURNS [address: Address, port: Port ¬ nullPort] ~ {
errorCode: ATOM;
Determine domain ...
IF Rope.IsEmpty[domainName] THEN domainName ¬ GetDefaultDomain[];
Determine host address and possibly YP port ...
errorCode ¬ $noServerSpecified;
IF (address ¬ addressHint) = nullAddress THEN {
addressRope: Rope.ROPE ¬ EnvironmentVariables.Get[Rope.Concat["XR←YPSERVER←", domainName]];
IF addressRope # NIL THEN address ¬ Convert.ArpaAddressFromRope[addressRope ! Convert.Error => CONTINUE ];
};
IF address = nullAddress THEN {
[address, port] ¬ GetServerAddressAndPortUsingYPBind[domainName
! Error => { errorCode ¬ code; CONTINUE }];
};
IF address = nullAddress THEN ERROR Error[errorCode];
Determine YP port ...
errorCode ¬ $noYP;
IF port = nullPort THEN {
port ¬ LookupYPPort[address, domainName]; -- ! Error[...]
};
IF port = nullPort THEN ERROR Error[errorCode];
};
}.