Mercurial > hg > mlmmj
changeset 343:6d1f589dee87
This is post crash commit of working copy mmj. Will test compile etc.
in a minute.
--- ChangeLog 14 Sep 2004 11:06:43 -0000 1.82
+++ ChangeLog 23 Sep 2004 14:25:13 -0000
@@ -1,6 +1,9 @@
- o Avoid message about changing uid in mlmmj-sub by only saying so when doing
- so
+ o Add support for not archiving the list by touching listdir/control/noarchive
+ o Add 'nomail' version of lists. Subscribers to the nomail version are
+ subscribed, but does not get any mail
+ o Don't talk about changing uid in mlmmj-sub when we're not really doing it
o Add sanity checks to disallow denial mails going to the list
+ o Add digest functionality
o Implement -d option for mlmmj-maintd to be able to supply it with a directory
containing several listdirs, where mlmmj-maintd then will run maintenance
o Chown option and a fix for mlmmj-make-ml.sh. Thanks Ingo Lameter
author | mmj |
---|---|
date | Fri, 24 Sep 2004 00:29:31 +1000 |
parents | 6b3e1584a0fd |
children | 410780151412 |
files | ChangeLog TUNABLES VERSION include/mlmmj-sub.h include/mlmmj-unsub.h include/mlmmj.h include/subscriberfuncs.h listtexts/notifysub-nomail listtexts/notifyunsub-nomail listtexts/sub-confirm-nomail listtexts/sub-ok-nomail listtexts/unsub-confirm-nomail listtexts/unsub-ok-nomail man/mlmmj-sub.1 man/mlmmj-unsub.1 src/listcontrol.c src/mlmmj-make-ml.sh src/mlmmj-send.c src/mlmmj-sub.c src/mlmmj-unsub.c src/subscriberfuncs.c |
diffstat | 21 files changed, 522 insertions(+), 147 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Tue Sep 14 21:06:44 2004 +1000 +++ b/ChangeLog Fri Sep 24 00:29:31 2004 +1000 @@ -1,6 +1,9 @@ - o Avoid message about changing uid in mlmmj-sub by only saying so when doing - so + o Add support for not archiving the list by touching listdir/control/noarchive + o Add 'nomail' version of lists. Subscribers to the nomail version are + subscribed, but does not get any mail + o Don't talk about changing uid in mlmmj-sub when we're not really doing it o Add sanity checks to disallow denial mails going to the list + o Add digest functionality o Implement -d option for mlmmj-maintd to be able to supply it with a directory containing several listdirs, where mlmmj-maintd then will run maintenance o Chown option and a fix for mlmmj-make-ml.sh. Thanks Ingo Lameter
--- a/TUNABLES Tue Sep 14 21:06:44 2004 +1000 +++ b/TUNABLES Fri Sep 24 00:29:31 2004 +1000 @@ -93,3 +93,8 @@ Here is specified for how long time in seconds an address can bounce before it's unsubscribed. Defaults to 432000 seconds, which is 5 days. + + · noarchive (boolean) + + If this file exists, the mail won't be saved in the archive but simply + deleted.
--- a/VERSION Tue Sep 14 21:06:44 2004 +1000 +++ b/VERSION Fri Sep 24 00:29:31 2004 +1000 @@ -1,1 +1,1 @@ -1.0.1 +1.1-pre-09182004
--- a/include/mlmmj-sub.h Tue Sep 14 21:06:44 2004 +1000 +++ b/include/mlmmj-sub.h Fri Sep 24 00:29:31 2004 +1000 @@ -24,10 +24,13 @@ #ifndef MLMMJ_SUBSCRIBE_H #define MLMMJ_SUBSCRIBE_H +#include <mlmmj.h> + void confirm_sub(const char *listdir, const char *listaddr, - const char *subaddr, const char *mlmmjsend, int digest); + const char *subaddr, const char *mlmmjsend, + enum subtype typesub); void generate_subconfirm(const char *listdir, const char *listadr, const char *subaddr, const char *mlmmjsend, - int digest); + enum subtype typesub); #endif /* MLMMJ_SUBSCRIBE_H */
--- a/include/mlmmj-unsub.h Tue Sep 14 21:06:44 2004 +1000 +++ b/include/mlmmj-unsub.h Fri Sep 24 00:29:31 2004 +1000 @@ -27,10 +27,11 @@ #include <sys/types.h> void confirm_unsub(const char *listdir, const char *listaddr, - const char *subaddr, const char *mlmmj, int digest); + 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 *subaddr, const char *mlmmjsend, - int digest); + enum subtype typesub); #endif /* MLMMJ_UNSUBSCRIBE_H */
--- a/include/mlmmj.h Tue Sep 14 21:06:44 2004 +1000 +++ b/include/mlmmj.h Fri Sep 24 00:29:31 2004 +1000 @@ -65,6 +65,13 @@ char **values; }; +/* Has to go here, since it's used in many places */ +enum subtype { + SUB_NORMAL, + SUB_DIGEST, + SUB_NOMAIL +}; + void print_version(const char *prg); #define MY_ASSERT(expression) if (!(expression)) { \
--- a/include/subscriberfuncs.h Tue Sep 14 21:06:44 2004 +1000 +++ b/include/subscriberfuncs.h Fri Sep 24 00:29:31 2004 +1000 @@ -25,6 +25,7 @@ #define SUBSCRIBERFUNC_H off_t find_subscriber(int fd, const char *address); +int is_subbed_in(const char *subddirname, const char *address); int is_subbed(const char *listdir, const char *address); #endif /* SUBSCRIBERFUNC_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/listtexts/notifysub-nomail Fri Sep 24 00:29:31 2004 +1000 @@ -0,0 +1,10 @@ +Hi, this is the mlmmj program managing the mailinglist + +*LSTADDR* + + +The following address has just subscribed to the nomail version of the +mailinglist: + +*SUBADDR* +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/listtexts/notifyunsub-nomail Fri Sep 24 00:29:31 2004 +1000 @@ -0,0 +1,10 @@ +Hi, this is the mlmmj program managing the mailinglist + +*LSTADDR* + + +The following address has just unsubscribed from the nomail version of +mailinglist: + +*SUBADDR* +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/listtexts/sub-confirm-nomail Fri Sep 24 00:29:31 2004 +1000 @@ -0,0 +1,31 @@ +Hi, this is the mlmmj program managing the mailinglist + +*LSTADDR* + + +To confirm you want the address + +*SUBADDR* + + +added to the nomail version of this list, please send a reply to + +*CNFADDR* + + +You are getting this mail because of two possible scenarios: + +1) You want to be subscribed to the list without getting any mail from it, + because you have other means of reading it, and have sent an email + specifically to subscribe + +2) You have tried to post to a list that only allows posting from sub- + scribers. In this case simply reply to this mail, and you will be + able to post to the list with this emailaddress in the future + +Your mailer probably automatically replies to this address, when you hit +the reply button. + +This confirmation serves two purposes. It tests that mail can be sent to your +address. Second, it makes sure someone else did not try and subscribe your +emailaddress.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/listtexts/sub-ok-nomail Fri Sep 24 00:29:31 2004 +1000 @@ -0,0 +1,6 @@ +WELCOME! You have been subscribed to the nomail version of the + +*LSTADDR* + + +mailinglist.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/listtexts/unsub-confirm-nomail Fri Sep 24 00:29:31 2004 +1000 @@ -0,0 +1,21 @@ +Hi, this is the mlmmj program managing the mailinglist + +*LSTADDR* + + +To confirm you want the address + +*SUBADDR* + + +removed from the nomail version of this list, please send a reply to + +*CNFADDR* + + +Your mailer probably automatically replies to this address, when you hit +the reply button. + +If you're not subscribed with this list, you will recieve no reply. You can +see in the From header of a mail to the mailinglist which mail you're sub- +scribed with.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/listtexts/unsub-ok-nomail Fri Sep 24 00:29:31 2004 +1000 @@ -0,0 +1,6 @@ +GOODBYE! You have been removed from the nomail version of the + +*LSTADDR* + + +mailinglist.
--- a/man/mlmmj-sub.1 Tue Sep 14 21:06:44 2004 +1000 +++ b/man/mlmmj-sub.1 Fri Sep 24 00:29:31 2004 +1000 @@ -3,19 +3,23 @@ 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] [\fI-h\fR] -[\fI-U\fR] [\fI-V\fR] +\fI-L /path/to/list -a john@doe.org \fR[\fI-c\fR | \fI-C\fR] \fR[\fI-d\fR | \fI-n\fR] +[\fI-h\fR] [\fI-U\fR] [\fI-V\fR] .HP \fB\-a\fR: Email address to subscribe .HP \fB\-c\fR: Send welcome mail .HP +\fB\-d\fR: Subscribe to digest version of the list +.HP \fB\-C\fR: Request mail confirmation .HP \fB\-h\fR: This help .HP \fB\-L\fR: Full path to list directory .HP +\fB\-n\fR: Subscribe to nomail version of the list +.HP \fB\-U\fR: Don't switch to the user id of the listdir owner .HP \fB\-V\fR: Print version @@ -28,6 +32,11 @@ owning the list directory. This is done to make sure that new files created are having correct permissions. +The nomail version of the list is a list version where people are subscribed +like usual, but they won't recieve any postings to the list. This is useful for +people who read the mailinglist through a news gateway, but want to be able to +post to the list. + When neither \fB\-c\fR nor \fB\-C\fR are specified, subscription silently happens. .SH "SEE ALSO"
--- a/man/mlmmj-unsub.1 Tue Sep 14 21:06:44 2004 +1000 +++ b/man/mlmmj-unsub.1 Fri Sep 24 00:29:31 2004 +1000 @@ -4,7 +4,7 @@ .SH SYNOPSIS .B mlmmj-sub \fI-L /path/to/list -a john@doe.org \fR[\fI-c\fR | \fI-C\fR] [\fI-h\fR] -[\fI-V\fR] +\fR[\fI-d\fR | \fI-n\fR] [\fI-V\fR] .HP \fB\-a\fR: Email address to unsubscribe .HP @@ -12,10 +12,14 @@ .HP \fB\-C\fR: Request mail confirmation .HP +\fB\-d\fR: Unsubscribe from the digest version of the list +.HP \fB\-h\fR: This help .HP \fB\-L\fR: Full path to list directory .HP +\fB\-n\fR: Unsubscribe from the nomail version of the list +.HP \fB\-V\fR: Print version .SH DESCRIPTION This utility is used to unsubscribe people from the specified mailinglist. It
--- a/src/listcontrol.c Tue Sep 14 21:06:44 2004 +1000 +++ b/src/listcontrol.c Fri Sep 24 00:29:31 2004 +1000 @@ -44,12 +44,16 @@ enum ctrl_e { CTRL_SUBSCRIBE_DIGEST, + CTRL_SUBSCRIBE_NOMAIL, CTRL_SUBSCRIBE, CTRL_CONFSUB_DIGEST, + CTRL_CONFSUB_NOMAIL, CTRL_CONFSUB, CTRL_UNSUBSCRIBE_DIGEST, + CTRL_UNSUBSCRIBE_NOMAIL, CTRL_UNSUBSCRIBE, CTRL_CONFUNSUB_DIGEST, + CTRL_CONFUNSUB_NOMAIL, CTRL_CONFUNSUB, CTRL_BOUNCES, CTRL_MODERATE, @@ -70,12 +74,16 @@ * first to match correctly. */ static struct ctrl_command ctrl_commands[] = { { "subscribe-digest", 0 }, + { "subscribe-nomail", 0 }, { "subscribe", 0 }, { "confsub-digest", 1 }, + { "confsub-nomail", 1 }, { "confsub", 1 }, { "unsubscribe-digest", 0 }, + { "unsubscribe-nomail", 0 }, { "unsubscribe", 0 }, { "confunsub-digest", 1 }, + { "confunsub-nomail", 1 }, { "confunsub", 1 }, { "bounces", 1 }, { "moderate", 1 }, @@ -167,6 +175,24 @@ exit(EXIT_FAILURE); break; + /* listname+subscribe-nomail@domain.tld */ + case CTRL_SUBSCRIBE_NOMAIL: + unlink(mailname); + if (closedlist) + exit(EXIT_SUCCESS); + if (!strchr(fromemails->emaillist[0], '@')) + /* Not a valid From: address, silently ignore */ + exit(EXIT_SUCCESS); + execlp(mlmmjsub, mlmmjsub, + "-L", listdir, + "-a", fromemails->emaillist[0], + "-n", + "-C", NULL); + log_error(LOG_ARGS, "execlp() of '%s' failed", + mlmmjsub); + exit(EXIT_FAILURE); + break; + /* listname+subscribe@domain.tld */ case CTRL_SUBSCRIBE: unlink(mailname); @@ -209,6 +235,31 @@ exit(EXIT_FAILURE); break; + /* listname+subconf-nomail-COOKIE@domain.tld */ + case CTRL_CONFSUB_NOMAIL: + unlink(mailname); + if (closedlist) + exit(EXIT_SUCCESS); + conffilename = concatstr(3, listdir, "/subconf/", param); + myfree(param); + if((tmpfd = open(conffilename, O_RDONLY)) < 0) { + /* invalid COOKIE, silently ignore */ + exit(EXIT_SUCCESS); + } + tmpstr = mygetline(tmpfd); + chomp(tmpstr); + close(tmpfd); + unlink(conffilename); + execlp(mlmmjsub, mlmmjsub, + "-L", listdir, + "-a", tmpstr, + "-n", + "-c", NULL); + log_error(LOG_ARGS, "execlp() of '%s' failed", + mlmmjsub); + exit(EXIT_FAILURE); + break; + /* listname+subconf-COOKIE@domain.tld */ case CTRL_CONFSUB: unlink(mailname); @@ -251,6 +302,24 @@ exit(EXIT_FAILURE); break; + /* listname+unsubscribe-nomail@domain.tld */ + case CTRL_UNSUBSCRIBE_NOMAIL: + unlink(mailname); + if (closedlist) + exit(EXIT_SUCCESS); + if (!strchr(fromemails->emaillist[0], '@')) + /* Not a valid From: address, silently ignore */ + exit(EXIT_SUCCESS); + execlp(mlmmjunsub, mlmmjunsub, + "-L", listdir, + "-a", fromemails->emaillist[0], + "-n", + "-C", NULL); + log_error(LOG_ARGS, "execlp() of '%s' failed", + mlmmjunsub); + exit(EXIT_FAILURE); + break; + /* listname+unsubscribe@domain.tld */ case CTRL_UNSUBSCRIBE: unlink(mailname); @@ -293,6 +362,31 @@ exit(EXIT_FAILURE); break; + /* listname+unsubconf-nomail-COOKIE@domain.tld */ + case CTRL_CONFUNSUB_NOMAIL: + unlink(mailname); + if (closedlist) + exit(EXIT_SUCCESS); + conffilename = concatstr(3, listdir, "/unsubconf/", param); + myfree(param); + if((tmpfd = open(conffilename, O_RDONLY)) < 0) { + /* invalid COOKIE, silently ignore */ + exit(EXIT_SUCCESS); + } + tmpstr = mygetline(tmpfd); + close(tmpfd); + chomp(tmpstr); + unlink(conffilename); + execlp(mlmmjunsub, mlmmjunsub, + "-L", listdir, + "-a", tmpstr, + "-n", + "-c", NULL); + log_error(LOG_ARGS, "execlp() of '%s' failed", + mlmmjunsub); + exit(EXIT_FAILURE); + break; + /* listname+unsubconf-COOKIE@domain.tld */ case CTRL_CONFUNSUB: unlink(mailname);
--- a/src/mlmmj-make-ml.sh Tue Sep 14 21:06:44 2004 +1000 +++ b/src/mlmmj-make-ml.sh Fri Sep 24 00:29:31 2004 +1000 @@ -67,7 +67,8 @@ mkdir -p $LISTDIR for DIR in incoming queue queue/discarded archive text subconf unsubconf \ - bounce control moderation subscribers.d digesters.d requeue + bounce control moderation subscribers.d digesters.d requeue \ + nomailsubs.d do mkdir "$LISTDIR"/"$DIR" done
--- a/src/mlmmj-send.c Tue Sep 14 21:06:44 2004 +1000 +++ b/src/mlmmj-send.c Fri Sep 24 00:29:31 2004 +1000 @@ -472,6 +472,7 @@ size_t len = 0, hdrslen, bodylen; int sockfd = 0, mailfd = 0, opt, mindex, subfd, tmpfd; int deletewhensent = 1, sendres, archive = 1, digest = 0; + int ctrlarchive; char *listaddr, *mailfilename = NULL, *subfilename = NULL; char *replyto = NULL, *bounceaddr = NULL, *to_addr = NULL; char *relayhost = NULL, *archivefilename = NULL, *tmpstr; @@ -611,6 +612,7 @@ addtohdr = statctrl(listdir, "addtohdr"); memmailsizestr = ctrlvalue(listdir, "memorymailsize"); + ctrlarchive = statctrl(listdir, "noarchive"); if(memmailsizestr) { memmailsize = strtol(memmailsizestr, NULL, 10); myfree(memmailsizestr); @@ -865,7 +867,10 @@ close(mailfd); if(archive) { + if(!ctrlarchive) rename(mailfilename, archivefilename); + else + unlink(mailfilename); myfree(archivefilename); } else if(deletewhensent) unlink(mailfilename);
--- a/src/mlmmj-sub.c Tue Sep 14 21:06:44 2004 +1000 +++ b/src/mlmmj-sub.c Fri Sep 24 00:29:31 2004 +1000 @@ -48,16 +48,25 @@ void confirm_sub(const char *listdir, const char *listaddr, const char *subaddr, const char *mlmmjsend, - int digest) + enum subtype typesub) { int subtextfd, queuefd; char *buf, *subtextfilename, *randomstr, *queuefilename = NULL; - char *fromaddr, *listname, *listfqdn, *s1; + char *fromaddr, *listname, *listfqdn, *s1, *subject; - if (!digest) { - subtextfilename = concatstr(2, listdir, "/text/sub-ok"); - } else { - subtextfilename = concatstr(2, listdir, "/text/sub-ok-digest"); + switch(typesub) { + case SUB_NORMAL: + subtextfilename = concatstr(2, listdir, + "/text/sub-ok"); + break; + case SUB_DIGEST: + subtextfilename = concatstr(2, listdir, + "/text/sub-ok-digest"); + break; + case SUB_NOMAIL: + subtextfilename = concatstr(2, listdir, + "/text/sub-ok-nomail"); + break; } if((subtextfd = open(subtextfilename, O_RDONLY)) < 0) { @@ -89,16 +98,23 @@ fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn); - if (!digest) { - s1 = concatstr(9, "From: ", listname, "+help@", listfqdn, - "\nTo: ", subaddr, "\nSubject: Welcome to ", - listaddr, "\n\n"); - } else { - s1 = concatstr(9, "From: ", listname, "+help@", listfqdn, - "\nTo: ", subaddr, "\nSubject: Welcome to " - "digest of ", listaddr, "\n\n"); + switch(typesub) { + case SUB_NORMAL: + subject = mystrdup("to "); + break; + case SUB_DIGEST: + subject = mystrdup("to digest of "); + break; + case SUB_NOMAIL: + subject = mystrdup("to nomail version of "); + break; } + s1 = concatstr(10, "From: ", listname, "+help@", listfqdn, "\nTo: ", + subaddr, "\nSubject: Welcome ", subject, listaddr, + "\n\n"); + myfree(subject); + if(writen(queuefd, s1, strlen(s1)) < 0) { log_error(LOG_ARGS, "Could not write welcome mail"); exit(EXIT_FAILURE); @@ -138,11 +154,11 @@ void notify_sub(const char *listdir, const char *listaddr, const char *subaddr, const char *mlmmjsend, - int digest) + enum subtype typesub) { char *maildata[4] = { "*LSTADDR*", NULL, "*SUBADDR*", NULL }; char *listfqdn, *listname, *fromaddr, *fromstr, *subject; - char *queuefilename = NULL; + char *queuefilename = NULL, *listtext; listname = genlistname(listaddr); listfqdn = genlistfqdn(listaddr); @@ -150,19 +166,31 @@ maildata[3] = mystrdup(subaddr); fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn); fromstr = concatstr(3, listname, "+owner@", listfqdn); - if (!digest) { - subject = concatstr(2, "New subscription to ", listaddr); - queuefilename = prepstdreply(listdir, "notifysub", fromstr, - fromstr, NULL, subject, 2, - maildata); - } else { - subject = concatstr(2, "New subscription to digest of ", + + switch(typesub) { + case SUB_NORMAL: + subject = concatstr(2, + "New subscription to ", listaddr); + listtext = mystrdup("notifysub"); + break; + case SUB_DIGEST: + subject = concatstr(2, + "New subscription to digest of ", listaddr); - queuefilename = prepstdreply(listdir, "notifysub-digest", - fromstr, fromstr, NULL, - subject, 2, maildata); + listtext = mystrdup("notifysub-digest"); + break; + case SUB_NOMAIL: + subject = concatstr(2, + "New subscription to nomail of ", + listaddr); + listtext = mystrdup("notifysub-nomail"); + break; } + + queuefilename = prepstdreply(listdir, listtext, fromstr, fromstr, + NULL, subject, 2, maildata); MY_ASSERT(queuefilename) + myfree(listtext); myfree(listname); myfree(listfqdn); myfree(subject); @@ -182,12 +210,12 @@ void generate_subconfirm(const char *listdir, const char *listaddr, const char *subaddr, const char *mlmmjsend, - int digest) + enum subtype typesub) { int subconffd, subtextfd, queuefd; char *confirmaddr, *listname, *listfqdn, *confirmfilename = NULL; char *subtextfilename, *queuefilename = NULL, *fromaddr; - char *buf, *s1, *randomstr = NULL; + char *buf, *s1, *randomstr = NULL, *tmpstr, *subject; listname = genlistname(listaddr); listfqdn = genlistfqdn(listaddr); @@ -225,17 +253,28 @@ fromaddr = concatstr(5, listname, "+bounces-confsub-", randomstr, "@", listfqdn); - if (!digest) { - subtextfilename = concatstr(2, listdir, "/text/sub-confirm"); - confirmaddr = concatstr(5, listname, "+confsub-", - randomstr, "@", listfqdn); - } else { - subtextfilename = concatstr(2, listdir, "/text/sub-confirm-digest"); - confirmaddr = concatstr(5, listname, "+confsub-digest-", - randomstr, "@", listfqdn); + switch(typesub) { + case SUB_NORMAL: + subtextfilename = concatstr(2, listdir, + "/text/sub-confirm"); + tmpstr = mystrdup("+confsub-"); + break; + case SUB_DIGEST: + subtextfilename = concatstr(2, listdir, + "/text/sub-confirm-digest"); + tmpstr = mystrdup("+confsub-digest-"); + break; + case SUB_NOMAIL: + subtextfilename = concatstr(2, listdir, + "/text/sub-confirm-nomail"); + tmpstr = mystrdup("+confsub-nomail-"); + break; } + confirmaddr = concatstr(5, listname, tmpstr, randomstr, "@", listfqdn); + myfree(randomstr); + myfree(tmpstr); if((subtextfd = open(subtextfilename, O_RDONLY)) < 0) { log_error(LOG_ARGS, "Could not open '%s'", subtextfilename); @@ -262,15 +301,22 @@ exit(EXIT_FAILURE); } - if (!digest) { - s1 = concatstr(9, "From: ", listname, "+help@", listfqdn, - "\nTo: ", subaddr, "\nSubject: Confirm subscribe to ", + switch(typesub) { + case SUB_NORMAL: + subject = mystrdup("to "); + break; + case SUB_DIGEST: + subject = mystrdup("to digest of "); + break; + case SUB_NOMAIL: + subject = mystrdup("to nomail version of "); + break; + } + + s1 = concatstr(10, "From: ", listname, "+help@", listfqdn, "\nTo: ", + subaddr, "\nSubject: Confirm subscribe ", subject, listaddr, "\n\n"); - } else { - s1 = concatstr(9, "From: ", listname, "+help@", listfqdn, - "\nTo: ", subaddr, "\nSubject: Confirm subscribe to " - "digest of ", listaddr, "\n\n"); - } + myfree(subject); if(writen(queuefd, s1, strlen(s1)) < 0) { log_error(LOG_ARGS, "Could not write subconffile"); @@ -326,13 +372,14 @@ static void print_help(const char *prg) { printf("Usage: %s -L /path/to/list -a john@doe.org " - "[-c] [-C] [-h]\n [-L] [-U] [-V]\n" + "[-c] [-C] [-h]\n [-L] [-d | -n] [-U] [-V]\n" " -a: Email address to subscribe \n" " -c: Send welcome mail\n" " -C: Request mail confirmation\n" " -d: Subscribe to digest of list\n" " -h: This help\n" " -L: Full path to list directory\n" + " -n: Subscribe to no mail version of list\n" " -U: Don't switch to the user id of the listdir owner\n" " -V: Print version\n" "When no options are specified, subscription silently " @@ -343,14 +390,15 @@ int main(int argc, char **argv) { char *listaddr, *listdir = NULL, *address = NULL, *subfilename = NULL; - char *mlmmjsend, *bindir, chstr[2]; + char *mlmmjsend, *bindir, chstr[2], *subdir; int subconfirm = 0, confirmsub = 0, opt, subfilefd, lock, notifysub; - int changeuid = 1, status, digest = 0; + int changeuid = 1, status, digest = 0, nomail = 0; size_t len; off_t suboff; struct stat st; pid_t pid, childpid; uid_t uid; + enum subtype typesub = SUB_NORMAL; CHECKFULLPATH(argv[0]); @@ -360,7 +408,7 @@ mlmmjsend = concatstr(2, bindir, "/mlmmj-send"); myfree(bindir); - while ((opt = getopt(argc, argv, "hcCdVL:a:")) != -1) { + while ((opt = getopt(argc, argv, "hcCdnVL:a:")) != -1) { switch(opt) { case 'a': address = optarg; @@ -380,6 +428,9 @@ case 'L': listdir = optarg; break; + case 'n': + nomail = 1; + break; case 'U': changeuid = 0; break; @@ -388,12 +439,24 @@ exit(0); } } + if(listdir == 0 || address == 0) { fprintf(stderr, "You have to specify -L and -a\n"); fprintf(stderr, "%s -h for help\n", argv[0]); exit(EXIT_FAILURE); } + if(digest && nomail) { + fprintf(stderr, "Specify either -d or -n, not both\n"); + fprintf(stderr, "%s -h for help\n", argv[0]); + exit(EXIT_FAILURE); + } + + if(digest) + typesub = SUB_DIGEST; + if(nomail) + typesub = SUB_NOMAIL; + if(confirmsub && subconfirm) { fprintf(stderr, "Cannot specify both -C and -c\n"); fprintf(stderr, "%s -h for help\n", argv[0]); @@ -422,12 +485,22 @@ chstr[0] = address[0]; chstr[1] = '\0'; - if (!digest) { - subfilename = concatstr(3, listdir, "/subscribers.d/", chstr); - } else { - subfilename = concatstr(3, listdir, "/digesters.d/", chstr); + + switch(typesub) { + case SUB_NORMAL: + subdir = mystrdup("/subscribers.d/"); + break; + case SUB_DIGEST: + subdir = mystrdup("/digesters.d/"); + break; + case SUB_NOMAIL: + subdir = mystrdup("/nomailsubs.d/"); + break; } + subfilename = concatstr(3, listdir, subdir, chstr); + myfree(subdir); + subfilefd = open(subfilename, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); if(subfilefd == -1) { log_error(LOG_ARGS, "Could not open '%s'", subfilename); @@ -444,7 +517,7 @@ if(suboff == -1) { if(subconfirm) generate_subconfirm(listdir, listaddr, address, - mlmmjsend, digest); + mlmmjsend, typesub); else { lseek(subfilefd, 0L, SEEK_END); len = strlen(address); @@ -466,7 +539,7 @@ if(childpid < 0) { log_error(LOG_ARGS, "Could not fork"); confirm_sub(listdir, listaddr, address, mlmmjsend, - digest); + typesub); } if(childpid > 0) { @@ -478,14 +551,14 @@ /* child confirms subscription */ if(childpid == 0) confirm_sub(listdir, listaddr, address, mlmmjsend, - digest); + typesub); } notifysub = statctrl(listdir, "notifysub"); /* Notify list owner about subscription */ if (notifysub) - notify_sub(listdir, listaddr, address, mlmmjsend, digest); + notify_sub(listdir, listaddr, address, mlmmjsend, typesub); myfree(listaddr);
--- a/src/mlmmj-unsub.c Tue Sep 14 21:06:44 2004 +1000 +++ b/src/mlmmj-unsub.c Fri Sep 24 00:29:31 2004 +1000 @@ -47,17 +47,26 @@ #include "prepstdreply.h" void confirm_unsub(const char *listdir, const char *listaddr, - const char *subaddr, const char *mlmmjsend, int digest) + const char *subaddr, const char *mlmmjsend, + enum subtype typesub) { int subtextfd, queuefd; char *buf, *subtextfilename, *randomstr, *queuefilename = NULL; - char *fromaddr, *listname, *listfqdn, *s1; + char *fromaddr, *listname, *listfqdn, *s1, *subject; - if (!digest) { - subtextfilename = concatstr(2, listdir, "/text/unsub-ok"); - } else { + switch(typesub) { + case SUB_NORMAL: + subtextfilename = concatstr(2, listdir, + "/text/sub-ok"); + break; + case SUB_DIGEST: subtextfilename = concatstr(2, listdir, - "/text/unsub-ok-digest"); + "/text/sub-ok-digest"); + break; + case SUB_NOMAIL: + subtextfilename = concatstr(2, listdir, + "/text/sub-ok-nomail"); + break; } if((subtextfd = open(subtextfilename, O_RDONLY)) < 0) { @@ -89,16 +98,23 @@ fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn); - if (!digest) { - s1 = concatstr(9, "From: ", listname, "+help@", listfqdn, - "\nTo: ", subaddr, "\nSubject: Goodbye from ", - listaddr, "\n\n"); - } else { - s1 = concatstr(9, "From: ", listname, "+help@", listfqdn, - "\nTo: ", subaddr, "\nSubject: Goodbye from " - "digest of ", listaddr, "\n\n"); + switch(typesub) { + case SUB_NORMAL: + subject = mystrdup("from "); + break; + case SUB_DIGEST: + subject = mystrdup("from digest of "); + break; + case SUB_NOMAIL: + subject = mystrdup("from nomail version of "); + break; } + s1 = concatstr(10, "From: ", listname, "+help@", listfqdn, "\nTo: ", + subaddr, "\nSubject: Goodbye ", subject, listaddr, + "\n\n"); + myfree(subject); + if(writen(queuefd, s1, strlen(s1)) < 0) { log_error(LOG_ARGS, "Could not write subconffile"); exit(EXIT_FAILURE); @@ -137,11 +153,12 @@ } void notify_unsub(const char *listdir, const char *listaddr, - const char *subaddr, const char *mlmmjsend, int digest) + const char *subaddr, const char *mlmmjsend, + enum subtype typesub) { char *maildata[4] = { "*LSTADDR*", NULL, "*SUBADDR*", NULL }; char *listfqdn, *listname, *fromaddr, *fromstr, *subject; - char *queuefilename = NULL; + char *queuefilename = NULL, *listtext; listname = genlistname(listaddr); listfqdn = genlistfqdn(listaddr); @@ -149,18 +166,32 @@ maildata[3] = mystrdup(subaddr); fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn); fromstr = concatstr(3, listname, "+owner@", listfqdn); - if (!digest) { - subject = concatstr(2, "Unsubscription from ", listaddr); - queuefilename = prepstdreply(listdir, "notifyunsub", fromstr, - fromstr, NULL, subject, 2, maildata); - } else { - subject = concatstr(2, "Unsubscription from digest of ", + + switch(typesub) { + case SUB_NORMAL: + subject = concatstr(2, + "Unsubscription from ", listaddr); + listtext = mystrdup("notifyunsub"); + break; + case SUB_DIGEST: + subject = concatstr(2, + "Unsubscription from digest of ", listaddr); - queuefilename = prepstdreply(listdir, "notifyunsub-digest", - fromstr, fromstr, NULL, subject, 2, - maildata); + listtext = mystrdup("notifyunsub-digest"); + break; + case SUB_NOMAIL: + subject = concatstr(2, + "Unsubscription from nomail of ", + listaddr); + listtext = mystrdup("notifyunsub-nomail"); + break; } - MY_ASSERT(queuefilename) + + + queuefilename = prepstdreply(listdir, listtext, fromstr, fromstr, + NULL, subject, 2, maildata); + MY_ASSERT(queuefilename); + myfree(listtext); myfree(listname); myfree(listfqdn); myfree(subject); @@ -181,11 +212,11 @@ void generate_unsubconfirm(const char *listdir, const char *listaddr, const char *subaddr, const char *mlmmjsend, - int digest) + enum subtype typesub) { - char *confirmaddr, *buf, *listname, *listfqdn; + char *confirmaddr, *buf, *listname, *listfqdn, *tmpstr; char *subtextfilename, *queuefilename = NULL, *fromaddr, *s1; - char *randomstr = NULL, *confirmfilename = NULL; + char *randomstr = NULL, *confirmfilename = NULL, *subject; int subconffd, subtextfd, queuefd; listname = genlistname(listaddr); @@ -224,18 +255,28 @@ fromaddr = concatstr(5, listname, "+bounces-confunsub-", randomstr, "@", listfqdn); - if (!digest) { - subtextfilename = concatstr(2, listdir, "/text/unsub-confirm"); - confirmaddr = concatstr(5, listname, "+confunsub-", randomstr, - "@", listfqdn); - } else { + switch(typesub) { + case SUB_NORMAL: + subtextfilename = concatstr(2, listdir, + "/text/unsub-confirm"); + tmpstr = mystrdup("+confunsub-"); + break; + case SUB_DIGEST: subtextfilename = concatstr(2, listdir, "/text/unsub-confirm-digest"); - confirmaddr = concatstr(5, listname, "+confunsub-digest-", - randomstr, "@", listfqdn); + tmpstr = mystrdup("+confunsub-digest-"); + break; + case SUB_NOMAIL: + subtextfilename = concatstr(2, listdir, + "/text/unsub-confirm-nomail"); + tmpstr = mystrdup("+confunsub-nomail-"); + break; } + confirmaddr = concatstr(5, listname, tmpstr, randomstr, "@", listfqdn); + myfree(randomstr); + myfree(tmpstr); if((subtextfd = open(subtextfilename, O_RDONLY)) < 0) { log_error(LOG_ARGS, "Could not open '%s'", subtextfilename); @@ -261,17 +302,22 @@ exit(EXIT_FAILURE); } - if (!digest) { - s1 = concatstr(9, "From: ", listname, "+help@", listfqdn, - "\nTo: ", subaddr, "\nSubject: Confirm " - "unsubscribe from ", listaddr, "\n\n"); - } else { - s1 = concatstr(9, "From: ", listname, "+help@", listfqdn, - "\nTo: ", subaddr, "\nSubject: Confirm " - "unsubscribe from digest of ", listaddr, - "\n\n"); + switch(typesub) { + case SUB_NORMAL: + subject = mystrdup("from "); + break; + case SUB_DIGEST: + subject = mystrdup("from digest of "); + break; + case SUB_NOMAIL: + subject = mystrdup("from nomail version of "); + break; } + s1 = concatstr(10, "From: ", listname, "+help@", listfqdn, "\nTo: ", + subaddr, "\nSubject: Confirm unsubscribe ", subject, + listaddr, "\n\n"); + if(writen(queuefd, s1, strlen(s1)) < 0) { log_error(LOG_ARGS, "Could not write subconffile"); exit(EXIT_FAILURE); @@ -362,13 +408,14 @@ static void print_help(const char *prg) { printf("Usage: %s -L /path/to/list -a john@doe.org " - "[-c] [-C] [-h] [-L] [-V]\n" + "[-c] [-C] [-h] [-L] [-d | -n] [-V]\n" " -a: Email address to unsubscribe \n" " -c: Send goodbye mail\n" " -C: Request mail confirmation\n" " -d: Subscribe to digest of list\n" " -h: This help\n" " -L: Full path to list directory\n" + " -n: Subscribe to no mail version of list\n" " -V: Print version\n" "When no options are specified, unsubscription silently " "happens\n", prg); @@ -377,15 +424,16 @@ int main(int argc, char **argv) { - int subread, subwrite, rlock, wlock, opt, unsubres, status; + int subread, subwrite, rlock, wlock, opt, unsubres, status, nomail = 0; int confirmunsub = 0, unsubconfirm = 0, notifysub = 0, digest = 0; char *listaddr, *listdir = NULL, *address = NULL, *subreadname = NULL; - char *subwritename, *mlmmjsend, *bindir; + char *subwritename, *mlmmjsend, *bindir, *subdir; char *subddirname; off_t suboff; DIR *subddir; struct dirent *dp; pid_t pid, childpid; + enum subtype typesub = SUB_NORMAL; CHECKFULLPATH(argv[0]); @@ -395,11 +443,14 @@ mlmmjsend = concatstr(2, bindir, "/mlmmj-send"); myfree(bindir); - while ((opt = getopt(argc, argv, "hcCdVL:a:")) != -1) { + while ((opt = getopt(argc, argv, "hcCdnVL:a:")) != -1) { switch(opt) { case 'L': listdir = optarg; break; + case 'n': + nomail = 1; + break; case 'a': address = optarg; break; @@ -426,6 +477,17 @@ exit(EXIT_FAILURE); } + if(digest && nomail) { + fprintf(stderr, "Specify either -d or -n, not both\n"); + fprintf(stderr, "%s -h for help\n", argv[0]); + exit(EXIT_FAILURE); + } + + if(digest) + typesub = SUB_DIGEST; + if(nomail) + typesub = SUB_NOMAIL; + if(confirmunsub && unsubconfirm) { fprintf(stderr, "Cannot specify both -C and -c\n"); fprintf(stderr, "%s -h for help\n", argv[0]); @@ -435,34 +497,50 @@ /* get the list address */ listaddr = getlistaddr(listdir); + switch(typesub) { + case SUB_NORMAL: + subdir = mystrdup("/subscribers.d/"); + break; + case SUB_DIGEST: + subdir = mystrdup("/digesters.d/"); + break; + case SUB_NOMAIL: + subdir = mystrdup("/nomailsubs.d/"); + break; + } + + subddirname = concatstr(2, listdir, subdir); + + if(is_subbed_in(subddirname, address)) { + /* Address is not subscribed, so exit silently */ + myfree(subddirname); + myfree(subdir); + myfree(listaddr); + exit(EXIT_SUCCESS); + } + if(unsubconfirm) generate_unsubconfirm(listdir, listaddr, address, mlmmjsend, - digest); + typesub); - if (!digest) { - subddirname = concatstr(2, listdir, "/subscribers.d/"); - } else { - subddirname = concatstr(2, listdir, "/digesters.d/"); - } if((subddir = opendir(subddirname)) == NULL) { log_error(LOG_ARGS, "Could not opendir(%s)", subddirname); myfree(subddirname); + myfree(subdir); + myfree(listaddr); exit(EXIT_FAILURE); } + myfree(subddirname); + while((dp = readdir(subddir)) != NULL) { if(!strcmp(dp->d_name, ".")) continue; if(!strcmp(dp->d_name, "..")) continue; - if (!digest) { - subreadname = concatstr(3, listdir, "/subscribers.d/", - dp->d_name); - } else { - subreadname = concatstr(3, listdir, "/digesters.d/", - dp->d_name); - } + + subreadname = concatstr(3, listdir, subdir, dp->d_name); subread = open(subreadname, O_RDWR); if(subread == -1) { @@ -574,12 +652,13 @@ } } + myfree(subdir); notifysub = statctrl(listdir, "notifysub"); /* Notify list owner about subscription */ if (notifysub) - notify_unsub(listdir, listaddr, address, mlmmjsend, digest); + notify_unsub(listdir, listaddr, address, mlmmjsend, typesub); myfree(listaddr);
--- a/src/subscriberfuncs.c Tue Sep 14 21:06:44 2004 +1000 +++ b/src/subscriberfuncs.c Fri Sep 24 00:29:31 2004 +1000 @@ -87,7 +87,7 @@ return (off_t)-1; } -static int is_subbed_in(const char *subddirname, const char *address) +int is_subbed_in(const char *subddirname, const char *address) { int retval = 1, subread; char *subreadname; @@ -148,5 +148,11 @@ if (retval == 0) return 0; + subddirname = concatstr(2, listdir, "/nomailsubs.d/"); + retval = is_subbed_in(subddirname, address); + myfree(subddirname); + if (retval == 0) + return 0; + return 1; }