s/qmail 4.2.29a
Next generation secure email transport
Loading...
Searching...
No Matches
matchup.c
Go to the documentation of this file.
1#include <unistd.h>
2#include "genalloc.h"
3#include "alloc.h"
4#include "stralloc.h"
5#include "logmsg.h"
6#include "getln.h"
7#include "buffer.h"
8#include "readwrite.h"
9#include "exit.h"
10#include "str.h"
11#include "fmt.h"
12#include "scan.h"
13#include "case.h"
14
15#define WHO "matchup"
16
17void nomem() { logmsg(WHO,111,FATAL,"out of memory"); }
18void die_read() { logmsg(WHO,110,ERROR,"unable to read input: "); }
19void die_write() { logmsg(WHO,110,ERROR,"unable to write output: "); }
20void die_write5() { logmsg(WHO,111,FATAL,"unable to write fd 5: "); }
21
22void out(char *buf,int len)
23{
24 if (buffer_put(buffer_1,buf,len) == -1) die_write();
25}
26void outs(char *buf)
27{
28 if (buffer_puts(buffer_1,buf) == -1) die_write();
29}
30
31char buf5[512];
32buffer bo5 = BUFFER_INIT(write,5,buf5,sizeof(buf5));
33
34void out5(char *buf,int len)
35{
36 if (buffer_put(&bo5,buf,len) == -1)
37 die_write5();
38}
39void outs5(char *buf)
40{
41 if (buffer_puts(&bo5,buf) == -1)
42 die_write5();
43}
44
45GEN_ALLOC_typedef(ulongalloc,unsigned long,u,len,a)
46GEN_ALLOC_ready(ulongalloc,unsigned long,u,len,a,i,n,x,30,ulongalloc_ready)
47GEN_ALLOC_readyplus(ulongalloc,unsigned long,u,len,a,i,n,x,30,ulongalloc_readyplus)
48
49char strnum[FMT_ULONG];
50
51stralloc pool = {0};
52unsigned int poolbytes = 0;
53
54int nummsg = 0;
55ulongalloc msg = {0};
56ulongalloc bytes = {0};
57ulongalloc qp = {0};
58ulongalloc uid = {0};
59ulongalloc numk = {0};
60ulongalloc numd = {0};
61ulongalloc numz = {0};
62ulongalloc sender = {0};
63ulongalloc birth = {0};
64
65int msg_find(unsigned long m)
66{
67 int i;
68 for (i = 0; i < nummsg; ++i)
69 if (msg.u[i] == m) return i;
70 return -1;
71}
72
73int msg_add(unsigned long m)
74{
75 int i;
76 for (i = 0; i < nummsg; ++i)
77 if (msg.u[i] == m) return i;
78 i = nummsg++;
79 if (!ulongalloc_ready(&msg,nummsg)) nomem();
80 if (!ulongalloc_ready(&bytes,nummsg)) nomem();
81 if (!ulongalloc_ready(&qp,nummsg)) nomem();
82 if (!ulongalloc_ready(&uid,nummsg)) nomem();
83 if (!ulongalloc_ready(&numk,nummsg)) nomem();
84 if (!ulongalloc_ready(&numd,nummsg)) nomem();
85 if (!ulongalloc_ready(&numz,nummsg)) nomem();
86 if (!ulongalloc_ready(&sender,nummsg)) nomem();
87 if (!ulongalloc_ready(&birth,nummsg)) nomem();
88 msg.u[i] = m;
89 return i;
90}
91
92void msg_kill(int i)
93{
94 poolbytes -= str_len(pool.s + sender.u[i]) + 1;
95 poolbytes -= str_len(pool.s + birth.u[i]) + 1;
96
97 --nummsg;
98 msg.u[i] = msg.u[nummsg];
99 bytes.u[i] = bytes.u[nummsg];
100 qp.u[i] = qp.u[nummsg];
101 uid.u[i] = uid.u[nummsg];
102 numk.u[i] = numk.u[nummsg];
103 numd.u[i] = numd.u[nummsg];
104 numz.u[i] = numz.u[nummsg];
105 sender.u[i] = sender.u[nummsg];
106 birth.u[i] = birth.u[nummsg];
107}
108
109int numdel = 0;
110ulongalloc del = {0};
111ulongalloc dmsg = {0};
112ulongalloc dchan = {0};
113ulongalloc drecip = {0};
114ulongalloc dstart = {0};
115
116int del_find(unsigned long d)
117{
118 int i;
119 for (i = 0; i < numdel; ++i)
120 if (del.u[i] == d) return i;
121 return -1;
122}
123
124int del_add(unsigned long d)
125{
126 int i;
127 for (i = 0; i < numdel; ++i)
128 if (del.u[i] == d) return i;
129 i = numdel++;
130 if (!ulongalloc_ready(&del,numdel)) nomem();
131 if (!ulongalloc_ready(&dmsg,numdel)) nomem();
132 if (!ulongalloc_ready(&dchan,numdel)) nomem();
133 if (!ulongalloc_ready(&drecip,numdel)) nomem();
134 if (!ulongalloc_ready(&dstart,numdel)) nomem();
135 del.u[i] = d;
136 return i;
137}
138
139void del_kill(int i)
140{
141 poolbytes -= str_len(pool.s + dchan.u[i]) + 1;
142 poolbytes -= str_len(pool.s + drecip.u[i]) + 1;
143 poolbytes -= str_len(pool.s + dstart.u[i]) + 1;
144 --numdel;
145 del.u[i] = del.u[numdel];
146 dmsg.u[i] = dmsg.u[numdel];
147 dchan.u[i] = dchan.u[numdel];
148 drecip.u[i] = drecip.u[numdel];
149 dstart.u[i] = dstart.u[numdel];
150}
151
152stralloc pool2 = {0};
153
155{
156 int i;
157 char *x;
158
159 if (pool.len - poolbytes < poolbytes + 4096) return;
160
161 if (!stralloc_copys(&pool2,"")) nomem();
162
163 for (i = 0; i < nummsg; ++i) {
164 x = pool.s + birth.u[i];
165 birth.u[i] = pool2.len;
166 if (!stralloc_cats(&pool2,x)) nomem();
167 if (!stralloc_0(&pool2)) nomem();
168 x = pool.s + sender.u[i];
169 sender.u[i] = pool2.len;
170 if (!stralloc_cats(&pool2,x)) nomem();
171 if (!stralloc_0(&pool2)) nomem();
172 }
173
174 for (i = 0; i < numdel; ++i) {
175 x = pool.s + dstart.u[i];
176 dstart.u[i] = pool2.len;
177 if (!stralloc_cats(&pool2,x)) nomem();
178 if (!stralloc_0(&pool2)) nomem();
179 x = pool.s + dchan.u[i];
180 dchan.u[i] = pool2.len;
181 if (!stralloc_cats(&pool2,x)) nomem();
182 if (!stralloc_0(&pool2)) nomem();
183 x = pool.s + drecip.u[i];
184 drecip.u[i] = pool2.len;
185 if (!stralloc_cats(&pool2,x)) nomem();
186 if (!stralloc_0(&pool2)) nomem();
187 }
188
189 if (!stralloc_copy(&pool,&pool2)) nomem();
190
191 poolbytes = pool.len; /* redundant, but doesn't hurt */
192}
193
194stralloc line = {0};
196
197#define FIELDS 20
199
200void clear()
201{
202 while (numdel > 0)
203 del_kill(0);
204 garbage();
205}
206
208{
209 unsigned long d;
210 unsigned long m;
211 int dpos;
212
213 scan_ulong(line.s + field[3],&d);
214 scan_ulong(line.s + field[5],&m);
215
216 dpos = del_add(d);
217
218 dmsg.u[dpos] = m;
219
220 dstart.u[dpos] = pool.len;
221 if (!stralloc_cats(&pool,line.s + field[0])) nomem();
222 if (!stralloc_0(&pool)) nomem();
223
224 dchan.u[dpos] = pool.len;
225 if (!stralloc_cats(&pool,line.s + field[7])) nomem();
226 if (!stralloc_0(&pool)) nomem();
227
228 drecip.u[dpos] = pool.len;
229 if (!stralloc_cats(&pool,line.s + field[8])) nomem();
230 if (!stralloc_0(&pool)) nomem();
231 case_lowers(pool.s + drecip.u[dpos]);
232
233 poolbytes += pool.len - dstart.u[dpos];
234}
235
237{
238 unsigned long d;
239 unsigned long m;
240 int dpos;
241 int mpos;
242 char *result = "?";
243 char *reason = "";
244
245 scan_ulong(line.s + field[2],&d);
246
247 dpos = del_find(d);
248 if (dpos == -1) return;
249
250 m = dmsg.u[dpos];
251 mpos = msg_find(m);
252
253 if (str_start(line.s + field[3],"succ")) {
254 if (mpos != -1) ++numk.u[mpos];
255 result = "d k ";
256 reason = line.s + field[4];
257 }
258 else if (str_start(line.s + field[3],"fail")) {
259 if (mpos != -1) ++numd.u[mpos];
260 result = "d d ";
261 reason = line.s + field[4];
262 }
263 else if (str_start(line.s + field[3],"defer")) {
264 if (mpos != -1) ++numz.u[mpos];
265 result = "d z ";
266 reason = line.s + field[4];
267 }
268 else if (str_start(line.s + field[3],"report")) {
269 if (mpos != -1) ++numz.u[mpos];
270 result = "d z ";
271 reason = "report_mangled";
272 }
273
274 outs(result);
275
276 if (mpos != -1) {
277 outs(pool.s + birth.u[mpos]);
278 outs(" "); outs(pool.s + dstart.u[dpos]);
279 outs(" "); outs(line.s + field[0]);
280 outs(" "); out(strnum,fmt_ulong(strnum,bytes.u[mpos]));
281 outs(" "); outs(pool.s + sender.u[mpos]);
282 outs(" "); outs(pool.s + dchan.u[dpos]);
283 outs("."); outs(pool.s + drecip.u[dpos]);
284 outs(" "); out(strnum,fmt_ulong(strnum,qp.u[mpos]));
285 outs(" "); out(strnum,fmt_ulong(strnum,uid.u[mpos]));
286 outs(" "); outs(reason);
287 } else {
288 outs(pool.s + dstart.u[dpos]);
289 outs(" "); outs(pool.s + dstart.u[dpos]);
290 outs(" "); outs(line.s + field[0]);
291 outs(" 0 ? "); outs(pool.s + dchan.u[dpos]);
292 outs("."); outs(pool.s + drecip.u[dpos]);
293 outs(" ? ? "); outs(reason);
294 }
295
296 outs("\n");
297
298 del_kill(dpos);
299 garbage();
300}
301
302void newmsg()
303{
304 unsigned long m;
305 int mpos;
306
307 scan_ulong(line.s + field[3],&m);
308 mpos = msg_find(m);
309 if (mpos == -1) return;
310 msg_kill(mpos);
311 garbage();
312}
313
314void endmsg()
315{
316 unsigned long m;
317 int mpos;
318
319 scan_ulong(line.s + field[3],&m);
320 mpos = msg_find(m);
321 if (mpos == -1) return;
322
323 outs("m "); outs(pool.s + birth.u[mpos]);
324 outs(" "); outs(line.s + field[0]);
325 outs(" "); out(strnum,fmt_ulong(strnum,bytes.u[mpos]));
326 outs(" "); out(strnum,fmt_ulong(strnum,numk.u[mpos]));
327 outs(" "); out(strnum,fmt_ulong(strnum,numd.u[mpos]));
328 outs(" "); out(strnum,fmt_ulong(strnum,numz.u[mpos]));
329 outs(" "); outs(pool.s + sender.u[mpos]);
330 outs(" "); out(strnum,fmt_ulong(strnum,qp.u[mpos]));
331 outs(" "); out(strnum,fmt_ulong(strnum,uid.u[mpos]));
332 outs("\n");
333
334 msg_kill(mpos);
335 garbage();
336}
337
338void info()
339{
340 unsigned long m;
341 int mpos;
342
343 scan_ulong(line.s + field[3],&m);
344 mpos = msg_add(m);
345
346 scan_ulong(line.s + field[5],&bytes.u[mpos]);
347 scan_ulong(line.s + field[9],&qp.u[mpos]);
348 scan_ulong(line.s + field[11],&uid.u[mpos]);
349
350 numk.u[mpos] = 0;
351 numd.u[mpos] = 0;
352 numz.u[mpos] = 0;
353
354 birth.u[mpos] = pool.len;
355 if (!stralloc_cats(&pool,line.s + field[0])) nomem();
356 if (!stralloc_0(&pool)) nomem();
357
358 sender.u[mpos] = pool.len;
359 if (!stralloc_cats(&pool,line.s + field[7])) nomem();
360 if (!stralloc_0(&pool)) nomem();
361 case_lowers(pool.s + sender.u[mpos]);
362
363 poolbytes += pool.len - birth.u[mpos];
364}
365
366void extra()
367{
368 unsigned long m;
369 int mpos;
370
371 scan_ulong(line.s + field[2],&m);
372 mpos = msg_find(m);
373 if (mpos == -1) return;
374
375 scan_ulong(line.s + field[3],&numk.u[mpos]);
376 scan_ulong(line.s + field[4],&numz.u[mpos]);
377 scan_ulong(line.s + field[5],&numd.u[mpos]);
378}
379
381{
382 int i;
383
384 for (i = 0; i < nummsg; ++i) {
385 outs5(pool.s + birth.u[i]);
386 outs5(" info msg ");
387 out5(strnum,fmt_ulong(strnum,msg.u[i]));
388 outs5(": bytes ");
389 out5(strnum,fmt_ulong(strnum,bytes.u[i]));
390 outs5(" from ");
391 outs5(pool.s + sender.u[i]);
392 outs5(" qp ");
393 out5(strnum,fmt_ulong(strnum,qp.u[i]));
394 outs5(" uid ");
395 out5(strnum,fmt_ulong(strnum,uid.u[i]));
396 outs5("\n");
397 outs5(pool.s + birth.u[i]);
398 outs5(" extra ");
399 out5(strnum,fmt_ulong(strnum,msg.u[i]));
400 outs5(" ");
401 out5(strnum,fmt_ulong(strnum,numk.u[i]));
402 outs5(" ");
403 out5(strnum,fmt_ulong(strnum,numz.u[i]));
404 outs5(" ");
405 out5(strnum,fmt_ulong(strnum,numd.u[i]));
406 outs5("\n");
407 }
408
409 for (i = 0; i < numdel; ++i) {
410 outs5(pool.s + dstart.u[i]);
411 outs5(" starting delivery ");
412 out5(strnum,fmt_ulong(strnum,del.u[i]));
413 outs5(": msg ");
414 out5(strnum,fmt_ulong(strnum,dmsg.u[i]));
415 outs5(" to ");
416 outs5(pool.s + dchan.u[i]);
417 outs5(" ");
418 outs5(pool.s + drecip.u[i]);
419 outs5("\n");
420 }
421
422 out5(line.s,line.len);
423 if (buffer_flush(&bo5) == -1) die_write5();
424}
425
426stralloc outline = {0};
427
428int main()
429{
430 int i;
431 int j;
432 char ch;
433
434 if (!stralloc_copys(&pool,"")) nomem();
435
436 if (!ulongalloc_ready(&msg,1)) nomem();
437 if (!ulongalloc_ready(&bytes,1)) nomem();
438 if (!ulongalloc_ready(&qp,1)) nomem();
439 if (!ulongalloc_ready(&uid,1)) nomem();
440 if (!ulongalloc_ready(&numk,1)) nomem();
441 if (!ulongalloc_ready(&numd,1)) nomem();
442 if (!ulongalloc_ready(&numz,1)) nomem();
443 if (!ulongalloc_ready(&del,1)) nomem();
444 if (!ulongalloc_ready(&dmsg,1)) nomem();
445
446 for (;;) {
447 if (getln(buffer_0,&line,&match,'\n') == -1) die_read();
448 if (!match) break;
449
450 if (!stralloc_copy(&outline,&line)) nomem();
451
452 for (i = 0; i < line.len; ++i) {
453 ch = line.s[i];
454 if ((ch == '\n') || (ch == ' ') || (ch == '\t')) line.s[i] = 0;
455 }
456 j = 0;
457 for (i = 0; i < FIELDS; ++i) {
458 while (j < line.len) if (line.s[j]) break; else ++j;
459 field[i] = j;
460 while (j < line.len) if (!line.s[j]) break; else ++j;
461 }
462 if (!stralloc_0(&line)) nomem();
463
464 if (str_equal(line.s + field[1],"status:")) ;
465 else if (str_equal(line.s + field[1],"starting")) starting();
466 else if (str_equal(line.s + field[1],"delivery")) delivery();
467 else if (str_equal(line.s + field[1],"new")) newmsg();
468 else if (str_equal(line.s + field[1],"end")) endmsg();
469 else if (str_equal(line.s + field[1],"info")) info();
470 else if (str_equal(line.s + field[1],"extra")) extra();
471 else if (str_equal(line.s + field[1],"running")) clear();
472 else if (str_equal(line.s + field[1],"exiting")) clear();
473 else if (str_equal(line.s + field[1],"number")) ;
474 else if (str_equal(line.s + field[1],"local")) ;
475 else if (str_equal(line.s + field[1],"remote")) ;
476 else if (str_equal(line.s + field[1],"warning:")) out(outline.s,outline.len);
477 else if (str_equal(line.s + field[1],"alert:")) out(outline.s,outline.len);
478 else {
479 outs("? ");
480 out(outline.s,outline.len);
481 }
482 }
483
484 if (buffer_flush(buffer_1) == -1) die_write();
485
486 pending();
487
488 _exit(0);
489}
int stralloc_copys(stralloc *, char const *)
stralloc out
Definition: dnscname.c:12
void _exit()
char buf[100+FMT_ULONG]
Definition: hier.c:10
void endmsg()
Definition: matchup.c:314
void delivery()
Definition: matchup.c:236
ulongalloc numk
Definition: matchup.c:59
stralloc outline
Definition: matchup.c:426
#define FIELDS
Definition: matchup.c:197
void die_write5()
Definition: matchup.c:20
void msg_kill(int i)
Definition: matchup.c:92
ulongalloc numz
Definition: matchup.c:61
void pending()
Definition: matchup.c:380
ulongalloc dchan
Definition: matchup.c:112
ulongalloc msg
Definition: matchup.c:55
ulongalloc drecip
Definition: matchup.c:113
stralloc pool2
Definition: matchup.c:152
int nummsg
Definition: matchup.c:54
int msg_find(unsigned long m)
Definition: matchup.c:65
void die_write()
Definition: matchup.c:19
int msg_add(unsigned long m)
Definition: matchup.c:73
int del_add(unsigned long d)
Definition: matchup.c:124
char buf5[512]
Definition: matchup.c:31
int numdel
Definition: matchup.c:109
ulongalloc bytes
Definition: matchup.c:56
ulongalloc numd
Definition: matchup.c:60
void nomem()
Definition: matchup.c:17
void out5(char *buf, int len)
Definition: matchup.c:34
void del_kill(int i)
Definition: matchup.c:139
void newmsg()
Definition: matchup.c:302
void outs5(char *buf)
Definition: matchup.c:39
ulongalloc sender
Definition: matchup.c:62
void die_read()
Definition: matchup.c:18
int del_find(unsigned long d)
Definition: matchup.c:116
ulongalloc qp
Definition: matchup.c:57
void outs(char *buf)
Definition: matchup.c:26
ulongalloc birth
Definition: matchup.c:63
int field[FIELDS]
Definition: matchup.c:198
void starting()
Definition: matchup.c:207
stralloc line
Definition: matchup.c:194
void extra()
Definition: matchup.c:366
ulongalloc dmsg
Definition: matchup.c:111
void info()
Definition: matchup.c:338
void clear()
Definition: matchup.c:200
int match
Definition: matchup.c:195
GEN_ALLOC_typedef(GEN_ALLOC_ready(ulongalloc, GEN_ALLOC_ready(unsigned long, GEN_ALLOC_ready(u, GEN_ALLOC_ready(len, GEN_ALLOC_ready(a)
Definition: matchup.c:45
#define WHO
Definition: matchup.c:15
ulongalloc dstart
Definition: matchup.c:114
int main()
Definition: matchup.c:428
void garbage()
Definition: matchup.c:154
buffer bo5
Definition: matchup.c:32
unsigned int poolbytes
Definition: matchup.c:52
ulongalloc uid
Definition: matchup.c:58
GEN_ALLOC_readyplus(prioq, struct prioq_elt, p, len, a, i, n, x, 100, prioq_readyplus)
Definition: prioq.c:5
char strnum[FMT_ULONG]
Definition: qmail-inject.c:505
struct message * m
int j
Definition: qmail-send.c:920
seek_pos mpos
Definition: qmail-send.c:922
struct del * d[CHANNELS]
Definition: qmail-send.c:720
GEN_ALLOC_ready(GEN_ALLOC_readyplus(token822_alloc, GEN_ALLOC_readyplus(struct token822, GEN_ALLOC_readyplus(t, GEN_ALLOC_readyplus(len, GEN_ALLOC_readyplus(a, GEN_ALLOC_readyplus(i, GEN_ALLOC_readyplus(n, GEN_ALLOC_readyplus(x, GEN_ALLOC_readyplus(30, token822_ready)
Definition: token822.c:23
void write()