GVProtocol.mesa - subroutines for mail and reg server protocols
Copyright © 1985 by Xerox Corporation. All rights reserved.
Andrew Birrell June 22, 1983 6:02 pm
Levin, September 22, 1983 10:38 am
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;
set sockets for test-only mode
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;
BSP "mark" byte used in Server-Server and ReadMail protocols
IsLocal:
PROC[addr: PupTypes.PupAddress]
RETURNS[
BOOLEAN ];
Whether the address is on this host
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 ];
may be raised by any of the following procedures,
except DestroyStream.
CreateStream:
PROC[host: PupTypes.PupAddress, socket: GVSocket, secs:
CARDINAL ← 120 ]
RETURNS[ Handle ];
Create stream, with given timeout for data
SendNow: PROC[str: Handle];
Close:
PROC[str: Handle] =
INLINE
{ str.Close[] };
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.
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]]] };
transmits the header.
ReceiveItemHeader:
PROC[ str: Handle ]
RETURNS[ header: GVBasics.ItemHeader ] =
TRUSTED
INLINE
{ ReceiveBytes[str, [LOOPHOLE[LONG[@header]], 0, bpw*SIZE[GVBasics.ItemHeader]]] };
receive header of item from stream.
SendTimestamp:
PROC[str: Handle, stamp: GVBasics.Timestamp] =
TRUSTED
INLINE
{ SendBytes[str, [LOOPHOLE[LONG[@stamp]], 0, bpw*SIZE[GVBasics.Timestamp]]] };
sends a Timestamp value over the stream.
ReceiveTimestamp:
PROC[str: Handle]
RETURNS [stamp: GVBasics.Timestamp] =
TRUSTED
INLINE
{ ReceiveBytes[str, [LOOPHOLE[LONG[@stamp]], 0, bpw*SIZE[GVBasics.Timestamp]]] };
receives a timestamp from the stream.
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]]] };
sends a return code value over the stream.
ReceiveRC:
PROC[str: Handle]
RETURNS [rc: ReturnCode] =
TRUSTED
INLINE
{ ReceiveBytes[str, [LOOPHOLE[LONG[@rc]], 0, bpw*SIZE[ReturnCode]]] };
receives a return code value from the stream.
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
the number of words occupied by protocol representation of a string
{ RETURN[ 2 + (str.Length[] + bpw-1) / bpw ] };
SendRName:
PROC[str: Handle, name: GVBasics.RName ] =
INLINE
{ SendGVString[str, name] };
transmits the contents of the R-Name.
ReceiveRName:
PROC[str: Handle]
RETURNS[GVBasics.RName ] =
INLINE
{
RETURN[ ReceiveGVString[str] ] };
SendConnect:
PROC[str: Handle, connect: GVBasics.Connect] =
INLINE
{ SendGVString[str, connect] };
sends the connect-site name as a Mesa string. "connect.length" should be < maxConnectLength
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];
Receive a string in GV protocol format
SendGVString:
PROC[ str: GVProtocol.Handle, rope: GVBasics.GVString];
Send a string in GV protocol format.
SendRope:
PROC[ str: GVProtocol.Handle, rope: Rope.
ROPE];
Send the characters of the rope with no extra protocol information
Enquire:
PROC[ str: Handle, op: RSOperation, name: GVBasics.RName, oldStamp: GVBasics.Timestamp ← GVBasics.oldestTime ]
RETURNS[ rc: ReturnCode, stamp: GVBasics.Timestamp ];
Sends an enquiry on the stream
ReceiveRList:
PROCEDURE[ str: Handle, work:
PROCEDURE[GVBasics.RName] ];
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
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 {
status of an RName, given in an R-Server reply.
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 {
result of an R-Server operation.
done(0), -- operation succeeded
noChange(1),
-- enquiry: given stamp was still valid
update: operation wouldn't change the database
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.