nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

qmail-qmqpc.c (3778B)


      1 #include <sys/types.h>
      2 #include <sys/socket.h>
      3 #include <netinet/in.h>
      4 #include <arpa/inet.h>
      5 #include "substdio.h"
      6 #include "getln.h"
      7 #include "readwrite.h"
      8 #include "exit.h"
      9 #include "stralloc.h"
     10 #include "slurpclose.h"
     11 #include "error.h"
     12 #include "sig.h"
     13 #include "ip.h"
     14 #include "timeoutconn.h"
     15 #include "timeoutread.h"
     16 #include "timeoutwrite.h"
     17 #include "auto_qmail.h"
     18 #include "control.h"
     19 #include "fmt.h"
     20 
     21 #define PORT_QMQP 628
     22 
     23 void die_success() { _exit(0); }
     24 void die_perm() { _exit(31); }
     25 void nomem() { _exit(51); }
     26 void die_read() { if (errno == error_nomem) nomem(); _exit(54); }
     27 void die_control() { _exit(55); }
     28 void die_socket() { _exit(56); }
     29 void die_home() { _exit(61); }
     30 void die_temp() { _exit(71); }
     31 void die_conn() { _exit(74); }
     32 void die_format() { _exit(91); }
     33 
     34 int lasterror = 55;
     35 int qmqpfd;
     36 
     37 GEN_SAFE_TIMEOUTREAD(saferead,60,qmqpfd,die_conn())
     38 GEN_SAFE_TIMEOUTWRITE(safewrite,60,qmqpfd,die_conn())
     39 
     40 char buf[1024];
     41 substdio to = SUBSTDIO_FDBUF(safewrite,-1,buf,sizeof(buf));
     42 substdio from = SUBSTDIO_FDBUF(saferead,-1,buf,sizeof(buf));
     43 substdio envelope = SUBSTDIO_FDBUF(read,1,buf,sizeof(buf));
     44 /* WARNING: can use only one of these at a time! */
     45 
     46 stralloc beforemessage = {0};
     47 stralloc message = {0};
     48 stralloc aftermessage = {0};
     49 
     50 char strnum[FMT_ULONG];
     51 stralloc line = {0};
     52 
     53 void getmess()
     54 {
     55   int match;
     56 
     57   if (slurpclose(0,&message,1024) == -1) die_read();
     58 
     59   strnum[fmt_ulong(strnum,(unsigned long) message.len)] = 0;
     60   if (!stralloc_copys(&beforemessage,strnum)) nomem();
     61   if (!stralloc_cats(&beforemessage,":")) nomem();
     62   if (!stralloc_copys(&aftermessage,",")) nomem();
     63 
     64   if (getln(&envelope,&line,&match,'\0') == -1) die_read();
     65   if (!match) die_format();
     66   if (line.len < 2) die_format();
     67   if (line.s[0] != 'F') die_format();
     68 
     69   strnum[fmt_ulong(strnum,(unsigned long) line.len - 2)] = 0;
     70   if (!stralloc_cats(&aftermessage,strnum)) nomem();
     71   if (!stralloc_cats(&aftermessage,":")) nomem();
     72   if (!stralloc_catb(&aftermessage,line.s + 1,line.len - 2)) nomem();
     73   if (!stralloc_cats(&aftermessage,",")) nomem();
     74 
     75   for (;;) {
     76     if (getln(&envelope,&line,&match,'\0') == -1) die_read();
     77     if (!match) die_format();
     78     if (line.len < 2) break;
     79     if (line.s[0] != 'T') die_format();
     80 
     81     strnum[fmt_ulong(strnum,(unsigned long) line.len - 2)] = 0;
     82     if (!stralloc_cats(&aftermessage,strnum)) nomem();
     83     if (!stralloc_cats(&aftermessage,":")) nomem();
     84     if (!stralloc_catb(&aftermessage,line.s + 1,line.len - 2)) nomem();
     85     if (!stralloc_cats(&aftermessage,",")) nomem();
     86   }
     87 }
     88 
     89 void doit(server)
     90 char *server;
     91 {
     92   struct ip_address ip;
     93   char ch;
     94 
     95   if (!ip_scan(server,&ip)) return;
     96 
     97   qmqpfd = socket(AF_INET,SOCK_STREAM,0);
     98   if (qmqpfd == -1) die_socket();
     99 
    100   if (timeoutconn(qmqpfd,&ip,PORT_QMQP,10) != 0) {
    101     lasterror = 73;
    102     if (errno == error_timeout) lasterror = 72;
    103     close(qmqpfd);
    104     return;
    105   }
    106 
    107   strnum[fmt_ulong(strnum,(unsigned long) (beforemessage.len + message.len + aftermessage.len))] = 0;
    108   substdio_puts(&to,strnum);
    109   substdio_puts(&to,":");
    110   substdio_put(&to,beforemessage.s,beforemessage.len);
    111   substdio_put(&to,message.s,message.len);
    112   substdio_put(&to,aftermessage.s,aftermessage.len);
    113   substdio_puts(&to,",");
    114   substdio_flush(&to);
    115 
    116   for (;;) {
    117     substdio_get(&from,&ch,1);
    118     if (ch == 'K') die_success();
    119     if (ch == 'Z') die_temp();
    120     if (ch == 'D') die_perm();
    121   }
    122 }
    123 
    124 stralloc servers = {0};
    125 
    126 int
    127 main()
    128 {
    129   int i;
    130   int j;
    131 
    132   sig_pipeignore();
    133 
    134   if (chdir(auto_qmail) == -1) die_home();
    135   if (control_init() == -1) die_control();
    136   if (control_readfile(&servers,"control/qmqpservers",0) != 1) die_control();
    137 
    138   getmess();
    139 
    140   i = 0;
    141   for (j = 0;j < servers.len;++j)
    142     if (!servers.s[j]) {
    143       doit(servers.s + i);
    144       i = j + 1;
    145     }
    146 
    147   return lasterror;
    148 }