2 #include <sys/socket.h>
3 #include <netinet/in.h>
10 #include "slurpclose.h"
14 #include "timeoutconn.h"
15 #include "timeoutread.h"
16 #include "timeoutwrite.h"
17 #include "auto_qmail.h"
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); }
37 int saferead(fd,buf,len) int fd; char *buf; int len;
40 r = timeoutread(60,qmqpfd,buf,len);
41 if (r <= 0) die_conn();
44 int safewrite(fd,buf,len) int fd; char *buf; int len;
47 r = timeoutwrite(60,qmqpfd,buf,len);
48 if (r <= 0) die_conn();
53 substdio to = SUBSTDIO_FDBUF(safewrite,-1,buf,sizeof buf);
54 substdio from = SUBSTDIO_FDBUF(saferead,-1,buf,sizeof buf);
55 substdio envelope = SUBSTDIO_FDBUF(read,1,buf,sizeof buf);
56 /* WARNING: can use only one of these at a time! */
58 stralloc beforemessage = {0};
59 stralloc message = {0};
60 stralloc aftermessage = {0};
62 char strnum[FMT_ULONG];
69 if (slurpclose(0,&message,1024) == -1) die_read();
71 strnum[fmt_ulong(strnum,(unsigned long) message.len)] = 0;
72 if (!stralloc_copys(&beforemessage,strnum)) nomem();
73 if (!stralloc_cats(&beforemessage,":")) nomem();
74 if (!stralloc_copys(&aftermessage,",")) nomem();
76 if (getln(&envelope,&line,&match,'\0') == -1) die_read();
77 if (!match) die_format();
78 if (line.len < 2) die_format();
79 if (line.s[0] != 'F') die_format();
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();
88 if (getln(&envelope,&line,&match,'\0') == -1) die_read();
89 if (!match) die_format();
90 if (line.len < 2) break;
91 if (line.s[0] != 'T') die_format();
93 strnum[fmt_ulong(strnum,(unsigned long) line.len - 2)] = 0;
94 if (!stralloc_cats(&aftermessage,strnum)) nomem();
95 if (!stralloc_cats(&aftermessage,":")) nomem();
96 if (!stralloc_catb(&aftermessage,line.s + 1,line.len - 2)) nomem();
97 if (!stralloc_cats(&aftermessage,",")) nomem();
104 struct ip_address ip;
107 if (!ip_scan(server,&ip)) return;
109 qmqpfd = socket(AF_INET,SOCK_STREAM,0);
110 if (qmqpfd == -1) die_socket();
112 if (timeoutconn(qmqpfd,&ip,PORT_QMQP,10) != 0) {
114 if (errno == error_timeout) lasterror = 72;
119 strnum[fmt_ulong(strnum,(unsigned long) (beforemessage.len + message.len + aftermessage.len))] = 0;
120 substdio_puts(&to,strnum);
121 substdio_puts(&to,":");
122 substdio_put(&to,beforemessage.s,beforemessage.len);
123 substdio_put(&to,message.s,message.len);
124 substdio_put(&to,aftermessage.s,aftermessage.len);
125 substdio_puts(&to,",");
129 substdio_get(&from,&ch,1);
130 if (ch == 'K') die_success();
131 if (ch == 'Z') die_temp();
132 if (ch == 'D') die_perm();
136 stralloc servers = {0};
145 if (chdir(auto_qmail) == -1) die_home();
146 if (control_init() == -1) die_control();
147 if (control_readfile(&servers,"control/qmqpservers",0) != 1) die_control();
152 for (j = 0;j < servers.len;++j)