Inbasket: PROGRAM 18 VERSION 2 = BEGIN DEPENDS UPON Authentication (14) VERSION 2, BulkData (0) VERSION 1, CHName (2) VERSION 0, MailTransport (17) VERSION 5; 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; BodyPartSequence: TYPE = SEQUENCE 500 OF BodyPartIndex; BodyPartsStatus: TYPE = SEQUENCE 500 OF BOOLEAN; BodyPartStatusChangeSequence: TYPE = SEQUENCE 500 OF BodyPartStatusChange; BodyPartStatusChange: TYPE = RECORD [ bodyPartIndex: BodyPartIndex, deleteable: Del ]; Del: TYPE = {true(0), noChange(1)}; 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. ]; Logon: PROCEDURE [inbasket: Name, credentials: Credentials, verifier: Verifier] RETURNS [session: Session, state: State, anchor: Anchor] REPORTS [AccessError, AuthenticationError, InbasketInUse, OtherError, ServiceError] = 5; Logoff: PROCEDURE [session: Session] REPORTS [AuthenticationError, OtherError, SessionError] = 4; MailPoll: PROCEDURE [inbasket:Name, credentials: Credentials, verifier: Verifier] RETURNS [state: State] REPORTS [AccessError, AuthenticationError, OtherError, ServiceError] = 7; MailCheck: PROCEDURE [session: Session] RETURNS [state: State] REPORTS [AuthenticationError, OtherError, SessionError, ServiceError] = 6; 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; RetrieveBodyParts: PROCEDURE [message: Index, bodyParts: BodyPartSequence, contents: BulkData.Sink, session: Session] REPORTS [AuthenticationError, IndexError, OtherError, SessionError, ServiceError, TransferError] = 8; ChangeMessageStatus: PROCEDURE [range: Range, changeUserDefinedStatus: BOOLEAN, newUserDefinedStatus: CARDINAL, session: Session] REPORTS [AuthenticationError, IndexError, OtherError, SessionError, ServiceError] = 0; ChangeBodyPartsStatus: PROCEDURE [index: Index, setStatusTo: BodyPartStatusChangeSequence, session: Session] RETURNS [deleted: BOOLEAN] REPORTS [AuthenticationError, IndexError, OtherError, SessionError, ServiceError] = 3; Delete: PROCEDURE [range: Range, session: Session] REPORTS [AuthenticationError, OtherError, SessionError, ServiceError] = 1; GetSize: PROCEDURE [inbasket: Name, credentials: Credentials, verifier: Verifier] RETURNS [sizeInBytes: LONG CARDINAL] REPORTS [AuthenticationError, AccessError, OtherError, ServiceError] =10; 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; 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". END. . 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. Types and Constants Used as an index into the tableOfContents. Indices should be monotonically increasing. allBodyParts: BodyPartSequence = []; -- Sirocco can't hack SEQUENCE[0] constructs Represents all the message body parts. For each body part of a message, indicates whether the body part is deleteable. A message can have up to 500 body parts. Status changes are unidirectional - there's no going back. Remote Procedures 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. Ends the session at the mail service, and invalidates the session handle. Makes permanent all status changes since the last call to MakePermanent. 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 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. 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. 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). Makes a message known, and changes the userDefinedStatus if the caller wants to do so. A message cannot be made new again. 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. 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. Retrieves the sizeInBytes of a mailbox. Suggested use: to warn users when an inbasket grows excessively large Remote Errors Errors numbered 2, 3, and 4 are no longer in the protocol. 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. Κ>•NewlineDelimiter –(cedarcode) style™codešœ ™ Kšœ Οeœ7™BKšœ™K™1K™KšœA™A—K˜šΟnœΟkœŸœŸ˜&šŸœŸ˜ KšœŸœ˜Kšœ Ÿœ˜Kšœ Ÿœ˜KšœŸœ˜—headšΟz™Kšœ Ÿœ˜/Kšœ Ÿœ˜(KšœŸœ˜KšœŸœŸœŸœΟc6˜SK˜šœŸœŸœ˜Kšœ˜Kšœ ˜ Kšœ˜—šœŸœŸœ˜KšœŸœ˜K˜K˜—KšœŸœ˜!šœŸœŸœ˜Kšœ*™*—KšœŸœŸœŸœ˜7Kšœ+™+Kšœ%‘Πcs‘™QKšœ&™&Kš œŸœŸœŸœŸœ˜0KšœO™OKšœ(™(KšœŸœŸœŸœ˜JšœŸœŸœ˜&Kšœ˜K˜K˜—KšœŸœ˜#Kšœ:™:šœŸœŸœ˜K˜K˜ K˜—šœ ŸœŸœ˜Kšœ ˜ Kšœ˜Kšœ˜—Kš œŸœŸœŸœŸ œ˜#Kš œŸœŸœŸœŸ œ‘5˜\šœŸœŸœ‘*˜AKšœŸœ‘+˜:KšœŸœ‘+˜;Kšœ˜——š ™šžœŸ œ@˜PKšŸœ1˜8KšŸœQ˜X—KšœΒ™ΒK˜šžœŸ œ˜$KšŸœ5˜<—Kšœ“™“K˜šžœŸ œ>˜QKšŸœ˜KšŸœB˜I—Kšœ«™«K˜šž œŸ œŸœ˜>KšŸœC˜J—KšœΩ™ΩK˜Kšœ Ÿœ˜$K˜šžœŸ œ4˜PKšŸœI˜PKšŸœO˜V—Kšœ™K˜šžœŸ œ.˜JK˜*KšŸœK˜RK˜—Kšœ΅™΅K˜šžœŸ œ)Ÿœ˜PKšœŸœ˜1KšŸœO˜V—Kšœ{™{K˜šžœŸ œL˜lKšŸœ Ÿœ˜KšŸœO˜V—Kšœμ™μK˜šžœŸ œ!˜2KšŸœC˜J—KšœΎ™ΎK˜Kšž œŸ œ™0Kšœ¦™¦K˜šžœŸ œ?˜QKšŸœŸœŸœ˜$KšŸœB˜I—Kšœn™n—š  ™ Kšž œŸœ˜0šœŸœ˜Kšœ‘˜Kšœ‘-˜GKšœ˜—K˜Kšž œŸœ‘(˜R—š ™Kšœώ™ώK™Kšœ¨™¨K™—KšŸœ˜K˜——…—<(¨