summaryrefslogtreecommitdiff
path: root/src/qmail-rspawn.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmail-rspawn.c')
-rw-r--r--src/qmail-rspawn.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/qmail-rspawn.c b/src/qmail-rspawn.c
new file mode 100644
index 0000000..a9b0a1a
--- /dev/null
+++ b/src/qmail-rspawn.c
@@ -0,0 +1,99 @@
+#include <unistd.h>
+#include <sys/stat.h>
+#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 "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(110);
+ if (stat("control/dkimdomains",&st) !=1)
+ 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;
+}