s/qmail 4.2.29a
Next generation secure email transport
Loading...
Searching...
No Matches
qmail-qmqpc.c
Go to the documentation of this file.
1#include <unistd.h>
2#include <sys/types.h>
3#include <sys/socket.h>
4#include <netinet/in.h>
5#include <arpa/inet.h>
6#include "buffer.h"
7#include "getln.h"
8#include "exit.h"
9#include "stralloc.h"
10#include "readclose.h"
11#include "timeoutconn.h"
12#include "logmsg.h"
13#include "str.h"
14#include "sig.h"
15#include "ip.h"
16#include "timeout.h"
17#include "auto_qmail.h"
18#include "control.h"
19#include "fmt.h"
20#include "uint_t.h"
21#include "socket_if.h"
22
23#define PORT_QMQP 628
24
25void die_success() { _exit(0); }
26void die_perm() { _exit(31); }
27void nomem() { _exit(51); }
28void die_read() { if (errno == ENOMEM) nomem(); _exit(54); }
29void die_control() { _exit(55); }
30void die_socket() { _exit(56); }
31void die_home() { _exit(61); }
32void die_temp() { _exit(71); }
33void die_conn() { _exit(74); }
34void die_format() { _exit(91); }
35
36int lasterror = 55;
38
39ssize_t saferead(int fd,char *buf,int len)
40{
41 int r;
42 r = timeoutread(60,qmqpfd,buf,len);
43 if (r <= 0) die_conn();
44 return r;
45}
46
47ssize_t safewrite(int fd,char *buf,int len)
48{
49 int r;
50 r = timeoutwrite(60,qmqpfd,buf,len);
51 if (r <= 0) die_conn();
52 return r;
53}
54
55char buf[1024];
56buffer bo = BUFFER_INIT(safewrite,-1,buf,sizeof(buf));
57buffer bi = BUFFER_INIT(saferead,-1,buf,sizeof(buf));
58buffer be = BUFFER_INIT(read,1,buf,sizeof(buf)); // envelope
59/* WARNING: can use only one of these at a time! */
60
61stralloc beforemessage = {0};
62stralloc message = {0};
63stralloc aftermessage = {0};
64
65char strnum[FMT_ULONG];
66stralloc line = {0};
67
68void getmess()
69{
70 int match;
71
72 if (readclose_append(0,&message,1024) == -1) die_read();
73
74 strnum[fmt_ulong(strnum,(unsigned long) message.len)] = 0;
76 if (!stralloc_cats(&beforemessage,":")) nomem();
77 if (!stralloc_copys(&aftermessage,",")) nomem();
78
79 if (getln(&be,&line,&match,'\0') == -1) die_read();
80 if (!match) die_format();
81 if (line.len < 2) die_format();
82 if (line.s[0] != 'F') die_format();
83
84 strnum[fmt_ulong(strnum,(unsigned long) line.len - 2)] = 0;
85 if (!stralloc_cats(&aftermessage,strnum)) nomem();
86 if (!stralloc_cats(&aftermessage,":")) nomem();
87 if (!stralloc_catb(&aftermessage,line.s + 1,line.len - 2)) nomem();
88 if (!stralloc_cats(&aftermessage,",")) nomem();
89
90 for (;;) {
91 if (getln(&be,&line,&match,'\0') == -1) die_read();
92 if (!match) die_format();
93 if (line.len < 2) break;
94 if (line.s[0] != 'T') die_format();
95
96 strnum[fmt_ulong(strnum,(unsigned long) line.len - 2)] = 0;
97 if (!stralloc_cats(&aftermessage,strnum)) nomem();
98 if (!stralloc_cats(&aftermessage,":")) nomem();
99 if (!stralloc_catb(&aftermessage,line.s + 1,line.len - 2)) nomem();
100 if (!stralloc_cats(&aftermessage,",")) nomem();
101 }
102}
103
104void doit(char *server)
105{
106 struct ip4_address ip4s;
107 struct ip6_address ip6s;
108 char *netif = 0;
109 uint32 ifidx = 0;
110 char ch;
111 int i, j, r;
112
113 i = str_chr(server,':');
114 if (server[i] == ':') {
115 j = str_chr(server,'%'); /* IF index */
116 if (server[j] == '%') {
117 server[j] = 0;
118 netif = &server[j + 1];
119 ifidx = socket_getifidx(netif);
120 }
121 if (!ip6_scan(server,(char *)&ip6s.d)) return;
122 qmqpfd = socket(AF_INET6,SOCK_STREAM,0);
123 if (qmqpfd == -1) die_socket();
124 r = timeoutconn6(qmqpfd,(char *)&ip6s.d,PORT_QMQP,10,ifidx);
125 } else {
126 if (!ip4_scan(server,(char *)&ip4s.d)) return;
127 qmqpfd = socket(AF_INET,SOCK_STREAM,0);
128 if (qmqpfd == -1) die_socket();
129 r = timeoutconn4(qmqpfd,(char *)&ip4s.d,PORT_QMQP,10);
130 }
131 if (r != 0) {
132 lasterror = 73;
133 if (errno == ETIMEDOUT) lasterror = 72;
134 close(qmqpfd);
135 return;
136 }
137
138 strnum[fmt_ulong(strnum,(unsigned long) (beforemessage.len + message.len + aftermessage.len))] = 0;
139 buffer_puts(&bo,strnum);
140 buffer_puts(&bo,":");
141 buffer_put(&bo,beforemessage.s,beforemessage.len);
142 buffer_put(&bo,message.s,message.len);
143 buffer_put(&bo,aftermessage.s,aftermessage.len);
144 buffer_puts(&bo,",");
145 buffer_flush(&bo);
146
147 for (;;) {
148 buffer_get(&bi,&ch,1);
149 if (ch == 'K') die_success();
150 if (ch == 'Z') die_temp();
151 if (ch == 'D') die_perm();
152 }
153}
154
155stralloc servers = {0};
156
157int main()
158{
159 int i;
160 int j;
161
162 sig_pipeignore();
163
164 if (chdir(auto_qmail) == -1) die_home();
165 if (control_init() == -1) die_control();
166 if (control_readfile(&servers,"control/qmqpservers",0) != 1) die_control();
167
168 getmess();
169
170 i = 0;
171 for (j = 0; j < servers.len; ++j)
172 if (!servers.s[j]) {
173 doit(servers.s + i);
174 i = j + 1;
175 }
176
178}
char auto_qmail[]
int control_readfile(stralloc *sa, char *fn, int flagme)
Definition: control.c:86
int control_init(void)
Definition: control.c:32
int stralloc_copys(stralloc *, char const *)
void _exit()
int match
Definition: matchup.c:195
void doit()
Definition: newaliases.c:256
int fd
void die_control()
Definition: qmail-qmqpc.c:29
ssize_t saferead(int fd, char *buf, int len)
Definition: qmail-qmqpc.c:39
void die_home()
Definition: qmail-qmqpc.c:31
void die_format()
Definition: qmail-qmqpc.c:34
void die_socket()
Definition: qmail-qmqpc.c:30
buffer be
Definition: qmail-qmqpc.c:58
char strnum[FMT_ULONG]
Definition: qmail-qmqpc.c:65
#define PORT_QMQP
Definition: qmail-qmqpc.c:23
void getmess()
Definition: qmail-qmqpc.c:68
stralloc aftermessage
Definition: qmail-qmqpc.c:63
void nomem()
Definition: qmail-qmqpc.c:27
void die_temp()
Definition: qmail-qmqpc.c:32
void die_read()
Definition: qmail-qmqpc.c:28
int lasterror
Definition: qmail-qmqpc.c:36
stralloc line
Definition: qmail-qmqpc.c:66
buffer bi
Definition: qmail-qmqpc.c:57
stralloc servers
Definition: qmail-qmqpc.c:155
char buf[1024]
Definition: qmail-qmqpc.c:55
void die_conn()
Definition: qmail-qmqpc.c:33
void die_success()
Definition: qmail-qmqpc.c:25
buffer bo
Definition: qmail-qmqpc.c:56
int qmqpfd
Definition: qmail-qmqpc.c:37
int main()
Definition: qmail-qmqpc.c:157
void die_perm()
Definition: qmail-qmqpc.c:26
stralloc beforemessage
Definition: qmail-qmqpc.c:61
uint32 ifidx
Definition: qmail-remote.c:90
int j
Definition: qmail-send.c:920
ssize_t safewrite()