-- Copyright (C) 1981, 1984, 1985 by Xerox Corporation. All rights reserved. -- MSMail.mesa, Transport Mechanism Mail Server - Reading Internal Mail. -- HGM, 15-Sep-85 4:28:40 -- Andrew Birrell, 24-Dec-81 12:05:21 DIRECTORY BodyDefs USING [ItemHeader, maxRNameLength, Password, RName], EnquiryDefs USING [], LocalNameDefs USING [ReadMSName], LogDefs USING [WriteLogEntry], MailboxDefs USING [FlushCacheAndRemail, InaccessibleArchive], PolicyDefs USING [EndOperation, Wait, WaitOperation], Process USING [SecondsToTicks], RestartDefs USING [], RetrieveDefs USING [ AccessProcs, Failed, Handle, Create, NewUser, NextServer, ServerName, ServerState, WaitForMail], String USING [AppendString]; MSMail: MONITOR IMPORTS LocalNameDefs, LogDefs, MailboxDefs, PolicyDefs, Process, RetrieveDefs, String EXPORTS EnquiryDefs --LoginMSMail-- , RestartDefs --PROGRAM-- = BEGIN handle: RetrieveDefs.Handle = RetrieveDefs.Create[pollingInterval: 300]; LoginMSMail: PUBLIC ENTRY PROC = BEGIN myName: BodyDefs.RName; myPassword: LONG STRING; [myName, myPassword, ] ← LocalNameDefs.ReadMSName[]; RetrieveDefs.NewUser[handle: handle, user: myName, password: myPassword]; DO sName: BodyDefs.RName = [BodyDefs.maxRNameLength]; noMore: BOOLEAN; [noMore, , ] ← RetrieveDefs.NextServer[handle]; IF noMore THEN EXIT; LogInboxSite["MS inbox-site: "L]; ENDLOOP; END; LogInboxSite: INTERNAL PROC [s: LONG STRING] = BEGIN log: STRING = [64]; server: STRING = [64]; RetrieveDefs.ServerName[handle, server]; String.AppendString[log, s]; server.length ← MIN[server.length, log.maxlength - log.length]; String.AppendString[log, server]; LogDefs.WriteLogEntry[log]; END; mbxInterval: CONDITION ← [timeout: Process.SecondsToTicks[300]]; -- wait on this if mailbox reading fails -- FetchMail: ENTRY PROC = BEGIN DO noMore: BOOLEAN; state: RetrieveDefs.ServerState; gv: RetrieveDefs.AccessProcs; [noMore, state, gv] ← RetrieveDefs.NextServer[handle]; IF noMore THEN EXIT; IF state # notEmpty THEN 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]; PolicyDefs.Wait[mins: 3]; ENDLOOP --each new mail-- ; END; CheckMessage: PROCEDURE [ handle: RetrieveDefs.Handle, gv: POINTER TO 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.