/* Test123.c -- Compiler still runs out of space. */ /* D. Swinehart, May 18, 1982 2:52 PM */ /* ***** #include ***** */ /* Env.h Useful stuff Last modified by D. Swinehart, May 14, 1982 2:01 pm */ #define true (-1) #define false 0 #define byte char /* Packets are "big-endian", so all of their word-level values have their bytes backwards. A "num" is such a word that is normally fetched and swapped so that we can treat it as a number. A "word" is such a word that is normally just left the way it is, except perhaps by special double-word routines that know how to manipulate it. These are just conventions, which the programmer has to diligently follow. Good luck to all. */ #define num int /* struct num { byte hiByte, loByte; }; Must be swapped to use */ #define word int /* struct word { byte hiByte, loByte; }; Normally left in big-endian form. */ #define swapped1 0400 #define swappedSign 0200 struct ShortSTRING { int length; int maxLength; char text[1]; }; #define lenShortSTRING 2 /* fixed part. */ /* More conventions: struct longInt { int low, high; }; Standard long number. struct longNum { num low, high; }; Standard packetized Mesa long integer -- word-level is right, byte-level wrong. Routines like DoubleDifference, DoubleIncrement work on longInts. Routines like DoubleDiff, DoubleInc work on longNums. We'll have to rename these if we ever want to get them into radix 50. */ /* ****** #include ****** */ /* RPC.h C Public interface to a lightweight RPC runtime Last modified by D. Swinehart, May 14, 1982 2:02 pm */ /* Requires #include */ #define maxRNameLength 64 #define maxShortStringLength 64 #define maxPrincipalLength 64 struct VersionRange { word first; word last; }; struct InterfaceName { int *type; /* e.g., "Lark.Lark" */ int *instance; /* e.g., "173#6#" */ int version[2]; }; #define lenInterfaceName (sizeof(struct InterfaceName)/2) struct EncryptionKey { char ekNib[8]; }; #define lenEncryptionKey (sizeof(struct EncryptionKey)/2) #define unencrypted 0 /* conversation handle for unencrtyped request */ /* AuthenticateFailed: ERROR[why: AuthenticateFailure= { */ #define badCommunications 1 #define badCaller 2 #define badKey 3 #define badCallee 4 /*}*/ /* ExportFailed: ERROR[why: ExportFailure = { */ /* badCommunications, */ #define badType 5 #define badInstance 6 #define badVersion 7 #define tooMany 8 #define badCredentials 9 /*}*/ /* ImportFailed: ERROR[why: ImportFailure = { */ /* badCommunications, badType, badInstance, badVersion, */ #define wrongVersion 10 #define interfaceUnbound 11 #define badStubProtocol 12 /*}*/ /* CallFailed: ERROR [why: CallFailure = { */ /* unbound, */ #define timeout 13 #define busy 14 #define protocolError 15 #define badArgs 16 /* ****** #include ****** */ /* RPCLupine.h*/ /* Last modified by D. Swinehart May 14, 1982 2:04 pm */ /* requires #include requires #include */ /* !!!! If lenPBIOverhead changes in Pup0, change it here too!!!!!!! */ #define lenPBIOverhead 4 /* !!!! MUST track Pup0!!!! */ #define headerSize 20 /* 10+6+4*/ #define maxDataLength (266 - headerSize - 1) /* in words -- max Pup less Pup and RPC overhead*/ /* ... is this all right?????*/ #define pktOverhead (lenPBIOverhead+headerSize+1) #define Dispatcher int /* TYPE=PROC[pkt, pktLength, conversation, dispatcherArgs) RETURNS [returnLength]*/ struct DArgs { int *Free; /* PROC[dArgs: POINTER TO DArgs] */ int args[1/*many*/]; }; /* arbitrary */ /* See RPCLupine.mesa for interface procedures and documentation.*/ /* ****** #include ****** */ /* RPCPkt.h*/ /* Last modified by D. Swinehart, May 18, 1982 10:59 AM */ struct PktType { /* "type" word of a Pup --*/ byte transport; /* should be zero before sending --*/ byte fields; /*: Here's what would be in them. subType bit 3 { rpc(3B), (7B) }, eom bit { end(0), notEnd(1) }, ack bit { dontAck(0), pleaseAck(1) }, class bit 3 { call(0), data(1), ack(2), nak(3), rfa(4), (7) } */ }; #define subtypeField 0340 #define eomField 0020 #define ackField 0010 #define classField 0007 #define rpc 0140 /* constant value for subType*/ #define call 0 /* class values*/ #define data 1 #define ack 2 /* obsolete nak = 3*/ #define rfa 4 /* Unambiguous name of a host */ struct Machine { /* a "word" */ byte host; byte net; }; struct Socket { word ms; byte midS; byte LS; }; /* a "word", but socket numbers are small in RPC */ #define lenSocket (sizeof (Socket)/2) struct HostConversationID { /* Host-relative ID of a conversation; unique for all time --*/ word LS; word fields; /* Here's what would be in them: bLank bit ms bit 15 */ }; #define lenHostConversationID (sizeof (HostConversationID)/2) struct ConversationID { /* Absolute ID of a conversation; unique for all hosts and a long time --*/ int originator; int count[2]; }; #define lenConversationID (sizeof (ConversationID)/2) struct PktConversationID { /* Same as ConversationID, but abbreviated within a packet --*/ /* Assumes originator is always caller or callee*/ word LS; word fields; /*: Here's what would be in them originator bit {caller, callee} // BCPL-style ms bit 15 */ }; #define lenPktConversationID (sizeof (PktConversationID)/2) #define callerField 0000000 /* swab(0000000) */ #define calleeField 0000200 /* swab(0100000) */ #define originatorField 0000200 /* swab(0100000) */ #define notCalleeMask 0177577 /* swab(0077777) */ struct ConnectionID { /* Uniquely identifies an independent sequence of calls --*/ int conv[2]; int caller; num activity; }; /* PSB.PsbIndex*/ #define lenConnectionID (sizeof (ConnectionID)/2) struct CallCount { /* [ConnectionID,CallCount] uniquely identifies call for all hosts and a long time*/ word LS; word ms; }; #define lenCallCount (sizeof (CallCount)/2) struct PktID { /* [ConversationID,PktID] uniquely identifies pkt for all hosts and a long time --*/ num activity; /* PSB.PsbIndex*/ int callCt[2]; num pktSeq; }; #define lenPktID (sizeof (PktID)/2) struct DispatcherID { word LS; word ms; }; #define lenDispatcherID (sizeof (DispatcherID)/2) struct DispatcherDetails { word mds; /* top half of dispatcher's MDS base address --*/ int dispatcherID[2]; /* exporter-relative UID of interface instance --*/ num dispatcherHint; }; /* hint to exporter host's export table --*/ #define lenDispatcherDetails (sizeof (DispatcherDetails)/2) union RPCCall { int dispatcherDet[4]; int outcome; byte bytes[2]; word words[1]; }; struct Header { num length; /* here's what it should be: length bit 15 // BCPL style oddByte bit { no(0), yes(1) }, [length must be swapped and shifted, viz: to remove from packet: (swab(hdr->length))>>1 to insert into packet: swab(hdr->length<<1) ] */ char type; num destPSB; /* in Mesa, PSB.PsbIndex,-- field has 6 extra bits*/ num srcePSB; /* in Mesa, PSB.PsbIndex,-- field has 6 extra bits*/ int destHost; int destSoc[2]; /* PupTypes.PupSocketID,*/ int srceHost; int srceSoc[2]; /* PupTypes.PupSocketID,*/ /* end of standard Pup header --*/ int conv[2]; /* For secure conversations, the remainder of the packet must be encrypted --*/ int pktID[2]; union RPCCall callData; }; #define lenHeader = (sizeof((Header)/2)-1) /* Mapping from Pup pkt types to RPC pkt types:*/ #define typeCall 0140 /* = [end, dontAck, call ]*/ #define typeData 0141 /* = [end, dontAck, data ]*/ #define typeAck 0142 /* = [end, dontAck, ack ]*/ #define typeRFA 0144 /* = [end, dontAck, rfa ]*/ /* 150B = [end, pleaseAck, call ]*/ /* 151B = [end, pleaseAck, data ]*/ #define typePing 0152 /* = [end, pleaseAck, ack ]*/ /* 154B = [, pleaseAck, rfa ] (also 174B)*/ /* 160B = [notEnd, dontAck, call ]*/ /* 161B = [notEnd, dontAck, data ]*/ /* 162B = [notEnd, dontAck, ack ]*/ /* 164B = [notEnd, dontAck, rfa ]*/ /* 170B = [notEnd, pleaseAck, call ]*/ /* 171B = [notEnd, pleaseAck, data ]*/ /* 172B = [notEnd, pleaseAck, ack ]*/ #define pktLengthOverhead lenHeader+1 /* include checksum word*/ /* Outcomes in outcome header-variant*/ #define result 0 /* normal --*/ #define unbound 1 /* dispatcher not known --*/ #define signal 2 /* signal propagation --*/ #define unwind 3 /* signal is unwinding --*/ #define protocol 4 /* stub protocol error detected. --*/ /* ******** Single-packet communication: exported by RPCPktIO ******** --*/ /* Packet Exchange States*/ /* receiving=0*/ /* sending=1*/ #define calling 2 #define endCall 3 #define authReq 4 #define rpcSocket 036 /* WARNING: All Client contexts calling RPC functions (StartCall, Call, etc.) MUST*/ /* Allocate an @RPCUser structure within their contexts. They must also initialize*/ /* the user.myPSB field with the results of calling NewPSB(). See RPCPktIO*/ /* listener/server initialization for examples.*/ struct RPCUser { int myPSB; /* randomly-assigned non-null psb*/ int sigVec[1]; }; struct RPCCtx { int next; int stack; int stackMin; int user; int stackArea[1]; }; #define lenRPCCtx ((sizeof (RPCCtx)/2)-2) /* ****** #include ****** */ /* RPCInternal.h*/ /* Last modified by D. Swinehart May 12, 1982 9:42 am */ /* requires #include */ /* requires #include */ /* requires #include */ /* requires #include */ struct ExportInstance { /* Exporter's record of exported interface --*/ /* Call Key*/ word mds; int id[2]; /* Dispatcher Values*/ Dispatcher *dispatcher; int *dispatcherArgs; /* Binding Key*/ struct InterfaceName name; }; #define lenExportInstance (sizeof (struct ExportInstance)/2) struct ImportInstance { /* Importer's record of successful binding --*/ int host; int dispatcherDet[4]; }; #define lenImportInstance (sizeof (struct ImportInstance)/2) #define maxPSB 10 #define nullPSB 0 /* */ /* ******** Authentication/Security: exported by RPCSecurity ******** --*/ struct ConversationObject { int *next; int id[2]; int *originator; /* RPC.Principal */ int *responder; /* RPC.Principal */ int key[4]; /* Conversation Key */ int *authenticator; /* pointer to authenticator */ }; #define lenConversationObject (sizeof (struct ConversationObject)/2) #define Conversation ConversationObject /* firstConversation: RPCPkt.PktConversationID; -- for unencrypted conversations --*/ /*GetConnectionState: PROC[ callPkt: RPCLupine.StubPkt, callLength: RPCLupine.DataLength] RETURNS[ ok: BOOLEAN, id: RPCPkt.ConnectionID, call: RPCPkt.CallCount, conv: LONG POINTER TO ConversationObject ]; -- Sends RFA and accepts response; results valid iff "ok" --*/ /*ReplyToRFA: PROC[b: BufferDefs.PupBuffer,-- incoming packet -- callHeader: POINTER TO RPCPkt.Header, -- encrypted -- callPktID: RPCPkt.PktID-- clear --] RETURNS[BOOLEAN]; -- Generates RFA response packet if request matches thisPktID --*/ /* ******** Packet stream functions: exported by RPCPktStream ******** --*/ /*DoSignal: PROC[b: BufferDefs.PupBuffer, pktLength: RPCLupine.DataLength, signalHandler: RPCLupine.Dispatcher] RETURNS[resumePkt: RPCLupine.StubPkt, resumeLength: RPCLupine.DataLength, myLocalFrame: POINTER]; -- Called from inside PktExchange to handle signal-back packets --*/ /*ServerMain: PROCEDURE; -- FORK'ed when needed by RPCPktIO, to maintain an adequate stock of them --*/