-- Transport Mechanism - DEFS for retrieval of new mail from GV Servers --

-- [Ivy]<DMS>MS>RetrieveDefs.mesa

-- M. D. Schroeder  February 20, 1980  5:05 PM --
-- Andrew Birrell  21-Jan-81 17:13:34 --

DIRECTORY
BodyDefs	USING[ ItemHeader, RName, Timestamp ];


RetrieveDefs:	DEFINITIONS = BEGIN


-- No procedures in this interface other than the "AccessProcs" returned by
-- "NextServer" ever raise a SIGNAL or ERROR.




Handle:		TYPE[SIZE[POINTER]];
   -- This interface is intended to be able to be used by multiple clients.
   -- They are distinquished by a "handle", created by "Create" and
   -- destroyed by "Destroy" --


Create:		PROC[pollingInterval: CARDINAL,
		     reportChanges: PROCEDURE[MBXState] ← NIL]
		RETURNS[Handle];
   -- Must be called before any other entries in this interface.  Can be
   -- called many times.  "pollingInterval" is the interval in seconds to
   -- wait between successive inbox checks and "reportChanges" (if
   -- provided) is called  whenever the state of the user's authentication
   -- or mailboxes changes;  "reportChanges" will not be called if the
   -- state changes to "unknown" or "userOK".


Destroy:	PROC[Handle];
   -- Terminates use of this handle, releasing all resources used by it. --




-- AUTHENTICATION AND MAILBOX POLLING --


NewUser:	PROC[ handle: Handle, user: BodyDefs.RName,
		      password: STRING];
   -- Provides new user name and password, and starts authentication and
   -- mailbox checking.


MBXState:	TYPE = { unknown, badName, badPwd, cantAuth, userOK,
			 allDown, someEmpty, allEmpty, notEmpty };
   -- Records current state of the user's mailboxes. Initially "unknown".
   -- Set to "badName", "badPwd", "cantAuth" or "userOK" after
   -- authentication check.  Set to "allDown", "someEmpty", "allEmpty", or
   -- "notEmpty" after mail polling is complete.  "someEmpty" means not all
   -- servers replied and none had mail; "allEmpty" means all replied and
   -- none had mail; "notEmpty" means at least one has mail; "allDown"
   -- means none replied.

MailboxState:	PROC[ handle: Handle] RETURNS[ state: MBXState];
   -- Returns the current mailbox state.  Will not return "unknown" or
   -- "userOK" (These change to "cantAuth" or "allDown" after suitable
   -- timeouts if necessary.)


WaitForMail:	PROC[ handle: Handle ];
   -- returns only when there is likely to be mail for the user --
   -- Possible ERRORS: none


SetMTPRetrieveDefault: PROC[host, reg: STRING];
   -- records "host" and "reg", and subsequently if the user name is such
   -- that its registry is an MTP registry, and its registry equals "reg",
   -- then the retrieve host is forced to be "host".
   -- NB: This is a temporary facility for the benefit of Laurel.




-- ACCESS TO MAILBOXES --


-- The intended use is as follows.

-- The user has a number of mailboxes, each of which is on an MTP server or
-- on a Grapevine server.  To access all of a client's mail, call
-- "NextServer" repeatedly until it returns noMore=TRUE.  For each
-- successful call of "NextServer", use the AccessProcs to read the mail in
-- the mailbox.

-- For either type of server, call "nextMessage" until it returns
-- msgExists=FALSE.  The first call of "nextMessage" for each server will
-- attempt to create a stream to the server (signalling if it fails). 
-- While accessing a mailbox, "Failed" may be signalled at any time if the
-- communication system fails (because of network or server error).  If
-- "Failed" is signalled, no further operations on this mailbox are allowed

--  If "nextMessage" returns deleted=TRUE it indicates that the message is
-- really just a placeholder and has been removed from the mailbox; you
-- should not attempt to access the message.  Returning archived=TRUE
-- indicates that the message has been spilled to some file server, and
-- accessing it is likely to be much slower.  For each message that exists
-- and is not deleted, the message may be manipulated by the other
-- procedures provided.

-- If the server type is GV, "readTOC" may be used to read any TOC entry
-- for the message (giving length=0 if there is no TOC entry), then
-- "startMessage" may be called to read the guaranteed properties of the
-- message; these are not available for MTP servers; these may not be
-- called after you have called "nextItem" for this message.

-- For either type of server, "nextItem" may be called to access in
-- sequence the items which are the contents of the message body.  Note
-- that the ItemHeader contains the item type and length in bytes.  For an
-- MTP server, the only item will be of type "text".  For a GV server, the
-- first item will be the guaranteed recipient list.  For all servers, the
-- message body is followed by an item of type "LastItem".  Within an item,
-- use "nextBlock" to access the data of the item.  Each call of
-- "nextBlock" within an item will fill its buffer if the data exists;  the
-- end of the item is indicated by "nextBlock" returning 0.

-- If the server is GV, you may call "writeTOC" to change or create a TOC
-- entry for the message, or you may call "deleteMessage" to remove this
-- single message from the mailbox;  "readTOC", "startMessage", "nextItem"
-- or "nextBlock" may not be called after calling "writeTOC" or
-- "deleteMessage" for this message.

-- At any time within an item, you may call "nextItem" to skip the
-- remainder of the item;  at any time within a message, you may call
-- "nextMessage" to skip the remainder of this message.

-- At any time within a mailbox, you may call "accept".  This
-- terminates reading the mailbox and deletes all messages from
-- the mailbox.  Calling "accept" will not delete any messages which you
-- haven't been given a chance to read.  No other operations on the mailbox
-- are allowed after calling "accept".  If you call "NextServer" without
-- having called "accept", the mailbox is closed (if necessary) without
-- deleting the messages (except those which were deleted by calling
-- "deleteMessage").


ServerType:	TYPE = { MTP, GV };

ServerState:	TYPE = { unknown, empty, notEmpty };
   -- "unknown" means the server didn't reply to mail check packets.

AccessProcs:	TYPE = RECORD[ -- procedures to access mailbox --
	nextMessage:	PROC[handle: Handle]
			RETURNS[msgExists, archived, deleted: BOOLEAN],
	nextItem:	PROC[handle: Handle]
			RETURNS[BodyDefs.ItemHeader],
	nextBlock:	PROC[handle: Handle,
		 	     buffer: DESCRIPTOR FOR PACKED ARRAY OF CHARACTER]
			RETURNS[bytes: CARDINAL],
	accept:		PROC[handle: Handle],
	extra:	SELECT type: ServerType FROM
	    MTP => NULL,
	    GV => [
		readTOC:	PROC[handle: Handle, text: STRING],
		startMessage:	PROC[handle: Handle,
			   postmark: POINTER TO BodyDefs.Timestamp ← NIL,
			   sender: BodyDefs.RName ← NIL,
			   returnTo: BodyDefs.RName ← NIL],
		writeTOC:	PROC[handle: Handle, text: STRING],
		deleteMessage:	PROC[handle: Handle] ],
	  ENDCASE
	];


NextServer:	PROCEDURE[ handle: Handle ]
		  RETURNS[ noMore: BOOLEAN,
			   state: ServerState,
			   procs: AccessProcs ];
   -- Returns information about the next server in the mailbox site list of
   -- the user, and that server becomes the "current server".  If there is
   -- no such server, noMore=TRUE, in which case the next call to
   -- "NextServer" will start a new sequence of mail retrieval.  If the
   -- state is "unknown", attempting to access the mailbox is inadvisable,
   -- as the server is probably down.  If the state is "empty", there may
   -- in fact be mail, as the state is only a hint obtained by polling. 


ServerName:	PROC[ handle: Handle,
		      serverName: BodyDefs.RName];
   -- Provides the name of the current server.  For MTP registries, this
   -- will be equivalent to the registry name.


FailureReason:	TYPE = { communicationFailure, -- server or network down --
			 noSuchServer,         -- server name incorrect --
			 connectionRejected,   -- server full, mbx busy, etc --
			 badCredentials,       -- name/pwd rejected --
			 unknownFailure        -- protocol violation
					       -- or unknown MTP error:
					       -- likely to be permanent --
			}; 

Failed:		ERROR[why: FailureReason];
   -- May be signalled by any of the "AcceptProcs" returned by "NextServer"



END.