-- Transport Mechanism Mail Server - Reading Internal Mail. -- [Indigo]<Grapevine>MS>MSMail.mesa -- Andrew Birrell, 24-Dec-81 12:05:21 DIRECTORY BodyDefs USING[ ItemHeader, maxRNameLength, Password, RName], EnquiryDefs USING[], LocalNameDefs USING[ ReadMSName ], MailboxDefs USING[ FlushCacheAndRemail, InaccessibleArchive ], PolicyDefs USING[ EndOperation, WaitOperation ], Process USING[ SecondsToTicks ], RestartDefs USING[], RetrieveDefs USING[ AccessProcs, Failed, Handle, Create, NewUser, NextServer, ServerState, WaitForMail ]; MSMail: MONITOR IMPORTS LocalNameDefs, MailboxDefs, PolicyDefs, Process, RetrieveDefs EXPORTS EnquiryDefs--LoginMSMail--, RestartDefs--PROGRAM-- = BEGIN handle: RetrieveDefs.Handle = RetrieveDefs.Create[pollingInterval: 300]; LoginMSMail: PUBLIC ENTRY PROC = BEGIN myName: BodyDefs.RName; myPassword: STRING; [myName, myPassword,] ← LocalNameDefs.ReadMSName[]; RetrieveDefs.NewUser[handle: handle, user: myName, password: myPassword]; END; mbxInterval: CONDITION ← [timeout:Process.SecondsToTicks[300]]; -- wait on this if mailbox reading fails -- FetchMail: ENTRY PROC = BEGIN DO noMore: BOOLEAN; state: RetrieveDefs.ServerState; procs: RetrieveDefs.AccessProcs; gv: GV RetrieveDefs.AccessProcs; [noMore, state, procs] ← RetrieveDefs.NextServer[handle]; IF noMore THEN EXIT; IF state # notEmpty THEN LOOP; WITH gvProcs:procs SELECT FROM GV => gv←gvProcs; ENDCASE => LOOP; BEGIN ENABLE RetrieveDefs.Failed => CONTINUE; allGood: BOOLEAN ← TRUE; WHILE CheckMessage[handle, @gv] DO BEGIN DO header: BodyDefs.ItemHeader = gv.nextItem[handle]; name: BodyDefs.RName = [BodyDefs.maxRNameLength]; SELECT header.type FROM LastItem => EXIT; reMail => BEGIN length: CARDINAL = gv.nextBlock[handle, DESCRIPTOR[@(name.text),name.maxlength] ]; name.length ← MIN[name.maxlength, length]; MailboxDefs.FlushCacheAndRemail[name ! MailboxDefs.InaccessibleArchive => GOTO trouble]; END; ENDCASE => NULL; ENDLOOP--each item--; gv.deleteMessage[handle]; EXITS trouble => allGood ← FALSE; END; ENDLOOP--each message--; IF allGood THEN gv.accept[handle] ELSE WAIT mbxInterval; END; ENDLOOP--each server--; END; ReadMail: PROCEDURE = BEGIN LoginMSMail[]; DO RetrieveDefs.WaitForMail[handle]; PolicyDefs.WaitOperation[MSReadMail]; FetchMail[]; PolicyDefs.EndOperation[MSReadMail]; ENDLOOP--each new mail--; END; CheckMessage: PROCEDURE[handle: RetrieveDefs.Handle, gv: POINTER TO GV RetrieveDefs.AccessProcs] RETURNS[ BOOLEAN ] = BEGIN DO msgExists, archived, deleted: BOOLEAN; [msgExists, archived, deleted] ← gv.nextMessage[handle]; IF deleted THEN LOOP; IF msgExists THEN { gv.startMessage[handle]; RETURN[TRUE] } ELSE RETURN[FALSE] ENDLOOP; END; ReadMailProcess: PROCESS = FORK ReadMail[]; END.