From 0da0955f30f1612c8973c8042380c2535cfd5c63 Mon Sep 17 00:00:00 2001 From: Ben Schmidt Date: Wed, 6 Oct 2010 23:30:26 +1100 Subject: [PATCH] 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 --- ChangeLog | 1 + README.listtexts | 5 +++++ include/ctrlvalue.h | 1 + include/mygetline.h | 1 + include/prepstdreply.h | 4 ++-- src/Makefile.am | 6 +++--- src/ctrlvalue.c | 34 +++++++++++++++++++++++------- src/mygetline.c | 14 +++++++++++-- src/prepstdreply.c | 47 ++++++++++++++++++++++++++++++++---------- src/send_digest.c | 4 ++-- 10 files changed, 90 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 607dc8f9..9626c947 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/README.listtexts b/README.listtexts index fa61c7cf..9cc78e1b 100644 --- a/README.listtexts +++ b/README.listtexts @@ -149,6 +149,11 @@ multi-line substitutions and would not work in a header): 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 diff --git a/include/ctrlvalue.h b/include/ctrlvalue.h index 7bc74677..52391cbf 100644 --- a/include/ctrlvalue.h +++ b/include/ctrlvalue.h @@ -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 */ diff --git a/include/mygetline.h b/include/mygetline.h index fb914913..d172c6e4 100644 --- a/include/mygetline.h +++ b/include/mygetline.h @@ -31,5 +31,6 @@ char *myfgetline(FILE *infile); #endif char *mygetline(int fd); +char *mygetcontent(int fd); #endif /* #ifndef MYGETLINE_H */ diff --git a/include/prepstdreply.h b/include/prepstdreply.h index b8c90ba6..635f22f8 100644 --- a/include/prepstdreply.h +++ b/include/prepstdreply.h @@ -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, diff --git a/src/Makefile.am b/src/Makefile.am index 1f1cae03..af2d67ba 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,19 +37,19 @@ mlmmj_sub_SOURCES = mlmmj-sub.c writen.c mylocking.c \ 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 \ diff --git a/src/ctrlvalue.c b/src/ctrlvalue.c index f3d538d0..f59f45d6 100644 --- a/src/ctrlvalue.c +++ b/src/ctrlvalue.c @@ -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; @@ -47,13 +47,33 @@ char *ctrlvalue(const char *listdir, const char *ctrlstr) if(ctrlfd < 0) return NULL; - - value = mygetline(ctrlfd); + + 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); +} diff --git a/src/mygetline.c b/src/mygetline.c index 2959713e..814b8dac 100644 --- a/src/mygetline.c +++ b/src/mygetline.c @@ -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 @@ char *mygetline(int fd) 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'); +} diff --git a/src/prepstdreply.c b/src/prepstdreply.c index 66e3e7f4..7d9001e3 100644 --- a/src/prepstdreply.c +++ b/src/prepstdreply.c @@ -32,6 +32,7 @@ #include #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(const char *line, const char *listaddr, const char *listdelim, } 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 @@ char *substitute_one(const char *line, const char *listaddr, 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++) { @@ -229,7 +254,7 @@ char *prepstdreply(const char *listdir, const char *filename, const char *from, for (i=0; i<2*tokencount; i++) { moredata[i] = data[i]; } - for (i=0; i<6; i++) { + for (i=0; i<6; i++) { moredata[2*(tokencount+i)] = mystrdup("randomN"); moredata[2*(tokencount+i)][6] = '0' + i; moredata[2*(tokencount+i)+1] = random_str(); @@ -237,11 +262,11 @@ char *prepstdreply(const char *listdir, const char *filename, const char *from, 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 @@ char *prepstdreply(const char *listdir, const char *filename, const char *from, 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 @@ char *prepstdreply(const char *listdir, const char *filename, const char *from, 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 @@ char *prepstdreply(const char *listdir, const char *filename, const char *from, 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 @@ char *prepstdreply(const char *listdir, const char *filename, const char *from, myfree(utfline); } else { str = substitute(utfline, listaddr, listdelim, - tokencount, moredata); + tokencount, moredata, listdir); myfree(utfline); if(writen(outfd, str, strlen(str)) < 0) { myfree(str); diff --git a/src/send_digest.c b/src/send_digest.c index 2da7b5e5..c079e5e2 100644 --- a/src/send_digest.c +++ b/src/send_digest.c @@ -263,7 +263,7 @@ int send_digest(const char *listdir, int firstindex, int lastindex, 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 @@ errdighdrs: myfree(line); tmp = substitute(utfline, listaddr, listdelim, - 5, subst_data); + 5, subst_data, listdir); myfree(utfline); if(writen(fd, tmp, strlen(tmp)) < 0) { -- 2.47.3