-- IntSendCom.mesa -- Edited by Levin, October 16, 1980 5:07 PM -- Edited by Schroeder, January 6, 1982 11:49 AM -- Edited by Brotz, March 7, 1983 11:09 AM DIRECTORY Ascii USING [ControlA, CR, DEL, ESC, SP], Core USING [DMSUser], Editor USING [cancelCode, DeUnderlineSelection, FormatMessage, MapCharIndexToLine, RefreshFromFirstChange, RefreshToPlaceCharOnLine, ResetBuffers, UnderlineSelection], exD: FROM "ExceptionDefs" USING [AppendExceptionToExceptionLine, arpaAtExpansion, arpaNeedsRegistry, cancelingDelivery, cannotExpandDL, cantConnectToMailServer, deliveryCanceled, DisplayException, DisplayExceptionLine, DisplayExceptionOrStringOnLine, DisplayExceptionString, errorInDL, errorNearSelection, Exception, ExceptionLineOverflow, FlashExceptionsRegion, maybeDelivered, nil, noMessage, noRecipients, noReplyTo, notAuthentic, notDelivered, noValidRecipients, spare133, spare134, tryAgainOrCancel, uncertainClosing, unexpectedServerResp, unqualNameInDL, wishToCancelDelivery], inD: FROM "InteractorDefs" USING [CharIndex, CommandProcedure, Confirm, ConfirmInner, HousePtr, IdleLoop, MessageTextNbrPtr, NewFormCommand, RefreshHouse, SendOperationResult, TextSelection, TextSelectionPtr], Inline USING [BITAND], intCommon USING [actionPoint, cmTextNbr, commandType, composedMessageEdited, deliverCommandHouse, deliverWithCR, keystream, newFormAfterDelivery, newFormCommandHouse, newTargetSelection, pendingDeleteSetByControl, profileRegistry, profileSendMode, retrieveHandle, target, user], LaurelSendDefs USING [FlushRecipientList, FromState, GVSend, InitializeRecipientList, MTPSend, ParseForSend, ProtocolType, SendErrorType, SendMode], MailParseDefs USING [endOfInput, FinalizeParse, GetFieldBody, GetFieldName, InitializeParse, ParseError, ParseHandle], ovD: FROM "OverviewDefs" USING [CharMask, LineBreakValue], Process USING [Yield], PupDefs USING [EnumeratePupAddresses, PupAddress, PupNameTrouble], RetrieveDefs USING [MailboxState], vmD: FROM "VirtualMgrDefs" USING [CharIndex, ComposedMessage, ComposedMessagePtr, GetMessageChar, GetMessageSize, InsertMessageChar, InsertRangeInMessage, InsertStringInMessage, MessageRange, StartMessageInsertion, StopMessageInsertion]; IntSendCom: MONITOR IMPORTS Editor, exD, inD, Inline, intC: intCommon, LaurelSendDefs, MailParseDefs, Process, PupDefs, RetrieveDefs, vmD EXPORTS inD, LaurelSendDefs = BEGIN OPEN LaurelSendDefs; SendError: ERROR [error: SendErrorType] = CODE; userFeedbackGlobal: BOOLEAN _ TRUE; invocationMode: SendMode; sendProtocol: ProtocolType = DetermineSendProtocol[]; userAbortGiven: BOOLEAN; SendCommand: PUBLIC inD.CommandProcedure = BEGIN target: inD.TextSelectionPtr _ @intC.target; cm: inD.MessageTextNbrPtr = intC.cmTextNbr; IF ~cm.haveMessage OR cm.message = NIL THEN {exD.DisplayException[exD.noMessage]; RETURN}; IF RetrieveDefs.MailboxState[intC.retrieveHandle] IN [unknown..cantAuth] THEN {exD.DisplayException[exD.notAuthentic]; RETURN}; IF target.pendingDelete THEN BEGIN Editor.DeUnderlineSelection[target, target]; target.pendingDelete _ FALSE; Editor.UnderlineSelection[target, target]; END; IF Editor.MapCharIndexToLine[0, cm] = NIL THEN Editor.RefreshToPlaceCharOnLine[0, cm.lines, cm]; IF SendOperation[vmD.ComposedMessage[cm.message], @intC.user, Editor.FormatMessage, confirmed, TRUE] = ok THEN BEGIN house: inD.HousePtr = intC.deliverCommandHouse; intC.composedMessageEdited _ FALSE; house.typeface _ italicFace; inD.RefreshHouse[house, "delivered"L]; house.callable _ FALSE; IF intC.newFormAfterDelivery THEN inD.NewFormCommand[intC.newFormCommandHouse, TRUE]; END; intC.keystream.reset[intC.keystream]; END; -- of SendCommand -- SendOperation: PUBLIC ENTRY PROCEDURE [cm: vmD.ComposedMessagePtr, user: Core.DMSUser, formatProc: PROC [vmD.ComposedMessagePtr], confirmed: BOOLEAN _ FALSE, userFeedback: BOOLEAN _ TRUE] RETURNS [result: inD.SendOperationResult] = BEGIN unexpandedDLs: CARDINAL; replyTo: BOOLEAN; fromState: FromState; FormatProc: PROCEDURE = {formatProc[cm]}; --makes sure all pseudo carriage returns are inserted or otherwise modifies text of message. invocationMode _ IF confirmed THEN blue ELSE red; message _ cm; userAbortGiven _ FALSE; userFeedbackGlobal _ userFeedback; InitializeRecipientList[]; BEGIN -- for SendError exit -- ENABLE SendError => BEGIN result _ SELECT error FROM cancelCode => cancelled, ftpError, uncertainClosing, cantConnect, unexpectedResponse => commFailure, ENDCASE => badMessage; CONTINUE; END; [unexpandedDLs, fromState, replyTo] _ ParseForSend[user, (sendProtocol = mtp), invocationMode, userFeedback]; IF sendProtocol = gv THEN GVSend [unexpandedDLs, invocationMode, fromState, replyTo, userFeedback, FormatProc, user] ELSE MTPSend[invocationMode, fromState, replyTo, userFeedback, FormatProc, user]; result _ ok; END; -- of SendError exit -- FlushRecipientList[]; END; -- of SendOperation -- GetSendProtocol: PUBLIC PROCEDURE RETURNS [ProtocolType] = {RETURN[sendProtocol]}; DetermineSendProtocol: PROCEDURE RETURNS [t: ProtocolType] = BEGIN Work: PROCEDURE [addr: PupDefs.PupAddress] RETURNS [ignoreRest: BOOLEAN] = BEGIN IF t = mtp THEN {t _ gv; ignoreRest _ TRUE} ELSE {t _ mtp; ignoreRest _ FALSE}; END; -- of Work -- t _ gv; SELECT intC.profileSendMode FROM mtp => t _ mtp; gv => NULL; ENDCASE => [] _ PupDefs.EnumeratePupAddresses[intC.profileRegistry, Work ! PupDefs.PupNameTrouble => CONTINUE]; END; -- of DetermineSendProtocol -- CancelDelivery: PUBLIC PROCEDURE = {userAbortGiven _ TRUE; AbortPoint[]}; AbortPoint: PUBLIC PROCEDURE = -- causes user requested termination. BEGIN IF ~userFeedbackGlobal THEN RETURN; NoticeUserAbort[]; IF userAbortGiven THEN ReportError[cancelCode, NIL, 0, 0]; END; -- of AbortPoint -- NoticeUserAbort: PUBLIC PROCEDURE = -- checks for user-requested termination. BEGIN OPEN intC; char: CHARACTER; IF userAbortGiven OR ~userFeedbackGlobal THEN RETURN; UNTIL keystream.endof[keystream] DO IF (char _ keystream.get[keystream]) = Editor.cancelCode OR char = Ascii.DEL THEN userAbortGiven _ TRUE; ENDLOOP; IF userAbortGiven THEN ReportProgress[exD.cancelingDelivery, NIL, FALSE]; END; -- of NoticeUserAbort -- AskUser: PUBLIC PROCEDURE [exception: exD.Exception, string: STRING] = BEGIN IF userFeedbackGlobal THEN BEGIN IF exception # exD.nil THEN exD.DisplayException[exception] ELSE IF string # NIL THEN exD.DisplayExceptionString[string]; END; IF ~userFeedbackGlobal OR ~inD.Confirm[2] THEN CancelDelivery[]; END; -- of AskUser -- RetryThis: PUBLIC PROCEDURE [string: STRING, excep: exD.Exception _ exD.nil] RETURNS [BOOLEAN] = BEGIN IF ~userFeedbackGlobal THEN RETURN[FALSE]; IF invocationMode = red THEN BEGIN exD.DisplayExceptionOrStringOnLine[excep, string, 1]; exD.DisplayExceptionLine[exD.tryAgainOrCancel, 2]; exD.FlashExceptionsRegion[]; RETURN[inD.Confirm[0]]; END ELSE RETURN[FALSE]; END; -- of RetryThis -- ReportProgress: PUBLIC PROCEDURE [exception: exD.Exception, string: STRING, displayCancelMessage: BOOLEAN] = BEGIN Process.Yield[]; IF ~userFeedbackGlobal THEN RETURN; exD.DisplayExceptionOrStringOnLine[exception, string, 1]; exD.DisplayExceptionLine [IF displayCancelMessage THEN exD.wishToCancelDelivery ELSE exD.nil, 2]; END; -- of ReportProgress -- ReportError: PUBLIC PROCEDURE [erc: SendErrorType, msg: STRING, start, end: vmD.CharIndex] = BEGIN OPEN intC; IF userFeedbackGlobal THEN BEGIN exD.DisplayExceptionOrStringOnLine [SELECT erc FROM messageSyntaxError => exD.errorNearSelection, dlSyntaxError => exD.errorInDL, dlExpandError => exD.cannotExpandDL, illegalRecipient => exD.unqualNameInDL, missingQualification => exD.arpaNeedsRegistry, noRecipientsSpecified => exD.noRecipients, unexpectedResponse => exD.unexpectedServerResp, cantConnect => exD.cantConnectToMailServer, badSender => exD.notAuthentic, cancelCode => exD.deliveryCanceled, illegalFileExpansion => exD.arpaAtExpansion, noValidRecipients => exD.noValidRecipients, ENDCASE => exD.nil, SELECT erc FROM ftpError, uncertainClosing => msg, ENDCASE => NIL, 1]; exD.DisplayExceptionOrStringOnLine [SELECT erc FROM dlExpandError, cancelCode => exD.nil, unexpectedResponse => exD.maybeDelivered, uncertainClosing => exD.uncertainClosing, ENDCASE => exD.notDelivered, SELECT erc FROM dlExpandError => msg, ENDCASE => NIL, 2]; MoveUnderline[start, end]; exD.FlashExceptionsRegion[]; keystream.reset[keystream]; END; ERROR SendError[erc]; END; -- of ReportError -- MoveUnderline: PUBLIC PROCEDURE [start, end: vmD.CharIndex] = BEGIN target: inD.TextSelectionPtr = @intC.target; IF ~userFeedbackGlobal THEN RETURN; Editor.DeUnderlineSelection[selection: target, underline: target]; target^ _ inD.TextSelection[intC.cmTextNbr, start, end, start, 0, char, FALSE]; intC.newTargetSelection _ TRUE; Editor.UnderlineSelection[selection:target, underline:target]; inD.IdleLoop[]; END; -- of MoveUnderline -- InsertReplyToField: PUBLIC PROCEDURE [user: Core.DMSUser] = BEGIN cm: inD.MessageTextNbrPtr = intC.cmTextNbr; message: vmD.ComposedMessagePtr = vmD.ComposedMessage[cm.message]; target: inD.TextSelectionPtr = @intC.target; start, end: vmD.CharIndex; name: STRING _ user.name; reg: STRING _ user.registry; replyToString: STRING = "Reply-To: "L; dummyString: STRING = [0]; ph: MailParseDefs.ParseHandle; confirmed: BOOLEAN; messageLength: vmD.CharIndex _ vmD.GetMessageSize[message]; ReadChar: PROCEDURE RETURNS [char: CHARACTER] = BEGIN char _ IF start >= messageLength THEN MailParseDefs.endOfInput ELSE vmD.GetMessageChar[message, start]; start _ start + 1; END; -- of ReadChar -- IF ~userFeedbackGlobal THEN RETURN; exD.AppendExceptionToExceptionLine [exD.noReplyTo, 1 ! exD.ExceptionLineOverflow => CONTINUE]; -- ". Please choose ""Reply-To"" option." exD.DisplayExceptionLine[exD.spare133, 2]; SELECT inD.ConfirmInner[0] FROM 'a, 'A => RETURN; Ascii.ESC, Ascii.SP, 'Y, 'y, Ascii.CR => confirmed _ TRUE; ENDCASE => confirmed _ FALSE; Editor.ResetBuffers[cm]; Editor.DeUnderlineSelection[target, target]; start _ 0; ph _ MailParseDefs.InitializeParse[ReadChar]; BEGIN UNTIL ~MailParseDefs.GetFieldName [ph, dummyString ! MailParseDefs.ParseError => GO TO out] DO MailParseDefs.GetFieldBody[ph, dummyString ! MailParseDefs.ParseError => GO TO out]; ENDLOOP; start _ start - 1; EXITS out => start _ 0; END; MailParseDefs.FinalizeParse[ph]; vmD.StartMessageInsertion[message, start]; [] _ vmD.InsertStringInMessage[message, replyToString]; [] _ vmD.InsertStringInMessage[message, name]; [] _ vmD.InsertMessageChar[message, '.]; [] _ vmD.InsertStringInMessage[message, reg]; [] _ vmD.InsertMessageChar[message, Ascii.CR]; vmD.StopMessageInsertion[message]; end _ start + replyToString.length + name.length + 1 + reg.length + 1; [] _ vmD.InsertRangeInMessage [targetIndex: 0, targetMessage: cm.insertionBuffer, from: vmD.MessageRange[start, end, message]]; intC.commandType _ insert; intC.actionPoint _ start; intC.newTargetSelection _ TRUE; target^ _ inD.TextSelection[cm, start, end, start, 0, word, FALSE]; intC.pendingDeleteSetByControl _ FALSE; Editor.RefreshFromFirstChange [actionIndex: start, deletedChars: 0, insertedChars: end - start, mnp: cm]; Editor.UnderlineSelection[target, target]; IF ~confirmed THEN CancelDelivery[ ! SendError => exD.DisplayExceptionLine[exD.spare134, 2]]; END; -- of InsertReplyToField -- inHeader, endOfMessage: BOOLEAN; message: vmD.ComposedMessagePtr; messageSize, currentIndex: vmD.CharIndex; stockChars: PACKED ARRAY [1 .. 2] OF CHARACTER; charsInStock: CARDINAL; InitReadChar: PUBLIC PROCEDURE = BEGIN inHeader _ TRUE; endOfMessage _ FALSE; charsInStock _ currentIndex _ 0; messageSize _ vmD.GetMessageSize[message]; END; -- of InitReadChar -- ReadChar: PUBLIC PROCEDURE RETURNS [ch: CHARACTER] = BEGIN IF charsInStock > 0 THEN {ch _ stockChars[charsInStock]; charsInStock _ charsInStock - 1; RETURN}; IF currentIndex >= messageSize THEN {endOfMessage _ TRUE; inHeader _ FALSE; RETURN[MailParseDefs.endOfInput]}; ch _ vmD.GetMessageChar[message, currentIndex]; currentIndex _ currentIndex + 1; SELECT ch FROM Ascii.CR => IF inHeader AND (currentIndex >= messageSize OR vmD.GetMessageChar[message, currentIndex] = Ascii.CR) THEN inHeader _ FALSE; >= ovD.LineBreakValue => BEGIN ch _ Inline.BITAND[ch, ovD.CharMask]; SELECT TRUE FROM ~intC.deliverWithCR => NULL; inHeader => BEGIN IF ch = Ascii.SP THEN {ch _ Ascii.CR; charsInStock _ 1} ELSE stockChars[charsInStock _ 2] _ Ascii.CR; stockChars[1] _ Ascii.SP; END; (ch = Ascii.SP) => ch _ Ascii.CR; ENDCASE => stockChars[charsInStock _ 1] _ Ascii.CR; END; ENDCASE; IF inHeader AND ch = Ascii.ControlA AND userFeedbackGlobal THEN ERROR MailParseDefs.ParseError[badFieldBody]; END; -- of ReadChar -- GetCharPosition: PUBLIC PROCEDURE RETURNS [vmD.CharIndex] = {RETURN[currentIndex]}; END. -- of IntSendCom --(635)\f1