GrapevineUser (Cedar): main loop of access to mailboxes
RetrieveMail.mesa
Andrew Birrell 21-Jan-81 17:26:03
DIRECTORY
GVBasics USING[ ItemHeader, ItemLength, RName ],
PupDefs USING[ PupAddress ],
GVRetrieve USING[ FailureReason, MBXState, ServerState, ServerType ],
GVRetrieveInternal USING[ FindAddress, GVClose, Handle, HandleObject, MBXPtr, noMBX ],
Rope USING[ ROPE ];
RetrieveMail:
CEDAR MONITOR
LOCKS handle
USING handle: GVRetrieveInternal.Handle
IMPORTS GVRetrieveInternal
EXPORTS GVRetrieve, GVRetrieveInternal =
BEGIN
Handle: PUBLIC TYPE = GVRetrieveInternal.Handle;
HandleObject: PUBLIC TYPE = GVRetrieveInternal.HandleObject;
MailboxState:
PUBLIC
ENTRY
PROCEDURE[handle: Handle]
RETURNS[state: GVRetrieve.MBXState] =
BEGIN
ENABLE UNWIND => NULL;
DO
SELECT handle.mbxState
FROM
unknown, userOK => WAIT handle.mbxStateChange;
ENDCASE => EXIT;
ENDLOOP;
RETURN[handle.mbxState]
END;
-- Client access to his mail: --
WrongCallSequence: ERROR = CODE;
ServerName:
PUBLIC
ENTRY
PROC[ handle: Handle]
RETURNS[serverName: GVBasics.RName ] =
BEGIN
IF handle.currentMBX = GVRetrieveInternal.noMBX THEN ERROR WrongCallSequence[];
RETURN[handle.currentMBX.name];
END;
ServerAddress:
PUBLIC
INTERNAL
PROC[handle: GVRetrieveInternal.Handle]
RETURNS[ PupDefs.PupAddress ] =
BEGIN
IF handle.currentMBX = GVRetrieveInternal.noMBX THEN ERROR WrongCallSequence[];
IF handle.currentMBX.addrState = unknown
THEN GVRetrieveInternal.FindAddress[handle, handle.currentMBX];
SELECT handle.currentMBX.addrState
FROM
unknown => ERROR Failed[communicationFailure, "Can't find mailbox server address"];
bad => ERROR Failed[noSuchServer, "Your mailbox site name is not valid"];
known => RETURN[handle.currentMBX.addr];
ENDCASE => ERROR;
END;
NextServer:
PUBLIC
ENTRY
PROCEDURE[handle: Handle]
RETURNS[ noMore:
BOOLEAN,
state: GVRetrieve.ServerState,
type: GVRetrieve.ServerType ] =
BEGIN
ENABLE UNWIND => NULL;
DO
SELECT handle.mbxState
FROM
unknown, userOK => WAIT handle.mbxStateChange;
ENDCASE => EXIT;
ENDLOOP;
IF handle.currentMBX = GVRetrieveInternal.noMBX
THEN
BEGIN
handle.currentMBX ← handle.MBXChain;
handle.newPollWanted ← TRUE; BROADCAST handle.pollCond;
WHILE handle.newPollWanted DO WAIT handle.mbxStateChange ENDLOOP;
END
ELSE
BEGIN
GVRetrieveInternal.GVClose[handle];
handle.currentMBX ← handle.currentMBX.next;
END;
IF handle.currentMBX = GVRetrieveInternal.noMBX
THEN
BEGIN
noMore ← TRUE;
END
ELSE
BEGIN
noMore ← FALSE;
WHILE handle.currentMBX.replyWanted
DO WAIT handle.mbxStateChange ENDLOOP;
state ← handle.currentMBX.state;
IF handle.currentMBX.type = MTP
THEN
BEGIN
handle.state ← beginning;
type ← MTP;
END
ELSE
BEGIN
handle.header ← [type: LastItem, length: 0];
handle.spareByte ← FALSE;
handle.state ← beforeMBX;
type ← GV;
END;
END;
END;
Failed: PUBLIC ERROR[why: GVRetrieve.FailureReason, text: Rope.ROPE] = CODE;
END.