<> <> <> <<>> <> <> <<>> <> <> <<>> DIRECTORY BasicTime USING [GMT, Now], FS USING [Error], IO USING [Error, STREAM], Rope USING [ROPE], WalnutDB -- USING lots -- , WalnutDefs USING [Error, dontCareMsgSetVersion, ServerInfo], WalnutLog -- USING lots -- , WalnutMiscLog USING [GetNewMailLog, CloseNewMailLog], WalnutOps, WalnutOpsMonitorImpl, WalnutOpsInternal USING [mailStream, newMailSomewhere, CarefullyApply, CheckInProgress, CheckReport, CleanupAfterCopy, LongRunningApply, ParseLog], WalnutRegistryPrivate USING [NotifyForEvent]; WalnutOpsNewMailImpl: CEDAR MONITOR LOCKS walnutOpsMonitorImpl IMPORTS BasicTime, IO, FS, walnutOpsMonitorImpl: WalnutOpsMonitorImpl, WalnutDB, WalnutDefs, WalnutOps, WalnutOpsInternal, WalnutLog, WalnutMiscLog, WalnutRegistryPrivate EXPORTS WalnutOps SHARES WalnutOpsMonitorImpl = BEGIN <> ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; <> <> <> <<>> StartNewMail: PUBLIC ENTRY PROC[] RETURNS[newMailStream: IO.STREAM] = { ENABLE UNWIND => NULL; newMailLogLength: INT _ -1; Gnml: PROC = { newMailLogLength _ WalnutDB.GetNewMailLogLength[] }; WalnutOpsInternal.CheckInProgress[]; IF WalnutOpsInternal.mailStream # NIL THEN RETURN[NIL]; WalnutOpsInternal.CarefullyApply[proc: Gnml, didUpdate: FALSE]; IF newMailLogLength = -1 THEN RETURN[NIL]; RETURN[WalnutOpsInternal.mailStream _ WalnutMiscLog.GetNewMailLog[newMailLogLength, -1]]; }; <<>> RecordNewMailInfo: PUBLIC ENTRY PROC[logLen: INT, server: ROPE, num: INT] = { ENABLE UNWIND => NULL; when: BasicTime.GMT; Snml: PROC = { now: INT _ WalnutDB.GetServerInfo[server] + num; [] _ WalnutLog.RecordNewMailInfo[logLen, when _ BasicTime.Now[], server, now]; WalnutDB.SetNewMailInfo[logLen, when, server, now]; }; WalnutOpsInternal.CheckInProgress[]; WalnutOpsInternal.CarefullyApply[proc: Snml, didUpdate: TRUE]; WalnutOpsInternal.newMailSomewhere _ TRUE; }; EndNewMail: PUBLIC ENTRY PROC = { ENABLE UNWIND => NULL; strm: STREAM _ WalnutOpsInternal.mailStream; WalnutOpsInternal.CheckInProgress[]; WalnutOpsInternal.mailStream _ NIL; IF strm # NIL THEN WalnutMiscLog.CloseNewMailLog[ ! WalnutDefs.Error , IO.Error, FS.Error => CONTINUE]; IF WalnutOpsInternal.newMailSomewhere THEN WalnutRegistryPrivate.NotifyForEvent[mailRead]; }; <> <<>> GetNewMail: PUBLIC ENTRY PROC[ activeVersion: INT, proc: PROC[msg, TOCentry: ROPE, startOfSubject: INT]] RETURNS[responses: LIST OF WalnutOps.ServerInfo, complete: BOOL] = { ENABLE UNWIND => NULL; someEntries: BOOL; Cml: PROC = { IF activeVersion # WalnutDefs.dontCareMsgSetVersion THEN [] _ WalnutDB.VerifyMsgSet[ [WalnutOps.ActiveMsgSetName, activeVersion] ]; someEntries _ WalnutDB.GetNewMailLogLength[] # 0; }; Cml2: PROC[inProgress: BOOL] = { fromPos: INT _ 0; complete _ WalnutLog.PrepareToCopyTempLog[which: newMail, pagesAlreadyCopied: 0, reportProc: WalnutOpsInternal.CheckReport]; IF ~complete THEN RETURN; IF ~inProgress THEN { at: INT _ WalnutLog.StartCopyNewMail[].at; WalnutDB.SetOpInProgressPos[at]; WalnutDB.SetCopyMailLogPos[at]; } ELSE { at: INT = WalnutDB.GetCopyMailLogPos[]; WalnutOpsInternal.CheckReport["\n Continue copying the newMailLog\n"]; [] _ WalnutLog.SetPosition[at]; [] _ WalnutLog.NextEntry[]; -- skip the copy entry fromPos _ WalnutLog.LogLength[] - WalnutLog.NextAt[]; }; WalnutDB.SetAddingServerMsgs[TRUE]; WalnutLog.CopyTempLog[newMail, WalnutDB.GetCopyMailLogPos[], fromPos, WalnutOpsInternal.CheckReport]; -- raises error if problem WalnutOpsInternal.CheckReport["\n"]; WalnutDB.SetParseLogInProgress[TRUE]; WalnutDB.SetParseLogPos[WalnutDB.GetOpInProgressPos[]]; WalnutDB.SetOpInProgressPos[-1]; }; Gnm: PROC = { IF proc # NIL THEN WalnutDB.EnumerateUnacceptedMsgs[activeVersion, proc]; responses _ WalnutDB.EnumerateServers[]; }; WalnutOpsInternal.CheckInProgress[]; WalnutOpsInternal.CarefullyApply[Cml, FALSE]; IF WalnutOpsInternal.mailStream # NIL THEN RETURN[NIL, FALSE]; -- file is busy IF someEntries THEN { WalnutOpsInternal.LongRunningApply[Cml2]; IF complete THEN { WalnutOpsInternal.CleanupAfterCopy[]; WalnutOpsInternal.CheckReport["Adding new mail to the database\n"]; [] _ WalnutOpsInternal.ParseLog[TRUE]; -- "see" messages }; } ELSE complete _ TRUE; WalnutOpsInternal.CarefullyApply[Gnm, FALSE]; }; AcceptNewMail: PUBLIC ENTRY PROC[activeVersion: INT] = { ENABLE UNWIND => NULL; Anm: PROC[inProgress: BOOL] = { at: INT; IF ~inProgress THEN { [] _ WalnutDB.VerifyMsgSet[[WalnutOps.ActiveMsgSetName, activeVersion]]; at _ WalnutLog.AcceptNewMail[].at; WalnutDB.SetOpInProgressPos[at]; } ELSE at _ WalnutDB.GetAcceptNewMailPos[]; WalnutDB.AcceptNewMail[at, activeVersion]; }; WalnutOpsInternal.CheckInProgress[]; WalnutOpsInternal.LongRunningApply[Anm]; WalnutOpsInternal.newMailSomewhere _ FALSE; }; END.