changeset 69:4e9e7f2d2e09

Bouncehandling, and massive cleanups around.
author mmj
date Sat, 01 May 2004 19:54:58 +1000
parents 11de6a95c9a8
children f94a79c3fb8b
files ChangeLog VERSION include/getlistaddr.h listtexts/listhelp listtexts/moderation src/Makefile.am src/Makefile.in src/getlistaddr.c src/init_sockfd.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 src/send_help.c src/statctrl.c
diffstat 17 files changed, 317 insertions(+), 187 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Apr 30 19:02:13 2004 +1000
+++ b/ChangeLog	Sat May 01 19:54:58 2004 +1000
@@ -1,3 +1,5 @@
+0.4.0
+ o Add moderation functionality
 0.3.4
  o Fix handling of lines which start with a dot
 0.3.3
--- a/VERSION	Fri Apr 30 19:02:13 2004 +1000
+++ b/VERSION	Sat May 01 19:54:58 2004 +1000
@@ -1,1 +1,1 @@
-0.3.4
+0.4.0
--- a/include/getlistaddr.h	Fri Apr 30 19:02:13 2004 +1000
+++ b/include/getlistaddr.h	Sat May 01 19:54:58 2004 +1000
@@ -9,6 +9,6 @@
 #ifndef GETLISTADDR_H
 #define GETLISTADDR_H
 
-char *getlistaddr(char *listaddrdeststr, const char *listdir);
+char *getlistaddr(const char *listdir);
 
 #endif /* GETLISTADDR_H */
--- a/listtexts/listhelp	Fri Apr 30 19:02:13 2004 +1000
+++ b/listtexts/listhelp	Sat May 01 19:54:58 2004 +1000
@@ -16,4 +16,5 @@
 
     *HLPADDR*
 
+
 Mails can have any subject and any body.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/listtexts/moderation	Sat May 01 19:54:58 2004 +1000
@@ -0,0 +1,22 @@
+Hello,
+
+Someone send a mail for moderation to:
+
+*LISTADDR*
+
+
+To accept it send a mail to
+
+*MODERATEADDR*
+
+
+Your mailer probably automatically replies to this address, when you hit
+the reply button. If you don't want it sent to the list, simply ignore this
+mail.
+
+The following moderators have recieved this mail:
+
+*MODERATORS*
+
+
+--- below this line the first 100 lines of the mail up for moderation --->
--- a/src/Makefile.am	Fri Apr 30 19:02:13 2004 +1000
+++ b/src/Makefile.am	Sat May 01 19:54:58 2004 +1000
@@ -15,7 +15,7 @@
 mlmmj_send_SOURCES = mlmmj-send.c writen.c mail-functions.c itoa.c chomp.c \
                      incindexfile.c checkwait_smtpreply.c getlistaddr.c \
 		     mylocking.c init_sockfd.c strgen.c random-int.c \
-		     print-version.c log_error.c
+		     print-version.c log_error.c mygetline.c
 
 mlmmj_recieve_SOURCES = mlmmj-recieve.c writen.c random-int.c header_token.c \
 			getlistaddr.c chomp.c strgen.c print-version.c \
--- a/src/Makefile.in	Fri Apr 30 19:02:13 2004 +1000
+++ b/src/Makefile.in	Sat May 01 19:54:58 2004 +1000
@@ -82,7 +82,8 @@
 	incindexfile.$(OBJEXT) checkwait_smtpreply.$(OBJEXT) \
 	getlistaddr.$(OBJEXT) mylocking.$(OBJEXT) \
 	init_sockfd.$(OBJEXT) strgen.$(OBJEXT) random-int.$(OBJEXT) \
-	print-version.$(OBJEXT) log_error.$(OBJEXT)
+	print-version.$(OBJEXT) log_error.$(OBJEXT) \
+	mygetline.$(OBJEXT)
 mlmmj_send_OBJECTS = $(am_mlmmj_send_OBJECTS)
 mlmmj_send_LDADD = $(LDADD)
 am_mlmmj_sub_OBJECTS = mlmmj-sub.$(OBJEXT) writen.$(OBJEXT) \
@@ -216,7 +217,7 @@
 mlmmj_send_SOURCES = mlmmj-send.c writen.c mail-functions.c itoa.c chomp.c \
                      incindexfile.c checkwait_smtpreply.c getlistaddr.c \
 		     mylocking.c init_sockfd.c strgen.c random-int.c \
-		     print-version.c log_error.c
+		     print-version.c log_error.c mygetline.c
 
 mlmmj_recieve_SOURCES = mlmmj-recieve.c writen.c random-int.c header_token.c \
 			getlistaddr.c chomp.c strgen.c print-version.c \
--- a/src/getlistaddr.c	Fri Apr 30 19:02:13 2004 +1000
+++ b/src/getlistaddr.c	Sat May 01 19:54:58 2004 +1000
@@ -10,31 +10,34 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+
 #include "getlistaddr.h"
 #include "chomp.h"
 #include "log_error.h"
-
-#define MAXLISTNAMELEN 1024
+#include "mygetline.h"
+#include "strgen.h"
 
-char *getlistaddr(char *listaddrdeststr, const char *listdir)
+char *getlistaddr(const char *listdir)
 {
-	size_t len;
 	char *tmpstr;
 	FILE *listnamefile;
 
-	len = strlen(listdir) + strlen("/listaddress") + 1;
-	tmpstr = malloc(len);
-
-	snprintf(tmpstr, len, "%s/listaddress", listdir);
+	tmpstr = concatstr(2, listdir, "/listaddress");;
 	if((listnamefile = fopen(tmpstr, "r")) == NULL) {
 		log_error(LOG_ARGS, "Could not open '%s'", tmpstr);
 		exit(EXIT_FAILURE);
 	}
+	free(tmpstr);
 
-	fgets(listaddrdeststr, MAXLISTNAMELEN, listnamefile);
-	chomp(listaddrdeststr);
+	tmpstr = myfgetline(listnamefile);
 
+	if(!tmpstr){
+		log_error(LOG_ARGS, "FATAL. Could not get listaddress");
+		exit(EXIT_FAILURE);
+	}
+
+	chomp(tmpstr);
 	fclose(listnamefile);
-	free(tmpstr);
-	return listaddrdeststr;
+
+	return tmpstr;
 }
--- a/src/init_sockfd.c	Fri Apr 30 19:02:13 2004 +1000
+++ b/src/init_sockfd.c	Sat May 01 19:54:58 2004 +1000
@@ -10,6 +10,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <string.h>
 
 #include "init_sockfd.h"
 #include "log_error.h"
--- a/src/listcontrol.c	Fri Apr 30 19:02:13 2004 +1000
+++ b/src/listcontrol.c	Sat May 01 19:54:58 2004 +1000
@@ -30,7 +30,7 @@
 {
 	char tmpstr[READ_BUFSIZE];
 	char *atsign, *recipdelimsign, *tokenvalue, *confstr, *bouncenr;
-	char *controlstr, *conffilename;
+	char *controlstr, *conffilename, *moderatefilename;
 	FILE *mailfile, *tempfile;
 	struct email_container fromemails;
 	struct stat stbuf;
@@ -123,7 +123,8 @@
 						"-L", listdir,
 						"-a", tmpstr,
 						"-c", 0);
-				log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjunsub);
+				log_error(LOG_ARGS, "execlp() of '%s' failed",
+						    mlmmjunsub);
 				exit(EXIT_FAILURE);
 			} else {
 				exit(EXIT_SUCCESS);
@@ -143,6 +144,23 @@
 				"-a", controlstr,
 				"-n", bouncenr, 0);
 		log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjbounce);
+		exit(EXIT_FAILURE);
+	} else if(strncasecmp(controlstr, "moderate-", 9) == 0) {
+		controlstr += 9;
+		moderatefilename = concatstr(3, listdir, "/moderation/queue/",
+						       controlstr);
+		controlstr -= 9;
+		free(controlstr);
+		if(stat(moderatefilename, &stbuf) < 0) {
+			free(moderatefilename);
+			exit(EXIT_SUCCESS); /* just exit, no mail to moderate */
+		} else {
+			execlp(mlmmjsend, mlmmjsend,
+					"-L", listdir,
+					"-m", moderatefilename, 0);
+			log_error(LOG_ARGS, "execlp() of %s failed", mlmmjsend);
+			exit(EXIT_FAILURE);
+		}
 	} else if(strncasecmp(controlstr, "help", 4) == 0) {
 		printf("Help wanted!\n");
 		free(controlstr);
--- a/src/mlmmj-make-ml.sh	Fri Apr 30 19:02:13 2004 +1000
+++ b/src/mlmmj-make-ml.sh	Sat May 01 19:54:58 2004 +1000
@@ -75,6 +75,15 @@
 	FQDN=`domainname`
 fi
 
+echo -n "The path to the directory with the texts for the list? [] : "
+read TEXTPATH
+if [ -z "$TEXTPATH" -o ! -d "$TEXTPATH" ]; then
+	echo "**NOTE** Could not copy the texts for the list"
+	echo "Please manually copy the files from the listtexts/ directory"
+	echo "in the source distribution of mlmmj."
+fi
+cp "$TEXTPATH"/* "$LISTDIR"/"text"
+
 LISTADDRESS="$LISTNAME@$FQDN"
 echo "$LISTADDRESS" > "$LISTDIR"/"listaddress"
 
@@ -106,85 +115,6 @@
 	echo "$ALIAS"
 fi
 
-echo "Hi, this is the mlmmj program managing the mailinglist
-
-*LSTADDR*
-
-
-To confirm you want the address
-
-*SUBADDR*
-
-
-added to this list, please send a reply to
-
-*CNFADDR*
-
-
-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." > $SPOOLDIR/$LISTNAME/text/sub-confirm
-
-echo "WELCOME! You have been subscribed to the
-
-*LSTADDR*
-
-
-mailinglist." > $SPOOLDIR/$LISTNAME/text/sub-ok
-
-echo "Hi, this is the mlmmj program managing the mailinglist
-
-*LSTADDR*
-
-
-To confirm you want the address
-
-*SUBADDR*
-
-
-removed from 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." > $SPOOLDIR/$LISTNAME/text/unsub-confirm
-
-
-echo "GOODBYE! You have been removed from the
-
-*LSTADDR*
-
-
-mailinglist." > $SPOOLDIR/$LISTNAME/text/unsub-ok
-
-echo "Hello,
-
-There exists the following options:
-
-    To unsubscribe send a mail to
-
-    *UNSUBADDR*
-
-
-    To subscribe send a mail to
-
-    *SUBADDR*
-
-
-    For this help send a mail to
-
-    *HLPADDR*
-
-Mails can have any subject and any body." > $SPOOLDIR/$LISTNAME/text/listhelp
-
 echo " ** DON'T FORGET **
 1) The mailinglist directory have to be owned by the user running the 
 mailserver (i.e. starting the binaries to work the list)
--- a/src/mlmmj-process.c	Fri Apr 30 19:02:13 2004 +1000
+++ b/src/mlmmj-process.c	Sat May 01 19:54:58 2004 +1000
@@ -25,6 +25,114 @@
 #include "strgen.h"
 #include "do_all_the_voodo_here.h"
 #include "log_error.h"
+#include "mygetline.h"
+#include "statctrl.h"
+
+void newmoderated(const char *listdir, const char *mailfilename,
+		  const char *mlmmjsend)
+{
+	char *to, *from, *subject, *fqdn, *listname, *replyto;
+	char *buf, *moderatorfilename, *listaddr = getlistaddr(listdir);
+	char *queuefilename, *moderatorsfilename, *randomstr = random_str();
+	char *mailbasename = basename(strdup(mailfilename));
+	FILE *moderatorfile, *queuefile, *moderatorsfile, *mailfile;
+	size_t count = 0;
+	
+	printf("mailfilename = [%s], mailbasename = [%s]\n", mailfilename,
+			                                     mailbasename);
+
+	fqdn = genlistfqdn(listaddr);
+	listname = genlistname(listaddr);
+	moderatorfilename = concatstr(2, listdir, "/text/moderation");
+	if((moderatorfile = fopen(moderatorfilename, "r")) == NULL) {
+		log_error(LOG_ARGS, "Could not open text/moderation");
+		free(moderatorfilename);
+		exit(EXIT_FAILURE);
+	}
+	queuefilename = concatstr(3, listdir, "/queue/", randomstr);
+	printf("%s\n", queuefilename);
+	
+	if((queuefile = fopen(queuefilename, "w")) == NULL) {
+		log_error(LOG_ARGS, "Could not open '%s'", queuefilename);
+		free(queuefilename);
+		free(randomstr);
+		exit(EXIT_FAILURE);
+	}
+	free(randomstr);
+
+	moderatorsfilename = concatstr(2, listdir, "/moderators");
+	if((moderatorsfile = fopen(moderatorsfilename, "r")) == NULL) {
+		log_error(LOG_ARGS, "Could not open '%s'", moderatorsfilename);
+		free(queuefilename);
+		free(moderatorsfilename);
+		fclose(queuefile);
+		exit(EXIT_FAILURE);
+	}
+	free(moderatorfilename);
+
+	if((mailfile = fopen(mailfilename, "r")) == NULL) {
+		log_error(LOG_ARGS, "Could not open '%s'", mailfilename);
+		free(queuefilename);
+		free(moderatorsfilename);
+		fclose(queuefile);
+		exit(EXIT_FAILURE);
+	}
+
+	fputs("From: ", queuefile);
+	from = concatstr(3, listname, "+owner@", fqdn);
+	fputs(from, queuefile);
+	fputc('\n', queuefile);
+	to = concatstr(5, "To: ", listname, "-moderators@", fqdn, "\n");
+	fputs(to, queuefile);
+	free(to);
+	replyto = concatstr(7, "Reply-To: ", listname, "+moderate-",
+			       mailbasename, "@", fqdn, "\n");
+	fputs(replyto, queuefile);
+	free(replyto);
+	subject = concatstr(3, "Subject: Moderation needed for ", listaddr,
+			       "\n\n");
+	fputs(subject, queuefile);
+	free(subject);
+	
+	while((buf = myfgetline(moderatorfile))) {
+		if(strncmp(buf, "*LISTADDR*", 10) == 0) {
+			fputs(listaddr, queuefile);
+		} else if(strncmp(buf, "*MODERATEADDR*", 14) == 0) {
+			fputs(listname, queuefile);
+			fputs("+moderate-", queuefile);
+			fputs(mailbasename, queuefile);
+			fputc('@', queuefile);
+			fputs(fqdn, queuefile);
+		} else if(strncmp(buf, "*MODERATORS*", 12) == 0) {
+			free(buf);
+			while((buf = myfgetline(moderatorsfile))) {
+				fputs(buf, queuefile);
+				free(buf);
+				buf = NULL;
+			}
+		} else
+			fputs(buf, queuefile);
+		free(buf);
+	}
+	fclose(moderatorfile);
+	while((buf = myfgetline(mailfile)) && count < 100) {
+		fputc(' ', queuefile);
+		fputs(buf, queuefile);
+		free(buf);
+		count++;
+	}
+	fclose(queuefile);
+
+	execlp(mlmmjsend, mlmmjsend,
+				"-l", "2",
+				"-L", listdir,
+				"-F", from,
+				"-m", queuefilename, 0);
+
+	log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsend);
+
+	exit(EXIT_FAILURE);
+}
 
 static void print_help(const char *prg)
 {
@@ -35,10 +143,10 @@
 
 int main(int argc, char **argv)
 {
-	int fd, opt, i, noprocess = 0;
+	int fd, opt, noprocess = 0, moderated = 0;
 	char *listdir = NULL, *mailfile = NULL, *headerfilename = NULL;
 	char *footerfilename = NULL, *donemailname = NULL;
-	char *randomstr = random_str();
+	char *randomstr = random_str(), *basename, *mqueuename;
 	char *mlmmjsend, *mlmmjsub, *mlmmjunsub, *mlmmjbounce;
 	char *argv0 = strdup(argv[0]);
 	FILE *headerfile, *footerfile, *rawmailfile, *donemailfile;
@@ -47,6 +155,7 @@
 	struct mailhdr readhdrs[] = {
 		{ "To:", NULL },
 		{ "Cc:", NULL },
+		{ "From:", NULL },
 		{ NULL, NULL }
 	};
 
@@ -80,7 +189,7 @@
 			break;
 		case 'V':
 			print_version(argv[0]);
-			exit(0);
+			exit(EXIT_SUCCESS);
 		}
 	}
 	if(listdir == NULL || mailfile == NULL) {
@@ -89,8 +198,9 @@
 		exit(EXIT_FAILURE);
 	}
 
-	donemailname = concatstr(3, listdir, "/queue/", randomstr);
+	basename = strdup(randomstr);
 	free(randomstr);
+	donemailname = concatstr(3, listdir, "/queue/", basename);
 	fd = open(donemailname, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
 	while(fd == -1 && errno == EEXIST) {
 		free(donemailname);
@@ -158,6 +268,7 @@
 #endif
 	}
 
+
 	if(strchr(toemails.emaillist[0], RECIPDELIM)) {
 #if 0
 		log_error(LOG_ARGS, "listcontrol(%s, %s, %s, %s, %s, %s, %s)\n", donemailname, listdir, toemails.emaillist[0], mlmmjsub, mlmmjunsub, mlmmjsend, mlmmjbounce);
@@ -167,6 +278,30 @@
 		return EXIT_SUCCESS;
 	}
 
+	moderated = statctrl(listdir, "moderated");
+
+	if(moderated) {
+		mqueuename = concatstr(3, listdir, "/moderation/queue/",
+				       basename);
+		printf("Going into moderatemode, mqueuename = [%s]\n",
+				mqueuename);
+		free(basename);
+		if(rename(donemailname, mqueuename) < 0) {
+			printf("could not rename(%s,%s)\n", 
+					    donemailname, mqueuename);
+			perror("rename");
+			log_error(LOG_ARGS, "could not rename(%s,%s)", 
+					    donemailname, mqueuename);
+			free(donemailname);
+			free(mqueuename);
+			exit(EXIT_FAILURE);
+		}
+		free(donemailname);
+		newmoderated(listdir, mqueuename, mlmmjsend);
+		return EXIT_SUCCESS;
+	}
+
+
 	if(noprocess) {
 		free(donemailname);
 		/* XXX: toemails and ccemails etc. have to be free() */
--- a/src/mlmmj-send.c	Fri Apr 30 19:02:13 2004 +1000
+++ b/src/mlmmj-send.c	Sat May 01 19:54:58 2004 +1000
@@ -164,15 +164,16 @@
 	size_t len = 0;
 	int sockfd = 0, opt, mindex, retval = 0;
 	FILE *subfile = NULL, *mailfile = NULL;
-	char listadr[READ_BUFSIZE], buf[READ_BUFSIZE];
+	char *listadr, buf[READ_BUFSIZE];
 	char *mailfilename = NULL, *subfilename = NULL, *listdir = NULL;
 	char *replyto = NULL, *bounce_adr = NULL, *to_addr = NULL;
 	char *bufres, *relayhost = NULL, *archivefilename = NULL;
+	char *listctrl = NULL;
 	int deletewhensent = 1;
 	
 	log_set_name(argv[0]);
 
-	while ((opt = getopt(argc, argv, "VDhm:L:R:F:T:r:")) != -1){
+	while ((opt = getopt(argc, argv, "VDhm:l:L:R:F:T:r:")) != -1){
 		switch(opt) {
 		case 'D':
 			deletewhensent = 0;
@@ -183,6 +184,9 @@
 		case 'h':
 			print_help(argv[0]);
 			break;
+		case 'l':
+			listctrl = optarg;
+			break;
 		case 'L':
 			listdir = optarg;
 			break;
@@ -200,21 +204,36 @@
 			break;
 		case 'V':
 			print_version(argv[0]);
-			exit(0);
+			exit(EXIT_SUCCESS);
 		}
 	}
 
-	if(mailfilename == 0 || listdir == 0) {
-		fprintf(stderr, "You have to specify -L and -m\n");
+	if(mailfilename == NULL || (listdir == NULL && listctrl == NULL)) {
+		fprintf(stderr, "You have to specify -m and -L or -l\n");
 		fprintf(stderr, "%s -h for help\n", argv[0]);
 		exit(EXIT_FAILURE);
 	}
+
+	if(!listctrl && listdir && listdir[0] == '1')
+		listctrl = strdup("1");
+
+	if(!listctrl)
+		listctrl = strdup("0");
+
+	
 	/* get the list address */
-	if(listdir[0] == '1' && (bounce_adr == 0 || to_addr == 0))
-		fprintf(stderr, "With -L 1 you need -F and -T\n");
+	if(listctrl[0] == '1' && (bounce_adr == NULL || to_addr == NULL)) {
+		fprintf(stderr, "With -l 1 you need -F and -T\n");
+		exit(EXIT_FAILURE);
+	}
 
-	if(listdir[0] != '1')
-		getlistaddr(listadr, listdir);
+	if((listctrl[0] == '2' && listdir == NULL)) {
+		fprintf(stderr, "With -l 2 you need -L\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if(listctrl[0] != '1' && listctrl[0] != '2')
+		listadr = getlistaddr(listdir);
 	
 	/* initialize file with mail to send */
 
@@ -228,21 +247,34 @@
 	else
 		init_sockfd(&sockfd, RELAYHOST);
 	
-	/* XXX: Here is the subscribers unrolled and mails are sent.
-	 * A more intelligent generic solution will be implemented
-	 * later, so we can get LDAP, SQL etc. support for the 
-	 * subscribers list. Choeger?
+	switch(listctrl[0]) {
+	case '1': /* A single mail is to be sent, do nothing */
+		break;
+	case '2': /* Moderators */
+		subfilename = concatstr(2, listdir, "/moderators");
+		if((subfile = fopen(subfilename, "r")) == NULL) {
+			log_error(LOG_ARGS, "Could not open '%s':",
+					    subfilename);
+			free(subfilename);
+			/* No moderators is no error. Could be the sysadmin
+			 * likes to do it manually.
 	 */
-	if(listdir[0] != '1') {
+			exit(EXIT_SUCCESS);
+		}
+		break;
+	default: /* normal list mail */
 		subfilename = concatstr(2, listdir, "/subscribers");
 		if((subfile = fopen(subfilename, "r")) == NULL) {
-			log_error(LOG_ARGS, "Could not open subscriberfile:");
+			log_error(LOG_ARGS, "Could not open '%s':",
+					    subfilename);
+			free(subfilename);
 			exit(EXIT_FAILURE);
 		}
+		break;
 	}
 
 	/* initialize the archive filename */
-	if(listdir[0] != '1') {
+	if(listctrl[0] != '1' && listctrl[0] != '2') {
 		mindex = incindexfile((const char *)listdir, 1);
 		len = strlen(listdir) + 9 + 20;
 		archivefilename = malloc(len);
@@ -262,17 +294,27 @@
 		/* FIXME: quit and tell admin to configure correctly */
 	}
 
-	if(listdir[0] != '1') {
+	/* FIXME: use myfgetline instead! */
+	switch(listctrl[0]) {
+	case '1': /* A single mail is to be sent */
+		send_mail(sockfd, bounce_adr, to_addr, replyto, mailfile);
+		break;
+	case '2': /* Moderators */
+		while((bufres = fgets(buf, READ_BUFSIZE, subfile))) {
+			chomp(buf);
+			send_mail(sockfd, bounce_adr, buf, 0, mailfile);
+		}
+		break;
+	default: /* normal list mail */
 		while((bufres = fgets(buf, READ_BUFSIZE, subfile))) {
 			chomp(buf);
 			bounce_adr = bounce_from_adr(buf, listadr,
 					archivefilename);
-
 			send_mail(sockfd, bounce_adr, buf, 0, mailfile);
 			free(bounce_adr);
 		}
-	} else
-		send_mail(sockfd, bounce_adr, to_addr, replyto, mailfile);
+		break;
+	}
 
 	write_quit(sockfd);
 	if((checkwait_smtpreply(sockfd, MLMMJ_QUIT)) != 0) {
@@ -280,7 +322,7 @@
 			  "We close the socket anyway though\n");
 	}
 
-	if(listdir[0] != '1') {
+	if(listctrl[0] != '1' && listctrl[0] != '2') {
 		/* The mail now goes to the archive */
 		rename(mailfilename, archivefilename);
 
--- a/src/mlmmj-sub.c	Fri Apr 30 19:02:13 2004 +1000
+++ b/src/mlmmj-sub.c	Sat May 01 19:54:58 2004 +1000
@@ -34,7 +34,6 @@
 	char *bufres, *subtextfilename, *randomstr, *queuefilename;
 	char *fromstr, *tostr, *subjectstr, *fromaddr, *helpaddr;
 	char *listname, *listfqdn;
-	size_t len;
 
 	subtextfilename = concatstr(2, listdir, "/text/sub-ok");
 
@@ -61,13 +60,9 @@
 	}
 	free(randomstr);
 
-	len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
-	helpaddr = malloc(len);
-	snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
+	helpaddr = concatstr(3, listname, "+help@", listfqdn);
 
-	len += strlen("-bounces");
-	fromaddr = malloc(len);
-	snprintf(fromaddr, len, "%s-bounces+help@%s", listname, listfqdn);
+	fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
 
 	fromstr = headerstr("From: ", helpaddr);
 	fputs(fromstr, queuefile);
@@ -110,7 +105,6 @@
 	char *confirmaddr, *bufres, *listname, *listfqdn, *confirmfilename;
 	char *subtextfilename, *queuefilename, *fromaddr, *randomstr;
 	char *tostr, *fromstr, *helpaddr, *subjectstr;
-	size_t len;
 
 	listname = genlistname(listaddr);
 	listfqdn = genlistfqdn(listaddr);
@@ -127,20 +121,13 @@
 	fclose(subconffile);
 	free(confirmfilename);
 
-	len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
-	helpaddr = malloc(len);
-	snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
+	helpaddr = concatstr(3, listname, "+help@", listfqdn);
 
-	len = strlen(listname) + strlen(listfqdn) + strlen("+confsub") 
-				+ strlen(subaddr) + 20;
-	confirmaddr = malloc(len);
-	snprintf(confirmaddr, len, "%s+confsub-%s@%s", listname, randomstr,
+	confirmaddr = concatstr(5, listname, "+confsub-", randomstr, "@",
 							listfqdn);
 
-	len += strlen("-bounces");
-	fromaddr = malloc(len);
-	snprintf(fromaddr, len, "%s-bounces+confsub-%s@%s", listname,
-			randomstr, listfqdn);
+	fromaddr = concatstr(5, listname, "+bounces-confsub-", randomstr,
+				"@", listfqdn);
 
 	subtextfilename = concatstr(2, listdir, "/text/sub-confirm");
 
@@ -193,7 +180,7 @@
 	fclose(queuefile);
 
 	execlp(mlmmjsend, mlmmjsend,
-				"-L", "1",
+				"-l", "1",
 				"-T", subaddr,
 				"-F", fromaddr,
 				"-R", confirmaddr,
@@ -215,8 +202,7 @@
 
 int main(int argc, char **argv)
 {
-	char listaddr[READ_BUFSIZE];
-	char *listdir = NULL, *address = NULL, *subfilename = NULL;
+	char *listaddr, *listdir = NULL, *address = NULL, *subfilename = NULL;
 	char *mlmmjsend, *argv0 = strdup(argv[0]);
 	int subconfirm = 0, confirmsub = 0, opt, subfilefd, lock;
 	size_t len;
@@ -262,7 +248,7 @@
 	}
 
 	/* get the list address */
-	getlistaddr(listaddr, listdir);
+	listaddr = getlistaddr(listdir);
 	if(strncasecmp(listaddr, address, strlen(listaddr)) == 0) {
 		printf("Cannot subscribe the list address to the list\n");
 		exit(EXIT_SUCCESS);  /* XXX is this success? */
--- a/src/mlmmj-unsub.c	Fri Apr 30 19:02:13 2004 +1000
+++ b/src/mlmmj-unsub.c	Sat May 01 19:54:58 2004 +1000
@@ -36,7 +36,6 @@
 	char *bufres, *subtextfilename, *randomstr, *queuefilename;
 	char *fromstr, *tostr, *subjectstr, *fromaddr, *helpaddr;
 	char *listname, *listfqdn;
-	size_t len;
 
 	subtextfilename = concatstr(2, listdir, "/text/unsub-ok");
 
@@ -63,13 +62,9 @@
 	}
 	free(randomstr);
 
-	len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
-	helpaddr = malloc(len);
-	snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
+	helpaddr = concatstr(3, listname, "+help@", listfqdn);
 
-	len += strlen("-bounces");
-	fromaddr = malloc(len);
-	snprintf(fromaddr, len, "%s-bounces+help@%s", listname, listfqdn);
+	fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
 
 	fromstr = headerstr("From: ", helpaddr);
 	fputs(fromstr, queuefile);
@@ -107,7 +102,6 @@
 void generate_unsubconfirm(const char *listdir, const char *listaddr,
 			   const char *subaddr, const char *mlmmjsend)
 {
-	size_t len;
 	char buf[READ_BUFSIZE];
 	char *confirmaddr, *bufres, *listname, *listfqdn, *confirmfilename;
 	char *subtextfilename, *queuefilename, *fromaddr, *randomstr;
@@ -128,21 +122,13 @@
 	fputs(subaddr, subconffile);
 	fclose(subconffile);
 	free(confirmfilename);
-
-	len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
-	helpaddr = malloc(len);
-	snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
+	helpaddr = concatstr(3, listname, "+help@", listfqdn);
 
-	len = strlen(listname) + strlen(listfqdn) + strlen("+confunsub") 
-				+ strlen(subaddr) + 20;
-	confirmaddr = malloc(len);
-	snprintf(confirmaddr, len, "%s+confunsub-%s@%s", listname, randomstr,
+	confirmaddr = concatstr(5, listname, "+confunsub-", randomstr, "@",
 							listfqdn);
 
-	len += strlen("-bounces");
-	fromaddr = malloc(len);
-	snprintf(fromaddr, len, "%s-bounces+confunsub-%s@%s", listname,
-			randomstr, listfqdn);
+	fromaddr = concatstr(5, listname, "+bounces-confunsub-", randomstr,
+				"@", listfqdn);
 
 	subtextfilename = concatstr(2, listdir, "/text/unsub-confirm");
 
@@ -195,7 +181,7 @@
 	fclose(queuefile);
 
 	execlp(mlmmjsend, mlmmjsend,
-				"-L", "1",
+				"-l", "1",
 				"-T", subaddr,
 				"-F", fromaddr,
 				"-R", confirmaddr,
@@ -212,7 +198,7 @@
 	size_t len = strlen(address) + 1; /* + 1 for the '\n' */
 
 	if(suboff == -1)
-		return 0; /* Did not find subscriber */
+		return 1; /* Did not find subscriber */
 
 	if(fstat(subreadfd, &st) < 0) {
 		log_error(LOG_ARGS, "Could not stat fd");
@@ -235,7 +221,7 @@
 static void print_help(const char *prg)
 {
 	printf("Usage: %s -L /path/to/chat-list\n"
-	       "          -a someguy@somewhere.ltd\n"
+	       "          -a someguy@somewhere.tld\n"
 	       "          -C request mail confirmation\n"
 	       "          -c send goodbye mail\n"
 	       "          -h this help\n"
@@ -245,10 +231,9 @@
 
 int main(int argc, char **argv)
 {
-	int subread, subwrite, rlock, wlock, opt;
+	int subread, subwrite, rlock, wlock, opt, unsubres;
 	int confirmunsub = 0, unsubconfirm = 0;
-	char listaddr[READ_BUFSIZE];
-	char *listdir = NULL, *address = NULL, *subreadname = NULL;
+	char *listaddr, *listdir = NULL, *address = NULL, *subreadname = NULL;
 	char *subwritename, *mlmmjsend, *argv0 = strdup(argv[0]);
 	off_t suboff;
 	
@@ -292,7 +277,7 @@
 	}
 
 	/* get the list address */
-	getlistaddr(listaddr, listdir);
+	listaddr = getlistaddr(listdir);
 
 	subreadname = concatstr(2, listdir, "/subscribers");
 	subwritename = concatstr(2, listdir, "/subscribers.new");
@@ -342,7 +327,10 @@
 	if(unsubconfirm)
 		generate_unsubconfirm(listdir, listaddr, address, mlmmjsend);
 	else
-		unsubscribe(subread, subwrite, address);
+		unsubres = unsubscribe(subread, subwrite, address);
+
+	if(unsubres == 0)
+		unlink(subreadname);
 	
 	if(rename(subwritename, subreadname) < 0) {
 		log_error(LOG_ARGS, "Could not rename '%s' to '%s'",
--- a/src/send_help.c	Fri Apr 30 19:02:13 2004 +1000
+++ b/src/send_help.c	Sat May 01 19:54:58 2004 +1000
@@ -23,13 +23,13 @@
 	       const char *mlmmjsend)
 {
 	FILE *helpfile, *queuefile;
-	char buf[READ_BUFSIZE], listaddr[READ_BUFSIZE];
-	char *bufres, *helpaddr, *fromaddr, *fromstr, *tostr;
+	char buf[READ_BUFSIZE];
+	char *listaddr, *bufres, *helpaddr, *fromaddr, *fromstr, *tostr;
 	char *subjectstr, *helpfilename, *queuefilename, *listname;
 	char *randomstr, *listfqdn;
 	size_t len;
 
-        getlistaddr(listaddr, listdir);
+        listaddr = getlistaddr(listdir);
 
 	helpfilename = concatstr(2, listdir, "/text/listhelp");
 
--- a/src/statctrl.c	Fri Apr 30 19:02:13 2004 +1000
+++ b/src/statctrl.c	Sat May 01 19:54:58 2004 +1000
@@ -8,6 +8,7 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <stdlib.h>
 
 #include "strgen.h"
 #include "statctrl.h"