From: Baptiste Daroussin Date: Sat, 14 Mar 2026 21:35:04 +0000 (+0100) Subject: subrelease: finish the implementation started in 2012 X-Git-Tag: RELEASE_1_8_0~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=545b6b03bed8a975dca64ddc254185d71e69a2cc;p=thirdparty%2Fmlmmj.git subrelease: finish the implementation started in 2012 --- diff --git a/README.listtexts.md b/README.listtexts.md index 5f103d7f..df895ea3 100644 --- a/README.listtexts.md +++ b/README.listtexts.md @@ -464,6 +464,11 @@ Unformatted substitutions that are available are: listname+subscribe-digest@domain.tld DEPRECATED: use $list+$subscribe-digest@$domain$ instead +- $digestsubreleaseaddr$ + (available only in deny-post-subonlypost and wait-post-modnonsubposts) + the address to which to send mail to simultaneously subscribe to the digest + version of the list and release the post in question + - $digestthreads$ (available only in digest) the formatted list of threads included in the digest @@ -508,6 +513,11 @@ Unformatted substitutions that are available are: listname+subscribe@domain.tld DEPRECATED: use $list+$subscribe@$domain$ instead +- $listsubreleaseaddr$ + (available only in deny-post-subonlypost and wait-post-modnonsubposts) + the address to which to send mail to simultaneously subscribe to the list + and release the post in question + - $listunsubaddr$ listname+unsubscribe@domain.tld DEPRECATED: use $list+$unsubscribe@$domain$ instead @@ -536,6 +546,11 @@ Unformatted substitutions that are available are: listname+subscribe-nomail@domain.tld DEPRECATED: use $list+$subscribe-nomail@$domain$ instead +- $nomailsubreleaseaddr$ + (available only in deny-post-subonlypost and wait-post-modnonsubposts) + the address to which to send mail to simultaneously subscribe to the no-mail + version of the list and release the post in question + - $nomailunsubaddr$ listname+unsubscribe-nomail@domain.tld DEPRECATED: use $list+$unsubscribe-nomail@$domain$ instead diff --git a/include/listcontrol.h b/include/listcontrol.h index 98d53ce7..c559c584 100644 --- a/include/listcontrol.h +++ b/include/listcontrol.h @@ -42,6 +42,9 @@ enum ctrl_e { CTRL_CONFUNSUB_NOMAIL, CTRL_CONFUNSUB, CTRL_BOUNCES, + CTRL_SUBRELEASE, + CTRL_DIGESTSUBRELEASE, + CTRL_NOMAILSUBRELEASE, CTRL_RELEASE, CTRL_REJECT, CTRL_PERMIT, diff --git a/src/listcontrol.c b/src/listcontrol.c index 96cbb1c8..6ea9e013 100644 --- a/src/listcontrol.c +++ b/src/listcontrol.c @@ -72,6 +72,9 @@ static struct ctrl_command ctrl_commands[] = { { "confunsub-nomail", true , false, true , CTRL_CONFUNSUB_NOMAIL }, { "confunsub", true , false, true , CTRL_CONFUNSUB }, { "bounces", true , true , true , CTRL_BOUNCES }, + { "subrelease", true , true , true , CTRL_SUBRELEASE }, + { "digestsubrelease", true , true , true , CTRL_DIGESTSUBRELEASE }, + { "nomailsubrelease", true , true , true , CTRL_NOMAILSUBRELEASE }, { "release", true , true , true , CTRL_RELEASE }, { "reject", true , true , true , CTRL_REJECT }, { "permit", true , true , true , CTRL_PERMIT }, @@ -400,6 +403,20 @@ int listcontrol(strlist *fromemails, struct ml *ml, const char *controlstr, exit(EXIT_SUCCESS); break; + /* listname+subrelease-COOKIE@domain.tld */ + case CTRL_SUBRELEASE: + ts = SUB_NORMAL; + /* fallthrough */ + /* listname+digestsubrelease-COOKIE@domain.tld */ + case CTRL_DIGESTSUBRELEASE: + if (ts == SUB_NONE) + ts = SUB_DIGEST; + /* fallthrough */ + /* listname+nomailsubrelease-COOKIE@domain.tld */ + case CTRL_NOMAILSUBRELEASE: + if (ts == SUB_NONE) + ts = SUB_NOMAIL; + /* fallthrough */ /* listname+release-COOKIE@domain.tld */ case CTRL_RELEASE: /* DEPRECATED: listname+moderate-COOKIE@domain.tld */ @@ -437,8 +454,15 @@ int listcontrol(strlist *fromemails, struct ml *ml, const char *controlstr, unlinkat(ml->fd, omitfilename, 0); free(omitfilename); free(moderatefilename); - bool autosubscribe = statctrl(ml->ctrlfd, "autosubscribe"); - if (autosubscribe) { + if (ts != SUB_NONE) { + /* subrelease: always subscribe with requested type */ + int mfd = openat(ml->fd, sendfilename, O_RDONLY); + if (mfd == -1) { + free(sendfilename); + return (-1); + } + autosubscribe_sender(ml, mfd, ts); + } else if (statctrl(ml->ctrlfd, "autosubscribe")) { int mfd = openat(ml->fd, sendfilename, O_RDONLY); if (mfd == -1) { free(sendfilename); diff --git a/src/mlmmj-process.c b/src/mlmmj-process.c index 741359df..099f12dd 100644 --- a/src/mlmmj-process.c +++ b/src/mlmmj-process.c @@ -222,7 +222,31 @@ static void newmoderated(struct ml *ml, const char *mailfilename, register_formatted(txt, "moderators", rewind_memory_lines, get_memory_line, mls); register_originalmail(txt, mailfilename); - qfname = prepstdreply(txt, ml, "$listowner$", efromsender, NULL); + + char *subreplyto = NULL; + if (modreason == MODNONSUBPOSTS && + !statctrl(ml->ctrlfd, "closedlist") && + !statctrl(ml->ctrlfd, "closedlistsub")) { + char *listsubreleaseaddr; + char *digestsubreleaseaddr; + char *nomailsubreleaseaddr; + gen_addr_cookie(listsubreleaseaddr, ml, + "subrelease-", mailbasename); + gen_addr_cookie(digestsubreleaseaddr, ml, + "digestsubrelease-", mailbasename); + gen_addr_cookie(nomailsubreleaseaddr, ml, + "nomailsubrelease-", mailbasename); + register_unformatted(txt, + "listsubreleaseaddr", listsubreleaseaddr); + register_unformatted(txt, + "digestsubreleaseaddr", digestsubreleaseaddr); + register_unformatted(txt, + "nomailsubreleaseaddr", nomailsubreleaseaddr); + subreplyto = listsubreleaseaddr; + } + + qfname = prepstdreply(txt, ml, "$listowner$", efromsender, + subreplyto); MY_ASSERT(qfname); close_text(txt); @@ -817,11 +841,52 @@ int main(int argc, char **argv) register_unformatted(txt, "subject", subject); register_unformatted(txt, "posteraddr", testaddr); register_originalmail(txt, donemailname); + + bool closedlist = statctrl(ml.ctrlfd, "closedlist"); + bool closedlistsub = statctrl(ml.ctrlfd, "closedlistsub"); + char *subreplyto = NULL; + + if (subonlypost && !closedlist && !closedlistsub) { + char *modname; + char *listsubreleaseaddr; + char *digestsubreleaseaddr; + char *nomailsubreleaseaddr; + xasprintf(&modname, "%s/moderation/%s", + ml.dir, randomstr); + if (rename(donemailname, modname) != 0) { + log_error(LOG_ARGS, + "could not rename(%s,%s)", + donemailname, modname); + free(modname); + close_text(txt); + free_parsed_hdrs(readhdrs, fromemails, + originalfromemails, toemails, + ccemails, rpemails, dtemails, + allheaders); + exit(EXIT_FAILURE); + } + free(modname); + gen_addr_cookie(listsubreleaseaddr, &ml, + "subrelease-", randomstr); + gen_addr_cookie(digestsubreleaseaddr, &ml, + "digestsubrelease-", randomstr); + gen_addr_cookie(nomailsubreleaseaddr, &ml, + "nomailsubrelease-", randomstr); + register_unformatted(txt, + "listsubreleaseaddr", listsubreleaseaddr); + register_unformatted(txt, + "digestsubreleaseaddr", digestsubreleaseaddr); + register_unformatted(txt, + "nomailsubreleaseaddr", nomailsubreleaseaddr); + subreplyto = listsubreleaseaddr; + } + queuefilename = prepstdreply(txt, &ml, - "$listowner$", testaddr, NULL); + "$listowner$", testaddr, subreplyto); MY_ASSERT(queuefilename) close_text(txt); - unlink(donemailname); + if (subreplyto == NULL) + unlink(donemailname); free(donemailname); send_help(&ml, queuefilename, testaddr); } diff --git a/tests/mlmmj-receive.in b/tests/mlmmj-receive.in index ec76c2aa..7c43ffb5 100644 --- a/tests/mlmmj-receive.in +++ b/tests/mlmmj-receive.in @@ -34,7 +34,8 @@ tests_init \ customheaders_with_subst \ verp \ normal_email_with_dot \ - multi_line_headers + multi_line_headers \ + subrelease mlmmjreceive=$(command -v mlmmj-receive) @@ -3372,3 +3373,90 @@ QUIT EOF atf_check -o file:expected-2.txt sed -e "/^Message-ID:/d; /^Date:/d;" mail-2.txt } + +subrelease_body() +{ + init_ml list + rmdir list/text + ln -s ${top_srcdir}/listtexts/en list/text + echo test@mlmmjtest > list/control/listaddress + start_fakesmtp list + echo "heloname" > list/control/smtphelo + + touch list/control/subonlypost + printf "user@test\nuser2@test" > list/subscribers.d/u + +cat > first < subrel < expected-release.txt < +RCPT TO: +DATA +From: bob@test +To: test@mlmmjtest +Subject: yeah + +Let's go, first email + +. +MAIL FROM: +RCPT TO: +DATA +From: bob@test +To: test@mlmmjtest +Subject: yeah + +Let's go, first email + +. +MAIL FROM: +RCPT TO: +DATA +From: bob@test +To: test@mlmmjtest +Subject: yeah + +Let's go, first email + +. +QUIT +EOF + atf_check -o file:expected-release.txt sed -e "/^Message-ID:/d; /^Date:/d;" mail-2.txt +}