]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
Move list text escaping and substitution into a text-reading function.
authorBen Schmidt <none@none>
Tue, 3 Jan 2012 17:15:20 +0000 (04:15 +1100)
committerBen Schmidt <none@none>
Tue, 3 Jan 2012 17:15:20 +0000 (04:15 +1100)
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.

include/prepstdreply.h
src/prepstdreply.c
src/send_digest.c

index 4d6d8df16d6861cf62c448bf2b11565d1d66b592..b4fd440e4b525b77acb9edc59d06acb6cc25f43f 100644 (file)
@@ -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,
index 394e1589846cd0941ee849eecd63a8d5207ab472..fb818d89ffb4f46e4b5767a23acb0221f60fb4f2 100644 (file)
@@ -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);
index 57f03e35bc4dcf87e42fa74ec8f83515c84bcc49..156d6af8f7cab282f61240c5fda51dc3b2d4c99f 100644 (file)
@@ -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]);