SimpleMailerImpl.mesa
Carl Hauser, August 5, 1986 9:42:28 am PDT
DIRECTORY
DefaultRemoteNames USING [Get],
GVBasics USING [RName],
GVSend USING [Abort, AddRecipient, AddToItem, CheckValidity, Create, Handle, Send, SendFailed, StartItem, StartSend],
IO USING [PutFR, time, rope],
Rope USING [Cat, Concat, Find, Flatten, IsEmpty, ROPE],
SimpleMailer USING [SendMessageInfo],
UserCredentials USING [Get];
SimpleMailerImpl: CEDAR PROGRAM
IMPORTS DefaultRemoteNames, GVSend, IO, Rope, UserCredentials
EXPORTS SimpleMailer
~ BEGIN
ROPE: TYPE = Rope.ROPE;
RName: TYPE = GVBasics.RName;
SendMessageInfo: TYPE = SimpleMailer.SendMessageInfo;
defaultRegistry: ROPE ← DefaultRemoteNames.Get[].registry;
SendMessage: PUBLIC PROC [from: ROPENIL, returnTo: RName ← NIL, to, cc: LIST OF RName ← NIL, subject: ROPENIL, otherHeader: ROPENIL, body: ROPENIL, validate: BOOLTRUE, sendIfValidateFails: BOOLFALSE] RETURNS [sent: BOOL, info: SendMessageInfo] ~ {
NoticeInvalidRecipient: PROC [rNumber: INT, rName: RName] = {
state ← $invalidRecipient;
};
h: GVSend.Handle = GVSend.Create[];
state: SendMessageInfo;
aborted: BOOLFALSE;
sender, senderPwd: ROPE;
[sender, senderPwd] ← UserCredentials.Get[];
IF from = NIL THEN from ← sender;
DO
ENABLE GVSend.SendFailed => IF notDelivered THEN LOOP ELSE EXIT;
SELECT h.StartSend[senderPwd, sender, returnTo, validate] FROM
ok => state ← $ok;
badPwd => { state ← $badPwd; EXIT };
badSender => { state ← $badSender; EXIT };
badReturnTo => { state ← $badReturnTo; EXIT };
allDown => { state ← $allDown; EXIT };
ENDCASE => ERROR;
AddRecipients[h, to];
AddRecipients[h, cc];
IF validate THEN {
IF h.CheckValidity[NoticeInvalidRecipient] = 0 THEN state ← $noValidRecipients;
IF NOT sendIfValidateFails AND state # $ok THEN {
h.Abort[]; aborted ← TRUE; EXIT;
};
};
h.StartItem[Text];
h.AddToItem[ConsMessage[sender, subject, from, to, cc, otherHeader, body]];
h.Send[];
EXIT;
ENDLOOP;
RETURN [state IN [$ok .. $noValidRecipients] AND NOT aborted, state]
};
AddRecipients: PROC [h: GVSend.Handle, recipients: LIST OF RName] = {
FOR r: LIST OF RName ← recipients, r.rest UNTIL r = NIL DO
recip: ROPE ← r.first;
IF Rope.Find[s1: recip, s2: "."] = -1 THEN recip ← Rope.Cat[recip, ".", defaultRegistry];
h.AddRecipient[recipient: recip];
ENDLOOP;
};
ConsMessage: PROC [
sender: RName, subject, from: ROPE, to, cc: LIST OF RName, otherHeader, body: ROPE]
RETURNS [ROPE] = {
dateRope: ROPE = ConsField["Date", IO.PutFR["%g", IO.time[]]];
senderRope: ROPE = IF from # sender THEN ConsField["Sender", sender] ELSE NIL;
subjectRope: ROPE = ConsField["Subject", subject];
fromRope: ROPE = ConsField["From", from];
toRope: ROPE = ConsListField["To", to];
ccRope: ROPE = IF cc # NIL THEN ConsListField["cc", cc] ELSE NIL;
header: ROPE = Rope.Cat[dateRope, senderRope, subjectRope, Rope.Cat[fromRope, toRope, ccRope]];
RETURN[Rope.Cat[header, otherHeader, "\n", body]];
};
ConsField: PROC [fieldName, fieldContents: ROPE] RETURNS [ROPE] = {
RETURN [IF fieldContents.IsEmpty[] THEN NIL
ELSE IO.PutFR["%g: %g\n", IO.rope[fieldName], IO.rope[fieldContents]]];
};
ConsListField: PROC [fieldName: ROPE, fieldContents: LIST OF ROPE] RETURNS [ROPE]= {
result: ROPENIL;
IF fieldContents # NIL THEN {
result ← fieldName.Concat[": "];
DO
result ← result.Concat[fieldContents.first];
fieldContents ← fieldContents.rest;
IF fieldContents = NIL THEN EXIT;
result ← result.Concat[", "];
ENDLOOP;
result ← result.Concat["\n"];
};
RETURN [result.Flatten[]];
};
END.