qmail-qmqpd.c (3325B)
1 #include <unistd.h> 2 #include "auto_qmail.h" 3 #include "qmail.h" 4 #include "received.h" 5 #include "sig.h" 6 #include "substdio.h" 7 #include "readwrite.h" 8 #include "exit.h" 9 #include "now.h" 10 #include "fmt.h" 11 #include "byte.h" 12 #include "env.h" 13 #include "str.h" 14 15 void resources() { _exit(111); } 16 void badproto() { _exit(100); } 17 18 ssize_t safewrite(int fd, const void *buf, size_t len) 19 { 20 ssize_t r; 21 r = write(fd,buf,len); 22 if (r == 0 || r == -1) _exit(0); 23 return r; 24 } 25 ssize_t saferead(int fd, void *buf, size_t len) 26 { 27 ssize_t r; 28 r = read(fd,buf,len); 29 if (r == 0 || r == -1) _exit(0); 30 return r; 31 } 32 33 char ssinbuf[512]; 34 substdio ssin = SUBSTDIO_FDBUF(saferead,0,ssinbuf,sizeof(ssinbuf)); 35 char ssoutbuf[256]; 36 substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof(ssoutbuf)); 37 38 unsigned long bytesleft = 100; 39 40 void getbyte(ch) 41 char *ch; 42 { 43 if (!bytesleft--) _exit(100); 44 substdio_get(&ssin,ch,1); 45 } 46 47 unsigned long getlen() 48 { 49 unsigned long len = 0; 50 char ch; 51 52 for (;;) { 53 getbyte(&ch); 54 if (ch == ':') return len; 55 if (len > 200000000) resources(); 56 if (ch < '0' || ch > '9') badproto(); 57 len = 10 * len + (ch - '0'); 58 } 59 } 60 61 void getcomma() 62 { 63 char ch; 64 getbyte(&ch); 65 if (ch != ',') _exit(100); 66 } 67 68 struct qmail qq; 69 70 void identify() 71 { 72 char *remotehost; 73 char *remoteinfo; 74 char *remoteip; 75 char *local; 76 77 remotehost = env_get("TCPREMOTEHOST"); 78 if (!remotehost) remotehost = "unknown"; 79 remoteinfo = env_get("TCPREMOTEINFO"); 80 remoteip = env_get("TCPREMOTEIP"); 81 if (!remoteip) remoteip = "unknown"; 82 local = env_get("TCPLOCALHOST"); 83 if (!local) local = env_get("TCPLOCALIP"); 84 if (!local) local = "unknown"; 85 86 received(&qq,"QMQP",local,remoteip,remotehost,remoteinfo,NULL); 87 } 88 89 char buf[1000]; 90 char strnum[FMT_ULONG]; 91 92 int getbuf() 93 { 94 unsigned long len; 95 int i; 96 97 len = getlen(); 98 if (len >= 1000) { 99 for (i = 0;i < len;++i) getbyte(buf); 100 getcomma(); 101 buf[0] = 0; 102 return 0; 103 } 104 105 for (i = 0;i < len;++i) getbyte(buf + i); 106 getcomma(); 107 buf[len] = 0; 108 return byte_chr(buf,len,'\0') == len; 109 } 110 111 int flagok = 1; 112 113 int 114 main() 115 { 116 char *result; 117 unsigned long qp; 118 unsigned long len; 119 char ch; 120 121 sig_pipeignore(); 122 sig_alarmcatch(resources); 123 alarm(3600); 124 125 bytesleft = getlen(); 126 127 len = getlen(); 128 129 if (chdir(auto_qmail) == -1) resources(); 130 if (qmail_open(&qq) == -1) resources(); 131 qp = qmail_qp(&qq); 132 identify(); 133 134 while (len > 0) { /* XXX: could speed this up */ 135 getbyte(&ch); 136 --len; 137 qmail_put(&qq,&ch,1); 138 } 139 getcomma(); 140 141 if (getbuf()) 142 qmail_from(&qq,buf); 143 else { 144 qmail_from(&qq,""); 145 qmail_fail(&qq); 146 flagok = 0; 147 } 148 149 while (bytesleft) 150 if (getbuf()) 151 qmail_to(&qq,buf); 152 else { 153 qmail_fail(&qq); 154 flagok = 0; 155 } 156 157 bytesleft = 1; 158 getcomma(); 159 160 result = qmail_close(&qq); 161 162 if (!*result) { 163 len = fmt_str(buf,"Kok "); 164 len += fmt_ulong(buf + len,(unsigned long) now()); 165 len += fmt_str(buf + len," qp "); 166 len += fmt_ulong(buf + len,qp); 167 buf[len] = 0; 168 result = buf; 169 } 170 171 if (!flagok) 172 result = "Dsorry, I can't accept addresses like that (#5.1.3)"; 173 174 substdio_put(&ssout,strnum,fmt_ulong(strnum,(unsigned long) str_len(result))); 175 substdio_puts(&ssout,":"); 176 substdio_puts(&ssout,result); 177 substdio_puts(&ssout,","); 178 substdio_flush(&ssout); 179 _exit(0); 180 }