From: Ben Schmidt Date: Tue, 3 Jan 2012 17:15:20 +0000 (+1100) Subject: Move list text escaping and substitution into a text-reading function. X-Git-Tag: RELEASE_1_2_18a1~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=25402e2beceb47a46e133448205458d835633378;p=thirdparty%2Fmlmmj.git 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 --git a/include/prepstdreply.h b/include/prepstdreply.h index 4d6d8df1..b4fd440e 100644 --- a/include/prepstdreply.h +++ b/include/prepstdreply.h @@ -33,7 +33,9 @@ char *substitute(const char *line, const char *listaddr, const char *listdelim, 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 --git a/src/prepstdreply.c b/src/prepstdreply.c index 394e1589..fb818d89 100644 --- a/src/prepstdreply.c +++ b/src/prepstdreply.c @@ -257,8 +257,27 @@ text *open_text(const char *listdir, const char *purpose, const char *action, } -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 @@ char *prepstdreply(const char *listdir, const char *purpose, const char *action, 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 @@ char *prepstdreply(const char *listdir, const char *purpose, const char *action, } 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 @@ char *prepstdreply(const char *listdir, const char *purpose, const char *action, 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 @@ char *prepstdreply(const char *listdir, const char *purpose, const char *action, 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 @@ char *prepstdreply(const char *listdir, const char *purpose, const char *action, /* 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 @@ char *prepstdreply(const char *listdir, const char *purpose, const char *action, 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 @@ char *prepstdreply(const char *listdir, const char *purpose, const char *action, 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 @@ char *prepstdreply(const char *listdir, const char *purpose, const char *action, } 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 --git a/src/send_digest.c b/src/send_digest.c index 57f03e35..156d6af8 100644 --- a/src/send_digest.c +++ b/src/send_digest.c @@ -181,10 +181,10 @@ int send_digest(const char *listdir, int firstindex, int lastindex, 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 @@ int send_digest(const char *listdir, int firstindex, int lastindex, 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); + + if (line == NULL) { + log_error(LOG_ARGS, "No content in digest listtext"); + goto fallback_subject; + } + + 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; + } - chomp(line); - utfsub = unistr_escaped_to_utf8(line + 9); + if (line != NULL) myfree(line); + line = NULL; + } else { + log_error(LOG_ARGS, "No subject or invalid " + "subject 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); +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 @@ errdighdrs: } myfree(tmp); - if (line && (strncasecmp(line, "Subject: ", 9) == 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); + 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); - - 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))); + log_error(LOG_ARGS, "Could not write" + " std mail"); + break; + } + myfree(line); } close_text(txt); @@ -381,7 +407,7 @@ errdighdrs: close_text(txt); } - myfree(line); + if (line != NULL) myfree(line); myfree(listaddr); myfree(listdelim); myfree(subst_data[1]);