<> <> <> <> DIRECTORY Basics USING [bytesPerWord], GVBasics USING[ Connect, ItemHeader, GVString, oldestTime, Password, Remark, RName, Timestamp ], GVNames USING[ RSOperation ], IO USING[ Close, STREAM, UnsafeBlock ], PupTypes USING[ PupAddress, PupSocketID ], Rope USING[ Length, ROPE ]; GVProtocol: CEDAR DEFINITIONS IMPORTS IO, Rope = BEGIN SetTestingMode: PROC; <> GVSocket: TYPE = { -- socket numbers are hidden, because they differ in testing mode none, -- use socket number in host address RSEnquiry, -- database operations RSPoll, -- "are you there" probes Lily, -- Lily terminal service MSPoll, -- "are you there" probes MSForward, -- internal forwarding protocol MSSend, -- mail submission protocol MSRetrieve -- mail retrieval }; GetSocket: PROC[gv: GVSocket] RETURNS[PupTypes.PupSocketID]; endSST: [0..256) = 1; <> IsLocal: PROC[addr: PupTypes.PupAddress] RETURNS[ BOOLEAN ]; <> Handle: TYPE = IO.STREAM; FailureReason: TYPE = { communicationError, noData, protocolError, clientError }; <<"communicationError" means some error pup arrived; "noData" means the stream is still there, but no data; "protocolError" means we cant understand him>> Failed: SIGNAL[ why: FailureReason, text: Rope.ROPE ]; <> <> CreateStream: PROC[host: PupTypes.PupAddress, socket: GVSocket, secs: CARDINAL _ 120 ] RETURNS[ Handle ]; <> SendNow: PROC[str: Handle]; Close: PROC[str: Handle] = INLINE { str.Close[] }; <> SendAck: PROC[str: Handle] = INLINE { SendByte[str, 0] }; ReceiveAck: PROC[str: Handle] = INLINE { [] _ ReceiveByte[str] }; SendBoolean: PROC[str: Handle, bool: BOOLEAN ] = INLINE { SendByte[str, IF bool THEN 1 ELSE 0 ] }; ReceiveBoolean: PROC[str: Handle] RETURNS[ BOOLEAN ] = INLINE { RETURN[ ReceiveByte[str] # 0 ] }; Byte: TYPE = [0..256); SendByte: PROCEDURE[ str: GVProtocol.Handle, byte: Byte ]; ReceiveByte: PROCEDURE[ str: GVProtocol.Handle ] RETURNS[ byte: Byte ]; bpw: INT = Basics.bytesPerWord; -- bytes per word SendCount: PROC[str: Handle, count: CARDINAL] = TRUSTED INLINE { SendBytes[str, [LOOPHOLE[LONG[@count]], 0, bpw*SIZE[CARDINAL]]] }; ReceiveCount: PROC[str: Handle] RETURNS[ count: CARDINAL ] = TRUSTED INLINE { ReceiveBytes[str, [LOOPHOLE[LONG[@count]], 0, bpw*SIZE[CARDINAL]]] }; SendItemHeader: PROC[ str: Handle, header: GVBasics.ItemHeader] = TRUSTED INLINE { SendBytes[str, [LOOPHOLE[LONG[@header]], 0, bpw*SIZE[GVBasics.ItemHeader]]] }; <> ReceiveItemHeader: PROC[ str: Handle ] RETURNS[ header: GVBasics.ItemHeader ] = TRUSTED INLINE { ReceiveBytes[str, [LOOPHOLE[LONG[@header]], 0, bpw*SIZE[GVBasics.ItemHeader]]] }; <> SendTimestamp: PROC[str: Handle, stamp: GVBasics.Timestamp] = TRUSTED INLINE { SendBytes[str, [LOOPHOLE[LONG[@stamp]], 0, bpw*SIZE[GVBasics.Timestamp]]] }; <> ReceiveTimestamp: PROC[str: Handle] RETURNS [stamp: GVBasics.Timestamp] = TRUSTED INLINE { ReceiveBytes[str, [LOOPHOLE[LONG[@stamp]], 0, bpw*SIZE[GVBasics.Timestamp]]] }; <> SendPassword: PROC[str: Handle, pw: GVBasics.Password] = TRUSTED INLINE { SendBytes[str, [LOOPHOLE[LONG[@pw]], 0, bpw*SIZE[GVBasics.Password]]] }; ReceivePassword: PROC[str: Handle] RETURNS[pw: GVBasics.Password] = TRUSTED INLINE { ReceiveBytes[str, [LOOPHOLE[LONG[@pw]], 0, bpw*SIZE[GVBasics.Password]]] }; SendRC: PROC[str: Handle, rc: ReturnCode] = TRUSTED INLINE { SendBytes[str, [LOOPHOLE[LONG[@rc]], 0, bpw*SIZE[ReturnCode]]] }; <> ReceiveRC: PROC[str: Handle] RETURNS [rc: ReturnCode] = TRUSTED INLINE { ReceiveBytes[str, [LOOPHOLE[LONG[@rc]], 0, bpw*SIZE[ReturnCode]]] }; <> SendMSOperation: PROC[str: Handle, op: MSOperation] = TRUSTED INLINE { SendBytes[str, [LOOPHOLE[LONG[@op]], 0, bpw*SIZE[MSOperation]]] }; ReceiveMSOperation: PROC[str: Handle] RETURNS[op: MSOperation] = TRUSTED INLINE { ReceiveBytes[str, [LOOPHOLE[LONG[@op]], 0, bpw*SIZE[MSOperation]]] }; SendRSOperation: PROC[str: Handle, op: RSOperation] = TRUSTED INLINE { SendBytes[str, [LOOPHOLE[LONG[@op]], 0, bpw*SIZE[RSOperation]]] }; ReceiveRSOperation: PROC[str: Handle] RETURNS[op: RSOperation] = TRUSTED INLINE { ReceiveBytes[str, [LOOPHOLE[LONG[@op]], 0, bpw*SIZE[RSOperation]]] }; SendBytes: PROC[str: GVProtocol.Handle, block: IO.UnsafeBlock]; ReceiveBytes: UNSAFE PROC[str: GVProtocol.Handle, block: IO.UnsafeBlock]; StringSize: PROC[str: GVBasics.GVString] RETURNS[ INT ] = INLINE <> { RETURN[ 2 + (str.Length[] + bpw-1) / bpw ] }; SendRName: PROC[str: Handle, name: GVBasics.RName ] = INLINE { SendGVString[str, name] }; <> ReceiveRName: PROC[str: Handle] RETURNS[GVBasics.RName ] = INLINE { RETURN[ ReceiveGVString[str] ] }; SendConnect: PROC[str: Handle, connect: GVBasics.Connect] = INLINE { SendGVString[str, connect] }; <> ReceiveConnect: PROC[str: Handle] RETURNS[GVBasics.Connect] = INLINE { RETURN[ ReceiveGVString[str] ] }; SendRemark: PROC[str: Handle, remark: GVBasics.Remark] = INLINE { SendGVString[str, remark] }; -- sends the remakr as a Mesa string. "remark.length" should be < maxRemarkLength -- ReceiveRemark: PROC[str: Handle] RETURNS[GVBasics.Remark] = INLINE { RETURN[ ReceiveGVString[str] ] }; ReceiveGVString: PROC[ str: GVProtocol.Handle] RETURNS[GVBasics.GVString]; <> SendGVString: PROC[ str: GVProtocol.Handle, rope: GVBasics.GVString]; <> SendRope: PROC[ str: GVProtocol.Handle, rope: Rope.ROPE]; <> Enquire: PROC[ str: Handle, op: RSOperation, name: GVBasics.RName, oldStamp: GVBasics.Timestamp _ GVBasics.oldestTime ] RETURNS[ rc: ReturnCode, stamp: GVBasics.Timestamp ]; <> ReceiveRList: PROCEDURE[ str: Handle, work: PROCEDURE[GVBasics.RName] ]; <> MSOperation: TYPE = MACHINE DEPENDENT { openMBX(0), nextMessage(1), readTOC(2), readMessage(3), writeTOC(4), deleteMessage(5), flushMBX(6), restartMBX(7), startSend(20), addRecipient(21), checkValidity(22), startItem(23), addToItem(24), send(26), expand(27), (255) }; RNameType: TYPE = MACHINE DEPENDENT { <> group(0), -- group of names individual(1), -- person or machine notFound(2), -- the R-Name does not exist dead(3), -- the R-Name has been deleted from the database (255) }; Code: TYPE = MACHINE DEPENDENT { <> done(0), -- operation succeeded noChange(1), -- enquiry: given stamp was still valid <> outOfDate(2), -- update: more recent info was in database (!) NotAllowed(3), -- update: operation prevented by access controls BadOperation(4), -- unknown operation number BadProtocol(5), -- protocol violation (e.g. list out of order) BadRName(6), -- R-Name does not exist or has wrong type BadPassword(7), -- what it says WrongServer(8), -- the R-Name's registry is not in this R-Server AllDown(9), -- remote R-Server was down for ACL enquiry (255) }; ReturnCode: TYPE = MACHINE DEPENDENT RECORD [ code: Code, type: RNameType]; RSOperation: TYPE = GVNames.RSOperation; END.