|
0
|
1 |
#include <sys/types.h>
|
|
|
2 |
#include <sys/stat.h>
|
|
|
3 |
#include "stralloc.h"
|
|
|
4 |
#include "substdio.h"
|
|
|
5 |
#include "subfd.h"
|
|
|
6 |
#include "fmt.h"
|
|
|
7 |
#include "str.h"
|
|
|
8 |
#include "getln.h"
|
|
|
9 |
#include "fmtqfn.h"
|
|
|
10 |
#include "readsubdir.h"
|
|
|
11 |
#include "auto_qmail.h"
|
|
|
12 |
#include "open.h"
|
|
|
13 |
#include "datetime.h"
|
|
|
14 |
#include "date822fmt.h"
|
|
|
15 |
#include "readwrite.h"
|
|
|
16 |
#include "error.h"
|
|
|
17 |
#include "exit.h"
|
|
|
18 |
|
|
|
19 |
readsubdir rs;
|
|
|
20 |
|
|
|
21 |
void die(n) int n; { substdio_flush(subfdout); _exit(n); }
|
|
|
22 |
|
|
|
23 |
void warn(s1,s2) char *s1; char *s2;
|
|
|
24 |
{
|
|
|
25 |
char *x;
|
|
|
26 |
x = error_str(errno);
|
|
|
27 |
substdio_puts(subfdout,s1);
|
|
|
28 |
substdio_puts(subfdout,s2);
|
|
|
29 |
substdio_puts(subfdout,": ");
|
|
|
30 |
substdio_puts(subfdout,x);
|
|
|
31 |
substdio_puts(subfdout,"\n");
|
|
|
32 |
}
|
|
|
33 |
|
|
|
34 |
void die_nomem() { substdio_puts(subfdout,"fatal: out of memory\n"); die(111); }
|
|
|
35 |
void die_chdir() { warn("fatal: unable to chdir",""); die(111); }
|
|
|
36 |
void die_opendir(fn) char *fn; { warn("fatal: unable to opendir ",fn); die(111); }
|
|
|
37 |
|
|
|
38 |
void err(id) unsigned long id;
|
|
|
39 |
{
|
|
|
40 |
char foo[FMT_ULONG];
|
|
|
41 |
foo[fmt_ulong(foo,id)] = 0;
|
|
|
42 |
warn("warning: trouble with #",foo);
|
|
|
43 |
}
|
|
|
44 |
|
|
|
45 |
char fnmess[FMTQFN];
|
|
|
46 |
char fninfo[FMTQFN];
|
|
|
47 |
char fnlocal[FMTQFN];
|
|
|
48 |
char fnremote[FMTQFN];
|
|
|
49 |
char fnbounce[FMTQFN];
|
|
|
50 |
|
|
|
51 |
char inbuf[1024];
|
|
|
52 |
stralloc sender = {0};
|
|
|
53 |
|
|
|
54 |
unsigned long id;
|
|
|
55 |
datetime_sec qtime;
|
|
|
56 |
int flagbounce;
|
|
|
57 |
unsigned long size;
|
|
|
58 |
|
|
|
59 |
unsigned int fmtstats(s)
|
|
|
60 |
char *s;
|
|
|
61 |
{
|
|
|
62 |
struct datetime dt;
|
|
|
63 |
unsigned int len;
|
|
|
64 |
unsigned int i;
|
|
|
65 |
|
|
|
66 |
len = 0;
|
|
|
67 |
datetime_tai(&dt,qtime);
|
|
|
68 |
i = date822fmt(s,&dt) - 7/*XXX*/; len += i; if (s) s += i;
|
|
|
69 |
i = fmt_str(s," GMT #"); len += i; if (s) s += i;
|
|
|
70 |
i = fmt_ulong(s,id); len += i; if (s) s += i;
|
|
|
71 |
i = fmt_str(s," "); len += i; if (s) s += i;
|
|
|
72 |
i = fmt_ulong(s,size); len += i; if (s) s += i;
|
|
|
73 |
i = fmt_str(s," <"); len += i; if (s) s += i;
|
|
|
74 |
i = fmt_str(s,sender.s + 1); len += i; if (s) s += i;
|
|
|
75 |
i = fmt_str(s,"> "); len += i; if (s) s += i;
|
|
|
76 |
if (flagbounce)
|
|
|
77 |
{
|
|
|
78 |
i = fmt_str(s," bouncing"); len += i; if (s) s += i;
|
|
|
79 |
}
|
|
|
80 |
|
|
|
81 |
return len;
|
|
|
82 |
}
|
|
|
83 |
|
|
|
84 |
stralloc stats = {0};
|
|
|
85 |
|
|
|
86 |
void out(s,n) char *s; unsigned int n;
|
|
|
87 |
{
|
|
|
88 |
while (n > 0)
|
|
|
89 |
{
|
|
|
90 |
substdio_put(subfdout,((*s >= 32) && (*s <= 126)) ? s : "_",1);
|
|
|
91 |
--n;
|
|
|
92 |
++s;
|
|
|
93 |
}
|
|
|
94 |
}
|
|
|
95 |
void outs(s) char *s; { out(s,str_len(s)); }
|
|
|
96 |
void outok(s) char *s; { substdio_puts(subfdout,s); }
|
|
|
97 |
|
|
|
98 |
void putstats()
|
|
|
99 |
{
|
|
|
100 |
if (!stralloc_ready(&stats,fmtstats(FMT_LEN))) die_nomem();
|
|
|
101 |
stats.len = fmtstats(stats.s);
|
|
|
102 |
out(stats.s,stats.len);
|
|
|
103 |
outok("\n");
|
|
|
104 |
}
|
|
|
105 |
|
|
|
106 |
stralloc line = {0};
|
|
|
107 |
|
|
|
108 |
void main()
|
|
|
109 |
{
|
|
|
110 |
int channel;
|
|
|
111 |
int match;
|
|
|
112 |
struct stat st;
|
|
|
113 |
int fd;
|
|
|
114 |
substdio ss;
|
|
|
115 |
int x;
|
|
|
116 |
|
|
|
117 |
if (chdir(auto_qmail) == -1) die_chdir();
|
|
|
118 |
if (chdir("queue") == -1) die_chdir();
|
|
|
119 |
readsubdir_init(&rs,"info",die_opendir);
|
|
|
120 |
|
|
|
121 |
while (x = readsubdir_next(&rs,&id))
|
|
|
122 |
if (x > 0)
|
|
|
123 |
{
|
|
|
124 |
fmtqfn(fnmess,"mess/",id,1);
|
|
|
125 |
fmtqfn(fninfo,"info/",id,1);
|
|
|
126 |
fmtqfn(fnlocal,"local/",id,1);
|
|
|
127 |
fmtqfn(fnremote,"remote/",id,1);
|
|
|
128 |
fmtqfn(fnbounce,"bounce/",id,0);
|
|
|
129 |
|
|
|
130 |
if (stat(fnmess,&st) == -1) { err(id); continue; }
|
|
|
131 |
size = st.st_size;
|
|
|
132 |
flagbounce = !stat(fnbounce,&st);
|
|
|
133 |
|
|
|
134 |
fd = open_read(fninfo);
|
|
|
135 |
if (fd == -1) { err(id); continue; }
|
|
|
136 |
substdio_fdbuf(&ss,read,fd,inbuf,sizeof(inbuf));
|
|
|
137 |
if (getln(&ss,&sender,&match,0) == -1) die_nomem();
|
|
|
138 |
if (fstat(fd,&st) == -1) { close(fd); err(id); continue; }
|
|
|
139 |
close(fd);
|
|
|
140 |
qtime = st.st_mtime;
|
|
|
141 |
|
|
|
142 |
putstats();
|
|
|
143 |
|
|
|
144 |
for (channel = 0;channel < 2;++channel)
|
|
|
145 |
{
|
|
|
146 |
fd = open_read(channel ? fnremote : fnlocal);
|
|
|
147 |
if (fd == -1)
|
|
|
148 |
{
|
|
|
149 |
if (errno != error_noent)
|
|
|
150 |
err(id);
|
|
|
151 |
}
|
|
|
152 |
else
|
|
|
153 |
{
|
|
|
154 |
for (;;)
|
|
|
155 |
{
|
|
|
156 |
if (getln(&ss,&line,&match,0) == -1) die_nomem();
|
|
|
157 |
if (!match) break;
|
|
|
158 |
switch(line.s[0])
|
|
|
159 |
{
|
|
|
160 |
case 'D':
|
|
|
161 |
outok(" done");
|
|
|
162 |
case 'T':
|
|
|
163 |
outok(channel ? "\tremote\t" : "\tlocal\t");
|
|
|
164 |
outs(line.s + 1);
|
|
|
165 |
outok("\n");
|
|
|
166 |
break;
|
|
|
167 |
}
|
|
|
168 |
}
|
|
|
169 |
close(fd);
|
|
|
170 |
}
|
|
|
171 |
}
|
|
|
172 |
}
|
|
|
173 |
|
|
|
174 |
die(0);
|
|
|
175 |
}
|