
(Note: some mail clients like mutt have hard coded limits on the length
of a To: address; e.g. mutt has a limit of 256 characters which it will
truncate if the address is longer than that.)
---
 src/listcontrol.c |   95 +++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 69 insertions(+), 26 deletions(-)

Index: b/src/listcontrol.c
===================================================================
--- a/src/listcontrol.c
+++ b/src/listcontrol.c
@@ -98,6 +98,34 @@ static struct ctrl_command ctrl_commands
 	{ "list",               0 }
 };
 
+struct strlist *splitparam(const char *param, const char split)
+{
+	char *c;
+	struct strlist *params = mymalloc(sizeof(struct strlist));
+	size_t len;
+
+	params->count = 0;
+	params->strs = NULL;
+
+	if (!param)
+		return params;
+
+	while (*param && (c = strchr(param, split)) != NULL) {
+		len = c - param;
+		params->strs = myrealloc(params->strs, sizeof(c) * (params->count + 1));
+		params->strs[params->count] = mymalloc(len + 1);
+		strncpy(params->strs[params->count], param, len);
+		params->strs[params->count++][len] = '\0';
+		param = c + 1;
+	}
+
+	/* handle last param */
+	if (*param) {
+		params->strs = myrealloc(params->strs, sizeof(c) * (params->count + 1));
+		params->strs[params->count++] = mystrdup(param);
+	}
+	return params;
+}
 
 int listcontrol(struct email_container *fromemails, const char *listdir,
 		const char *controlstr, const char *mlmmjsub,
@@ -114,7 +142,9 @@ int listcontrol(struct email_container *
 	size_t cmdlen;
 	unsigned int ctrl;
 	struct strlist *owners;
-	int owner_idx;
+	struct strlist *params;
+	int owner_idx, rc;
+	pid_t childpid;
 	
 	/* A closed list doesn't allow subscribtion and unsubscription */
 	closedlist = statctrl(listdir, "closedlist");
@@ -588,13 +618,13 @@ int listcontrol(struct email_container *
 		exit(EXIT_FAILURE);
 		break;
 
-	/* listname+moderate-COOKIE@domain.tld */
+	/* listname+moderate-COOKIE[-COOKIE...]@domain.tld */
 	case CTRL_MODERATE:
 		/* TODO Add accept/reject parameter to moderate */
-		moderatefilename = concatstr(3, listdir, "/moderation/", param);
 
 		/* Subscriber moderation */
 		if(strncmp(param, "subscribe", 9) == 0) {
+			moderatefilename = concatstr(3, listdir, "/moderation/", param);
 			log_oper(listdir, OPLOGFNAME, "%s moderated %s",
 				fromemails->emaillist[0], moderatefilename);
 			execlp(mlmmjsub, mlmmjsub,
@@ -603,32 +633,45 @@ int listcontrol(struct email_container *
 					"-c", (char *)NULL);
 		}
 
-		sendfilename = concatstr(2, moderatefilename, ".sending");
+		rc = EXIT_SUCCESS;
+		params = splitparam(param, '-');
+		for (i = 0; i < params->count; i++) {
+			moderatefilename = concatstr(3, listdir, "/moderation/", params->strs[i]);
+
+			sendfilename = concatstr(2, moderatefilename, ".sending");
+
+			if (stat(moderatefilename, &stbuf) < 0) {
+				myfree(moderatefilename);
+				/* no mail to moderate */
+				errno = 0;
+				log_error(LOG_ARGS, "A moderate request was"
+					" sent with a mismatching cookie."
+					" Ignoring mail");
+				continue;
+			}
+			/* Rename it to avoid mail being sent twice */
+			if (rename(moderatefilename, sendfilename) < 0) {
+				log_error(LOG_ARGS, "Could not rename to .sending");
+				rc = EXIT_FAILURE;
+			}
 
-		if(stat(moderatefilename, &stbuf) < 0) {
+			log_oper(listdir, OPLOGFNAME, "%s moderated %s",
+				fromemails->emaillist[0], moderatefilename);
 			myfree(moderatefilename);
-			/* no mail to moderate */
-			errno = 0;
-			log_error(LOG_ARGS, "A moderate request was"
-				" sent with a mismatching cookie."
-				" Ignoring mail");
-			return -1;
-		}
-		/* Rename it to avoid mail being sent twice */
-		if(rename(moderatefilename, sendfilename) < 0) {
-			log_error(LOG_ARGS, "Could not rename to .sending");
-			exit(EXIT_FAILURE);
-		}
+			childpid = fork();
+			if (childpid < 0)
+				log_error(LOG_ARGS, "fork() failed!  Proceeding anyway");
 
-		log_oper(listdir, OPLOGFNAME, "%s moderated %s",
-				fromemails->emaillist[0], moderatefilename);
-		myfree(moderatefilename);
-		execlp(mlmmjsend, mlmmjsend,
-				"-L", listdir,
-				"-m", sendfilename, (char *)NULL);
-		log_error(LOG_ARGS, "execlp() of '%s' failed",
-					mlmmjsend);
-		exit(EXIT_FAILURE);
+			if (!childpid) {
+				execlp(mlmmjsend, mlmmjsend,
+					"-L", listdir,
+					"-m", sendfilename, (char *)NULL);
+				log_error(LOG_ARGS, "execlp() of '%s' failed",
+						mlmmjsend);
+				exit(EXIT_FAILURE);
+			}
+		}
+		exit(rc);
 		break;
 
 	/* listname+help@domain.tld */


