9e771495d671f9147f4b5de2496e986dae885477
[oweals/busybox.git] / libbb / xconnect.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Utility routines.
4  *
5  * Connect to host at port using address resolusion from getaddrinfo
6  *
7  */
8
9 #include "inet_common.h"
10 #include <unistd.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <netdb.h>
16 #include <netinet/in.h>
17 #include "libbb.h"
18
19 int xconnect(const char *host, const char *port)
20 {
21 #if CONFIG_FEATURE_IPV6
22         struct addrinfo hints;
23         struct addrinfo *res;
24         struct addrinfo *addr_info;
25         int error;
26         int s;
27
28         memset(&hints, 0, sizeof(hints));
29         /* set-up hints structure */
30         hints.ai_family = PF_UNSPEC;
31         hints.ai_socktype = SOCK_STREAM;
32         error = getaddrinfo(host, port, &hints, &res);
33         if (error||!res)
34                 perror_msg_and_die(gai_strerror(error));
35         addr_info=res;
36         while (res) {
37                 s=socket(res->ai_family, res->ai_socktype, res->ai_protocol);
38                 if (s<0)
39                 {
40                         error=s;
41                         res=res->ai_next;
42                         continue;
43                 }
44                 /* try to connect() to res->ai_addr */
45                 error = connect(s, res->ai_addr, res->ai_addrlen);
46                 if (error >= 0)
47                         break;
48                 close(s);
49                 res=res->ai_next;
50         }
51         freeaddrinfo(addr_info);
52         if (error < 0)
53         {
54                 perror_msg_and_die("Unable to connect to remote host (%s)", host);
55         }
56         return s;
57 #else
58         struct sockaddr_in s_addr;
59         int s = socket(AF_INET, SOCK_STREAM, 0);
60         struct servent *tserv;
61         int port_nr=atoi(port);
62         struct hostent * he;
63
64         if (port_nr==0 && (tserv = getservbyname(port, "tcp")) != NULL)
65                 port_nr = tserv->s_port;
66
67         memset(&s_addr, 0, sizeof(struct sockaddr_in));
68         s_addr.sin_family = AF_INET;
69         s_addr.sin_port = htons(port_nr);
70
71         he = xgethostbyname(host);
72         memcpy(&s_addr.sin_addr, he->h_addr, sizeof s_addr.sin_addr);
73
74         if (connect(s, (struct sockaddr *)&s_addr, sizeof s_addr) < 0)
75         {
76                 perror_msg_and_die("Unable to connect to remote host (%s)", host);
77         }
78         return s;
79 #endif
80 }