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
ROPE: TYPE = Rope.ROPE;
RName: TYPE = GVBasics.RName;
SendMessageInfo: TYPE = SimpleMailer.SendMessageInfo;
defaultRegistry: ROPE ← DefaultRemoteNames.Get[].registry;
SendMessage:
PUBLIC PROC [from:
ROPE ←
NIL, returnTo: RName ←
NIL, to, cc:
LIST
OF RName ←
NIL, subject:
ROPE ←
NIL, otherHeader:
ROPE ←
NIL, body:
ROPE ←
NIL, validate:
BOOL ←
TRUE, sendIfValidateFails:
BOOL ←
FALSE]
RETURNS [sent:
BOOL, info: SendMessageInfo] ~ {
NoticeInvalidRecipient:
PROC [rNumber:
INT, rName: RName] = {
state ← $invalidRecipient;
};
h: GVSend.Handle = GVSend.Create[];
state: SendMessageInfo;
aborted: BOOL ← FALSE;
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: ROPE ← NIL;
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.