nightmaremail

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

qmail-qmqpd.c (3325B)


      1 #include <unistd.h>
      2 #include "auto_qmail.h"
      3 #include "qmail.h"
      4 #include "received.h"
      5 #include "sig.h"
      6 #include "substdio.h"
      7 #include "readwrite.h"
      8 #include "exit.h"
      9 #include "now.h"
     10 #include "fmt.h"
     11 #include "byte.h"
     12 #include "env.h"
     13 #include "str.h"
     14 
     15 void resources() { _exit(111); }
     16 void badproto() { _exit(100); }
     17 
     18 ssize_t safewrite(int fd, const void *buf, size_t len)
     19 {
     20   ssize_t r;
     21   r = write(fd,buf,len);
     22   if (r == 0 || r == -1) _exit(0);
     23   return r;
     24 }
     25 ssize_t saferead(int fd, void *buf, size_t len)
     26 {
     27   ssize_t r;
     28   r = read(fd,buf,len);
     29   if (r == 0 || r == -1) _exit(0);
     30   return r;
     31 }
     32 
     33 char ssinbuf[512];
     34 substdio ssin = SUBSTDIO_FDBUF(saferead,0,ssinbuf,sizeof(ssinbuf));
     35 char ssoutbuf[256];
     36 substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof(ssoutbuf));
     37 
     38 unsigned long bytesleft = 100;
     39 
     40 void getbyte(ch)
     41 char *ch;
     42 {
     43   if (!bytesleft--) _exit(100);
     44   substdio_get(&ssin,ch,1);
     45 }
     46 
     47 unsigned long getlen()
     48 {
     49   unsigned long len = 0;
     50   char ch;
     51 
     52   for (;;) {
     53     getbyte(&ch);
     54     if (ch == ':') return len;
     55     if (len > 200000000) resources();
     56     if (ch < '0' || ch > '9') badproto();
     57     len = 10 * len + (ch - '0');
     58   }
     59 }
     60 
     61 void getcomma()
     62 {
     63   char ch;
     64   getbyte(&ch);
     65   if (ch != ',') _exit(100);
     66 }
     67 
     68 struct qmail qq;
     69 
     70 void identify()
     71 {
     72   char *remotehost;
     73   char *remoteinfo;
     74   char *remoteip;
     75   char *local;
     76 
     77   remotehost = env_get("TCPREMOTEHOST");
     78   if (!remotehost) remotehost = "unknown";
     79   remoteinfo = env_get("TCPREMOTEINFO");
     80   remoteip = env_get("TCPREMOTEIP");
     81   if (!remoteip) remoteip = "unknown";
     82   local = env_get("TCPLOCALHOST");
     83   if (!local) local = env_get("TCPLOCALIP");
     84   if (!local) local = "unknown";
     85  
     86   received(&qq,"QMQP",local,remoteip,remotehost,remoteinfo,NULL);
     87 }
     88 
     89 char buf[1000];
     90 char strnum[FMT_ULONG];
     91 
     92 int getbuf()
     93 {
     94   unsigned long len;
     95   int i;
     96 
     97   len = getlen();
     98   if (len >= 1000) {
     99     for (i = 0;i < len;++i) getbyte(buf);
    100     getcomma();
    101     buf[0] = 0;
    102     return 0;
    103   }
    104 
    105   for (i = 0;i < len;++i) getbyte(buf + i);
    106   getcomma();
    107   buf[len] = 0;
    108   return byte_chr(buf,len,'\0') == len;
    109 }
    110 
    111 int flagok = 1;
    112 
    113 int
    114 main()
    115 {
    116   char *result;
    117   unsigned long qp;
    118   unsigned long len;
    119   char ch;
    120 
    121   sig_pipeignore();
    122   sig_alarmcatch(resources);
    123   alarm(3600);
    124 
    125   bytesleft = getlen();
    126 
    127   len = getlen();
    128 
    129   if (chdir(auto_qmail) == -1) resources();
    130   if (qmail_open(&qq) == -1) resources();
    131   qp = qmail_qp(&qq);
    132   identify();
    133 
    134   while (len > 0) { /* XXX: could speed this up */
    135     getbyte(&ch);
    136     --len;
    137     qmail_put(&qq,&ch,1);
    138   }
    139   getcomma();
    140 
    141   if (getbuf())
    142     qmail_from(&qq,buf);
    143   else {
    144     qmail_from(&qq,"");
    145     qmail_fail(&qq);
    146     flagok = 0;
    147   }
    148 
    149   while (bytesleft)
    150     if (getbuf())
    151       qmail_to(&qq,buf);
    152     else {
    153       qmail_fail(&qq);
    154       flagok = 0;
    155     }
    156 
    157   bytesleft = 1;
    158   getcomma();
    159 
    160   result = qmail_close(&qq);
    161 
    162   if (!*result) {
    163     len = fmt_str(buf,"Kok ");
    164     len += fmt_ulong(buf + len,(unsigned long) now());
    165     len += fmt_str(buf + len," qp ");
    166     len += fmt_ulong(buf + len,qp);
    167     buf[len] = 0;
    168     result = buf;
    169   }
    170 
    171   if (!flagok)
    172     result = "Dsorry, I can't accept addresses like that (#5.1.3)";
    173 
    174   substdio_put(&ssout,strnum,fmt_ulong(strnum,(unsigned long) str_len(result)));
    175   substdio_puts(&ssout,":");
    176   substdio_puts(&ssout,result);
    177   substdio_puts(&ssout,",");
    178   substdio_flush(&ssout);
    179   _exit(0);
    180 }