qmail-rspawn.c (2349B)
1 #include "fd.h" 2 #include "spawn.h" 3 #include "wait.h" 4 #include "substdio.h" 5 #include "exit.h" 6 #include "fork.h" 7 #include "error.h" 8 #include "tcpto.h" 9 #include "uidgid.h" 10 #include "auto_uids.h" 11 #include "auto_users.h" 12 #include "env.h" 13 14 void initialize(int argc, char **argv) 15 { 16 auto_uidq = inituid(auto_userq); 17 tcpto_clean(); 18 } 19 20 int truncreport = 0; 21 22 void report(substdio *ss, int wstat, char *s, int len) 23 { 24 int j; 25 int k; 26 int result; 27 int orr; 28 29 if (wait_crashed(wstat)) 30 { substdio_puts(ss,"Zqmail-remote crashed.\n"); return; } 31 switch(wait_exitcode(wstat)) 32 { 33 case 0: break; 34 case 111: substdio_puts(ss,"ZUnable to run qmail-remote.\n"); return; 35 default: substdio_puts(ss,"DUnable to run qmail-remote.\n"); return; 36 } 37 if (!len) 38 { substdio_puts(ss,"Zqmail-remote produced no output.\n"); return; } 39 40 result = -1; 41 j = 0; 42 for (k = 0;k < len;++k) 43 if (!s[k]) 44 { 45 if (s[j] == 'I') { result = -2; break; }; // Informational reports have no use to rspawn. In future, they should probably be posted upchain. 46 if (s[j] == 'K') { result = 1; break; } 47 if (s[j] == 'Z') { result = 0; break; } 48 if (s[j] == 'D') break; 49 j = k + 1; 50 } 51 52 orr = result; 53 switch(s[0]) 54 { 55 case 's': orr = 0; break; 56 case 'h': orr = -1; 57 } 58 59 switch(orr) 60 { 61 case 1: substdio_put(ss,"K",1); break; 62 case 0: substdio_put(ss,"Z",1); break; 63 case -1: substdio_put(ss,"D",1); break; 64 case -2: return; // Informational reports have no use to rspawn. In future, they should probably be posted upchain. 65 } 66 67 for (k = 1;k < len;) 68 if (!s[k++]) 69 { 70 substdio_puts(ss,s + 1); 71 if (result <= orr) 72 if (k < len) 73 switch(s[k]) 74 { 75 case 'Z': case 'D': case 'K': 76 substdio_puts(ss,s + k + 1); 77 } 78 break; 79 } 80 } 81 82 static char *setup_qrargs() 83 { 84 static char *qr; 85 if (qr) return qr; 86 qr = env_get("QMAILREMOTE"); 87 if (qr) return qr; 88 qr = "qmail-remote"; 89 return qr; 90 } 91 92 int spawn(int fdmess, int fdout, char *s, char *r, int at) 93 { 94 int f; 95 char *(args[5]); 96 97 args[0] = setup_qrargs(); 98 args[1] = r + at + 1; 99 args[2] = s; 100 args[3] = r; 101 args[4] = 0; 102 103 if (!(f = fork())) 104 { 105 if (fd_move(0,fdmess) == -1) _exit(111); 106 if (fd_move(1,fdout) == -1) _exit(111); 107 if (fd_copy(2,1) == -1) _exit(111); 108 execvp(*args,args); 109 if (error_temp(errno)) _exit(111); 110 _exit(100); 111 } 112 return f; 113 }