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. ΈWalnutOpsNewMailImpl.mesa Willie-Sue, January 6, 1986 6:14:27 pm PST Donahue, August 5, 1985 2:36:34 pm PDT Implementation of WalnutOps NewMail stuff Copyright c 1985 by Xerox Corporation. All rights reserved. Initialted by Willie-sue, February 7, 1985 Last Edited by: Donahue, December 11, 1984 8:51:42 pm PST Types Procedures Adding new messages from grapevine to the database used by newMail process used by higher levels Κ+– "cedar" style˜šΟb™J™*Icode™&—J™Jšœ*™*Jšœ Οmœ1™šŸ˜Jšœ ŸœŸœ˜Jšœ+˜+Jšœ3˜3Jšœ/˜/—JšŸœ ˜JšŸœ˜J˜JšœŸ˜—headšœ™JšŸœŸœŸœ˜JšŸœŸœŸœŸœ˜—š ™ ™2Jšœ™J™šΟn œŸœŸœŸœŸœŸœŸœ˜GJšŸœŸœŸœ˜JšœŸœ˜š‘œŸœ˜ Jšœ6˜6—Jšœ$˜$Jš Ÿœ ŸœŸœŸœŸœ˜7Jšœ8Ÿœ˜?J˜JšŸœŸœŸœŸœ˜*JšŸœS˜YJ˜—J™š ‘œŸœŸ œ Ÿœ ŸœŸœ˜MJšŸœŸœŸœ˜JšœŸœ˜š‘œŸœ˜JšœŸœ(˜0JšœN˜NJšœ3˜3Jšœ˜—J˜Jšœ$˜$Jšœ8Ÿœ˜>Jšœ%Ÿœ˜*J˜—J˜š‘ œŸœŸ œ˜!JšŸœŸœŸœ˜JšœŸœ ˜,Jšœ$˜$JšœŸœ˜#šŸœŸœŸ˜Jšœ4ŸœŸœ Ÿœ˜T—šŸœ$Ÿ˜*Jšœ/˜/—J˜—J˜Jšœ™J™š‘ œŸœŸœŸœŸœŸœŸœŸœŸœ ŸœŸœ!Ÿœ˜­JšŸœŸœŸœ˜Jšœ Ÿœ˜š‘œŸœ˜ šŸœ2Ÿ˜8JšœK˜K—Jšœ1˜1J˜J˜—š‘œŸœ Ÿœ˜ Jšœ Ÿœ˜Jšœ}˜}JšŸœ ŸœŸœ˜šŸœ Ÿœ˜JšœŸœ#˜*J˜ Jšœ˜J˜šŸœ˜JšœŸœ ˜'JšœF˜FJšœ˜Jšœ œ˜4Jšœ5˜5J˜——JšœŸœ˜#šœe˜eJš ˜—Jšœ$˜$JšœŸœ˜%Jšœ7˜7J˜ Jšœ˜—š‘œŸœ˜ JšŸœŸœŸœ7˜IJšœ(˜(J˜—J˜Jšœ$˜$Jšœ&Ÿœ˜-Jš Ÿœ ŸœŸœŸœŸœŸœ ˜OJ˜šŸœ Ÿœ˜Jšœ)˜)šŸœ Ÿœ˜Jšœ%˜%JšœD˜DJšœ Ÿœ ˜9J˜—J˜JšŸœ Ÿœ˜—J˜Jšœ&Ÿœ˜-J˜J˜—š ‘ œŸœŸœŸœŸœ˜8JšŸœŸœŸœ˜š‘œŸœ Ÿœ˜JšœŸœ˜šŸœ Ÿœ˜JšœH˜HJšœ"˜"J˜ J˜JšŸœ%˜)—Jšœ*˜*Jšœ˜—Jšœ$˜$Jšœ(˜(Jšœ%Ÿœ˜+J˜—J˜——JšŸœ˜J˜—…—&