From 3d013afe9d8a2e6851b809cfcad23b0719800c50 Mon Sep 17 00:00:00 2001 From: mortenp Date: Mon, 4 Sep 2006 07:41:02 +1000 Subject: [PATCH] added support for digest text part and digestissue keyword --- TUNABLES | 5 + include/send_digest.h | 2 +- src/Makefile.am | 3 +- src/mlmmj-maintd.c | 24 +++- src/send_digest.c | 292 ++++++++++++++++++++++++++++++++++++++---- 5 files changed, 295 insertions(+), 31 deletions(-) diff --git a/TUNABLES b/TUNABLES index ac60f939..a36bd690 100644 --- a/TUNABLES +++ b/TUNABLES @@ -161,3 +161,8 @@ to specify several entries (one pr. line), it's marked "list". This specifies what to use as recipient delimiter for the list. Default is "+". + + ยท nodigesttext (boolean) + + If this file exists, digest mails won't have a text part with a thread + sumary. diff --git a/include/send_digest.h b/include/send_digest.h index cacecd49..3d7e06bd 100644 --- a/include/send_digest.h +++ b/include/send_digest.h @@ -25,6 +25,6 @@ #define SEND_DIGEST_H int send_digest(const char *listdir, int lastindex, int index, - const char *addr, const char *mlmmjsend); + int issue, const char *addr, const char *mlmmjsend); #endif /* SEND_DIGEST_H */ diff --git a/src/Makefile.am b/src/Makefile.am index aef1d510..ba11d1f6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -53,7 +53,8 @@ mlmmj_bounce_SOURCES = mlmmj-bounce.c print-version.c log_error.c \ mlmmj_maintd_SOURCES = mlmmj-maintd.c print-version.c log_error.c mygetline.c \ strgen.c random-int.c chomp.c writen.c memory.c \ ctrlvalue.c send_digest.c getlistaddr.c dumpfd2fd.c \ - mylocking.c log_oper.c readn.c getlistdelim.c + mylocking.c log_oper.c readn.c getlistdelim.c \ + prepstdreply.c statctrl.c gethdrline.c unistr.c mlmmj_list_SOURCES = mlmmj-list.c strgen.c writen.c print-version.c memory.c \ log_error.c random-int.c readn.c diff --git a/src/mlmmj-maintd.c b/src/mlmmj-maintd.c index 6108c6d2..c08e1f1d 100644 --- a/src/mlmmj-maintd.c +++ b/src/mlmmj-maintd.c @@ -749,12 +749,12 @@ int unsub_bouncers(const char *listdir, const char *mlmmjunsub) int run_digests(const char *listdir, const char *mlmmjsend) { - char *lasttimestr, *lastindexstr; + char *lasttimestr, *lastindexstr, *lastissuestr; char *digestname, *indexname; char *digestintervalstr, *digestmaxmailsstr; char *s1, *s2, *s3; time_t digestinterval, t, lasttime; - long digestmaxmails, lastindex, index; + long digestmaxmails, lastindex, index, lastissue; int fd, indexfd, lock; size_t lenbuf, lenstr; @@ -792,9 +792,15 @@ int run_digests(const char *listdir, const char *mlmmjsend) s1 = mygetline(fd); - /* Syntax is lastindex:lasttime */ + /* Syntax is lastindex:lasttime or lastindex:lasttime:lastissue */ if (s1 && (lasttimestr = strchr(s1, ':'))) { *(lasttimestr++) = '\0'; + if ((lastissuestr = strchr(lasttimestr, ':'))) { + *(lastissuestr++) = '\0'; + lastissue = atol(lastissuestr); + } else { + lastissue = 0; + } lasttime = atol(lasttimestr); lastindexstr = s1; lastindex = atol(lastindexstr); @@ -810,6 +816,7 @@ int run_digests(const char *listdir, const char *mlmmjsend) /* If lastdigest is empty, we start from scratch */ lasttime = 0; lastindex = 0; + lastissue = 0; } indexname = concatstr(2, listdir, "/index"); @@ -843,15 +850,18 @@ int run_digests(const char *listdir, const char *mlmmjsend) if (index > lastindex+digestmaxmails) index = lastindex+digestmaxmails; - send_digest(listdir, lastindex+1, index, NULL, mlmmjsend); + if (index > lastindex) { + lastissue++; + send_digest(listdir, lastindex+1, index, lastissue, NULL, mlmmjsend); + } if (lseek(fd, 0, SEEK_SET) < 0) { log_error(LOG_ARGS, "Could not seek '%s'", digestname); } else { - /* index + ':' + time + '\n' + '\0' */ - lenbuf = 20 + 1 + 20 + 2; + /* index + ':' + time + ':' + issue + '\n' + '\0' */ + lenbuf = 20 + 1 + 20 + 1 + 20 + 2; s3 = mymalloc(lenbuf); - lenstr = snprintf(s3, lenbuf, "%ld:%ld\n", index, (long)t); + lenstr = snprintf(s3, lenbuf, "%ld:%ld:%ld\n", index, (long)t, lastissue); if (lenstr >= lenbuf) lenstr = lenbuf - 1; if (writen(fd, s3, lenstr) == -1) { diff --git a/src/send_digest.c b/src/send_digest.c index ba4ce653..7a1673b9 100644 --- a/src/send_digest.c +++ b/src/send_digest.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004 Morten K. Poulsen +/* Copyright (C) 2004, 2005 Morten K. Poulsen * * $Id$ * @@ -29,6 +29,7 @@ #include #include #include +#include #include "mlmmj.h" #include "send_digest.h" @@ -38,15 +39,151 @@ #include "getlistaddr.h" #include "getlistdelim.h" #include "wrappers.h" +#include "prepstdreply.h" +#include "mygetline.h" +#include "gethdrline.h" +#include "statctrl.h" +#include "unistr.h" + + +struct mail { + int idx; + char *from; +}; + +struct thread { + char *subject; + int num_mails; + struct mail *mails; +}; + + +static char *thread_list(const char *listdir, int firstindex, int lastindex) +{ + int i, j, archivefd, thread_idx; + char *ret, *line, *tmp, *subj, *from; + char *archivename; + int num_threads = 0; + struct thread *threads = NULL; + char buf[45]; + + for (i=firstindex; i<=lastindex; i++) { + + snprintf(buf, sizeof(buf), "%d", i); + + archivename = concatstr(3, listdir, "/archive/", buf); + archivefd = open(archivename, O_RDONLY); + myfree(archivename); + + if (archivefd < 0) + continue; + + subj = NULL; + from = NULL; + + while ((line = gethdrline(archivefd))) { + if (strcmp(line, "\n") == 0) { + myfree(line); + break; + } + if (strncasecmp(line, "Subject: ", 9) == 0) { + myfree(subj); + subj = unistr_header_to_utf8(line + 9); + } + if (strncasecmp(line, "From: ", 6) == 0) { + myfree(from); + from = unistr_header_to_utf8(line + 6); + } + myfree(line); + } + + if (!subj) { + subj = mystrdup("no subject"); + } + + if (!from) { + from = mystrdup("anonymous"); + } + + tmp = subj; + for (;;) { + if (isspace(*tmp)) { + tmp++; + continue; + } + if (strncasecmp(tmp, "Re:", 3) == 0) { + tmp += 3; + continue; + } + break; + } + /* tmp is now the clean subject */ + + thread_idx = -1; + for (j=0; j 0) && (line = mygetline(txtfd)) && + (strncasecmp(line, "Subject: ", 9) == 0)) { + subject = substitute(line + 9, listaddr, listdelim, + 5, subst_data); + } else { + subject = substitute("Digest of $listaddr$ issue $digestissue$" + " ($digestinterval$)\n", listaddr, listdelim, + 5, subst_data); + } + + tmp = concatstr(9, "From: ", listname, listdelim, "help@", listfqdn, + "\nMIME-Version: 1.0" + "\nContent-Type: multipart/" DIGESTMIMETYPE "; " + "boundary=", boundary, + "\nSubject: ", subject); + /* subject includes a newline */ - tmp = concatstr(6, "MIME-Version: 1.0" - "\nContent-Type: multipart/" DIGESTMIMETYPE "; " - "boundary=", boundary, - "\nSubject: Digest of ", listname, buf, "\n\n"); myfree(listfqdn); + myfree(subject); - if (writen(fd, fromstr, strlen(fromstr)) < -1) + if (writen(fd, tmp, strlen(tmp)) < 0) { + myfree(tmp); goto errdighdrs; + } + myfree(tmp); if(hdrfd >= 0 && dumpfd2fd(hdrfd, fd) < 0) { - close(hdrfd); goto errdighdrs; } close(hdrfd); + hdrfd = -1; - if (writen(fd, tmp, strlen(tmp)) < -1) { + if (writen(fd, "\n", 1) < 0) { errdighdrs: log_error(LOG_ARGS, "Could not write digest headers to '%s'", queuename); close(fd); unlink(queuename); myfree(boundary); - myfree(fromstr); - myfree(tmp); myfree(queuename); + myfree(listaddr); myfree(listname); + myfree(listdelim); + myfree(subst_data[1]); + myfree(subst_data[3]); + myfree(subst_data[5]); + myfree(subst_data[7]); + myfree(subst_data[9]); + if (txtfd > 0) { + close(txtfd); + myfree(line); + } + if (hdrfd > 0) { + close(hdrfd); + } return -1; } - myfree(tmp); - myfree(fromstr); + + if ((txtfd > 0) && !statctrl(listdir, "nodigesttext")) { + + tmp = concatstr(3, "--", boundary, + "\nContent-Type: text/plain; charset=UTF-8" + "\n\n"); + if (writen(fd, tmp, strlen(tmp)) == -1) { + log_error(LOG_ARGS, "Could not write digest text/plain" + " part headers to '%s'", queuename); + close(fd); + unlink(queuename); + myfree(boundary); + myfree(tmp); + myfree(queuename); + myfree(listaddr); + myfree(listname); + myfree(listdelim); + myfree(subst_data[1]); + myfree(subst_data[3]); + myfree(subst_data[5]); + myfree(subst_data[7]); + myfree(subst_data[9]); + if (txtfd > 0) { + close(txtfd); + myfree(line); + } + return -1; + } + myfree(tmp); + + if (line && (strncasecmp(line, "Subject: ", 9) == 0)) { + myfree(line); + line = mygetline(txtfd); + if (line && (strcmp(line, "\n") == 0)) { + /* skip empty line after Subject: */ + line[0] = '\0'; + } + } + + if (line) { + do { + tmp = substitute(line, listaddr, listdelim, + 5, subst_data); + myfree(line); + if(writen(fd, tmp, strlen(tmp)) < 0) { + myfree(tmp); + log_error(LOG_ARGS, "Could not write" + " std mail"); + break; + } + myfree(tmp); + } while ((line = mygetline(txtfd))); + } + + close(txtfd); + } + + myfree(line); + myfree(listaddr); + myfree(listdelim); + myfree(subst_data[1]); + myfree(subst_data[3]); + myfree(subst_data[5]); + myfree(subst_data[7]); + myfree(subst_data[9]); for (i=firstindex; i<=lastindex; i++) { snprintf(buf, sizeof(buf), "%d", i); -- 2.47.3