From dd8026041f324f9dcb9396e59e6c906706dac4c0 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 8 Mar 2023 11:37:49 +0100 Subject: [PATCH] mlmmj-maintd: pass the mailfile to resend via file descriptor This reduces the memory allocation and also plug some memory leak --- src/mlmmj-maintd.c | 47 +++++++++++++++++++------------------------ src/mlmmj-send.c | 10 +++++++-- tests/mlmmj-maintd.sh | 12 +++++------ 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/mlmmj-maintd.c b/src/mlmmj-maintd.c index 31e89f24..f0c6121d 100644 --- a/src/mlmmj-maintd.c +++ b/src/mlmmj-maintd.c @@ -261,7 +261,7 @@ resend_requeue(struct ml *ml, const char *mlmmjsend, int logfd) { DIR *queuedir; struct dirent *dp; - char *archivefilename, *subfilename, *subnewname; + char *archivefilename, *subnewname; struct stat st; time_t t; bool fromrequeuedir; @@ -289,53 +289,48 @@ resend_requeue(struct ml *ml, const char *mlmmjsend, int logfd) unlinkat(fd, dp->d_name, AT_REMOVEDIR) == 0) continue; + int requeuefd = openat(fd, dp->d_name, O_DIRECTORY); + xasprintf(&archivefilename, "archive/%s", dp->d_name); + int archivefd = openat(ml->fd, archivefilename, O_RDONLY); + free(archivefilename); /* Explicitly initialize for each mail we examine */ fromrequeuedir = false; - if(faccessat(ml->fd, archivefilename, F_OK, 0) < 0) { - /* Might be it's just not moved to the archive - * yet because it's still getting sent, so just - * continue - */ - free(archivefilename); - + if (archivefd == -1) { /* If the list is set not to archive we want to look * in /requeue/ for a mailfile */ - xasprintf(&archivefilename, "requeue/%s/mailfile", - dp->d_name); - if(faccessat(ml->fd, archivefilename, F_OK, 0) < 0) { - free(archivefilename); + archivefd = openat(requeuefd, "mailfile", O_RDONLY); + if (archivefd == -1) { + close(requeuefd); continue; } fromrequeuedir = true; } - xasprintf(&subfilename, "%s/subscribers", dp->d_name); - if(faccessat(fd, subfilename, F_OK, 0) < 0) { - if (fromrequeuedir) { - if (unlinkat(ml->fd, archivefilename, 0) == -1) { - log(" - Cound not remove %s: %s\n", - archivefilename, strerror(errno)); - ret = false; - } + int subfd = openat(requeuefd, "subscribers", O_RDONLY); + if (subfd == -1) { + if (fromrequeuedir && unlinkat(requeuefd, "mailfile", 0) == -1) { + log(" - Cound not remove requeue/%s/mailfile: %s\n", + dp->d_name, strerror(errno)); + ret = false; } - free(archivefilename); - free(subfilename); + close(requeuefd); continue; } - - int subfd = openat(fd, subfilename, O_RDONLY); - unlinkat(fd, subfilename, 0); + unlinkat(requeuefd, "subscribers", 0); xasprintf(&subnewname, "%d", subfd); + xasprintf(&archivefilename, "%d", archivefd); exec_and_wait(mlmmjsend, "-l", "3", "-L", ml->dir, "-m", archivefilename, "-s", subnewname, "-a", "-D", NULL); free(subnewname); + free(archivefilename); if (fromrequeuedir) - unlinkat(ml->fd, archivefilename, 0); + unlinkat(requeuefd, "mailfile", 0); close(subfd); + close(requeuefd); } closedir(queuedir); diff --git a/src/mlmmj-send.c b/src/mlmmj-send.c index b601573f..0536659a 100644 --- a/src/mlmmj-send.c +++ b/src/mlmmj-send.c @@ -486,8 +486,14 @@ int main(int argc, char **argv) /* initialize file with mail to send */ - if ((mailfd = open(mailfilename, O_RDWR)) == -1 || - !lock(mailfd, true)) { + mailfd = strtoim(mailfilename, 0, INT_MAX, &errp); + if (errp == NULL) { + /* cannot delete a mail sent from file descriptor */ + deletewhensent = false; + } + + if (errp != NULL && ((mailfd = open(mailfilename, O_RDWR)) == -1 || + !lock(mailfd, true))) { if (ml.dir != NULL && mailfd == -1) { if ((mailfd = openat(ml.fd, mailfilename, O_RDWR)) == -1 || !lock(mailfd, true)) { diff --git a/tests/mlmmj-maintd.sh b/tests/mlmmj-maintd.sh index e0deb63f..54fd4598 100755 --- a/tests/mlmmj-maintd.sh +++ b/tests/mlmmj-maintd.sh @@ -780,7 +780,7 @@ EOF atf_check $mlmmjmaintd -L list -F cat > expect1.txt < +MAIL FROM: RCPT TO: DATA From: plop @@ -792,7 +792,7 @@ body . QUIT EOF - atf_check -o file:expect1.txt sed -e "/^Message-ID:/d; /^Date:/d; s/confsub-.*@mlmmjtest/confsub-@mlmmjtest/g" mail-1.txt + atf_check -o file:expect1.txt sed -e "/^Message-ID:/d; /^Date:/d; s/bounces-.*-/bounces-/g" mail-1.txt atf_check -s exit:1 test -f mail-2.txt atf_check -s exit:1 test -f list/requeue/3/mailfile cat > list/archive/1 < expect2.txt < +MAIL FROM: RCPT TO: DATA From: plop @@ -815,7 +815,7 @@ Subject: test body . -MAIL FROM: +MAIL FROM: RCPT TO: DATA From: plop @@ -825,7 +825,7 @@ Subject: test body . -MAIL FROM: +MAIL FROM: RCPT TO: DATA From: plop @@ -838,7 +838,7 @@ body QUIT EOF atf_check $mlmmjmaintd -L list -F - atf_check -o file:expect2.txt sed -e "/^Message-ID:/d; /^Date:/d; s/confsub-.*@mlmmjtest/confsub-@mlmmjtest/g" mail-2.txt + atf_check -o file:expect2.txt sed -e "/^Message-ID:/d; /^Date:/d; s/bounces-.*-/bounces-/g" mail-2.txt atf_check -s exit:1 test -f mail-4.txt atf_check -s exit:0 test -f list/archive/1 } -- 2.47.2