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