comparison src/prepstdreply.c @ 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 5edfa9eef6c7
children af2d036b7d0c
comparison
equal deleted inserted replaced
753:b58fd7980358 754:ecb991e41a4c
30 #include <fcntl.h> 30 #include <fcntl.h>
31 #include <string.h> 31 #include <string.h>
32 #include <errno.h> 32 #include <errno.h>
33 33
34 #include "prepstdreply.h" 34 #include "prepstdreply.h"
35 #include "ctrlvalue.h"
35 #include "strgen.h" 36 #include "strgen.h"
36 #include "chomp.h" 37 #include "chomp.h"
37 #include "log_error.h" 38 #include "log_error.h"
38 #include "mygetline.h" 39 #include "mygetline.h"
39 #include "wrappers.h" 40 #include "wrappers.h"
42 #include "mlmmj.h" 43 #include "mlmmj.h"
43 #include "getlistdelim.h" 44 #include "getlistdelim.h"
44 #include "unistr.h" 45 #include "unistr.h"
45 46
46 char *substitute(const char *line, const char *listaddr, const char *listdelim, 47 char *substitute(const char *line, const char *listaddr, const char *listdelim,
47 size_t datacount, char **data) 48 size_t datacount, char **data, const char *listdir)
48 { 49 {
49 char *s1, *s2; 50 char *s1, *s2;
50 51
51 s1 = substitute_one(line, listaddr, listdelim, datacount, data); 52 s1 = substitute_one(line, listaddr, listdelim, datacount, data,
53 listdir);
52 while(s1) { 54 while(s1) {
53 s2 = substitute_one(s1, listaddr, listdelim, datacount, data); 55 s2 = substitute_one(s1, listaddr, listdelim, datacount, data,
56 listdir);
54 if(s2) { 57 if(s2) {
55 myfree(s1); 58 myfree(s1);
56 s1 = s2; 59 s1 = s2;
57 } else 60 } else
58 return s1; 61 return s1;
60 63
61 return mystrdup(line); 64 return mystrdup(line);
62 } 65 }
63 66
64 char *substitute_one(const char *line, const char *listaddr, 67 char *substitute_one(const char *line, const char *listaddr,
65 const char *listdelim, size_t datacount, char **data) 68 const char *listdelim, size_t datacount, char **data,
69 const char *listdir)
66 { 70 {
67 char *fqdn, *listname, *d1, *d2, *token, *value = NULL; 71 char *fqdn, *listname, *d1, *d2, *token, *value = NULL;
68 char *retstr, *origline; 72 char *retstr, *origline;
69 size_t len, i; 73 size_t len, i;
70 74
130 goto concatandreturn; 134 goto concatandreturn;
131 } else if(strcmp(token, "nomailsubaddr") == 0) { 135 } else if(strcmp(token, "nomailsubaddr") == 0) {
132 value = concatstr(4, listname, listdelim, "subscribe-nomail@", 136 value = concatstr(4, listname, listdelim, "subscribe-nomail@",
133 fqdn); 137 fqdn);
134 goto concatandreturn; 138 goto concatandreturn;
139 } else if(strncmp(token, "control", 7) == 0) {
140 value = token + 7;
141 if(*value == '\0') {
142 value = mystrdup("");
143 goto concatandreturn;
144 }
145 for(; *value != '\0'; value++) {
146 if(*value >= '0' && *value <= '9') continue;
147 if(*value >= 'A' && *value <= 'Z') continue;
148 if(*value >= 'a' && *value <= 'z') continue;
149 break;
150 }
151 if(*value != '\0') {
152 value = mystrdup(token + 7);
153 goto concatandreturn;
154 }
155 value = token + 7;
156 value = ctrlcontent(listdir, value);
157 if (value == NULL)
158 value = mystrdup("");
159 goto concatandreturn;
135 } 160 }
136 if(data) { 161 if(data) {
137 for(i = 0; i < datacount; i++) { 162 for(i = 0; i < datacount; i++) {
138 if(strcmp(token, data[i*2]) == 0) { 163 if(strcmp(token, data[i*2]) == 0) {
139 value = mystrdup(data[(i*2)+1]); 164 value = mystrdup(data[(i*2)+1]);
227 252
228 moredata = mymalloc(2*(tokencount+6) * sizeof(char *)); 253 moredata = mymalloc(2*(tokencount+6) * sizeof(char *));
229 for (i=0; i<2*tokencount; i++) { 254 for (i=0; i<2*tokencount; i++) {
230 moredata[i] = data[i]; 255 moredata[i] = data[i];
231 } 256 }
232 for (i=0; i<6; i++) { 257 for (i=0; i<6; i++) {
233 moredata[2*(tokencount+i)] = mystrdup("randomN"); 258 moredata[2*(tokencount+i)] = mystrdup("randomN");
234 moredata[2*(tokencount+i)][6] = '0' + i; 259 moredata[2*(tokencount+i)][6] = '0' + i;
235 moredata[2*(tokencount+i)+1] = random_str(); 260 moredata[2*(tokencount+i)+1] = random_str();
236 } 261 }
237 tokencount += 6; 262 tokencount += 6;
238 263
239 tmp = substitute(from, listaddr, listdelim, 264 tmp = substitute(from, listaddr, listdelim,
240 tokencount, moredata); 265 tokencount, moredata, listdir);
241 headers[0] = concatstr(2, "From: ", tmp); 266 headers[0] = concatstr(2, "From: ", tmp);
242 myfree(tmp); 267 myfree(tmp);
243 tmp = substitute(to, listaddr, listdelim, 268 tmp = substitute(to, listaddr, listdelim,
244 tokencount, moredata); 269 tokencount, moredata, listdir);
245 headers[1] = concatstr(2, "To: ", tmp); 270 headers[1] = concatstr(2, "To: ", tmp);
246 myfree(tmp); 271 myfree(tmp);
247 headers[2] = genmsgid(listfqdn); 272 headers[2] = genmsgid(listfqdn);
248 chomp(headers[2]); 273 chomp(headers[2]);
249 headers[3] = gendatestr(); 274 headers[3] = gendatestr();
253 headers[6] = mystrdup("Content-Type: text/plain; charset=utf-8"); 278 headers[6] = mystrdup("Content-Type: text/plain; charset=utf-8");
254 headers[7] = mystrdup("Content-Transfer-Encoding: 8bit"); 279 headers[7] = mystrdup("Content-Transfer-Encoding: 8bit");
255 280
256 if(replyto) { 281 if(replyto) {
257 tmp = substitute(replyto, listaddr, listdelim, 282 tmp = substitute(replyto, listaddr, listdelim,
258 tokencount, moredata); 283 tokencount, moredata, listdir);
259 headers[8] = concatstr(2, "Reply-To: ", tmp); 284 headers[8] = concatstr(2, "Reply-To: ", tmp);
260 myfree(tmp); 285 myfree(tmp);
261 } 286 }
262 287
263 for(;;) { 288 for(;;) {
277 if (*line == ' ' || *line == '\t') { 302 if (*line == ' ' || *line == '\t') {
278 /* line beginning with linear whitespace is a 303 /* line beginning with linear whitespace is a
279 continuation of previous header line */ 304 continuation of previous header line */
280 utfsub = unistr_escaped_to_utf8(line); 305 utfsub = unistr_escaped_to_utf8(line);
281 str = substitute(utfsub, listaddr, listdelim, 306 str = substitute(utfsub, listaddr, listdelim,
282 tokencount, moredata); 307 tokencount, moredata, listdir);
283 myfree(utfsub); 308 myfree(utfsub);
284 len = strlen(str); 309 len = strlen(str);
285 str[len] = '\n'; 310 str[len] = '\n';
286 if(writen(outfd, str, len+1) < 0) { 311 if(writen(outfd, str, len+1) < 0) {
287 log_error(LOG_ARGS, "Could not write std mail"); 312 log_error(LOG_ARGS, "Could not write std mail");
319 } 344 }
320 } 345 }
321 utfsub = unistr_escaped_to_utf8(tmp); 346 utfsub = unistr_escaped_to_utf8(tmp);
322 *tmp = '\0'; 347 *tmp = '\0';
323 utfsub2 = substitute(utfsub, listaddr, listdelim, 348 utfsub2 = substitute(utfsub, listaddr, listdelim,
324 tokencount, moredata); 349 tokencount, moredata, listdir);
325 myfree(utfsub); 350 myfree(utfsub);
326 if (strncasecmp(line, "Subject:", len) == 0) { 351 if (strncasecmp(line, "Subject:", len) == 0) {
327 tmp = unistr_utf8_to_header(utfsub2); 352 tmp = unistr_utf8_to_header(utfsub2);
328 myfree(utfsub2); 353 myfree(utfsub2);
329 str = concatstr(2, line, tmp); 354 str = concatstr(2, line, tmp);
425 log_error(LOG_ARGS, "Bad $originalmailNNN$ substitution"); 450 log_error(LOG_ARGS, "Bad $originalmailNNN$ substitution");
426 } 451 }
427 myfree(utfline); 452 myfree(utfline);
428 } else { 453 } else {
429 str = substitute(utfline, listaddr, listdelim, 454 str = substitute(utfline, listaddr, listdelim,
430 tokencount, moredata); 455 tokencount, moredata, listdir);
431 myfree(utfline); 456 myfree(utfline);
432 if(writen(outfd, str, strlen(str)) < 0) { 457 if(writen(outfd, str, strlen(str)) < 0) {
433 myfree(str); 458 myfree(str);
434 log_error(LOG_ARGS, "Could not write std mail"); 459 log_error(LOG_ARGS, "Could not write std mail");
435 myfree(retstr); 460 myfree(retstr);