From d4ede892abaf346c9851115f4a664b737a689626 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 27 Oct 2021 17:53:43 +0200 Subject: [PATCH] mlmmj-send: convert to struct mlmmj_list --- include/mlmmj-send.h | 12 +-- src/mlmmj-send.c | 173 ++++++++++++++++++------------------------- 2 files changed, 78 insertions(+), 107 deletions(-) diff --git a/include/mlmmj-send.h b/include/mlmmj-send.h index 923ad318..47db0bdc 100644 --- a/include/mlmmj-send.h +++ b/include/mlmmj-send.h @@ -24,25 +24,25 @@ #ifndef MMJML_SEND_H #define MMJML_SEND_H +#include "mlmmj.h" + int send_mail(int sockfd, const char *from, const char *to, const char *replyto, char *mailmap, size_t mailsize, - const char *listdir, const char *mlmmjbounce, + struct mlmmj_list *, const char *mlmmjbounce, const char *hdrs, size_t hdrslen, const char *body, size_t bodylen); int send_mail_many_fd(int sockfd, const char *from, const char *replyto, char *mailmap, size_t mailsize, int subfd, - const char *listaddr, const char *listdelim, - const char *archivefilename, const char *listdir, + const char *archivefilename, struct mlmmj_list *list, const char *mlmmjbounce, const char *hdrs, size_t hdrslen, const char *body, size_t bodylen); int send_mail_many_list(int sockfd, const char *from, const char *replyto, char *mailmap, size_t mailsize, struct strlist *addrs, - const char *listaddr, const char *listdelim, - const char *archivefilename, const char *listdir, + const char *archivefilename, struct mlmmj_list *list, const char *mlmmjbounce, const char *hdrs, size_t hdrslen, const char *body, size_t bodylen); int send_mail_verp(int sockfd, struct strlist *addrs, char *mailmap, - size_t mailsize, const char *from, const char *listdir, + size_t mailsize, const char *from, struct mlmmj_list *list, const char *hdrs, size_t hdrslen, const char *body, size_t bodylen, const char *extra); int initsmtp(int *sockfd, const char *relayhost, unsigned short port, const char *heloname); diff --git a/src/mlmmj-send.c b/src/mlmmj-send.c index db076108..82e217d3 100644 --- a/src/mlmmj-send.c +++ b/src/mlmmj-send.c @@ -101,9 +101,8 @@ char *get_index_from_filename(const char *filename) return ret; } -char *bounce_from_adr(const char *recipient, const char *listadr, - const char *listdelim, const char *mailfilename, - const char *listdir) +char *bounce_from_adr(const char *recipient, const char *mailfilename, + struct mlmmj_list *list) { char *bounceaddr, *myrecipient, *mylistadr; char *indexstr, *listdomain, *a = NULL, *mymailfilename; @@ -131,7 +130,7 @@ char *bounce_from_adr(const char *recipient, const char *listadr, if (a) *a = '='; - mylistadr = mystrdup(listadr); + mylistadr = mystrdup(list->listaddr); if (!mylistadr) { myfree(mymailfilename); myfree(myrecipient); @@ -148,10 +147,10 @@ char *bounce_from_adr(const char *recipient, const char *listadr, *listdomain++ = '\0'; /* 11 = "bounces-" + "-" + "@" + NUL */ - len = strlen(mylistadr) + strlen(listdelim) + strlen(myrecipient) + len = strlen(mylistadr) + strlen(list->listdelim) + strlen(myrecipient) + strlen(indexstr) + strlen(listdomain) + 11; - staticbounceaddr = ctrlvalue(listdir, "staticbounceaddr"); + staticbounceaddr = ctrlvalue(list->listdir, "staticbounceaddr"); if (staticbounceaddr) { staticbounceaddr_localpart = genlistname(staticbounceaddr); staticbounceaddr_domain = genlistfqdn(staticbounceaddr); @@ -176,14 +175,14 @@ char *bounce_from_adr(const char *recipient, const char *listadr, if (staticbounceaddr) { snprintf(bounceaddr, len, "%s%s%s-bounces-%s-%s@%s", - staticbounceaddr_localpart, listdelim, mylistadr, + staticbounceaddr_localpart, list->listdelim, mylistadr, indexstr, myrecipient, staticbounceaddr_domain); myfree(staticbounceaddr); myfree(staticbounceaddr_localpart); myfree(staticbounceaddr_domain); } else { - snprintf(bounceaddr, len, "%s%sbounces-%s-%s@%s", mylistadr, listdelim, + snprintf(bounceaddr, len, "%s%sbounces-%s-%s@%s", mylistadr, list->listdelim, indexstr, myrecipient, listdomain); } @@ -195,23 +194,21 @@ char *bounce_from_adr(const char *recipient, const char *listadr, return bounceaddr; } -int bouncemail(const char *listdir, const char *mlmmjbounce, const char *from) +int bouncemail(struct mlmmj_list *list, const char *mlmmjbounce, const char *from) { char *myfrom = mystrdup(from); - char *listdelim = getlistdelim(listdir); char *addr, *num, *c; size_t len; pid_t pid = 0; if((c = strchr(myfrom, '@')) == NULL) { myfree(myfrom); - myfree(listdelim); return 0; /* Success when malformed 'from' */ } *c = '\0'; num = strrchr(myfrom, '-'); num++; - c = strstr(myfrom, listdelim); + c = strstr(myfrom, list->listdelim); myfrom = strchr(c, '-'); myfrom++; len = num - myfrom - 1; @@ -219,8 +216,6 @@ int bouncemail(const char *listdir, const char *mlmmjbounce, const char *from) addr[len] = '\0'; strncpy(addr, myfrom, len); - myfree(listdelim); - pid = fork(); if(pid < 0) { @@ -232,7 +227,7 @@ int bouncemail(const char *listdir, const char *mlmmjbounce, const char *from) return 0; execlp(mlmmjbounce, mlmmjbounce, - "-L", listdir, + "-L", list->listdir, "-a", num, "-n", addr, (char *)NULL); @@ -243,7 +238,7 @@ int bouncemail(const char *listdir, const char *mlmmjbounce, const char *from) int send_mail(int sockfd, const char *from, const char *to, const char *replyto, char *mailmap, size_t mailsize, - const char *listdir, const char *mlmmjbounce, + struct mlmmj_list *list, const char *mlmmjbounce, const char *hdrs, size_t hdrslen, const char *body, size_t bodylen) { @@ -289,7 +284,7 @@ int send_mail(int sockfd, const char *from, const char *to, if(mlmmjbounce && ((reply[0] == '4') || (reply[0] == '5')) && (reply[1] == '5')) { myfree(reply); - return bouncemail(listdir, mlmmjbounce, from); + return bouncemail(list, mlmmjbounce, from); } else { log_error(LOG_ARGS, "Error in RCPT TO. Reply = [%s]", reply); @@ -522,7 +517,7 @@ int endsmtp(int *sockfd) } int send_mail_verp(int sockfd, struct strlist *addrs, char *mailmap, - size_t mailsize, const char *from, const char *listdir, + size_t mailsize, const char *from, struct mlmmj_list *list, const char *hdrs, size_t hdrslen, const char *body, size_t bodylen, const char *verpextra) { @@ -633,8 +628,7 @@ int send_mail_verp(int sockfd, struct strlist *addrs, char *mailmap, int send_mail_many_fd(int sockfd, const char *from, const char *replyto, char *mailmap, size_t mailsize, int subfd, - const char *listaddr, const char *listdelim, - const char *archivefilename, const char *listdir, + const char *archivefilename, struct mlmmj_list *list, const char *mlmmjbounce, const char *hdrs, size_t hdrslen, const char *body, size_t bodylen) { @@ -648,8 +642,8 @@ int send_mail_many_fd(int sockfd, const char *from, const char *replyto, res = getaddrsfromfd(&stl, subfd, maxverprecips); if(stl.count == maxverprecips) { ret = send_mail_many_list(sockfd, from, replyto, - mailmap, mailsize, &stl, listaddr, - listdelim, archivefilename, listdir, + mailmap, mailsize, &stl, + archivefilename, list, mlmmjbounce, hdrs, hdrslen, body, bodylen); for(i = 0; i < stl.count; i++) @@ -662,9 +656,8 @@ int send_mail_many_fd(int sockfd, const char *from, const char *replyto, if(stl.count) { ret = send_mail_many_list(sockfd, from, replyto, mailmap, - mailsize, &stl, listaddr, listdelim, - archivefilename, listdir, mlmmjbounce, - hdrs, hdrslen, body, bodylen); + mailsize, &stl, archivefilename, list, + mlmmjbounce, hdrs, hdrslen, body, bodylen); for(i = 0; i < stl.count; i++) myfree(stl.strs[i]); stl.count = 0; @@ -727,8 +720,7 @@ int requeuemail(const char *listdir, const char *index, struct strlist *addrs, int send_mail_many_list(int sockfd, const char *from, const char *replyto, char *mailmap, size_t mailsize, struct strlist *addrs, - const char *listaddr, const char *listdelim, - const char *archivefilename, const char *listdir, + const char *archivefilename, struct mlmmj_list *list, const char *mlmmjbounce, const char *hdrs, size_t hdrslen, const char *body, size_t bodylen) { @@ -743,31 +735,30 @@ int send_mail_many_list(int sockfd, const char *from, const char *replyto, addr); continue; } - if(gotsigterm && listaddr && archivefilename) { + if(gotsigterm && list->listaddr && archivefilename) { /* we got SIGTERM, so save the addresses and bail */ log_error(LOG_ARGS, "TERM signal received, " "shutting down."); index = get_index_from_filename(archivefilename); - status = requeuemail(listdir, index, addrs, i); + status = requeuemail(list->listdir, index, addrs, i); myfree(index); return status; } if(from) { res = send_mail(sockfd, from, addr, replyto, - mailmap, mailsize, listdir, NULL, + mailmap, mailsize, list, NULL, hdrs, hdrslen, body, bodylen); } else { - bounceaddr = bounce_from_adr(addr, listaddr, listdelim, - archivefilename, listdir); + bounceaddr = bounce_from_adr(addr, archivefilename, list); res = send_mail(sockfd, bounceaddr, addr, replyto, - mailmap, mailsize, listdir, mlmmjbounce, + mailmap, mailsize, list, mlmmjbounce, hdrs, hdrslen, body, bodylen); myfree(bounceaddr); } - if(res && listaddr && archivefilename) { + if(res && list->listaddr && archivefilename) { /* we failed, so save the addresses and bail */ index = get_index_from_filename(archivefilename); - status = requeuemail(listdir, index, addrs, i); + status = requeuemail(list->listdir, index, addrs, i); myfree(index); return status; } @@ -810,14 +801,13 @@ int main(int argc, char **argv) int sockfd = -1, mailfd = 0, opt, mindex = 0, subfd = 0, tmpfd, i; int deletewhensent = 1, sendres = 0, archive = 1, digest = 0; int ctrlarchive, res; - char *listaddr = NULL, *listdelim = NULL; char *mailfilename = NULL, *subfilename = NULL, *omit = NULL; char *replyto = NULL, *bounceaddr = NULL, *to_addr = NULL; char *relayhost = NULL, *archivefilename = NULL, *tmpstr; - char *listctrl = NULL, *subddirname = NULL, *listdir = NULL; + char *listctrl = NULL, *subddirname = NULL; char *mlmmjbounce = NULL, *bindir, *mailmap, *probefile, *a; char *body = NULL, *hdrs = NULL, *memmailsizestr = NULL, *verp = NULL; - char relay[16], *listname, *listfqdn, *verpfrom, *maxverprecipsstr; + char relay[16], *verpfrom, *maxverprecipsstr; char strindex[32], *reply, *strport, *smtphelo, *requeuefilename; ssize_t memmailsize = 0; DIR *subddir; @@ -826,9 +816,11 @@ int main(int argc, char **argv) struct hostent *relayent; uid_t uid; struct strlist stl; + struct mlmmj_list list; unsigned short smtpport = 25; struct sigaction sigact; + mlmmj_list_init(&list); CHECKFULLPATH(argv[0]); log_set_name(argv[0]); @@ -862,7 +854,7 @@ int main(int argc, char **argv) listctrl = optarg; break; case 'L': - listdir = optarg; + list.listdir = optarg; break; case 'm': mailfilename = optarg; @@ -888,15 +880,15 @@ int main(int argc, char **argv) } } - if(mailfilename == NULL || (listdir == NULL && listctrl == NULL)) { + if(mailfilename == NULL || (!mlmmj_list_open(&list) && listctrl == NULL)) { fprintf(stderr, "You have to specify -m and -L or -l\n"); fprintf(stderr, "%s -h for help\n", argv[0]); exit(EXIT_FAILURE); } /* Lets make sure no random user tries to send mail to the list */ - if(listdir) { - if(stat(listdir, &st) == 0) { + if(list.listdir) { + if(stat(list.listdir, &st) == 0) { uid = getuid(); if(uid && uid != st.st_uid) { log_error(LOG_ARGS, @@ -908,7 +900,7 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } } else { - log_error(LOG_ARGS, "Could not stat %s", listdir); + log_error(LOG_ARGS, "Could not stat %s", list.listdir); exit(EXIT_FAILURE); } } @@ -923,22 +915,22 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - if((listctrl[0] == '2' && (listdir == NULL || bounceaddr == NULL))) { + if((listctrl[0] == '2' && (list.listdir == NULL || bounceaddr == NULL))) { fprintf(stderr, "With -l 2 you need -L and -F\n"); exit(EXIT_FAILURE); } - if((listctrl[0] == '7' && listdir == NULL)) { + if((listctrl[0] == '7' && list.listdir == NULL)) { fprintf(stderr, "With -l 7 you need -L\n"); exit(EXIT_FAILURE); } - verp = ctrlvalue(listdir, "verp"); + verp = ctrlvalue(list.listdir, "verp"); if(verp == NULL) - if(statctrl(listdir, "verp") == 1) + if(statctrl(list.listdir, "verp") == 1) verp = mystrdup(""); - maxverprecipsstr = ctrlvalue(listdir, "maxverprecips"); + maxverprecipsstr = ctrlvalue(list.listdir, "maxverprecips"); if(verp && maxverprecipsstr) { maxverprecips = atol(maxverprecipsstr); myfree(maxverprecipsstr); @@ -963,9 +955,6 @@ int main(int argc, char **argv) break; } - if(listdir && listctrl[0] != '5') - listaddr = getlistaddr(listdir); - /* initialize file with mail to send */ if((mailfd = open(mailfilename, O_RDWR)) < 0) { @@ -984,8 +973,8 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - memmailsizestr = ctrlvalue(listdir, "memorymailsize"); - ctrlarchive = statctrl(listdir, "noarchive"); + memmailsizestr = ctrlvalue(list.listdir, "memorymailsize"); + ctrlarchive = statctrl(list.listdir, "noarchive"); if(memmailsizestr) { memmailsize = strtol(memmailsizestr, NULL, 10); myfree(memmailsizestr); @@ -1023,22 +1012,18 @@ int main(int argc, char **argv) } } - if(listdir) - listdelim = getlistdelim(listdir); - switch(listctrl[0]) { case '1': /* A single mail is to be sent, do nothing */ case '5': break; case '2': /* Moderators */ - subfilename = concatstr(2, listdir, "/control/moderators"); + subfilename = concatstr(2, list.listdir, "/control/moderators"); if((subfd = open(subfilename, O_RDONLY)) < 0) { log_error(LOG_ARGS, "Could not open '%s':", subfilename); myfree(hdrs); myfree(body); myfree(subfilename); - myfree(listdelim); /* No moderators is no error. Could be the sysadmin * likes to do it manually. */ @@ -1046,14 +1031,13 @@ int main(int argc, char **argv) } break; case '3': - addtohdr = statctrl(listdir, "addtohdr"); + addtohdr = statctrl(list.listdir, "addtohdr"); case '4': /* sending mails to subfile */ if((subfd = open(subfilename, O_RDONLY)) < 0) { log_error(LOG_ARGS, "Could not open '%s':", subfilename); myfree(hdrs); myfree(body); - myfree(listdelim); exit(EXIT_FAILURE); } break; @@ -1061,27 +1045,26 @@ int main(int argc, char **argv) archive = 0; deletewhensent = 0; archivefilename = mystrdup(mailfilename); - bounceaddr = bounce_from_adr(to_addr, listaddr, listdelim, - archivefilename, listdir); + bounceaddr = bounce_from_adr(to_addr, archivefilename, &list); break; default: /* normal list mail -- now handled when forking */ - addtohdr = statctrl(listdir, "addtohdr"); + addtohdr = statctrl(list.listdir, "addtohdr"); break; } /* initialize the archive filename */ if(archive) { - mindex = incindexfile((const char *)listdir); - len = strlen(listdir) + 9 + 20; + mindex = incindexfile(list.listdir); + len = strlen(list.listdir) + 9 + 20; archivefilename = mymalloc(len); - snprintf(archivefilename, len, "%s/archive/%d", listdir, + snprintf(archivefilename, len, "%s/archive/%d", list.listdir, mindex); } itoa(mindex, strindex); if(!relayhost) { - relayhost = ctrlvalue(listdir, "relayhost"); + relayhost = ctrlvalue(list.listdir, "relayhost"); } if(!relayhost) strncpy(relay, RELAYHOST, sizeof(relay)); @@ -1096,11 +1079,11 @@ int main(int argc, char **argv) strncpy(relay, RELAYHOST, sizeof(relay)); } } - strport = ctrlvalue(listdir, "smtpport"); + strport = ctrlvalue(list.listdir, "smtpport"); if(strport) smtpport = (unsigned short)atol(strport); - if ((smtphelo = ctrlvalue(listdir, "smtphelo")) == NULL) { + if ((smtphelo = ctrlvalue(list.listdir, "smtphelo")) == NULL) { smtphelo = hostnamestr(); } @@ -1109,7 +1092,7 @@ int main(int argc, char **argv) case '6': initsmtp(&sockfd, relay, smtpport, smtphelo); if(send_mail(sockfd, bounceaddr, to_addr, replyto, - mailmap, st.st_size, listdir, NULL, + mailmap, st.st_size, &list, NULL, hdrs, hdrslen, body, bodylen)) { close(sockfd); sockfd = -1; @@ -1167,8 +1150,8 @@ int main(int argc, char **argv) case '2': /* Moderators */ initsmtp(&sockfd, relay, smtpport, smtphelo); if(send_mail_many_fd(sockfd, bounceaddr, NULL, mailmap, - st.st_size, subfd, NULL, NULL, NULL, - listdir, NULL, hdrs, hdrslen, + st.st_size, subfd, NULL, + &list, NULL, hdrs, hdrslen, body, bodylen)) { close(sockfd); sockfd = -1; @@ -1179,8 +1162,7 @@ int main(int argc, char **argv) case '3': /* resending earlier failed mails */ initsmtp(&sockfd, relay, smtpport, smtphelo); if(send_mail_many_fd(sockfd, NULL, NULL, mailmap, st.st_size, - subfd, listaddr, listdelim, mailfilename, - listdir, mlmmjbounce, hdrs, hdrslen, + subfd, mailfilename, &list, mlmmjbounce, hdrs, hdrslen, body, bodylen)) { close(sockfd); sockfd = -1; @@ -1192,8 +1174,7 @@ int main(int argc, char **argv) case '4': /* send mails to owner */ initsmtp(&sockfd, relay, smtpport, smtphelo); if(send_mail_many_fd(sockfd, bounceaddr, NULL, mailmap, - st.st_size, subfd, listaddr, listdelim, - mailfilename, listdir, mlmmjbounce, + st.st_size, subfd, mailfilename, &list, mlmmjbounce, hdrs, hdrslen, body, bodylen)) { close(sockfd); sockfd = -1; @@ -1204,7 +1185,7 @@ int main(int argc, char **argv) case '5': /* bounceprobe - handle relayhost local users bouncing*/ initsmtp(&sockfd, relay, smtpport, smtphelo); if(send_mail(sockfd, bounceaddr, to_addr, replyto, - mailmap, st.st_size, listdir, NULL, + mailmap, st.st_size, &list, NULL, hdrs, hdrslen, body, bodylen)) { close(sockfd); sockfd = -1; @@ -1213,7 +1194,7 @@ int main(int argc, char **argv) a = strchr(tmpstr, '@'); MY_ASSERT(a); *a = '='; - probefile = concatstr(4, listdir, "/bounce/", tmpstr, + probefile = concatstr(4, list.listdir, "/bounce/", tmpstr, "-probe"); unlink(probefile); myfree(probefile); @@ -1229,27 +1210,21 @@ int main(int argc, char **argv) /* fall through */ default: /* normal list mail */ if (!digest) { - subddirname = concatstr(2, listdir, "/subscribers.d/"); + subddirname = concatstr(2, list.listdir, "/subscribers.d/"); } else { - subddirname = concatstr(2, listdir, "/digesters.d/"); + subddirname = concatstr(2, list.listdir, "/digesters.d/"); } if((subddir = opendir(subddirname)) == NULL) { log_error(LOG_ARGS, "Could not opendir(%s)", subddirname); - myfree(listdelim); myfree(subddirname); myfree(hdrs); myfree(body); exit(EXIT_FAILURE); } - listdelim = getlistdelim(listdir); - listname = genlistname(listaddr); - listfqdn = genlistfqdn(listaddr); - verpfrom = concatstr(6, listname, listdelim, "bounces-", - strindex, "@", listfqdn); - myfree(listname); - myfree(listfqdn); + verpfrom = concatstr(6, list.listname, list.listdelim, "bounces-", + strindex, "@", list.listfqdn); if(digest) verp = NULL; @@ -1338,11 +1313,11 @@ int main(int argc, char **argv) mailmap, st.st_size, verpfrom, - listdir, hdrs, + &list, hdrs, hdrslen, body, bodylen, verp); if(sendres) - requeuemail(listdir, + requeuemail(list.listdir, strindex, &stl, 0); } else { @@ -1351,10 +1326,8 @@ int main(int argc, char **argv) NULL, mailmap, st.st_size, &stl, - listaddr, - listdelim, archivefilename, - listdir, + &list, mlmmjbounce, hdrs, hdrslen, body, bodylen); @@ -1378,17 +1351,16 @@ int main(int argc, char **argv) initsmtp(&sockfd, relay, smtpport, smtphelo); if(verp) { sendres = send_mail_verp(sockfd, &stl, mailmap, - st.st_size, verpfrom, listdir, + st.st_size, verpfrom, &list, hdrs, hdrslen, body, bodylen, verp); if(sendres) - requeuemail(listdir, strindex, &stl, + requeuemail(list.listdir, strindex, &stl, 0); } else { sendres = send_mail_many_list(sockfd, NULL, NULL, mailmap, st.st_size, - &stl, listaddr, listdelim, - archivefilename, listdir, + &stl, archivefilename, &list, mlmmjbounce, hdrs, hdrslen, body, bodylen); } @@ -1409,7 +1381,6 @@ int main(int argc, char **argv) break; } - myfree(listdelim); myfree(hdrs); myfree(body); myfree(mlmmjbounce); @@ -1427,10 +1398,10 @@ int main(int argc, char **argv) archivefilename); } } else { - len = strlen(listdir) + 9 + 20 + 9; + len = strlen(list.listdir) + 9 + 20 + 9; requeuefilename = mymalloc(len); snprintf(requeuefilename, len, "%s/requeue/%d", - listdir, mindex); + list.listdir, mindex); if(stat(requeuefilename, &st) < 0) { /* Nothing was requeued and we don't keep * mail for a noarchive list. */ @@ -1438,7 +1409,7 @@ int main(int argc, char **argv) } else { snprintf(requeuefilename, len, "%s/requeue/%d/mailfile", - listdir, mindex); + list.listdir, mindex); if (rename(mailfilename, requeuefilename) < 0) { log_error(LOG_ARGS, "Could not rename(%s,%s);", -- 2.47.3