-- Copyright (C) 1981, 1984 by Xerox Corporation. All rights reserved. -- RetrieveMail.mesa, Transport Mechanism: User: main loop of access to mailboxes -- -- HGM: 10-Dec-84 23:52:22 -- Andrew Birrell 21-Jan-81 17:26:03 -- DIRECTORY BodyDefs USING [ItemHeader, ItemLength, RName, Timestamp], PupDefs USING [PupAddress], RetrieveDefs USING [ AccessProcs, FailureReason, MBXState, ServerState], RetrieveXDefs USING [ FindAddress, GVAccept, GVClose, GVDeleteMessage, GVNextBlock, GVNextItem, GVNextMessage, GVReadTOC, GVStartMessage, GVWriteTOC, Handle, HandleObject, MBXPtr, NoteChangedMBX, noMBX], String USING [AppendString]; RetrieveMail: MONITOR LOCKS handle USING handle: RetrieveXDefs.Handle IMPORTS RetrieveXDefs, String EXPORTS RetrieveDefs, RetrieveXDefs = BEGIN Handle: PUBLIC TYPE = RetrieveXDefs.Handle; HandleObject: PUBLIC TYPE = RetrieveXDefs.HandleObject; MailboxState: PUBLIC ENTRY PROCEDURE [handle: Handle] RETURNS [state: RetrieveDefs.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 PROCEDURE [ handle: Handle, serverName: BodyDefs.RName] = BEGIN IF handle.currentMBX = RetrieveXDefs.noMBX THEN ERROR WrongCallSequence[]; serverName.length ← 0; String.AppendString[serverName, handle.currentMBX.name]; END; ServerAddress: PUBLIC INTERNAL PROC [handle: RetrieveXDefs.Handle] RETURNS [PupDefs.PupAddress] = BEGIN IF handle.currentMBX = RetrieveXDefs.noMBX THEN ERROR WrongCallSequence[]; IF handle.currentMBX.addrState = unknown THEN RetrieveXDefs.FindAddress[handle, handle.currentMBX]; SELECT handle.currentMBX.addrState FROM unknown => ERROR Failed[communicationFailure]; bad => ERROR Failed[noSuchServer]; known => RETURN[handle.currentMBX.addr]; ENDCASE => ERROR; END; NextServer: PUBLIC ENTRY PROCEDURE [handle: Handle] RETURNS [ noMore: BOOLEAN, state: RetrieveDefs.ServerState, procs: RetrieveDefs.AccessProcs] = BEGIN ENABLE UNWIND => NULL; DO SELECT handle.mbxState FROM unknown, userOK => WAIT handle.mbxStateChange; ENDCASE => EXIT; ENDLOOP; IF handle.currentMBX = RetrieveXDefs.noMBX THEN BEGIN handle.currentMBX ← handle.MBXChain; handle.newPollWanted ← TRUE; BROADCAST handle.pollCond; WHILE handle.newPollWanted DO WAIT handle.mbxStateChange ENDLOOP; END ELSE BEGIN RetrieveXDefs.GVClose[handle]; handle.currentMBX ← handle.currentMBX.next; END; IF handle.currentMBX = RetrieveXDefs.noMBX THEN BEGIN noMore ← TRUE; END ELSE BEGIN noMore ← FALSE; WHILE handle.currentMBX.replyWanted DO WAIT handle.mbxStateChange ENDLOOP; state ← handle.currentMBX.state; handle.header ← [type: LastItem, length: 0]; handle.spareByte ← FALSE; handle.state ← beforeMBX; procs ← [ nextMessage: RetrieveXDefs.GVNextMessage, nextItem: RetrieveXDefs.GVNextItem, nextBlock: RetrieveXDefs.GVNextBlock, accept: Accept, readTOC: RetrieveXDefs.GVReadTOC, startMessage: RetrieveXDefs.GVStartMessage, writeTOC: RetrieveXDefs.GVWriteTOC, deleteMessage: RetrieveXDefs.GVDeleteMessage]; END; END; Accept: ENTRY PROCEDURE [handle: Handle] = BEGIN ENABLE UNWIND => NULL; RetrieveXDefs.GVAccept[handle]; RetrieveXDefs.NoteChangedMBX[handle, handle.currentMBX, empty]; END; Failed: PUBLIC ERROR [why: RetrieveDefs.FailureReason] = CODE; END.