changeset 754:ecb991e41a4c

Add $controlN$ substitution The interfaces to substitute() and substitute_one() have changed, as they now need to know the listdir to be able to find control files
author Ben Schmidt
date Wed, 06 Oct 2010 23:30:26 +1100
parents b58fd7980358
children bb803487199c
files ChangeLog README.listtexts include/ctrlvalue.h include/mygetline.h include/prepstdreply.h src/Makefile.am src/ctrlvalue.c src/mygetline.c src/prepstdreply.c src/send_digest.c
diffstat 10 files changed, 90 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Oct 06 23:26:26 2010 +1100
+++ b/ChangeLog	Wed Oct 06 23:30:26 2010 +1100
@@ -1,3 +1,4 @@
+ o Add $controlN$ substitution
  o Fix theoretically possible memory corruption by chomp()
  o Remove .sh from mlmmj-make-ml.sh; symlink original name
  o Correct spelling of 'receive' and 'voodoo' throughout the code and
--- a/README.listtexts	Wed Oct 06 23:26:26 2010 +1100
+++ b/README.listtexts	Wed Oct 06 23:30:26 2010 +1100
@@ -149,6 +149,11 @@
   the address to which to send mail to confirm the (un-)subscription in
   question
 
+- $controlN$
+  the contents of the control file named N, with its final newline stripped; N
+  represents the name of the file to be found in the list's control
+  subdirectory; the name may only include letters and digits
+
 - $digestfirst$
   (available only in digest)
   index of the first message included in a digest
--- a/include/ctrlvalue.h	Wed Oct 06 23:26:26 2010 +1100
+++ b/include/ctrlvalue.h	Wed Oct 06 23:30:26 2010 +1100
@@ -25,5 +25,6 @@
 #define CTRLVALUE_H
 
 char *ctrlvalue(const char *listdir, const char *ctrlstr);
+char *ctrlcontent(const char *listdir, const char *ctrlstr);
 
 #endif /* CTRLVALUE_H */
--- a/include/mygetline.h	Wed Oct 06 23:26:26 2010 +1100
+++ b/include/mygetline.h	Wed Oct 06 23:30:26 2010 +1100
@@ -31,5 +31,6 @@
 char *myfgetline(FILE *infile);
 #endif
 char *mygetline(int fd);
+char *mygetcontent(int fd);
 
 #endif /* #ifndef MYGETLINE_H */
--- a/include/prepstdreply.h	Wed Oct 06 23:26:26 2010 +1100
+++ b/include/prepstdreply.h	Wed Oct 06 23:30:26 2010 +1100
@@ -25,9 +25,9 @@
 #define PREPSTDREPLY_H
 
 char *substitute(const char *line, const char *listaddr, const char *listdelim,
-		size_t datacount, char **data);
+		size_t datacount, char **data, const char *listdir);
 char *substitute_one(const char *line, const char *listaddr,
-		const char *listdelim, size_t datacount, char **data);
+		const char *listdelim, size_t datacount, char **data, const char *listdir);
 int open_listtext(const char *listdir, const char *filename);
 char *prepstdreply(const char *listdir, const char *filename, const char *from,
 		const char *to, const char *replyto, size_t tokencount,
--- a/src/Makefile.am	Wed Oct 06 23:26:26 2010 +1100
+++ b/src/Makefile.am	Wed Oct 06 23:30:26 2010 +1100
@@ -37,19 +37,19 @@
 			subscriberfuncs.c print-version.c \
 			log_error.c mygetline.c prepstdreply.c memory.c \
 			statctrl.c readn.c getlistdelim.c ctrlvalues.c \
-			unistr.c
+			unistr.c ctrlvalue.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 \
-			getlistdelim.c unistr.c
+			getlistdelim.c unistr.c ctrlvalue.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 unistr.c
+		       getlistdelim.c unistr.c ctrlvalue.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 \
--- a/src/ctrlvalue.c	Wed Oct 06 23:26:26 2010 +1100
+++ b/src/ctrlvalue.c	Wed Oct 06 23:30:26 2010 +1100
@@ -33,10 +33,10 @@
 #include "chomp.h"
 #include "memory.h"
 
-char *ctrlvalue(const char *listdir, const char *ctrlstr)
+static char *ctrlval(const char *listdir, const char *ctrlstr, int oneline)
 {
 	char *filename, *value = NULL;
-	int ctrlfd;
+	int ctrlfd, i;
 
 	if(listdir == NULL)
 		return NULL;
@@ -48,12 +48,32 @@
 	if(ctrlfd < 0)
 		return NULL;
 		
+	if (oneline) {
 	value = mygetline(ctrlfd);
+		chomp(value);
+	} else {
+		value = mygetcontent(ctrlfd);
+		i = strlen(value) - 1;
+		if (i >= 0 && value[i] == '\n') {
+			value[i] = '\0';
+			i--;
+		}
+		if (i >= 0 && value[i] == '\r') {
+			value[i] = '\0';
+			i--;
+		}
+	}
 	close(ctrlfd);
-	chomp(value);
 
 	return value;
 }
 
+char *ctrlvalue(const char *listdir, const char *ctrlstr)
+{
+	return ctrlval(listdir, ctrlstr, 1);
+}
 	
-	
+char *ctrlcontent(const char *listdir, const char *ctrlstr)
+{
+	return ctrlval(listdir, ctrlstr, 0);
+}
--- a/src/mygetline.c	Wed Oct 06 23:26:26 2010 +1100
+++ b/src/mygetline.c	Wed Oct 06 23:30:26 2010 +1100
@@ -30,7 +30,7 @@
 #include "mygetline.h"
 #include "memory.h"
 
-char *mygetline(int fd)
+static char *mygetuntil(int fd, char eof)
 {
 	size_t i = 0, res, buf_size = BUFSIZE;  /* initial buffer size */
 	char *buf, ch;
@@ -62,9 +62,19 @@
 			buf = myrealloc(buf, buf_size);
 		}
 		buf[i++] = ch;
-		if(ch == '\n') {
+		if(ch == eof) {
 			buf[i] = '\0';
 			return buf;
 		}
 	}
 }
+
+char *mygetline(int fd)
+{
+	return mygetuntil(fd, '\n');
+}
+
+char *mygetcontent(int fd)
+{
+	return mygetuntil(fd, '\0');
+}
--- a/src/prepstdreply.c	Wed Oct 06 23:26:26 2010 +1100
+++ b/src/prepstdreply.c	Wed Oct 06 23:30:26 2010 +1100
@@ -32,6 +32,7 @@
 #include <errno.h>
 
 #include "prepstdreply.h"
+#include "ctrlvalue.h"
 #include "strgen.h"
 #include "chomp.h"
 #include "log_error.h"
@@ -44,13 +45,15 @@
 #include "unistr.h"
 
 char *substitute(const char *line, const char *listaddr, const char *listdelim,
-		 size_t datacount, char **data)
+		 size_t datacount, char **data, const char *listdir)
 {
 	char *s1, *s2;
 
-	s1 = substitute_one(line, listaddr, listdelim, datacount, data);
+	s1 = substitute_one(line, listaddr, listdelim, datacount, data,
+			listdir);
 	while(s1) {
-		s2 = substitute_one(s1, listaddr, listdelim, datacount, data);
+		s2 = substitute_one(s1, listaddr, listdelim, datacount, data,
+				listdir);
 		if(s2) {
 			myfree(s1);
 			s1 = s2;
@@ -62,7 +65,8 @@
 }
 
 char *substitute_one(const char *line, const char *listaddr,
-			const char *listdelim, size_t datacount, char **data)
+			const char *listdelim, size_t datacount, char **data,
+			const char *listdir)
 {
 	char *fqdn, *listname, *d1, *d2, *token, *value = NULL;
 	char *retstr, *origline;
@@ -132,6 +136,27 @@
 		value = concatstr(4, listname, listdelim, "subscribe-nomail@",
 				  fqdn);
 		goto concatandreturn;
+	} else if(strncmp(token, "control", 7) == 0) {
+		value = token + 7;
+		if(*value == '\0') {
+			value = mystrdup("");
+			goto concatandreturn;
+		}
+		for(; *value != '\0'; value++) {
+			if(*value >= '0' && *value <= '9') continue;
+			if(*value >= 'A' && *value <= 'Z') continue;
+			if(*value >= 'a' && *value <= 'z') continue;
+			break;
+		}
+		if(*value != '\0') {
+			value = mystrdup(token + 7);
+			goto concatandreturn;
+		}
+		value = token + 7;
+		value = ctrlcontent(listdir, value);
+		if (value == NULL)
+			value = mystrdup("");
+		goto concatandreturn;
 	}
 	if(data) {
 		for(i = 0; i < datacount; i++) {
@@ -237,11 +262,11 @@
 	tokencount += 6;
 
 	tmp = substitute(from, listaddr, listdelim,
-	                 tokencount, moredata);
+	                 tokencount, moredata, listdir);
 	headers[0] = concatstr(2, "From: ", tmp);
 	myfree(tmp);
 	tmp = substitute(to, listaddr, listdelim,
-	                 tokencount, moredata);
+	                 tokencount, moredata, listdir);
 	headers[1] = concatstr(2, "To: ", tmp);
 	myfree(tmp);
 	headers[2] = genmsgid(listfqdn);
@@ -255,7 +280,7 @@
 
 	if(replyto) {
 		tmp = substitute(replyto, listaddr, listdelim,
-		                 tokencount, moredata);
+		                 tokencount, moredata, listdir);
 		headers[8] = concatstr(2, "Reply-To: ", tmp);
 		myfree(tmp);
 	}
@@ -279,7 +304,7 @@
 			   continuation of previous header line */
 			utfsub = unistr_escaped_to_utf8(line);
 			str = substitute(utfsub, listaddr, listdelim,
-			                 tokencount, moredata);
+			                 tokencount, moredata, listdir);
 			myfree(utfsub);
 			len = strlen(str);
 			str[len] = '\n';
@@ -321,7 +346,7 @@
 			utfsub = unistr_escaped_to_utf8(tmp);
 			*tmp = '\0';
 			utfsub2 = substitute(utfsub, listaddr, listdelim,
-			                     tokencount, moredata);
+			                     tokencount, moredata, listdir);
 			myfree(utfsub);
 			if (strncasecmp(line, "Subject:", len) == 0) {
 				tmp = unistr_utf8_to_header(utfsub2);
@@ -427,7 +452,7 @@
 			myfree(utfline);
 		} else {
 			str = substitute(utfline, listaddr, listdelim,
-			                 tokencount, moredata);
+			                 tokencount, moredata, listdir);
 			myfree(utfline);
 			if(writen(outfd, str, strlen(str)) < 0) {
 				myfree(str);
--- a/src/send_digest.c	Wed Oct 06 23:26:26 2010 +1100
+++ b/src/send_digest.c	Wed Oct 06 23:30:26 2010 +1100
@@ -263,7 +263,7 @@
 		utfsub = unistr_escaped_to_utf8(line + 9);
 	}
 
-	utfsub2 = substitute(utfsub, listaddr, listdelim, 5, subst_data);
+	utfsub2 = substitute(utfsub, listaddr, listdelim, 5, subst_data, listdir);
 	subject = unistr_utf8_to_header(utfsub2);
 	myfree(utfsub);
 	myfree(utfsub2);
@@ -362,7 +362,7 @@
 				myfree(line);
 
 				tmp = substitute(utfline, listaddr, listdelim,
-						5, subst_data);
+						5, subst_data, listdir);
 				myfree(utfline);
 
 				if(writen(fd, tmp, strlen(tmp)) < 0) {