# HG changeset patch # User Ben Schmidt # Date 1325610920 -39600 # Node ID 8479195595aff4dd43be7f367064c1374a01efcb # Parent 5dc52f70e76b16640afbd4f6e6e58218018069ac Move list text escaping and substitution into a text-reading function. This paves the way for doing more complicated processing such as conditionals and formatting later. Also make the way digest headers are processed more consistent with how they are processed in list texts. diff -r 5dc52f70e76b -r 8479195595af include/prepstdreply.h --- a/include/prepstdreply.h Fri Dec 30 11:29:12 2011 +1100 +++ b/include/prepstdreply.h Wed Jan 04 04:15:20 2012 +1100 @@ -33,7 +33,9 @@ text *open_text_file(const char *listdir, const char *filename); text *open_text(const char *listdir, const char *purpose, const char *action, const char *reason, const char *type, const char *compat); -char *get_text_line(text *txt); +char *get_processed_text_line(text *txt, + const char *listaddr, const char *listdelim, + size_t datacount, char **data, const char *listdir); void close_text(text *txt); char *prepstdreply(const char *listdir, const char *purpose, const char *action, const char *reason, const char *type, const char *compat, diff -r 5dc52f70e76b -r 8479195595af src/prepstdreply.c --- a/src/prepstdreply.c Fri Dec 30 11:29:12 2011 +1100 +++ b/src/prepstdreply.c Wed Jan 04 04:15:20 2012 +1100 @@ -257,8 +257,27 @@ } -char *get_text_line(text *txt) { - return mygetline(txt->fd); +char *get_processed_text_line(text *txt, + const char *listaddr, const char *listdelim, + size_t datacount, char **data, const char *listdir) +{ + char *line; + char *tmp; + char *retstr; + + line = mygetline(txt->fd); + if (line == NULL) return NULL; + + chomp(line); + + tmp = unistr_escaped_to_utf8(line); + myfree(line); + + retstr = substitute(tmp, listaddr, listdelim, + datacount, data, listdir); + myfree(tmp); + + return retstr; } @@ -276,8 +295,8 @@ int outfd, mailfd; text *txt; char *listaddr, *listdelim, *tmp, *retstr = NULL; - char *listfqdn, *line, *utfline, *utfsub, *utfsub2; - char *str = NULL; + char *listfqdn, *line; + char *str; char **moredata; char *headers[10] = { NULL }; /* relies on NULL to flag end */ @@ -345,36 +364,30 @@ } for(;;) { - line = get_text_line(txt); + line = get_processed_text_line(txt, listaddr, listdelim, + tokencount, moredata, listdir); if (!line) { log_error(LOG_ARGS, "No body in listtext"); break; } - if (*line == '\n') { + if (*line == '\0') { /* end of headers */ myfree(line); line = NULL; break; } - chomp(line); if (*line == ' ' || *line == '\t') { /* line beginning with linear whitespace is a continuation of previous header line */ - utfsub = unistr_escaped_to_utf8(line); - str = substitute(utfsub, listaddr, listdelim, - tokencount, moredata, listdir); - myfree(utfsub); - len = strlen(str); - str[len] = '\n'; - if(writen(outfd, str, len+1) < 0) { + len = strlen(line); + line[len] = '\n'; + if(writen(outfd, line, len+1) < 0) { log_error(LOG_ARGS, "Could not write std mail"); - myfree(str); myfree(line); myfree(retstr); retstr = NULL; goto freeandreturn; } - myfree(str); } else { tmp = line; len = 0; @@ -400,33 +413,24 @@ break; } } - utfsub = unistr_escaped_to_utf8(tmp); - *tmp = '\0'; - utfsub2 = substitute(utfsub, listaddr, listdelim, - tokencount, moredata, listdir); - myfree(utfsub); if (strncasecmp(line, "Subject:", len) == 0) { - tmp = unistr_utf8_to_header(utfsub2); - myfree(utfsub2); - str = concatstr(2, line, tmp); + tmp = unistr_utf8_to_header(tmp); + myfree(line); + line = concatstr(2, "Subject:", tmp); myfree(tmp); - } else { - str = concatstr(2, line, utfsub2); - myfree(utfsub2); } - len = strlen(str); - str[len] = '\n'; - if(writen(outfd, str, len+1) < 0) { + len = strlen(line); + line[len] = '\n'; + if(writen(outfd, line, len+1) < 0) { log_error(LOG_ARGS, "Could not write std mail"); - myfree(str); myfree(line); myfree(retstr); retstr = NULL; goto freeandreturn; } - myfree(str); } myfree(line); + line = NULL; } for (i=0; headers[i] != NULL; i++) { @@ -436,7 +440,6 @@ log_error(LOG_ARGS, "Could not write std mail"); if (line) myfree(line); - myfree(str); myfree(retstr); retstr = NULL; goto freeandreturn; @@ -446,7 +449,6 @@ /* end the headers */ if(writen(outfd, "\n", 1) < 0) { log_error(LOG_ARGS, "Could not write std mail"); - myfree(str); if (line) myfree(line); myfree(retstr); @@ -454,17 +456,12 @@ goto freeandreturn; } - if (line) { - str = concatstr(2, line, "\n"); - myfree(line); - } else { - str = get_text_line(txt); + if (line == NULL) { + line = get_processed_text_line(txt, listaddr, listdelim, + tokencount, moredata, listdir); } - while(str) { - utfline = unistr_escaped_to_utf8(str); - myfree(str); - - tmp = utfline; + while(line) { + tmp = line; while (*tmp && (*tmp == ' ' || *tmp == '\t')) { tmp++; } @@ -490,11 +487,10 @@ while (i < len && (str = mygetline(mailfd))) { tmp = str; - str = concatstr(2,utfline,str); + str = concatstr(2,line,str); myfree(tmp); if(writen(outfd,str,strlen(str)) < 0) { myfree(str); - myfree(utfline); log_error(LOG_ARGS, "Could not write std mail"); myfree(retstr); retstr = NULL; @@ -510,22 +506,21 @@ } else { log_error(LOG_ARGS, "Bad $originalmail N$ substitution"); } - myfree(utfline); } else { - str = substitute(utfline, listaddr, listdelim, - tokencount, moredata, listdir); - myfree(utfline); - if(writen(outfd, str, strlen(str)) < 0) { + len = strlen(line); + line[len] = '\n'; + if(writen(outfd, line, len+1) < 0) { myfree(str); log_error(LOG_ARGS, "Could not write std mail"); myfree(retstr); retstr = NULL; goto freeandreturn; } - myfree(str); } - str = get_text_line(txt); + myfree(line); + line = get_processed_text_line(txt, listaddr, listdelim, + tokencount, moredata, listdir); } fsync(outfd); diff -r 5dc52f70e76b -r 8479195595af src/send_digest.c --- a/src/send_digest.c Fri Dec 30 11:29:12 2011 +1100 +++ b/src/send_digest.c Wed Jan 04 04:15:20 2012 +1100 @@ -181,10 +181,10 @@ int issue, const char *addr, const char *mlmmjsend) { int i, fd, archivefd, status, hdrfd; + size_t len; text * txt; char buf[45]; - char *tmp, *queuename = NULL, *archivename, *subject, *line = NULL; - char *utfsub, *utfsub2, *utfline; + char *tmp, *queuename = NULL, *archivename, *subject = NULL, *line = NULL; char *boundary, *listaddr, *listdelim, *listname, *listfqdn; char *subst_data[10]; pid_t childpid, pid; @@ -253,21 +253,60 @@ subst_data[8] = "digestthreads"; subst_data[9] = thread_list(listdir, firstindex, lastindex); - if (txt == NULL || (line = get_text_line(txt)) == NULL || - (strncasecmp(line, "Subject: ", 9) != 0)) { + if (txt == NULL) goto fallback_subject; - utfsub = mystrdup("Digest of $listaddr$ issue $digestissue$" - " ($digestinterval$)"); - } else { + line = get_processed_text_line(txt, listaddr, listdelim, + 5, subst_data, listdir); - chomp(line); - utfsub = unistr_escaped_to_utf8(line + 9); + if (line == NULL) { + log_error(LOG_ARGS, "No content in digest listtext"); + goto fallback_subject; } - utfsub2 = substitute(utfsub, listaddr, listdelim, 5, subst_data, listdir); - subject = unistr_utf8_to_header(utfsub2); - myfree(utfsub); - myfree(utfsub2); + tmp = line; + len = 0; + while (*tmp && *tmp != ':') { + tmp++; + len++; + } + if (!*tmp) { + log_error(LOG_ARGS, "No subject or invalid " + "subject in digest listtext"); + goto fallback_subject; + } + tmp++; + len++; + if (strncasecmp(line, "Subject:", len) == 0) { + tmp = unistr_utf8_to_header(tmp); + subject = concatstr(2, "Subject:", tmp); + myfree(tmp); + myfree(line); + + /* Skip the empty line after the subject */ + line = get_processed_text_line(txt, listaddr, listdelim, + 5, subst_data, listdir); + if (line == NULL || *line != '\0') { + log_error(LOG_ARGS, "Too many headers " + "in digest listtext"); + goto fallback_subject; + } + + if (line != NULL) myfree(line); + line = NULL; + } else { + log_error(LOG_ARGS, "No subject or invalid " + "subject in digest listtext"); + goto fallback_subject; + } + +fallback_subject: + if (subject == NULL) { + tmp = substitute("Digest of $listaddr$ issue $digestissue$" + " ($digestinterval$)", listaddr, listdelim, + 5, subst_data, listdir); + subject = unistr_utf8_to_header(tmp); + myfree(tmp); + } tmp = concatstr(10, "From: ", listname, listdelim, "help@", listfqdn, "\nMIME-Version: 1.0" @@ -348,32 +387,19 @@ } myfree(tmp); - if (line && (strncasecmp(line, "Subject: ", 9) == 0)) { + for (;;) { + line = get_processed_text_line(txt, listaddr, listdelim, + 5, subst_data, listdir); + if (line == NULL) break; + len = strlen(line); + line[len] = '\n'; + if(writen(fd, line, len+1) < 0) { myfree(line); - line = get_text_line(txt); - if (line && (strcmp(line, "\n") == 0)) { - /* skip empty line after Subject: */ - line[0] = '\0'; - } - } - - if (line) { - do { - utfline = unistr_escaped_to_utf8(line); - myfree(line); - - tmp = substitute(utfline, listaddr, listdelim, - 5, subst_data, listdir); - myfree(utfline); - - if(writen(fd, tmp, strlen(tmp)) < 0) { - myfree(tmp); log_error(LOG_ARGS, "Could not write" " std mail"); break; } - myfree(tmp); - } while ((line = get_text_line(txt))); + myfree(line); } close_text(txt); @@ -381,7 +407,7 @@ close_text(txt); } - myfree(line); + if (line != NULL) myfree(line); myfree(listaddr); myfree(listdelim); myfree(subst_data[1]);