<> <> <> 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; <> 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.