]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
mail functions: factorize the code and add unit test
authorBaptiste Daroussin <bapt@FreeBSD.org>
Thu, 16 Dec 2021 12:37:40 +0000 (13:37 +0100)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Thu, 16 Dec 2021 12:43:00 +0000 (13:43 +0100)
include/mail-functions.h
src/mail-functions.c
tests/Makefile.am
tests/mlmmj.c

index 2c17c77eec0df7ee084570b735692a1011a3c265..3ea7a910fab43be42754c7e3a7b6f2016cc13cbb 100644 (file)
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
+ * Copyright (C) 2021 Baptiste Daroussin <bapt@FreeBSD.org>
  *
  * $Id$
  *
@@ -32,7 +33,6 @@ int write_helo(int sockfd, const char *hostname);
 int write_ehlo(int sockfd, const char *hostname);
 int write_mail_from(int sockfd, const char *from_addr, const char *extra);
 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);
 char *get_preppedhdrs_from_map(char *mapstart, size_t *hdrslen);
index 0928ff177526d203a17f65702343f47a5796d3fb..d387291213c909910f09ab0564e0686112c63f71 100644 (file)
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
+ * Copyright (C) 2021 Baptiste Daroussin <bapt@FreeBSD.org>
  *
  * $Id$
  *
@@ -24,6 +25,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include "log_error.h"
 #include "memory.h"
 
-int write_ehlo(int sockfd, const char *hostname)
-{
-       size_t bytes_written;
+static int
+write_sock(int sockfd, const char *errstr, const char *fmt, ...) {
+       int bytes_written;
+       va_list ap;
 
-       bytes_written = dprintf(sockfd, "EHLO %s\r\n", hostname);
+       va_start(ap, fmt);
+       bytes_written = vdprintf(sockfd, fmt, ap);
+       va_end(ap);
        if(bytes_written < 0) {
-               log_error(LOG_ARGS, "Could not write EHLO");
+               log_error(LOG_ARGS, "Could not write %s", errstr);
                return errno;
        }
        return 0;
 }
 
-int write_helo(int sockfd, const char *hostname)
+int write_ehlo(int sockfd, const char *hostname)
 {
-       size_t bytes_written;
+       return (write_sock(sockfd, "EHLO", "EHLO %s\r\n", hostname));
+}
 
-       bytes_written = dprintf(sockfd, "HELO %s\r\n", hostname);
-       if(bytes_written < 0) {
-               log_error(LOG_ARGS, "Could not write HELO");
-               return errno;
-       }
-       return 0;
+int write_helo(int sockfd, const char *hostname)
+{
+       return (write_sock(sockfd, "HELO", "HELO %s\r\n", hostname));
 }
 
 int write_mail_from(int sockfd, const char *from_addr, const char *extra)
 {
-       size_t bytes_written;
-
        if(extra && extra[0] != '\0') {
                if(extra[0] == ' ') extra++;
-               bytes_written = dprintf(sockfd, "MAIL FROM:<%s> %s\r\n",
-                   from_addr, extra);
+               return (write_sock(sockfd, "FROM", "MAIL FROM:<%s> %s\r\n",
+                   from_addr, extra));
        } else
-               bytes_written = dprintf(sockfd, "MAIL FROM:<%s>\r\n", from_addr);
-
-       if(bytes_written < 0) {
-               log_error(LOG_ARGS, "Could not write FROM");
-               return errno;
-       }
-       return 0;
+               return (write_sock(sockfd, "FROM", "MAIL FROM:<%s>\r\n", from_addr));
 }
 
 int write_rcpt_to(int sockfd, const char *rcpt_addr)
 {
-       size_t bytes_written;
-
-       bytes_written = dprintf(sockfd, "RCPT TO:<%s>\r\n", rcpt_addr);
-       if(bytes_written < 0) {
-               log_error(LOG_ARGS, "Could not write TO");
-               return errno;
-       }
-       return 0;
+       return (write_sock(sockfd, "TO", "RCPT TO:<%s>\r\n", rcpt_addr));
 }
 
 int write_mailbody_from_map(int sockfd, char *mapstart, size_t size,
@@ -188,65 +176,25 @@ char *get_prepped_mailbody_from_map(char *mapstart, size_t size, size_t *blen)
 
 int write_dot(int sockfd)
 {
-       size_t bytes_written;
-
-       bytes_written = dprintf(sockfd, "\r\n.\r\n");
-       if(bytes_written < 0)
-               return errno;
-
-       return 0;
-}
-
-int write_custom_line(int sockfd, const char *line)
-{
-       size_t bytes_written;
-
-       bytes_written = dprintf(sockfd, "%s\r\n", line);
-       if(bytes_written < 0) {
-               log_error(LOG_ARGS, "Could not write customline");
-               return errno;
-       }
-       return 0;
+       return write_sock(sockfd, "", "\r\n.\r\n");
 }
 
 int write_replyto(int sockfd, const char *replyaddr)
 {
-       size_t bytes_written;
-       
-       bytes_written = dprintf(sockfd, "Reply-To: %s\r\n", replyaddr);
-       if(bytes_written < 0) {
-               log_error(LOG_ARGS, "Could not write Reply-To header");
-               return errno;
-       }
-       return 0;
+       return write_sock(sockfd, "Reply-To header", "Reply-To: %s\r\n", replyaddr);
 }
 
 int write_data(int sockfd)
 {
-       if(write_custom_line(sockfd, "DATA")) {
-               log_error(LOG_ARGS, "Could not write DATA");
-               return errno;
-       }
-
-       return 0;
+       return write_sock(sockfd, "DATA", "DATA\r\n");
 }
 
 int write_quit(int sockfd)
 {
-       if(write_custom_line(sockfd, "QUIT")) {
-               log_error(LOG_ARGS, "Could not write QUIT");
-               return errno;
-       }
-
-       return 0;
+       return write_sock(sockfd, "QUIT", "QUIT\r\n");
 }
 
 int write_rset(int sockfd)
 {
-       if(write_custom_line(sockfd, "RSET")) {
-               log_error(LOG_ARGS, "Could not write RSET");
-               return errno;
-       }
-
-       return 0;
+       return write_sock(sockfd, "RSET", "RSET\r\n");
 }
index 483637ecc5a67ecb46a4d3e23a547b70749a256f..23c9e8533acc32391f9c361fadb4cfc7ca914424 100644 (file)
@@ -6,7 +6,7 @@ mlmmj_SOURCES = mlmmj.c $(top_srcdir)/src/prepstdreply.c $(top_srcdir)/include/p
               $(top_srcdir)/src/memory.c $(top_srcdir)/src/controls.c $(top_srcdir)/src/utils.c \
               $(top_srcdir)/src/strgen.c $(top_srcdir)/src/random-int.c $(top_srcdir)/src/readn.c \
               $(top_srcdir)/src/log_error.c $(top_srcdir)/src/chomp.c $(top_srcdir)/src/mygetline.c $(top_srcdir)/src/unistr.c \
-              $(top_srcdir)/src/mlmmj.c
+              $(top_srcdir)/src/mlmmj.c $(top_srcdir)/src/mail-functions.c
 mlmmj_CFLAGS = @ATF_CFLAGS@ -g -Wall -pedantic -Wsign-compare -DDEFAULTTEXTDIR='"@textlibdir@"' -I$(top_srcdir)/include -DSRCDIR='"@abs_top_srcdir@"'
 mlmmj_LDADD =  @ATF_LIBS@
 
index 8f8479c81824cc5eae0f7fa0a7941d29683a3ffb..7deaf4d89a8961c2a284a3b311bc638e8a754cf3 100644 (file)
@@ -39,6 +39,7 @@
 #include "strgen.h"
 #include "utils.h"
 #include "memory.h"
+#include "mail-functions.h"
 
 ATF_TC(random_int);
 ATF_TC(statctrl);
@@ -49,6 +50,13 @@ ATF_TC(mydirname);
 ATF_TC(mybasename);
 ATF_TC(strtoim);
 ATF_TC(strtotimet);
+ATF_TC(write_ehlo);
+ATF_TC(write_helo);
+ATF_TC(write_dot);
+ATF_TC(write_data);
+ATF_TC(write_quit);
+ATF_TC(write_rset);
+ATF_TC(write_replyto);
 
 ATF_TC_HEAD(random_int, tc) { }
 ATF_TC_HEAD(statctrl, tc) { }
@@ -59,6 +67,13 @@ ATF_TC_HEAD(mydirname, tc) {}
 ATF_TC_HEAD(mybasename, tc) {}
 ATF_TC_HEAD(strtoim, tc) {}
 ATF_TC_HEAD(strtotimet, tc) {}
+ATF_TC_HEAD(write_ehlo, tc) {}
+ATF_TC_HEAD(write_helo, tc) {}
+ATF_TC_HEAD(write_dot, tc) {}
+ATF_TC_HEAD(write_data, tc) {}
+ATF_TC_HEAD(write_quit, tc) {}
+ATF_TC_HEAD(write_rset, tc) {}
+ATF_TC_HEAD(write_replyto, tc) {}
 
 #ifndef NELEM
 #define NELEM(array)    (sizeof(array) / sizeof((array)[0]))
@@ -125,6 +140,7 @@ ATF_TC_BODY(mlmmj_list, tc)
 {
        struct mlmmj_list list;
        mlmmj_list_init(&list);
+       ATF_CHECK(mlmmj_list_open(&list) == false);
        list.dir = "list";
        pid_t p = atf_utils_fork();
        if (p == 0) {
@@ -304,6 +320,76 @@ ATF_TC_BODY(strtotimet, tc)
        ATF_REQUIRE_STREQ(errp, "too large");
 }
 
+ATF_TC_BODY(write_ehlo, tc)
+{
+       ATF_REQUIRE_EQ(write_ehlo(-1, "myname"), EACCES);
+       int fd = open("ehlo.txt", O_CREAT|O_WRONLY, 0644);
+       ATF_REQUIRE_EQ(write_ehlo(fd, "myname"), 0);
+       close(fd);
+       if (!atf_utils_compare_file("ehlo.txt", "EHLO myname\r\n"))
+               atf_tc_fail("Unexpected output");
+}
+
+ATF_TC_BODY(write_helo, tc)
+{
+       ATF_REQUIRE_EQ(write_helo(-1, "myname"), EACCES);
+       int fd = open("helo.txt", O_CREAT|O_WRONLY, 0644);
+       ATF_REQUIRE_EQ(write_helo(fd, "myname"), 0);
+       close(fd);
+       if (!atf_utils_compare_file("helo.txt", "HELO myname\r\n"))
+               atf_tc_fail("Unexpected output");
+}
+
+ATF_TC_BODY(write_dot, tc)
+{
+       ATF_REQUIRE_EQ(write_dot(-1), EACCES);
+       int fd = open("dot.txt", O_CREAT|O_WRONLY, 0644);
+       ATF_REQUIRE_EQ(write_dot(fd), 0);
+       close(fd);
+       if (!atf_utils_compare_file("dot.txt", "\r\n.\r\n"))
+               atf_tc_fail("Unexpected output");
+}
+
+ATF_TC_BODY(write_data, tc)
+{
+       ATF_REQUIRE_EQ(write_data(-1), EACCES);
+       int fd = open("data.txt", O_CREAT|O_WRONLY, 0644);
+       ATF_REQUIRE_EQ(write_data(fd), 0);
+       close(fd);
+       if (!atf_utils_compare_file("data.txt", "DATA\r\n"))
+               atf_tc_fail("Unexpected output");
+}
+
+ATF_TC_BODY(write_quit, tc)
+{
+       ATF_REQUIRE_EQ(write_quit(-1), EACCES);
+       int fd = open("quit.txt", O_CREAT|O_WRONLY, 0644);
+       ATF_REQUIRE_EQ(write_quit(fd), 0);
+       close(fd);
+       if (!atf_utils_compare_file("quit.txt", "QUIT\r\n"))
+               atf_tc_fail("Unexpected output");
+}
+
+ATF_TC_BODY(write_rset, tc)
+{
+       ATF_REQUIRE_EQ(write_rset(-1), EACCES);
+       int fd = open("rset.txt", O_CREAT|O_WRONLY, 0644);
+       ATF_REQUIRE_EQ(write_rset(fd), 0);
+       close(fd);
+       if (!atf_utils_compare_file("rset.txt", "RSET\r\n"))
+               atf_tc_fail("Unexpected output");
+}
+
+ATF_TC_BODY(write_replyto, tc)
+{
+       ATF_REQUIRE_EQ(write_replyto(-1, "toto"), EACCES);
+       int fd = open("replyto.txt", O_CREAT|O_WRONLY, 0644);
+       ATF_REQUIRE_EQ(write_replyto(fd, "toto"), 0);
+       close(fd);
+       if (!atf_utils_compare_file("replyto.txt", "Reply-To: toto\r\n"))
+               atf_tc_fail("Unexpected output");
+}
+
 ATF_TP_ADD_TCS(tp)
 {
        ATF_TP_ADD_TC(tp, random_int);
@@ -315,6 +401,13 @@ ATF_TP_ADD_TCS(tp)
        ATF_TP_ADD_TC(tp, mybasename);
        ATF_TP_ADD_TC(tp, strtoim);
        ATF_TP_ADD_TC(tp, strtotimet);
+       ATF_TP_ADD_TC(tp, write_ehlo);
+       ATF_TP_ADD_TC(tp, write_helo);
+       ATF_TP_ADD_TC(tp, write_dot);
+       ATF_TP_ADD_TC(tp, write_data);
+       ATF_TP_ADD_TC(tp, write_quit);
+       ATF_TP_ADD_TC(tp, write_rset);
+       ATF_TP_ADD_TC(tp, write_replyto);
 
        return (atf_no_error());
 }