Rework wget, the xconnect interface, and its various clients
[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 <unistd.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <sys/types.h>
13 #include <sys/socket.h>
14 #include <errno.h>
15 #include <netdb.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 #include "libbb.h"
20
21 int bb_getport(char *port)
22 {
23         int port_nr;
24         char *endptr;
25         struct servent *tserv;
26
27         if (!port) {
28                 return -1;
29         }
30         port_nr=strtol(port, &endptr, 10);
31         if (errno != 0 || *endptr!='\0' || endptr==port || port_nr < 1 || port_nr > 65536) 
32         {
33                 if (port_nr==0 && (tserv = getservbyname(port, "tcp")) != NULL) {
34                         port_nr = tserv->s_port;
35                 } else {
36                         return -1;
37                 }
38         } else {
39                 port_nr = htons(port_nr);
40         }
41         return port_nr;
42 }
43
44 void bb_lookup_host(struct sockaddr_in *s_in, char *host, char *port)
45 {
46         struct hostent *he;
47
48         memset(s_in, 0, sizeof(struct sockaddr_in));
49         s_in->sin_family = AF_INET;
50         he = xgethostbyname(host);
51         memcpy(&(s_in->sin_addr), he->h_addr_list[0], he->h_length);
52
53         if (port) {
54                 s_in->sin_port=bb_getport(port);
55         }
56 }
57
58 int xconnect(struct sockaddr_in *s_addr)
59 {
60         int s = socket(AF_INET, SOCK_STREAM, 0);
61         if (connect(s, (struct sockaddr_in *)s_addr, sizeof(struct sockaddr_in)) < 0)
62         {
63                 bb_perror_msg_and_die("Unable to connect to remote host (%s)", 
64                                 inet_ntoa(s_addr->sin_addr));
65         }
66         return s;
67 }