Inbasket2.cr
Copyright Ó 1987, 1991 by Xerox Corporation. All rights reserved.
MChen, 09-Apr-87 11:04:31 PDT
Bill Jackson (bj) November 7, 1988 1:59:35 pm PST
The complete declaration of the Inbasket protocol is given below.
Inbasket: PROGRAM 18 VERSION 2 = BEGIN
DEPENDS UPON
Authentication (14) VERSION 2,
BulkData (0) VERSION 1,
CHName (2) VERSION 0,
MailTransport (17) VERSION 5;
Types and Constants
Credentials: TYPE = Authentication.Credentials;
Verifier:TYPE = Authentication.Verifier;
Name: TYPE = CHName.Name;
Index: TYPE = LONG CARDINAL; -- Names a message; unique until the mailbox is moved.
nullIndex: Index = 0;
Range: TYPE = RECORD [
low,
high: Index
];
MessageStatus: TYPE = RECORD [
userDefinedStatus: CARDINAL,
existenceOfMessage: Exist
];
Exist: TYPE = {new(0), known(1)};
BodyPartIndex: TYPE = CARDINAL;
Used as an index into the tableOfContents.
BodyPartSequence: TYPE = SEQUENCE 500 OF BodyPartIndex;
Indices should be monotonically increasing.
allBodyParts: BodyPartSequence = []; -- Sirocco can't hack SEQUENCE[0] constructs
Represents all the message body parts.
BodyPartsStatus: TYPE = SEQUENCE 500 OF BOOLEAN;
For each body part of a message, indicates whether the body part is deleteable.
A message can have up to 500 body parts.
BodyPartStatusChangeSequence: TYPE = SEQUENCE 500 OF BodyPartStatusChange;
BodyPartStatusChange: TYPE = RECORD [
bodyPartIndex: BodyPartIndex,
deleteable: Del
];
Del: TYPE = {true(0), noChange(1)};
Status changes are unidirectional - there's no going back.
Status: TYPE = RECORD [
messageStatus: MessageStatus,
bodyPartsStatus: BodyPartsStatus
];
Session: TYPE = RECORD [
token: Two,
verifier: Verifier
];
Two: TYPE = ARRAY 2 OF UNSPECIFIED;
Anchor: TYPE = ARRAY 5 OF UNSPECIFIED; -- Stored by clients that cache info across sessions.
State: TYPE = RECORD [ -- State of the mailbox, used for polling.
new: CARDINAL, -- Number of "new" messages in the mailbox.
total: CARDINAL -- Total number of messages in the mailbox.
];
Remote Procedures
Logon: PROCEDURE [inbasket: Name, credentials: Credentials, verifier: Verifier]
RETURNS [session: Session, state: State, anchor: Anchor]
REPORTS [AccessError, AuthenticationError, InbasketInUse, OtherError, ServiceError] = 5;
Creates a session with the mail service. Returns the Inbasket.State. Clients which retain indices between sessions store a copy of the old Anchor. If the returned Anchor is different, then the message indices have been renumbered, and the clients MUST flush the old indices from their cache to operate correctly. Courier connection costs of low-activity sessions must be kept to a minimum to allow many sessions to exist for long periods of time.
Logoff: PROCEDURE [session: Session]
REPORTS [AuthenticationError, OtherError, SessionError] = 4;
Ends the session at the mail service, and invalidates the session handle. Makes permanent all status changes since the last call to MakePermanent.
MailPoll: PROCEDURE [inbasket:Name, credentials: Credentials, verifier: Verifier]
RETURNS [state: State]
REPORTS [AccessError, AuthenticationError, OtherError, ServiceError] = 7;
MailPoll returns the state of the inbasket. A non-zero state.new implies that new mail exists. This is for use outside a session. This call is intended to be expedited.
MailCheck: PROCEDURE [session: Session] RETURNS [state: State]
REPORTS [AuthenticationError, OtherError, SessionError, ServiceError] = 6;
MailCheck returns the state of the inbasket. A non-zero state.new implies that new mail exists. For use within a session. MailCheck should not be used to keep a session open. This call is intended to be expedited.
WhichOne: TYPE = {this(0), next(1)};
RetrieveEnvelopes: PROCEDURE [last: Index, whichMsg: WhichOne, session: Session]
RETURNS [transportEnvelope: MailTransport.Envelope, status: Status, next: Index]
REPORTS [AuthenticationError, IndexError, OtherError, SessionError, ServiceError] = 2;
Returns the envelope, the inbasket status, and the message index of whichMsg. To start a stateless enumeration, pass in either a nullIndex or an index saved from the last time the User Agent inspected the mailbox. Returns "nullIndex" when there are no more envelopes. For random access to the inbasket, whichMsg should be set to "this", and IndexError will be raised when the index does not exist.
RetrieveBodyParts: PROCEDURE [message: Index, bodyParts: BodyPartSequence,
contents: BulkData.Sink, session: Session]
REPORTS [AuthenticationError, IndexError, OtherError, SessionError, ServiceError,
TransferError] = 8;
Retrieves body parts of a message named via "Index", to the local workstation. Either individual parts, or the whole message may be specified (see the AllBodyParts constant above).
ChangeMessageStatus: PROCEDURE [range: Range, changeUserDefinedStatus: BOOLEAN,
newUserDefinedStatus: CARDINAL, session: Session]
REPORTS [AuthenticationError, IndexError, OtherError, SessionError, ServiceError] = 0;
Makes a message known, and changes the userDefinedStatus if the caller wants to do so. A message cannot be made new again.
ChangeBodyPartsStatus: PROCEDURE [index: Index, setStatusTo: BodyPartStatusChangeSequence, session: Session]
RETURNS [deleted: BOOLEAN]
REPORTS [AuthenticationError, IndexError, OtherError, SessionError, ServiceError] = 3;
Makes a message known and changes its status. Individual message body parts cannot be deleted. A body part that is marked deleteable may be retrieved by a User Agent. If all of the body parts of a message are marked deleteable, then the message will be deleted by the Mail Service. Deletion takes effect upon either a call to MakePermanent or a call to Logoff.
Delete: PROCEDURE [range: Range, session: Session]
REPORTS [AuthenticationError, OtherError, SessionError, ServiceError] = 1;
Deletes a range of messages from the inbasket. Deletion takes effect upon either a call to MakePermanent or a call to Logoff. If there aren't any messages in the range, no error is raised.
MakePermanent: PROCEDURE [session: Session] = 9;
Makes permanent all status changes since the last call to MakePermanent. Status changes outstanding when a session times out are not guaranteed to be made permanent.
GetSize: PROCEDURE [inbasket: Name, credentials: Credentials, verifier: Verifier]
RETURNS [sizeInBytes: LONG CARDINAL]
REPORTS [AuthenticationError, AccessError, OtherError, ServiceError] =10;
Retrieves the sizeInBytes of a mailbox. Suggested use: to warn users when an inbasket grows excessively large
Remote Errors
AccessError: ERROR [problem: AccessProblem] = 0;
AccessProblem: TYPE = {
accessRightsInsufficient(0), -- the user doesn't have access
accessRightsIndeterminate(1), -- cannot determine whether the user has access
noSuchInbasket(2), -- no inbasket for this recipient
inbasketIndeterminate(3), -- cannot resolve potential alias
wrongService(4) -- mailbox does not reside on this service
};
AuthenticationError: ERROR [problem: Authentication.Problem] = 1;
Errors numbered 2, 3, and 4 are no longer in the protocol.
SessionError: ERROR [problem: SessionProblem] = 5;
SessionProblem: TYPE = {
tokenInvalid(0) -- the Inbasket.Session is invalid
};
ServiceError: ERROR [problem: ServiceProblem] = 6;
ServiceProblem: TYPE = {
cannotAuthenticate(0), -- generally, an Authentication.CallProblem on the server
serviceFull(1), -- no more operations of that type can be accepted
serviceUnavailable(2) -- operations of that type are currently disabled
};
TransferError: ERROR [problem: TransferProblem] = 7;
TransferProblem: TYPE = {
aborted(0) -- the transfer was aborted by the source or sink
};
OtherError: ERROR [problem: OtherProblem] = 8;
OtherProblem: TYPE = {
cantExpedite(0), -- the operation cannot be expedited
malformedMessage(1), -- the message bodyparts or other portions are malformed
invalidOperation(2), -- the sequence of operations is invalid
last(65535) -- errors will be added to the protocol here
};
IndexError: ERROR [problem: IndexProblem] = 9;
IndexProblem: TYPE = {
invalidIndex(0), -- the index doesn't name an existing message
invalidBodyPartIndex(1) -- the index doesn't name an existing body part
};
InbasketInUse: ERROR [user: Name] = 10; -- inbasket is currently in use by "user".
Bulk Data Formats
Bulk data is used as defined in the Addenda to Standards, XSIS 138301. That is, the transfer simply consists of a series of packets, the last of which has end-of-message set to TRUE (if the transfer was successful). No additional structuring is needed.
The RetrieveBodyParts procedure returns the body parts in the order that they were requested. The body parts are concatenated without any structuring information between them, so that the client can determine where each body part begins by using the body part sizes given in the tableOfContents.
END.