Mercurial > hg > mlmmj
changeset 291:7da5c55b9330
0.8.3 commit
author | mmj |
---|---|
date | Thu, 12 Aug 2004 08:29:38 +1000 |
parents | 1180bcbc90d9 |
children | 958a3ecff04c |
files | ChangeLog README TODO TUNABLES UPGRADE VERSION listtexts/notifysub listtexts/notifyunsub src/Makefile.am src/chomp.c src/ctrlvalue.c src/listcontrol.c src/mlmmj-make-ml.sh src/mlmmj-process.c src/mlmmj-send.c src/mlmmj-sub.c src/mlmmj-unsub.c |
diffstat | 17 files changed, 250 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Sat Jul 10 06:28:16 2004 +1000 +++ b/ChangeLog Thu Aug 12 08:29:38 2004 +1000 @@ -1,3 +1,14 @@ +0.8.3 + o Have mlmmj-make-ml.sh remind people about using cron if they want + o Replying to the confirmation address is enough to sub/unsub, no matter what + address is used the second time + o Fix possible DoS wrt. unsubscribing. Thank you Erik Toubro Nielsen + o Add 'notifysub' functionality to have owner know when people sub/unsub. + Thank you Kenneth Vestergaard Schmidt + o Use Return-Path: for envelope From. Thanks Anders Johansson + o Specification of which relayhost to use can now be done in control/relayhost + o Add configure check to link against libnsl if needed. + o Implement our own daemon() function since we don't have daemon() on Solaris 0.8.2 o Make sure we don't cut of the first char of an emailaddress o Fix header value copying (thanks Anders Johansson)
--- a/README Sat Jul 10 06:28:16 2004 +1000 +++ b/README Thu Aug 12 08:29:38 2004 +1000 @@ -1,4 +1,4 @@ -README mlmmj-0.8.2 Jul 3rd 2004 +README mlmmj-0.8.3 Aug 11th 2004 This is an attempt at implementing a mailing list manager with the same functionality as the brilliant ezmlm, but with a decent license and mail server
--- a/TODO Sat Jul 10 06:28:16 2004 +1000 +++ b/TODO Thu Aug 12 08:29:38 2004 +1000 @@ -1,11 +1,9 @@ Code cleanup: - o Convert opening of write files to openrandexclrw o Add some more logging to mlmmj-maintd--actually we have to rethink logging a bit. Do we want to use our own /var/log/mlmmj Functionality items: o listname+get functionality - o web interface Nice to do: o Convert mlmmj-sub, mlmmj-unsub and mlmmj-process (moderation) to use
--- a/TUNABLES Sat Jul 10 06:28:16 2004 +1000 +++ b/TUNABLES Thu Aug 12 08:29:38 2004 +1000 @@ -67,3 +67,13 @@ When this file is present, a To: header including the recipients emailaddress will be added to outgoing mail. Recommended usage is to remove existing To: headers with delheaders (see above) first. + + · relayhost (normal) + + The host specified (IP address og domainname, both works) in this file will + be used for relaying the mail sent to the list. Defaults to 127.0.0.1. + + · notifysub (boolean) + + If this file is present, the owner(s) will get a mail with the address of + someone sub/unsubscribing to a mailinglist.
--- a/UPGRADE Sat Jul 10 06:28:16 2004 +1000 +++ b/UPGRADE Thu Aug 12 08:29:38 2004 +1000 @@ -1,4 +1,4 @@ -This applies to everyone using mlmmj > 0.7.3: +This applies to everyone using mlmmj < 0.8.3: --------------------------------------------- Don't forget to upgrade the listtexts!
--- a/VERSION Sat Jul 10 06:28:16 2004 +1000 +++ b/VERSION Thu Aug 12 08:29:38 2004 +1000 @@ -1,1 +1,1 @@ -0.8.2 +0.8.3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/listtexts/notifysub Thu Aug 12 08:29:38 2004 +1000 @@ -0,0 +1,9 @@ +Hi, this is the mlmmj program managing the mailinglist + +*LSTADDR* + + +The following address has just subscribed to the mailinglist: + +*SUBADDR* +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/listtexts/notifyunsub Thu Aug 12 08:29:38 2004 +1000 @@ -0,0 +1,9 @@ +Hi, this is the mlmmj program managing the mailinglist + +*LSTADDR* + + +The following address has just unsubscribed from the mailinglist: + +*SUBADDR* +
--- a/src/Makefile.am Sat Jul 10 06:28:16 2004 +1000 +++ b/src/Makefile.am Thu Aug 12 08:29:38 2004 +1000 @@ -32,12 +32,13 @@ mlmmj_sub_SOURCES = mlmmj-sub.c writen.c mylocking.c \ getlistaddr.c chomp.c random-int.c strgen.c \ subscriberfuncs.c print-version.c \ - log_error.c mygetline.c prepstdreply.c memory.c + log_error.c mygetline.c prepstdreply.c memory.c \ + statctrl.c mlmmj_unsub_SOURCES = mlmmj-unsub.c writen.c mylocking.c \ getlistaddr.c chomp.c subscriberfuncs.c random-int.c \ strgen.c print-version.c log_error.c mygetline.c \ - prepstdreply.c memory.c + prepstdreply.c memory.c statctrl.c mlmmj_bounce_SOURCES = mlmmj-bounce.c print-version.c log_error.c \ subscriberfuncs.c strgen.c random-int.c writen.c \
--- a/src/chomp.c Sat Jul 10 06:28:16 2004 +1000 +++ b/src/chomp.c Thu Aug 12 08:29:38 2004 +1000 @@ -26,7 +26,12 @@ char *chomp(char *str) { - int i = strlen(str) - 1; + size_t i; + + if(str == NULL) + return NULL; + + i = strlen(str) - 1; while(str[i] == '\n') { str[i] = 0;
--- a/src/ctrlvalue.c Sat Jul 10 06:28:16 2004 +1000 +++ b/src/ctrlvalue.c Thu Aug 12 08:29:38 2004 +1000 @@ -35,10 +35,13 @@ char *ctrlvalue(const char *listdir, const char *ctrlstr) { - char *value = NULL; - char *filename = concatstr(3, listdir, "/control/", ctrlstr); + char *filename, *value = NULL; int ctrlfd; + if(listdir == NULL) + return NULL; + + filename = concatstr(3, listdir, "/control/", ctrlstr); ctrlfd = open(filename, O_RDONLY); myfree(filename);
--- a/src/listcontrol.c Sat Jul 10 06:28:16 2004 +1000 +++ b/src/listcontrol.c Thu Aug 12 08:29:38 2004 +1000 @@ -156,11 +156,10 @@ if (closedlist) exit(EXIT_SUCCESS); conffilename = concatstr(3, listdir, "/subconf/", param); myfree(param); - if((tmpfd = open(conffilename, O_RDONLY)) > 0) { + if((tmpfd = open(conffilename, O_RDONLY)) >= 0) { tmpstr = mygetline(tmpfd); chomp(tmpstr); close(tmpfd); - if(strcasecmp(tmpstr, fromemails->emaillist[0]) == 0) { unlink(conffilename); execlp(mlmmjsub, mlmmjsub, "-L", listdir, @@ -169,11 +168,6 @@ log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsub); exit(EXIT_FAILURE); - } else { - /* Not proper confirm */ - myfree(tmpstr); - exit(EXIT_SUCCESS); - } } else /* Not a confirm so silently ignore */ exit(EXIT_SUCCESS); break; @@ -198,11 +192,10 @@ if (closedlist) exit(EXIT_SUCCESS); conffilename = concatstr(3, listdir, "/unsubconf/", param); myfree(param); - if((tmpfd = open(conffilename, O_RDONLY))) { + if((tmpfd = open(conffilename, O_RDONLY)) >= 0) { tmpstr = mygetline(tmpfd); close(tmpfd); chomp(tmpstr); - if(strcasecmp(tmpstr, fromemails->emaillist[0]) == 0) { unlink(conffilename); execlp(mlmmjunsub, mlmmjunsub, "-L", listdir, @@ -211,10 +204,6 @@ log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjunsub); exit(EXIT_FAILURE); - } else { - myfree(tmpstr); - exit(EXIT_SUCCESS); - } } else /* Not a confirm so silently ignore */ exit(EXIT_SUCCESS); break;
--- a/src/mlmmj-make-ml.sh Sat Jul 10 06:28:16 2004 +1000 +++ b/src/mlmmj-make-ml.sh Thu Aug 12 08:29:38 2004 +1000 @@ -100,7 +100,13 @@ MLMMJRECIEVE="/path/to/mlmmj-recieve" fi +MLMMJMAINTD=`which mlmmj-maintd 2>/dev/null` +if [ -z "$MLMMJRECIEVE" ]; then + MLMMJMAINTD="/path/to/mlmmj-maintd" +fi + ALIAS="$LISTNAME: \"|$MLMMJRECIEVE -L $SPOOLDIR/$LISTNAME/\"" +CRONENTRY="0 */2 * * * \"$MLMMJMAINTD -L $SPOOLDIR/$LISTNAME/\"" if [ -n "$A_CREATE" ]; then echo "I want to add the following to your /etc/aliases file:" @@ -123,9 +129,13 @@ echo "Don't forget to add this to /etc/aliases:" echo "$ALIAS" fi +echo +echo "If you're not starting mlmmj-maintd in daemon mode," +echo "don't forget to add this to your crontab:" +echo $CRONENTRY echo echo " ** FINAL NOTES ** 1) The mailinglist directory have to be owned by the user running the mailserver (i.e. starting the binaries to work the list) -2) To run newaliases" +2) Run newaliases"
--- a/src/mlmmj-process.c Sat Jul 10 06:28:16 2004 +1000 +++ b/src/mlmmj-process.c Thu Aug 12 08:29:38 2004 +1000 @@ -495,7 +495,7 @@ recipdelim = NULL; if(recipdelim) { - owner = concatstr(2, listdir, "control/owner"); + owner = concatstr(2, listdir, "/control/owner"); if(owner && strncmp(recipdelim, "+owner@", 7) == 0) { unlink(donemailname); execlp(mlmmjsend, mlmmjsend,
--- a/src/mlmmj-send.c Sat Jul 10 06:28:16 2004 +1000 +++ b/src/mlmmj-send.c Thu Aug 12 08:29:38 2004 +1000 @@ -37,6 +37,10 @@ #include <stdarg.h> #include <sys/mman.h> #include <limits.h> +#include <netdb.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> #include "mlmmj-send.h" #include "mlmmj.h" @@ -461,10 +465,12 @@ char *listctrl = NULL, *subddirname = NULL, *listdir = NULL; char *mlmmjbounce = NULL, *bindir, *mailmap, *probefile, *a; char *body = NULL, *hdrs = NULL, *memmailsizestr = NULL; + char relay[16]; ssize_t memmailsize = 0; DIR *subddir; struct dirent *dp; struct stat st; + struct hostent *relayent; CHECKFULLPATH(argv[0]); @@ -642,12 +648,27 @@ mindex); } + if(!relayhost) { + relayhost = ctrlvalue(listdir, "relayhost"); + chomp(relayhost); + } if(!relayhost) - relayhost = mystrdup(RELAYHOST); + strncpy(relay, RELAYHOST, sizeof(relay)); + else { + relayent = gethostbyname(relayhost); + if(relayent == NULL) { + strncpy(relay, RELAYHOST, sizeof(relay)); + } else { + if(inet_ntop(relayent->h_addrtype, + relayent->h_addr_list[0], + relay, sizeof(relay)) == NULL) + strncpy(relay, RELAYHOST, sizeof(relay)); + } + } switch(listctrl[0]) { case '1': /* A single mail is to be sent */ - initsmtp(&sockfd, relayhost); + initsmtp(&sockfd, relay); sendres = send_mail(sockfd, bounceaddr, to_addr, replyto, mailmap, st.st_size, listdir, NULL, hdrs, hdrslen, body, bodylen); @@ -690,7 +711,7 @@ } break; case '2': /* Moderators */ - initsmtp(&sockfd, relayhost); + initsmtp(&sockfd, relay); if(send_mail_many(sockfd, bounceaddr, NULL, mailmap, st.st_size, subfd, NULL, NULL, listdir, NULL, hdrs, hdrslen, body, bodylen)) @@ -699,7 +720,7 @@ endsmtp(&sockfd); break; case '3': /* resending earlier failed mails */ - initsmtp(&sockfd, relayhost); + initsmtp(&sockfd, relay); if(send_mail_many(sockfd, NULL, NULL, mailmap, st.st_size, subfd, listaddr, mailfilename, listdir, mlmmjbounce, hdrs, hdrslen, body, bodylen)) @@ -709,7 +730,7 @@ unlink(subfilename); break; case '4': /* send mails to owner */ - initsmtp(&sockfd, relayhost); + initsmtp(&sockfd, relay); if(send_mail_many(sockfd, bounceaddr, NULL, mailmap, st.st_size, subfd, listaddr, mailfilename, listdir, mlmmjbounce, hdrs, hdrslen, body, bodylen)) @@ -718,7 +739,7 @@ endsmtp(&sockfd); break; case '5': /* bounceprobe - handle relayhost local users bouncing*/ - initsmtp(&sockfd, relayhost); + initsmtp(&sockfd, relay); sendres = send_mail(sockfd, bounceaddr, to_addr, replyto, mailmap, st.st_size, listdir, NULL, hdrs, hdrslen, body, bodylen); @@ -762,7 +783,7 @@ } myfree(subfilename); - initsmtp(&sockfd, relayhost); + initsmtp(&sockfd, relay); sendres = send_mail_many(sockfd, NULL, NULL, mailmap, st.st_size, subfd, listaddr, archivefilename, listdir, mlmmjbounce,
--- a/src/mlmmj-sub.c Sat Jul 10 06:28:16 2004 +1000 +++ b/src/mlmmj-sub.c Thu Aug 12 08:29:38 2004 +1000 @@ -31,6 +31,7 @@ #include <sys/stat.h> #include <fcntl.h> #include <libgen.h> +#include <sys/wait.h> #include "mlmmj.h" #include "mlmmj-sub.h" @@ -41,6 +42,8 @@ #include "subscriberfuncs.h" #include "log_error.h" #include "mygetline.h" +#include "statctrl.h" +#include "prepstdreply.h" #include "memory.h" void confirm_sub(const char *listdir, const char *listaddr, @@ -120,6 +123,40 @@ exit(EXIT_FAILURE); } +void notify_sub(const char *listdir, const char *listaddr, + const char *subaddr, const char *mlmmjsend) +{ + char *maildata[4] = { "*LSTADDR*", NULL, "*SUBADDR*", NULL }; + char *listfqdn, *listname, *fromaddr, *fromstr, *subject; + char *queuefilename = NULL; + + listname = genlistname(listaddr); + listfqdn = genlistfqdn(listaddr); + maildata[1] = mystrdup(listaddr); + maildata[3] = mystrdup(subaddr); + fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn); + fromstr = concatstr(3, listname, "+owner@", listfqdn); + subject = concatstr(2, "New subscription to ", listaddr); + queuefilename = prepstdreply(listdir, "notifysub", fromstr, + fromstr, NULL, subject, 2, maildata); + MY_ASSERT(queuefilename) + myfree(listname); + myfree(listfqdn); + myfree(subject); + myfree(maildata[1]); + myfree(maildata[3]); + execlp(mlmmjsend, mlmmjsend, + "-l", "1", + "-T", fromstr, + "-F", fromaddr, + "-m", queuefilename, 0); + + myfree(fromstr); + + log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsend); + exit(EXIT_FAILURE); +} + void generate_subconfirm(const char *listdir, const char *listaddr, const char *subaddr, const char *mlmmjsend) { @@ -270,11 +307,12 @@ { char *listaddr, *listdir = NULL, *address = NULL, *subfilename = NULL; char *mlmmjsend, *bindir, chstr[2]; - int subconfirm = 0, confirmsub = 0, opt, subfilefd, lock; - int changeuid = 1; + int subconfirm = 0, confirmsub = 0, opt, subfilefd, lock, notifysub; + int changeuid = 1, status; size_t len; off_t suboff; struct stat st; + pid_t pid, childpid; CHECKFULLPATH(argv[0]); @@ -376,8 +414,30 @@ return EXIT_SUCCESS; } - if(confirmsub) + if(confirmsub) { + childpid = fork(); + + if(childpid < 0) { + log_error(LOG_ARGS, "Could not fork"); confirm_sub(listdir, listaddr, address, mlmmjsend); + } + + if(childpid > 0) { + do /* Parent waits for the child */ + pid = waitpid(childpid, &status, 0); + while(pid == -1 && errno == EINTR); + } + + /* child confirms subscription */ + if(childpid == 0) + confirm_sub(listdir, listaddr, address, mlmmjsend); + } + + notifysub = statctrl(listdir, "notifysub"); + + /* Notify list owner about subscription */ + if (notifysub) + notify_sub(listdir, listaddr, address, mlmmjsend); myfree(listaddr);
--- a/src/mlmmj-unsub.c Sat Jul 10 06:28:16 2004 +1000 +++ b/src/mlmmj-unsub.c Thu Aug 12 08:29:38 2004 +1000 @@ -31,6 +31,7 @@ #include <fcntl.h> #include <libgen.h> #include <dirent.h> +#include <sys/wait.h> #include "mlmmj.h" #include "mlmmj-unsub.h" @@ -42,6 +43,8 @@ #include "strgen.h" #include "log_error.h" #include "memory.h" +#include "statctrl.h" +#include "prepstdreply.h" void confirm_unsub(const char *listdir, const char *listaddr, const char *subaddr, const char *mlmmjsend) @@ -122,6 +125,41 @@ exit(EXIT_FAILURE); } +void notify_unsub(const char *listdir, const char *listaddr, + const char *subaddr, const char *mlmmjsend) +{ + char *maildata[4] = { "*LSTADDR*", NULL, "*SUBADDR*", NULL }; + char *listfqdn, *listname, *fromaddr, *fromstr, *subject; + char *queuefilename = NULL; + + listname = genlistname(listaddr); + listfqdn = genlistfqdn(listaddr); + maildata[1] = mystrdup(listaddr); + maildata[3] = mystrdup(subaddr); + fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn); + fromstr = concatstr(3, listname, "+owner@", listfqdn); + subject = concatstr(2, "Unsubscription from ", listaddr); + queuefilename = prepstdreply(listdir, "notifyunsub", fromstr, + fromstr, NULL, subject, 2, maildata); + MY_ASSERT(queuefilename) + myfree(listname); + myfree(listfqdn); + myfree(subject); + myfree(maildata[1]); + myfree(maildata[3]); + execlp(mlmmjsend, mlmmjsend, + "-l", "1", + "-T", fromstr, + "-F", fromaddr, + "-m", queuefilename, 0); + + myfree(fromstr); + + log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsend); + exit(EXIT_FAILURE); +} + + void generate_unsubconfirm(const char *listdir, const char *listaddr, const char *subaddr, const char *mlmmjsend) { @@ -303,14 +341,15 @@ int main(int argc, char **argv) { - int subread, subwrite, rlock, wlock, opt, unsubres; - int confirmunsub = 0, unsubconfirm = 0; + int subread, subwrite, rlock, wlock, opt, unsubres, status; + int confirmunsub = 0, unsubconfirm = 0, notifysub = 0; char *listaddr, *listdir = NULL, *address = NULL, *subreadname = NULL; char *subwritename, *mlmmjsend, *bindir; char *subddirname; off_t suboff; DIR *subddir; struct dirent *dp; + pid_t pid, childpid; CHECKFULLPATH(argv[0]); @@ -462,10 +501,37 @@ myfree(subreadname); myfree(subwritename); - if(confirmunsub) - confirm_unsub(listdir, listaddr, address, mlmmjsend); + closedir(subddir); + + if(confirmunsub) { + childpid = fork(); + + if(childpid < 0) { + log_error(LOG_ARGS, "Could not fork"); + confirm_unsub(listdir, listaddr, address, + mlmmjsend); + } + + if(childpid > 0) { + do /* Parent waits for the child */ + pid = waitpid(childpid, &status, 0); + while(pid == -1 && errno == EINTR); } - closedir(subddir); + + /* child confirms subscription */ + if(childpid == 0) + confirm_unsub(listdir, listaddr, address, + mlmmjsend); + } + } + + + notifysub = statctrl(listdir, "notifysub"); + + /* Notify list owner about subscription */ + if (notifysub) + notify_unsub(listdir, listaddr, address, mlmmjsend); + myfree(listaddr); return EXIT_SUCCESS;