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