s/qmail 4.3.20
Next generation secure email transport
Loading...
Searching...
No Matches
qmail-todo.c
Go to the documentation of this file.
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <unistd.h>
4#include <string.h>
5#include "alloc.h"
6#include "auto_qmail.h"
7#include "auto_queue.h"
8#include "byte.h"
9#include "constmap.h"
10#include "control.h"
11#include "direntry.h"
12#include "error.h"
13#include "exit.h"
14#include "fmt.h"
15#include "fmtqfn.h"
16#include "getln.h"
17#include "open.h"
18#include "ndelay.h"
19#include "now.h"
20#include "readsubdir.h"
21#include "buffer.h"
22#include "scan.h"
23#include "select.h"
24#include "str.h"
25#include "sig.h"
26#include "stralloc.h"
27#include "trigger.h"
28#include "qsutil.h"
29#include "sendtodo.h"
30#include "qmail.h"
31
32stralloc queuedir = {0};
33
34stralloc percenthack = {0};
36stralloc locals = {0};
38stralloc vdoms = {0};
40stralloc envnoathost = {0};
41
42char strnum[FMT_ULONG];
43
44/* XXX not good, if qmail-send.c changes this has to be updated */
45#define CHANNELS 2
46#define BUF_CHANNELS 1024
47char *chanaddr[CHANNELS] = { "local/", "remote/" };
48
51
52void sendlog1(char *x);
53void sendlog3(char *x,char *y,char *z);
54
55void sigterm(void)
56{
57 if (flagquitasap == 0)
58 sendlog1("status: qmail-todo stop processing asap\n");
59 flagquitasap = 1;
60}
61
62int flagreadasap = 0; void sighup(void) { flagreadasap = 1; }
63int flagsendalive = 1; void senddied(void) { flagsendalive = 0; }
64
66{
67 sendlog1("alert: qmail-todo lost connection to qmail-clean ... exiting\n");
68 flagquitasap = 1;
69}
70
71
72/* this file is not so long ------------------------------------- FILENAMES */
73
74stralloc fn = {0};
75
76void fnmake_init(void)
77{
78 while (!stralloc_ready(&fn,FMTQFN)) nomem();
79}
80
81void fnmake_info(unsigned long id) { fn.len = fmtqfn(fn.s,"info/",id,1); }
82void fnmake_todo(unsigned long id) { fn.len = fmtqfn(fn.s,"todo/",id,1); }
83void fnmake_mess(unsigned long id) { fn.len = fmtqfn(fn.s,"mess/",id,1); }
84void fnmake_chanaddr(unsigned long id,int c) { fn.len = fmtqfn(fn.s,chanaddr[c],id,1); }
85
86
87/* this file is not so long ------------------------------------- REWRITING */
88
89stralloc rwline = {0};
90
91/* 1 if by land, 2 if by sea, 0 if out of memory. not allowed to barf. */
92/* may trash recip. must set up rwline, between a T and a \0. */
93
94int rewrite(char *recip)
95{
96 int i;
97 int j;
98 char *x;
99 static stralloc addr = {0};
100 int at;
101
102 if (!stralloc_copys(&rwline,"T")) return 0;
103 if (!stralloc_copys(&addr,recip)) return 0;
104
105 i = byte_rchr(addr.s,addr.len,'@');
106 if (i == addr.len) {
107 if (!stralloc_cats(&addr,"@")) return 0;
108 if (!stralloc_cat(&addr,&envnoathost)) return 0;
109 }
110
111 while (constmap(&mappercenthack,addr.s + i + 1,addr.len - i - 1)) {
112 j = byte_rchr(addr.s,i,'%');
113 if (j == i) break;
114 addr.len = i;
115 i = j;
116 addr.s[i] = '@';
117 }
118
119 at = byte_rchr(addr.s,addr.len,'@');
120
121 if (constmap(&maplocals,addr.s + at + 1,addr.len - at - 1)) {
122 if (!stralloc_cat(&rwline,&addr)) return 0;
123 if (!stralloc_0(&rwline)) return 0;
124 return 1;
125 }
126
127 for (i = 0; i <= addr.len; ++i)
128 if (!i || (i == at + 1) || (i == addr.len) || ((i > at) && (addr.s[i] == '.')))
129 if ((x = constmap(&mapvdoms,addr.s + i,addr.len - i))) {
130 if (!*x) break;
131 if (!stralloc_cats(&rwline,x)) return 0;
132 if (!stralloc_cats(&rwline,"-")) return 0;
133 if (!stralloc_cat(&rwline,&addr)) return 0;
134 if (!stralloc_0(&rwline)) return 0;
135 return 1;
136 }
137
138 if (!stralloc_cat(&rwline,&addr)) return 0;
139 if (!stralloc_0(&rwline)) return 0;
140 return 2;
141}
142
143/* this file is not so long --------------------------------- COMMUNICATION */
144
145buffer toqc;
147buffer fromqc;
149stralloc comm_buf = {0};
151int fdout = -1;
152int fdin = -1;
153
154void sendlog1(char* x)
155{
156 int pos;
157
158 pos = comm_buf.len;
159 if (!stralloc_cats(&comm_buf,"L")) goto FAIL;
160 if (!stralloc_cats(&comm_buf,x)) goto FAIL;
161 if (!stralloc_0(&comm_buf)) goto FAIL;
162 return;
163
164 FAIL:
165 /* either all or nothing */
166 comm_buf.len = pos;
167}
168
169void sendlog3(char* x, char *y, char *z)
170{
171 int pos;
172
173 pos = comm_buf.len;
174 if (!stralloc_cats(&comm_buf,"L")) goto FAIL;
175 if (!stralloc_cats(&comm_buf,x)) goto FAIL;
176 if (!stralloc_cats(&comm_buf,y)) goto FAIL;
177 if (!stralloc_cats(&comm_buf,z)) goto FAIL;
178 if (!stralloc_0(&comm_buf)) goto FAIL;
179 return;
180
181 FAIL:
182 /* either all or nothing */
183 comm_buf.len = pos;
184}
185
186void comm_init(void)
187{
188 buffer_init(&toqc,buffer_unixwrite,2,toqcbuf,sizeof(toqcbuf));
189 buffer_init(&fromqc,buffer_unixread,3,fromqcbuf,sizeof(fromqcbuf));
190
191 fdout = 1; /* stdout */
192 fdin = 0; /* stdin */
193 if (ndelay_on(fdout) == -1)
194 /* this is so stupid: NDELAY semantics should be default on write */
195 senddied(); /* drastic, but better than risking deadlock */
196
197 while (!stralloc_ready(&comm_buf,BUF_CHANNELS)) nomem();
198}
199
201{
202 /* XXX: could allow a bigger buffer; say 10 recipients */
203 /* XXX: returns true if there is something in the buffer */
204 if (!flagsendalive) return 0;
205 if (comm_buf.s && comm_buf.len) return 1;
206 return 0;
207}
208
209void comm_write(unsigned long id,int local,int remote)
210{
211 int pos;
212 char *s;
213
214 if (local && remote) s="B";
215 else if (local) s="L";
216 else if (remote) s="R";
217 else s="X";
218
219 pos = comm_buf.len;
220 strnum[fmt_ulong(strnum,id)] = 0;
221 if (!stralloc_cats(&comm_buf,"D")) goto FAIL;
222 if (!stralloc_cats(&comm_buf,s)) goto FAIL;
223 if (!stralloc_cats(&comm_buf,strnum)) goto FAIL;
224 if (!stralloc_0(&comm_buf)) goto FAIL;
225 return;
226
227 FAIL:
228 /* either all or nothing */
229 comm_buf.len = pos;
230}
231
232void comm_info(unsigned long id,unsigned long size,char* from,unsigned long pid,unsigned long uid)
233{
234 int pos;
235 int i;
236
237 pos = comm_buf.len;
238 if (!stralloc_cats(&comm_buf,"Linfo msg ")) goto FAIL;
239 strnum[fmt_ulong(strnum,id)] = 0;
240 if (!stralloc_cats(&comm_buf,strnum)) goto FAIL;
241 if (!stralloc_cats(&comm_buf,": bytes ")) goto FAIL;
242 strnum[fmt_ulong(strnum,size)] = 0;
243 if (!stralloc_cats(&comm_buf,strnum)) goto FAIL;
244 if (!stralloc_cats(&comm_buf," from <")) goto FAIL;
245 i = comm_buf.len;
246 if (!stralloc_cats(&comm_buf,from)) goto FAIL;
247
248 for (; i < comm_buf.len; ++i)
249 if (comm_buf.s[i] == '\n')
250 comm_buf.s[i] = '/';
251 else
252 if (!issafe(comm_buf.s[i]))
253 comm_buf.s[i] = '_';
254
255 if (!stralloc_cats(&comm_buf,"> qp ")) goto FAIL;
256 strnum[fmt_ulong(strnum,pid)] = 0;
257 if (!stralloc_cats(&comm_buf,strnum)) goto FAIL;
258 if (!stralloc_cats(&comm_buf," uid ")) goto FAIL;
259 strnum[fmt_ulong(strnum,uid)] = 0;
260 if (!stralloc_cats(&comm_buf,strnum)) goto FAIL;
261 if (!stralloc_cats(&comm_buf,"\n")) goto FAIL;
262 if (!stralloc_0(&comm_buf)) goto FAIL;
263 return;
264
265 FAIL:
266 /* either all or nothing */
267 comm_buf.len = pos;
268}
269
270void comm_exit(void)
271{
272 /* if it FAILs exit, we have already stoped */
273 if (!stralloc_cats(&comm_buf,"X")) _exit(1);
274 if (!stralloc_0(&comm_buf)) _exit(1);
275}
276
277void comm_selprep(int *nfds, fd_set *wfds, fd_set *rfds)
278{
279 if (flagsendalive) {
280 if (flagquitasap && comm_canwrite() == 0)
281 comm_exit();
282 if (comm_canwrite()) {
283 FD_SET(fdout,wfds);
284 if (*nfds <= fdout)
285 *nfds = fdout + 1;
286 }
287 FD_SET(fdin,rfds);
288 if (*nfds <= fdin)
289 *nfds = fdin + 1;
290 }
291}
292
293void comm_do(fd_set *wfds, fd_set *rfds)
294{
295 /* first write then read */
296 if (flagsendalive)
297 if (comm_canwrite())
298 if (FD_ISSET(fdout,wfds)) {
299 int w;
300 int len;
301 len = comm_buf.len;
302 w = write(fdout,comm_buf.s + comm_pos,len - comm_pos);
303 if (w <= 0) {
304 if ((w == -1) && (errno == EPIPE))
305 senddied();
306 } else {
307 comm_pos += w;
308 if (comm_pos == len) {
309 comm_buf.len = 0;
310 comm_pos = 0;
311 }
312 }
313 }
314 if (flagsendalive)
315 if (FD_ISSET(fdin,rfds)) {
316 /* there are only two messages 'H' and 'X' */
317 char c;
318 int r;
319 r = read(fdin, &c, 1);
320 if (r <= 0) {
321 if ((r == -1) && (errno != EINTR))
322 senddied();
323 } else {
324 switch (c) {
325 case 'H':
326 sighup();
327 break;
328 case 'X':
329 sigterm();
330 break;
331 default:
332 sendlog1("warning: qmail-todo: qmail-send speaks an obscure dialect\n");
333 break;
334 }
335 }
336 }
337}
338
339/* this file is not so long ------------------------------------------ TODO */
340
342int flagtododir; /* if 0, have to opendir again */
344stralloc todoline = {0};
348
349void todo_init(void)
350{
351 flagtododir = 0;
352 nexttodorun = now();
353 trigger_set();
354}
355
356void todo_selprep(int *nfds, fd_set *rfds, datetime_sec *wakeup)
357{
358 if (flagquitasap) return;
359 trigger_selprep(nfds,rfds);
360 if (flagtododir) *wakeup = 0;
361 if (*wakeup > nexttodorun) *wakeup = nexttodorun;
362}
363
364void todo_do(fd_set *rfds)
365{
366 struct stat st;
367 buffer bi;
368 int fd;
369 buffer bo;
370 int fdnumber;
371 buffer bchan[CHANNELS];
372 int fdchan[CHANNELS];
373 int flagchan[CHANNELS];
374 char ch;
375 int match;
376 unsigned long id;
377 int c;
378 unsigned long uid;
379 unsigned long pid;
380
381 fd = -1;
382 fdnumber = -1;
383 for (c = 0; c < CHANNELS; ++c)
384 fdchan[c] = -1;
385
386 if (flagquitasap) return;
387
388 if (!flagtododir) {
389 if (!trigger_pulled(rfds)) {
390 if (recent < nexttodorun) return;
391 }
392 trigger_set();
394 flagtododir = 1;
396 }
397
398 switch (readsubdir_next(&todosubdir,&id)) {
399 case 1: break;
400 case 0: flagtododir = 0;
401 default: return;
402 }
403
404 fnmake_todo(id);
405
406 fd = open_read(fn.s);
407 if (fd == -1)
408 { sendlog3("warning: qmail-todo is unable to open ",fn.s,"\n"); return; }
409
410 fnmake_mess(id);
411 /* just for the statistics */
412 if (stat(fn.s,&st) == -1)
413 { sendlog3("warning: qmail-todo is unable to stat ",fn.s," for mess\n"); goto FAIL; }
414
415 for (c = 0; c < CHANNELS; ++c) {
416 fnmake_chanaddr(id,c);
417 if (unlink(fn.s) == -1) if (errno != ENOENT)
418 { sendlog3("warning: qmail-todo is unable to unlink ",fn.s," for mess\n"); goto FAIL; }
419 }
420
421 fnmake_info(id);
422 if (unlink(fn.s) == -1) if (errno != ENOENT)
423 { sendlog3("warning: qmail-todo is unable to unlink ",fn.s," for info\n"); goto FAIL; }
424
425 fdnumber = open_excl(fn.s);
426 if (fdnumber == -1)
427 { sendlog3("warning: qmail-todo unable to create ",fn.s," for info\n"); goto FAIL; }
428
429 strnum[fmt_ulong(strnum,id)] = 0;
430 sendlog3("new msg ",strnum,"\n");
431
432 for (c = 0; c < CHANNELS; ++c)
433 flagchan[c] = 0;
434
435 buffer_init(&bi,buffer_unixread,fd,todobuf,sizeof(todobuf));
436 buffer_init(&bo,buffer_unixwrite,fdnumber,todobufinfo,sizeof(todobufinfo));
437
438 uid = 0;
439 pid = 0;
440
441 for (;;) {
442 if (getln(&bi,&todoline,&match,'\0') == -1) {
443 /* perhaps we're out of memory, perhaps an I/O error */
444 fnmake_todo(id);
445 sendlog3("warning: qmail-todo has trouble reading ",fn.s,"\n"); goto FAIL;
446 }
447 if (!match) break;
448
449 switch (todoline.s[0]) {
450 case 'u':
451 scan_ulong(todoline.s + 1,&uid); break;
452 case 'p':
453 scan_ulong(todoline.s + 1,&pid); break;
454 case 'F':
455 if (buffer_putflush(&bo,todoline.s,todoline.len) == -1) {
456 fnmake_info(id);
457 sendlog3("warning: qmail-todo has trouble writing to ",fn.s," for todo\n"); goto FAIL;
458 }
459 comm_info(id,(unsigned long) st.st_size,todoline.s + 1,pid,uid);
460 break;
461 case 'T':
462 switch (rewrite(todoline.s + 1)) {
463 case 0: nomem(); goto FAIL;
464 case 2: c = 1; break;
465 default: c = 0; break;
466 }
467 if (fdchan[c] == -1) {
468 fnmake_chanaddr(id,c);
469 fdchan[c] = open_excl(fn.s);
470 if (fdchan[c] == -1)
471 { sendlog3("warning: qmail-todo is unable to create ",fn.s," for delivery\n"); goto FAIL; }
472 buffer_init(&bchan[c],buffer_unixwrite,fdchan[c],todobufchan[c],sizeof(todobufchan[c]));
473 flagchan[c] = 1;
474 }
475 if (buffer_put(&bchan[c],rwline.s,rwline.len) == -1) {
476 fnmake_chanaddr(id,c);
477 sendlog3("warning: qmail-todo has trouble writing to ",fn.s," for delivery\n"); goto FAIL;
478 }
479 break;
480 default:
481 fnmake_todo(id);
482 sendlog3("warning: qmail-todo recognizes unknown record type in ",fn.s,"\n"); goto FAIL;
483 }
484 }
485
486 close(fd); fd = -1;
487
488 fnmake_info(id);
489 if (buffer_flush(&bo) == -1)
490 { sendlog3("warning: qmail-todo has trouble writing to ",fn.s," for info\n"); goto FAIL; }
491 if (fsync(fdnumber) == -1)
492 { sendlog3("warning: qmail-todo has trouble fsyncing ",fn.s," for info\n"); goto FAIL; }
493 close(fdnumber); fdnumber = -1;
494
495 for (c = 0; c < CHANNELS; ++c)
496 if (fdchan[c] != -1) {
497 fnmake_chanaddr(id,c);
498 if (buffer_flush(&bchan[c]) == -1)
499 { sendlog3("warning: qmail-todo has trouble writing to ",fn.s," in channel\n"); goto FAIL; }
500 if (fsync(fdchan[c]) == -1)
501 { sendlog3("warning: qmail-todo has trouble fsyncing ",fn.s," in channel\n"); goto FAIL; }
502 close(fdchan[c]); fdchan[c] = -1;
503 }
504
505 fnmake_todo(id);
506 if (buffer_putflush(&toqc,fn.s,fn.len) == -1) { cleandied(); return; }
507 if (buffer_get(&fromqc,&ch,1) != 1) { cleandied(); return; }
508
509 if (ch != '+') {
510 sendlog3("warning: qmail-clean unable to clean up ",fn.s,"\n");
511 return;
512 }
513
514 comm_write(id,flagchan[0],flagchan[1]);
515 return;
516
517 FAIL:
518 if (fd != -1) close(fd);
519 if (fdnumber != -1) close(fdnumber);
520 for (c = 0; c < CHANNELS; ++c)
521 if (fdchan[c] != -1) close(fdchan[c]);
522}
523
524/* this file is too long ---------------------------------------------- MAIN */
525
526int getcontrols(void)
527{
528 if (control_init() == -1) return 0;
529 if (control_rldef(&envnoathost,"control/envnoathost",1,"envnoathost") != 1) return 0;
530 if (control_readfile(&locals,"control/locals",1) != 1) return 0;
531 if (!constmap_init(&maplocals,locals.s,locals.len,0)) return 0;
532 switch (control_readfile(&percenthack,"control/percenthack",0)) {
533 case -1: return 0;
534 case 0: if (!constmap_init(&mappercenthack,"",0,0)) return 0; break;
535 case 1: if (!constmap_init(&mappercenthack,percenthack.s,percenthack.len,0)) return 0; break;
536 }
537 switch (control_readfile(&vdoms,"control/virtualdomains",0)) {
538 case -1: return 0;
539 case 0: if (!constmap_init(&mapvdoms,"",0,1)) return 0; break;
540 case 1: if (!constmap_init(&mapvdoms,vdoms.s,vdoms.len,1)) return 0; break;
541 }
542 return 1;
543}
544
545stralloc newlocals = {0};
546stralloc newvdoms = {0};
547
549{
550 int r;
551
552 if (control_readfile(&newlocals,"control/locals",1) != 1)
553 { sendlog1("alert: qmail-todo is unable to reread control/locals\n"); return; }
554
555 r = control_readfile(&newvdoms,"control/virtualdomains",0);
556 if (r == -1)
557 { sendlog1("alert: qmail-todo is unable to reread control/virtualdomains\n"); return; }
558
561
562 while (!stralloc_copy(&locals,&newlocals)) nomem();
563 while (!constmap_init(&maplocals,locals.s,locals.len,0)) nomem();
564
565 if (r) {
566 while (!stralloc_copy(&vdoms,&newvdoms)) nomem();
567 while (!constmap_init(&mapvdoms,vdoms.s,vdoms.len,1)) nomem();
568 }
569 else
570 while (!constmap_init(&mapvdoms,"",0,1)) nomem();
571}
572
573void reread(void)
574{
575 if (chdir(auto_qmail) == -1) {
576 sendlog1("alert: qmail-todo is unable to reread controls: unable to switch to home directory\n");
577 return;
578 }
579
581
582 while (chdir(queuedir.s) == -1) {
583 sendlog1("alert: qmail-todo is unable to switch back to queue directory; HELP! sleeping...\n");
584 sleep(10);
585 }
586}
587
588int main()
589{
590 datetime_sec wakeup;
591 fd_set rfds;
592 fd_set wfds;
593 int nfds;
594 struct timeval tv;
595 int r;
596 char c;
597
599 if (!stralloc_cats(&queuedir,"/queue")) _exit(110);
600 if (!stralloc_0(&queuedir)) _exit(110);
601
602 if (chdir(auto_qmail) == -1)
603 { sendlog1("alert: qmail-todo cannot start and switch to home directory\n"); _exit(110); }
604 if (!getcontrols())
605 { sendlog1("alert: qmail-todo cannot start and read controls\n"); _exit(112); }
606 if (chdir(queuedir.s) == -1)
607 { sendlog1("alert: qmail-todo cannot start and switch to queue directory\n"); _exit(110); }
608 sig_pipeignore();
609 umask(077);
610
611 fnmake_init();
612 todo_init();
613 comm_init();
614
615 do {
616 r = read(fdin, &c, 1);
617 if ((r == -1) && (errno != EINTR))
618 _exit(100); /* read failed probably qmail-send died */
619 } while ((r =! 1)); /* we assume it is a 'S' */
620
621 for (;;) {
622 recent = now();
623 if (flagreadasap) { flagreadasap = 0; reread(); }
624 if (!flagsendalive) {
625 /* qmail-send finaly exited, so do the same. */
626 if (flagquitasap) _exit(0);
627 /* qmail-send died. We can not log and we can not work therefor _exit(1). */
628 _exit(1);
629 }
630
631 wakeup = recent + SLEEP_FOREVER;
632 FD_ZERO(&rfds);
633 FD_ZERO(&wfds);
634 nfds = 1;
635
636 todo_selprep(&nfds,&rfds,&wakeup);
637 comm_selprep(&nfds,&wfds,&rfds);
638
639 if (wakeup <= recent) tv.tv_sec = 0;
640 else tv.tv_sec = wakeup - recent + SLEEP_FUZZ;
641 tv.tv_usec = 0;
642
643 if (select(nfds,&rfds,&wfds,(fd_set *) 0,&tv) == -1)
644 if (errno == EINTR)
645 ;
646 else
647 sendlog1("warning: qmail-todo has trouble in select\n");
648 else {
649 recent = now();
650
651 todo_do(&rfds);
652 comm_do(&wfds, &rfds);
653 }
654 }
655 /* NOTREACHED */
656 _exit(1);
657}
658
char auto_qmail[]
char auto_queue[]
void nomem()
Definition: columnt.c:15
buffer bo
Definition: columnt.c:13
buffer bi
Definition: condredirect.c:23
void constmap_free(struct constmap *cm)
Definition: constmap.c:161
int constmap_init(struct constmap *cm, char *s, int len, int flagcolon)
Definition: constmap.c:35
int control_rldef(stralloc *sa, char *fn, int flagme, char *def)
Definition: control.c:42
int control_readfile(stralloc *sa, char *fn, int flagme)
Definition: control.c:87
int control_init(void)
Definition: control.c:33
long datetime_sec
Definition: datetime.h:15
int stralloc_copys(stralloc *, char const *)
void _exit(int)
unsigned int fmtqfn(char *s, char *dirslash, unsigned long id, int flagsplit)
Definition: fmtqfn.c:5
#define FMTQFN
Definition: fmtqfn.h:6
void z(char *, char *, int, int, int, int)
Definition: install.c:111
void c(char *, char *, char *, int, int, int)
Definition: install.c:67
int match
Definition: matchup.c:196
ulongalloc uid
Definition: matchup.c:59
datetime_sec now()
Definition: now.c:5
int fd
char * local
Definition: qmail-getpw.c:18
int remote
Definition: qmail-mrtg.c:28
unsigned long size
Definition: qmail-qread.c:56
unsigned long id
Definition: qmail-qread.c:53
stralloc recip
Definition: qmail-remote.c:101
int j
Definition: qmail-send.c:926
stralloc addr
Definition: qmail-smtpd.c:529
datetime_sec recent
Definition: qmail-todo.c:49
char todobufinfo[BUFSIZE_OUT]
Definition: qmail-todo.c:346
void sendlog1(char *x)
Definition: qmail-todo.c:154
void cleandied()
Definition: qmail-todo.c:65
void sighup(void)
Definition: qmail-todo.c:62
stralloc comm_buf
Definition: qmail-todo.c:149
int getcontrols(void)
Definition: qmail-todo.c:526
readsubdir todosubdir
Definition: qmail-todo.c:343
#define CHANNELS
Definition: qmail-todo.c:45
int flagreadasap
Definition: qmail-todo.c:62
char todobufchan[CHANNELS][BUF_CHANNELS]
Definition: qmail-todo.c:347
void fnmake_todo(unsigned long id)
Definition: qmail-todo.c:82
void fnmake_info(unsigned long id)
Definition: qmail-todo.c:81
#define BUF_CHANNELS
Definition: qmail-todo.c:46
buffer toqc
Definition: qmail-todo.c:145
stralloc fn
Definition: qmail-todo.c:74
int comm_pos
Definition: qmail-todo.c:150
char * chanaddr[CHANNELS]
Definition: qmail-todo.c:47
stralloc queuedir
Definition: qmail-todo.c:32
char strnum[FMT_ULONG]
Definition: qmail-todo.c:42
stralloc vdoms
Definition: qmail-todo.c:38
void todo_init(void)
Definition: qmail-todo.c:349
int rewrite(char *recip)
Definition: qmail-todo.c:94
char todobuf[BUFSIZE_MESS]
Definition: qmail-todo.c:345
int fdin
Definition: qmail-todo.c:152
void comm_init(void)
Definition: qmail-todo.c:186
void comm_write(unsigned long id, int local, int remote)
Definition: qmail-todo.c:209
datetime_sec nexttodorun
Definition: qmail-todo.c:341
void comm_exit(void)
Definition: qmail-todo.c:270
stralloc envnoathost
Definition: qmail-todo.c:40
stralloc todoline
Definition: qmail-todo.c:344
void regetcontrols(void)
Definition: qmail-todo.c:548
stralloc locals
Definition: qmail-todo.c:36
char toqcbuf[BUFSIZE_LINE]
Definition: qmail-todo.c:146
int fdout
Definition: qmail-todo.c:151
stralloc percenthack
Definition: qmail-todo.c:34
char fromqcbuf[BUFSIZE_LINE]
Definition: qmail-todo.c:148
struct constmap mappercenthack
Definition: qmail-todo.c:35
void fnmake_mess(unsigned long id)
Definition: qmail-todo.c:83
void todo_do(fd_set *rfds)
Definition: qmail-todo.c:364
int flagtododir
Definition: qmail-todo.c:342
stralloc newlocals
Definition: qmail-todo.c:545
stralloc rwline
Definition: qmail-todo.c:89
void comm_do(fd_set *wfds, fd_set *rfds)
Definition: qmail-todo.c:293
void sigterm(void)
Definition: qmail-todo.c:55
int comm_canwrite(void)
Definition: qmail-todo.c:200
buffer fromqc
Definition: qmail-todo.c:147
void todo_selprep(int *nfds, fd_set *rfds, datetime_sec *wakeup)
Definition: qmail-todo.c:356
void comm_info(unsigned long id, unsigned long size, char *from, unsigned long pid, unsigned long uid)
Definition: qmail-todo.c:232
stralloc newvdoms
Definition: qmail-todo.c:546
void reread(void)
Definition: qmail-todo.c:573
int flagsendalive
Definition: qmail-todo.c:63
struct constmap maplocals
Definition: qmail-todo.c:37
void fnmake_chanaddr(unsigned long id, int c)
Definition: qmail-todo.c:84
void senddied(void)
Definition: qmail-todo.c:63
int main()
Definition: qmail-todo.c:588
void comm_selprep(int *nfds, fd_set *wfds, fd_set *rfds)
Definition: qmail-todo.c:277
void fnmake_init(void)
Definition: qmail-todo.c:76
void sendlog3(char *x, char *y, char *z)
Definition: qmail-todo.c:169
int flagquitasap
Definition: qmail-todo.c:50
struct constmap mapvdoms
Definition: qmail-todo.c:39
#define BUFSIZE_MESS
Definition: qmail.h:7
#define BUFSIZE_LINE
Definition: qmail.h:8
#define BUFSIZE_OUT
Definition: qmail.h:10
void pausedir(char *)
Definition: qsutil.c:58
int issafe(char)
Definition: qsutil.c:64
void readsubdir_init(readsubdir *, char *, void(*)())
Definition: readsubdir.c:7
int readsubdir_next(readsubdir *, unsigned long *)
Definition: readsubdir.c:17
#define SLEEP_FOREVER
Definition: sendtodo.h:9
#define SLEEP_TODO
Definition: sendtodo.h:7
#define SLEEP_FUZZ
Definition: sendtodo.h:8
void write()
void trigger_set(void)
Definition: trigger.c:9
void trigger_selprep(int *, fd_set *)
Definition: trigger.c:15
int trigger_pulled(fd_set *)
Definition: trigger.c:23