debian/rules: Use `git' potty wrapper.
[qmail] / timeoutconn.c
CommitLineData
2117e02e
MW
1#include <sys/types.h>
2#include <sys/socket.h>
3#include <netinet/in.h>
4#include <arpa/inet.h>
5#include "ndelay.h"
6#include "select.h"
7#include "error.h"
8#include "readwrite.h"
9#include "ip.h"
10#include "byte.h"
11#include "timeoutconn.h"
12
13int timeoutconn(s,ip,port,timeout)
14int s;
15struct ip_address *ip;
16unsigned int port;
17int timeout;
18{
19 char ch;
20 struct sockaddr_in sin;
21 char *x;
22 fd_set wfds;
23 struct timeval tv;
24
25 byte_zero(&sin,sizeof(sin));
26 byte_copy(&sin.sin_addr,4,ip);
27 x = (char *) &sin.sin_port;
28 x[1] = port; port >>= 8; x[0] = port;
29 sin.sin_family = AF_INET;
30
31 if (ndelay_on(s) == -1) return -1;
32
33 /* XXX: could bind s */
34
35 if (connect(s,(struct sockaddr *) &sin,sizeof(sin)) == 0) {
36 ndelay_off(s);
37 return 0;
38 }
39 if ((errno != error_inprogress) && (errno != error_wouldblock)) return -1;
40
41 FD_ZERO(&wfds);
42 FD_SET(s,&wfds);
43 tv.tv_sec = timeout; tv.tv_usec = 0;
44
45 if (select(s + 1,(fd_set *) 0,&wfds,(fd_set *) 0,&tv) == -1) return -1;
46 if (FD_ISSET(s,&wfds)) {
47 int dummy;
48 dummy = sizeof(sin);
49 if (getpeername(s,(struct sockaddr *) &sin,&dummy) == -1) {
50 read(s,&ch,1);
51 return -1;
52 }
53 ndelay_off(s);
54 return 0;
55 }
56
57 errno = error_timeout; /* note that connect attempt is continuing */
58 return -1;
59}