ezmlmx 0.68
ezmlmx
Loading...
Searching...
No Matches
ezmlm-store.c
Go to the documentation of this file.
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <unistd.h>
4#include "stralloc.h"
5#include "error.h"
6#include "qmail.h"
7#include "env.h"
8#include "lock.h"
9#include "sig.h"
10#include "open.h"
11#include "getln.h"
12#include "str.h"
13#include "fmt.h"
14#include "readwrite.h"
15#include "wait.h"
16#include "exit.h"
17#include "buffer.h"
18#include "getconf.h"
19#include "datetime.h"
20#include "now.h"
21#include "cookie.h"
22#include "getoptb.h"
23#include "errtxt.h"
24#include "byte.h"
25#include "case.h"
26#include "readclose.h"
27#include "quote.h"
28#include "hdr.h"
29#include "idx.h"
30#include "subscribe.h"
31#include "mime.h"
32#include "wrap.h"
33#include "auto_version.h"
34#include "logmsg.h"
35#include "ezcopy.h"
36#include "lockfile.h"
37#include "ezmlm.h"
38
39#define WHO "ezmlm-store"
40
46
47int flagmime = MOD_MIME; /* default is message as attachment */
48int flagpublic = 1; /* default anyone can post */
49 /* =0 for only moderators can */
50int flagself = 0; /* `modpost` mods approve own posts */
51 /* but mod/ is used for moderators */
52 /* of other posts. Def=no=0 */
53int flagconfirm = -1; /* if true, sender must approve its own posts */
54char flagcd = '\0'; /* default: don't use quoted-printable */
55int flagbody = 1; /* body of message enclosed with mod request */
56 /* 0 => headers only */
57
58static void die_usage() { logmsg(WHO,100,USAGE,"ezmlm-store [-cCmMpPrRsSvV] dir"); }
59static void die_nomem() { logmsg(WHO,111,FATAL,ERR_NOMEM); }
60
61stralloc fnmsg = {0};
62static void die_msg() { logmsg(WHO,111,FATAL,B(ERR_WRITE,fnmsg.s)); }
63
66int pid;
68
69static char strnum[FMT_ULONG];
70char hash[COOKIE];
73struct stat st;
74
75stralloc outhost = {0};
76stralloc outlocal = {0};
77
78stralloc fnbase = {0};
79stralloc line = {0};
80stralloc mailinglist = {0};
81stralloc mydtline = {0};
82stralloc returnpath = {0};
83stralloc accept = {0};
84stralloc action = {0};
85stralloc reject = {0};
86stralloc quoted = {0};
87stralloc key = {0};
88stralloc subject = {0};
89stralloc moderators = {0};
90stralloc confirmpost = {0};
91stralloc charset = {0};
92stralloc sendopt = {0};
93
94struct qmail qq;
95ssize_t qqwrite(int fd,char *buf,unsigned int len)
96{
98 return len;
99}
100
101int subto(char *s,unsigned int l)
102{
103 qmail_put(&qq,"T",1);
104 qmail_put(&qq,s,l);
105 qmail_put(&qq,"",1);
106 return (int) l;
107}
108
109char qqbuf[1];
110buffer bq = BUFFER_INIT(qqwrite,-1,qqbuf,sizeof(qqbuf));
111buffer bi;
112char inbuf[1024];
113buffer bo;
114char outbuf[1024];
115buffer bt;
116char textbuf[512];
117buffer bs;
118char subbuf[512];
119
126
127void makeacthash(stralloc *act)
128{
129 int d;
130
131 d = 2 + str_chr(act->s + 1,'-');
132 cookie(hash,key.s,key.len,act->s + d,"","a");
133 *(act->s + act->len - 1) = '.'; /* we put a '.' Bad, but works */
134 if (!stralloc_catb(act,hash,COOKIE)) die_nomem();
135 if (!stralloc_cats(act,"@")) die_nomem();
136 if (!stralloc_cat(act,&outhost)) die_nomem();
137}
138
139int main(int argc,char **argv)
140{
141 char *dir;
142 int fdlock;
143 char *sender;
144 int match;
145 int flaginheader;
146 int flagmodpost;
147 int flagremote;
148 const char *pmod;
149 const char *err;
150 int opt;
151 unsigned int i;
152 char szchar[2] = "-";
153 int child;
154
155 umask(022);
156 sig_pipeignore();
157
158 if (!stralloc_copys(&sendopt,"-")) die_nomem();
159
160 while ((opt = getoptb(argc,argv,"bBcCmMpPrRsSvVyY")) != opteof)
161 switch(opt) {
162 case 'b': flagbody = 1; break;
163 case 'B': flagbody = 0; break;
164 case 'm': flagmime = 1; break;
165 case 'M': flagmime = 0; break;
166 case 'p': flagpublic = 1; break; /* anyone can post (still moderated)*/
167 case 'P': flagpublic = 0; break; /* only moderators can post */
168 case 's': flagself = 1; break; /* modpost and DIR/mod diff fxns */
169 case 'S': flagself = 0; break; /* same fxn */
170 case 'y': flagconfirm = 1; break; /* force post confirmation */
171 case 'Y': flagconfirm = 0; break; /* disable post confirmation */
172 case 'c': /* ezmlm-send flags */
173 case 'C':
174 case 'r':
175 case 'R': szchar[0] = (char) opt & 0xff;
176 if (!stralloc_append(&sendopt,szchar)) die_nomem();
177 break;
178 case 'v':
179 case 'V': logmsg(WHO,0,VERSION,auto_version);
180 default: die_usage();
181 }
182
183 sender = env_get("SENDER");
184
185 if (sender) {
186 if (!*sender || str_equal(sender,"#@[]"))
187 logmsg(WHO,100,FATAL,ERR_BOUNCE);
188 }
189
190 dir = argv[optind];
191 if (!dir) die_usage();
192
193 if (chdir(dir) == -1)
194 logmsg(WHO,111,FATAL,B(ERR_SWITCH,dir));
195
196 if (flagconfirm == -1)
197 flagconfirm = getconf_line(&confirmpost,"confirmpost",0,dir);
198 else
199 getconf_line(&confirmpost,"confirmpost",0,dir);
200
201 flagmodpost = getconf_line(&moderators,"modpost",0,dir);
202 flagremote = getconf_line(&line,"remote",0,dir);
203 if (!flagmodpost && !flagconfirm) { /* not msg-mod. Pipe to ezmlm-send */
204 if ((child = wrap_fork()) == 0)
205 wrap_execbin("/ezmlm-send", &sendopt, dir);
206 /* parent */
208 }
209
210 if (!moderators.len || !(moderators.s[0] == '/')) {
211 if (!stralloc_copys(&moderators,dir)) die_nomem();
212 if (!stralloc_cats(&moderators,"/mod")) die_nomem();
213 }
214 if (!stralloc_0(&moderators)) die_nomem();
215
216 if (sender) {
217 pmod = issub(moderators.s,sender,(char *) 0);
218 closesql();
219 /* sender = moderator? */
220 } else
221 pmod = 0;
222
223 if (!pmod && !flagpublic)
224 logmsg(WHO,100,FATAL,ERR_NO_POST);
225
226 switch (openreadclose("key",&key,32)) {
227 case -1: logmsg(WHO,111,FATAL,B(ERR_READ,"/key: ",dir));
228 case 0: logmsg(WHO,100,FATAL,B("/key",dir,ERR_NOEXIST));
229 }
230
231 getconf_line(&outhost,"outhost",1,dir);
232 getconf_line(&outlocal,"outlocal",1,dir);
233 getconf_line(&mailinglist,"mailinglist",1,dir);
234
235 fdlock = lockfile("mod/lock");
236
237 if (!stralloc_copys(&mydtline, flagconfirm
238 ? "Delivered-To: confirm to "
239 : "Delivered-To: moderator for ")) die_nomem();
240 if (!stralloc_catb(&mydtline,outlocal.s,outlocal.len)) die_nomem();
241 if (!stralloc_append(&mydtline,"@")) die_nomem();
242 if (!stralloc_catb(&mydtline,outhost.s,outhost.len)) die_nomem();
243 if (!stralloc_cats(&mydtline,"\n")) die_nomem();
244
245 if (!stralloc_copys(&returnpath,"Return-Path: <")) die_nomem();
246 if (sender) {
247 if (!stralloc_cats(&returnpath,sender)) die_nomem();
248 for (i = 14; i < returnpath.len;++i)
249 if (returnpath.s[i] == '\n' || !returnpath.s[i] )
250 returnpath.s[i] = '_';
251 /* NUL and '\n' are bad, but we don't quote since this is */
252 /* only for ezmlm-moderate, NOT for SMTP */
253 }
254 if (!stralloc_cats(&returnpath,">\n")) die_nomem();
255
256 pid = getpid(); /* unique file name */
257
258 for (i = 0 ;; ++i) { /* got lock - nobody else can add files */
259 when = now(); /* when is also used later for date! */
260 if (!stralloc_copys(&fnmsg, flagconfirm?"mod/unconfirmed/":"mod/pending/")) die_nomem();
261 if (!stralloc_copyb(&fnbase,strnum,fmt_ulong(strnum,when))) die_nomem();
262 if (!stralloc_append(&fnbase,".")) die_nomem();
263 if (!stralloc_catb(&fnbase,strnum,fmt_ulong(strnum,pid))) die_nomem();
264 if (!stralloc_cat(&fnmsg,&fnbase)) die_nomem();
265 if (!stralloc_0(&fnmsg)) die_nomem();
266 if (stat(fnmsg.s,&st) == -1) if (errno == ENOENT) break;
267 /* really should never get to this point */
268 if (i == 2) logmsg(WHO,111,FATAL,ERR_UNIQUE);
269 sleep(2);
270 }
271
272 if (!stralloc_copys(&action,"-")) die_nomem();
274 if (!stralloc_cat(&action,&fnbase)) die_nomem();
275 if (!stralloc_0(&action)) die_nomem();
277 if (!quote(&quoted,&outlocal)) die_nomem();
278 if (!stralloc_copy(&reject,&quoted)) die_nomem();
279 if (!stralloc_cat(&reject,&action)) die_nomem();
280 if (!stralloc_0(&reject)) die_nomem();
281
282 if (!stralloc_copys(&action,"-")) die_nomem();
284 if (!stralloc_cat(&action,&fnbase)) die_nomem();
285 if (!stralloc_0(&action)) die_nomem();
287 if (!stralloc_copy(&accept,&quoted)) die_nomem();
288 if (!stralloc_cat(&accept,&action)) die_nomem();
289 if (!stralloc_0(&accept)) die_nomem();
290
291 set_cpoutlocal(&outlocal);
292 set_cpouthost(&outhost);
293 set_cptarget(accept.s); /* for copy () */
295
296 fdmsg = open_trunc(fnmsg.s);
297 if (fdmsg == -1)
298 logmsg(WHO,111,FATAL,B(ERR_WRITE,dir,"/",fnmsg.s));
299 buffer_init(&bo,buffer_unixwrite,fdmsg,outbuf,sizeof(outbuf));
300
301 if (qmail_open(&qq, (stralloc *) 0) == -1) /* Open mailer */
302 logmsg(WHO,111,FATAL,ERR_QMAIL_QUEUE);
303
304 hdr_add2("Mailing-List: ",mailinglist.s,mailinglist.len);
305
306 if (getconf_line(&line,"listid",0,dir))
307 hdr_add2("List-ID: ",line.s,line.len);
309 if (flagconfirm)
310 hdr_from("-owner");
311 else
312 hdr_add2s("From: ",reject.s);
313
314 hdr_add2s("Reply-To: ",accept.s);
315
316 if (!flagconfirm && !pmod && flagremote) { /* if remote admin add -allow- address */
317 qmail_puts(&qq,"Cc: "); /* for ezmlm-gate users */
318 strnum[fmt_ulong(strnum,(unsigned long) when)] = 0;
319 cookie(hash,key.s,key.len-FLD_ALLOW,strnum,sender,"t");
320 if (!stralloc_copy(&line,&outlocal)) die_nomem();
321 if (!stralloc_cats(&line,"-allow-tc.")) die_nomem();
322 if (!stralloc_cats(&line,strnum)) die_nomem();
323 if (!stralloc_append(&line,".")) die_nomem();
324 if (!stralloc_catb(&line,hash,COOKIE)) die_nomem();
325 if (!stralloc_append(&line,"-")) die_nomem();
326 i = str_rchr(sender,'@');
327 if (!stralloc_catb(&line,sender,i)) die_nomem();
328 if (sender[i]) {
329 if (!stralloc_append(&line,"=")) die_nomem();
330 if (!stralloc_cats(&line,sender + i + 1)) die_nomem();
331 }
332 qmail_put(&qq,line.s,line.len);
333 qmail_puts(&qq,"@");
334 qmail_put(&qq,outhost.s,outhost.len);
335 qmail_puts(&qq,"\n");
336 }
337 if (flagconfirm) {
338 qmail_puts(&qq,"To: <");
339 if (sender)
340 qmail_puts(&qq, sender);
341 qmail_puts(&qq,">\n");
342 } else {
343 qmail_puts(&qq,"To: Recipient list not shown: ;\n");
344 }
345
346 /* FIXME: Drop the custom subject hack and use hdr_listsubject1 */
347
348 if (!stralloc_copys(&subject,"Subject: ")) die_nomem();
349 if (flagconfirm) {
350 if (confirmpost.len) {
351 if (!stralloc_cat(&subject,&confirmpost)) die_nomem();
352 if (!stralloc_cats(&subject," ")) die_nomem();
353 } else {
354 if (!stralloc_cats(&subject,TXT_CONFIRM_POST)) die_nomem();
355 }
356 } else {
357 if (!stralloc_cats(&subject,TXT_MODERATE)) die_nomem();
358 }
359 if (!quote(&quoted,&outlocal)) die_nomem();
360 if (!stralloc_cat(&subject,&quoted)) die_nomem();
361 if (!stralloc_append(&subject,"@")) die_nomem();
362 if (!stralloc_cat(&subject,&outhost)) die_nomem();
363 if (flagmime) {
364 if (getconf_line(&charset,"charset",0,dir)) {
365 if (charset.len >= 2 && charset.s[charset.len - 2] == ':') {
366 if (charset.s[charset.len - 1] == 'B' ||
367 charset.s[charset.len - 1] == 'Q') {
368 flagcd = charset.s[charset.len - 1];
369 charset.s[charset.len - 2] = '\0';
370 }
371 }
372 } else
373 if (!stralloc_copys(&charset,TXT_DEF_CHARSET)) die_nomem();
374 if (!stralloc_0(&charset)) die_nomem();
376 qmail_put(&qq,subject.s,subject.len);
377 hdr_boundary(0);
380 } else {
381 qmail_put(&qq,subject.s,subject.len);
382 qmail_puts(&qq,"\n\n");
383 }
384 ezcopy(&qq,flagconfirm?"text/post-confirm":"text/mod-request",flagcd);
385 if (flagcd == 'B') {
386 encode_b64("",0,&line,2);
387 qmail_put(&qq,line.s,line.len);
388 }
389 if (buffer_put(&bo,returnpath.s,returnpath.len) == -1) die_msg();
390 if (buffer_put(&bo,mydtline.s,mydtline.len) == -1) die_msg();
391 buffer_init(&bi,buffer_unixread,0,inbuf,sizeof(inbuf));
392
393 if (flagmime) {
394 hdr_boundary(0);
396 qmail_puts(&qq, "\n");
397 }
398
401 flaginheader = 1;
402
403 for (;;) {
404 if (getln(&bi,&line,&match,'\n') == -1)
405 logmsg(WHO,111,FATAL,ERR_READ_INPUT);
406 if (!match) break;
407 if (line.len == 1) flaginheader = 0;
408 if (flaginheader) {
409 if ((line.len == mydtline.len) && !byte_diff(line.s,line.len,mydtline.s)) {
410 close(fdmsg); /* be nice - clean up */
411 unlink(fnmsg.s);
412 logmsg(WHO,100,FATAL,ERR_LOOPING);
413 }
414 if (case_startb(line.s,line.len,"mailing-list:")) {
415 close(fdmsg); /* be nice - clean up */
416 unlink(fnmsg.s);
417 logmsg(WHO,100,FATAL,ERR_MAILING_LIST);
418 }
419 }
420
421 if (flagbody || flaginheader) /* skip body if !flagbody */
422 qmail_put(&qq,line.s,line.len);
423 if (buffer_put(&bo,line.s,line.len) == -1) die_msg();
424 }
425
426 if (flagmime)
427 hdr_boundary(1);
428
429/* close archive before qmail. Loss of qmail will result in re-run, and */
430/* worst case this results in a duplicate msg sitting orphaned until it's */
431/* cleaned out. */
432
433 if (buffer_flush(&bo) == -1) die_msg();
434 if (fsync(fdmsg) == -1) die_msg();
435 if (fchmod(fdmsg,MODE_MOD_MSG | 0700) == -1) die_msg();
436 if (close(fdmsg) == -1) die_msg(); /* NFS stupidity */
437
438 close(fdlock);
439
440 if (flagconfirm) {
441 qmail_from(&qq,reject.s); /* envelope sender */
442 } else {
443 if (!stralloc_copy(&line,&outlocal)) die_nomem();
444 if (!stralloc_cats(&line,"-return-@")) die_nomem();
445 if (!stralloc_cat(&line,&outhost)) die_nomem();
446 if (!stralloc_0(&line)) die_nomem();
447 qmail_from(&qq,line.s); /* envelope sender */
448 }
449 if (flagconfirm) /* to sender */
450 qmail_to(&qq,sender);
451 else if (pmod) /* to moderator only */
452 qmail_to(&qq,pmod);
453 else {
454 if (flagself) { /* to all moderators */
455 if (!stralloc_copys(&moderators,dir)) die_nomem();
456 if (!stralloc_cats(&moderators,"/mod")) die_nomem();
457 if (!stralloc_0(&moderators)) die_nomem();
458 }
459 putsubs(moderators.s,0,52,subto,1);
460 }
461
462 if (*(err = qmail_close(&qq)) == '\0') {
463 strnum[fmt_ulong(strnum,qmail_qp(&qq))] = 0;
464 logmsg(WHO,0,INFO,B("qp ",strnum));
465 } else
466 logmsg(WHO,111,FATAL,B(ERR_TMP_QMAIL_QUEUE,err+1));
467
468 return 0;
469}
datetime_sec now(void)
Definition now.c:5
#define COOKIE
Definition cookie.h:4
#define ACTION_REJECT
Definition idx.h:195
#define TXT_DEF_CHARSET
Definition idx.h:93
#define MODE_MOD_MSG
Definition idx.h:248
#define TXT_CONFIRM_POST
Definition idx.h:105
#define FLD_ALLOW
Definition idx.h:309
#define ACTION_ACCEPT
Definition idx.h:194
#define TXT_MODERATE
Definition idx.h:102
#define MOD_MIME
Definition idx.h:173
#define ACTION_CONFIRM
Definition idx.h:198
#define ACTION_DISCARD
Definition idx.h:199
int issub()
Returns (char *) to match if userhost is in the subscriber database dbname, 0 otherwise....
int quote(stralloc *saout, const stralloc *sain)
Definition quote.c:57
const char auto_version[]
@ CTYPE_TEXT
Definition hdr.h:13
@ CTYPE_MULTIPART
Definition hdr.h:14
@ CTYPE_MESSAGE
Definition hdr.h:16
void wrap_exitcode(int pid)
int wrap_fork(void)
Definition wrap_fork.c:15
void wrap_execbin(const char *program, struct stralloc *opts, const char *dir)
Error messages. If you translate these, I would urge you to keep the English version as well....
#define ERR_NOMEM
Definition errtxt.h:14
#define ERR_NOEXIST
Definition errtxt.h:40
#define ERR_READ_INPUT
Definition errtxt.h:26
#define ERR_MAILING_LIST
Definition errtxt.h:57
#define ERR_READ
Definition errtxt.h:18
#define ERR_LOOPING
Definition errtxt.h:58
#define ERR_NO_POST
Definition errtxt.h:110
#define ERR_QMAIL_QUEUE
Definition errtxt.h:53
#define ERR_SWITCH
Definition errtxt.h:42
#define ERR_WRITE
Definition errtxt.h:17
#define ERR_TMP_QMAIL_QUEUE
Definition errtxt.h:54
#define ERR_BOUNCE
Definition errtxt.h:38
#define ERR_UNIQUE
Definition errtxt.h:109
int lockfile(const char *)
Definition lockfile.c:15
long datetime_sec
Definition datetime.h: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
unsigned long putsubs(const char *dir, unsigned long hash_lo, unsigned long hash_hi, int subwrite(), int flagsql)
Definition putsubs.c:49
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_cptarget(const char *tg)
Definition ezcopy.c:79
void set_cpouthost(const stralloc *ln)
Definition ezcopy.c:73
void set_cpconfirm(const char *cf)
Definition ezcopy.c:89
#define WHO
Definition author.c:1
stralloc mydtline
Definition ezmlm-get.c:72
int act
Definition ezmlm-get.c:119
int flagpublic
Definition ezmlm-get.c:52
int subto(char *s, unsigned int l)
Definition ezmlm-get.c:141
int flagbody
void hdr_from(const char *append)
Definition hdr_from.c:23
char inbuf[1024]
char outbuf[1024]
char * dir
buffer bi
buffer bo
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
int fdlock
Definition ezmlm-cron.c:71
char szchar[2]
Definition ezmlm-gate.c:40
const char * pmod
Definition ezmlm-gate.c:42
char buf[256]
Definition install.c:113
int child
Definition ezmlm-cgi.c:143
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
unsigned int flagmime
Definition ezmlm-cgi.c:145
stralloc subject
Definition ezmlm-cgi.c:119
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
stralloc fnmsg
Definition ezmlm-clean.c:60
char flagcd
Definition ezmlm-clean.c:59
struct qmail qq
Definition ezmlm-clean.c:73
void hdr_transferenc(void)
buffer bs
stralloc reject
char subbuf[256]
stralloc accept
void hdr_add2(const char *start, const char *value, unsigned int len)
Definition hdr_add.c:25
void hdr_add2s(const char *start, const char *value)
Definition hdr_add.c:32
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
void makeacthash(stralloc *act)
int flagself
Definition ezmlm-store.c:50
stralloc action
Definition ezmlm-store.c:84
int subto(char *s, unsigned int l)
int fdmod
Definition ezmlm-store.c:65
int flagconfirm
Definition ezmlm-store.c:53
stralloc moderators
Definition ezmlm-store.c:89
ssize_t qqwrite(int fd, char *buf, unsigned int len)
Definition ezmlm-store.c:95
stralloc confirmpost
Definition ezmlm-store.c:90
stralloc returnpath
Definition ezmlm-store.c:82
int pid
Definition ezmlm-store.c:66
int fdmsg
Definition ezmlm-store.c:64
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