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. &GVProtocol.mesa - subroutines for mail and reg server protocols Copyright c 1985 by Xerox Corporation. All rights reserved. Andrew Birrell June 22, 1983 6:02 pm 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 ΚΞ˜codešœΟc&œ ™?Kšœ Οmœ1™˜QKšœ–™–K˜—šœŸœ!Ÿœ˜6Kšœ1™1Kšœ™K˜—š  œŸœ4Ÿœ˜VšŸœ ˜Kšœ*™*——K˜Kš œŸœ˜K˜š œŸœŸ˜!K˜—K˜K˜Kšœ²™²K˜š œŸœŸ˜#Kšœ˜K˜—š  œŸœŸ˜&Kšœ˜K˜K˜—š  œŸœŸœŸ˜7KšœŸœŸœŸœ˜*K˜—š  œŸœŸœŸœŸ˜=KšœŸœ˜#K˜K˜—KšœŸœ ˜K˜Kš œŸ œ'˜:K˜š  œŸ œŸœ˜GK˜—K˜KšœŸœ˜1K˜š   œŸœŸœŸœŸ˜>Kš œŸœŸœŸœŸœ˜D—K˜š   œŸœŸœ ŸœŸœŸ˜KKš œŸœŸœŸœŸœ˜G—K˜K˜š œŸœ.ŸœŸ˜PKšœŸœŸœŸœ˜PKšœ™K˜—š œŸœ˜&šŸœ"ŸœŸ˜7KšœŸœŸœŸœ˜S—šœ#™#K˜K˜——š  œŸœ+ŸœŸ˜LKšœŸœŸœŸœ˜NKšœ(™(K˜—š  œŸœŸœŸœŸ˜XKšœŸœŸœŸœ˜QKšœ%™%K˜K˜—š  œŸœ'ŸœŸ˜GKšœŸœŸœŸœ˜JK˜—š  œŸœŸœŸœŸ˜RšœŸœŸœŸœ˜MK˜K˜——š œŸœ ŸœŸ˜:KšœŸœŸœŸœ˜CKšœ*™*K˜—š   œŸœŸœŸœŸ˜FKšœŸœŸœŸœ˜FKšœ-™-K˜K˜—š œŸœ!ŸœŸ˜DKšœŸœŸœŸœ˜D—K˜š  œŸœŸœŸœŸ˜OKšœŸœŸœŸœ˜G—K˜K˜š œŸœ!ŸœŸ˜DKšœŸœŸœŸœ˜D—K˜š  œŸœŸœŸœŸ˜OKšœŸœŸœŸœ˜G—K˜K˜š  œŸœ Ÿœ˜?K˜—š  œŸœŸœ Ÿœ˜IK˜K˜—š   œŸœŸœŸœŸ˜@KšœC™CKšœŸœ'˜/—K˜š  œŸœ'Ÿ˜<˜Kšœ%™%K˜——š  œŸœŸœŸ˜AšœŸœ˜#K˜K˜——š  œŸœ+Ÿ˜B˜Kšœ\™\K˜——š œŸœŸœŸ˜DšœŸœ˜#K˜K˜——š  œŸœ)Ÿ˜?˜KšU˜UK˜——š  œŸœŸœŸ˜BšœŸœ˜#K˜K˜——š œŸœŸœ˜JKšœ&™&—K˜š  œŸœ3˜EKšœ$™$—K˜K˜š œŸœ%Ÿœ˜9KšœB™B—K˜K˜š œŸœkŸœ.˜­šœ™K˜——š  œŸ œŸ œ˜HKšœ”/™ΓK˜K˜—Kšœ ŸœŸœŸ œ˜'˜K˜ K˜K˜ K˜K˜ K˜K˜ K˜K˜K˜K˜K˜K˜K˜K˜ K˜ K˜˜K˜K˜——šœ ŸœŸœŸ œ˜%Kšœ/™/Kšœ ˜Kšœ˜#Kšœ ˜)Kšœ 0˜9K˜K˜K˜—šœŸœŸœŸ œ˜ Kšœ ™ Kšœ ˜šœ '˜4Kšœ/™/—Kšœ0˜>Kšœ2˜AKšœ˜,Kšœ.˜>Kšœ *˜7Kšœ˜Kšœ0˜@Kšœ +˜7K˜K˜K˜—š œ ŸœŸœŸ œŸœ˜-K˜K˜K˜—šœ Ÿœ˜(K˜K˜—KšŸœ˜K˜—…—V)J