Commit | Line | Data |
---|---|---|
2117e02e MW |
1 | #include <sys/types.h> |
2 | #include <sys/stat.h> | |
3 | #include "readwrite.h" | |
4 | #include "sig.h" | |
5 | #include "exit.h" | |
6 | #include "open.h" | |
7 | #include "seek.h" | |
8 | #include "fmt.h" | |
9 | #include "alloc.h" | |
10 | #include "substdio.h" | |
11 | #include "datetime.h" | |
12 | #include "now.h" | |
13 | #include "triggerpull.h" | |
14 | #include "extra.h" | |
15 | #include "auto_qmail.h" | |
16 | #include "auto_uids.h" | |
17 | #include "date822fmt.h" | |
18 | #include "fmtqfn.h" | |
19 | ||
20 | #define DEATH 86400 /* 24 hours; _must_ be below q-s's OSSIFIED (36 hours) */ | |
21 | #define ADDR 1003 | |
22 | ||
23 | char inbuf[2048]; | |
24 | struct substdio ssin; | |
25 | char outbuf[256]; | |
26 | struct substdio ssout; | |
27 | ||
28 | datetime_sec starttime; | |
29 | struct datetime dt; | |
30 | unsigned long mypid; | |
31 | unsigned long uid; | |
32 | char *pidfn; | |
33 | struct stat pidst; | |
34 | unsigned long messnum; | |
35 | char *messfn; | |
36 | char *todofn; | |
37 | char *intdfn; | |
38 | int messfd; | |
39 | int intdfd; | |
40 | int flagmademess = 0; | |
41 | int flagmadeintd = 0; | |
42 | ||
43 | void cleanup() | |
44 | { | |
45 | if (flagmadeintd) | |
46 | { | |
47 | seek_trunc(intdfd,0); | |
48 | if (unlink(intdfn) == -1) return; | |
49 | } | |
50 | if (flagmademess) | |
51 | { | |
52 | seek_trunc(messfd,0); | |
53 | if (unlink(messfn) == -1) return; | |
54 | } | |
55 | } | |
56 | ||
57 | void die(e) int e; { _exit(e); } | |
212b6f5d MW |
58 | void die_write() { cleanup(); die(53); } |
59 | void die_read() { cleanup(); die(54); } | |
60 | void sigalrm() { /* thou shalt not clean up here */ die(52); } | |
61 | void sigbug() { die(81); } | |
2117e02e MW |
62 | |
63 | unsigned int receivedlen; | |
64 | char *received; | |
65 | /* "Received: (qmail-queue invoked by alias); 26 Sep 1995 04:46:54 -0000\n" */ | |
66 | ||
67 | static unsigned int receivedfmt(s) | |
68 | char *s; | |
69 | { | |
70 | unsigned int i; | |
71 | unsigned int len; | |
72 | len = 0; | |
73 | i = fmt_str(s,"Received: (qmail "); len += i; if (s) s += i; | |
74 | i = fmt_ulong(s,mypid); len += i; if (s) s += i; | |
75 | i = fmt_str(s," invoked "); len += i; if (s) s += i; | |
76 | if (uid == auto_uida) | |
77 | { i = fmt_str(s,"by alias"); len += i; if (s) s += i; } | |
78 | else if (uid == auto_uidd) | |
79 | { i = fmt_str(s,"from network"); len += i; if (s) s += i; } | |
80 | else if (uid == auto_uids) | |
81 | { i = fmt_str(s,"for bounce"); len += i; if (s) s += i; } | |
82 | else | |
83 | { | |
84 | i = fmt_str(s,"by uid "); len += i; if (s) s += i; | |
85 | i = fmt_ulong(s,uid); len += i; if (s) s += i; | |
86 | } | |
87 | i = fmt_str(s,"); "); len += i; if (s) s += i; | |
88 | i = date822fmt(s,&dt); len += i; if (s) s += i; | |
89 | return len; | |
90 | } | |
91 | ||
92 | void received_setup() | |
93 | { | |
94 | receivedlen = receivedfmt((char *) 0); | |
95 | received = alloc(receivedlen + 1); | |
212b6f5d | 96 | if (!received) die(51); |
2117e02e MW |
97 | receivedfmt(received); |
98 | } | |
99 | ||
100 | unsigned int pidfmt(s,seq) | |
101 | char *s; | |
102 | unsigned long seq; | |
103 | { | |
104 | unsigned int i; | |
105 | unsigned int len; | |
106 | ||
107 | len = 0; | |
108 | i = fmt_str(s,"pid/"); len += i; if (s) s += i; | |
109 | i = fmt_ulong(s,mypid); len += i; if (s) s += i; | |
110 | i = fmt_str(s,"."); len += i; if (s) s += i; | |
111 | i = fmt_ulong(s,starttime); len += i; if (s) s += i; | |
112 | i = fmt_str(s,"."); len += i; if (s) s += i; | |
113 | i = fmt_ulong(s,seq); len += i; if (s) s += i; | |
114 | ++len; if (s) *s++ = 0; | |
115 | ||
116 | return len; | |
117 | } | |
118 | ||
119 | char *fnnum(dirslash,flagsplit) | |
120 | char *dirslash; | |
121 | int flagsplit; | |
122 | { | |
123 | char *s; | |
124 | ||
125 | s = alloc(fmtqfn((char *) 0,dirslash,messnum,flagsplit)); | |
212b6f5d | 126 | if (!s) die(51); |
2117e02e MW |
127 | fmtqfn(s,dirslash,messnum,flagsplit); |
128 | return s; | |
129 | } | |
130 | ||
131 | void pidopen() | |
132 | { | |
133 | unsigned int len; | |
134 | unsigned long seq; | |
135 | ||
136 | seq = 1; | |
137 | len = pidfmt((char *) 0,seq); | |
138 | pidfn = alloc(len); | |
212b6f5d | 139 | if (!pidfn) die(51); |
2117e02e MW |
140 | |
141 | for (seq = 1;seq < 10;++seq) | |
142 | { | |
212b6f5d | 143 | if (pidfmt((char *) 0,seq) > len) die(81); /* paranoia */ |
2117e02e MW |
144 | pidfmt(pidfn,seq); |
145 | messfd = open_excl(pidfn); | |
146 | if (messfd != -1) return; | |
147 | } | |
148 | ||
212b6f5d | 149 | die(63); |
2117e02e MW |
150 | } |
151 | ||
152 | char tmp[FMT_ULONG]; | |
153 | ||
154 | void main() | |
155 | { | |
156 | unsigned int len; | |
157 | char ch; | |
158 | ||
159 | sig_blocknone(); | |
160 | umask(033); | |
212b6f5d MW |
161 | if (chdir(auto_qmail) == -1) die(61); |
162 | if (chdir("queue") == -1) die(62); | |
2117e02e MW |
163 | |
164 | mypid = getpid(); | |
165 | uid = getuid(); | |
166 | starttime = now(); | |
167 | datetime_tai(&dt,starttime); | |
168 | ||
169 | received_setup(); | |
170 | ||
171 | sig_pipeignore(); | |
172 | sig_miscignore(); | |
173 | sig_alarmcatch(sigalrm); | |
174 | sig_bugcatch(sigbug); | |
175 | ||
176 | alarm(DEATH); | |
177 | ||
178 | pidopen(); | |
212b6f5d | 179 | if (fstat(messfd,&pidst) == -1) die(63); |
2117e02e MW |
180 | |
181 | messnum = pidst.st_ino; | |
182 | messfn = fnnum("mess/",1); | |
183 | todofn = fnnum("todo/",0); | |
184 | intdfn = fnnum("intd/",0); | |
185 | ||
212b6f5d MW |
186 | if (link(pidfn,messfn) == -1) die(64); |
187 | if (unlink(pidfn) == -1) die(63); | |
2117e02e MW |
188 | flagmademess = 1; |
189 | ||
190 | substdio_fdbuf(&ssout,write,messfd,outbuf,sizeof(outbuf)); | |
191 | substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf)); | |
192 | ||
193 | if (substdio_bput(&ssout,received,receivedlen) == -1) die_write(); | |
194 | ||
195 | switch(substdio_copy(&ssout,&ssin)) | |
196 | { | |
197 | case -2: die_read(); | |
198 | case -3: die_write(); | |
199 | } | |
200 | ||
201 | if (substdio_flush(&ssout) == -1) die_write(); | |
202 | if (fsync(messfd) == -1) die_write(); | |
203 | ||
204 | intdfd = open_excl(intdfn); | |
212b6f5d | 205 | if (intdfd == -1) die(65); |
2117e02e MW |
206 | flagmadeintd = 1; |
207 | ||
208 | substdio_fdbuf(&ssout,write,intdfd,outbuf,sizeof(outbuf)); | |
209 | substdio_fdbuf(&ssin,read,1,inbuf,sizeof(inbuf)); | |
210 | ||
211 | if (substdio_bput(&ssout,"u",1) == -1) die_write(); | |
212 | if (substdio_bput(&ssout,tmp,fmt_ulong(tmp,uid)) == -1) die_write(); | |
213 | if (substdio_bput(&ssout,"",1) == -1) die_write(); | |
214 | ||
215 | if (substdio_bput(&ssout,"p",1) == -1) die_write(); | |
216 | if (substdio_bput(&ssout,tmp,fmt_ulong(tmp,mypid)) == -1) die_write(); | |
217 | if (substdio_bput(&ssout,"",1) == -1) die_write(); | |
218 | ||
219 | if (substdio_get(&ssin,&ch,1) < 1) die_read(); | |
212b6f5d | 220 | if (ch != 'F') die(91); |
2117e02e MW |
221 | if (substdio_bput(&ssout,&ch,1) == -1) die_write(); |
222 | for (len = 0;len < ADDR;++len) | |
223 | { | |
224 | if (substdio_get(&ssin,&ch,1) < 1) die_read(); | |
225 | if (substdio_put(&ssout,&ch,1) == -1) die_write(); | |
226 | if (!ch) break; | |
227 | } | |
212b6f5d | 228 | if (len >= ADDR) die(11); |
2117e02e MW |
229 | |
230 | if (substdio_bput(&ssout,QUEUE_EXTRA,QUEUE_EXTRALEN) == -1) die_write(); | |
231 | ||
232 | for (;;) | |
233 | { | |
234 | if (substdio_get(&ssin,&ch,1) < 1) die_read(); | |
235 | if (!ch) break; | |
212b6f5d | 236 | if (ch != 'T') die(91); |
2117e02e MW |
237 | if (substdio_bput(&ssout,&ch,1) == -1) die_write(); |
238 | for (len = 0;len < ADDR;++len) | |
239 | { | |
240 | if (substdio_get(&ssin,&ch,1) < 1) die_read(); | |
241 | if (substdio_bput(&ssout,&ch,1) == -1) die_write(); | |
242 | if (!ch) break; | |
243 | } | |
212b6f5d | 244 | if (len >= ADDR) die(11); |
2117e02e MW |
245 | } |
246 | ||
247 | if (substdio_flush(&ssout) == -1) die_write(); | |
248 | if (fsync(intdfd) == -1) die_write(); | |
249 | ||
212b6f5d | 250 | if (link(intdfn,todofn) == -1) die(66); |
2117e02e MW |
251 | |
252 | triggerpull(); | |
253 | die(0); | |
254 | } |