qmail-qread.c
changeset 0 068428edee47
equal deleted inserted replaced
-1:000000000000 0:068428edee47
       
     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 }