-- IntSendCom.mesa -- Edited by Levin, October 16, 1980 5:07 PM -- Edited by Schroeder, April 2, 1981 10:22 AM -- Edited by Brotz, April 9, 1981 1:09 PM DIRECTORY Ascii, Editor, exD: FROM "ExceptionDefs", inD: FROM "InteractorDefs", Inline, intCommon: FROM "intCommon", LaurelSendDefs, MailParse, ovD: FROM "OverviewDefs", PupDefs, RetrieveDefs, String, vmD: FROM "VirtualMgrDefs"; IntSendCom: PROGRAM IMPORTS Editor, exD, inD, Inline, intC: intCommon, LaurelSendDefs, MailParse, PupDefs, RetrieveDefs, String, vmD EXPORTS inD, LaurelSendDefs = BEGIN OPEN LaurelSendDefs; SendError: PUBLIC ERROR = CODE; SendCommand: PUBLIC PROCEDURE [hp: inD.HousePtr, confirmed: BOOLEAN] = BEGIN SendOperation[Editor.FormatCM, confirmed]; END; -- of SendCommand -- SendOperation: PUBLIC PROCEDURE [formatProc: PROC [vmD.ComposeMessagePtr], confirmed: BOOLEAN _ FALSE] = BEGIN target: inD.TextSelectionPtr _ @intC.target; cm: inD.MessageTextNbrPtr = intC.cmTextNbr; FormatProc: PROCEDURE = {formatProc[LOOPHOLE[cm.message]]}; --makes sure all pseudo carriage returns are inserted or otherwise modifies text of message. 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]; BEGIN -- for sendError exit -- unexpandedDLs: CARDINAL; netMail, fromField, replyTo: BOOLEAN; house: inD.HousePtr = intC.deliverCommandHouse; invocationMode _ IF confirmed THEN blue ELSE red; message _ vmD.MapVirtualToComposeMessage[cm.message]; userAbortGiven _ FALSE; InitializeRecipientList[]; [unexpandedDLs, netMail, fromField, replyTo] _ ParseForSend[(sendProtocol=mtp), invocationMode ! SendError => GOTO sendError]; IF sendProtocol=gv THEN GVSend[unexpandedDLs, invocationMode, netMail, fromField, replyTo, FormatProc ! SendError => GOTO sendError] ELSE MTPSend[invocationMode, netMail, fromField, replyTo, FormatProc ! SendError => GOTO sendError]; intC.composedMessageEdited _ FALSE; house.text.length _ 0; String.AppendString[house.text, "delivered"L]; house.typeface _ italicFace; inD.TextHouseRefresher[house]; house.callable _ FALSE; IF intC.newFormAfterDelivery THEN inD.NewFormCommand[intC.newFormCommandHouse, TRUE]; EXITS sendError => NULL; END; intC.keystream.reset[intC.keystream]; FlushRecipientList[]; END; -- of SendOperation -- sendProtocol: ProtocolType = DetermineSendProtocol[]; 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; t _ gv; SELECT intC.profileSendMode FROM mtp => t _ mtp; gv => NULL; ENDCASE => [] _ PupDefs.EnumeratePupAddresses[intC.profileRegistry, Work ! PupDefs.PupNameTrouble => CONTINUE]; END; userAbortGiven: BOOLEAN; CancelDelivery: PUBLIC PROCEDURE = {userAbortGiven _ TRUE; AbortPoint[]}; AbortPoint: PUBLIC PROCEDURE = -- causes user requested termination. BEGIN NoticeUserAbort[]; IF userAbortGiven THEN ReportError[cancelCode, NIL, 0, 0]; END; -- AbortPoint -- NoticeUserAbort: PUBLIC PROCEDURE = -- checks for user-requested termination. BEGIN OPEN intC; char: CHARACTER; IF userAbortGiven 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]; RETURN END; -- NoticeUserAbort -- invocationMode: SendMode; AskUser: PUBLIC PROCEDURE [exception: exD.Exception, string: STRING] = BEGIN IF exception # exD.nil THEN exD.DisplayException[exception] ELSE IF string # NIL THEN exD.DisplayExceptionString[string]; IF ~inD.Confirm[2] THEN CancelDelivery[]; END; -- AskUser -- RetryThis: PUBLIC PROCEDURE[string: STRING, excep: exD.Exception _ exD.nil] RETURNS [BOOLEAN] = BEGIN 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; -- RetryThis -- ReportProgress: PUBLIC PROCEDURE[exception: exD.Exception, string: STRING, displayCancelMessage: BOOLEAN] = BEGIN exD.DisplayExceptionOrStringOnLine[exception, string, 1]; exD.DisplayExceptionLine[ IF displayCancelMessage THEN exD.wishToCancelDelivery ELSE exD.nil, 2]; END; -- ReportProgress -- ReportError: PUBLIC PROCEDURE[erc: SendErrorType, msg: STRING, start, end: ovD.CharIndex] = BEGIN OPEN intC; 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]; ERROR SendError; END; -- ReportError -- MoveUnderline: PUBLIC PROCEDURE [start, end: ovD.CharIndex] = BEGIN target: POINTER TO inD.TextSelection = @intC.target; Editor.DeUnderlineSelection[selection:target, underline:target]; target^ _ inD.TextSelection[intC.cmTextNbr, start, end, start, char, FALSE]; intC.newTargetSelection _ TRUE; Editor.UnderlineSelection[selection:target, underline:target]; inD.IdleLoop[]; END; InsertReplyToField: PUBLIC PROCEDURE = BEGIN cm: inD.MessageTextNbrPtr = intC.cmTextNbr; message: vmD.ComposeMessagePtr = LOOPHOLE[cm.message]; target: inD.TextSelectionPtr = @intC.target; start, end: ovD.CharIndex; name: STRING _ intC.user.name; replyToString: STRING = "Reply-To: "L; dummyString: STRING = [0]; ph: MailParse.ParseHandle; confirmed: BOOLEAN; ReadChar: PROCEDURE RETURNS [char: CHARACTER] = BEGIN char _ vmD.GetMessageChar[message, start]; start _ start + 1; END; -- of ReadChar -- BackUpChar: PROCEDURE = {start _ start - 1}; 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; BEGIN ph _ MailParse.InitializeParse[ReadChar, BackUpChar]; UNTIL ~MailParse.GetFieldName[ph, dummyString ! MailParse.ParseError => GO TO out] DO MailParse.GetFieldBody[ph, dummyString ! MailParse.ParseError => GO TO out]; ENDLOOP; MailParse.FinalizeParse[ph]; start _ start - 1; EXITS out => {MailParse.FinalizeParse[ph]; RETURN}; END; vmD.StartMessageInsertion[message, start]; [] _ vmD.InsertSubstringInMessage[message, replyToString, 0, replyToString.length]; [] _ vmD.InsertSubstringInMessage[message, name, 0, name.length]; [] _ vmD.InsertMessageChar[message, Ascii.CR]; vmD.StopMessageInsertion[message]; end _ start + replyToString.length + name.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, 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 InsertReplyTo -- inHeader, endOfMessage: BOOLEAN; message: vmD.ComposeMessagePtr; messageSize, currentIndex: ovD.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[MailParse.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]; IF inHeader THEN BEGIN IF ch = Ascii.SP THEN {ch _ Ascii.CR; charsInStock _ 1} ELSE stockChars[charsInStock _ 2] _ Ascii.CR; stockChars[1] _ Ascii.SP; END ELSE IF ch = Ascii.SP THEN ch _ Ascii.CR ELSE stockChars[charsInStock _ 1] _ Ascii.CR; END; ENDCASE; IF inHeader AND ch = Ascii.ControlA THEN ReportError[messageSyntaxError, NIL, currentIndex-1, currentIndex]; END; -- of ReadChar -- BackupChar: PUBLIC PROCEDURE = {currentIndex _ currentIndex - 1}; -- assert: cannot be called immediately after yield a stocked character (!) GetCharPosition: PUBLIC PROCEDURE RETURNS[ovD.CharIndex] = {RETURN[currentIndex]}; END. -- of IntSendCom -- (635)\f1