RetrieveMail.mesa: main loop of access to mailboxes
Copyright © 1985 by Xerox Corporation. All rights reserved.
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.