All of lore.kernel.org
 help / color / mirror / Atom feed
* Per-list recipient delimiters (patch attached)
@ 2005-10-01 23:54 Joel Aelwyn
  2005-10-02 12:28 ` Mads Martin Joergensen
  0 siblings, 1 reply; 2+ messages in thread
From: Joel Aelwyn @ 2005-10-01 23:54 UTC (permalink / raw)
  To: mlmmj


[-- Attachment #1.1: Type: text/plain, Size: 3300 bytes --]

As discussed a bit ago, I've been working on a patch to support per-list 
configurable recipient delimiters. I believe the patch below covers just about 
everything, and in some ways is significantly more flexible than most of the 
alternatives which I've seen so far:

1) Recipient delimiters are considered strings, not characters. This means 
that it supports arbitrary multi-character sequences; something which isn't 
used very often in practice, but which is supported by at least some mailers. 
Really, it's no more complex or slower, so why not support it?

2) Uses the standard configuration file arrangement. The delimiter for a list 
is read from the first line of .../control/delimiter (not including the 
newline, if present, of course).

3) I have attempted to keep the patch minimally invasive. Casual visual 
inspection should be enough to make it fairly obvious what's going on; I have 
specifically *not* cleaned up several sub-optimal situations that I came 
across while doing the patch (mostly places with memory leaks that almost 
certainly don't matter in practice, or where things are re-allocated several 
times rather than being passed around, despite all callers being guaranteed to 
have the data available).

4) I have *not* attempted to write a help file for this (apart from, well, 
this mail).

5) The code has at least a couple of points where it assumes that the literal 
'-' is safe to use (things like -moderators). However, I cannot find anything 
where this is actually a failure case; all of the addresses generated this way 
are either unused, or occur after at least one instance of the actual 
delimiter (as 'parameter' separators), or do not appear to be used for 
anything but labeling. However, I don't know every possible situation that 
could fall into this category offhand, so...

6) The only guarantee you have about this patch is that I'm running it, and so 
far it hasn't broken things on my server. I certainly tried to throw several 
pathological cases at it, but I could always have missed something. Since 
MLMMJ doesn't appear to have any unit test suite, I didn't add any.

7) There is at least one known... hmmm. I'm not sure if it's a 'misfeature' or 
not, and it will only occur if your server is configured to recognize 
*multiple* list delimiters (say, both '+' and '-') on all lists. In this case, 
if someone sends email to, say, 'list-subscribe' but your list is configured 
to look for '+' as a delimiter, it will fail to match the recipient-extra 
string (since it is looking for '+...' but the string is '-subscribe'). The 
only obvious way around this would be to make the delimiter entirely optional, 
and parse it up front, but read a string provided by the mailer in some 
fashion to find the recipient-extra portion if it can't match the extra 
portion at all. If there's demand, I can investigate this; I might do so 
anyway (since I believe my mailer can provide this, and it would allow users 
to use either extension), but no promises.

[ Note: the patch was made against sources based on the Debian 1.2.8-7 
package, but as far as I know, it *should* patch just fine against stock 
1.2.8, possibly with the free() -> myfree() patch for prepstdreply.c that was 
posted previously. ]
-- 
Joel Aelwyn <joel@lightbearer.com>

[-- Attachment #1.2: per-list_recipient_delimiter.patch --]
[-- Type: text/plain, Size: 50830 bytes --]

diff -urNad mlmmj-1.2.8.DEBIAN-7/include/getlistdelim.h chroot-work.5/include/getlistdelim.h
--- mlmmj-1.2.8.DEBIAN-7/include/getlistdelim.h	1969-12-31 17:00:00.000000000 -0700
+++ chroot-work.5/include/getlistdelim.h	2005-09-15 00:50:52.000000000 -0600
@@ -0,0 +1,29 @@
+/* Copyright 2005 Joel Aelwyn <joel@lightbearer.com>
+ *
+ * $Id$
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef GETLISTDELIM_H
+#define GETLISTDELIM_H
+
+char *getlistdelim(const char *listdir);
+
+#endif /* GETLISTDELIM_H */
diff -urNad mlmmj-1.2.8.DEBIAN-7/include/mlmmj.h chroot-work.5/include/mlmmj.h
--- mlmmj-1.2.8.DEBIAN-7/include/mlmmj.h	2005-01-15 03:53:52.000000000 -0700
+++ chroot-work.5/include/mlmmj.h	2005-09-21 01:00:22.646289000 -0600
@@ -28,7 +28,7 @@
 
 #define RELAYHOST "127.0.0.1"
 #define READ_BUFSIZE 2048
-#define RECIPDELIM '+'  /* XXX Warning: not changable at the moment */
+#define DEFAULT_RECIPDELIM "+"  /* Default recipient delimiter */
 #define MODREQLIFE 604800 /* How long time will moderation requests be kept?
 			   * 604800s is 7 days */
 #define DISCARDEDLIFE 604800 /* How long time will discarded mails be kept?
diff -urNad mlmmj-1.2.8.DEBIAN-7/include/mlmmj-send.h chroot-work.5/include/mlmmj-send.h
--- mlmmj-1.2.8.DEBIAN-7/include/mlmmj-send.h	2005-02-08 11:13:14.000000000 -0700
+++ chroot-work.5/include/mlmmj-send.h	2005-09-20 22:13:15.577746000 -0600
@@ -31,16 +31,16 @@
 	      size_t bodylen);
 int send_mail_many_fd(int sockfd, const char *from, const char *replyto,
 		   char *mailmap, size_t mailsize, int subfd,
-		   const char *listaddr, const char *archivefilename,
-		   const char *listdir, const char *mlmmjbounce,
-		   const char *hdrs, size_t hdrslen, const char *body,
-		   size_t bodylen);
+		   const char *listaddr, const char *listdelim,
+		   const char *archivefilename, const char *listdir,
+		   const char *mlmmjbounce, const char *hdrs, size_t hdrslen,
+		   const char *body, size_t bodylen);
 int send_mail_many_list(int sockfd, const char *from, const char *replyto,
 		   char *mailmap, size_t mailsize, struct strlist *addrs,
-		   const char *listaddr, const char *archivefilename,
-		   const char *listdir, const char *mlmmjbounce,
-		   const char *hdrs, size_t hdrslen, const char *body,
-		   size_t bodylen);
+		   const char *listaddr, const char *listdelim,
+		   const char *archivefilename, const char *listdir,
+		   const char *mlmmjbounce, const char *hdrs, size_t hdrslen,
+		   const char *body, size_t bodylen);
 int send_mail_verp(int sockfd, struct strlist *addrs, char *mailmap,
 		   size_t mailsize, const char *from, const char *listdir,
 		   const char *hdrs, size_t hdrslen, const char *body,
diff -urNad mlmmj-1.2.8.DEBIAN-7/include/mlmmj-sub.h chroot-work.5/include/mlmmj-sub.h
--- mlmmj-1.2.8.DEBIAN-7/include/mlmmj-sub.h	2004-09-23 08:29:26.000000000 -0600
+++ chroot-work.5/include/mlmmj-sub.h	2005-09-15 01:49:39.000000000 -0600
@@ -27,10 +27,10 @@
 #include <mlmmj.h>
 
 void confirm_sub(const char *listdir, const char *listaddr,
-		 const char *subaddr, const char *mlmmjsend,
-		 enum subtype typesub);
+		 const char *listdelim, const char *subaddr,
+		 const char *mlmmjsend, enum subtype typesub);
 void generate_subconfirm(const char *listdir, const char *listadr,
-		const char *subaddr, const char *mlmmjsend,
-		enum subtype typesub);
+		const char *listdelim, const char *subaddr,
+		const char *mlmmjsend, enum subtype typesub);
 
 #endif /* MLMMJ_SUBSCRIBE_H */
diff -urNad mlmmj-1.2.8.DEBIAN-7/include/mlmmj-unsub.h chroot-work.5/include/mlmmj-unsub.h
--- mlmmj-1.2.8.DEBIAN-7/include/mlmmj-unsub.h	2004-09-23 08:29:27.000000000 -0600
+++ chroot-work.5/include/mlmmj-unsub.h	2005-09-15 01:42:29.000000000 -0600
@@ -27,11 +27,11 @@
 #include <sys/types.h>
 
 void confirm_unsub(const char *listdir, const char *listaddr,
-		   const char *subaddr, const char *mlmmj,
-		   enum subtype typesub);
+		   const char *listdelim, const char *subaddr,
+		   const char *mlmmj, enum subtype typesub);
 ssize_t unsubscribe(int subreadfd, int subwritefd, const char *address);
 void generate_unsubconfirm(const char *listdir, const char *listaddr,
-			   const char *subaddr, const char *mlmmjsend,
-			   enum subtype typesub);
+			   const char *listdelim, const char *subaddr,
+			   const char *mlmmjsend, enum subtype typesub);
 
 #endif /* MLMMJ_UNSUBSCRIBE_H */
diff -urNad mlmmj-1.2.8.DEBIAN-7/include/prepstdreply.h chroot-work.5/include/prepstdreply.h
--- mlmmj-1.2.8.DEBIAN-7/include/prepstdreply.h	2004-11-11 16:27:06.000000000 -0700
+++ chroot-work.5/include/prepstdreply.h	2005-09-20 21:51:45.104699000 -0600
@@ -24,10 +24,10 @@
 #ifndef PREPSTDREPLY_H
 #define PREPSTDREPLY_H
 
-char *substitute(const char *line, const char *listaddr, size_t datacount,
-		 char **data);
-char *substitute_one(const char *line, const char *listaddr, size_t datacount,
-		 char **data);
+char *substitute(const char *line, const char *listaddr, const char *listdelim,
+		 size_t datacount, char **data);
+char *substitute_one(const char *line, const char *listaddr,
+		 const char *listdelim, size_t datacount, char **data);
 char *prepstdreply(const char *listdir, const char *filename, const char *from,
 		   const char *to, const char *replyto, size_t tokencount,
 		   char **data);
diff -urNad mlmmj-1.2.8.DEBIAN-7/src/getlistdelim.c chroot-work.6/src/getlistdelim.c
--- mlmmj-1.2.8.DEBIAN-7/src/getlistdelim.c	1969-12-31 17:00:00.000000000 -0700
+++ chroot-work.6/src/getlistdelim.c	2005-09-21 09:57:31.400197000 -0600
@@ -0,0 +1,70 @@
+/* Copyright 2005 Joel Aelwyn <joel@lightbearer.com>
+ *
+ * $Id$
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS+ * IN THE SOFTWARE.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "mlmmj.h"
+#include "getlistdelim.h"
+#include "chomp.h"
+#include "log_error.h"
+#include "mygetline.h"
+#include "strgen.h"
+#include "memory.h"
+
+char *getlistdelim(const char *listdir)
+{
+	char *delimfn, *delimstr;
+	int delimfd;
+
+	delimfn = concatstr(2, listdir, "/control/delimiter");
+	if(-1 != (delimfd = open(delimfn, O_RDONLY))){
+		delimstr = mygetline(delimfd);
+		close(delimfd);
+
+		if(NULL == delimstr){
+			log_error(LOG_ARGS,
+				  "FATAL. Could not get list delimiter from %s",
+				  delimfn);
+			myfree(delimfn);
+			exit(EXIT_FAILURE);
+		}
+	
+		chomp(delimstr);
+	
+		if(0 == strlen(delimstr)){
+			log_error(LOG_ARGS,
+				  "FATAL. Zero-length delimiter found from %s",
+				  delimfn);
+			myfree(delimfn);
+			exit(EXIT_FAILURE);
+		}
+	} else
+		delimstr = mystrdup(DEFAULT_RECIPDELIM);
+
+	myfree(delimfn);
+
+	return delimstr;
+}
diff -urNad mlmmj-1.2.8.DEBIAN-7/src/listcontrol.c chroot-work.6/src/listcontrol.c
--- mlmmj-1.2.8.DEBIAN-7/src/listcontrol.c	2005-05-02 11:39:10.000000000 -0600
+++ chroot-work.6/src/listcontrol.c	2005-09-22 00:25:24.642281625 -0600
@@ -34,6 +34,7 @@
 #include "mlmmj.h"
 #include "listcontrol.h"
 #include "find_email_adr.h"
+#include "getlistdelim.h"
 #include "strgen.h"
 #include "send_help.h"
 #include "send_list.h"
@@ -100,7 +101,7 @@
 		const char *mlmmjunsub, const char *mlmmjsend,
 		const char *mlmmjbounce, const char *mailname)
 {
-	char *atsign, *recipdelimsign, *bouncenr, *tmpstr;
+	char *atsign, *recipdelimsign, *listdelim, *bouncenr, *tmpstr;
 	char *controlstr, *param = NULL, *conffilename, *moderatefilename;
 	char *c, *archivefilename, *sendfilename;
 	const char *subswitch;
@@ -120,7 +121,8 @@
 	else
 		subswitch = "-C";
 	
-	recipdelimsign = index(controladdr, RECIPDELIM);
+	listdelim = getlistdelim(listdir);
+	recipdelimsign = strstr(controladdr, listdelim);
 	MY_ASSERT(recipdelimsign);
 	atsign = index(controladdr, '@');
 	MY_ASSERT(atsign);
@@ -128,7 +130,8 @@
 
 	controlstr = mymalloc(len);
 	MY_ASSERT(controlstr);
-	snprintf(controlstr, len, "%s", recipdelimsign + 1);
+	snprintf(controlstr, len, "%s", recipdelimsign + strlen(listdelim));
+	myfree(listdelim);
 
 #if 0
 	log_error(LOG_ARGS, "controlstr = [%s]\n", controlstr);
diff -urNad mlmmj-1.2.8.DEBIAN-7/src/Makefile.in chroot-work.5/src/Makefile.in
--- mlmmj-1.2.8.DEBIAN-7/src/Makefile.in	2005-06-20 07:34:02.000000000 -0600
+++ chroot-work.5/src/Makefile.in	2005-09-15 01:38:29.000000000 -0600
@@ -61,8 +61,8 @@
 	subscriberfuncs.$(OBJEXT) strgen.$(OBJEXT) \
 	random-int.$(OBJEXT) writen.$(OBJEXT) prepstdreply.$(OBJEXT) \
 	mygetline.$(OBJEXT) chomp.$(OBJEXT) getlistaddr.$(OBJEXT) \
-	memory.$(OBJEXT) find_email_adr.$(OBJEXT) gethdrline.$(OBJEXT) \
-	readn.$(OBJEXT)
+	getlistdelim.$(OBJEXT) memory.$(OBJEXT) find_email_adr.$(OBJEXT) \
+	gethdrline.$(OBJEXT) readn.$(OBJEXT)
 mlmmj_bounce_OBJECTS = $(am_mlmmj_bounce_OBJECTS)
 mlmmj_bounce_LDADD = $(LDADD)
 am_mlmmj_list_OBJECTS = mlmmj-list.$(OBJEXT) strgen.$(OBJEXT) \
@@ -75,15 +75,15 @@
 	mygetline.$(OBJEXT) strgen.$(OBJEXT) random-int.$(OBJEXT) \
 	chomp.$(OBJEXT) writen.$(OBJEXT) memory.$(OBJEXT) \
 	ctrlvalue.$(OBJEXT) send_digest.$(OBJEXT) \
-	getlistaddr.$(OBJEXT) dumpfd2fd.$(OBJEXT) mylocking.$(OBJEXT) \
-	log_oper.$(OBJEXT) readn.$(OBJEXT)
+	getlistaddr.$(OBJEXT) getlistdelim.$(OBJEXT) dumpfd2fd.$(OBJEXT) \
+	mylocking.$(OBJEXT) log_oper.$(OBJEXT) readn.$(OBJEXT)
 mlmmj_maintd_OBJECTS = $(am_mlmmj_maintd_OBJECTS)
 mlmmj_maintd_LDADD = $(LDADD)
 am_mlmmj_process_OBJECTS = mlmmj-process.$(OBJEXT) writen.$(OBJEXT) \
 	find_email_adr.$(OBJEXT) incindexfile.$(OBJEXT) itoa.$(OBJEXT) \
-	getlistaddr.$(OBJEXT) chomp.$(OBJEXT) mylocking.$(OBJEXT) \
-	listcontrol.$(OBJEXT) random-int.$(OBJEXT) strgen.$(OBJEXT) \
-	print-version.$(OBJEXT) send_help.$(OBJEXT) \
+	getlistaddr.$(OBJEXT) getlistdelim.$(OBJEXT) chomp.$(OBJEXT) \
+	mylocking.$(OBJEXT) listcontrol.$(OBJEXT) random-int.$(OBJEXT) \
+	strgen.$(OBJEXT) print-version.$(OBJEXT) send_help.$(OBJEXT) \
 	prepstdreply.$(OBJEXT) do_all_the_voodo_here.$(OBJEXT) \
 	mygetline.$(OBJEXT) gethdrline.$(OBJEXT) log_error.$(OBJEXT) \
 	statctrl.$(OBJEXT) ctrlvalue.$(OBJEXT) dumpfd2fd.$(OBJEXT) \
@@ -101,7 +101,7 @@
 am_mlmmj_send_OBJECTS = mlmmj-send.$(OBJEXT) writen.$(OBJEXT) \
 	mail-functions.$(OBJEXT) itoa.$(OBJEXT) chomp.$(OBJEXT) \
 	incindexfile.$(OBJEXT) checkwait_smtpreply.$(OBJEXT) \
-	getlistaddr.$(OBJEXT) mylocking.$(OBJEXT) \
+	getlistaddr.$(OBJEXT) getlistdelim.$(OBJEXT) mylocking.$(OBJEXT) \
 	init_sockfd.$(OBJEXT) strgen.$(OBJEXT) random-int.$(OBJEXT) \
 	print-version.$(OBJEXT) log_error.$(OBJEXT) \
 	mygetline.$(OBJEXT) memory.$(OBJEXT) statctrl.$(OBJEXT) \
@@ -109,16 +109,16 @@
 mlmmj_send_OBJECTS = $(am_mlmmj_send_OBJECTS)
 mlmmj_send_LDADD = $(LDADD)
 am_mlmmj_sub_OBJECTS = mlmmj-sub.$(OBJEXT) writen.$(OBJEXT) \
-	mylocking.$(OBJEXT) getlistaddr.$(OBJEXT) chomp.$(OBJEXT) \
-	random-int.$(OBJEXT) strgen.$(OBJEXT) \
+	mylocking.$(OBJEXT) getlistaddr.$(OBJEXT) getlistdelim.$(OBJEXT) \
+	chomp.$(OBJEXT) random-int.$(OBJEXT) strgen.$(OBJEXT) \
 	subscriberfuncs.$(OBJEXT) print-version.$(OBJEXT) \
 	log_error.$(OBJEXT) mygetline.$(OBJEXT) prepstdreply.$(OBJEXT) \
 	memory.$(OBJEXT) statctrl.$(OBJEXT) readn.$(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) \
+	mylocking.$(OBJEXT) getlistaddr.$(OBJEXT) getlistdelim.$(OBJEXT) \
+	chomp.$(OBJEXT) subscriberfuncs.$(OBJEXT) random-int.$(OBJEXT) \
 	strgen.$(OBJEXT) print-version.$(OBJEXT) log_error.$(OBJEXT) \
 	mygetline.$(OBJEXT) prepstdreply.$(OBJEXT) memory.$(OBJEXT) \
 	statctrl.$(OBJEXT) readn.$(OBJEXT)
@@ -223,43 +223,44 @@
 EXTRA_DIST = mlmmj-make-ml.sh
 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 mygetline.c memory.c \
-		     statctrl.c ctrlvalue.c getaddrsfromfd.c readn.c
+		     getlistdelim.c mylocking.c init_sockfd.c strgen.c \
+		     random-int.c print-version.c log_error.c mygetline.c \
+		     memory.c statctrl.c ctrlvalue.c getaddrsfromfd.c readn.c
 
 mlmmj_recieve_SOURCES = mlmmj-recieve.c writen.c random-int.c strgen.c \
 			print-version.c log_error.c dumpfd2fd.c memory.c \
 			log_oper.c mylocking.c readn.c
 
 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 \
-			print-version.c send_help.c prepstdreply.c \
+			incindexfile.c itoa.c getlistaddr.c getlistdelim.c \
+			chomp.c mylocking.c listcontrol.c random-int.c \
+			strgen.c print-version.c send_help.c prepstdreply.c \
 			do_all_the_voodo_here.c mygetline.c gethdrline.c \
 			log_error.c statctrl.c ctrlvalue.c dumpfd2fd.c \
 			subscriberfuncs.c ctrlvalues.c memory.c log_oper.c \
 			send_list.c readn.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 \
+			getlistaddr.c getlistdelim.c chomp.c random-int.c \
+			strgen.c subscriberfuncs.c print-version.c \
 			log_error.c mygetline.c prepstdreply.c memory.c \
 			statctrl.c readn.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 statctrl.c readn.c
+			getlistaddr.c getlistdelim.c chomp.c subscriberfuncs.c \
+			random-int.c strgen.c print-version.c log_error.c \
+			mygetline.c prepstdreply.c memory.c statctrl.c readn.c
 
 mlmmj_bounce_SOURCES = mlmmj-bounce.c print-version.c log_error.c \
 		       subscriberfuncs.c strgen.c random-int.c writen.c \
 		       prepstdreply.c mygetline.c chomp.c getlistaddr.c \
-		       memory.c find_email_adr.c gethdrline.c readn.c
+		       getlistdelim.c memory.c find_email_adr.c gethdrline.c \
+		       readn.c
 
 mlmmj_maintd_SOURCES = mlmmj-maintd.c print-version.c log_error.c mygetline.c \
 		       strgen.c random-int.c chomp.c writen.c memory.c \
-		       ctrlvalue.c send_digest.c getlistaddr.c dumpfd2fd.c \
-		       mylocking.c log_oper.c readn.c
+		       ctrlvalue.c send_digest.c getlistaddr.c getlistdelim.c \
+		       dumpfd2fd.c mylocking.c log_oper.c readn.c
 
 mlmmj_list_SOURCES = mlmmj-list.c strgen.c writen.c print-version.c memory.c \
 		     log_error.c random-int.c readn.c
diff -urNad mlmmj-1.2.8.DEBIAN-7/src/mlmmj-bounce.c chroot-work.5/src/mlmmj-bounce.c
--- mlmmj-1.2.8.DEBIAN-7/src/mlmmj-bounce.c	2005-05-02 11:39:10.000000000 -0600
+++ chroot-work.5/src/mlmmj-bounce.c	2005-09-15 01:21:33.000000000 -0600
@@ -36,6 +36,7 @@
 #include <ctype.h>
 
 #include "getlistaddr.h"
+#include "getlistdelim.h"
 #include "mlmmj.h"
 #include "strgen.h"
 #include "wrappers.h"
@@ -101,7 +102,7 @@
 void do_probe(const char *listdir, const char *mlmmjsend, const char *addr)
 {
 	char *myaddr, *from, *a, *indexstr, *queuefilename, *listaddr;
-	char *listfqdn, *listname, *probefile;
+	char *listfqdn, *listname, *probefile, *listdelim=getlistdelim(listdir);
 	char *maildata[] = { "bouncenumbers", NULL };
 	int fd;
 	time_t t;
@@ -112,9 +113,11 @@
 	listname = genlistname(listaddr);
 	listfqdn = genlistfqdn(listaddr);
 
-	from = concatstr(5, listname, "+bounces-probe-", myaddr, "@", listfqdn);
+	from = concatstr(6, listname, listdelim, "bounces-probe-", myaddr, "@",
+			 listfqdn);
 
 	myfree(listaddr);
+	myfree(listdelim);
 	myfree(listfqdn);
 	myfree(listname);
 
diff -urNad mlmmj-1.2.8.DEBIAN-7/src/mlmmj-process.c chroot-work.6/src/mlmmj-process.c
--- mlmmj-1.2.8.DEBIAN-7/src/mlmmj-process.c	2005-05-02 11:41:01.000000000 -0600
+++ chroot-work.6/src/mlmmj-process.c	2005-09-21 23:51:58.518244405 -0600
@@ -37,6 +37,7 @@
 #include "find_email_adr.h"
 #include "incindexfile.h"
 #include "getlistaddr.h"
+#include "getlistdelim.h"
 #include "listcontrol.h"
 #include "strgen.h"
 #include "do_all_the_voodo_here.h"
@@ -71,7 +72,7 @@
 		  const char *mlmmjsend)
 {
 	char *from, *listfqdn, *listname, *moderators = NULL;
-	char *buf, *replyto, *listaddr = getlistaddr(listdir);
+	char *buf, *replyto, *listaddr = getlistaddr(listdir), *listdelim;
 	char *queuefilename = NULL, *moderatorsfilename;
 	char *mailbasename = mybasename(mailfilename), *tmp, *to;
 	int queuefd, moderatorsfd, mailfd;
@@ -106,15 +107,17 @@
 
 	close(moderatorsfd);
 
-	replyto = concatstr(5, listname, "+moderate-", mailbasename, "@",
-			    listfqdn);
+	listdelim = getlistdelim(listdir);
+	replyto = concatstr(6, listname, listdelim, "moderate-", mailbasename,
+			    "@", listfqdn);
 
 	maildata[1] = replyto;
 	maildata[3] = moderators;
 
-	from = concatstr(3, listname, "+owner@", listfqdn);
-	to = concatstr(3, listname, "-moderators@", listfqdn);
+	from = concatstr(4, listname, listdelim, "owner@", listfqdn);
+	to = concatstr(3, listname, "-moderators@", listfqdn); /* FIXME JFA: Should this be converted? Why, why not? */
 
+	myfree(listdelim);
 	myfree(listname);
 	myfree(listfqdn);
 
@@ -318,9 +321,9 @@
 	char *footerfilename = NULL, *donemailname = NULL;
 	char *randomstr = NULL, *mqueuename;
 	char *mlmmjsend, *mlmmjsub, *mlmmjunsub, *mlmmjbounce;
-	char *bindir, *subjectprefix, *discardname, *listaddr;
+	char *bindir, *subjectprefix, *discardname, *listaddr, *listdelim;
 	char *listfqdn, *listname, *fromaddr;
-	char *queuefilename, *recipdelim, *owner = NULL;
+	char *queuefilename, *recipextra, *owner = NULL;
 	char *maildata[2] = { "posteraddr", NULL };
 	struct stat st;
 	uid_t uid;
@@ -512,14 +515,18 @@
 	else
 		whichto = NULL;
 
-	if(whichto && whichto->emaillist && whichto->emaillist[0])
-		recipdelim = strchr(whichto->emaillist[0], RECIPDELIM);
-	else
-		recipdelim = NULL;
+	listdelim = getlistdelim(listdir);
+	if(whichto && whichto->emaillist && whichto->emaillist[0]){
+		recipextra = strstr(whichto->emaillist[0], listdelim);
+		if (recipextra)
+			recipextra += strlen(listdelim);
+	} else
+		recipextra = NULL;
+	myfree(listdelim);
 
-	if(recipdelim) {
+	if(recipextra) {
 		owner = concatstr(2, listdir, "/control/owner");
-		if(owner && strncmp(recipdelim, "+owner@", 7) == 0) {
+		if(owner && strncmp(recipextra, "owner@", 6) == 0) {
 			/* strip envelope from before resending */
 			delheaders->count = 0;
 			delheaders->strs = NULL;
@@ -643,13 +650,16 @@
 			myfree(donemailname);
 			exit(EXIT_SUCCESS);
 		}
+		listdelim = getlistdelim(listdir);
 		listname = genlistname(listaddr);
 		listfqdn = genlistfqdn(listaddr);
-		fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
+		fromaddr = concatstr(4, listname, listdelim, "bounces-help@",
+				     listfqdn);
 		queuefilename = prepstdreply(listdir, "notintocc",
 					"$listowner$", fromemails.emaillist[0],
 					NULL, 0, NULL);
 		MY_ASSERT(queuefilename)
+		myfree(listdelim);
 		myfree(listname);
 		myfree(listfqdn);
 		unlink(donemailname);
@@ -683,16 +693,18 @@
 				myfree(donemailname);
 				exit(EXIT_SUCCESS);
 			}
+			listdelim = getlistdelim(listdir);
 			listname = genlistname(listaddr);
 			listfqdn = genlistfqdn(listaddr);
 			maildata[1] = fromemails.emaillist[0];
-			fromaddr = concatstr(3, listname, "+bounces-help@",
-					listfqdn);
+			fromaddr = concatstr(4, listname, listdelim,
+					"bounces-help@", listfqdn);
 			queuefilename = prepstdreply(listdir, "subonlypost",
 					"$listowner$", fromemails.emaillist[0],
 					NULL, 1, maildata);
 			MY_ASSERT(queuefilename)
 			myfree(listaddr);
+			myfree(listdelim);
 			myfree(listname);
 			myfree(listfqdn);
 			unlink(donemailname);
@@ -724,16 +736,18 @@
 				myfree(donemailname);
 				exit(EXIT_SUCCESS);
 			}
+			listdelim = getlistdelim(listdir);
 			listname = genlistname(listaddr);
 			listfqdn = genlistfqdn(listaddr);
-			fromaddr = concatstr(3, listname, "+bounces-help@",
-					listfqdn);
+			fromaddr = concatstr(4, listname, listdelim,
+					"bounces-help@", listfqdn);
 			queuefilename = prepstdreply(listdir, "access",
 							"$listowner$",
 							fromemails.emaillist[0],
 							NULL, 0, NULL);
 			MY_ASSERT(queuefilename)
 			myfree(listaddr);
+			myfree(listdelim);
 			myfree(listname);
 			myfree(listfqdn);
 			unlink(donemailname);
diff -urNad mlmmj-1.2.8.DEBIAN-7/src/mlmmj-send.c chroot-work.5/src/mlmmj-send.c
--- mlmmj-1.2.8.DEBIAN-7/src/mlmmj-send.c	2005-06-20 06:40:39.000000000 -0600
+++ chroot-work.5/src/mlmmj-send.c	2005-09-20 22:32:37.400886000 -0600
@@ -51,6 +51,7 @@
 #include "chomp.h"
 #include "checkwait_smtpreply.h"
 #include "getlistaddr.h"
+#include "getlistdelim.h"
 #include "init_sockfd.h"
 #include "strgen.h"
 #include "log_error.h"
@@ -73,9 +74,9 @@
 }
 
 char *bounce_from_adr(const char *recipient, const char *listadr,
-		      const char *mailfilename)
+		      const char *listdelim, const char *mailfilename)
 {
-	char *bounceaddr, *myrecipient, *mylistadr;
+	char *bounceaddr, *myrecipient, *mylistadr, *mylistdelim;
 	char *indexstr, *listdomain, *a = NULL, *mymailfilename;
 	size_t len;
 
@@ -107,29 +108,40 @@
 		return NULL;
 	}
 
+	mylistdelim = mystrdup(listdelim);
+	if (!mylistdelim) {
+		myfree(mymailfilename);
+		myfree(myrecipient);
+		myfree(mylistadr);
+		return NULL;
+	}
+
 	listdomain = strchr(mylistadr, '@');
 	if (!listdomain) {
 		myfree(mymailfilename);
 		myfree(myrecipient);
 		myfree(mylistadr);
+		myfree(mylistdelim);
 		return NULL;
 	}
 	*listdomain++ = '\0';
 
-	/* 12 = RECIPDELIM + "bounces-" + "-" + "@" + NUL */
-	len = strlen(mylistadr) + strlen(myrecipient) + strlen(indexstr)
-		 + strlen(listdomain) + 12;
+	/* 11 = "bounces-" + "-" + "@" + NUL */
+	len = strlen(mylistadr) + strlen(mylistdelim) + strlen(myrecipient)
+		 + strlen(indexstr) + strlen(listdomain) + 11;
 	bounceaddr = mymalloc(len);
 	if (!bounceaddr) {
 		myfree(myrecipient);
 		myfree(mylistadr);
+		myfree(mylistdelim);
 		return NULL;
 	}
-	snprintf(bounceaddr, len, "%s%cbounces-%s-%s@%s", mylistadr, RECIPDELIM,
+	snprintf(bounceaddr, len, "%s%sbounces-%s-%s@%s", mylistadr, listdelim,
 		 indexstr, myrecipient, listdomain);
 
 	myfree(myrecipient);
 	myfree(mylistadr);
+	myfree(mylistdelim);
 	myfree(mymailfilename);
 
 	return bounceaddr;
@@ -138,18 +150,20 @@
 int bouncemail(const char *listdir, const char *mlmmjbounce, const char *from)
 {
 	char *myfrom = mystrdup(from);
+	char *listdelim = getlistdelim(listdir);
 	char *addr, *num, *c;
 	size_t len;
 	pid_t pid = 0;
 
 	if((c = strchr(myfrom, '@')) == NULL) {
 		myfree(myfrom);
+		myfree(listdelim);
 		return 0; /* Success when malformed 'from' */
 	}
 	*c = '\0';
 	num = strrchr(myfrom, '-');
 	num++;
-	c = strchr(myfrom, RECIPDELIM);
+	c = strstr(myfrom, listdelim);
 	myfrom = strchr(c, '-');
 	myfrom++;
 	len = num - myfrom - 1;
@@ -157,6 +171,8 @@
 	addr[len] = '\0';
 	strncpy(addr, myfrom, len);
 
+	myfree(listdelim);
+
 	pid = fork();
 	
 	if(pid < 0) {
@@ -464,10 +480,10 @@
 
 int send_mail_many_fd(int sockfd, const char *from, const char *replyto,
 		      char *mailmap, size_t mailsize, int subfd,
-		      const char *listaddr, const char *archivefilename,
-		      const char *listdir, const char *mlmmjbounce,
-		      const char *hdrs, size_t hdrslen, const char *body,
-		      size_t bodylen)
+		      const char *listaddr, const char *listdelim,
+		      const char *archivefilename, const char *listdir,
+		      const char *mlmmjbounce, const char *hdrs, size_t hdrslen,
+		      const char *body, size_t bodylen)
 {
 	int res, ret, i;
 	struct strlist stl;
@@ -480,8 +496,9 @@
 		if(stl.count == maxverprecips) {
 			ret = send_mail_many_list(sockfd, from, replyto,
 					mailmap, mailsize, &stl, listaddr,
-					archivefilename, listdir, mlmmjbounce,
-					hdrs, hdrslen, body, bodylen);
+					listdelim, archivefilename, listdir,
+					mlmmjbounce, hdrs, hdrslen,
+					body, bodylen);
 			for(i = 0; i < stl.count; i++)
 				myfree(stl.strs[i]);
 			if(ret < 0)
@@ -492,9 +509,9 @@
 
 	if(stl.count) {
 		ret = send_mail_many_list(sockfd, from, replyto, mailmap,
-				mailsize, &stl, listaddr, archivefilename,
-				listdir, mlmmjbounce, hdrs, hdrslen, body,
-				bodylen);
+				mailsize, &stl, listaddr, listdelim,
+				archivefilename, listdir, mlmmjbounce,
+				hdrs, hdrslen, body, bodylen);
 		for(i = 0; i < stl.count; i++)
 			myfree(stl.strs[i]);
 		stl.count = 0;
@@ -557,10 +574,10 @@
 
 int send_mail_many_list(int sockfd, const char *from, const char *replyto,
 		   char *mailmap, size_t mailsize, struct strlist *addrs,
-		   const char *listaddr, const char *archivefilename,
-		   const char *listdir, const char *mlmmjbounce,
-		   const char *hdrs, size_t hdrslen, const char *body,
-		   size_t bodylen)
+		   const char *listaddr, const char *listdelim,
+		   const char *archivefilename, const char *listdir,
+		   const char *mlmmjbounce, const char *hdrs, size_t hdrslen,
+		   const char *body, size_t bodylen)
 {
 	int res = 0, i;
 	char *bounceaddr, *addr, *index;
@@ -585,7 +602,7 @@
 					    mailmap, mailsize, listdir, NULL,
 					    hdrs, hdrslen, body, bodylen);
 		} else {
-			bounceaddr = bounce_from_adr(addr, listaddr,
+			bounceaddr = bounce_from_adr(addr, listaddr, listdelim,
 						     archivefilename);
 			res = send_mail(sockfd, bounceaddr, addr, replyto,
 				  mailmap, mailsize, listdir, mlmmjbounce,
@@ -634,7 +651,8 @@
 	int sockfd = -1, mailfd = 0, opt, mindex = 0, subfd = 0, tmpfd, i;
 	int deletewhensent = 1, sendres = 0, archive = 1, digest = 0;
 	int ctrlarchive, res;
-	char *listaddr = NULL, *mailfilename = NULL, *subfilename = NULL;
+	char *listaddr = NULL, *listdelim = NULL;
+	char *mailfilename = NULL, *subfilename = NULL;
 	char *replyto = NULL, *bounceaddr = NULL, *to_addr = NULL;
 	char *relayhost = NULL, *archivefilename = NULL, *tmpstr;
 	char *listctrl = NULL, *subddirname = NULL, *listdir = NULL;
@@ -845,6 +862,9 @@
 		}
 	}
 
+	if(listdir)
+		listdelim = getlistdelim(listdir);
+
 	switch(listctrl[0]) {
 	case '1': /* A single mail is to be sent, do nothing */
 	case '5':
@@ -857,6 +877,7 @@
 			myfree(hdrs);
 			myfree(body);
 			myfree(subfilename);
+			myfree(listdelim);
 			/* No moderators is no error. Could be the sysadmin
 			 * likes to do it manually.
 			 */
@@ -870,6 +891,7 @@
 					    subfilename);
 			myfree(hdrs);
 			myfree(body);
+			myfree(listdelim);
 			exit(EXIT_FAILURE);
 		}
 		break;
@@ -877,7 +899,7 @@
 		archive = 0;
 		deletewhensent = 0;
 		archivefilename = mystrdup(mailfilename);
-		bounceaddr = bounce_from_adr(to_addr, listaddr,
+		bounceaddr = bounce_from_adr(to_addr, listaddr, listdelim,
 						archivefilename);
 		break;
 	default: /* normal list mail -- now handled when forking */
@@ -977,8 +999,9 @@
 	case '2': /* Moderators */
 		initsmtp(&sockfd, relay, smtpport);
 		if(send_mail_many_fd(sockfd, bounceaddr, NULL, mailmap,
-				     st.st_size, subfd, NULL, NULL, listdir,
-				     NULL, hdrs, hdrslen, body, bodylen))
+				     st.st_size, subfd, NULL, NULL, NULL,
+				     listdir, NULL, hdrs, hdrslen,
+				     body, bodylen))
 			close(sockfd);
 		else
 			endsmtp(&sockfd);
@@ -986,8 +1009,9 @@
 	case '3': /* resending earlier failed mails */
 		initsmtp(&sockfd, relay, smtpport);
 		if(send_mail_many_fd(sockfd, NULL, NULL, mailmap, st.st_size,
-				subfd, listaddr, mailfilename, listdir,
-				mlmmjbounce, hdrs, hdrslen, body, bodylen))
+				subfd, listaddr, listdelim, mailfilename,
+				listdir, mlmmjbounce, hdrs, hdrslen,
+				body, bodylen))
 			close(sockfd);
 		else
 			endsmtp(&sockfd);
@@ -996,9 +1020,9 @@
 	case '4': /* send mails to owner */
 		initsmtp(&sockfd, relay, smtpport);
 		if(send_mail_many_fd(sockfd, bounceaddr, NULL, mailmap,
-				st.st_size, subfd, listaddr, mailfilename,
-				listdir, mlmmjbounce, hdrs, hdrslen, body,
-				bodylen))
+				st.st_size, subfd, listaddr, listdelim,
+				mailfilename, listdir, mlmmjbounce,
+				hdrs, hdrslen, body, bodylen))
 			close(sockfd);
 		else
 			endsmtp(&sockfd);
@@ -1035,16 +1059,18 @@
 		if((subddir = opendir(subddirname)) == NULL) {
 			log_error(LOG_ARGS, "Could not opendir(%s)",
 					    subddirname);
+			myfree(listdelim);
 			myfree(subddirname);
 			myfree(hdrs);
 			myfree(body);
 			exit(EXIT_FAILURE);
 		}
 
+		listdelim = getlistdelim(listdir);
 		listname = genlistname(listaddr);	
 		listfqdn = genlistfqdn(listaddr);	
-		verpfrom = concatstr(5, listname, "+bounces-", strindex, "@",
-				listfqdn);
+		verpfrom = concatstr(6, listname, listdelim, "bounces-",
+				strindex, "@", listfqdn);
 		myfree(listname);
 		myfree(listfqdn);
 
@@ -1120,6 +1146,7 @@
 								st.st_size,
 								&stl,
 								listaddr,
+								listdelim,
 								archivefilename,
 								listdir,
 								mlmmjbounce,
@@ -1149,7 +1176,7 @@
 			} else {
 				sendres = send_mail_many_list(sockfd, NULL,
 						NULL, mailmap, st.st_size,
-						&stl, listaddr,
+						&stl, listaddr, listdelim,
 						archivefilename, listdir,
 						mlmmjbounce, hdrs, hdrslen,
 						body, bodylen);
@@ -1180,6 +1207,7 @@
 		myfree(stl.strs[i]);
 	stl.count = 0;
 
+	myfree(listdelim);
 	myfree(hdrs);
 	myfree(body);
 	myfree(mlmmjbounce);
diff -urNad mlmmj-1.2.8.DEBIAN-7/src/mlmmj-sub.c chroot-work.5/src/mlmmj-sub.c
--- mlmmj-1.2.8.DEBIAN-7/src/mlmmj-sub.c	2005-06-20 06:40:39.000000000 -0600
+++ chroot-work.5/src/mlmmj-sub.c	2005-09-15 01:53:32.000000000 -0600
@@ -38,6 +38,7 @@
 #include "mylocking.h"
 #include "wrappers.h"
 #include "getlistaddr.h"
+#include "getlistdelim.h"
 #include "strgen.h"
 #include "subscriberfuncs.h"
 #include "log_error.h"
@@ -47,15 +48,15 @@
 #include "memory.h"
 
 void confirm_sub(const char *listdir, const char *listaddr,
-		const char *subaddr, const char *mlmmjsend,
-		enum subtype typesub)
+		const char *listdelim, const char *subaddr,
+		const char *mlmmjsend, enum subtype typesub)
 {
 	char *queuefilename, *fromaddr, *listname, *listfqdn, *listtext;
 
 	listname = genlistname(listaddr);
 	listfqdn = genlistfqdn(listaddr);
 
-	fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
+	fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn);
 
 	myfree(listname);
 	myfree(listfqdn);
@@ -88,8 +89,8 @@
 }
 
 void notify_sub(const char *listdir, const char *listaddr,
-		const char *subaddr, const char *mlmmjsend,
-		enum subtype typesub)
+		const char *listdelim, const char *subaddr,
+		const char *mlmmjsend, enum subtype typesub)
 {
 	char *maildata[2] = { "newsub", NULL };
 	char *listfqdn, *listname, *fromaddr, *tostr;
@@ -100,8 +101,8 @@
 
 	maildata[1] = mystrdup(subaddr);
 	
-	fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
-	tostr = concatstr(3, listname, "+owner@", listfqdn);
+	fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn);
+	tostr = concatstr(4, listname, listdelim, "owner@", listfqdn);
 	
 	myfree(listname);
 	myfree(listfqdn);
@@ -135,8 +136,8 @@
 }
 
 void generate_subconfirm(const char *listdir, const char *listaddr,
-			 const char *subaddr, const char *mlmmjsend,
-			 enum subtype typesub)
+			 const char *listdelim, const char *subaddr,
+			 const char *mlmmjsend, enum subtype typesub)
 {
 	int subconffd;
 	char *confirmaddr, *listname, *listfqdn, *confirmfilename = NULL;
@@ -177,26 +178,27 @@
 
 	close(subconffd);
 
-	fromaddr = concatstr(5, listname, "+bounces-confsub-", randomstr,
-				"@", listfqdn);
+	fromaddr = concatstr(6, listname, listdelim, "bounces-confsub-",
+				randomstr, "@", listfqdn);
 	
 	switch(typesub) {
 		default:
 		case SUB_NORMAL:
 			listtext = mystrdup("sub-confirm");
-			tmpstr = mystrdup("+confsub-");
+			tmpstr = mystrdup("confsub-");
 			break;
 		case SUB_DIGEST:
 			listtext = mystrdup("sub-confirm-digest");
-			tmpstr = mystrdup("+confsub-digest-");
+			tmpstr = mystrdup("confsub-digest-");
 			break;
 		case SUB_NOMAIL:
 			listtext = mystrdup("sub-confirm-nomail");
-			tmpstr = mystrdup("+confsub-nomail-");
+			tmpstr = mystrdup("confsub-nomail-");
 			break;
 	}
 
-	confirmaddr = concatstr(5, listname, tmpstr, randomstr, "@", listfqdn);
+	confirmaddr = concatstr(6, listname, listdelim, tmpstr, randomstr, "@",
+				listfqdn);
 
 	myfree(randomstr);
 	myfree(tmpstr);
@@ -245,12 +247,14 @@
 		const char *mlmmjsend)
 {
 	char *queuefilename, *fromaddr, *listname, *listfqdn, *listaddr;
+	char *listdelim = getlistdelim(listdir);
 
 	listaddr = getlistaddr(listdir);
 	listname = genlistname(listaddr);
 	listfqdn = genlistfqdn(listaddr);
 
-	fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
+	fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn);
+	myfree(listdelim);
 
 	queuefilename = prepstdreply(listdir, "sub-subscribed", "$helpaddr$",
 				     subaddr, NULL, 0, NULL);
@@ -272,9 +276,9 @@
 
 int main(int argc, char **argv)
 {
-	char *listaddr, *listdir = NULL, *address = NULL, *subfilename = NULL;
-	char *mlmmjsend, *bindir, chstr[2], *subdir, *subddirname = NULL;
-	char *sublockname;
+	char *listaddr, *listdelim, *listdir = NULL, *address = NULL;
+	char *subfilename = NULL, *mlmmjsend, *bindir, chstr[2], *subdir;
+	char *subddirname = NULL, *sublockname;
 	int subconfirm = 0, confirmsub = 0, opt, subfilefd, lock, notifysub;
 	int changeuid = 1, status, digest = 0, nomail = 0;
 	int groupwritable = 0, sublock, sublockfd, nogensubscribed = 0;
@@ -439,14 +443,15 @@
 		exit(EXIT_FAILURE);
 	}
 	suboff = find_subscriber(subfilefd, address);
+	listdelim = getlistdelim(listdir);
 	if(suboff == -1) {
 		if(subconfirm) {
 			close(subfilefd);
 			close(sublockfd);
 			unlink(sublockname);
 			myfree(sublockname);
-			generate_subconfirm(listdir, listaddr, address,
-					    mlmmjsend, typesub);
+			generate_subconfirm(listdir, listaddr, listdelim,
+					    address, mlmmjsend, typesub);
 		} else {
 			lseek(subfilefd, 0L, SEEK_END);
 			len = strlen(address);
@@ -479,8 +484,8 @@
 
 		if(childpid < 0) {
 			log_error(LOG_ARGS, "Could not fork");
-			confirm_sub(listdir, listaddr, address, mlmmjsend,
-					typesub);
+			confirm_sub(listdir, listaddr, listdelim, address,
+					mlmmjsend, typesub);
 		}
 		
 		if(childpid > 0) {
@@ -491,17 +496,19 @@
 
 		/* child confirms subscription */
 		if(childpid == 0)
-			confirm_sub(listdir, listaddr, address, mlmmjsend,
-					typesub);
+			confirm_sub(listdir, listaddr, listdelim, address,
+					mlmmjsend, typesub);
 	}
 
 	notifysub = statctrl(listdir, "notifysub");
 
 	/* Notify list owner about subscription */
 	if (notifysub)
-		notify_sub(listdir, listaddr, address, mlmmjsend, typesub);
+		notify_sub(listdir, listaddr, listdelim, address, mlmmjsend,
+				typesub);
 
 	myfree(listaddr);
+	myfree(listdelim);
 
 	return EXIT_SUCCESS;
 }
diff -urNad mlmmj-1.2.8.DEBIAN-7/src/mlmmj-unsub.c chroot-work.5/src/mlmmj-unsub.c
--- mlmmj-1.2.8.DEBIAN-7/src/mlmmj-unsub.c	2005-06-20 06:40:39.000000000 -0600
+++ chroot-work.5/src/mlmmj-unsub.c	2005-09-15 01:53:14.000000000 -0600
@@ -39,6 +39,7 @@
 #include "wrappers.h"
 #include "mygetline.h"
 #include "getlistaddr.h"
+#include "getlistdelim.h"
 #include "subscriberfuncs.h"
 #include "strgen.h"
 #include "log_error.h"
@@ -47,15 +48,15 @@
 #include "prepstdreply.h"
 
 void confirm_unsub(const char *listdir, const char *listaddr,
-		   const char *subaddr, const char *mlmmjsend,
-		   enum subtype typesub)
+		   const char *listdelim, const char *subaddr,
+		   const char *mlmmjsend, enum subtype typesub)
 {
 	char *queuefilename, *fromaddr, *listname, *listfqdn, *listtext;
 
 	listname = genlistname(listaddr);
 	listfqdn = genlistfqdn(listaddr);
 
-	fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
+	fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn);
 
 	myfree(listname);
 	myfree(listfqdn);
@@ -89,8 +90,8 @@
 }
 
 void notify_unsub(const char *listdir, const char *listaddr,
-		  const char *subaddr, const char *mlmmjsend,
-		  enum subtype typesub)
+		  const char *listdelim, const char *subaddr,
+		  const char *mlmmjsend, enum subtype typesub)
 {
         char *maildata[4] = { "oldsub", NULL };
         char *listfqdn, *listname, *fromaddr, *tostr;
@@ -101,8 +102,8 @@
 
         maildata[1] = mystrdup(subaddr);
 
-        fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
-	tostr = concatstr(3, listname, "+owner@", listfqdn);
+        fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn);
+	tostr = concatstr(4, listname, listdelim, "owner@", listfqdn);
 
 	myfree(listname);
 	myfree(listfqdn);
@@ -138,8 +139,8 @@
 
 
 void generate_unsubconfirm(const char *listdir, const char *listaddr,
-			   const char *subaddr, const char *mlmmjsend,
-			   enum subtype typesub)
+			   const char *listdelim, const char *subaddr,
+			   const char *mlmmjsend, enum subtype typesub)
 {
 	char *confirmaddr, *listname, *listfqdn, *tmpstr;
 	char *queuefilename, *fromaddr;
@@ -180,26 +181,27 @@
 
 	close(subconffd);
 
-	fromaddr = concatstr(5, listname, "+bounces-confunsub-", randomstr,
-				"@", listfqdn);
+	fromaddr = concatstr(6, listname, listdelim, "bounces-confunsub-",
+				randomstr, "@", listfqdn);
 
 	switch(typesub) {
 		default:
 		case SUB_NORMAL:
 			listtext = mystrdup("unsub-confirm");
-			tmpstr = mystrdup("+confunsub-");
+			tmpstr = mystrdup("confunsub-");
 			break;
 		case SUB_DIGEST:
 			listtext = mystrdup("unsub-confirm-digest");
-			tmpstr = mystrdup("+confunsub-digest-");
+			tmpstr = mystrdup("confunsub-digest-");
 			break;
 		case SUB_NOMAIL:
 			listtext = mystrdup("unsub-confirm-nomail");
-			tmpstr = mystrdup("+confunsub-nomail-");
+			tmpstr = mystrdup("confunsub-nomail-");
 			break;
 	}
 
-	confirmaddr = concatstr(5, listname, tmpstr, randomstr, "@", listfqdn);
+	confirmaddr = concatstr(6, listname, listdelim, tmpstr, randomstr, "@",
+				listfqdn);
 
 	myfree(randomstr);
 	myfree(tmpstr);
@@ -289,12 +291,14 @@
 		const char *mlmmjsend)
 {
 	char *queuefilename, *fromaddr, *listname, *listfqdn, *listaddr;
+	char *listdelim = getlistdelim(listdir);
 
 	listaddr = getlistaddr(listdir);
 	listname = genlistname(listaddr);
 	listfqdn = genlistfqdn(listaddr);
 
-	fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
+	fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn);
+	myfree(listdelim);
 
 	queuefilename = prepstdreply(listdir, "unsub-notsubscribed",
 				     "$helpaddr$", subaddr, NULL, 0, NULL);
@@ -321,8 +325,8 @@
 	int confirmunsub = 0, unsubconfirm = 0, notifysub = 0, digest = 0;
 	int changeuid = 1, groupwritable = 0, sublock, sublockfd;
 	int nogennotsubscribed = 0;
-	char *listaddr, *listdir = NULL, *address = NULL, *subreadname = NULL;
-	char *subwritename, *mlmmjsend, *bindir, *subdir;
+	char *listaddr, *listdelim, *listdir = NULL, *address = NULL;
+	char *subreadname = NULL, *subwritename, *mlmmjsend, *bindir, *subdir;
 	char *subddirname, *sublockname;
 	off_t suboff;
 	DIR *subddir;
@@ -446,15 +450,17 @@
 		exit(EXIT_SUCCESS);
 	}
 
+	listdelim = getlistdelim(listdir);
 	if(unsubconfirm)
-		generate_unsubconfirm(listdir, listaddr, address, mlmmjsend,
-				typesub);
+		generate_unsubconfirm(listdir, listaddr, listdelim, address,
+				mlmmjsend, typesub);
 
 	if((subddir = opendir(subddirname)) == NULL) {
 		log_error(LOG_ARGS, "Could not opendir(%s)",
 				    subddirname);
 		myfree(subddirname);
 		myfree(listaddr);
+		myfree(listdelim);
 		exit(EXIT_FAILURE);
 	}
 
@@ -582,8 +588,8 @@
 
 			if(childpid < 0) {
 				log_error(LOG_ARGS, "Could not fork");
-				confirm_unsub(listdir, listaddr, address,
-						mlmmjsend, digest);
+				confirm_unsub(listdir, listaddr, listdelim,
+						address, mlmmjsend, digest);
 			}
 
 			if(childpid > 0) {
@@ -594,8 +600,8 @@
 
 			/* child confirms subscription */
 			if(childpid == 0)
-				confirm_unsub(listdir, listaddr, address,
-						mlmmjsend, digest);
+				confirm_unsub(listdir, listaddr, listdelim,
+						address, mlmmjsend, digest);
 		}
         }
 
@@ -605,9 +611,11 @@
 
         /* Notify list owner about subscription */
         if (notifysub)
-                notify_unsub(listdir, listaddr, address, mlmmjsend, typesub);
+                notify_unsub(listdir, listaddr, listdelim, address, mlmmjsend,
+				typesub);
 
 	myfree(listaddr);
+	myfree(listdelim);
 
 	return EXIT_SUCCESS;
 }
diff -urNad mlmmj-1.2.8.DEBIAN-7/src/prepstdreply.c chroot-work.5/src/prepstdreply.c
--- mlmmj-1.2.8.DEBIAN-7/src/prepstdreply.c	2005-01-15 03:46:24.000000000 -0700
+++ chroot-work.5/src/prepstdreply.c	2005-09-21 01:00:22.623299000 -0600
@@ -38,15 +38,16 @@
 #include "wrappers.h"
 #include "memory.h"
 #include "getlistaddr.h"
+#include "getlistdelim.h"
 
-char *substitute(const char *line, const char *listaddr, size_t datacount,
-		 char **data)
+char *substitute(const char *line, const char *listaddr, const char *listdelim,
+		 size_t datacount, char **data)
 {
 	char *s1, *s2;
 
-	s1 = substitute_one(line, listaddr, datacount, data);
+	s1 = substitute_one(line, listaddr, listdelim, datacount, data);
 	while(s1) {
-		s2 = substitute_one(s1, listaddr, datacount, data);
+		s2 = substitute_one(s1, listaddr, listdelim, datacount, data);
 		if(s2) {
 			myfree(s1);
 			s1 = s2;
@@ -57,8 +58,8 @@
 	return mystrdup(line);
 }
 
-char *substitute_one(const char *line, const char *listaddr, size_t datacount,
-		     char **data)
+char *substitute_one(const char *line, const char *listaddr,
+		     const char *listdelim, size_t datacount, char **data)
 {
 	char *fqdn, *listname, *d1, *d2, *token, *value = NULL;
 	char *retstr, *origline;
@@ -95,31 +96,35 @@
 		value = mystrdup(listaddr);
 		goto concatandreturn;
 	} else if(strcmp(token, "listowner") == 0) {
-		value = concatstr(3, listname, "+owner@", fqdn);
+		value = concatstr(4, listname, listdelim, "owner@", fqdn);
 		goto concatandreturn;
 	} else if(strcmp(token, "helpaddr") == 0) {
-		value = concatstr(3, listname, "+help@", fqdn);
+		value = concatstr(4, listname, listdelim, "help@", fqdn);
 		goto concatandreturn;
 	} else if(strcmp(token, "listgetN") == 0) {
-		value = concatstr(3, listname, "+get-N@", fqdn);
+		value = concatstr(4, listname, listdelim, "get-N@", fqdn);
 		goto concatandreturn;
 	} else if(strcmp(token, "listunsubaddr") == 0) {
-		value = concatstr(3, listname, "+unsubscribe@", fqdn);
+		value = concatstr(4, listname, listdelim, "unsubscribe@", fqdn);
 		goto concatandreturn;
 	} else if(strcmp(token, "digestunsubaddr") == 0) {
-		value = concatstr(3, listname, "+unsubscribe-digest@", fqdn);
+		value = concatstr(4, listname, listdelim,
+				  "unsubscribe-digest@", fqdn);
 		goto concatandreturn;
 	} else if(strcmp(token, "nomailunsubaddr") == 0) {
-		value = concatstr(3, listname, "+unsubscribe-nomail@", fqdn);
+		value = concatstr(4, listname, listdelim,
+				  "unsubscribe-nomail@", fqdn);
 		goto concatandreturn;
 	} else if(strcmp(token, "listsubaddr") == 0) {
-		value = concatstr(3, listname, "+subscribe@", fqdn);
+		value = concatstr(4, listname, listdelim, "subscribe@", fqdn);
 		goto concatandreturn;
 	} else if(strcmp(token, "digestsubaddr") == 0) {
-		value = concatstr(3, listname, "+subscribe-digest@", fqdn);
+		value = concatstr(4, listname, listdelim, "subscribe-digest@",
+				  fqdn);
 		goto concatandreturn;
 	} else if(strcmp(token, "nomailsubaddr") == 0) {
-		value = concatstr(3, listname, "+subscribe-nomail@", fqdn);
+		value = concatstr(4, listname, listdelim, "subscribe-nomail@",
+				  fqdn);
 		goto concatandreturn;
 	}
 	if(data) {
@@ -150,7 +155,7 @@
 		   char **data)
 {
 	int infd, outfd;
-	char *listaddr, *myfrom, *tmp, *subject, *retstr = NULL;
+	char *listaddr, *listdelim, *myfrom, *tmp, *subject, *retstr = NULL;
 	char *myreplyto, *myto, *str = NULL, *mydate, *mymsgid;
 
 	tmp = concatstr(3, listdir, "/text/", filename);
@@ -162,6 +167,7 @@
 	}
 
 	listaddr = getlistaddr(listdir);
+	listdelim = getlistdelim(listdir);
 
 	tmp = mygetline(infd);
 	if(strncasecmp(tmp, "Subject:", 8) != 0) {
@@ -169,17 +175,19 @@
 				"standard subject");
 		subject = mystrdup("mlmmj administrativa\n");
 	} else
-		subject = substitute(tmp, listaddr, tokencount, data);
+		subject = substitute(tmp, listaddr, listdelim, tokencount,
+				     data);
 
 	myfree(tmp);
 	
-	myfrom = substitute(from, listaddr, tokencount, data);
-	myto = substitute(to, listaddr, tokencount, data);
+	myfrom = substitute(from, listaddr, listdelim, tokencount, data);
+	myto = substitute(to, listaddr, listdelim, tokencount, data);
 	mydate = gendatestr();
 	mymsgid = genmsgid();
 
 	if(replyto) {
-		myreplyto = substitute(replyto, listaddr, tokencount, data);
+		myreplyto = substitute(replyto, listaddr, listdelim,
+				       tokencount, data);
 		tmp = concatstr(3, "Reply-To: ", myreplyto, "\n");
 		free(myreplyto);
 		myreplyto = tmp;
@@ -199,6 +207,7 @@
 	if(outfd < 0) {
 		log_error(LOG_ARGS, "Could not open std mail %s", retstr);
 		myfree(str);
+		myfree(listdelim);
 		return NULL;
 	}
 
@@ -208,6 +217,7 @@
 	if(writen(outfd, str, strlen(str)) < 0) {
 		log_error(LOG_ARGS, "Could not write std mail");
 		myfree(str);
+		myfree(listdelim);
 		return NULL;
 	}
 
@@ -215,10 +225,11 @@
 
 	while((str = mygetline(infd))) {
 		tmp = str;
-		str = substitute(tmp, listaddr, tokencount, data);
+		str = substitute(tmp, listaddr, listdelim, tokencount, data);
 		myfree(tmp);
 		if(writen(outfd, str, strlen(str)) < 0) {
 			myfree(str);
+			myfree(listdelim);
 			log_error(LOG_ARGS, "Could not write std mail");
 			return NULL;
 		}
diff -urNad mlmmj-1.2.8.DEBIAN-7/src/send_digest.c chroot-work.5/src/send_digest.c
--- mlmmj-1.2.8.DEBIAN-7/src/send_digest.c	2005-01-19 12:22:14.000000000 -0700
+++ chroot-work.5/src/send_digest.c	2005-09-15 01:27:35.000000000 -0600
@@ -36,6 +36,7 @@
 #include "strgen.h"
 #include "memory.h"
 #include "getlistaddr.h"
+#include "getlistdelim.h"
 #include "wrappers.h"
 
 
@@ -45,7 +46,7 @@
 	int i, fd, archivefd, status, hdrfd;
 	char buf[45];
 	char *tmp, *queuename = NULL, *archivename, *fromstr;
-	char *boundary, *listaddr, *listname, *listfqdn;
+	char *boundary, *listaddr, *listdelim, *listname, *listfqdn;
 	pid_t childpid, pid;
 
 	if (addr) {
@@ -90,7 +91,11 @@
 		snprintf(buf, sizeof(buf), " (%d-%d)", firstindex, lastindex);
 	}
 
-	fromstr = concatstr(5, "From: ", listname, "+help@", listfqdn, "\n");
+	listdelim = getlistdelim(listdir);
+	fromstr = concatstr(6, "From: ", listname, listdelim, "help@", listfqdn,
+			    "\n");
+	myfree(listdelim);
+
 	tmp = concatstr(6, "MIME-Version: 1.0"
 			    "\nContent-Type: multipart/" DIGESTMIMETYPE "; "
 			    "boundary=", boundary,
diff -urNad mlmmj-1.2.8.DEBIAN-7/src/send_help.c chroot-work.5/src/send_help.c
--- mlmmj-1.2.8.DEBIAN-7/src/send_help.c	2005-01-19 12:22:14.000000000 -0700
+++ chroot-work.5/src/send_help.c	2005-09-15 01:30:22.000000000 -0600
@@ -34,6 +34,7 @@
 #include "strgen.h"
 #include "find_email_adr.h"
 #include "getlistaddr.h"
+#include "getlistdelim.h"
 #include "log_error.h"
 #include "chomp.h"
 #include "wrappers.h"
@@ -44,13 +45,16 @@
 void send_help(const char *listdir, const char *emailaddr,
 	       const char *mlmmjsend)
 {
-	char *queuefilename, *listaddr, *listname, *listfqdn, *fromaddr;
+	char *queuefilename, *listaddr, *listdelim, *listname, *listfqdn;
+	char *fromaddr;
 
 	listaddr = getlistaddr(listdir);
+	listdelim = getlistdelim(listdir);
 	listname = genlistname(listaddr);
 	listfqdn = genlistfqdn(listaddr);
 
-	fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
+	fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn);
+	myfree(listdelim);
 
 	queuefilename = prepstdreply(listdir, "listhelp", "$listowner$",
 					emailaddr, NULL, 0, NULL);
diff -urNad mlmmj-1.2.8.DEBIAN-7/src/send_list.c chroot-work.5/src/send_list.c
--- mlmmj-1.2.8.DEBIAN-7/src/send_list.c	2005-04-26 04:24:18.000000000 -0600
+++ chroot-work.5/src/send_list.c	2005-09-15 01:33:38.000000000 -0600
@@ -34,6 +34,7 @@
 #include "send_list.h"
 #include "strgen.h"
 #include "getlistaddr.h"
+#include "getlistdelim.h"
 #include "log_error.h"
 #include "chomp.h"
 #include "wrappers.h"
@@ -44,18 +45,20 @@
 void send_list(const char *listdir, const char *emailaddr,
 	       const char *mlmmjsend)
 {
-	char *queuefilename, *listaddr, *listname, *listfqdn, *fromaddr;
-	char *subdir, *fileiter;
+	char *queuefilename, *listaddr, *listdelim, *listname, *listfqdn;
+	char *fromaddr, *subdir, *fileiter;
 	DIR *dirp;
 	struct dirent *dp;
 	int fd, subfd;
 
 	listaddr = getlistaddr(listdir);
+	listdelim = getlistdelim(listdir);
 	listname = genlistname(listaddr);
 	listfqdn = genlistfqdn(listaddr);
 	subdir = concatstr(2, listdir, "/subscribers.d/");
 
-	fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
+	fromaddr = concatstr(4, listname, listdelim, "bounces-help@", listfqdn);
+	myfree(listdelim);
 
 	queuefilename = prepstdreply(listdir, "listsubs", "$listowner$",
 					emailaddr, NULL, 0, NULL);

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 187 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Per-list recipient delimiters (patch attached)
  2005-10-01 23:54 Per-list recipient delimiters (patch attached) Joel Aelwyn
@ 2005-10-02 12:28 ` Mads Martin Joergensen
  0 siblings, 0 replies; 2+ messages in thread
From: Mads Martin Joergensen @ 2005-10-02 12:28 UTC (permalink / raw)
  To: mlmmj

* Joel Aelwyn <joel@lightbearer.com> [Oct 02. 2005 02:11]:
> As discussed a bit ago, I've been working on a patch to support per-list 
> configurable recipient delimiters. I believe the patch below covers just 
> about everything, and in some ways is significantly more flexible than most 
> of the alternatives which I've seen so far:

[snip good stuff]

Thanks a lot. I'll review and merge the patch next week. 1.2.9 is coming
closer.

-- 
Mads Martin Joergensen, http://mmj.dk
"Why make things difficult, when it is possible to make them cryptic
 and totally illogical, with just a little bit more effort?"
                                -- A. P. J.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2005-10-02 12:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-10-01 23:54 Per-list recipient delimiters (patch attached) Joel Aelwyn
2005-10-02 12:28 ` Mads Martin Joergensen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.