]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
mail-functions: allow to send an email from a FILE *
authorBaptiste Daroussin <bapt@FreeBSD.org>
Tue, 14 Feb 2023 10:52:26 +0000 (11:52 +0100)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Tue, 14 Feb 2023 10:52:26 +0000 (11:52 +0100)
include/mail-functions.h
src/mail-functions.c
src/send_mail.c
tests/mlmmj.c

index f01dd0e7106ccba4c724bc969a7031d61f5d2b42..221b3bb3c55056efccf7af647156e064acce3aa8 100644 (file)
@@ -35,6 +35,7 @@ int write_rcpt_to(int sockfd, const char *rcpt_addr);
 int write_custom_line(int sockfd, const char *line);
 int write_mailbody_from_map(int sockfd, char *mailmap, size_t mailsize,
                            const char *tohdr);
+void write_mailbody(int sockfd, FILE *fp, const char *tohdr);
 char *get_preppedhdrs_from_map(char *mapstart, size_t maplen, size_t *hdrslen);
 char *get_prepped_mailbody_from_map(char *mapstart, size_t size,
                                    size_t *bodylen);
index f0bd834290a3c3c783bb8d456259673720babf55..215aead26d62c3dc1c83df6c85e2d36fb8400cef 100644 (file)
@@ -31,6 +31,7 @@
 #include <arpa/inet.h>
 #include <string.h>
 #include <fcntl.h>
+#include <stdbool.h>
 
 #include "xmalloc.h"
 #include "mail-functions.h"
@@ -117,6 +118,26 @@ int write_mailbody_from_map(int sockfd, char *mapstart, size_t size,
        return 0;
 }
 
+void
+write_mailbody(int sockfd, FILE *fp, const char *tohdr)
+{
+       int c, next;
+       bool addhdr = true;
+       while ((c = fgetc(fp)) != EOF) {
+               if (c != '\n') {
+                       dprintf(sockfd, "%c", c);
+                       continue;
+               }
+               next = fgetc(fp);
+               dprintf(sockfd, "\r\n");
+               if (addhdr && tohdr != NULL && next == '\n') {
+                       dprintf(sockfd, "To: %s\r\n", tohdr);
+                       addhdr = false;
+               }
+               ungetc(next, fp);
+       }
+}
+
 char *get_preppedhdrs_from_map(char *mapstart, size_t maplen, size_t *hlen)
 {
        char *cur, *next, *endhdrs, *retstr, *r;
index eee1df90e0aee8422262a76b9664d2705148e8b2..f2aa80e8fd45e97d53c8c79912564d8997566beb 100644 (file)
@@ -345,23 +345,7 @@ send_mail(int sockfd, struct mail *mail, int listfd, int ctrlfd, bool bounce)
                        return retval;
                }
        } else if (mail->fp != NULL) {
-               int c, next;
-               bool addhdr = true;
-               while ((c = fgetc(mail->fp)) != EOF) {
-                       if (c != '\n') {
-                               dprintf(sockfd, "%c", c);
-                               continue;
-                       }
-                       next = fgetc(mail->fp);
-                       if (next == '.') {
-                               dprintf(sockfd, "\r\n.");
-                       }
-                       if (addhdr && mail->addtohdr && next == '\n') {
-                               dprintf(sockfd, "To: %s\r\n", mail->to);
-                               addhdr = false;
-                       }
-                       ungetc(c, mail->fp);
-               }
+               write_mailbody(sockfd, mail->fp, mail->addtohdr ? mail->to : NULL);
        } else {
                retval = write_mailbody_from_map(sockfd, mail->map, mail->size,
                    mail->addtohdr ? mail->to : NULL);
index d034a1912ef5c7d779babeac17017068f59d433c..a6558f09bcc19fe82c69831c33782594911b0adc 100644 (file)
@@ -86,6 +86,7 @@ ATF_TC_WITHOUT_HEAD(write_replyto);
 ATF_TC_WITHOUT_HEAD(write_rcpt_to);
 ATF_TC_WITHOUT_HEAD(write_mail_from);
 ATF_TC_WITHOUT_HEAD(write_mailbody_from_map);
+ATF_TC_WITHOUT_HEAD(write_mailbody);
 ATF_TC_WITHOUT_HEAD(strtotimet);
 ATF_TC_WITHOUT_HEAD(decode_qp);
 ATF_TC_WITHOUT_HEAD(parse_lastdigest);
@@ -662,6 +663,88 @@ ATF_TC_BODY(write_mailbody_from_map, tc)
        close(fd1);
 }
 
+ATF_TC_BODY(write_mailbody, tc)
+{
+       /* no new lines: ignore */
+       FILE *fp;
+       atf_utils_create_file("myemailbody.txt", "line");
+       fp = fopen("myemailbody.txt", "r");
+       ATF_REQUIRE(fp != NULL);
+       int fd = open("out.txt", O_CREAT|O_WRONLY, 0644);
+       write_mailbody(fd, fp, "test@plop.meh");
+       fclose(fp);
+       close(fd);
+       if (!atf_utils_compare_file("out.txt", "line")) {
+               atf_utils_cat_file("out.txt", ">");
+               atf_tc_fail("Unexpected output (no new lines case)");
+       }
+
+       /* With a single new line */
+       atf_utils_create_file("myemailbody.txt", "line\n");
+       fp = fopen("myemailbody.txt", "r");
+       ATF_REQUIRE(fp != NULL);
+       fd = open("out.txt", O_CREAT|O_TRUNC|O_WRONLY, 0644);
+       write_mailbody(fd, fp, "test@plop.meh");
+       close(fd);
+       fclose(fp);
+       if (!atf_utils_compare_file("out.txt", "line\r\n")) {
+               atf_utils_cat_file("out.txt", ">");
+               atf_tc_fail("Unexpected output (a single new line)");
+       }
+
+       /* With a single new line with a . */
+       atf_utils_create_file("myemailbody.txt", "line\n.");
+       fp = fopen("myemailbody.txt", "r");
+       ATF_REQUIRE(fp != NULL);
+       fd = open("out.txt", O_CREAT|O_TRUNC|O_WRONLY, 0644);
+       write_mailbody(fd, fp,  "test@plop.meh");
+       close(fd);
+       fclose(fp);
+       if (!atf_utils_compare_file("out.txt", "line\r\n.")) {
+               atf_utils_cat_file("out.txt", ">");
+               atf_tc_fail("Unexpected output (single new line with a .)");
+       }
+
+       /* With a single new line, 2 new lines */
+       atf_utils_create_file("myemailbody.txt", "line\n\n");
+       fp = fopen("myemailbody.txt", "r");
+       ATF_REQUIRE(fp != NULL);
+       fd = open("out.txt", O_CREAT|O_TRUNC|O_WRONLY, 0644);
+       write_mailbody(fd, fp,  "test@plop.meh");
+       close(fd);
+       fclose(fp);
+       if (!atf_utils_compare_file("out.txt", "line\r\nTo: test@plop.meh\r\n\r\n")) {
+               atf_utils_cat_file("out.txt", ">");
+               atf_tc_fail("Unexpected output (a single new line, 2 new lines)");
+       }
+
+       /* With a single 2 lines separated by 2 new lines*/
+       atf_utils_create_file("myemailbody.txt", "line\n\nline2\n\n");
+       fp = fopen("myemailbody.txt", "r");
+       ATF_REQUIRE(fp != NULL);
+       fd = open("out.txt", O_CREAT|O_TRUNC|O_WRONLY, 0644);
+       write_mailbody(fd, fp,  "test@plop.meh");
+       close(fd);
+       fclose(fp);
+       if (!atf_utils_compare_file("out.txt", "line\r\nTo: test@plop.meh\r\n\r\nline2\r\n\r\n")) {
+               atf_utils_cat_file("out.txt", ">");
+               atf_tc_fail("Unexpected output (2 lines separated by 2 new lines)");
+       }
+
+       /* No to header */
+       atf_utils_create_file("myemailbody.txt", "line\n\nline2\n\n");
+       fp = fopen("myemailbody.txt", "r");
+       ATF_REQUIRE(fp != NULL);
+       fd = open("out.txt", O_CREAT|O_TRUNC|O_WRONLY, 0644);
+       write_mailbody(fd, fp,  NULL);
+       close(fd);
+       fclose(fp);
+       if (!atf_utils_compare_file("out.txt", "line\r\n\r\nline2\r\n\r\n")) {
+               atf_utils_cat_file("out.txt", ">");
+               atf_tc_fail("Unexpected output (no to header)");
+       }
+}
+
 ATF_TC_BODY(strtotimet, tc)
 {
        const char *errp;
@@ -1377,7 +1460,6 @@ ATF_TC_BODY(send_mail_8, tc)
 {
        int smtppipe[2];
        struct mail mail = {};
-       struct stat st;
        ATF_REQUIRE(socketpair(AF_UNIX, SOCK_STREAM, 0, smtppipe) >= 0);
        pid_t p = atf_utils_fork();
        if (p == 0) {
@@ -1400,10 +1482,7 @@ ATF_TC_BODY(send_mail_8, tc)
        mail.from = "test@meh";
        mail.inmem = false;
        atf_utils_create_file("mymail.txt", "headers\n\nbody\n");
-       int fd = open("mymail.txt", O_RDONLY);
-       fstat(fd, &st);
-       mail.size = st.st_size;
-       mail.map = mmap(0, mail.size, PROT_READ, MAP_SHARED, fd, 0);
+       mail.fp = fopen("mymail.txt", "r");
        mail.addtohdr = true;
        ATF_REQUIRE_EQ(send_mail(smtppipe[1], &mail, -1, -1, false), 0);
        atf_utils_wait(p, 0, "MAIL FROM:<test@meh>\r\nRCPT TO:<plop@meh>\r\nDATA\r\nheaders\r\nTo: plop@meh\r\n\r\nbody\r\n\r\n.\r\n", "");
@@ -2379,6 +2458,7 @@ ATF_TP_ADD_TCS(tp)
        ATF_TP_ADD_TC(tp, write_rcpt_to);
        ATF_TP_ADD_TC(tp, write_mail_from);
        ATF_TP_ADD_TC(tp, write_mailbody_from_map);
+       ATF_TP_ADD_TC(tp, write_mailbody);
        ATF_TP_ADD_TC(tp, strtotimet);
        ATF_TP_ADD_TC(tp, decode_qp);
        ATF_TP_ADD_TC(tp, parse_lastdigest);