<<>> <> <> <> <> <> <> <> <> <> DIRECTORY RefText USING [New, ObtainScratch, ReleaseScratch, TrustTextRopeAsText], Rope USING [FromRefText, Flatten, ROPE], SunRPC, SunRPCAuth USING [Conversation, Flavor, GetCredentialsAndNextVerifier, maxValueBytes, nullFlavor], SunRPCNumbers USING [], SunRPCType USING [AcceptStat, MsgType, ReplyStat, rpcVersion] ; SunRPCImpl: CEDAR PROGRAM IMPORTS RefText, Rope, SunRPC, SunRPCAuth EXPORTS SunRPC, SunRPCNumbers ~ { OPEN RPCT: SunRPCType; <> ROPE: TYPE ~ Rope.ROPE; Handle: TYPE ~ SunRPC.Handle; Conversation: TYPE ~ SunRPCAuth.Conversation; AuthFlavor: TYPE ~ SunRPCAuth.Flavor; nullFlavor: AuthFlavor ~ SunRPCAuth.nullFlavor; AuthValue: TYPE ~ REF TEXT; Error: PUBLIC ERROR [code: ATOM] ~ CODE; <> maxRefTextLength: CARDINAL ¬ 8*1024; maxAuthBytes: CARDINAL ~ SunRPCAuth.maxValueBytes; <> GetFlavor: PUBLIC PROC [h: Handle] RETURNS [flavor: ATOM] ~ { RETURN [ h.flavor ]; }; <<>> StartCall: PUBLIC PROC [h: Handle, c: Conversation, pgm, version, proc: CARD] ~ { cFlavor, vFlavor: AuthFlavor; credentials, verifier: AuthValue; h.procs.prepareForMessage[h]; h.xid ¬ h.xid + 1; h.authData ¬ c; <> SunRPC.PutCard32[h, h.xid]; -- xid SunRPC.PutCard32[h, ORD[RPCT.MsgType.call]]; -- msgType SunRPC.PutCard32[h, RPCT.rpcVersion]; -- rpcvers SunRPC.PutCard32[h, pgm]; -- prog SunRPC.PutCard32[h, version]; -- vers SunRPC.PutCard32[h, proc]; -- proc [cFlavor, credentials, vFlavor, verifier] ¬ SunRPCAuth.GetCredentialsAndNextVerifier[c]; SunRPC.PutCard32[h, cFlavor]; SunRPC.PutCard32[h, credentials.length]; IF credentials.length > 0 THEN SunRPC.PutBlock[h, credentials, 0, credentials.length]; SunRPC.PutCard32[h, vFlavor]; SunRPC.PutCard32[h, verifier.length]; IF verifier.length > 0 THEN SunRPC.PutBlock[h, verifier, 0, verifier.length]; }; <> StartAcceptReply: PUBLIC PROC [h: Handle, acceptStat: CARD32] ~ { <> h.procs.prepareForMessage[h]; SunRPC.PutCard32[h, h.xid]; -- xid SunRPC.PutCard32[h, ORD[RPCT.MsgType.reply]]; -- msgType SunRPC.PutCard32[h, ORD[RPCT.ReplyStat.msgAccepted]]; -- replyStat SunRPC.PutAuth[h, h.authFlavor, NARROW[h.authData]]; -- replyVerifier SunRPC.PutCard32[h, acceptStat]; -- acceptStat }; StartRejectReply: PUBLIC PROC [h: Handle, rejectStat: CARD32] ~ { <> h.procs.prepareForMessage[h]; SunRPC.PutCard32[h, h.xid]; -- xid SunRPC.PutCard32[h, ORD[RPCT.MsgType.reply]]; -- msgType SunRPC.PutCard32[h, ORD[RPCT.ReplyStat.msgDenied]]; -- replyStat SunRPC.PutCard32[h, rejectStat]; -- rejectStat }; StartReply: PUBLIC PROC [h: Handle] ~ { StartAcceptReply[h, ORD[RPCT.AcceptStat.success]]; }; <> SkipBytes: PUBLIC PROC [h: Handle, bytes: CARDINAL] ~ { h.procs.skipBytes[h, bytes]; }; GetRefText: PUBLIC PROC [h: Handle] RETURNS [refText: REF TEXT] ~ { length: CARD ¬ SunRPC.GetCard32[h]; IF length > maxRefTextLength THEN ERROR Error[$outOfBufferSpace]; refText ¬ RefText.New[length]; SunRPC.GetBlock[h, refText, 0, length]; SunRPC.GetAlign[h]; }; GetEphemeralRefText: PUBLIC PROC [h: Handle, oldBuffer: REF TEXT] RETURNS [newBuffer: REF TEXT] ~ { length: CARD ¬ SunRPC.GetCard32[h]; IF length > maxRefTextLength THEN ERROR Error[$outOfBufferSpace]; SELECT TRUE FROM (oldBuffer = NIL) => { newBuffer ¬ RefText.ObtainScratch[length]; }; (oldBuffer.maxLength < length) => { RefText.ReleaseScratch[oldBuffer]; newBuffer ¬ RefText.ObtainScratch[length]; }; ENDCASE => { newBuffer ¬ oldBuffer; }; IF (newBuffer.length ¬ length) > 0 THEN { SunRPC.GetBlock[h, newBuffer, 0, length]; SunRPC.GetAlign[h]; }; }; GetRope: PUBLIC PROC [h: Handle] RETURNS [ROPE] ~ { temp: REF TEXT ¬ GetEphemeralRefText[h, NIL]; result: ROPE ¬ Rope.FromRefText[temp]; RefText.ReleaseScratch[temp]; RETURN [result]; }; GetAuth: PUBLIC PROC [h: Handle] RETURNS [flavor: AuthFlavor, value: AuthValue] ~ { <> flavor ¬ [SunRPC.GetCard32[h]]; value ¬ GetEphemeralRefText[h, NIL]; }; GetBool: PUBLIC PROC [h: Handle] RETURNS [BOOL] ~ { rep: CARD32 ~ SunRPC.GetCard32[h]; RETURN [rep#0] }; GetInt64: PUBLIC PROC [h: Handle] RETURNS [INT64] ~ { <> a: PACKED ARRAY [0..1] OF CARD32; a[0] ¬ SunRPC.GetCard32[h]; a[1] ¬ SunRPC.GetCard32[h]; RETURN [LOOPHOLE[a]]; }; GetCard64: PUBLIC PROC [h: Handle] RETURNS [CARD64] ~ { <> a: PACKED ARRAY [0..1] OF CARD32; a[0] ¬ SunRPC.GetCard32[h]; a[1] ¬ SunRPC.GetCard32[h]; RETURN [LOOPHOLE[a]]; }; GetReal: PUBLIC PROC [h: Handle] RETURNS [REAL] ~ { rep: CARD32 ~ SunRPC.GetCard32[h]; RETURN [LOOPHOLE[rep]] }; oneDRealRep: PACKED ARRAY [0..1] OF CARD32 ~ LOOPHOLE[DREAL[1.0]]; drealHi: [0..1] ~ IF oneDRealRep[1] = 0 THEN 0 ELSE 1; drealLo: [0..1] ~ 1 - drealHi; GetDReal: PUBLIC PROC [h: Handle] RETURNS [DREAL] ~ { a: PACKED ARRAY [0..1] OF CARD32; a[drealHi] ¬ SunRPC.GetCard32[h]; a[drealLo] ¬ SunRPC.GetCard32[h]; RETURN [LOOPHOLE[a]] }; PutRefText: PUBLIC PROC [h: Handle, refText: REF READONLY TEXT] ~ { SunRPC.PutCard32[h, refText.length]; SunRPC.PutBlock[h, refText, 0, refText.length]; SunRPC.PutAlign[h, 0]; }; PutRope: PUBLIC PROC [h: Handle, rope: ROPE] ~ { IF rope = NIL THEN { SunRPC.PutCard32[h, 0]; } ELSE TRUSTED { PutRefText[h, RefText.TrustTextRopeAsText[Rope.Flatten[rope]]]; }; }; PutAuth: PUBLIC PROC [h: Handle, flavor: AuthFlavor, value: AuthValue] ~ { SunRPC.PutCard32[h, flavor]; IF value.length > maxAuthBytes THEN ERROR; SunRPC.PutCard32[h, value.length]; IF value.length > 0 THEN SunRPC.PutBlock[h, value, 0, value.length]; SunRPC.PutAlign[h, 0]; }; PutBool: PUBLIC PROC [h: Handle, bool: BOOL] ~ { SunRPC.PutCard32[h, ORD[bool]]; }; PutInt64: PUBLIC PROC [h: Handle, int64: INT64] ~ { <> a: PACKED ARRAY [0..1] OF CARD32 ¬ LOOPHOLE[int64]; SunRPC.PutCard32[h, a[0]]; SunRPC.PutCard32[h, a[1]]; }; PutCard64: PUBLIC PROC [h: Handle, card64: CARD64] ~ { <> a: PACKED ARRAY [0..1] OF CARD32 ¬ LOOPHOLE[card64]; SunRPC.PutCard32[h, a[0]]; SunRPC.PutCard32[h, a[1]]; }; PutReal: PUBLIC PROC [h: Handle, real: REAL] ~ { SunRPC.PutCard32[h, LOOPHOLE[real]]; }; PutDReal: PUBLIC PROC [h: Handle, dreal: DREAL] ~ { a: PACKED ARRAY [0..1] OF CARD32 ¬ LOOPHOLE[dreal]; SunRPC.PutCard32[h, a[drealHi]]; SunRPC.PutCard32[h, a[drealLo]]; }; }...