commit 4e3d596

shtrophic  ·  2025-01-20 18:43:42 +0000 UTC
parent 7add876
add xs_smtp_request
3 files changed,  +56, -30
M data.c
+19, -29
 1@@ -962,17 +962,20 @@ void notify(snac *snac, const char *type, const char *utype, const char *actor,
 2 
 3         xs *subject = xs_fmt("snac notify for @%s@%s",
 4                     xs_dict_get(snac->config, "uid"), xs_dict_get(srv_config, "host"));
 5-        xs *from    = xs_fmt("snac-daemon <snac-daemon@%s>", xs_dict_get(srv_config, "host"));
 6+        xs *from    = xs_fmt("<snac-daemon@%s>", xs_dict_get(srv_config, "host"));
 7         xs *header  = xs_fmt(
 8-                    "From: %s\n"
 9+                    "From: snac-daemon %s\n"
10                     "To: %s\n"
11                     "Subject: %s\n"
12                     "\n",
13                     from, email, subject);
14 
15-        xs *email_body = xs_fmt("%s%s", header, body);
16+        xs_dict *mailinfo = xs_dict_new();
17+        xs_dict_append(mailinfo, "from", from);
18+        xs_dict_append(mailinfo, "to", email);
19+        xs_dict_append(mailinfo, "body", xs_fmt("%s%s", header, body));
20 
21-        enqueue_email(email_body, 0);
22+        enqueue_email(mailinfo, 0);
23     }
24 
25     /* telegram */
26@@ -2461,32 +2464,19 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
27 }
28 
29 
30-int send_email(const char *msg)
31+int send_email(const xs_dict *mailinfo)
32 /* invoke sendmail with email headers and body in msg */
33 {
34-    FILE *f;
35-    int status;
36-    int fds[2];
37-    pid_t pid;
38-    if (pipe(fds) == -1) return -1;
39-    pid = vfork();
40-    if (pid == -1) return -1;
41-    else if (pid == 0) {
42-        dup2(fds[0], 0);
43-        close(fds[0]);
44-        close(fds[1]);
45-        execl("/usr/sbin/sendmail", "sendmail", "-t", (char *) NULL);
46-        _exit(1);
47-    }
48-    close(fds[0]);
49-    if ((f = fdopen(fds[1], "w")) == NULL) {
50-        close(fds[1]);
51-        return -1;
52-    }
53-    fprintf(f, "%s\n", msg);
54-    fclose(f);
55-    if (waitpid(pid, &status, 0) == -1) return -1;
56-    return status;
57+    const xs_dict *smtp_cfg = xs_dict_get(srv_config, "smtp");
58+    const char 
59+        *url  = xs_dict_get(smtp_cfg, "url"),
60+        *user = xs_dict_get(smtp_cfg, "username"),
61+        *pass = xs_dict_get(smtp_cfg, "password"),
62+        *from = xs_dict_get(mailinfo, "from"),
63+        *to   = xs_dict_get(mailinfo, "to"),
64+        *body = xs_dict_get(mailinfo, "body");
65+
66+    return xs_smtp_request(url, user, pass, from, to, body);
67 }
68 
69 
70@@ -2749,7 +2739,7 @@ void process_queue_item(xs_dict *q_item)
71     else
72     if (strcmp(type, "email") == 0) {
73         /* send this email */
74-        const xs_str *msg = xs_dict_get(q_item, "message");
75+        const xs_dict *msg = xs_dict_get(q_item, "message");
76         int retries = xs_number_get(xs_dict_get(q_item, "retries"));
77 
78         if (!send_email(msg))
M data.c
+1, -1
1@@ -3195,7 +3195,7 @@ void enqueue_output_by_actor(snac *snac, const xs_dict *msg,
2 }
3 
4 
5-void enqueue_email(const xs_str *msg, int retries)
6+void enqueue_email(const xs_dict *msg, int retries)
7 /* enqueues an email message to be sent */
8 {
9     xs *qmsg   = _new_qmsg("email", msg, retries);
+36, -0
 1@@ -9,6 +9,9 @@ xs_dict *xs_http_request(const char *method, const char *url,
 2                         const xs_str *body, int b_size, int *status,
 3                         xs_str **payload, int *p_size, int timeout);
 4 
 5+int xs_smtp_request(const char *url, const char *user, const char *pass,
 6+                   const char *from, const char *to, const xs_str *body);
 7+
 8 #ifdef XS_IMPLEMENTATION
 9 
10 #include <curl/curl.h>
11@@ -194,6 +197,39 @@ xs_dict *xs_http_request(const char *method, const char *url,
12     return response;
13 }
14 
15+int xs_smtp_request(const char *url, const char *user, const char *pass,
16+                   const char *from, const char *to, const xs_str *body)
17+{
18+    CURL *curl;
19+    CURLcode res = CURLE_OK;
20+    struct curl_slist *rcpt = NULL;
21+    struct _payload_data pd = {
22+        .data = (char *)body,
23+        .size = xs_size(body),
24+        .offset = 0
25+    };
26+
27+    curl = curl_easy_init();
28+
29+    curl_easy_setopt(curl, CURLOPT_URL, url);
30+    curl_easy_setopt(curl, CURLOPT_USERNAME, user);
31+    curl_easy_setopt(curl, CURLOPT_PASSWORD, pass);
32+    
33+    curl_easy_setopt(curl, CURLOPT_MAIL_FROM, from);
34+    curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt = curl_slist_append(rcpt, to));
35+
36+    curl_easy_setopt(curl, CURLOPT_READDATA, &pd);
37+    curl_easy_setopt(curl, CURLOPT_READFUNCTION, _post_callback);
38+    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
39+
40+    res = curl_easy_perform(curl);
41+    
42+    curl_slist_free_all(rcpt);
43+    curl_easy_cleanup(curl);
44+
45+    return (int)res;
46+}
47+
48 #endif /* XS_IMPLEMENTATION */
49 
50 #endif /* _XS_CURL_H */