#include #include #include "fd.h" #include "wait.h" #include "buffer.h" #include "exit.h" #include "error.h" #include "ipalloc.h" #include "tcpto.h" #include "auto_qmail.h" #include "auto_queue.h" #include "open.h" #include "pathexec.h" void initialize(int argc,char **argv) { tcpto_clean(); } int truncreport = 0; void report(buffer *log,int wstat,char *s,int len) { int j; int k; int result; int orr; if (wait_crashed(wstat)) { buffer_putsflush(log,"Zqmail-spawn: qmail-remote crashed.\n"); return; } switch (wait_exitcode(wstat)) { case 0: break; case 111: buffer_putsflush(log,"Zqmail-rspawn: Unable to run qmail-remote.\n"); break; default: buffer_putsflush(log,"Dqmail-rspawn: Unable to run qmail-remote.\n"); return; } if (!len) { buffer_putsflush(log,"Zqmail-rspawn: qmail-remote produced no output.\n"); return; } result = -1; j = 0; for (k = 0; k < len; ++k) if (!s[k]) { if (s[j] == 'K') { result = 1; break; } if (s[j] == 'Z') { result = 0; break; } if (s[j] == 'D') break; j = k + 1; } orr = result; switch (s[0]) { case 's': orr = 0; break; case 'h': orr = -1; } switch (orr) { case 1: buffer_put(log,"K",1); break; case 0: buffer_put(log,"Z",1); break; case -1: buffer_put(log,"D",1); break; } for (k = 1; k < len;) if (!s[k++]) { buffer_puts(log,s + 1); if (result <= orr) if (k < len) switch (s[k]) { case 'Z': case 'D': case 'K': buffer_puts(log,s + k + 1); } break; } } int spawn(int fdmess,int fdout,const char *s,char *r,const int at) { int f; char *(args[5]); struct stat st; if (chdir(auto_qmail) == -1) _exit(61); if (!stat("control/dkimdomains",&st)) args[0] = "qmail-dksign"; else args[0] = "qmail-remote"; args[1] = r + at + 1; args[2] = s; args[3] = r; args[4] = 0; if (chdir(auto_queue) == -1) _exit(62); if (chdir("queue/mess") == -1) _exit(62); if (!(f = vfork())) { if (fd_move(0,fdmess) == -1) _exit(63); if (fd_move(1,fdout) == -1) _exit(63); if (fd_copy(2,1) == -1) _exit(63); pathexec(args); if (errno) _exit(111); _exit(100); } return f; }