changeset 34:1344f636cff3

Rename mlmmj-{un,}subscribe to mlmmj-{un,}sub
author mmj
date Fri, 23 Apr 2004 18:25:37 +1000
parents 647ec4f439b4
children fd6096b0426a
files src/Makefile.am src/Makefile.in src/listcontrol.c src/mlmmj-sub.c src/mlmmj-subscribe.c src/mlmmj-unsub.c src/mlmmj-unsubscribe.c
diffstat 7 files changed, 728 insertions(+), 732 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.am	Fri Apr 23 18:25:16 2004 +1000
+++ b/src/Makefile.am	Fri Apr 23 18:25:37 2004 +1000
@@ -5,8 +5,8 @@
 CFLAGS = -g -O2 -Wall -pedantic -Wsign-compare
 INCLUDES = -I../include
 
-bin_PROGRAMS = mlmmj-send mlmmj-recieve mlmmj-process mlmmj-subscribe \
-               mlmmj-unsubscribe
+bin_PROGRAMS = mlmmj-send mlmmj-recieve mlmmj-process mlmmj-sub \
+               mlmmj-unsub
 
 bin_SCRIPTS = mlmmj-make-ml.sh
 
@@ -23,16 +23,16 @@
 
 mlmmj_process_SOURCES = mlmmj-process.c writen.c find_email_adr.c \
 			incindexfile.c itoa.c getlistaddr.c chomp.c \
-			mylocking.c listcontrol.c random-int.c strgen.c i\
+			mylocking.c listcontrol.c random-int.c strgen.c \
 			header_token.c print-version.c send_help.c \
 			do_all_the_voodo_here.c mygetline.c gethdrline.c \
 			log_error.c
 
-mlmmj_subscribe_SOURCES = mlmmj-subscribe.c writen.c mylocking.c \
+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
 
-mlmmj_unsubscribe_SOURCES = mlmmj-unsubscribe.c writen.c mylocking.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
--- a/src/Makefile.in	Fri Apr 23 18:25:16 2004 +1000
+++ b/src/Makefile.in	Fri Apr 23 18:25:37 2004 +1000
@@ -17,7 +17,7 @@
 #
 
 
-SOURCES = $(mlmmj_process_SOURCES) $(mlmmj_recieve_SOURCES) $(mlmmj_send_SOURCES) $(mlmmj_subscribe_SOURCES) $(mlmmj_unsubscribe_SOURCES)
+SOURCES = $(mlmmj_process_SOURCES) $(mlmmj_recieve_SOURCES) $(mlmmj_send_SOURCES) $(mlmmj_sub_SOURCES) $(mlmmj_unsub_SOURCES)
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -40,8 +40,7 @@
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
 bin_PROGRAMS = mlmmj-send$(EXEEXT) mlmmj-recieve$(EXEEXT) \
-	mlmmj-process$(EXEEXT) mlmmj-subscribe$(EXEEXT) \
-	mlmmj-unsubscribe$(EXEEXT)
+	mlmmj-process$(EXEEXT) mlmmj-sub$(EXEEXT) mlmmj-unsub$(EXEEXT)
 subdir = src
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -78,20 +77,20 @@
 	print-version.$(OBJEXT) log_error.$(OBJEXT)
 mlmmj_send_OBJECTS = $(am_mlmmj_send_OBJECTS)
 mlmmj_send_LDADD = $(LDADD)
-am_mlmmj_subscribe_OBJECTS = mlmmj-subscribe.$(OBJEXT) \
-	writen.$(OBJEXT) mylocking.$(OBJEXT) getlistaddr.$(OBJEXT) \
-	chomp.$(OBJEXT) random-int.$(OBJEXT) strgen.$(OBJEXT) \
+am_mlmmj_sub_OBJECTS = mlmmj-sub.$(OBJEXT) writen.$(OBJEXT) \
+	mylocking.$(OBJEXT) getlistaddr.$(OBJEXT) chomp.$(OBJEXT) \
+	random-int.$(OBJEXT) strgen.$(OBJEXT) \
 	subscriberfuncs.$(OBJEXT) print-version.$(OBJEXT) \
 	log_error.$(OBJEXT) mygetline.$(OBJEXT)
-mlmmj_subscribe_OBJECTS = $(am_mlmmj_subscribe_OBJECTS)
-mlmmj_subscribe_LDADD = $(LDADD)
-am_mlmmj_unsubscribe_OBJECTS = mlmmj-unsubscribe.$(OBJEXT) \
-	writen.$(OBJEXT) mylocking.$(OBJEXT) getlistaddr.$(OBJEXT) \
-	chomp.$(OBJEXT) subscriberfuncs.$(OBJEXT) random-int.$(OBJEXT) \
+mlmmj_sub_OBJECTS = $(am_mlmmj_sub_OBJECTS)
+mlmmj_sub_LDADD = $(LDADD)
+am_mlmmj_unsub_OBJECTS = mlmmj-unsub.$(OBJEXT) writen.$(OBJEXT) \
+	mylocking.$(OBJEXT) getlistaddr.$(OBJEXT) chomp.$(OBJEXT) \
+	subscriberfuncs.$(OBJEXT) random-int.$(OBJEXT) \
 	strgen.$(OBJEXT) print-version.$(OBJEXT) log_error.$(OBJEXT) \
 	mygetline.$(OBJEXT)
-mlmmj_unsubscribe_OBJECTS = $(am_mlmmj_unsubscribe_OBJECTS)
-mlmmj_unsubscribe_LDADD = $(LDADD)
+mlmmj_unsub_OBJECTS = $(am_mlmmj_unsub_OBJECTS)
+mlmmj_unsub_LDADD = $(LDADD)
 binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 SCRIPTS = $(bin_SCRIPTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
@@ -111,9 +110,8 @@
 @AMDEP_TRUE@	./$(DEPDIR)/mail-functions.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/mlmmj-process.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/mlmmj-recieve.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/mlmmj-send.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/mlmmj-subscribe.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/mlmmj-unsubscribe.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/mlmmj-send.Po ./$(DEPDIR)/mlmmj-sub.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/mlmmj-unsub.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/mygetline.Po ./$(DEPDIR)/mylocking.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/print-version.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/random-int.Po ./$(DEPDIR)/send_help.Po \
@@ -125,11 +123,11 @@
 CCLD = $(CC)
 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 SOURCES = $(mlmmj_process_SOURCES) $(mlmmj_recieve_SOURCES) \
-	$(mlmmj_send_SOURCES) $(mlmmj_subscribe_SOURCES) \
-	$(mlmmj_unsubscribe_SOURCES)
+	$(mlmmj_send_SOURCES) $(mlmmj_sub_SOURCES) \
+	$(mlmmj_unsub_SOURCES)
 DIST_SOURCES = $(mlmmj_process_SOURCES) $(mlmmj_recieve_SOURCES) \
-	$(mlmmj_send_SOURCES) $(mlmmj_subscribe_SOURCES) \
-	$(mlmmj_unsubscribe_SOURCES)
+	$(mlmmj_send_SOURCES) $(mlmmj_sub_SOURCES) \
+	$(mlmmj_unsub_SOURCES)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -217,17 +215,17 @@
 
 mlmmj_process_SOURCES = mlmmj-process.c writen.c find_email_adr.c \
 			incindexfile.c itoa.c getlistaddr.c chomp.c \
-			mylocking.c listcontrol.c random-int.c strgen.c i\
+			mylocking.c listcontrol.c random-int.c strgen.c \
 			header_token.c print-version.c send_help.c \
 			do_all_the_voodo_here.c mygetline.c gethdrline.c \
 			log_error.c
 
-mlmmj_subscribe_SOURCES = mlmmj-subscribe.c writen.c mylocking.c \
+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
 
-mlmmj_unsubscribe_SOURCES = mlmmj-unsubscribe.c writen.c mylocking.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
 
@@ -296,12 +294,12 @@
 mlmmj-send$(EXEEXT): $(mlmmj_send_OBJECTS) $(mlmmj_send_DEPENDENCIES) 
 	@rm -f mlmmj-send$(EXEEXT)
 	$(LINK) $(mlmmj_send_LDFLAGS) $(mlmmj_send_OBJECTS) $(mlmmj_send_LDADD) $(LIBS)
-mlmmj-subscribe$(EXEEXT): $(mlmmj_subscribe_OBJECTS) $(mlmmj_subscribe_DEPENDENCIES) 
-	@rm -f mlmmj-subscribe$(EXEEXT)
-	$(LINK) $(mlmmj_subscribe_LDFLAGS) $(mlmmj_subscribe_OBJECTS) $(mlmmj_subscribe_LDADD) $(LIBS)
-mlmmj-unsubscribe$(EXEEXT): $(mlmmj_unsubscribe_OBJECTS) $(mlmmj_unsubscribe_DEPENDENCIES) 
-	@rm -f mlmmj-unsubscribe$(EXEEXT)
-	$(LINK) $(mlmmj_unsubscribe_LDFLAGS) $(mlmmj_unsubscribe_OBJECTS) $(mlmmj_unsubscribe_LDADD) $(LIBS)
+mlmmj-sub$(EXEEXT): $(mlmmj_sub_OBJECTS) $(mlmmj_sub_DEPENDENCIES) 
+	@rm -f mlmmj-sub$(EXEEXT)
+	$(LINK) $(mlmmj_sub_LDFLAGS) $(mlmmj_sub_OBJECTS) $(mlmmj_sub_LDADD) $(LIBS)
+mlmmj-unsub$(EXEEXT): $(mlmmj_unsub_OBJECTS) $(mlmmj_unsub_DEPENDENCIES) 
+	@rm -f mlmmj-unsub$(EXEEXT)
+	$(LINK) $(mlmmj_unsub_LDFLAGS) $(mlmmj_unsub_OBJECTS) $(mlmmj_unsub_LDADD) $(LIBS)
 install-binSCRIPTS: $(bin_SCRIPTS)
 	@$(NORMAL_INSTALL)
 	test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
@@ -344,8 +342,8 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mlmmj-process.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mlmmj-recieve.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mlmmj-send.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mlmmj-subscribe.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mlmmj-unsubscribe.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mlmmj-sub.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mlmmj-unsub.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mygetline.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mylocking.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print-version.Po@am__quote@
--- a/src/listcontrol.c	Fri Apr 23 18:25:16 2004 +1000
+++ b/src/listcontrol.c	Fri Apr 23 18:25:37 2004 +1000
@@ -56,11 +56,11 @@
 	if(strncasecmp(controlstr, "subscribe", 9) == 0) {
 		free(controlstr);
 		if(index(fromemails.emaillist[0], '@')) {
-			execlp(BINDIR"mlmmj-subscribe", "mlmmj-subscribe",
+			execlp(BINDIR"mlmmj-sub", "mlmmj-sub",
 					"-L", listdir,
 					"-a", fromemails.emaillist[0],
 					"-C", 0);
-			log_error("execlp() of "BINDIR"mlmmj-subscribe failed");
+			log_error("execlp() of "BINDIR"mlmmj-sub failed");
 			exit(EXIT_FAILURE);
 		} else /* Not a valid From: address, so we silently ignore */
 			exit(EXIT_SUCCESS);
@@ -76,12 +76,11 @@
 			if(strncasecmp(tmpstr, fromemails.emaillist[0],
 						strlen(tmpstr)) == 0) {
 				unlink(conffilename);
-				execlp(BINDIR"mlmmj-subscribe",
-						"mlmmj-subscribe",
+				execlp(BINDIR"mlmmj-sub", "mlmmj-sub",
 						"-L", listdir,
 						"-a", tmpstr,
 						"-c", 0);
-				log_error("execlp() of "BINDIR"mlmmj-subscribe"
+				log_error("execlp() of "BINDIR"mlmmj-sub"
 					" failed");
 				exit(EXIT_FAILURE);
 			} else {
@@ -93,11 +92,11 @@
 	} else if(strncasecmp(controlstr, "unsubscribe", 11) == 0) {
 		free(controlstr);
 		if(index(fromemails.emaillist[0], '@')) {
-			execlp(BINDIR"mlmmj-unsubscribe", "mlmmj-unsubscribe",
+			execlp(BINDIR"mlmmj-unsub", "mlmmj-unsub",
 					"-L", listdir,
 					"-a", fromemails.emaillist[0],
 					"-C", 0);
-			log_error("execlp() of "BINDIR"mlmmj-unsubscribe"
+			log_error("execlp() of "BINDIR"mlmmj-unsub"
 				" failed");
 			exit(EXIT_FAILURE);
 		} else /* Not a valid From: address, so we silently ignore */
@@ -114,13 +113,12 @@
 			if(strncasecmp(tmpstr, fromemails.emaillist[0],
 						strlen(tmpstr)) == 0) {
 				unlink(conffilename);
-				execlp(BINDIR"mlmmj-unsubscribe",
-						"mlmmj-unsubscribe",
+				execlp(BINDIR"mlmmj-unsub", "mlmmj-unsub",
 						"-L", listdir,
 						"-a", tmpstr,
 						"-c", 0);
 				log_error("execlp() of "
-					BINDIR"mlmmj-unsubscribe failed");
+					BINDIR"mlmmj-unsub failed");
 				exit(EXIT_FAILURE);
 			} else {
 				exit(EXIT_SUCCESS);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mlmmj-sub.c	Fri Apr 23 18:25:37 2004 +1000
@@ -0,0 +1,335 @@
+/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
+ *
+ * $Id$
+ *
+ * This file is redistributable under version 2 of the GNU General
+ * Public License as described at http://www.gnu.org/licenses/gpl.txt
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "mlmmj.h"
+#include "mlmmj-sub.h"
+#include "mylocking.h"
+#include "wrappers.h"
+#include "getlistaddr.h"
+#include "strgen.h"
+#include "subscriberfuncs.h"
+#include "log_error.h"
+
+void confirm_sub(const char *listdir, const char *listaddr, const char *subaddr)
+{
+	size_t len;
+	FILE *subtextfile;
+	FILE *queuefile;
+	char buf[READ_BUFSIZE];
+	char *bufres;
+	char *subtextfilename;
+	char *randomstr;
+	char *queuefilename;
+	char *fromstr;
+	char *tostr;
+	char *subjectstr;
+	char *fromaddr;
+	char *helpaddr;
+	char *listname;
+	char *listfqdn;
+
+	subtextfilename = concatstr(2, listdir, "/text/sub-ok");
+
+	if((subtextfile = fopen(subtextfilename, "r")) == NULL) {
+		log_error("Could not open text/sub-confirm\n");
+		free(subtextfilename);
+		exit(EXIT_FAILURE);
+	}
+	free(subtextfilename);
+
+	listname = genlistname(listaddr);
+	listfqdn = genlistfqdn(listaddr);
+	randomstr = random_str();
+
+	queuefilename = concatstr(3, listdir, "/queue/", randomstr);
+
+	printf("%s\n", queuefilename);
+
+	if((queuefile = fopen(queuefilename, "w")) == NULL) {
+		log_error(queuefilename);
+		free(queuefilename);
+		free(randomstr);
+		exit(EXIT_FAILURE);
+	}
+	free(randomstr);
+
+	len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
+	helpaddr = malloc(len);
+	snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
+
+	len += strlen("-bounces");
+	fromaddr = malloc(len);
+	snprintf(fromaddr, len, "%s-bounces+help@%s", listname, listfqdn);
+
+	fromstr = headerstr("From: ", helpaddr);
+	fputs(fromstr, queuefile);
+	free(helpaddr);
+
+	tostr = headerstr("To: ", subaddr);
+	fputs(tostr, queuefile);
+
+	subjectstr = headerstr("Subject: Welcome to ", listaddr);
+	fputs(subjectstr, queuefile);
+	fputc('\n', queuefile);
+
+	while((bufres = fgets(buf, READ_BUFSIZE, subtextfile)))
+		if(strncmp(buf, "*LSTADDR*", 9) == 0)
+			fputs(listaddr, queuefile);
+		else
+			fputs(buf, queuefile);
+#ifdef MLMMJ_DEBUG
+	fprintf(stderr, "subaddr: [%s]", subaddr);
+	fprintf(stderr, "[%s]", fromstr);
+	fprintf(stderr, "[%s]", tostr);
+	fprintf(stderr, "[%s]", subjectstr);
+#endif
+	free(tostr);
+	free(subjectstr);
+	free(listname);
+	free(listfqdn);
+	fclose(subtextfile);
+	fclose(queuefile);
+
+	execlp(BINDIR"mlmmj-send", "mlmmj-send",
+				"-L", "1",
+				"-T", subaddr,
+				"-F", fromaddr,
+				"-m", queuefilename, 0);
+	log_error("execlp() of "BINDIR"mlmmj-send");
+	exit(EXIT_FAILURE);
+}
+
+void generate_subconfirm(const char *listdir, const char *listaddr,
+				const char *subaddr)
+{
+	size_t len;
+	char *confirmaddr;
+	char buf[READ_BUFSIZE];
+	char *bufres;
+	char *listname;
+	char *listfqdn;
+	char *confirmfilename;
+	char *subtextfilename;
+	char *queuefilename;
+	char *fromaddr;
+	char *randomstr;
+	char *tostr;
+	char *fromstr;
+	char *helpaddr;
+	char *subjectstr;
+	FILE *subconffile;
+	FILE *subtextfile;
+	FILE *queuefile;
+
+	listname = genlistname(listaddr);
+	listfqdn = genlistfqdn(listaddr);
+	randomstr = random_plus_addr(subaddr);
+	confirmfilename = concatstr(3, listdir, "/subconf/", randomstr);
+
+	if((subconffile = fopen(confirmfilename, "w")) == NULL) {
+		log_error(confirmfilename);
+		free(confirmfilename);
+		free(randomstr);
+		exit(EXIT_FAILURE);
+	}
+	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);
+
+	len = strlen(listname) + strlen(listfqdn) + strlen("+confsub") 
+				+ strlen(subaddr) + 20;
+	confirmaddr = malloc(len);
+	snprintf(confirmaddr, len, "%s+confsub-%s@%s", listname, randomstr,
+							listfqdn);
+
+	len += strlen("-bounces");
+	fromaddr = malloc(len);
+	snprintf(fromaddr, len, "%s-bounces+confsub-%s@%s", listname,
+			randomstr, listfqdn);
+
+	subtextfilename = concatstr(2, listdir, "/text/sub-confirm");
+
+	if((subtextfile = fopen(subtextfilename, "r")) == NULL) {
+		log_error("Could not open text/sub-confirm\n");
+		free(randomstr);
+		free(subtextfilename);
+		exit(EXIT_FAILURE);
+	}
+	free(subtextfilename);
+
+	queuefilename = concatstr(3, listdir, "/queue/", randomstr);
+
+	printf("%s\n", queuefilename);
+
+	if((queuefile = fopen(queuefilename, "w")) == NULL) {
+		log_error(queuefilename);
+		free(queuefilename);
+		free(randomstr);
+		exit(EXIT_FAILURE);
+	}
+	free(randomstr);
+
+	fromstr = headerstr("From: ", helpaddr);
+	fputs(fromstr, queuefile);
+	free(fromstr);
+
+	tostr = headerstr("To: ", subaddr);
+	fputs(tostr, queuefile);
+	free(tostr);
+
+	subjectstr = headerstr("Subject: Confirm subscribe to ", listaddr);
+	fputs(subjectstr, queuefile);
+	fputc('\n', queuefile);
+	free(subjectstr);
+
+	while((bufres = fgets(buf, READ_BUFSIZE, subtextfile)))
+		if(strncmp(buf, "*LSTADDR*", 9) == 0)
+			fputs(listaddr, queuefile);
+		else if(strncmp(buf, "*SUBADDR*", 9) == 0)
+			fputs(subaddr, queuefile);
+		else if(strncmp(buf, "*CNFADDR*", 9) == 0)
+			fputs(confirmaddr, queuefile);
+		else
+			fputs(buf, queuefile);
+#ifdef MLMMJ_DEBUG
+	fprintf(stderr, "[%s]", fromstr);
+	fprintf(stderr, "[%s]", tostr);
+	fprintf(stderr, "[%s]", subjectstr);
+#endif
+	free(listname);
+	free(listfqdn);
+	fclose(subtextfile);
+	fclose(queuefile);
+
+	execlp(BINDIR"mlmmj-send", "mlmmj-send",
+				"-L", "1",
+				"-T", subaddr,
+				"-F", fromaddr,
+				"-R", confirmaddr,
+				"-m", queuefilename, 0);
+	log_error("execlp() of "BINDIR"mlmmj-send failed");
+	exit(EXIT_FAILURE);
+}
+
+static void print_help(const char *prg)
+{
+	printf("Usage: %s -L /path/to/chat-list\n"
+	       "          -a someguy@somewhere.ltd\n"
+	       "          -C request mail confirmation\n"
+	       "          -c send welcome mail\n"
+	       "          -h this help\n"
+	       "          -V print version\n", prg);
+	exit(EXIT_SUCCESS);
+}
+
+int main(int argc, char **argv)
+{
+	size_t len;
+	int opt, subfilefd, lock;
+	char listaddr[READ_BUFSIZE];
+	char *listdir = 0;
+	char *address = 0;
+	char *subfilename = 0;
+	int subconfirm = 0;
+	int confirmsub = 0;
+
+	log_set_name(argv[0]);
+
+	while ((opt = getopt(argc, argv, "hcCVL:a:")) != -1) {
+		switch(opt) {
+		case 'a':
+			address = optarg;
+			break;
+		case 'c':
+			confirmsub = 1;
+			break;
+		case 'C':
+			subconfirm = 1;
+			break;
+		case 'h':
+			print_help(argv[0]);
+			break;
+		case 'L':
+			listdir = optarg;
+			break;
+		case 'V':
+			print_version(argv[0]);
+			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(confirmsub && subconfirm) {
+		fprintf(stderr, "Cannot specify both -C and -c\n");
+		fprintf(stderr, "%s -h for help\n", argv[0]);
+		exit(EXIT_FAILURE);
+	}
+
+	/* get the list address */
+	getlistaddr(listaddr, 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? */
+	}
+
+	subfilename = concatstr(2, listdir, "/subscribers");
+
+	subfilefd = open(subfilename, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
+	if(subfilefd == -1) {
+		log_error("Could not open subscriberfile:");
+		exit(EXIT_FAILURE);
+	}
+
+	lock = myexcllock(subfilefd);
+	if(lock) {
+		log_error("Error locking subscriber file:");
+		close(subfilefd);
+		exit(EXIT_FAILURE);
+	}
+
+	if(find_subscriber(subfilefd, address)) {
+		if(subconfirm)
+			generate_subconfirm(listdir, listaddr, address);
+		else {
+			lseek(subfilefd, 0L, SEEK_END);
+			len = strlen(address);
+			address[len] = '\n';
+			writen(subfilefd, address, len + 1);
+			address[len] = 0;
+		}
+	} else {
+		myunlock(subfilefd);
+		free(subfilename);
+		close(subfilefd);
+		
+		return EXIT_SUCCESS;
+	}
+
+	if(confirmsub)
+		confirm_sub(listdir, listaddr, address);
+
+	return EXIT_SUCCESS;
+}
--- a/src/mlmmj-subscribe.c	Fri Apr 23 18:25:16 2004 +1000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,335 +0,0 @@
-/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
- *
- * $Id$
- *
- * This file is redistributable under version 2 of the GNU General
- * Public License as described at http://www.gnu.org/licenses/gpl.txt
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <syslog.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "mlmmj.h"
-#include "mlmmj-subscribe.h"
-#include "mylocking.h"
-#include "wrappers.h"
-#include "getlistaddr.h"
-#include "strgen.h"
-#include "subscriberfuncs.h"
-#include "log_error.h"
-
-void confirm_sub(const char *listdir, const char *listaddr, const char *subaddr)
-{
-	size_t len;
-	FILE *subtextfile;
-	FILE *queuefile;
-	char buf[READ_BUFSIZE];
-	char *bufres;
-	char *subtextfilename;
-	char *randomstr;
-	char *queuefilename;
-	char *fromstr;
-	char *tostr;
-	char *subjectstr;
-	char *fromaddr;
-	char *helpaddr;
-	char *listname;
-	char *listfqdn;
-
-	subtextfilename = concatstr(2, listdir, "/text/sub-ok");
-
-	if((subtextfile = fopen(subtextfilename, "r")) == NULL) {
-		log_error("Could not open text/sub-confirm\n");
-		free(subtextfilename);
-		exit(EXIT_FAILURE);
-	}
-	free(subtextfilename);
-
-	listname = genlistname(listaddr);
-	listfqdn = genlistfqdn(listaddr);
-	randomstr = random_str();
-
-	queuefilename = concatstr(3, listdir, "/queue/", randomstr);
-
-	printf("%s\n", queuefilename);
-
-	if((queuefile = fopen(queuefilename, "w")) == NULL) {
-		log_error(queuefilename);
-		free(queuefilename);
-		free(randomstr);
-		exit(EXIT_FAILURE);
-	}
-	free(randomstr);
-
-	len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
-	helpaddr = malloc(len);
-	snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
-
-	len += strlen("-bounces");
-	fromaddr = malloc(len);
-	snprintf(fromaddr, len, "%s-bounces+help@%s", listname, listfqdn);
-
-	fromstr = headerstr("From: ", helpaddr);
-	fputs(fromstr, queuefile);
-	free(helpaddr);
-
-	tostr = headerstr("To: ", subaddr);
-	fputs(tostr, queuefile);
-
-	subjectstr = headerstr("Subject: Welcome to ", listaddr);
-	fputs(subjectstr, queuefile);
-	fputc('\n', queuefile);
-
-	while((bufres = fgets(buf, READ_BUFSIZE, subtextfile)))
-		if(strncmp(buf, "*LSTADDR*", 9) == 0)
-			fputs(listaddr, queuefile);
-		else
-			fputs(buf, queuefile);
-#ifdef MLMMJ_DEBUG
-	fprintf(stderr, "subaddr: [%s]", subaddr);
-	fprintf(stderr, "[%s]", fromstr);
-	fprintf(stderr, "[%s]", tostr);
-	fprintf(stderr, "[%s]", subjectstr);
-#endif
-	free(tostr);
-	free(subjectstr);
-	free(listname);
-	free(listfqdn);
-	fclose(subtextfile);
-	fclose(queuefile);
-
-	execlp(BINDIR"mlmmj-send", "mlmmj-send",
-				"-L", "1",
-				"-T", subaddr,
-				"-F", fromaddr,
-				"-m", queuefilename, 0);
-	log_error("execlp() of "BINDIR"mlmmj-send");
-	exit(EXIT_FAILURE);
-}
-
-void generate_subconfirm(const char *listdir, const char *listaddr,
-				const char *subaddr)
-{
-	size_t len;
-	char *confirmaddr;
-	char buf[READ_BUFSIZE];
-	char *bufres;
-	char *listname;
-	char *listfqdn;
-	char *confirmfilename;
-	char *subtextfilename;
-	char *queuefilename;
-	char *fromaddr;
-	char *randomstr;
-	char *tostr;
-	char *fromstr;
-	char *helpaddr;
-	char *subjectstr;
-	FILE *subconffile;
-	FILE *subtextfile;
-	FILE *queuefile;
-
-	listname = genlistname(listaddr);
-	listfqdn = genlistfqdn(listaddr);
-	randomstr = random_plus_addr(subaddr);
-	confirmfilename = concatstr(3, listdir, "/subconf/", randomstr);
-
-	if((subconffile = fopen(confirmfilename, "w")) == NULL) {
-		log_error(confirmfilename);
-		free(confirmfilename);
-		free(randomstr);
-		exit(EXIT_FAILURE);
-	}
-	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);
-
-	len = strlen(listname) + strlen(listfqdn) + strlen("+confsub") 
-				+ strlen(subaddr) + 20;
-	confirmaddr = malloc(len);
-	snprintf(confirmaddr, len, "%s+confsub-%s@%s", listname, randomstr,
-							listfqdn);
-
-	len += strlen("-bounces");
-	fromaddr = malloc(len);
-	snprintf(fromaddr, len, "%s-bounces+confsub-%s@%s", listname,
-			randomstr, listfqdn);
-
-	subtextfilename = concatstr(2, listdir, "/text/sub-confirm");
-
-	if((subtextfile = fopen(subtextfilename, "r")) == NULL) {
-		log_error("Could not open text/sub-confirm\n");
-		free(randomstr);
-		free(subtextfilename);
-		exit(EXIT_FAILURE);
-	}
-	free(subtextfilename);
-
-	queuefilename = concatstr(3, listdir, "/queue/", randomstr);
-
-	printf("%s\n", queuefilename);
-
-	if((queuefile = fopen(queuefilename, "w")) == NULL) {
-		log_error(queuefilename);
-		free(queuefilename);
-		free(randomstr);
-		exit(EXIT_FAILURE);
-	}
-	free(randomstr);
-
-	fromstr = headerstr("From: ", helpaddr);
-	fputs(fromstr, queuefile);
-	free(fromstr);
-
-	tostr = headerstr("To: ", subaddr);
-	fputs(tostr, queuefile);
-	free(tostr);
-
-	subjectstr = headerstr("Subject: Confirm subscribe to ", listaddr);
-	fputs(subjectstr, queuefile);
-	fputc('\n', queuefile);
-	free(subjectstr);
-
-	while((bufres = fgets(buf, READ_BUFSIZE, subtextfile)))
-		if(strncmp(buf, "*LSTADDR*", 9) == 0)
-			fputs(listaddr, queuefile);
-		else if(strncmp(buf, "*SUBADDR*", 9) == 0)
-			fputs(subaddr, queuefile);
-		else if(strncmp(buf, "*CNFADDR*", 9) == 0)
-			fputs(confirmaddr, queuefile);
-		else
-			fputs(buf, queuefile);
-#ifdef MLMMJ_DEBUG
-	fprintf(stderr, "[%s]", fromstr);
-	fprintf(stderr, "[%s]", tostr);
-	fprintf(stderr, "[%s]", subjectstr);
-#endif
-	free(listname);
-	free(listfqdn);
-	fclose(subtextfile);
-	fclose(queuefile);
-
-	execlp(BINDIR"mlmmj-send", "mlmmj-send",
-				"-L", "1",
-				"-T", subaddr,
-				"-F", fromaddr,
-				"-R", confirmaddr,
-				"-m", queuefilename, 0);
-	log_error("execlp() of "BINDIR"mlmmj-send failed");
-	exit(EXIT_FAILURE);
-}
-
-static void print_help(const char *prg)
-{
-	printf("Usage: %s -L /path/to/chat-list\n"
-	       "          -a someguy@somewhere.ltd\n"
-	       "          -C request mail confirmation\n"
-	       "          -c send welcome mail\n"
-	       "          -h this help\n"
-	       "          -V print version\n", prg);
-	exit(EXIT_SUCCESS);
-}
-
-int main(int argc, char **argv)
-{
-	size_t len;
-	int opt, subfilefd, lock;
-	char listaddr[READ_BUFSIZE];
-	char *listdir = 0;
-	char *address = 0;
-	char *subfilename = 0;
-	int subconfirm = 0;
-	int confirmsub = 0;
-
-	log_set_name(argv[0]);
-
-	while ((opt = getopt(argc, argv, "hcCVL:a:")) != -1) {
-		switch(opt) {
-		case 'a':
-			address = optarg;
-			break;
-		case 'c':
-			confirmsub = 1;
-			break;
-		case 'C':
-			subconfirm = 1;
-			break;
-		case 'h':
-			print_help(argv[0]);
-			break;
-		case 'L':
-			listdir = optarg;
-			break;
-		case 'V':
-			print_version(argv[0]);
-			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(confirmsub && subconfirm) {
-		fprintf(stderr, "Cannot specify both -C and -c\n");
-		fprintf(stderr, "%s -h for help\n", argv[0]);
-		exit(EXIT_FAILURE);
-	}
-
-	/* get the list address */
-	getlistaddr(listaddr, 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? */
-	}
-
-	subfilename = concatstr(2, listdir, "/subscribers");
-
-	subfilefd = open(subfilename, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
-	if(subfilefd == -1) {
-		log_error("Could not open subscriberfile:");
-		exit(EXIT_FAILURE);
-	}
-
-	lock = myexcllock(subfilefd);
-	if(lock) {
-		log_error("Error locking subscriber file:");
-		close(subfilefd);
-		exit(EXIT_FAILURE);
-	}
-
-	if(find_subscriber(subfilefd, address)) {
-		if(subconfirm)
-			generate_subconfirm(listdir, listaddr, address);
-		else {
-			lseek(subfilefd, 0L, SEEK_END);
-			len = strlen(address);
-			address[len] = '\n';
-			writen(subfilefd, address, len + 1);
-			address[len] = 0;
-		}
-	} else {
-		myunlock(subfilefd);
-		free(subfilename);
-		close(subfilefd);
-		
-		return EXIT_SUCCESS;
-	}
-
-	if(confirmsub)
-		confirm_sub(listdir, listaddr, address);
-
-	return EXIT_SUCCESS;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mlmmj-unsub.c	Fri Apr 23 18:25:37 2004 +1000
@@ -0,0 +1,351 @@
+/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
+ *
+ * $Id$
+ *
+ * This file is redistributable under version 2 of the GNU General
+ * Public License as described at http://www.gnu.org/licenses/gpl.txt
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "mlmmj.h"
+#include "mlmmj-sub.h"
+#include "mylocking.h"
+#include "wrappers.h"
+#include "mygetline.h"
+#include "getlistaddr.h"
+#include "subscriberfuncs.h"
+#include "strgen.h"
+#include "log_error.h"
+
+void confirm_unsub(const char *listdir, const char *listaddr, const char *subaddr)
+{
+	size_t len;
+	FILE *subtextfile;
+	FILE *queuefile;
+	char buf[READ_BUFSIZE];
+	char *bufres;
+	char *subtextfilename;
+	char *randomstr;
+	char *queuefilename;
+	char *fromstr;
+	char *tostr;
+	char *subjectstr;
+	char *fromaddr;
+	char *helpaddr;
+	char *listname;
+	char *listfqdn;
+
+	subtextfilename = concatstr(2, listdir, "/text/unsub-ok");
+
+	if((subtextfile = fopen(subtextfilename, "r")) == NULL) {
+		log_error("Could not open text/unsub-ok\n");
+		free(subtextfilename);
+		exit(EXIT_FAILURE);
+	}
+	free(subtextfilename);
+
+	listname = genlistname(listaddr);
+	listfqdn = genlistfqdn(listaddr);
+	randomstr = random_str();
+
+	queuefilename = concatstr(3, listdir, "/queue/", randomstr);
+
+	printf("%s\n", queuefilename);
+
+	if((queuefile = fopen(queuefilename, "w")) == NULL) {
+		log_error(queuefilename);
+		free(queuefilename);
+		free(randomstr);
+		exit(EXIT_FAILURE);
+	}
+	free(randomstr);
+
+	len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
+	helpaddr = malloc(len);
+	snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
+
+	len += strlen("-bounces");
+	fromaddr = malloc(len);
+	snprintf(fromaddr, len, "%s-bounces+help@%s", listname, listfqdn);
+
+	fromstr = headerstr("From: ", helpaddr);
+	fputs(fromstr, queuefile);
+	free(helpaddr);
+
+	tostr = headerstr("To: ", subaddr);
+	fputs(tostr, queuefile);
+
+	subjectstr = headerstr("Subject: Goodbye from ", listaddr);
+	fputs(subjectstr, queuefile);
+	fputc('\n', queuefile);
+
+	while((bufres = fgets(buf, READ_BUFSIZE, subtextfile)))
+		if(strncmp(buf, "*LSTADDR*", 9) == 0)
+			fputs(listaddr, queuefile);
+		else
+			fputs(buf, queuefile);
+#ifdef MLMMJ_DEBUG
+	fprintf(stderr, "subaddr: [%s]", subaddr);
+	fprintf(stderr, "[%s]", fromstr);
+	fprintf(stderr, "[%s]", tostr);
+	fprintf(stderr, "[%s]", subjectstr);
+#endif
+	free(tostr);
+	free(subjectstr);
+	free(listname);
+	free(listfqdn);
+	fclose(subtextfile);
+	fclose(queuefile);
+
+	execlp(BINDIR"mlmmj-send", "mlmmj-send",
+				"-L", "1",
+				"-T", subaddr,
+				"-F", fromaddr,
+				"-m", queuefilename, 0);
+	log_error("execlp() of "BINDIR"mlmmj-send failed");
+	exit(EXIT_FAILURE);
+}
+
+void generate_unsubconfirm(const char *listdir, const char *listaddr,
+				const char *subaddr)
+{
+	size_t len;
+	char *confirmaddr;
+	char buf[READ_BUFSIZE];
+	char *bufres;
+	char *listname;
+	char *listfqdn;
+	char *confirmfilename;
+	char *subtextfilename;
+	char *queuefilename;
+	char *fromaddr;
+	char *randomstr;
+	char *tostr;
+	char *fromstr;
+	char *helpaddr;
+	char *subjectstr;
+	FILE *subconffile;
+	FILE *subtextfile;
+	FILE *queuefile;
+
+	listname = genlistname(listaddr);
+	listfqdn = genlistfqdn(listaddr);
+	randomstr = random_plus_addr(subaddr);
+	confirmfilename = concatstr(3, listdir, "/unsubconf/", randomstr);
+
+	if((subconffile = fopen(confirmfilename, "w")) == NULL) {
+		log_error(confirmfilename);
+		free(confirmfilename);
+		free(randomstr);
+		exit(EXIT_FAILURE);
+	}
+	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);
+
+	len = strlen(listname) + strlen(listfqdn) + strlen("+confunsub") 
+				+ strlen(subaddr) + 20;
+	confirmaddr = malloc(len);
+	snprintf(confirmaddr, len, "%s+confunsub-%s@%s", listname, randomstr,
+							listfqdn);
+
+	len += strlen("-bounces");
+	fromaddr = malloc(len);
+	snprintf(fromaddr, len, "%s-bounces+confunsub-%s@%s", listname,
+			randomstr, listfqdn);
+
+	subtextfilename = concatstr(2, listdir, "/text/unsub-confirm");
+
+	if((subtextfile = fopen(subtextfilename, "r")) == NULL) {
+		log_error("Could not open text/unsub-confirm\n");
+		free(randomstr);
+		free(subtextfilename);
+		exit(EXIT_FAILURE);
+	}
+	free(subtextfilename);
+
+	queuefilename = concatstr(3, listdir, "/queue/", randomstr);
+
+	printf("%s\n", queuefilename);
+
+	if((queuefile = fopen(queuefilename, "w")) == NULL) {
+		log_error(queuefilename);
+		free(queuefilename);
+		free(randomstr);
+		exit(EXIT_FAILURE);
+	}
+	free(randomstr);
+
+	fromstr = headerstr("From: ", helpaddr);
+	fputs(fromstr, queuefile);
+	free(fromstr);
+
+	tostr = headerstr("To: ", subaddr);
+	fputs(tostr, queuefile);
+	free(tostr);
+
+	subjectstr = headerstr("Subject: Confirm unsubscribe from ", listaddr);
+	fputs(subjectstr, queuefile);
+	fputc('\n', queuefile);
+	free(subjectstr);
+
+	while((bufres = fgets(buf, READ_BUFSIZE, subtextfile)))
+		if(strncmp(buf, "*LSTADDR*", 9) == 0)
+			fputs(listaddr, queuefile);
+		else if(strncmp(buf, "*SUBADDR*", 9) == 0)
+			fputs(subaddr, queuefile);
+		else if(strncmp(buf, "*CNFADDR*", 9) == 0)
+			fputs(confirmaddr, queuefile);
+		else
+			fputs(buf, queuefile);
+#ifdef MLMMJ_DEBUG
+	fprintf(stderr, "[%s]", fromstr);
+	fprintf(stderr, "[%s]", tostr);
+	fprintf(stderr, "[%s]", subjectstr);
+#endif
+	free(listname);
+	free(listfqdn);
+	fclose(subtextfile);
+	fclose(queuefile);
+
+	execlp(BINDIR"mlmmj-send", "mlmmj-send",
+				"-L", "1",
+				"-T", subaddr,
+				"-F", fromaddr,
+				"-R", confirmaddr,
+				"-m", queuefilename, 0);
+	log_error("execlp() of "BINDIR"mlmmj-send failed");
+	exit(EXIT_FAILURE);
+}
+
+void unsubscribe(int subreadfd, int subwritefd, const char *address)
+{
+	char *buf;
+
+	lseek(subreadfd, 0, SEEK_SET);
+	lseek(subwritefd, 0, SEEK_SET);
+
+	while((buf = mygetline(subreadfd))) {
+		if(strncasecmp(buf, address, strlen(address)) != 0)
+			writen(subwritefd, buf, strlen(buf));
+		free(buf);
+	}
+	ftruncate(subwritefd, lseek(subwritefd, 0, SEEK_CUR));
+}
+
+static void print_help(const char *prg)
+{
+	printf("Usage: %s -L /path/to/chat-list\n"
+	       "          -a someguy@somewhere.ltd\n"
+	       "          -C request mail confirmation\n"
+	       "          -c send goodbye mail\n"
+	       "          -h this help\n"
+	       "          -V print version\n", prg);
+	exit(EXIT_SUCCESS);
+}
+
+int main(int argc, char **argv)
+{
+	int subread, subwrite, sublock, opt;
+	int confirmunsub = 0;
+	int unsubconfirm = 0;
+	char listaddr[READ_BUFSIZE];
+	char *listdir = 0;
+	char *address = 0;
+	char *subreadname = 0;
+
+        log_set_name(argv[0]);
+
+	while ((opt = getopt(argc, argv, "hcCVL:a:")) != -1) {
+		switch(opt) {
+		case 'L':
+			listdir = optarg;
+			break;
+		case 'a':
+			address = optarg;
+			break;
+		case 'c':
+			confirmunsub = 1;
+			break;
+		case 'C':
+			unsubconfirm = 1;
+			break;
+		case 'h':
+			print_help(argv[0]);
+			break;
+		case 'V':
+			print_version(argv[0]);
+			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(confirmunsub && unsubconfirm) {
+		fprintf(stderr, "Cannot specify both -C and -c\n");
+		fprintf(stderr, "%s -h for help\n", argv[0]);
+		exit(EXIT_FAILURE);
+	}
+
+	/* get the list address */
+	getlistaddr(listaddr, listdir);
+
+	subreadname = concatstr(2, listdir, "/subscribers");
+
+	subread = open(subreadname, O_RDWR);
+	if(subread == -1) {
+		log_error("Could not open subscriberfile:");
+		exit(EXIT_FAILURE);
+	}
+
+	sublock = myexcllock(subread);
+	if(sublock) {
+		log_error("Error locking subscriber file:");
+		close(subread);
+		exit(EXIT_FAILURE);
+	}
+
+	if(find_subscriber(subread, address)) {
+		myunlock(subread);
+		free(subreadname);
+		close(subread);
+		exit(EXIT_SUCCESS);
+	}
+
+	subwrite = open(subreadname, O_RDWR);
+	if(subwrite == -1){
+		log_error("Could not open subfile:");
+		exit(EXIT_FAILURE);
+	}
+	if(unsubconfirm)
+		generate_unsubconfirm(listdir, listaddr, address);
+	else
+		unsubscribe(subread, subwrite, address);
+	
+	myunlock(subread);
+
+	free(subreadname);
+	close(subread);
+	close(subwrite);
+
+	if(confirmunsub)
+		confirm_unsub(listdir, listaddr, address);
+
+	return EXIT_SUCCESS;
+}
--- a/src/mlmmj-unsubscribe.c	Fri Apr 23 18:25:16 2004 +1000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,351 +0,0 @@
-/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
- *
- * $Id$
- *
- * This file is redistributable under version 2 of the GNU General
- * Public License as described at http://www.gnu.org/licenses/gpl.txt
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <syslog.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "mlmmj.h"
-#include "mlmmj-subscribe.h"
-#include "mylocking.h"
-#include "wrappers.h"
-#include "mygetline.h"
-#include "getlistaddr.h"
-#include "subscriberfuncs.h"
-#include "strgen.h"
-#include "log_error.h"
-
-void confirm_unsub(const char *listdir, const char *listaddr, const char *subaddr)
-{
-	size_t len;
-	FILE *subtextfile;
-	FILE *queuefile;
-	char buf[READ_BUFSIZE];
-	char *bufres;
-	char *subtextfilename;
-	char *randomstr;
-	char *queuefilename;
-	char *fromstr;
-	char *tostr;
-	char *subjectstr;
-	char *fromaddr;
-	char *helpaddr;
-	char *listname;
-	char *listfqdn;
-
-	subtextfilename = concatstr(2, listdir, "/text/unsub-ok");
-
-	if((subtextfile = fopen(subtextfilename, "r")) == NULL) {
-		log_error("Could not open text/unsub-ok\n");
-		free(subtextfilename);
-		exit(EXIT_FAILURE);
-	}
-	free(subtextfilename);
-
-	listname = genlistname(listaddr);
-	listfqdn = genlistfqdn(listaddr);
-	randomstr = random_str();
-
-	queuefilename = concatstr(3, listdir, "/queue/", randomstr);
-
-	printf("%s\n", queuefilename);
-
-	if((queuefile = fopen(queuefilename, "w")) == NULL) {
-		log_error(queuefilename);
-		free(queuefilename);
-		free(randomstr);
-		exit(EXIT_FAILURE);
-	}
-	free(randomstr);
-
-	len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
-	helpaddr = malloc(len);
-	snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
-
-	len += strlen("-bounces");
-	fromaddr = malloc(len);
-	snprintf(fromaddr, len, "%s-bounces+help@%s", listname, listfqdn);
-
-	fromstr = headerstr("From: ", helpaddr);
-	fputs(fromstr, queuefile);
-	free(helpaddr);
-
-	tostr = headerstr("To: ", subaddr);
-	fputs(tostr, queuefile);
-
-	subjectstr = headerstr("Subject: Goodbye from ", listaddr);
-	fputs(subjectstr, queuefile);
-	fputc('\n', queuefile);
-
-	while((bufres = fgets(buf, READ_BUFSIZE, subtextfile)))
-		if(strncmp(buf, "*LSTADDR*", 9) == 0)
-			fputs(listaddr, queuefile);
-		else
-			fputs(buf, queuefile);
-#ifdef MLMMJ_DEBUG
-	fprintf(stderr, "subaddr: [%s]", subaddr);
-	fprintf(stderr, "[%s]", fromstr);
-	fprintf(stderr, "[%s]", tostr);
-	fprintf(stderr, "[%s]", subjectstr);
-#endif
-	free(tostr);
-	free(subjectstr);
-	free(listname);
-	free(listfqdn);
-	fclose(subtextfile);
-	fclose(queuefile);
-
-	execlp(BINDIR"mlmmj-send", "mlmmj-send",
-				"-L", "1",
-				"-T", subaddr,
-				"-F", fromaddr,
-				"-m", queuefilename, 0);
-	log_error("execlp() of "BINDIR"mlmmj-send failed");
-	exit(EXIT_FAILURE);
-}
-
-void generate_unsubconfirm(const char *listdir, const char *listaddr,
-				const char *subaddr)
-{
-	size_t len;
-	char *confirmaddr;
-	char buf[READ_BUFSIZE];
-	char *bufres;
-	char *listname;
-	char *listfqdn;
-	char *confirmfilename;
-	char *subtextfilename;
-	char *queuefilename;
-	char *fromaddr;
-	char *randomstr;
-	char *tostr;
-	char *fromstr;
-	char *helpaddr;
-	char *subjectstr;
-	FILE *subconffile;
-	FILE *subtextfile;
-	FILE *queuefile;
-
-	listname = genlistname(listaddr);
-	listfqdn = genlistfqdn(listaddr);
-	randomstr = random_plus_addr(subaddr);
-	confirmfilename = concatstr(3, listdir, "/unsubconf/", randomstr);
-
-	if((subconffile = fopen(confirmfilename, "w")) == NULL) {
-		log_error(confirmfilename);
-		free(confirmfilename);
-		free(randomstr);
-		exit(EXIT_FAILURE);
-	}
-	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);
-
-	len = strlen(listname) + strlen(listfqdn) + strlen("+confunsub") 
-				+ strlen(subaddr) + 20;
-	confirmaddr = malloc(len);
-	snprintf(confirmaddr, len, "%s+confunsub-%s@%s", listname, randomstr,
-							listfqdn);
-
-	len += strlen("-bounces");
-	fromaddr = malloc(len);
-	snprintf(fromaddr, len, "%s-bounces+confunsub-%s@%s", listname,
-			randomstr, listfqdn);
-
-	subtextfilename = concatstr(2, listdir, "/text/unsub-confirm");
-
-	if((subtextfile = fopen(subtextfilename, "r")) == NULL) {
-		log_error("Could not open text/unsub-confirm\n");
-		free(randomstr);
-		free(subtextfilename);
-		exit(EXIT_FAILURE);
-	}
-	free(subtextfilename);
-
-	queuefilename = concatstr(3, listdir, "/queue/", randomstr);
-
-	printf("%s\n", queuefilename);
-
-	if((queuefile = fopen(queuefilename, "w")) == NULL) {
-		log_error(queuefilename);
-		free(queuefilename);
-		free(randomstr);
-		exit(EXIT_FAILURE);
-	}
-	free(randomstr);
-
-	fromstr = headerstr("From: ", helpaddr);
-	fputs(fromstr, queuefile);
-	free(fromstr);
-
-	tostr = headerstr("To: ", subaddr);
-	fputs(tostr, queuefile);
-	free(tostr);
-
-	subjectstr = headerstr("Subject: Confirm unsubscribe from ", listaddr);
-	fputs(subjectstr, queuefile);
-	fputc('\n', queuefile);
-	free(subjectstr);
-
-	while((bufres = fgets(buf, READ_BUFSIZE, subtextfile)))
-		if(strncmp(buf, "*LSTADDR*", 9) == 0)
-			fputs(listaddr, queuefile);
-		else if(strncmp(buf, "*SUBADDR*", 9) == 0)
-			fputs(subaddr, queuefile);
-		else if(strncmp(buf, "*CNFADDR*", 9) == 0)
-			fputs(confirmaddr, queuefile);
-		else
-			fputs(buf, queuefile);
-#ifdef MLMMJ_DEBUG
-	fprintf(stderr, "[%s]", fromstr);
-	fprintf(stderr, "[%s]", tostr);
-	fprintf(stderr, "[%s]", subjectstr);
-#endif
-	free(listname);
-	free(listfqdn);
-	fclose(subtextfile);
-	fclose(queuefile);
-
-	execlp(BINDIR"mlmmj-send", "mlmmj-send",
-				"-L", "1",
-				"-T", subaddr,
-				"-F", fromaddr,
-				"-R", confirmaddr,
-				"-m", queuefilename, 0);
-	log_error("execlp() of "BINDIR"mlmmj-send failed");
-	exit(EXIT_FAILURE);
-}
-
-void unsubscribe(int subreadfd, int subwritefd, const char *address)
-{
-	char *buf;
-
-	lseek(subreadfd, 0, SEEK_SET);
-	lseek(subwritefd, 0, SEEK_SET);
-
-	while((buf = mygetline(subreadfd))) {
-		if(strncasecmp(buf, address, strlen(address)) != 0)
-			writen(subwritefd, buf, strlen(buf));
-		free(buf);
-	}
-	ftruncate(subwritefd, lseek(subwritefd, 0, SEEK_CUR));
-}
-
-static void print_help(const char *prg)
-{
-	printf("Usage: %s -L /path/to/chat-list\n"
-	       "          -a someguy@somewhere.ltd\n"
-	       "          -C request mail confirmation\n"
-	       "          -c send goodbye mail\n"
-	       "          -h this help\n"
-	       "          -V print version\n", prg);
-	exit(EXIT_SUCCESS);
-}
-
-int main(int argc, char **argv)
-{
-	int subread, subwrite, sublock, opt;
-	int confirmunsub = 0;
-	int unsubconfirm = 0;
-	char listaddr[READ_BUFSIZE];
-	char *listdir = 0;
-	char *address = 0;
-	char *subreadname = 0;
-
-        log_set_name(argv[0]);
-
-	while ((opt = getopt(argc, argv, "hcCVL:a:")) != -1) {
-		switch(opt) {
-		case 'L':
-			listdir = optarg;
-			break;
-		case 'a':
-			address = optarg;
-			break;
-		case 'c':
-			confirmunsub = 1;
-			break;
-		case 'C':
-			unsubconfirm = 1;
-			break;
-		case 'h':
-			print_help(argv[0]);
-			break;
-		case 'V':
-			print_version(argv[0]);
-			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(confirmunsub && unsubconfirm) {
-		fprintf(stderr, "Cannot specify both -C and -c\n");
-		fprintf(stderr, "%s -h for help\n", argv[0]);
-		exit(EXIT_FAILURE);
-	}
-
-	/* get the list address */
-	getlistaddr(listaddr, listdir);
-
-	subreadname = concatstr(2, listdir, "/subscribers");
-
-	subread = open(subreadname, O_RDWR);
-	if(subread == -1) {
-		log_error("Could not open subscriberfile:");
-		exit(EXIT_FAILURE);
-	}
-
-	sublock = myexcllock(subread);
-	if(sublock) {
-		log_error("Error locking subscriber file:");
-		close(subread);
-		exit(EXIT_FAILURE);
-	}
-
-	if(find_subscriber(subread, address)) {
-		myunlock(subread);
-		free(subreadname);
-		close(subread);
-		exit(EXIT_SUCCESS);
-	}
-
-	subwrite = open(subreadname, O_RDWR);
-	if(subwrite == -1){
-		log_error("Could not open subfile:");
-		exit(EXIT_FAILURE);
-	}
-	if(unsubconfirm)
-		generate_unsubconfirm(listdir, listaddr, address);
-	else
-		unsubscribe(subread, subwrite, address);
-	
-	myunlock(subread);
-
-	free(subreadname);
-	close(subread);
-	close(subwrite);
-
-	if(confirmunsub)
-		confirm_unsub(listdir, listaddr, address);
-
-	return EXIT_SUCCESS;
-}