From b732a73bc773789894466b0e5320b2f1fe42c7e9 Mon Sep 17 00:00:00 2001 From: John Denker Date: Fri, 1 Jun 2012 18:58:45 -0700 Subject: original, as downloaded from http://www.qmail.org/netqmail-1.06.tar.gz --- qmail-qmqpc.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 qmail-qmqpc.c (limited to 'qmail-qmqpc.c') diff --git a/qmail-qmqpc.c b/qmail-qmqpc.c new file mode 100644 index 0000000..d5adf05 --- /dev/null +++ b/qmail-qmqpc.c @@ -0,0 +1,159 @@ +#include +#include +#include +#include +#include "substdio.h" +#include "getln.h" +#include "readwrite.h" +#include "exit.h" +#include "stralloc.h" +#include "slurpclose.h" +#include "error.h" +#include "sig.h" +#include "ip.h" +#include "timeoutconn.h" +#include "timeoutread.h" +#include "timeoutwrite.h" +#include "auto_qmail.h" +#include "control.h" +#include "fmt.h" + +#define PORT_QMQP 628 + +void die_success() { _exit(0); } +void die_perm() { _exit(31); } +void nomem() { _exit(51); } +void die_read() { if (errno == error_nomem) nomem(); _exit(54); } +void die_control() { _exit(55); } +void die_socket() { _exit(56); } +void die_home() { _exit(61); } +void die_temp() { _exit(71); } +void die_conn() { _exit(74); } +void die_format() { _exit(91); } + +int lasterror = 55; +int qmqpfd; + +int saferead(fd,buf,len) int fd; char *buf; int len; +{ + int r; + r = timeoutread(60,qmqpfd,buf,len); + if (r <= 0) die_conn(); + return r; +} +int safewrite(fd,buf,len) int fd; char *buf; int len; +{ + int r; + r = timeoutwrite(60,qmqpfd,buf,len); + if (r <= 0) die_conn(); + return r; +} + +char buf[1024]; +substdio to = SUBSTDIO_FDBUF(safewrite,-1,buf,sizeof buf); +substdio from = SUBSTDIO_FDBUF(saferead,-1,buf,sizeof buf); +substdio envelope = SUBSTDIO_FDBUF(read,1,buf,sizeof buf); +/* WARNING: can use only one of these at a time! */ + +stralloc beforemessage = {0}; +stralloc message = {0}; +stralloc aftermessage = {0}; + +char strnum[FMT_ULONG]; +stralloc line = {0}; + +void getmess() +{ + int match; + + if (slurpclose(0,&message,1024) == -1) die_read(); + + strnum[fmt_ulong(strnum,(unsigned long) message.len)] = 0; + if (!stralloc_copys(&beforemessage,strnum)) nomem(); + if (!stralloc_cats(&beforemessage,":")) nomem(); + if (!stralloc_copys(&aftermessage,",")) nomem(); + + if (getln(&envelope,&line,&match,'\0') == -1) die_read(); + if (!match) die_format(); + if (line.len < 2) die_format(); + if (line.s[0] != 'F') die_format(); + + strnum[fmt_ulong(strnum,(unsigned long) line.len - 2)] = 0; + if (!stralloc_cats(&aftermessage,strnum)) nomem(); + if (!stralloc_cats(&aftermessage,":")) nomem(); + if (!stralloc_catb(&aftermessage,line.s + 1,line.len - 2)) nomem(); + if (!stralloc_cats(&aftermessage,",")) nomem(); + + for (;;) { + if (getln(&envelope,&line,&match,'\0') == -1) die_read(); + if (!match) die_format(); + if (line.len < 2) break; + if (line.s[0] != 'T') die_format(); + + strnum[fmt_ulong(strnum,(unsigned long) line.len - 2)] = 0; + if (!stralloc_cats(&aftermessage,strnum)) nomem(); + if (!stralloc_cats(&aftermessage,":")) nomem(); + if (!stralloc_catb(&aftermessage,line.s + 1,line.len - 2)) nomem(); + if (!stralloc_cats(&aftermessage,",")) nomem(); + } +} + +void doit(server) +char *server; +{ + struct ip_address ip; + char ch; + + if (!ip_scan(server,&ip)) return; + + qmqpfd = socket(AF_INET,SOCK_STREAM,0); + if (qmqpfd == -1) die_socket(); + + if (timeoutconn(qmqpfd,&ip,PORT_QMQP,10) != 0) { + lasterror = 73; + if (errno == error_timeout) lasterror = 72; + close(qmqpfd); + return; + } + + strnum[fmt_ulong(strnum,(unsigned long) (beforemessage.len + message.len + aftermessage.len))] = 0; + substdio_puts(&to,strnum); + substdio_puts(&to,":"); + substdio_put(&to,beforemessage.s,beforemessage.len); + substdio_put(&to,message.s,message.len); + substdio_put(&to,aftermessage.s,aftermessage.len); + substdio_puts(&to,","); + substdio_flush(&to); + + for (;;) { + substdio_get(&from,&ch,1); + if (ch == 'K') die_success(); + if (ch == 'Z') die_temp(); + if (ch == 'D') die_perm(); + } +} + +stralloc servers = {0}; + +main() +{ + int i; + int j; + + sig_pipeignore(); + + if (chdir(auto_qmail) == -1) die_home(); + if (control_init() == -1) die_control(); + if (control_readfile(&servers,"control/qmqpservers",0) != 1) die_control(); + + getmess(); + + i = 0; + for (j = 0;j < servers.len;++j) + if (!servers.s[j]) { + doit(servers.s + i); + i = j + 1; + } + + _exit(lasterror); +} -- cgit v1.2.3