/* Test123.c -- Compiler still runs out of space. */
/* D. Swinehart, May 18, 1982  2:52 PM */

/* ***** #include <Env.h> ***** */
/* 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> ****** */
/* RPC.h
   C Public interface to a lightweight RPC runtime
   Last modified by D. Swinehart, May 14, 1982 2:02 pm */
   
/* Requires #include <env.h> */

#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> ****** */
/* RPCLupine.h*/
/* Last modified by D. Swinehart May 14, 1982 2:04 pm */

/* requires #include <env.h>
	requires #include <rpc.h> */
/* !!!! 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> ****** */
/* 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> ****** */
/* RPCInternal.h*/
/* Last modified by D. Swinehart  May 12, 1982 9:42 am */

/* requires #include <env.h> */
/* requires #include <rpc.h> */
/* requires #include <RPCLupine.h> */
/* requires #include <rpcpkt.h> */

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 --*/