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