#include #include #include "buffer.h" #include "error.h" #include "exit.h" #include "fd.h" #include "open.h" #include "pathexec.h" #include "wait.h" #include "auto_qmail.h" #include "ipalloc.h" #include "tcpto.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(110); 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("queue/mess") == -1) _exit(110); if (!(f = vfork())) { if (fd_move(0, fdmess) == -1) _exit(111); if (fd_move(1, fdout) == -1) _exit(111); if (fd_copy(2, 1) == -1) _exit(111); pathexec(args); if (errno) _exit(111); _exit(100); } return f; }