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