]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
Implement new list text naming scheme
authorBen Schmidt <none@none>
Sat, 10 Sep 2011 02:23:40 +0000 (12:23 +1000)
committerBen Schmidt <none@none>
Sat, 10 Sep 2011 02:23:40 +0000 (12:23 +1000)
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

18 files changed:
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

index cf711a23cdfdc9b91364622b49727a82fce49f73..cb15693bade1848589f7529ea5b13841a2e00848 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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)
index 2df0e03afe8f6f8a37c951f65aaaf91e685d0faf..6bd22076b6e18f241694ed7b961af2b59f938885 100644 (file)
 #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 */
index fecf0d07037e9b359c2823076b7d765ce3ea3a46..62fd06845f84d9ecb254c98fcf153a61b6ef512d 100644 (file)
 #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 */
index 7373d5a888abdc368ce93caa5e2c3592814b4551..768960c043addc8087ce39b2b668641ee1a518df 100644 (file)
@@ -70,13 +70,27 @@ struct mailhdr {
 };
 
 /* 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)) { \
index 635f22f8acb9bece5be8398aac6fa2916911838a..1a8d86405d75db5a5ae41fb7cd170a05976d5e21 100644 (file)
@@ -29,8 +29,9 @@ char *substitute(const char *line, const char *listaddr, const char *listdelim,
 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 */
index 1cfd15b31543f122e541b361b8d7077487344b0e..46b92b8051b2731d32c9cfb5bab4dec5b4e2d124 100644 (file)
@@ -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
index 917489bf8c60369a52a29d76f413696c35d2f87b..6eb7c98a43c3cd9ec97b1a49a0596d7f67ca087c 100644 (file)
@@ -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 @@ mlmmj-sub \- subscribe address to a mailinglist run by mlmmj
 .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
index 9fa7bc829b57910eaf6ffeb1906cf24b12ff9e1f..10ea49dcb81632d1b2aac560ddc2fb463352e62a 100644 (file)
@@ -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 @@ mlmmj-unsub \- manual page for mlmmj-unsub
 .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
index e9e425ca91c500e4826cfc25671ae68d7840c26a..68e6d5b203e3d735f1b05724cfd875ece3f83edd 100644 (file)
@@ -212,7 +212,7 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                        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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                                "-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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                        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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                                "-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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                                "-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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                                "-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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                                "-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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                                "-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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                                "-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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                                "-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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                }
                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 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                }
                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 */
index 6a817a8be176b35d59a8faecebbb06e592d9d2c4..2767339141e53a565884123b6cbcc6f9462e88c9 100644 (file)
@@ -145,8 +145,9 @@ void do_probe(const char *listdir, const char *mlmmjsend, const char *addr)
        }
 
        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);
 
index 3cc67e1c09f58d7a9df305ccaf994b6a310971ae..afe5c68877e0fd19f7c402f0b8cba7a941af90e5 100644 (file)
@@ -754,7 +754,7 @@ int unsub_bouncers(const char *listdir, const char *mlmmjunsub)
                } 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;
index ca2f88f78a0bbd6e0c98379bc5e6c862010b9c03..6b010b21df384097ae8e11d3d60d04a9cd285ea9 100644 (file)
@@ -71,9 +71,23 @@ static char *action_strs[] = {
 };
 
 
+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 @@ void newmoderated(const char *listdir, const char *mailfilename,
        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,9 +199,10 @@ void newmoderated(const char *listdir, const char *mailfilename,
 
        /* send mail to poster that the list is moderated */
 
-       queuefilename = prepstdreply(listdir, "moderation-poster",
-                                    "$listowner$", efromsender,
-                                    NULL, tokencount-1, maildata+2, mailfilename);
+       queuefilename = prepstdreply(listdir,
+                       "wait", "post", modreason_strs[modreason], NULL,
+                       "moderation-poster", "$listowner$", efromsender,
+                       NULL, tokencount-1, maildata+2, mailfilename);
 
        execlp(mlmmjsend, mlmmjsend,
                        "-l", "1",
@@ -382,6 +398,7 @@ static void print_help(const char *prg)
 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 @@ int main(int argc, char **argv)
                                        "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 @@ int main(int argc, char **argv)
                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 @@ int main(int argc, char **argv)
                                        "modnonsubposts");
                        if(modnonsubposts) {
                                moderated = 1;
+                               modreason = MODNONSUBPOSTS;
                                goto startaccess;
                        }
 
@@ -890,9 +910,11 @@ int main(int argc, char **argv)
                        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 @@ int main(int argc, char **argv)
 
 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 @@ startaccess:
                        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 @@ startaccess:
                        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 @@ startaccess:
                        fsync(omitfd);
                        close(omitfd);
                }
-               newmoderated(listdir, mqueuename, mlmmjsend, efrom, 2, maildata);
+               newmoderated(listdir, mqueuename,
+                               mlmmjsend, efrom, 2, maildata, modreason);
                return EXIT_SUCCESS;
        }
 
index 65dd70d822a542e8d0adcc780e1afdc2364a86c0..d74d9556c8dfb6f8c2d080d4c90852e08a06a2f7 100644 (file)
 #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,9 +162,10 @@ void moderate_sub(const char *listdir, const char *listaddr,
        maildata[3] = replyto;
        maildata[5] = moderators;
 
-       queuefilename = prepstdreply(listdir, "submod-moderator",
-                               "$listowner$", to, replyto, 3, maildata, NULL);
-       
+       queuefilename = prepstdreply(listdir,
+                       "gatekeep", "sub", NULL, NULL, "submod-moderator",
+                       "$listowner$", to, replyto, 3, maildata, NULL);
+
        myfree(maildata[1]);
        
        /* we might need to exec more than one mlmmj-send */
@@ -188,9 +205,10 @@ void moderate_sub(const char *listdir, const char *listaddr,
        /* 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);
        execl(mlmmjsend, mlmmjsend,
@@ -256,7 +274,7 @@ freedone:
 
 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 @@ void confirm_sub(const char *listdir, const char *listaddr,
                        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 confirm_sub(const char *listdir, const char *listaddr,
 
 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 @@ void notify_sub(const char *listdir, const char *listaddr,
                        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 notify_sub(const char *listdir, const char *listaddr,
 
 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 @@ void generate_subconfirm(const char *listdir, const char *listaddr,
        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 @@ void generate_subconfirm(const char *listdir, const char *listaddr,
 
 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 @@ static void print_help(const char *prg)
               " -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 @@ void generate_subscribed(const char *listdir, const char *subaddr,
        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 @@ int main(int argc, char **argv)
        pid_t pid, childpid;
        uid_t uid;
        enum subtype typesub = SUB_NORMAL;
+       enum subreason reasonsub = SUB_ADMIN;
 
        CHECKFULLPATH(argv[0]);
 
@@ -511,7 +542,7 @@ int main(int argc, char **argv)
        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 @@ int main(int argc, char **argv)
                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 @@ int main(int argc, char **argv)
                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 @@ int main(int argc, char **argv)
                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 @@ int main(int argc, char **argv)
                        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 @@ int main(int argc, char **argv)
                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 @@ int main(int argc, char **argv)
                /* 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 @@ int main(int argc, char **argv)
        /* Notify list owner about subscription */
        if (notifysub)
                notify_sub(listdir, listaddr, listdelim, address, mlmmjsend,
-                               typesub);
+                               typesub, reasonsub);
 
        myfree(address);
        myfree(listaddr);
index 0f26a9426defb66020165415c7ccc1907301d4f7..96ff58cdbd3cf227eb6ca84ccc1e203b91ce04dc 100644 (file)
@@ -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 @@ void confirm_unsub(const char *listdir, const char *listaddr,
                        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 confirm_unsub(const char *listdir, const char *listaddr,
 
 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 @@ void notify_unsub(const char *listdir, const char *listaddr,
                        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 notify_unsub(const char *listdir, const char *listaddr,
 
 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 @@ void generate_unsubconfirm(const char *listdir, const char *listaddr,
        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 @@ ssize_t unsubscribe(int subreadfd, int subwritefd, const char *address)
 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 @@ void generate_notsubscribed(const char *listdir, const char *subaddr,
        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 @@ int main(int argc, char **argv)
        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 @@ int main(int argc, char **argv)
        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 @@ int main(int argc, char **argv)
                case 'a':
                        address = optarg;
                        break;
+               case 'b':
+                       reasonsub = SUB_BOUNCING;
+                       break;
                case 'c':
                        confirmunsub = 1;
                        break;
@@ -372,6 +392,12 @@ int main(int argc, char **argv)
                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 @@ int main(int argc, char **argv)
                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 @@ int main(int argc, char **argv)
        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 @@ int main(int argc, char **argv)
                        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 @@ int main(int argc, char **argv)
                        /* child confirms subscription */
                        if(childpid == 0)
                                confirm_unsub(listdir, listaddr, listdelim,
-                                               address, mlmmjsend, digest);
+                                               address, mlmmjsend,
+                                               typesub, reasonsub);
                }
         }
 
@@ -626,7 +666,7 @@ int main(int argc, char **argv)
         /* Notify list owner about subscription */
         if (notifysub)
                 notify_unsub(listdir, listaddr, listdelim, address, mlmmjsend,
-                               typesub);
+                               typesub, reasonsub);
 
        myfree(listaddr);
        myfree(listdelim);
index d82e6de87d056ebd016069cd4a37aafc2683cbd6..537f0120a235d10178f575257b16ef27d8e444ef 100644 (file)
@@ -225,26 +225,51 @@ int open_listtext(const char *listdir, const char *filename)
        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 @@ char *prepstdreply(const char *listdir, const char *filename, const char *from,
                myfree(listdelim);
                myfree(listfqdn);
                myfree(retstr);
+               myfree(filename);
                return NULL;
        }
 
@@ -501,5 +527,7 @@ freeandreturn:
        }
        myfree(moredata);
 
+       myfree(filename);
+
        return retstr;
 }
index c079e5e29be21b3dda69a7dbaed93530df843c39..6106668aacab2e4968602176601044ad468c5118 100644 (file)
@@ -226,7 +226,7 @@ int send_digest(const char *listdir, int firstindex, int lastindex,
        
        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";
index 05af1edba835df9e5cea5bad54a9aff2a4f84d47..e013990abf638dacd76aa971f5d9235412bd02cc 100644 (file)
@@ -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 @@ void send_help(const char *listdir, const char *emailaddr,
        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);
        }
        
index 155b7bd006f7ddd18210659a3314d6a1530c56bf..5d5bedaeaf53dbd0595391180a7a059ad6c0b25f 100644 (file)
@@ -98,8 +98,10 @@ void send_list(const char *listdir, const char *emailaddr,
        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);