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 }; 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. GrapevineUser (Cedar) - subroutines for mail and reg server protocols GVProtocol.mesa Andrew Birrell June 22, 1983 6:02 pm Last Edited by: Levin, September 22, 1983 10:38 am set sockets for test-only mode BSP "mark" byte used in Server-Server and ReadMail protocols Whether the address is on this host "communicationError" means some error pup arrived; "noData" means the stream is still there, but no data; "protocolError" means we cant understand him may be raised by any of the following procedures, except DestroyStream. Create stream, with given timeout for data The following procedures provide type-safe access to the communication protocols. Note that sending characters directly on the stream is not always correct if they have one of these types. These procedures implement any conversion needed between Cedar internal representation and the Grapevine protocols. transmits the header. receive header of item from stream. sends a Timestamp value over the stream. receives a timestamp from the stream. sends a return code value over the stream. receives a return code value from the stream. the number of words occupied by protocol representation of a string transmits the contents of the R-Name. sends the connect-site name as a Mesa string. "connect.length" should be < maxConnectLength Receive a string in GV protocol format Send a string in GV protocol format. Send the characters of the rope with no extra protocol information Sends an enquiry on the stream receives a sequence of R-Names from the stream, calling "work" for each R-Name. The sequence should have been sent by HeapDefs.SendComponent or its equivalent. See also HeapDefs.ReceiveComponent status of an RName, given in an R-Server reply. result of an R-Server operation. update: operation wouldn't change the database ÊƘJšÏc;œ ™EJšœ™Jšœ%™%J™2šÏk ˜ Jšœžœ˜Jšœ žœR˜`Jšœžœ˜Jšžœžœ žœ˜'Jšœ žœ˜*Jšœžœ žœ˜—J˜šœ žœž ˜Jšžœžœ˜—J˜Jšž˜J˜šÏnœžœ˜Jšœ™J˜—šœ žœA˜TJšœ$˜*Jšœ ˜!Jšœ˜!Jšœ˜Jšœ˜!Jšœ ˜*Jšœ˜#Jšœ ˜J˜—J˜JšŸ œžœžœ˜˜QJšœ–™–J˜—šœžœ!žœ˜6Jšœ1™1Jšœ™J˜—šŸ œžœ4žœ˜Všžœ ˜Jšœ*™*——J˜JšŸœžœ˜J˜šŸœžœž˜!J˜—J˜J˜Jšœ²™²J˜šŸœžœž˜#Jšœ˜J˜—šŸ œžœž˜&Jšœ˜J˜J˜—šŸ œžœžœž˜7Jšœžœžœžœ˜*J˜—š Ÿœžœžœžœž˜=Jšœžœ˜#J˜J˜—Jšœžœ ˜J˜JšŸœž œ'˜:J˜šŸ œž œžœ˜GJ˜—J˜Jšœžœ˜1J˜š Ÿ œžœžœžœž˜>Jš œžœžœžœžœ˜D—J˜š Ÿ œžœžœ žœžœž˜KJš œžœžœžœžœ˜G—J˜J˜šŸœžœ.žœž˜PJšœžœžœžœ˜PJšœ™J˜—šŸœžœ˜&šžœ"žœž˜7Jšœžœžœžœ˜S—šœ#™#J˜J˜——šŸ œžœ+žœž˜LJšœžœžœžœ˜NJšœ(™(J˜—š Ÿœžœžœžœž˜XJšœžœžœžœ˜QJšœ%™%J˜J˜—šŸ œžœ'žœž˜GJšœžœžœžœ˜JJ˜—š Ÿœžœžœžœž˜Ršœžœžœžœ˜MJ˜J˜——šŸœžœ žœž˜:Jšœžœžœžœ˜CJšœ*™*J˜—š Ÿ œžœžœžœž˜FJšœžœžœžœ˜FJšœ-™-J˜J˜—šŸœžœ!žœž˜DJšœžœžœžœ˜D—J˜š Ÿœžœžœžœž˜OJšœžœžœžœ˜G—J˜J˜šŸœžœ!žœž˜DJšœžœžœžœ˜D—J˜š Ÿœžœžœžœž˜OJšœžœžœžœ˜G—J˜J˜šŸ œžœ žœ˜?J˜—šŸ œžœžœ žœ˜IJ˜J˜—š Ÿ œžœžœžœž˜@JšœC™CJšœžœ'˜/—J˜šŸ œžœ'ž˜<˜Jšœ%™%J˜——šŸ œžœžœž˜Ašœžœ˜#J˜J˜——šŸ œžœ+ž˜B˜Jšœ\™\J˜——šŸœžœžœž˜Dšœžœ˜#J˜J˜——šŸ œžœ)ž˜?˜JšU˜UJ˜——šŸ œžœžœž˜Bšœžœ˜#J˜J˜——šŸœžœžœ˜JJšœ&™&—J˜šŸ œžœ3˜EJšœ$™$—J˜J˜šŸœžœ%žœ˜9JšœB™B—J˜J˜šŸœžœkžœ.˜­šœ™J˜——šŸ œž œž œ˜HJšœ”/™ÃJ˜J˜—Jšœ žœžœž œ˜'˜J˜ J˜J˜ J˜J˜ J˜J˜ J˜J˜J˜J˜J˜J˜J˜J˜ J˜ J˜˜J˜J˜——šœ žœžœž œ˜%Jšœ/™/Jšœ ˜Jšœ˜#Jšœ ˜)Jšœ 0˜9J˜J˜J˜—šœžœžœž œ˜ Jšœ ™ Jšœ ˜šœ '˜4Jšœ/™/—Jšœ0˜>Jšœ2˜AJšœ˜,Jšœ.˜>Jšœ *˜7Jšœ˜Jšœ0˜@Jšœ +˜7J˜J˜J˜—š œ žœžœž œžœ˜-J˜J˜J˜—šœ žœ˜(J˜J˜—Jšžœ˜J˜—…—V)*