SunYPBindClientStub.mesa
Copyright Ó 1989, 1991, 1992 by Xerox Corporation. All rights reserved.
Demers, March 11, 1993 12:04 pm PST
Willie-Sue, March 15, 1989 2:34:38 pm PST
Chauser, March 10, 1993 8:53 am PST
DIRECTORY
Arpa USING [Address, nullAddress],
Rope USING [Equal, ROPE],
RuntimeError USING [BoundsFault],
SunRPC USING [Error, GetAlign, GetCard16, GetCard32, GetF, GetRope, Handle, PutAlign, PutCard16, PutF, PutRope, ReleaseReply, SendCallAndReceiveReply, StartCall],
SunRPCAuth USING [Conversation],
SunYP USING [programVersion],
SunYPBind USING [--Binding,-- domain, DomainProc, ErrorCode, null, NullProc, program, programVersion, RequestDomainBinding, --ResponseBinding,-- ResponseCode, setdom, SetdomProc],
SunYPBindClient USING []
;
SunYPBindClientStub: CEDAR PROGRAM
IMPORTS Rope, RuntimeError, SunRPC
EXPORTS SunYPBindClient
~ {
Types
Handle: TYPE ~ SunRPC.Handle;
Conversation: TYPE ~ SunRPCAuth.Conversation;
Parameters
fastTimeout: CARD ¬ 500;
mediumTimeout: CARD ¬ 1000;
defaultRetries: CARD ¬ 10;
usefulVersions: TYPE ~ [SunYPBind.programVersion..SunYPBind.programVersion+1];
Procedures
Null: PUBLIC SunYPBind.NullProc -- [h: Handle, c: Conversation] -- ~ {
SunRPC.StartCall[h, c, SunYPBind.program, SunYPBind.programVersion, SunYPBind.null];
[] ¬ SunRPC.SendCallAndReceiveReply[h, fastTimeout, defaultRetries];
SunRPC.ReleaseReply[h];
};
This client stub has been modified to use either version 2 or 3 of the YPBind protocol. This is not beautiful, but it's the simplest way to get up under Solaris 2.x ...
The types that come back in a successful YPBind V3 response ...
struct netconfig from <sys/netconfig.h>
NetConfig3: TYPE ~ RECORD [
netID: Rope.ROPE,
semanticsCode: CARD32,
flag: CARD32,
protocolFamilyName: Rope.ROPE,
protocolName: Rope.ROPE,
deviceName: Rope.ROPE,
nLookups: CARD32,
lookups: LIST OF Rope.ROPE
unused: ARRAY[0..7] OF CARD32;
];
struct netbuf from <sys/tiuser.h>
SvcAddr3: TYPE ~ RECORD [
maxLen: CARD32,
len: CARD32,
gok: CARD16,
port: CARD16,
host: Arpa.Address
];
struct ypbind𡤋inding from yp𡤋.h (o where, o where is the little .x file?)
Binding3: TYPE ~ RECORD [
netConfigs: REF NetConfig3,
svcAddr: REF SvcAddr3,
svcName: Rope.ROPE,
hiVersion: CARD32,
loVersion: CARD32
];
ParseSuccessResponse: PROC[h: Handle, version: CARD]
RETURNS [gotIt: BOOL, address: Arpa.Address, port: CARD32] ~ {
IF version < 3 THEN {
Arpa.Address is known equivalent to FWORD here ...
address ¬ LOOPHOLE[SunRPC.GetF[h]];
The following should be SunRPC.GetCard32[h], but this is what works ...
port ¬ SunRPC.GetCard16[h];
SunRPC.GetAlign[h];
gotIt ← TRUE;
RETURN;
};
IF version = 3 THEN {
b: Binding3;
nc: NetConfig3;
sa: SvcAddr3;
tag: CARD32;
gotIt ← TRUE; address ← Arpa.nullAddress; port ← 0;
tag ← SunRPC.GetCard32[h]; -- is there a Binding?
gotIt ← gotIt AND (tag # 0); -- mandatory
IF tag # 0 THEN {
tag ← SunRPC.GetCard32[h]; -- is there a NetConfig?
IF tag # 0 THEN {
nc.netID ← SunRPC.GetRope[h];
nc.semanticsCode ← SunRPC.GetCard32[h];
nc.flag ← SunRPC.GetCard32[h];
nc.protocolFamilyName ← SunRPC.GetRope[h];
nc.protocolName ← SunRPC.GetRope[h];
nc.deviceName ← SunRPC.GetRope[h];
nc.nLookups ← SunRPC.GetCard32[h];
THROUGH [1 .. nc.nLookups] DO
nc.lookups ← CONS[SunRPC.GetRope[h], nc.lookups];
ENDLOOP;
THROUGH [0 .. 7] DO
[] ← SunRPC.GetCard32[h];
ENDLOOP;
gotIt ← gotIt AND Rope.Equal[nc.protocolName, "udp", FALSE];
};
tag ← SunRPC.GetCard32[h];
gotIt ← gotIt AND (tag # 0); -- mandatory
IF tag # 0 THEN {
resid: INT;
sa.maxLen ← SunRPC.GetCard32[h];
sa.len ← SunRPC.GetCard32[h];
sa.gok ← SunRPC.GetCard16[h];
sa.port ← SunRPC.GetCard16[h];
sa.host ← LOOPHOLE[SunRPC.GetCard32[h]];
resid ← sa.len - 8;
WHILE resid >= 4 DO
[] ← SunRPC.GetCard32[h]; resid ← resid - 4;
ENDLOOP;
SunRPC.GetAlign[h];
port ← sa.port;
address ← sa.host;
};
b.svcName ← SunRPC.GetRope[h];
b.hiVersion ← SunRPC.GetCard32[h];
b.loVersion ← SunRPC.GetCard32[h];
gotIt ← gotIt AND (b.hiVersion >= SunYP.programVersion) AND (b.loVersion <= SunYP.programVersion);
};
RETURN; -- [gotIt, address, port]
};
ERROR; -- unimplemented version, can't happen
};
Domain: PUBLIC SunYPBind.DomainProc -- [h: Handle, c: Conversation, domainName: DomainName] RETURNS [resp: ResponseBinding] -- ~ {
ENABLE RuntimeError.BoundsFault => ERROR SunRPC.Error[$protocolError];
responseCode: SunYPBind.ResponseCode;
FOR version: CARD IN usefulVersions DO
ENABLE SunRPC.Error => IF code=$wrongProgramVersion THEN LOOP ELSE REJECT;
SunRPC.StartCall[h, c, SunYPBind.program, version, SunYPBind.domain];
SunRPC.PutRope[h, domainName];
[] ¬ SunRPC.SendCallAndReceiveReply[h, mediumTimeout, defaultRetries];
responseCode ¬ VAL[CARDINAL[SunRPC.GetCard32[h]]];
SELECT responseCode FROM
success => {
gotIt: BOOL;
address: Arpa.Address;
port: CARD32;
[gotIt, address, port] ← ParseSuccessResponse[h, version];
SunRPC.ReleaseReply[h];
IF gotIt
THEN RETURN [ [success[[address, port]]] ]
ELSE RETURN [ [failure[noServer]] ];
};
failure => {
errorCode: SunYPBind.ErrorCode;
errorCode ¬ VAL[CARDINAL[SunRPC.GetCard32[h]]];
SunRPC.ReleaseReply[h];
RETURN [ [failure[errorCode]] ];
};
ENDCASE => ERROR;
ENDLOOP;
ERROR SunRPC.Error[$wrongProgramVersion];
};
Setdom: PUBLIC SunYPBind.SetdomProc -- [h: Handle, c: Conversation, req: RequestDomainBinding] -- ~ {
FOR version: CARD IN usefulVersions DO
ENABLE SunRPC.Error => IF code=$wrongProgramVersion THEN LOOP ELSE REJECT;
SunRPC.StartCall[h, c, SunYPBind.program, SunYPBind.programVersion, SunYPBind.setdom];
PutRequestDomainBinding ...
SunRPC.PutRope[h, req.domainName];
Arpa.Address is known equivalent to FWORD here ...
SunRPC.PutF[h, LOOPHOLE[req.binding.address]];
The following should be SunRPC.PutCard32[req.binding.port], but this is what works ...
SunRPC.PutCard16[h, CARD16[req.binding.port]];
SunRPC.PutAlign[h];
[] ¬ SunRPC.SendCallAndReceiveReply[h, fastTimeout, defaultRetries];
SunRPC.ReleaseReply[h];
RETURN;
ENDLOOP;
ERROR SunRPC.Error[$wrongProgramVersion];
};
}...