-- GVSender.mesa
-- Edited by Schroeder, April 2, 1981 10:37 AM
-- Edited by Brotz, March 7, 1983 11:06 AM

DIRECTORY
BodyDefs USING [RName],
Core USING [DMSUser],
exD: FROM "ExceptionDefs" USING [anotherServer, AppendStringToExceptionLine,
DisplayExceptionString, ExceptionLineOverflow, nil, SysBug],
LaurelSendDefs USING [AbortPoint, DeliverBody, EnumerateRecipientList, FromState,
GetRecipients, InsertReplyToField, ReportDelivery, ReportError, ReportProgress,
ReportRejectedRecipients, SendMode],
SendDefs USING [Abort, AddRecipient, AddToItem, CheckValidity, Create, Destroy, Handle,
Send, SendFailed, StartSend, StartText],
String USING [AppendChar, AppendDecimal, AppendString];

GVSender: PROGRAM
IMPORTS exD, LaurelSendDefs, SendDefs, String
EXPORTS LaurelSendDefs =

BEGIN
OPEN LaurelSendDefs;


GVSend: PUBLIC PROCEDURE [publicDLs: CARDINAL, sendMode: SendMode,
fromState: FromState, replyTo: BOOLEAN, userFeedback: BOOLEAN,
formatProc: PROCEDURE, user: Core.DMSUser] =
BEGIN

screenStringLength: CARDINAL = 100;
maxRecipientsWithoutConfirmation: CARDINAL = 20;
utilityString: STRING = [screenStringLength];
sendHandle: SendDefs.Handle;
badList, badOther, charsDelivered, recipients: CARDINAL;
nameListFull: BOOLEAN;

RecordInvalidRecipient: PROCEDURE [recipNo: CARDINAL, name: BodyDefs.RName] =
BEGIN
IF utilityString.length+name.length+3 <= utilityString.maxlength
THEN BEGIN
IF utilityString.length > 0 THEN String.AppendString[utilityString, ", "L];
String.AppendString[utilityString, name];
END
ELSE nameListFull ← TRUE;
FOR i: CARDINAL DECREASING IN [1 .. name.length) DO
IF name[i] = ’. THEN BEGIN
IF name[i-1] = ’↑
THEN badList ← badList + 1
ELSE badOther ← badOther + 1;
EXIT;
END;
REPEAT FINISHED => badOther ← badOther + 1;
ENDLOOP;
AbortPoint[];
END; -- of RecordInvalidRecipient --

SendRecipient: PROCEDURE [name: STRING] RETURNS [BOOLEAN] =
BEGIN
SendDefs.AddRecipient[sendHandle, name];
AbortPoint[];
RETURN[FALSE] --stop sending recipients if abort
END; -- of SendRecipient --

SendBodyBlock: PROCEDURE[block: POINTER, bytes: CARDINAL] =
BEGIN
buffer: DESCRIPTOR FOR PACKED ARRAY OF CHARACTER =
DESCRIPTOR[block, bytes];
SendDefs.AddToItem[sendHandle, buffer];
charsDelivered ← charsDelivered+bytes;
END; -- of SendBodyBlock --

BuildCredentialsString: PROCEDURE =
BEGIN
utilityString.length ← 0;
String.AppendString[utilityString, user.name];
String.AppendChar[utilityString, ’.];
String.AppendString[utilityString, user.registry];
END; -- of BuildCredentialsString --

-- main body of GVSend

utilityString.length ← 0;
recipients ← GetRecipients[];
IF publicDLs > 0
THEN BEGIN
others: CARDINAL = recipients - publicDLs;
String.AppendDecimal[utilityString, publicDLs];
String.AppendString[utilityString, " public distribution list"L];
IF publicDLs > 1 THEN String.AppendChar[utilityString, ’s];
IF others # 0 THEN BEGIN
String.AppendString[utilityString, " + "L];
String.AppendDecimal[utilityString, others];
String.AppendString[utilityString, " other recipients"L];
IF others = 1 THEN utilityString.length ← utilityString.length - 1;
END;
END
ELSE BEGIN
String.AppendDecimal[utilityString, recipients];
String.AppendString[utilityString, " recipient"L];
IF recipients # 1 THEN String.AppendChar[utilityString, ’s];
END;
IF userFeedback AND sendMode = red AND ~replyTo
AND (publicDLs > 0 OR recipients > maxRecipientsWithoutConfirmation)
THEN {exD.DisplayExceptionString[utilityString]; InsertReplyToField[user]};
formatProc[];
ReportProgress[exD.nil, utilityString, TRUE];
sendHandle ← SendDefs.Create[];
DO
ENABLE BEGIN
SendDefs.SendFailed =>
IF notDelivered
THEN BEGIN
ReportProgress[exD.anotherServer, NIL, TRUE];
LOOP
END
ELSE ReportError[uncertainClosing, "Communication failure."L, 0, 0];
UNWIND =>
{SendDefs.Abort[sendHandle]; SendDefs.Destroy[sendHandle]};
END;
AbortPoint[];
BuildCredentialsString[];
IF userFeedback THEN exD.AppendStringToExceptionLine
[" ..."L, 1 ! exD.ExceptionLineOverflow => CONTINUE];
SELECT SendDefs.StartSend[sendHandle, user.password, utilityString, NIL, TRUE] FROM
badSender, badPwd => ReportError[badSender, NIL, 0, 0];
badReturnTo => exD.SysBug[];
allDown => ReportError[cantConnect, NIL, 0, 0];
ENDCASE; --ok--
IF userFeedback THEN exD.AppendStringToExceptionLine
["."L, 1 ! exD.ExceptionLineOverflow => CONTINUE];
[] ← EnumerateRecipientList[user.registry.length + 1, SendRecipient];
badList ← 0; badOther ← 0; nameListFull ← FALSE; utilityString.length ← 0;
IF SendDefs.CheckValidity[sendHandle, RecordInvalidRecipient] = 0
THEN ReportError[noValidRecipients, NIL, 0, 0];
IF userFeedback AND sendMode = red AND badList + badOther > 0
THEN ReportRejectedRecipients[badList + badOther, utilityString, nameListFull];
SendDefs.StartText[sendHandle];
charsDelivered ← 0;
DeliverBody[user, fromState, userFeedback, SendBodyBlock];
SendDefs.Send[sendHandle];
EXIT;
ENDLOOP;
BEGIN
totalOther: CARDINAL = recipients - publicDLs;
IF userFeedback THEN ReportDelivery
[charsDelivered, totalOther - badOther, totalOther, publicDLs - badList, publicDLs];
END;
SendDefs.Destroy[sendHandle];
END; -- GVSend --


END. -- of GVSender --