From: Baptiste Daroussin Date: Thu, 16 Dec 2021 12:37:40 +0000 (+0100) Subject: mail functions: factorize the code and add unit test X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a3d4494f032ed26f094fb0ea79b087944aecf0de;p=thirdparty%2Fmlmmj.git mail functions: factorize the code and add unit test --- diff --git a/include/mail-functions.h b/include/mail-functions.h index 2c17c77e..3ea7a910 100644 --- a/include/mail-functions.h +++ b/include/mail-functions.h @@ -1,4 +1,5 @@ /* Copyright (C) 2002, 2003 Mads Martin Joergensen + * Copyright (C) 2021 Baptiste Daroussin * * $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); diff --git a/src/mail-functions.c b/src/mail-functions.c index 0928ff17..d3872912 100644 --- a/src/mail-functions.c +++ b/src/mail-functions.c @@ -1,4 +1,5 @@ /* Copyright (C) 2002, 2003 Mads Martin Joergensen + * Copyright (C) 2021 Baptiste Daroussin * * $Id$ * @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -37,58 +39,44 @@ #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"); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 483637ec..23c9e853 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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@ diff --git a/tests/mlmmj.c b/tests/mlmmj.c index 8f8479c8..7deaf4d8 100644 --- a/tests/mlmmj.c +++ b/tests/mlmmj.c @@ -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()); }