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