ezmlmx 0.68
ezmlmx
Loading...
Searching...
No Matches
ezmlm-warn.c
Go to the documentation of this file.
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <stdio.h>
4#include <unistd.h>
5#include "direntry.h"
6#include "readwrite.h"
7#include "getln.h"
8#include "buffer.h"
9#include "stralloc.h"
10#include "readclose.h"
11#include "getoptb.h"
12#include "getconf.h"
13#include "byte.h"
14#include "error.h"
15#include "str.h"
16#include "sig.h"
17#include "now.h"
18#include "datetime.h"
19#include "fmt.h"
20#include "cookie.h"
21#include "qmail.h"
22#include "errtxt.h"
23#include "quote.h"
24#include "open.h"
25#include "scan.h"
26#include "lock.h"
27#include "ezcopy.h"
28#include "mime.h"
29#include "auto_version.h"
30#include "hdr.h"
31#include "idx.h"
32#include "subscribe.h"
33#include "logmsg.h"
34#include "lockfile.h"
35#include "ezmlm.h"
36#include "errno.h"
37
38#define WHO "ezmlm-warn"
39
45
46static void die_usage() { logmsg(WHO,100,USAGE,"ezmlm-warn -dD -l secs -t days dir"); }
47static void die_nomem() { logmsg(WHO,111,FATAL,ERR_NOMEM); }
48
49stralloc outhost = {0};
50stralloc outlocal = {0};
51
52stralloc key = {0};
53stralloc mailinglist = {0};
54stralloc digdir = {0};
55stralloc charset = {0};
57
58buffer bo;
59char outbuf[16];
60
61unsigned long when;
62char *dir;
63char *workdir;
64int flagdig = 0;
65char flagcd = '\0'; /* default: don't use transfer encoding */
66stralloc fn = {0};
67stralloc bdname = {0};
68stralloc fnlasth = {0};
69stralloc fnlastd = {0};
70stralloc lasth = {0};
71stralloc lastd = {0};
72struct stat st;
73
74void die_read() { logmsg(WHO,111,FATAL,B(ERR_READ,fn.s)); }
75
76void makedir(char *s)
77{
78 if (mkdir(s,0755) == -1)
79 if (errno != EEXIST)
80 logmsg(WHO,111,FATAL,B(ERR_CREATE,s));
81}
82
83char inbuf[1024];
84buffer bi;
85char textbuf[1024];
86buffer bt;
87
88stralloc addr = {0};
89char strnum[FMT_ULONG];
90char hash[COOKIE];
91stralloc fnhash = {0};
92stralloc quoted = {0};
93stralloc line = {0};
94stralloc qline = {0};
95
96struct qmail qq;
97ssize_t qqwrite(int fd,char *buf,unsigned int len)
98{
100 return len;
101}
102char qqbuf[1];
103buffer bq = BUFFER_INIT(qqwrite,-1,qqbuf,sizeof(qqbuf));
104
105void code_qput(char *s,unsigned int n)
106{
107 if (!flagcd)
108 qmail_put(&qq,s,n);
109 else {
110 if (flagcd == 'B')
111 encode_b64(s,n,&qline,0);
112 else
113 encode_qp(s,n,&qline);
114 qmail_put(&qq,qline.s,qline.len);
115 }
116}
117
118void doit(int flagw)
119{
120 unsigned int i;
121 int fd;
122 int match;
123 int fdhash;
124 const char *err;
125
126 fd = open_read(fn.s);
127 if (fd == -1) die_read();
128 buffer_init(&bi,buffer_unixread,fd,inbuf,sizeof(inbuf));
129
130 if (getln(&bi,&addr,&match,'\0') == -1) die_read();
131 if (!match) { close(fd); return; }
132 if (!issub(workdir,addr.s,(char *) 0)) {
133 close(fd);
134 /*XXX*/unlink(fn.s);
135 return;
136 }
137 cookie(hash,"",0,"",addr.s,"");
138 if (!stralloc_copys(&fnhash,workdir)) die_nomem();
139 if (!stralloc_cats(&fnhash,"/bounce/h/")) die_nomem();
140 if (!stralloc_catb(&fnhash,hash,1)) die_nomem();
141 if (!stralloc_cats(&fnhash,"/h")) die_nomem();
142 if (!stralloc_catb(&fnhash,hash+1,COOKIE-1)) die_nomem();
143 if (!stralloc_0(&fnhash)) die_nomem();
144
145 if (qmail_open(&qq,(stralloc *) 0) == -1)
146 logmsg(WHO,111,FATAL,ERR_QMAIL_QUEUE);
147
148 hdr_add2("Mailing-List: ",mailinglist.s,mailinglist.len);
149 if (getconf_line(&line,"listid",0,dir))
150 hdr_add2("\nList-ID: ",line.s,line.len);
152 if (flagcd) {
153 if (!stralloc_0(&line)) die_nomem();
154 }
155 hdr_from("-help");
156 if (!quote2(&quoted,addr.s)) die_nomem();
157 hdr_add2("To: ",quoted.s,quoted.len);
158 /* to accomodate transfer-encoding */
160 hdr_listsubject1(flagw ? "probe from " : "warning from ");
161
162 if (flagcd) { /* first part for QP/base64 multipart msg */
163 hdr_boundary(0);
166 } else
167 qmail_puts(&qq,"\n");
168
169 ezcopy(&qq,"text/top",flagcd);
170 ezcopy(&qq,flagw ? "text/bounce-probe" : "text/bounce-warn",flagcd);
171
172 if (!flagw) {
173 if (flagdig)
174 ezcopy(&qq,"text/dig-bounce-num",flagcd);
175 else
176 ezcopy(&qq,"text/bounce-num",flagcd);
177 if (!flagcd) {
178 fdhash = open_read(fnhash.s);
179 if (fdhash == -1) {
180 if (errno != ENOENT)
181 logmsg(WHO,111,FATAL,B(ERR_OPEN,fnhash.s));
182 } else {
183 buffer_init(&bt,buffer_unixread,fdhash,textbuf,sizeof(textbuf));
184 for(;;) {
185 if (getln(&bt,&line,&match,'\n') == -1)
186 logmsg(WHO,111,FATAL,B(ERR_READ,fnhash.s));
187 if (!match) break;
188 code_qput(line.s,line.len);
189 }
190 }
191 close(fdhash);
192 } else {
193 if (!stralloc_copys(&line,"")) die_nomem();
194 if (openreadclose(fnhash.s,&line,256) < 0)
195 logmsg(WHO,111,FATAL,B(ERR_OPEN,fnhash.s));
196 code_qput(line.s,line.len);
197 }
198 }
199
200 ezcopy(&qq,"text/bounce-bottom",flagcd);
201 if (flagcd) {
202 if (flagcd == 'B') {
203 encode_b64("",0,&line,2);
204 qmail_put(&qq,line.s,line.len); /* flush */
205 }
206 hdr_boundary(0);
208 qmail_puts(&qq,"\n");
209 }
210 if (buffer_copy(&bq,&bi) < 0) die_read();
211 close(fd);
212
213 if (flagcd) /* end multipart/mixed */
214 hdr_boundary(1);
215
216 strnum[fmt_ulong(strnum,when)] = 0;
217 cookie(hash,key.s,key.len,strnum,addr.s,flagw ? "P" : "W");
218 if (!stralloc_copy(&line,&outlocal)) die_nomem();
219 if (!stralloc_cats(&line,flagw ? "-return-probe-" : "-return-warn-"))
220 die_nomem();
221 if (!stralloc_cats(&line,strnum)) die_nomem();
222 if (!stralloc_cats(&line,".")) die_nomem();
223 if (!stralloc_catb(&line,hash,COOKIE)) die_nomem();
224 if (!stralloc_cats(&line,"-")) die_nomem();
225 i = str_chr(addr.s,'@');
226 if (!stralloc_catb(&line,addr.s,i)) die_nomem();
227 if (addr.s[i]) {
228 if (!stralloc_cats(&line,"=")) die_nomem();
229 if (!stralloc_cats(&line,addr.s + i + 1)) die_nomem();
230 }
231 if (!stralloc_cats(&line,"@")) die_nomem();
232 if (!stralloc_cat(&line,&outhost)) die_nomem();
233 if (!stralloc_0(&line)) die_nomem();
234 qmail_from(&qq,line.s);
235
236 qmail_to(&qq,addr.s);
237 if (*(err = qmail_close(&qq)) != '\0')
238 logmsg(WHO,111,FATAL,B(ERR_TMP_QMAIL_QUEUE,err + 1));
239
240 strnum[fmt_ulong(strnum,qmail_qp(&qq))] = 0;
241 logmsg(WHO,0,INFO,B("qp ",strnum));
242
243 if (!flagw) {
244 if (unlink(fnhash.s) == -1)
245 if (errno != ENOENT)
246 logmsg(WHO,111,FATAL,B(ERR_DELETE,fnhash.s));
247 }
248 if (unlink(fn.s) == -1)
249 logmsg(WHO,111,FATAL,B(ERR_DELETE,fn.s));
250}
251
252int main(int argc,char **argv)
253{
254 DIR *bouncedir, *bsdir, *hdir;
255 direntry *d, *ds;
256 unsigned long bouncedate;
257 unsigned long bouncetimeout = BOUNCE_TIMEOUT;
258 unsigned long lockout = 0L;
259 unsigned long ld;
260 unsigned long ddir, dfile;
261 int fdlock, fd;
262 int opt;
263 char ch;
264
265 umask(022);
266 sig_pipeignore();
267 when = (unsigned long) now();
268 while ((opt = getoptb(argc,argv,"dDl:t:vV")) != opteof)
269 switch(opt) {
270 case 'd': flagdig = 1; break;
271 case 'D': flagdig = 0; break;
272 case 'l': if (optarg) { /* lockout in seconds */
273 scan_ulong(optarg,&lockout);
274 }
275 break;
276 case 't': if (optarg) { /* bouncetimeout in days */
277 scan_ulong(optarg,&bouncetimeout);
278 bouncetimeout *= 3600L * 24L;
279 }
280 break;
281 case 'v':
282 case 'V': logmsg(WHO,0,VERSION,auto_version);
283 default: die_usage();
284 }
285 dir = argv[optind];
286 if (!dir) die_usage();
287 if (chdir(dir) == -1)
288 logmsg(WHO,111,FATAL,B(ERR_SWITCH,dir));
289 if (flagdig) {
290 if (!stralloc_copys(&digdir,dir)) die_nomem();
291 if (!stralloc_cats(&digdir,"/digest")) die_nomem();
292 if (!stralloc_0(&digdir)) die_nomem();
293 workdir = digdir.s;
294 } else
295 workdir = dir;
296
297 if (!stralloc_copys(&fnlastd,workdir)) die_nomem();
298 if (!stralloc_cats(&fnlastd,"/bounce/lastd")) die_nomem();
299 if (!stralloc_0(&fnlastd)) die_nomem();
300 if (openreadclose(fnlastd.s,&lastd,16) == -1) /* last time d was scanned */
301 logmsg(WHO,111,FATAL,B(ERR_READ,fnlastd.s));
302 if (!stralloc_0(&lastd)) die_nomem();
303 scan_ulong(lastd.s,&ld);
304 if (!lockout)
305 lockout = bouncetimeout / 50; /* 5.6 h for default timeout */
306 if (ld + lockout > when && ld < when)
307 _exit(0); /* exit silently. */
308 /*Second check is to prevent lockup if lastd gets corrupted */
309
310 if (!stralloc_copy(&fnlasth,&fnlastd)) die_nomem();
311 fnlasth.s[fnlasth.len - 2] = 'h'; /* bad, but feels good ... */
312
313 switch (openreadclose("key",&key,32)) {
314 case -1: logmsg(WHO,111,FATAL,B(ERR_READ,"/key: ",dir));
315 case 0: logmsg(WHO,100,FATAL,B(dir,"/key",ERR_NOEXIST));
316 }
317 getconf_line(&outhost,"outhost",1,dir);
318 getconf_line(&outlocal,"outlocal",1,dir);
319 if (flagdig)
320 if (!stralloc_cats(&outlocal,"-digest")) die_nomem();
321 getconf_line(&mailinglist,"mailinglist",1,dir);
322 if (getconf_line(&charset,"charset",0,dir)) {
323 if (charset.len >= 2 && charset.s[charset.len - 2] == ':') {
324 if (charset.s[charset.len - 1] == 'B' ||
325 charset.s[charset.len - 1] == 'Q') {
326 flagcd = charset.s[charset.len - 1];
327 charset.s[charset.len - 2] = '\0';
328 }
329 }
330 } else
331 if (!stralloc_copys(&charset,TXT_DEF_CHARSET)) die_nomem();
332 if (!stralloc_0(&charset)) die_nomem();
333
334 set_cpoutlocal(&outlocal); /* for copy */
335 set_cpouthost(&outhost); /* for copy */
336 ddir = when / 10000;
337 dfile = when - 10000 * ddir;
338
339 if (!stralloc_copys(&line,workdir)) die_nomem();
340 if (!stralloc_cats(&line,"/lockbounce")) die_nomem();
341 if (!stralloc_0(&line)) die_nomem();
342 fdlock = lockfile(line.s);
343
344 if (!stralloc_copys(&line,workdir)) die_nomem();
345 if (!stralloc_cats(&line,"/bounce/d")) die_nomem();
346 if (!stralloc_0(&line)) die_nomem();
347 bouncedir = opendir(line.s);
348 if (!bouncedir)
349 if (errno != ENOENT)
350 logmsg(WHO,111,FATAL,B(ERR_OPEN,line.s));
351 else
352 _exit(0); /* no bouncedir - no bounces! */
353
354 while ((d = readdir(bouncedir))) { /* dxxx/ */
355 if (str_equal(d->d_name,".")) continue;
356 if (str_equal(d->d_name,"..")) continue;
357
358 scan_ulong(d->d_name,&bouncedate);
359
360 /* since we do entire dir, we do files that are not old enough. */
361 /* to not do this and accept a delay of 10000s (2.8h) of the oldest */
362 /* bounce we add to bouncedate. We don't if bouncetimeout=0 so that */
363 /* that setting still processes _all_ bounces. */
364
365 if (bouncetimeout) ++bouncedate;
366 if (when >= bouncedate * 10000 + bouncetimeout) {
367 if (!stralloc_copys(&bdname,workdir)) die_nomem();
368 if (!stralloc_cats(&bdname,"/bounce/d/")) die_nomem();
369 if (!stralloc_cats(&bdname,d->d_name)) die_nomem();
370 if (!stralloc_0(&bdname)) die_nomem();
371 bsdir = opendir(bdname.s);
372 if (!bsdir) {
373 if (errno != ENOTDIR)
374 logmsg(WHO,111,FATAL,B(ERR_OPEN,bdname.s,"y "));
375 else { /* leftover nnnnn_dmmmmm file */
376 if (unlink(bdname.s) == -1)
377 logmsg(WHO,111,FATAL,B(ERR_DELETE,bdname.s));
378 continue;
379 }
380 }
381 while ((ds = readdir(bsdir))) { /* dxxxx/yyyy */
382 if (str_equal(ds->d_name,".")) continue;
383 if (str_equal(ds->d_name,"..")) continue;
384 if (!stralloc_copy(&fn,&bdname)) die_nomem(); /* '\0' at end */
385 fn.s[fn.len - 1] = '/';
386 if (!stralloc_cats(&fn,ds->d_name)) die_nomem();
387 if (!stralloc_0(&fn)) die_nomem();
388 if ((ds->d_name[0] == 'd') || (ds->d_name[0] == 'w'))
389 doit(ds->d_name[0] == 'w');
390 else /* other stuff is junk */
391 if (unlink(fn.s) == -1)
392 logmsg(WHO,111,FATAL,B(ERR_DELETE,fn.s));
393 }
394 closedir(bsdir);
395 if (rmdir(bdname.s) == -1) /* the directory itself */
396 if (errno != ENOENT)
397 logmsg(WHO,111,FATAL,B(ERR_DELETE,bdname.s));
398 }
399 }
400 closedir(bouncedir);
401
402 if (!stralloc_copy(&line,&fnlastd)) die_nomem();
403 line.s[line.len - 2] = 'D';
404 fd = open_trunc(line.s); /* write lastd. Do safe */
405 /* since we read before lock*/
406 if (fd == -1)
407 logmsg(WHO,111,FATAL,B(ERR_OPEN,line.s));
408 buffer_init(&bo,buffer_unixwrite,fd,outbuf,sizeof(outbuf));
409 if (buffer_put(&bo,strnum,fmt_ulong(strnum,when)) == -1)
410 logmsg(WHO,111,FATAL,B(ERR_WRITE,line.s));
411 if (buffer_put(&bo,"\n",1) == -1) /* prettier */
412 logmsg(WHO,111,FATAL,B(ERR_WRITE,line.s));
413 if (buffer_flush(&bo) == -1)
414 logmsg(WHO,111,FATAL,B(ERR_FLUSH,line.s));
415 if (fsync(fd) == -1)
416 logmsg(WHO,111,FATAL,B(ERR_SYNC,line.s));
417 if (close(fd) == -1)
418 logmsg(WHO,111,FATAL,B(ERR_CLOSE,line.s));
419
420 if (rename(line.s,fnlastd.s) == -1)
421 logmsg(WHO,111,FATAL,B(ERR_MOVE,fnlastd.s));
422
423 /* no need to do h dir cleaning more than */
424 /* once per 1-2 days (17-30 days for all) */
425
426 if (stat(fnlasth.s,&st) == -1) {
427 if (errno != ENOENT)
428 logmsg(WHO,111,FATAL,B(ERR_STAT,fnlasth.s));
429 } else if (when < st.st_mtime + 100000 && when > st.st_mtime)
430 _exit(0); /* 2nd comp to guard against corruption */
431
432 if (openreadclose(fnlasth.s,&lasth,16) == -1) /* last h cleaned */
433 logmsg(WHO,111,FATAL,B(ERR_READ,fnlasth.s));
434 if (!stralloc_0(&lasth)) die_nomem();
435
436 ch = lasth.s[0]; /* clean h */
437 if (ch >= 'a' && ch <= 'o')
438 ++ch;
439 else
440 ch = 'a';
441 lasth.s[0] = ch;
442 if (!stralloc_copys(&line,workdir)) die_nomem();
443 if (!stralloc_cats(&line,"/bounce/h/")) die_nomem();
444 if (!stralloc_catb(&line,lasth.s,1)) die_nomem();
445 if (!stralloc_0(&line)) die_nomem();
446 hdir = opendir(line.s); /* clean ./h/xxxxxx */
447
448 if (!hdir) {
449 if (errno != ENOENT)
450 logmsg(WHO,111,FATAL,B(ERR_OPEN,line.s));
451 } else {
452 while ((d = readdir(hdir))) {
453 if (str_equal(d->d_name,".")) continue;
454 if (str_equal(d->d_name,"..")) continue;
455 if (!stralloc_copys(&fn,line.s)) die_nomem();
456 if (!stralloc_append(&fn,"/")) die_nomem();
457 if (!stralloc_cats(&fn,d->d_name)) die_nomem();
458 if (!stralloc_0(&fn)) die_nomem();
459 if (stat(fn.s,&st) == -1) {
460 if (errno == ENOENT) continue;
461 logmsg(WHO,111,FATAL,B(ERR_STAT,fn.s));
462 }
463 if (when > st.st_mtime + 3 * bouncetimeout)
464 if (unlink(fn.s) == -1)
465 logmsg(WHO,111,FATAL,B(ERR_DELETE,fn.s));
466 }
467 closedir(hdir);
468 }
469
470 fd = open_trunc(fnlasth.s); /* write lasth */
471 if (fd == -1)
472 logmsg(WHO,111,FATAL,B(ERR_OPEN,fnlasth.s));
473
474 buffer_init(&bo,buffer_unixwrite,fd,outbuf,sizeof(outbuf));
475 if (buffer_put(&bo,lasth.s,1) == -1)
476 logmsg(WHO,111,FATAL,B(ERR_OPEN,fnlasth.s));
477 if (buffer_put(&bo,"\n",1) == -1) /* prettier */
478 logmsg(WHO,111,FATAL,B(ERR_OPEN,fnlasth.s));
479 if (buffer_flush(&bo) == -1)
480 logmsg(WHO,111,FATAL,B(ERR_FLUSH,fnlasth.s));
481
482 close(fd); /* no big loss. No reason to flush/sync */
483 /* See check of ld above to guard against */
484 /* it being corrupted and > when */
485 closesql();
486 _exit(0);
487
488 return 0;
489}
datetime_sec now(void)
Definition now.c:5
#define COOKIE
Definition cookie.h:4
#define TXT_DEF_CHARSET
Definition idx.h:93
#define BOUNCE_TIMEOUT
Definition idx.h:33
int issub()
Returns (char *) to match if userhost is in the subscriber database dbname, 0 otherwise....
int quote2(stralloc *sa, const char *s)
Definition quote.c:65
const char auto_version[]
#define hdr_listsubject1(a)
Definition hdr.h:27
@ CTYPE_TEXT
Definition hdr.h:13
@ CTYPE_MULTIPART
Definition hdr.h:14
@ CTYPE_MESSAGE
Definition hdr.h:16
Error messages. If you translate these, I would urge you to keep the English version as well....
#define ERR_FLUSH
Definition errtxt.h:20
#define ERR_NOMEM
Definition errtxt.h:14
#define ERR_SYNC
Definition errtxt.h:22
#define ERR_OPEN
Definition errtxt.h:30
#define ERR_MOVE
Definition errtxt.h:29
#define ERR_NOEXIST
Definition errtxt.h:40
#define ERR_DELETE
Definition errtxt.h:25
#define ERR_READ
Definition errtxt.h:18
#define ERR_CREATE
Definition errtxt.h:28
#define ERR_QMAIL_QUEUE
Definition errtxt.h:53
#define ERR_SWITCH
Definition errtxt.h:42
#define ERR_WRITE
Definition errtxt.h:17
#define ERR_STAT
Definition errtxt.h:24
#define ERR_CLOSE
Definition errtxt.h:16
#define ERR_TMP_QMAIL_QUEUE
Definition errtxt.h:54
int lockfile(const char *)
Definition lockfile.c:15
const char * qmail_close(struct qmail *)
Definition qmail.c:120
void qmail_puts(struct qmail *, const char *)
Definition qmail.c:94
void qmail_put(struct qmail *, const char *, int)
Definition qmail.c:87
void qmail_from(struct qmail *, const char *)
Definition qmail.c:103
void qmail_to(struct qmail *, const char *)
Definition qmail.c:113
unsigned long qmail_qp(struct qmail *)
Definition qmail.c:77
int qmail_open(struct qmail *, const stralloc *)
Definition qmail.c:25
charset, outhost, outlocal and flagcd are shared
void closesql(void)
close connection to SQL server, if open
Definition opensql.c:21
void die_nomem()
Definition getconf.c:17
int getconf_line(stralloc *sa, const char *fn, int flagrequired, const char *dir)
Definition getconf.c:53
void ezcopy(struct qmail *qqp, const char *fn, char q)
Definition ezcopy.c:128
void set_cpoutlocal(const stralloc *ln)
Definition ezcopy.c:67
void set_cpouthost(const stralloc *ln)
Definition ezcopy.c:73
#define WHO
Definition author.c:1
void encode_qp(const char *indata, unsigned int n, stralloc *outdata)
Definition encode_qp.c:21
char * workdir
Definition ezmlm-get.c:129
stralloc ddir
Definition ezmlm-get.c:116
void hdr_from(const char *append)
Definition hdr_from.c:23
stralloc fn
char inbuf[1024]
char outbuf[1024]
char * dir
buffer bi
buffer bo
int flagdig
int main()
Definition ezmlm-weed.c:69
void hdr_boundary(int last)
void hdr_datemsgid(unsigned long when)
void cookie(char *hash, const char *key, unsigned int keylen, const char *date, const char *addr, const char *action)
Definition cookie.c:14
int opt
Definition ezmlm-cron.c:53
unsigned int len
Definition ezmlm-cron.c:68
stralloc addr
Definition ezmlm-cron.c:45
int fdlock
Definition ezmlm-cron.c:71
char buf[256]
Definition install.c:113
int fd
Definition ezmlm-cgi.c:141
datetime_sec when
Definition ezmlm-cgi.c:173
const char * charset
Definition ezmlm-cgi.c:110
int match
Definition ezmlm-cgi.c:140
stralloc fnhash
void makedir(char *s)
Definition ezmlm-warn.c:76
void doit(int flagw)
Definition ezmlm-warn.c:118
stralloc digdir
Definition ezmlm-warn.c:54
unsigned long when
Definition ezmlm-warn.c:61
stralloc lasth
Definition ezmlm-warn.c:70
ssize_t qqwrite(int fd, char *buf, unsigned int len)
Definition ezmlm-warn.c:97
stralloc fnlastd
Definition ezmlm-warn.c:69
void die_read()
Definition ezmlm-warn.c:74
stralloc bdname
Definition ezmlm-warn.c:67
stralloc fnlasth
Definition ezmlm-warn.c:68
stralloc lastd
Definition ezmlm-warn.c:71
void code_qput(char *s, unsigned int n)
Definition ezmlm-warn.c:105
stralloc quoted
Definition ezmlm-clean.c:90
buffer bq
Definition ezmlm-clean.c:81
stralloc mailinglist
Definition ezmlm-clean.c:93
ssize_t qqwrite(int fd, char *buf, unsigned int len)
Definition ezmlm-clean.c:75
char hboundary[HASHLEN]
Definition ezmlm-clean.c:86
char flagcd
Definition ezmlm-clean.c:59
struct qmail qq
Definition ezmlm-clean.c:73
void hdr_transferenc(void)
void hdr_add2(const char *start, const char *value, unsigned int len)
Definition hdr_add.c:25
void encode_b64(const unsigned char *indata, unsigned int n, stralloc *outdata, int control)
Definition encode_b64.c:75
void hdr_ctype(enum ctype ctype)
Definition hdr_mime.c:24
void hdr_mime(enum ctype ctype)
Definition hdr_mime.c:43
Definition qmail.h:10
const char * logmsg(const char *dir, unsigned long num, unsigned long listno, unsigned long subs, int done)
Definition loginfo.c:32