comparison src/prepstdreply.c @ 742:b00eb39643c1

Changes to how $originalmail$ works - No longer buffer the whole mail in memory, but copy a line at a time - Allow a line-count - Change to the indent/whitespace behaviour; to essentially get current behaviour, a space must be prepended to the lines currently containing $originalmail$ in the listtexts The interface to substitute() and substitute_one() has changed. They no longer take the original mail filename, and cannot be used to do $originalmail$ substitution. This was never used except by prepstdreply() which now incorporates that substitution itself.
author Ben Schmidt
date Mon, 20 Sep 2010 02:05:31 +1000
parents b72bcb7e08a2
children 5edfa9eef6c7
comparison
equal deleted inserted replaced
741:b72bcb7e08a2 742:b00eb39643c1
42 #include "mlmmj.h" 42 #include "mlmmj.h"
43 #include "getlistdelim.h" 43 #include "getlistdelim.h"
44 #include "unistr.h" 44 #include "unistr.h"
45 45
46 char *substitute(const char *line, const char *listaddr, const char *listdelim, 46 char *substitute(const char *line, const char *listaddr, const char *listdelim,
47 size_t datacount, char **data, const char *mailname) 47 size_t datacount, char **data)
48 { 48 {
49 char *s1, *s2; 49 char *s1, *s2;
50 50
51 s1 = substitute_one(line, listaddr, listdelim, datacount, data, mailname); 51 s1 = substitute_one(line, listaddr, listdelim, datacount, data);
52 while(s1) { 52 while(s1) {
53 s2 = substitute_one(s1, listaddr, listdelim, datacount, data, mailname); 53 s2 = substitute_one(s1, listaddr, listdelim, datacount, data);
54 if(s2) { 54 if(s2) {
55 myfree(s1); 55 myfree(s1);
56 s1 = s2; 56 s1 = s2;
57 } else 57 } else
58 return s1; 58 return s1;
60 60
61 return mystrdup(line); 61 return mystrdup(line);
62 } 62 }
63 63
64 char *substitute_one(const char *line, const char *listaddr, 64 char *substitute_one(const char *line, const char *listaddr,
65 const char *listdelim, size_t datacount, char **data, 65 const char *listdelim, size_t datacount, char **data)
66 const char* mailname)
67 { 66 {
68 char *fqdn, *listname, *d1, *d2, *token, *value = NULL; 67 char *fqdn, *listname, *d1, *d2, *token, *value = NULL;
69 char *retstr, *origline; 68 char *retstr, *origline;
70 size_t len, i; 69 size_t len, i;
71 70
131 goto concatandreturn; 130 goto concatandreturn;
132 } else if(strcmp(token, "nomailsubaddr") == 0) { 131 } else if(strcmp(token, "nomailsubaddr") == 0) {
133 value = concatstr(4, listname, listdelim, "subscribe-nomail@", 132 value = concatstr(4, listname, listdelim, "subscribe-nomail@",
134 fqdn); 133 fqdn);
135 goto concatandreturn; 134 goto concatandreturn;
136 } else if(strcmp(token, "originalmail") == 0) {
137 /* append the first 100 lines of the mail inline */
138 int mailfd;
139 if(mailname &&
140 ((mailfd = open(mailname, O_RDONLY)) > 0)){
141 size_t count = 0;
142 char* str = NULL;
143 while(count < 100 && (str = mygetline(mailfd))) {
144 char* tmp = value;
145 value = concatstr(3, value, " ", str);
146 if(tmp)
147 myfree(tmp);
148 myfree(str);
149 count++;
150 }
151 close(mailfd);
152 }else{
153 log_error(LOG_ARGS, "Could not substitute $originalmail$ (mailname == %s)",mailname);
154 }
155 goto concatandreturn;
156 } 135 }
157 if(data) { 136 if(data) {
158 for(i = 0; i < datacount; i++) { 137 for(i = 0; i < datacount; i++) {
159 if(strcmp(token, data[i*2]) == 0) { 138 if(strcmp(token, data[i*2]) == 0) {
160 value = mystrdup(data[(i*2)+1]); 139 value = mystrdup(data[(i*2)+1]);
209 char *prepstdreply(const char *listdir, const char *filename, const char *from, 188 char *prepstdreply(const char *listdir, const char *filename, const char *from,
210 const char *to, const char *replyto, size_t tokencount, 189 const char *to, const char *replyto, size_t tokencount,
211 char **data, const char *mailname) 190 char **data, const char *mailname)
212 { 191 {
213 size_t i, len; 192 size_t i, len;
214 int infd, outfd; 193 int infd, outfd, mailfd;
215 char *listaddr, *listdelim, *tmp, *retstr = NULL; 194 char *listaddr, *listdelim, *tmp, *retstr = NULL;
216 char *listfqdn, *line, *utfline, *utfsub, *utfsub2; 195 char *listfqdn, *line, *utfline, *utfsub, *utfsub2;
217 char *str = NULL; 196 char *str = NULL;
218 char *headers[10] = { NULL }; /* relies on NULL to flag end */ 197 char *headers[10] = { NULL }; /* relies on NULL to flag end */
219 198
242 myfree(listfqdn); 221 myfree(listfqdn);
243 return NULL; 222 return NULL;
244 } 223 }
245 224
246 tmp = substitute(from, listaddr, listdelim, 225 tmp = substitute(from, listaddr, listdelim,
247 tokencount, data, NULL); 226 tokencount, data);
248 headers[0] = concatstr(2, "From: ", tmp); 227 headers[0] = concatstr(2, "From: ", tmp);
249 myfree(tmp); 228 myfree(tmp);
250 tmp = substitute(to, listaddr, listdelim, 229 tmp = substitute(to, listaddr, listdelim,
251 tokencount, data, NULL); 230 tokencount, data);
252 headers[1] = concatstr(2, "To: ", tmp); 231 headers[1] = concatstr(2, "To: ", tmp);
253 myfree(tmp); 232 myfree(tmp);
254 headers[2] = genmsgid(listfqdn); 233 headers[2] = genmsgid(listfqdn);
255 chomp(headers[2]); 234 chomp(headers[2]);
256 headers[3] = gendatestr(); 235 headers[3] = gendatestr();
260 headers[6] = mystrdup("Content-Type: text/plain; charset=utf-8"); 239 headers[6] = mystrdup("Content-Type: text/plain; charset=utf-8");
261 headers[7] = mystrdup("Content-Transfer-Encoding: 8bit"); 240 headers[7] = mystrdup("Content-Transfer-Encoding: 8bit");
262 241
263 if(replyto) { 242 if(replyto) {
264 tmp = substitute(replyto, listaddr, listdelim, 243 tmp = substitute(replyto, listaddr, listdelim,
265 tokencount, data, NULL); 244 tokencount, data);
266 headers[8] = concatstr(2, "Reply-To: ", tmp); 245 headers[8] = concatstr(2, "Reply-To: ", tmp);
267 myfree(tmp); 246 myfree(tmp);
268 } 247 }
269 248
270 for(;;) { 249 for(;;) {
284 if (*line == ' ' || *line == '\t') { 263 if (*line == ' ' || *line == '\t') {
285 /* line beginning with linear whitespace is a 264 /* line beginning with linear whitespace is a
286 continuation of previous header line */ 265 continuation of previous header line */
287 utfsub = unistr_escaped_to_utf8(line); 266 utfsub = unistr_escaped_to_utf8(line);
288 str = substitute(utfsub, listaddr, listdelim, 267 str = substitute(utfsub, listaddr, listdelim,
289 tokencount, data, NULL); 268 tokencount, data);
290 myfree(utfsub); 269 myfree(utfsub);
291 len = strlen(str); 270 len = strlen(str);
292 str[len] = '\n'; 271 str[len] = '\n';
293 if(writen(outfd, str, len+1) < 0) { 272 if(writen(outfd, str, len+1) < 0) {
294 log_error(LOG_ARGS, "Could not write std mail"); 273 log_error(LOG_ARGS, "Could not write std mail");
327 } 306 }
328 } 307 }
329 utfsub = unistr_escaped_to_utf8(tmp); 308 utfsub = unistr_escaped_to_utf8(tmp);
330 *tmp = '\0'; 309 *tmp = '\0';
331 utfsub2 = substitute(utfsub, listaddr, listdelim, 310 utfsub2 = substitute(utfsub, listaddr, listdelim,
332 tokencount, data, NULL); 311 tokencount, data);
333 myfree(utfsub); 312 myfree(utfsub);
334 if (strncasecmp(line, "Subject:", len) == 0) { 313 if (strncasecmp(line, "Subject:", len) == 0) {
335 tmp = unistr_utf8_to_header(utfsub2); 314 tmp = unistr_utf8_to_header(utfsub2);
336 myfree(utfsub2); 315 myfree(utfsub2);
337 str = concatstr(2, line, tmp); 316 str = concatstr(2, line, tmp);
391 } 370 }
392 while(str) { 371 while(str) {
393 utfline = unistr_escaped_to_utf8(str); 372 utfline = unistr_escaped_to_utf8(str);
394 myfree(str); 373 myfree(str);
395 374
396 str = substitute(utfline, listaddr, listdelim, tokencount, data, mailname); 375 tmp = utfline;
397 myfree(utfline); 376 while (*tmp && (*tmp == ' ' || *tmp == '\t')) {
398 377 tmp++;
399 if(writen(outfd, str, strlen(str)) < 0) { 378 }
379 if (strncmp(tmp,"$originalmail",13) == 0) {
380 *tmp = '\0';
381 tmp += 13;
382 str = tmp;
383 while (*tmp >= '0' && *tmp <= '9')
384 tmp++;
385 if (*tmp == '$') {
386 *tmp = '\0';
387 len = 100;
388 if (str != tmp)
389 len = atol(str);
390 if (mailname &&
391 ((mailfd = open(mailname, O_RDONLY)) > 0)){
392 str = NULL;
393 i = 0;
394 while (i < len &&
395 (str = mygetline(mailfd))) {
396 tmp = str;
397 str = concatstr(2,utfline,str);
398 myfree(tmp);
399 if(writen(outfd,str,strlen(str)) < 0) {
400 myfree(str);
401 myfree(utfline);
402 myfree(listaddr);
403 myfree(listdelim);
404 myfree(listfqdn);
405 log_error(LOG_ARGS, "Could not write std mail");
406 return NULL;
407 }
408 myfree(str);
409 i++;
410 }
411 close(mailfd);
412 } else {
413 log_error(LOG_ARGS, "Could not substitute $originalmail%d$ (mailname == %s)",len,mailname);
414 }
415 } else {
416 log_error(LOG_ARGS, "Bad $originalmailNNN$ substitution");
417 }
418 myfree(utfline);
419 } else {
420 str = substitute(utfline, listaddr, listdelim,
421 tokencount, data);
422 myfree(utfline);
423 if(writen(outfd, str, strlen(str)) < 0) {
424 myfree(str);
425 myfree(listaddr);
426 myfree(listdelim);
427 myfree(listfqdn);
428 log_error(LOG_ARGS, "Could not write std mail");
429 return NULL;
430 }
400 myfree(str); 431 myfree(str);
401 myfree(listaddr); 432 }
402 myfree(listdelim); 433
403 myfree(listfqdn);
404 log_error(LOG_ARGS, "Could not write std mail");
405 return NULL;
406 }
407 myfree(str);
408 str = mygetline(infd); 434 str = mygetline(infd);
409 } 435 }
410 436
411 fsync(outfd); 437 fsync(outfd);
412 close(outfd); 438 close(outfd);