LoganBerrySunRPCClientStub.Mesa
Copyright Ó 1986, 1992 by Xerox Corporation. All rights reserved.
Doug Terry, September 14, 1989 3:30:52 pm PDT
Adapted from LoganBerryP2205V1ClientImpl.mesa
Willie-s, April 23, 1992 3:07 pm PDT
DIRECTORY
Rope,
SunRPC,
SunRPCAuth,
LoganBerrySunRPC,
LoganBerrySunRPCClient;
LoganBerrySunRPCClientStub: CEDAR PROGRAM
IMPORTS Rope, SunRPC, SunRPCAuth
EXPORTS LoganBerrySunRPCClient ~ {
OPEN LoganBerrySunRPC;
Handle: TYPE ~ SunRPC.Handle;
Conversation: TYPE ~ SunRPCAuth.Conversation;
Errors
Error: PUBLIC ErrorType ~ CODE;
GetErrorProc
GetError: SunRPCGetErrorProc ~ {
ec: ROPE;
explanation: ROPE;
ec ¬ SunRPC.GetRope[h];
IF NOT Rope.IsEmpty[ec] THEN {
explanation ¬ SunRPC.GetRope[h];
ERROR Error[ec, explanation];
};
};
Remote Procedures --
Close: PUBLIC CloseType ~ {
PutArgs: PROC [h: Handle] ~ {
SunRPC.PutCard32[h, conv];
SunRPC.PutCard32[h, db];
};
GetResults: PROC [h: Handle] ~ {
NULL
};
SunRPCCall[h~h, remotePgm~2205, remotePgmVersion~1, remoteProc~8 , putArgs~PutArgs, getResults~GetResults, getError~GetError];
};
Describe: PUBLIC DescribeType ~ {
PutArgs: PROC [h: Handle] ~ {
SunRPC.PutCard32[h, conv];
SunRPC.PutCard32[h, db];
};
GetResults: PROC [h: Handle] ~ {
info.dbName ¬ SunRPC.GetRope[h];
info.logs ¬ UProc1[h];
info.indices ¬ UProc2[h];
};
SunRPCCall[h~h, remotePgm~2205, remotePgmVersion~1, remoteProc~1 , putArgs~PutArgs, getResults~GetResults, getError~GetError];
};
EndGenerate: PUBLIC EndGenerateType ~ {
PutArgs: PROC [h: Handle] ~ {
SunRPC.PutCard32[h, conv];
SunRPC.PutCard32[h, cursor];
};
GetResults: PROC [h: Handle] ~ {
NULL
};
SunRPCCall[h~h, remotePgm~2205, remotePgmVersion~1, remoteProc~5 , putArgs~PutArgs, getResults~GetResults, getError~GetError];
};
NextEntry: PUBLIC NextEntryType ~ {
PutArgs: PROC [h: Handle] ~ {
SunRPC.PutCard32[h, conv];
SunRPC.PutCard32[h, cursor];
SunRPC.PutCard32[h, ORD[dir]];
};
GetResults: PROC [h: Handle] ~ {
entry ¬ UProc3[h];
};
SunRPCCall[h~h, remotePgm~2205, remotePgmVersion~1, remoteProc~4 , putArgs~PutArgs, getResults~GetResults, getError~GetError];
};
DeleteEntry: PUBLIC DeleteEntryType ~ {
PutArgs: PROC [h: Handle] ~ {
SunRPC.PutCard32[h, conv];
SunRPC.PutCard32[h, db];
SunRPC.PutRope[h, key];
SunRPC.PutRope[h, value];
};
GetResults: PROC [h: Handle] ~ {
NULL
};
SunRPCCall[h~h, remotePgm~2205, remotePgmVersion~1, remoteProc~7 , putArgs~PutArgs, getResults~GetResults, getError~GetError];
};
ReadEntry: PUBLIC ReadEntryType ~ {
PutArgs: PROC [h: Handle] ~ {
SunRPC.PutCard32[h, conv];
SunRPC.PutCard32[h, db];
SunRPC.PutRope[h, key];
SunRPC.PutRope[h, value];
};
GetResults: PROC [h: Handle] ~ {
entry ¬ UProc3[h];
others ¬ SunRPCGetBool[h];
};
SunRPCCall[h~h, remotePgm~2205, remotePgmVersion~1, remoteProc~2 , putArgs~PutArgs, getResults~GetResults, getError~GetError];
};
Open: PUBLIC OpenType ~ {
PutArgs: PROC [h: Handle] ~ {
SunRPC.PutCard32[h, conv];
SunRPC.PutRope[h, dbName];
};
GetResults: PROC [h: Handle] ~ {
db ¬ SunRPC.GetCard32[h];
};
SunRPCCall[h~h, remotePgm~2205, remotePgmVersion~1, remoteProc~11 , putArgs~PutArgs, getResults~GetResults, getError~GetError];
};
WriteEntry: PUBLIC WriteEntryType ~ {
PutArgs: PROC [h: Handle] ~ {
SunRPC.PutCard32[h, conv];
SunRPC.PutCard32[h, db];
MProc4[h, entry];
SunRPC.PutCard32[h, log];
SunRPCPutBool[h, replace];
};
GetResults: PROC [h: Handle] ~ {
NULL
};
SunRPCCall[h~h, remotePgm~2205, remotePgmVersion~1, remoteProc~6 , putArgs~PutArgs, getResults~GetResults, getError~GetError];
};
GenerateEntries: PUBLIC GenerateEntriesType ~ {
PutArgs: PROC [h: Handle] ~ {
SunRPC.PutCard32[h, conv];
SunRPC.PutCard32[h, db];
SunRPC.PutRope[h, key];
SunRPC.PutRope[h, start];
SunRPC.PutRope[h, end];
};
GetResults: PROC [h: Handle] ~ {
cursor ¬ SunRPC.GetCard32[h];
};
SunRPCCall[h~h, remotePgm~2205, remotePgmVersion~1, remoteProc~3 , putArgs~PutArgs, getResults~GetResults, getError~GetError];
};
BuildIndices: PUBLIC BuildIndicesType ~ {
PutArgs: PROC [h: Handle] ~ {
SunRPC.PutCard32[h, conv];
SunRPC.PutCard32[h, db];
};
GetResults: PROC [h: Handle] ~ {
NULL
};
SunRPCCall[h~h, remotePgm~2205, remotePgmVersion~1, remoteProc~9 , putArgs~PutArgs, getResults~GetResults, getError~GetError];
};
CompactLogs: PUBLIC CompactLogsType ~ {
PutArgs: PROC [h: Handle] ~ {
SunRPC.PutCard32[h, conv];
SunRPC.PutCard32[h, db];
};
GetResults: PROC [h: Handle] ~ {
NULL
};
SunRPCCall[h~h, remotePgm~2205, remotePgmVersion~1, remoteProc~10 , putArgs~PutArgs, getResults~GetResults, getError~GetError];
};
Null: PUBLIC NullType ~ {
PutArgs: PROC [h: Handle] ~ {
NULL
};
GetResults: PROC [h: Handle] ~ {
NULL
};
SunRPCCall[h~h, remotePgm~2205, remotePgmVersion~1, remoteProc~0 , putArgs~PutArgs, getResults~GetResults, getError~GetError];
};
Unmarshal / Marshal Procs --
SunRPCGetBool: PROC [h: SunRPC.Handle] RETURNS [BOOL] ~ INLINE {
RETURN [SunRPC.GetCard32[h] # 0] };
SunRPCPutBool: PROC [h: SunRPC.Handle, bool: BOOL] ~ INLINE {
SunRPC.PutCard32[h, IF bool THEN 1 ELSE 0] };
UProc2: PROC [h: SunRPC.Handle] RETURNS [res: IndexList] ~ {
{
length7: CARDINAL ~ SunRPC.GetCard32[h];
res ¬ NEW[IndexListObject[length7]];
FOR i6: CARDINAL IN [0..length7) DO
res.body[i6].key ¬ SunRPC.GetRope[h];
res.body[i6].file ¬ SunRPC.GetRope[h];
res.body[i6].order ¬ SunRPC.GetRope[h];
ENDLOOP;
};
};
UProc3: PROC [h: SunRPC.Handle] RETURNS [res: Entry] ~ {
{
length11: CARDINAL ~ SunRPC.GetCard32[h];
res ¬ NEW[EntryObject[length11]];
FOR i10: CARDINAL IN [0..length11) DO
res.body[i10].type ¬ SunRPC.GetRope[h];
res.body[i10].value ¬ SunRPC.GetRope[h];
ENDLOOP;
};
};
UProc1: PROC [h: SunRPC.Handle] RETURNS [res: LogList] ~ {
{
length9: CARDINAL ~ SunRPC.GetCard32[h];
res ¬ NEW[LogListObject[length9]];
FOR i8: CARDINAL IN [0..length9) DO
res.body[i8].id ¬ SunRPC.GetCard32[h];
res.body[i8].file ¬ SunRPC.GetRope[h];
ENDLOOP;
};
};
MProc4: PROC [h: SunRPC.Handle, val: Entry] ~ {
SunRPC.PutCard32[h, val.length];
FOR i5: CARDINAL IN [0..val.length) DO
SunRPC.PutRope[h, val.body[i5].type];
SunRPC.PutRope[h, val.body[i5].value];
ENDLOOP;
};
Placing calls --
This is where this module differs most from the Courier stub from which it is derived. We define a SunRPCCall that looks similar to the CrRPC.Call and hides the differences in calling sequences between the two protocols.

Since SUN RPC doesn't have any error handling mechanism, remote errors are returned as explict error codes. An error code is at the head of all returned results. If the returned error code is NIL, then the regular procedure results follow; otherwise, the error code is followed by the error explanation.
sunPgm: CARD ¬ 390905; -- decimal program number
sunPgmVersion: CARD ¬ 1;
fastTimeout: CARD ¬ 500;
mediumTimeout: CARD ¬ 2000;
defaultRetries: CARD ¬ 5;
noRetries: CARD ¬ 0;
SunRPCPutArgsProc: TYPE ~ PROC [h: Handle];
SunRPCGetResultsProc: TYPE ~ PROC [h: Handle];
SunRPCGetErrorProc: TYPE ~ PROC [h: Handle];
SunRPCCall: PROC [h: SunRPC.Handle, remotePgm, remotePgmVersion, remoteProc: CARD, putArgs: SunRPCPutArgsProc, getResults: SunRPCGetResultsProc, getError: SunRPCGetErrorProc] ~ {
Note: we ignore the passed remotePgm number and version (its the Courier one).
SunRPC.StartCall[h~h, c~SunRPCAuth.Initiate[], pgm~sunPgm, version~sunPgmVersion, proc~remoteProc];
putArgs[h];
[] ¬ SunRPC.SendCallAndReceiveReply[h~h, timeoutMsec~mediumTimeout, retries~defaultRetries];
getError[h];
The following will not be called if getError raises an Error.
getResults[h];
SunRPC.ReleaseReply[h];
};
}...