Mercurial > hg > mlmmj
changeset 797:c3ee2bfaeb02
Implement new list text naming scheme
Also fix a bug where the normal list text would be sent when unsubscribing
from the nomail version of the list
Also fix some minor documentation bugs
author | Ben Schmidt |
---|---|
date | Sat, 10 Sep 2011 12:23:40 +1000 |
parents | 9f503b69a55d |
children | 98a5de42afcc |
files | ChangeLog include/mlmmj-sub.h include/mlmmj-unsub.h include/mlmmj.h include/prepstdreply.h include/send_help.h man/mlmmj-sub.1 man/mlmmj-unsub.1 src/listcontrol.c src/mlmmj-bounce.c src/mlmmj-maintd.c src/mlmmj-process.c src/mlmmj-sub.c src/mlmmj-unsub.c src/prepstdreply.c src/send_digest.c src/send_help.c src/send_list.c |
diffstat | 18 files changed, 290 insertions(+), 130 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Mon Mar 07 01:30:02 2011 +1100 +++ b/ChangeLog Sat Sep 10 12:23:40 2011 +1000 @@ -1,3 +1,6 @@ + o Fix bug where the normal listtext would be sent when unsubscribing from the + nomail version of the list + o New listtext naming scheme o Avoid trailing whitespace in MAIL FROM line (Lukas Fleischer) o Better end-of-line handling and error reporting in php-admin (Franky Van Liedekerke)
--- a/include/mlmmj-sub.h Mon Mar 07 01:30:02 2011 +1100 +++ b/include/mlmmj-sub.h Sat Sep 10 12:23:40 2011 +1000 @@ -24,18 +24,5 @@ #ifndef MLMMJ_SUBSCRIBE_H #define MLMMJ_SUBSCRIBE_H -#include <mlmmj.h> - -void moderate_sub(const char *listdir, const char *listaddr, - const char *listdelim, const char *subaddr, - const char *mlmmjsend, enum subtype typesub); -void getaddrandtype(const char *listdir, const char *modstr, - char **addrptr, enum subtype *subtypeptr); -void confirm_sub(const char *listdir, const char *listaddr, - const char *listdelim, const char *subaddr, - const char *mlmmjsend, enum subtype typesub); -void generate_subconfirm(const char *listdir, const char *listadr, - const char *listdelim, const char *subaddr, - const char *mlmmjsend, enum subtype typesub); #endif /* MLMMJ_SUBSCRIBE_H */
--- a/include/mlmmj-unsub.h Mon Mar 07 01:30:02 2011 +1100 +++ b/include/mlmmj-unsub.h Sat Sep 10 12:23:40 2011 +1000 @@ -24,14 +24,5 @@ #ifndef MLMMJ_UNSUBSCRIBE_H #define MLMMJ_UNSUBSCRIBE_H -#include <sys/types.h> - -void confirm_unsub(const char *listdir, const char *listaddr, - const char *listdelim, const char *subaddr, - const char *mlmmj, enum subtype typesub); -ssize_t unsubscribe(int subreadfd, int subwritefd, const char *address); -void generate_unsubconfirm(const char *listdir, const char *listaddr, - const char *listdelim, const char *subaddr, - const char *mlmmjsend, enum subtype typesub); #endif /* MLMMJ_UNSUBSCRIBE_H */
--- a/include/mlmmj.h Mon Mar 07 01:30:02 2011 +1100 +++ b/include/mlmmj.h Sat Sep 10 12:23:40 2011 +1000 @@ -70,13 +70,27 @@ }; /* Has to go here, since it's used in many places */ + enum subtype { SUB_NORMAL, SUB_DIGEST, SUB_NOMAIL, - SUB_FILE /* For single files (moderator, owner etc.) */ + SUB_FILE, /* For single files (moderator, owner etc.) */ + SUB_ALL /* For listing all kinds of subscribers */ }; +char *subtype_strs[5]; /* count matches enum above; defined in mlmmj-sub.c */ + +enum subreason { + SUB_REQUEST, + SUB_CONFIRM, + SUB_PERMIT, + SUB_ADMIN, + SUB_BOUNCING +}; + +char * subreason_strs[5]; /* count matches enum above; defined in mlmmj-sub.c */ + void print_version(const char *prg); #define MY_ASSERT(expression) if (!(expression)) { \
--- a/include/prepstdreply.h Mon Mar 07 01:30:02 2011 +1100 +++ b/include/prepstdreply.h Sat Sep 10 12:23:40 2011 +1000 @@ -29,8 +29,9 @@ char *substitute_one(const char *line, const char *listaddr, const char *listdelim, size_t datacount, char **data, const char *listdir); int open_listtext(const char *listdir, const char *filename); -char *prepstdreply(const char *listdir, const char *filename, const char *from, - const char *to, const char *replyto, size_t tokencount, - char **data, const char *mailname); +char *prepstdreply(const char *listdir, const char *purpose, const char *action, + const char *reason, const char *type, const char *compat, + const char *from, const char *to, const char *replyto, + size_t tokencount, char **data, const char *mailname); #endif /* PREPSTDREPLY_H */
--- a/include/send_help.h Mon Mar 07 01:30:02 2011 +1100 +++ b/include/send_help.h Sat Sep 10 12:23:40 2011 +1000 @@ -25,6 +25,7 @@ #define SEND_HELP_H void send_help(const char *listdir, const char *emailaddr, - const char *mlmmjsend, const char *name, const char *textfile); + const char *mlmmjsend, const char *purpose, const char *action, + const char *reason, const char *type, const char *compat); #endif
--- a/man/mlmmj-sub.1 Mon Mar 07 01:30:02 2011 +1100 +++ b/man/mlmmj-sub.1 Sat Sep 10 12:23:40 2011 +1000 @@ -3,8 +3,8 @@ mlmmj-sub \- subscribe address to a mailinglist run by mlmmj .SH SYNOPSIS .B mlmmj-sub -\fI-L /path/to/list -a john@doe.org \fR[\fI-c\fR | \fI-C\fR] \fR[\fI-d\fR | \fI-n\fR] -[\fI-f\fR] [\fI-h\fR] [\fI-U\fR] [\fI-V\fR] +\fI-L /path/to/list\fR [\fI-a john@doe.org\fR | \fI-m str\fR] +[\fI-c\fR | \fI-C\fR] [\fI-d\fR | \fI-n\fR] [\fI-f\fR] [\fI-h\fR] \fR[\fI-r\fR | \fI-R\fR] [\fI-s\fR] [\fI-U\fR] [\fI-V\fR] .HP \fB\-a\fR: Email address to subscribe .HP @@ -24,6 +24,10 @@ .HP \fB\-n\fR: Subscribe to nomail version of the list .HP +\fB\-r\fR: Behave as if request arrived via email (internal use) +.HP +\fB\-R\fR: Behave as if confirmation arrived via email (internal use) +.HP \fB\-s\fR: Don't send a mail to the subscriber if already subscribed .HP \fB\-U\fR: Don't switch to the user id of the listdir owner
--- a/man/mlmmj-unsub.1 Mon Mar 07 01:30:02 2011 +1100 +++ b/man/mlmmj-unsub.1 Sat Sep 10 12:23:40 2011 +1000 @@ -3,11 +3,13 @@ mlmmj-unsub \- manual page for mlmmj-unsub .SH SYNOPSIS .B mlmmj-unsub -\fI-L /path/to/list -a john@doe.org \fR[\fI-c\fR | \fI-C\fR] [\fI-h\fR] -\fR[\fI-d\fR | \fI-n\fR] [\fI-V\fR] +\fI-L /path/to/list -a john@doe.org\fR [\fI-b\fR] [\fI-c\fR | \fI-C\fR] +[\fI-d\fR | \fI-n\fR] [\fI-h\fR] [\fI-r\fR | \fI-R\fR] [\fI-s\fR] [\fI-U\fR] [\fI-V\fR] .HP \fB\-a\fR: Email address to unsubscribe .HP +\fB\-b\fR: Behave as if unsubscription is due to bouncing (internal use) +.HP \fB\-c\fR: Send goodbye mail .HP \fB\-C\fR: Request mail confirmation @@ -20,6 +22,10 @@ .HP \fB\-n\fR: Unsubscribe from the nomail version of the list .HP +\fB\-r\fR: Behave as if request arrived via email (internal use) +.HP +\fB\-R\fR: Behave as if confirmation arrived via email (internal use) +.HP \fB\-s\fR: Don't send a mail to the address if not subscribed .HP \fB\-U\fR: Don't switch to the user id of the listdir owner
--- a/src/listcontrol.c Mon Mar 07 01:30:02 2011 +1100 +++ b/src/listcontrol.c Sat Sep 10 12:23:40 2011 +1000 @@ -212,7 +212,7 @@ log_error(LOG_ARGS, "A subcribe-digest request was" " denied"); send_help(listdir, fromemails->emaillist[0], - mlmmjsend, "nodigest", "sub-deny-digest"); + mlmmjsend, "deny", "sub", "disabled", "digest", "sub-deny-digest"); return -1; } log_oper(listdir, OPLOGFNAME, "mlmmj-sub: request for digest" @@ -222,7 +222,7 @@ "-L", listdir, "-a", fromemails->emaillist[0], "-d", - subswitch, (char *)NULL); + "-r", subswitch, (char *)NULL); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsub); exit(EXIT_FAILURE); @@ -249,7 +249,7 @@ log_error(LOG_ARGS, "A subcribe-nomail request was" " denied"); send_help(listdir, fromemails->emaillist[0], - mlmmjsend, "nonomail", "sub-deny-nomail"); + mlmmjsend, "deny", "sub", "disabled", "nomail", "sub-deny-nomail"); return -1; } log_oper(listdir, OPLOGFNAME, "mlmmj-sub: request for nomail" @@ -259,7 +259,7 @@ "-L", listdir, "-a", fromemails->emaillist[0], "-n", - subswitch, (char *)NULL); + "-r", subswitch, (char *)NULL); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsub); exit(EXIT_FAILURE); @@ -287,7 +287,7 @@ execlp(mlmmjsub, mlmmjsub, "-L", listdir, "-a", fromemails->emaillist[0], - subswitch, (char *)NULL); + "-r", subswitch, (char *)NULL); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsub); exit(EXIT_FAILURE); @@ -315,7 +315,7 @@ "-L", listdir, "-a", tmpstr, "-d", - "-c", (char *)NULL); + "-R", "-c", (char *)NULL); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsub); exit(EXIT_FAILURE); @@ -343,7 +343,7 @@ "-L", listdir, "-a", tmpstr, "-n", - "-c", (char *)NULL); + "-R", "-c", (char *)NULL); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsub); exit(EXIT_FAILURE); @@ -371,7 +371,7 @@ execlp(mlmmjsub, mlmmjsub, "-L", listdir, "-a", tmpstr, - "-c", (char *)NULL); + "-R", "-c", (char *)NULL); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsub); exit(EXIT_FAILURE); @@ -400,7 +400,7 @@ "-L", listdir, "-a", fromemails->emaillist[0], "-d", - subswitch, (char *)NULL); + "-r", subswitch, (char *)NULL); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjunsub); exit(EXIT_FAILURE); @@ -429,7 +429,7 @@ "-L", listdir, "-a", fromemails->emaillist[0], "-n", - subswitch, (char *)NULL); + "-r", subswitch, (char *)NULL); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjunsub); exit(EXIT_FAILURE); @@ -457,7 +457,7 @@ execlp(mlmmjunsub, mlmmjunsub, "-L", listdir, "-a", fromemails->emaillist[0], - subswitch, (char *)NULL); + "-r", subswitch, (char *)NULL); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjunsub); exit(EXIT_FAILURE); @@ -491,7 +491,7 @@ "-L", listdir, "-a", tmpstr, "-d", - "-c", (char *)NULL); + "-R", "-c", (char *)NULL); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjunsub); exit(EXIT_FAILURE); @@ -525,7 +525,7 @@ "-L", listdir, "-a", tmpstr, "-n", - "-c", (char *)NULL); + "-R", "-c", (char *)NULL); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjunsub); exit(EXIT_FAILURE); @@ -559,7 +559,7 @@ execlp(mlmmjunsub, mlmmjunsub, "-L", listdir, "-a", tmpstr, - "-c", (char *)NULL); + "-R", "-c", (char *)NULL); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjunsub); exit(EXIT_FAILURE); @@ -664,7 +664,8 @@ } log_oper(listdir, OPLOGFNAME, "%s requested help", fromemails->emaillist[0]); - send_help(listdir, fromemails->emaillist[0], mlmmjsend, "help", "listhelp"); + send_help(listdir, fromemails->emaillist[0], mlmmjsend, + "help", NULL, NULL, NULL, "listhelp"); break; /* listname+faq@domain.tld */ @@ -679,7 +680,8 @@ } log_oper(listdir, OPLOGFNAME, "%s requested faq", fromemails->emaillist[0]); - send_help(listdir, fromemails->emaillist[0], mlmmjsend, "faq", "listfaq"); + send_help(listdir, fromemails->emaillist[0], mlmmjsend, + "faq", NULL, NULL, NULL, "listfaq"); break; /* listname+get-INDEX@domain.tld */
--- a/src/mlmmj-bounce.c Mon Mar 07 01:30:02 2011 +1100 +++ b/src/mlmmj-bounce.c Sat Sep 10 12:23:40 2011 +1000 @@ -145,8 +145,9 @@ } maildata[1] = indexstr; - queuefilename = prepstdreply(listdir, "bounce-probe", "$listowner$", - myaddr, NULL, 1, maildata, NULL); + queuefilename = prepstdreply(listdir, + "probe", NULL, NULL, NULL, "bounce-probe", + "$listowner$", myaddr, NULL, 1, maildata, NULL); MY_ASSERT(queuefilename); myfree(indexstr);
--- a/src/mlmmj-maintd.c Mon Mar 07 01:30:02 2011 +1100 +++ b/src/mlmmj-maintd.c Sat Sep 10 12:23:40 2011 +1000 @@ -754,7 +754,7 @@ } else { execlp(mlmmjunsub, mlmmjunsub, "-L", listdir, - "-a", address, (char *)NULL); + "-b", "-a", address, (char *)NULL); log_error(LOG_ARGS, "Could not execlp %s", mlmmjunsub); return 1;
--- a/src/mlmmj-process.c Mon Mar 07 01:30:02 2011 +1100 +++ b/src/mlmmj-process.c Sat Sep 10 12:23:40 2011 +1000 @@ -71,9 +71,23 @@ }; +enum modreason { + MODNONSUBPOSTS, + ACCESS, + MODERATED +}; + + +static char *modreason_strs[] = { + "modnonsubposts", + "access", + "moderated" +}; + + void newmoderated(const char *listdir, const char *mailfilename, const char *mlmmjsend, const char *efromsender, - size_t tokencount, char **data) + size_t tokencount, char **data, enum modreason modreason) { size_t i; char *from, *listfqdn, *listname, *moderators = NULL; @@ -142,9 +156,10 @@ myfree(listname); myfree(listfqdn); - queuefilename = prepstdreply(listdir, "moderation", "$listowner$", - to, replyto, tokencount, maildata, - mailfilename); + queuefilename = prepstdreply(listdir, + "moderate", "post", modreason_strs[modreason], NULL, + "moderation", "$listowner$", to, replyto, + tokencount, maildata, mailfilename); /* we might need to exec more than one mlmmj-send */ @@ -184,8 +199,9 @@ /* send mail to poster that the list is moderated */ - queuefilename = prepstdreply(listdir, "moderation-poster", - "$listowner$", efromsender, + queuefilename = prepstdreply(listdir, + "wait", "post", modreason_strs[modreason], NULL, + "moderation-poster", "$listowner$", efromsender, NULL, tokencount-1, maildata+2, mailfilename); execlp(mlmmjsend, mlmmjsend, @@ -382,6 +398,7 @@ int main(int argc, char **argv) { int i, j, opt, noprocess = 0, moderated = 0; + enum modreason modreason; int hdrfd, footfd, rawmailfd, donemailfd, omitfd; int subonlypost = 0, addrtocc = 1, intocc = 0, modnonsubposts = 0; int maxmailsize = 0; @@ -715,6 +732,7 @@ "bounces-help@", listfqdn); maildata[5] = maxmailsizestr; queuefilename = prepstdreply(listdir, + "deny", "post", "maxmailsize", NULL, "maxmailsize", "$listowner$", fromemails.emaillist[0], NULL, 1, maildata+4, donemailname); @@ -830,9 +848,10 @@ listfqdn = genlistfqdn(listaddr); fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn); - queuefilename = prepstdreply(listdir, "notintocc", - "$listowner$", fromemails.emaillist[0], - NULL, 2, maildata, donemailname); + queuefilename = prepstdreply(listdir, + "deny", "post", "notintocc", NULL, "notintocc", + "$listowner$", fromemails.emaillist[0], NULL, + 2, maildata, donemailname); MY_ASSERT(queuefilename) myfree(listdelim); myfree(listname); @@ -869,6 +888,7 @@ "modnonsubposts"); if(modnonsubposts) { moderated = 1; + modreason = MODNONSUBPOSTS; goto startaccess; } @@ -890,9 +910,11 @@ listfqdn = genlistfqdn(listaddr); fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn); - queuefilename = prepstdreply(listdir, "subonlypost", - "$listowner$", fromemails.emaillist[0], - NULL, 2, maildata, donemailname); + queuefilename = prepstdreply(listdir, + "deny", "post", "subonlypost", NULL, + "subonlypost", "$listowner$", + fromemails.emaillist[0], NULL, + 2, maildata, donemailname); MY_ASSERT(queuefilename) myfree(listaddr); myfree(listdelim); @@ -913,8 +935,12 @@ startaccess: - if(!moderated) - moderated = statctrl(listdir, "moderated"); + if(!moderated) { + if(statctrl(listdir, "moderated")) { + moderated = 1; + modreason = MODERATED; + } + } noaccessdenymails = statctrl(listdir, "noaccessdenymails"); @@ -944,10 +970,11 @@ listfqdn = genlistfqdn(listaddr); fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn); - queuefilename = prepstdreply(listdir, "access", - "$listowner$", - fromemails.emaillist[0], - NULL, 2, maildata, donemailname); + queuefilename = prepstdreply(listdir, + "deny", "post", "access", NULL, + "access", "$listowner$", + fromemails.emaillist[0], NULL, + 2, maildata, donemailname); MY_ASSERT(queuefilename) myfree(listaddr); myfree(listdelim); @@ -968,6 +995,7 @@ exit(EXIT_FAILURE); } else if (accret == MODERATE) { moderated = 1; + modreason = ACCESS; } else if (accret == DISCARD) { discardname = concatstr(3, listdir, "/queue/discarded/", randomstr); @@ -1024,7 +1052,8 @@ fsync(omitfd); close(omitfd); } - newmoderated(listdir, mqueuename, mlmmjsend, efrom, 2, maildata); + newmoderated(listdir, mqueuename, + mlmmjsend, efrom, 2, maildata, modreason); return EXIT_SUCCESS; }
--- a/src/mlmmj-sub.c Mon Mar 07 01:30:02 2011 +1100 +++ b/src/mlmmj-sub.c Sat Sep 10 12:23:40 2011 +1000 @@ -50,6 +50,22 @@ #include "ctrlvalues.h" #include "chomp.h" +char *subtype_strs[] = { + "normal", + "digest", + "nomail", + "file", + "all" +}; + +char * subreason_strs[] = { + "request", + "confirm", + "permit", + "admin", + "bouncing" +}; + void moderate_sub(const char *listdir, const char *listaddr, const char *listdelim, const char *subaddr, const char *mlmmjsend, enum subtype typesub) @@ -146,7 +162,8 @@ maildata[3] = replyto; maildata[5] = moderators; - queuefilename = prepstdreply(listdir, "submod-moderator", + queuefilename = prepstdreply(listdir, + "gatekeep", "sub", NULL, NULL, "submod-moderator", "$listowner$", to, replyto, 3, maildata, NULL); myfree(maildata[1]); @@ -188,8 +205,9 @@ /* send mail to requester that the list is submod'ed */ from = concatstr(4, listname, listdelim, "bounces-help@", listfqdn); - queuefilename = prepstdreply(listdir, "submod-requester", "$listowner$", - subaddr, NULL, 0, NULL, NULL); + queuefilename = prepstdreply(listdir, + "wait", "sub", NULL, NULL, "submod-requester", + "$listowner$", subaddr, NULL, 0, NULL, NULL); myfree(listname); myfree(listfqdn); @@ -256,7 +274,7 @@ void confirm_sub(const char *listdir, const char *listaddr, const char *listdelim, const char *subaddr, - const char *mlmmjsend, enum subtype typesub) + const char *mlmmjsend, enum subtype typesub, enum subreason reasonsub) { char *queuefilename, *fromaddr, *listname, *listfqdn, *listtext; @@ -281,8 +299,11 @@ break; } - queuefilename = prepstdreply(listdir, listtext, "$helpaddr$", - subaddr, NULL, 0, NULL, NULL); + queuefilename = prepstdreply(listdir, + "finish", "sub", + subreason_strs[reasonsub], subtype_strs[typesub], + listtext, "$helpaddr$", subaddr, NULL, + 0, NULL, NULL); MY_ASSERT(queuefilename); myfree(listtext); @@ -298,7 +319,7 @@ void notify_sub(const char *listdir, const char *listaddr, const char *listdelim, const char *subaddr, - const char *mlmmjsend, enum subtype typesub) + const char *mlmmjsend, enum subtype typesub, enum subreason reasonsub) { char *maildata[2] = { "newsub", NULL }; char *listfqdn, *listname, *fromaddr, *tostr; @@ -328,8 +349,11 @@ break; } - queuefilename = prepstdreply(listdir, listtext, "$listowner$", - "$listowner$", NULL, 1, maildata, NULL); + queuefilename = prepstdreply(listdir, + "notify", "sub", + subreason_strs[reasonsub], subtype_strs[typesub], + listtext, "$listowner$", "$listowner$", NULL, + 1, maildata, NULL); MY_ASSERT(queuefilename) myfree(listtext); myfree(maildata[1]); @@ -346,7 +370,7 @@ void generate_subconfirm(const char *listdir, const char *listaddr, const char *listdelim, const char *subaddr, - const char *mlmmjsend, enum subtype typesub) + const char *mlmmjsend, enum subtype typesub, enum subreason reasonsub) { int subconffd; char *confirmaddr, *listname, *listfqdn, *confirmfilename = NULL; @@ -415,8 +439,11 @@ maildata[1] = mystrdup(subaddr); maildata[3] = mystrdup(confirmaddr); - queuefilename = prepstdreply(listdir, listtext, "$helpaddr$", subaddr, - confirmaddr, 2, maildata, NULL); + queuefilename = prepstdreply(listdir, + "confirm", "sub", + subreason_strs[reasonsub], subtype_strs[typesub], + listtext, "$helpaddr$", subaddr, confirmaddr, + 2, maildata, NULL); myfree(maildata[1]); myfree(maildata[3]); @@ -436,8 +463,8 @@ static void print_help(const char *prg) { - printf("Usage: %s -L /path/to/list [-a john@doe.org | -m str]\n" - " [-c] [-C] [-f] [-h] [-L] [-d | -n] [-s] [-U] [-V]\n" + printf("Usage: %s -L /path/to/list {-a john@doe.org | -m str}\n" + " [-c | -C] [-f] [-h] [-L] [-d | -n] [-r | -R] [-s] [-U] [-V]\n" " -a: Email address to subscribe \n" " -c: Send welcome mail\n" " -C: Request mail confirmation\n" @@ -447,7 +474,9 @@ " -L: Full path to list directory\n" " -m: moderation string\n" " -n: Subscribe to no mail version of list\n", prg); - printf(" -s: Don't send a mail to subscriber if already subscribed\n" + printf(" -r: Behave as if request arrived via email (internal use)\n" + " -R: Behave as if confirmation arrived via email (internal use)\n" + " -s: Don't send a mail to subscriber if already subscribed\n" " -U: Don't switch to the user id of the listdir owner\n" " -V: Print version\n" "When no options are specified, subscription may be " @@ -468,8 +497,9 @@ fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn); myfree(listdelim); - queuefilename = prepstdreply(listdir, "sub-subscribed", "$helpaddr$", - subaddr, NULL, 0, NULL, NULL); + queuefilename = prepstdreply(listdir, + "deny", "sub", "subbed", NULL, "sub-subscribed", + "$helpaddr$", subaddr, NULL, 0, NULL, NULL); MY_ASSERT(queuefilename); myfree(listaddr); @@ -502,6 +532,7 @@ pid_t pid, childpid; uid_t uid; enum subtype typesub = SUB_NORMAL; + enum subreason reasonsub = SUB_ADMIN; CHECKFULLPATH(argv[0]); @@ -511,7 +542,7 @@ mlmmjsend = concatstr(2, bindir, "/mlmmj-send"); myfree(bindir); - while ((opt = getopt(argc, argv, "hcCdfm:nsVUL:a:")) != -1) { + while ((opt = getopt(argc, argv, "hcCdfm:nsVUL:a:rR")) != -1) { switch(opt) { case 'a': address = optarg; @@ -540,6 +571,12 @@ case 'n': nomail = 1; break; + case 'r': + reasonsub = SUB_REQUEST; + break; + case 'R': + reasonsub = SUB_CONFIRM; + break; case 's': nogensubscribed = 1; break; @@ -564,8 +601,10 @@ exit(EXIT_FAILURE); } - if(modstr) + if(modstr) { getaddrandtype(listdir, modstr, &address, &typesub); + reasonsub = SUB_PERMIT; + } if(strchr(address, '@') == NULL) { log_error(LOG_ARGS, "No '@' sign in '%s', not subscribing", @@ -590,6 +629,12 @@ exit(EXIT_FAILURE); } + if(reasonsub == SUB_CONFIRM && subconfirm) { + fprintf(stderr, "Cannot specify both -C and -R\n"); + fprintf(stderr, "%s -h for help\n", argv[0]); + exit(EXIT_FAILURE); + } + /* Make the address lowercase */ lowcaseaddr = mystrdup(address); i = 0; @@ -690,7 +735,7 @@ unlink(sublockname); myfree(sublockname); generate_subconfirm(listdir, listaddr, listdelim, - address, mlmmjsend, typesub); + address, mlmmjsend, typesub, reasonsub); } else { if(modstr == NULL) submod = !force && statctrl(listdir, "submod"); @@ -734,7 +779,7 @@ if(childpid < 0) { log_error(LOG_ARGS, "Could not fork; owner not notified"); confirm_sub(listdir, listaddr, listdelim, address, - mlmmjsend, typesub); + mlmmjsend, typesub, reasonsub); } if(childpid > 0) { @@ -746,7 +791,7 @@ /* child confirms subscription */ if(childpid == 0) confirm_sub(listdir, listaddr, listdelim, address, - mlmmjsend, typesub); + mlmmjsend, typesub, reasonsub); } notifysub = statctrl(listdir, "notifysub"); @@ -754,7 +799,7 @@ /* Notify list owner about subscription */ if (notifysub) notify_sub(listdir, listaddr, listdelim, address, mlmmjsend, - typesub); + typesub, reasonsub); myfree(address); myfree(listaddr);
--- a/src/mlmmj-unsub.c Mon Mar 07 01:30:02 2011 +1100 +++ b/src/mlmmj-unsub.c Sat Sep 10 12:23:40 2011 +1000 @@ -50,7 +50,8 @@ void confirm_unsub(const char *listdir, const char *listaddr, const char *listdelim, const char *subaddr, - const char *mlmmjsend, enum subtype typesub) + const char *mlmmjsend, + enum subtype typesub, enum subreason reasonsub) { char *queuefilename, *fromaddr, *listname, *listfqdn, *listtext; @@ -75,8 +76,10 @@ break; } - queuefilename = prepstdreply(listdir, listtext, "$helpaddr$", - subaddr, NULL, 0, NULL, NULL); + queuefilename = prepstdreply(listdir, + "finish", "unsub", + subreason_strs[reasonsub], subtype_strs[typesub], + listtext, "$helpaddr$", subaddr, NULL, 0, NULL, NULL); MY_ASSERT(queuefilename); myfree(listtext); @@ -93,7 +96,8 @@ void notify_unsub(const char *listdir, const char *listaddr, const char *listdelim, const char *subaddr, - const char *mlmmjsend, enum subtype typesub) + const char *mlmmjsend, + enum subtype typesub, enum subreason reasonsub) { char *maildata[4] = { "oldsub", NULL }; char *listfqdn, *listname, *fromaddr, *tostr; @@ -123,8 +127,11 @@ break; } - queuefilename = prepstdreply(listdir, listtext, "$listowner$", - "$listowner$", NULL, 1, maildata, NULL); + queuefilename = prepstdreply(listdir, + "notify", "unsub", + subreason_strs[reasonsub], subtype_strs[typesub], + listtext, "$listowner$", "$listowner$", NULL, + 1, maildata, NULL); MY_ASSERT(queuefilename); myfree(listtext); myfree(maildata[1]); @@ -143,7 +150,8 @@ void generate_unsubconfirm(const char *listdir, const char *listaddr, const char *listdelim, const char *subaddr, - const char *mlmmjsend, enum subtype typesub) + const char *mlmmjsend, + enum subtype typesub, enum subreason reasonsub) { char *confirmaddr, *listname, *listfqdn, *tmpstr; char *queuefilename, *fromaddr; @@ -212,8 +220,11 @@ maildata[1] = mystrdup(subaddr); maildata[3] = mystrdup(confirmaddr); - queuefilename = prepstdreply(listdir, listtext, "$helpaddr$", subaddr, - confirmaddr, 2, maildata, NULL); + queuefilename = prepstdreply(listdir, + "confirm", "unsub", + subreason_strs[reasonsub], subtype_strs[typesub], + listtext, "$helpaddr$", subaddr, confirmaddr, + 2, maildata, NULL); myfree(maildata[1]); myfree(maildata[3]); @@ -275,19 +286,22 @@ static void print_help(const char *prg) { printf("Usage: %s -L /path/to/list -a john@doe.org\n" - " [-c] [-C] [-h] [-L] [-d | -n] [-s] [-V]\n" + " [-b] [-c | -C] [-h] [-L] [-d | -n] [-r | -R] [-s] [-V]\n" " -a: Email address to unsubscribe \n" + " -b: Behave as if unsubscription is due to bouncing (internal use)\n" " -c: Send goodbye mail\n" " -C: Request mail confirmation\n" " -d: Unsubscribe from digest of list\n" " -h: This help\n" " -L: Full path to list directory\n" - " -n: Unsubscribe from no mail version of list\n" + " -n: Unsubscribe from no mail version of list\n", prg); + printf(" -r: Behave as if request arrived via email (internal use)\n" + " -R: Behave as if confirmation arrived via email (internal use)\n" " -s: Don't send a mail to the address if not subscribed\n" " -U: Don't switch to the user id of the listdir owner\n" " -V: Print version\n" "When no options are specified, unsubscription silently " - "happens\n", prg); + "happens\n"); exit(EXIT_SUCCESS); } @@ -304,8 +318,10 @@ fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn); myfree(listdelim); - queuefilename = prepstdreply(listdir, "unsub-notsubscribed", - "$helpaddr$", subaddr, NULL, 0, NULL, NULL); + queuefilename = prepstdreply(listdir, + "deny", "unsub", "unsubbed", NULL, + "unsub-notsubscribed", "$helpaddr$", subaddr, NULL, + 0, NULL, NULL); MY_ASSERT(queuefilename); myfree(listaddr); @@ -338,6 +354,7 @@ struct dirent *dp; pid_t pid, childpid; enum subtype typesub = SUB_NORMAL; + enum subreason reasonsub = SUB_ADMIN; uid_t uid; struct stat st; @@ -349,7 +366,7 @@ mlmmjsend = concatstr(2, bindir, "/mlmmj-send"); myfree(bindir); - while ((opt = getopt(argc, argv, "hcCdnVUL:a:s")) != -1) { + while ((opt = getopt(argc, argv, "hcCdnVUL:a:sbrR")) != -1) { switch(opt) { case 'L': listdir = optarg; @@ -360,6 +377,9 @@ case 'a': address = optarg; break; + case 'b': + reasonsub = SUB_BOUNCING; + break; case 'c': confirmunsub = 1; break; @@ -372,6 +392,12 @@ case 'h': print_help(argv[0]); break; + case 'r': + reasonsub = SUB_REQUEST; + break; + case 'R': + reasonsub = SUB_CONFIRM; + break; case 's': nogennotsubscribed = 1; break; @@ -406,6 +432,18 @@ exit(EXIT_FAILURE); } + if(reasonsub == SUB_CONFIRM && unsubconfirm) { + fprintf(stderr, "Cannot specify both -C and -R\n"); + fprintf(stderr, "%s -h for help\n", argv[0]); + exit(EXIT_FAILURE); + } + + if(reasonsub == SUB_BOUNCING && unsubconfirm) { + fprintf(stderr, "Cannot specify both -C and -b\n"); + fprintf(stderr, "%s -h for help\n", argv[0]); + exit(EXIT_FAILURE); + } + /* Make the address lowercase */ lowcaseaddr = mystrdup(address); i = 0; @@ -467,7 +505,7 @@ listdelim = getlistdelim(listdir); if(unsubconfirm) generate_unsubconfirm(listdir, listaddr, listdelim, address, - mlmmjsend, typesub); + mlmmjsend, typesub, reasonsub); if((subddir = opendir(subddirname)) == NULL) { log_error(LOG_ARGS, "Could not opendir(%s)", @@ -603,7 +641,8 @@ if(childpid < 0) { log_error(LOG_ARGS, "Could not fork"); confirm_unsub(listdir, listaddr, listdelim, - address, mlmmjsend, digest); + address, mlmmjsend, + typesub, reasonsub); } if(childpid > 0) { @@ -615,7 +654,8 @@ /* child confirms subscription */ if(childpid == 0) confirm_unsub(listdir, listaddr, listdelim, - address, mlmmjsend, digest); + address, mlmmjsend, + typesub, reasonsub); } } @@ -626,7 +666,7 @@ /* Notify list owner about subscription */ if (notifysub) notify_unsub(listdir, listaddr, listdelim, address, mlmmjsend, - typesub); + typesub, reasonsub); myfree(listaddr); myfree(listdelim);
--- a/src/prepstdreply.c Mon Mar 07 01:30:02 2011 +1100 +++ b/src/prepstdreply.c Sat Sep 10 12:23:40 2011 +1000 @@ -225,26 +225,51 @@ if (fd >= 0) return fd; - log_error(LOG_ARGS, "Could not open listtext '%s'", filename); return -1; } -char *prepstdreply(const char *listdir, const char *filename, const char *from, - const char *to, const char *replyto, size_t tokencount, - char **data, const char *mailname) +char *prepstdreply(const char *listdir, const char *purpose, const char *action, + const char *reason, const char *type, const char *compat, + const char *from, const char *to, const char *replyto, + size_t tokencount, char **data, const char *mailname) { - size_t i, len; + size_t filenamelen, i, len; int infd, outfd, mailfd; - char *listaddr, *listdelim, *tmp, *retstr = NULL; + char *filename, *listaddr, *listdelim, *tmp, *retstr = NULL; char *listfqdn, *line, *utfline, *utfsub, *utfsub2; char *str = NULL; char **moredata; char *headers[10] = { NULL }; /* relies on NULL to flag end */ - if ((infd = open_listtext(listdir, filename)) < 0) { + filename = concatstr(7,purpose,"-",action,"-",reason,"-",type); + filenamelen = strlen(filename); + do { + if ((infd = open_listtext(listdir, filename)) >= 0) break; + len = type ? strlen(type) : 0; + filename[filenamelen-len-1] = '\0'; + if ((infd = open_listtext(listdir, filename)) >= 0) break; + filename[filenamelen-len-1] = '-'; + filenamelen -= len + 1; + len = reason ? strlen(reason) : 0; + filename[filenamelen-len-1] = '\0'; + if ((infd = open_listtext(listdir, filename)) >= 0) break; + filename[filenamelen-len-1] = '-'; + filenamelen -= len + 1; + len = action ? strlen(action) : 0; + filename[filenamelen-len-1] = '\0'; + if ((infd = open_listtext(listdir, filename)) >= 0) break; + filename[filenamelen-len-1] = '-'; + filenamelen -= len + 1; + if ((infd = open_listtext(listdir, compat)) >= 0) { + myfree(filename); + filename = mystrdup(compat); + break; + } + log_error(LOG_ARGS, "Could not open listtext '%s'", filename); + myfree(filename); return NULL; - } + } while (0); listaddr = getlistaddr(listdir); listdelim = getlistdelim(listdir); @@ -267,6 +292,7 @@ myfree(listdelim); myfree(listfqdn); myfree(retstr); + myfree(filename); return NULL; } @@ -501,5 +527,7 @@ } myfree(moredata); + myfree(filename); + return retstr; }
--- a/src/send_digest.c Mon Mar 07 01:30:02 2011 +1100 +++ b/src/send_digest.c Sat Sep 10 12:23:40 2011 +1000 @@ -226,7 +226,7 @@ txtfd = open_listtext(listdir, "digest"); if (txtfd < 0) { - log_error(LOG_ARGS, "Notice: Could not open std mail digest"); + log_error(LOG_ARGS, "Could not open listtext 'digest'"); } subst_data[0] = "digestfirst";
--- a/src/send_help.c Mon Mar 07 01:30:02 2011 +1100 +++ b/src/send_help.c Sat Sep 10 12:23:40 2011 +1000 @@ -43,7 +43,8 @@ #include "memory.h" void send_help(const char *listdir, const char *emailaddr, - const char *mlmmjsend, const char *name, const char *textfile) + const char *mlmmjsend, const char *purpose, const char *action, + const char *reason, const char *type, const char *compat) { char *queuefilename, *listaddr, *listdelim, *listname, *listfqdn; char *fromaddr; @@ -56,10 +57,15 @@ fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn); myfree(listdelim); - queuefilename = prepstdreply(listdir, textfile, "$listowner$", - emailaddr, NULL, 0, NULL, NULL); + queuefilename = prepstdreply(listdir, + purpose, action, reason, type, compat, + "$listowner$", emailaddr, NULL, 0, NULL, NULL); if(queuefilename == NULL) { - log_error(LOG_ARGS, "Could not prepare %s mail", name); + if (action == NULL) action = ""; + if (reason == NULL) reason = ""; + if (type == NULL) type = ""; + log_error(LOG_ARGS, "Could not prepare %s-%s-%s-%s mail", + purpose, action, reason, type); exit(EXIT_FAILURE); }
--- a/src/send_list.c Mon Mar 07 01:30:02 2011 +1100 +++ b/src/send_list.c Sat Sep 10 12:23:40 2011 +1000 @@ -98,8 +98,10 @@ fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn); myfree(listdelim); - queuefilename = prepstdreply(listdir, "listsubs", "$listowner$", - emailaddr, NULL, 0, NULL, NULL); + queuefilename = prepstdreply(listdir, + "list", NULL, NULL, subtype_strs[SUB_ALL], + "listsubs", "$listowner$", emailaddr, NULL, + 0, NULL, NULL); if(queuefilename == NULL) { log_error(LOG_ARGS, "Could not prepare sub list mail"); exit(EXIT_FAILURE);