|
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); } |
|
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); } |
|
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); |
|
96 if (!received) die(51); |
|
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)); |
|
126 if (!s) die(51); |
|
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); |
|
139 if (!pidfn) die(51); |
|
140 |
|
141 for (seq = 1;seq < 10;++seq) |
|
142 { |
|
143 if (pidfmt((char *) 0,seq) > len) die(81); /* paranoia */ |
|
144 pidfmt(pidfn,seq); |
|
145 messfd = open_excl(pidfn); |
|
146 if (messfd != -1) return; |
|
147 } |
|
148 |
|
149 die(63); |
|
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); |
|
161 if (chdir(auto_qmail) == -1) die(61); |
|
162 if (chdir("queue") == -1) die(62); |
|
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(); |
|
179 if (fstat(messfd,&pidst) == -1) die(63); |
|
180 |
|
181 messnum = pidst.st_ino; |
|
182 messfn = fnnum("mess/",1); |
|
183 todofn = fnnum("todo/",0); |
|
184 intdfn = fnnum("intd/",0); |
|
185 |
|
186 if (link(pidfn,messfn) == -1) die(64); |
|
187 if (unlink(pidfn) == -1) die(63); |
|
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); |
|
205 if (intdfd == -1) die(65); |
|
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(); |
|
220 if (ch != 'F') die(91); |
|
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 } |
|
228 if (len >= ADDR) die(11); |
|
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; |
|
236 if (ch != 'T') die(91); |
|
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 } |
|
244 if (len >= ADDR) die(11); |
|
245 } |
|
246 |
|
247 if (substdio_flush(&ssout) == -1) die_write(); |
|
248 if (fsync(intdfd) == -1) die_write(); |
|
249 |
|
250 if (link(intdfn,todofn) == -1) die(66); |
|
251 |
|
252 triggerpull(); |
|
253 die(0); |
|
254 } |