-- SenderCommon.mesa
-- Edited by Levin, October 16, 1980 5:07 PM
-- Edited by Schroeder, March 13, 1981 1:15 PM
-- Edited by Brotz, March 7, 1983 11:08 AM

DIRECTORY
Ascii USING [CR],
Core USING [DMSUser],
DMSTimeDefs USING [MapPackedTimeToTimeZoneString],
exD: FROM "ExceptionDefs" USING [AppendDecimalToExceptionLine,
AppendStringToExceptionLine, ClearExceptionsRegion, DisplayExceptionStringOnLine,
ExceptionLineOverflow, nil],
LaurelSendDefs USING [AbortPoint, AskUser, InitReadChar, FromState, ReadChar,
ReportProgress],
MailParseDefs USING [endOfInput],
TimeDefs USING [CurrentDayTime],
VMDefs USING [AllocatePage, Page, pageByteSize, Release];

SenderCommon: PROGRAM
IMPORTS DMSTimeDefs, exD, LaurelSendDefs, TimeDefs, VMDefs
EXPORTS LaurelSendDefs =

BEGIN
OPEN LaurelSendDefs;


DeliverBody: PUBLIC PROCEDURE
[user: Core.DMSUser, fromState: FromState, userFeedback: BOOLEAN,
SendBlock: PROCEDURE [POINTER, CARDINAL] ] =
BEGIN
block: VMDefs.Page;
flushStart: CARDINAL ← 0;
charsInBodyBlock: CARDINAL ← 0;
lastBodyChar: CHARACTER;

PrepareDateField: PROCEDURE =
BEGIN
OPEN DMSTimeDefs;
timeString: STRING = [40];
PutString["Date: "L];
MapPackedTimeToTimeZoneString
[LOOPHOLE[TimeDefs.CurrentDayTime[]], timeString, arpaMsg];
PutString[timeString];
PutChar[Ascii.CR];
END; -- of PrepareDateField --

PrepareOriginatorField: PROCEDURE =
BEGIN
IF fromState = ok OR ~userFeedback THEN RETURN;
PutString[IF fromState = needsSender THEN "Sender: "L ELSE "From: "L];
PutString[user.name];
PutChar[’.];
PutString[user.registry];
PutChar[Ascii.CR];
END; -- of PrepareOriginatorField --

SendBodyBlock: PROCEDURE =
BEGIN
SendBlock[block, charsInBodyBlock];
AbortPoint[];
charsInBodyBlock ← 0;
END; -- of SendBodyBlock --

PutChar: PROCEDURE[ch: CHARACTER] =
BEGIN
IF charsInBodyBlock = VMDefs.pageByteSize THEN SendBodyBlock[];
block.chars[charsInBodyBlock] ← lastBodyChar ← ch;
charsInBodyBlock ← charsInBodyBlock + 1;
END; -- of SendBodyBlock --

PutString: PROCEDURE[s: STRING] =
BEGIN
IF charsInBodyBlock + s.length > VMDefs.pageByteSize THEN SendBodyBlock[];
FOR i: CARDINAL IN [0 .. s.length) DO
block.chars[charsInBodyBlock + i] ← s[i]
ENDLOOP;
charsInBodyBlock ← charsInBodyBlock + s.length;
lastBodyChar ← s[s.length - 1];
END; -- of PutString --

OutputMessage: PROCEDURE =
BEGIN
c: CHARACTER;
DO
c ← ReadChar[];
IF c = MailParseDefs.endOfInput THEN EXIT;
PutChar[c];
ENDLOOP;
IF lastBodyChar ~= Ascii.CR THEN PutChar[Ascii.CR];
IF charsInBodyBlock > 0 THEN SendBodyBlock[];
END; -- of OutputMessage --

-- main body of DeliverBody
block ← VMDefs.AllocatePage[];
BEGIN ENABLE UNWIND => VMDefs.Release[block];
IF userFeedback THEN exD.AppendStringToExceptionLine
["."L, 1 ! exD.ExceptionLineOverflow => CONTINUE];
InitReadChar[];
PrepareDateField[];
PrepareOriginatorField[];
OutputMessage[];
IF userFeedback THEN exD.DisplayExceptionStringOnLine[NIL, 2]; --cancel DEL to abort message
AbortPoint[];
END; -- of ENABLE UNWIND --
VMDefs.Release[block];
END; -- DeliverBody --


ReportRejectedRecipients: PUBLIC PROCEDURE [rejected: CARDINAL,
nameList: STRING, nameListFull: BOOLEAN] =
BEGIN
exD.ClearExceptionsRegion[];
EDecimal[rejected];
EString[" invalid name"L];
IF rejected > 1 THEN EString["s"L];
EString[" ("L];
EString[nameList ! exD.ExceptionLineOverflow => CONTINUE];
IF NOT nameListFull THEN EString[")"L ! exD.ExceptionLineOverflow => CONTINUE];
AskUser[exD.nil, NIL];
ReportProgress[exD.nil, "Continuing delivery .."L, TRUE];
END; -- of ReportRejectedRecipients --


ReportDelivery: PUBLIC PROCEDURE [chars, goodOther, totalOther: CARDINAL,
goodList: CARDINAL ← 0, totalList: CARDINAL ← 0] =
BEGIN
sStr: STRING = "s"L;
ofStr: STRING = " of "L;
exD.ClearExceptionsRegion[];
EDecimal[chars];
EString[" character message sent to "L];
IF totalList # 0 THEN BEGIN
EDecimal[goodList];
IF goodList < totalList THEN BEGIN
EString[ofStr];
EDecimal[totalList];
END;
EString[" public list"L];
IF NOT (goodList = 1 AND totalList = 1) THEN EString[sStr];
IF totalOther # 0 THEN EString[" + "L];
END;
IF totalOther # 0 THEN BEGIN
EDecimal[goodOther];
IF goodOther < totalOther THEN BEGIN
EString[ofStr];
EDecimal[totalOther];
END;
IF totalList # 0 THEN EString[" other"L];
EString[" recipient"L];
IF NOT (goodOther = 1 AND totalOther = 1) THEN EString[sStr];
END;
EString["."L];
END; -- of ReportDelivery --


EDecimal: PROCEDURE[n: CARDINAL] = {exD.AppendDecimalToExceptionLine[n, 1]};

EString: PROCEDURE[s: STRING] = {exD.AppendStringToExceptionLine[s, 1]};



END. -- of SenderCommon --