<> <> <> <> <> 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 ~ { <> Handle: TYPE ~ SunRPC.Handle; Conversation: TYPE ~ SunRPCAuth.Conversation; <> fastTimeout: CARD ¬ 500; mediumTimeout: CARD ¬ 1000; defaultRetries: CARD ¬ 10; usefulVersions: TYPE ~ [SunYPBind.programVersion..SunYPBind.programVersion+1]; <> 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]; }; <> <> <>> 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 <> ]; <>> SvcAddr3: TYPE ~ RECORD [ maxLen: CARD32, len: CARD32, gok: CARD16, port: CARD16, host: Arpa.Address ]; <> 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 { <> address ¬ LOOPHOLE[SunRPC.GetF[h]]; <> 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]; <> SunRPC.PutRope[h, req.domainName]; <> SunRPC.PutF[h, LOOPHOLE[req.binding.address]]; <> SunRPC.PutCard16[h, CARD16[req.binding.port]]; SunRPC.PutAlign[h]; [] ¬ SunRPC.SendCallAndReceiveReply[h, fastTimeout, defaultRetries]; SunRPC.ReleaseReply[h]; RETURN; ENDLOOP; ERROR SunRPC.Error[$wrongProgramVersion]; }; }...