Mercurial > hg > mlmmj
annotate src/send_digest.c @ 740:5db75af2d0db
Fix Content-Transfer-Encoding: header for digests,
and always close digest listtext
author | Ben Schmidt |
---|---|
date | Mon, 20 Sep 2010 01:41:32 +1000 |
parents | c26e97a2207b |
children | b00eb39643c1 |
rev | line source |
---|---|
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
1 /* Copyright (C) 2004, 2005 Morten K. Poulsen <morten at afdelingp.dk> |
338 | 2 * |
3 * $Id$ | |
4 * | |
5 * Permission is hereby granted, free of charge, to any person obtaining a copy | |
6 * of this software and associated documentation files (the "Software"), to | |
7 * deal in the Software without restriction, including without limitation the | |
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |
9 * sell copies of the Software, and to permit persons to whom the Software is | |
10 * furnished to do so, subject to the following conditions: | |
11 * | |
12 * The above copyright notice and this permission notice shall be included in | |
13 * all copies or substantial portions of the Software. | |
14 * | |
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
21 * IN THE SOFTWARE. | |
22 */ | |
23 | |
24 #include <unistd.h> | |
25 #include <string.h> | |
26 #include <stdio.h> | |
27 #include <fcntl.h> | |
28 #include <stdlib.h> | |
29 #include <sys/types.h> | |
30 #include <sys/stat.h> | |
31 #include <sys/wait.h> | |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
32 #include <ctype.h> |
338 | 33 |
34 #include "mlmmj.h" | |
35 #include "send_digest.h" | |
36 #include "log_error.h" | |
37 #include "strgen.h" | |
38 #include "memory.h" | |
39 #include "getlistaddr.h" | |
520 | 40 #include "getlistdelim.h" |
338 | 41 #include "wrappers.h" |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
42 #include "prepstdreply.h" |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
43 #include "mygetline.h" |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
44 #include "gethdrline.h" |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
45 #include "statctrl.h" |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
46 #include "unistr.h" |
652 | 47 #include "chomp.h" |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
48 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
49 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
50 struct mail { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
51 int idx; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
52 char *from; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
53 }; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
54 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
55 struct thread { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
56 char *subject; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
57 int num_mails; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
58 struct mail *mails; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
59 }; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
60 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
61 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
62 static char *thread_list(const char *listdir, int firstindex, int lastindex) |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
63 { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
64 int i, j, archivefd, thread_idx; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
65 char *ret, *line, *tmp, *subj, *from; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
66 char *archivename; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
67 int num_threads = 0; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
68 struct thread *threads = NULL; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
69 char buf[45]; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
70 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
71 for (i=firstindex; i<=lastindex; i++) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
72 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
73 snprintf(buf, sizeof(buf), "%d", i); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
74 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
75 archivename = concatstr(3, listdir, "/archive/", buf); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
76 archivefd = open(archivename, O_RDONLY); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
77 myfree(archivename); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
78 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
79 if (archivefd < 0) |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
80 continue; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
81 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
82 subj = NULL; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
83 from = NULL; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
84 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
85 while ((line = gethdrline(archivefd))) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
86 if (strcmp(line, "\n") == 0) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
87 myfree(line); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
88 break; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
89 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
90 if (strncasecmp(line, "Subject: ", 9) == 0) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
91 myfree(subj); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
92 subj = unistr_header_to_utf8(line + 9); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
93 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
94 if (strncasecmp(line, "From: ", 6) == 0) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
95 myfree(from); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
96 from = unistr_header_to_utf8(line + 6); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
97 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
98 myfree(line); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
99 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
100 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
101 if (!subj) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
102 subj = mystrdup("no subject"); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
103 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
104 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
105 if (!from) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
106 from = mystrdup("anonymous"); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
107 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
108 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
109 tmp = subj; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
110 for (;;) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
111 if (isspace(*tmp)) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
112 tmp++; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
113 continue; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
114 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
115 if (strncasecmp(tmp, "Re:", 3) == 0) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
116 tmp += 3; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
117 continue; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
118 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
119 break; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
120 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
121 /* tmp is now the clean subject */ |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
122 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
123 thread_idx = -1; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
124 for (j=0; j<num_threads; j++) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
125 if (strcmp(subj, threads[j].subject) == 0) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
126 thread_idx = j; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
127 break; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
128 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
129 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
130 if (thread_idx == -1) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
131 num_threads++; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
132 threads = myrealloc(threads, |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
133 num_threads*sizeof(struct thread)); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
134 threads[num_threads-1].subject = mystrdup(tmp); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
135 threads[num_threads-1].num_mails = 0; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
136 threads[num_threads-1].mails = NULL; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
137 thread_idx = num_threads-1; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
138 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
139 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
140 threads[thread_idx].num_mails++; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
141 threads[thread_idx].mails = myrealloc(threads[thread_idx].mails, |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
142 threads[thread_idx].num_mails*sizeof(struct mail)); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
143 threads[thread_idx].mails[threads[thread_idx].num_mails-1].idx = i; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
144 threads[thread_idx].mails[threads[thread_idx].num_mails-1].from = |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
145 concatstr(5, " ", buf, " - ", from, "\n"); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
146 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
147 myfree(subj); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
148 myfree(from); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
149 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
150 close(archivefd); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
151 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
152 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
153 ret = mystrdup(""); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
154 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
155 for (i=0; i<num_threads; i++) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
156 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
157 tmp = concatstr(3, ret, threads[i].subject, "\n"); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
158 myfree(ret); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
159 ret = tmp; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
160 myfree(threads[i].subject); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
161 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
162 for (j=0; j<threads[i].num_mails; j++) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
163 tmp = concatstr(2, ret, threads[i].mails[j].from); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
164 myfree(ret); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
165 ret = tmp; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
166 myfree(threads[i].mails[j].from); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
167 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
168 myfree(threads[i].mails); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
169 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
170 tmp = concatstr(2, ret, "\n"); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
171 myfree(ret); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
172 ret = tmp; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
173 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
174 myfree(threads); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
175 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
176 return ret; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
177 } |
338 | 178 |
179 | |
180 int send_digest(const char *listdir, int firstindex, int lastindex, | |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
181 int issue, const char *addr, const char *mlmmjsend) |
338 | 182 { |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
183 int i, fd, archivefd, status, hdrfd, txtfd; |
338 | 184 char buf[45]; |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
185 char *tmp, *queuename = NULL, *archivename, *subject, *line = NULL; |
652 | 186 char *utfsub, *utfsub2, *utfline; |
520 | 187 char *boundary, *listaddr, *listdelim, *listname, *listfqdn; |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
188 char *subst_data[10]; |
338 | 189 pid_t childpid, pid; |
190 | |
191 if (addr) { | |
192 errno = 0; | |
193 log_error(LOG_ARGS, "send_digest() does not support sending " | |
194 "digest mails to only one recipient yet"); | |
195 return -1; | |
196 } | |
197 | |
198 if (firstindex > lastindex) | |
199 return -1; | |
200 | |
201 do { | |
202 tmp = random_str(); | |
203 myfree(queuename); | |
204 queuename = concatstr(3, listdir, "/queue/", tmp); | |
205 myfree(tmp); | |
206 fd = open(queuename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR); | |
207 } while ((fd < 0) && (errno == EEXIST)); | |
208 | |
209 if (fd < 0) { | |
210 log_error(LOG_ARGS, "Could not open digest queue file '%s'", | |
211 queuename); | |
212 myfree(queuename); | |
213 return -1; | |
214 } | |
215 | |
372 | 216 tmp = concatstr(2, listdir, "/control/customheaders"); |
217 hdrfd = open(tmp, O_RDONLY); | |
218 myfree(tmp); | |
219 | |
338 | 220 boundary = random_str(); |
221 | |
222 listaddr = getlistaddr(listdir); | |
223 listname = genlistname(listaddr); | |
224 listfqdn = genlistfqdn(listaddr); | |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
225 listdelim = getlistdelim(listdir); |
338 | 226 |
652 | 227 txtfd = open_listtext(listdir, "digest"); |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
228 if (txtfd < 0) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
229 log_error(LOG_ARGS, "Notice: Could not open std mail digest"); |
338 | 230 } |
372 | 231 |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
232 subst_data[0] = "digestfirst"; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
233 snprintf(buf, sizeof(buf), "%d", firstindex); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
234 subst_data[1] = mystrdup(buf); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
235 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
236 subst_data[2] = "digestlast"; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
237 snprintf(buf, sizeof(buf), "%d", lastindex); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
238 subst_data[3] = mystrdup(buf); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
239 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
240 subst_data[4] = "digestinterval"; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
241 if (lastindex == firstindex) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
242 snprintf(buf, sizeof(buf), "%d", firstindex); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
243 } else { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
244 snprintf(buf, sizeof(buf), "%d-%d", firstindex, lastindex); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
245 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
246 subst_data[5] = mystrdup(buf); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
247 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
248 subst_data[6] = "digestissue"; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
249 snprintf(buf, sizeof(buf), "%d", issue); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
250 subst_data[7] = mystrdup(buf); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
251 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
252 subst_data[8] = "digestthreads"; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
253 subst_data[9] = thread_list(listdir, firstindex, lastindex); |
520 | 254 |
652 | 255 if ((txtfd < 0) || !(line = mygetline(txtfd)) || |
256 (strncasecmp(line, "Subject: ", 9) != 0)) { | |
257 | |
258 utfsub = mystrdup("Digest of $listaddr$ issue $digestissue$" | |
259 " ($digestinterval$)"); | |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
260 } else { |
652 | 261 |
262 chomp(line); | |
263 utfsub = unistr_escaped_to_utf8(line + 9); | |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
264 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
265 |
660
c26e97a2207b
Added support for the 'originalmail' keyword (Sascha Sommer)
mortenp
parents:
652
diff
changeset
|
266 utfsub2 = substitute(utfsub, listaddr, listdelim, 5, subst_data, NULL); |
652 | 267 subject = unistr_utf8_to_header(utfsub2); |
268 myfree(utfsub); | |
269 myfree(utfsub2); | |
270 | |
271 tmp = concatstr(10, "From: ", listname, listdelim, "help@", listfqdn, | |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
272 "\nMIME-Version: 1.0" |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
273 "\nContent-Type: multipart/" DIGESTMIMETYPE "; " |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
274 "boundary=", boundary, |
652 | 275 "\nSubject: ", subject, |
276 "\n"); | |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
277 |
338 | 278 myfree(listfqdn); |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
279 myfree(subject); |
338 | 280 |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
281 if (writen(fd, tmp, strlen(tmp)) < 0) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
282 myfree(tmp); |
372 | 283 goto errdighdrs; |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
284 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
285 myfree(tmp); |
372 | 286 |
374 | 287 if(hdrfd >= 0 && dumpfd2fd(hdrfd, fd) < 0) { |
372 | 288 goto errdighdrs; |
289 } | |
290 | |
291 close(hdrfd); | |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
292 hdrfd = -1; |
372 | 293 |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
294 if (writen(fd, "\n", 1) < 0) { |
372 | 295 errdighdrs: |
338 | 296 log_error(LOG_ARGS, "Could not write digest headers to '%s'", |
297 queuename); | |
298 close(fd); | |
299 unlink(queuename); | |
300 myfree(boundary); | |
301 myfree(queuename); | |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
302 myfree(listaddr); |
338 | 303 myfree(listname); |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
304 myfree(listdelim); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
305 myfree(subst_data[1]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
306 myfree(subst_data[3]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
307 myfree(subst_data[5]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
308 myfree(subst_data[7]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
309 myfree(subst_data[9]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
310 if (txtfd > 0) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
311 close(txtfd); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
312 myfree(line); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
313 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
314 if (hdrfd > 0) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
315 close(hdrfd); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
316 } |
338 | 317 return -1; |
318 } | |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
319 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
320 if ((txtfd > 0) && !statctrl(listdir, "nodigesttext")) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
321 |
630
d132d689873a
Fixed digest multipart boundary (Thanks to Ulrich Mueller)
mortenp
parents:
566
diff
changeset
|
322 tmp = concatstr(3, "\n--", boundary, |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
323 "\nContent-Type: text/plain; charset=UTF-8" |
740
5db75af2d0db
Fix Content-Transfer-Encoding: header for digests,
Ben Schmidt
parents:
660
diff
changeset
|
324 "\nContent-Transfer-Encoding: 8bit" |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
325 "\n\n"); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
326 if (writen(fd, tmp, strlen(tmp)) == -1) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
327 log_error(LOG_ARGS, "Could not write digest text/plain" |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
328 " part headers to '%s'", queuename); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
329 close(fd); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
330 unlink(queuename); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
331 myfree(boundary); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
332 myfree(tmp); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
333 myfree(queuename); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
334 myfree(listaddr); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
335 myfree(listname); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
336 myfree(listdelim); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
337 myfree(subst_data[1]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
338 myfree(subst_data[3]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
339 myfree(subst_data[5]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
340 myfree(subst_data[7]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
341 myfree(subst_data[9]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
342 if (txtfd > 0) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
343 close(txtfd); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
344 myfree(line); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
345 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
346 return -1; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
347 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
348 myfree(tmp); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
349 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
350 if (line && (strncasecmp(line, "Subject: ", 9) == 0)) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
351 myfree(line); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
352 line = mygetline(txtfd); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
353 if (line && (strcmp(line, "\n") == 0)) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
354 /* skip empty line after Subject: */ |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
355 line[0] = '\0'; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
356 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
357 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
358 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
359 if (line) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
360 do { |
652 | 361 utfline = unistr_escaped_to_utf8(line); |
362 myfree(line); | |
363 | |
364 tmp = substitute(utfline, listaddr, listdelim, | |
660
c26e97a2207b
Added support for the 'originalmail' keyword (Sascha Sommer)
mortenp
parents:
652
diff
changeset
|
365 5, subst_data, NULL); |
652 | 366 myfree(utfline); |
367 | |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
368 if(writen(fd, tmp, strlen(tmp)) < 0) { |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
369 myfree(tmp); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
370 log_error(LOG_ARGS, "Could not write" |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
371 " std mail"); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
372 break; |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
373 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
374 myfree(tmp); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
375 } while ((line = mygetline(txtfd))); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
376 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
377 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
378 close(txtfd); |
740
5db75af2d0db
Fix Content-Transfer-Encoding: header for digests,
Ben Schmidt
parents:
660
diff
changeset
|
379 } else if (txtfd > 0) { |
5db75af2d0db
Fix Content-Transfer-Encoding: header for digests,
Ben Schmidt
parents:
660
diff
changeset
|
380 close(txtfd); |
565
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
381 } |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
382 |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
383 myfree(line); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
384 myfree(listaddr); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
385 myfree(listdelim); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
386 myfree(subst_data[1]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
387 myfree(subst_data[3]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
388 myfree(subst_data[5]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
389 myfree(subst_data[7]); |
e3a9ca0e9c33
added support for digest text part and digestissue keyword
mortenp
parents:
520
diff
changeset
|
390 myfree(subst_data[9]); |
338 | 391 |
392 for (i=firstindex; i<=lastindex; i++) { | |
393 snprintf(buf, sizeof(buf), "%d", i); | |
394 | |
395 archivename = concatstr(3, listdir, "/archive/", buf); | |
396 archivefd = open(archivename, O_RDONLY); | |
397 myfree(archivename); | |
398 | |
399 if (archivefd < 0) | |
400 continue; | |
401 | |
630
d132d689873a
Fixed digest multipart boundary (Thanks to Ulrich Mueller)
mortenp
parents:
566
diff
changeset
|
402 tmp = concatstr(7, "\n--", boundary, |
338 | 403 "\nContent-Type: message/rfc822" |
404 "\nContent-Disposition: inline; filename=\"", | |
405 listname, "_", buf, ".eml\"" | |
406 "\n\n"); | |
407 if (writen(fd, tmp, strlen(tmp)) == -1) { | |
408 log_error(LOG_ARGS, "Could not write digest part " | |
409 "headers for archive index %d to " | |
410 "'%s'", i, queuename); | |
411 close(fd); | |
412 close(archivefd); | |
413 unlink(queuename); | |
414 myfree(boundary); | |
415 myfree(tmp); | |
416 myfree(queuename); | |
417 myfree(listname); | |
418 return -1; | |
419 } | |
420 myfree(tmp); | |
421 | |
422 if (dumpfd2fd(archivefd, fd) < 0) { | |
423 log_error(LOG_ARGS, "Could not write digest part %d " | |
424 "to '%s'", i, | |
425 queuename); | |
426 close(fd); | |
427 close(archivefd); | |
428 unlink(queuename); | |
429 myfree(boundary); | |
430 myfree(queuename); | |
431 myfree(listname); | |
432 return -1; | |
433 } | |
434 | |
435 close(archivefd); | |
436 } | |
437 | |
630
d132d689873a
Fixed digest multipart boundary (Thanks to Ulrich Mueller)
mortenp
parents:
566
diff
changeset
|
438 tmp = concatstr(3, "\n--", boundary, "--\n"); |
338 | 439 if (writen(fd, tmp, strlen(tmp)) == -1) { |
440 log_error(LOG_ARGS, "Could not write digest end to '%s'", | |
441 queuename); | |
442 close(fd); | |
443 unlink(queuename); | |
444 myfree(boundary); | |
445 myfree(queuename); | |
446 myfree(listname); | |
447 return -1; | |
448 } | |
449 | |
450 close(fd); | |
451 myfree(boundary); | |
452 myfree(listname); | |
369 | 453 myfree(tmp); |
338 | 454 |
455 childpid = fork(); | |
456 | |
457 if(childpid < 0) { | |
458 log_error(LOG_ARGS, "Could not fork"); | |
459 myfree(queuename); | |
460 return -1; | |
461 } | |
462 | |
463 if(childpid > 0) { | |
464 do /* Parent waits for the child */ | |
465 pid = waitpid(childpid, &status, 0); | |
466 while(pid == -1 && errno == EINTR); | |
467 } else { | |
468 execlp(mlmmjsend, mlmmjsend, | |
469 "-l", "7", | |
470 "-L", listdir, | |
471 "-m", queuename, | |
435 | 472 (char *)NULL); |
338 | 473 log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsend); |
474 exit(EXIT_FAILURE); /* It is OK to exit, as this is a child */ | |
475 } | |
476 | |
477 myfree(queuename); | |
478 | |
479 return 0; | |
480 } |