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
)