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