diff options
Diffstat (limited to 'busybox/libbb/xconnect.c')
-rw-r--r-- | busybox/libbb/xconnect.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/busybox/libbb/xconnect.c b/busybox/libbb/xconnect.c new file mode 100644 index 000000000..09a1daad1 --- /dev/null +++ b/busybox/libbb/xconnect.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Utility routines. | ||
4 | * | ||
5 | * Connect to host at port using address resolution 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 | /* Return network byte ordered port number for a service. | ||
22 | * If "port" is a number use it as the port. | ||
23 | * If "port" is a name it is looked up in /etc/services, if it isnt found return | ||
24 | * default_port | ||
25 | */ | ||
26 | unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port) | ||
27 | { | ||
28 | unsigned short port_nr = htons(default_port); | ||
29 | if (port) { | ||
30 | char *endptr; | ||
31 | int old_errno; | ||
32 | long port_long; | ||
33 | |||
34 | /* Since this is a lib function, we're not allowed to reset errno to 0. | ||
35 | * Doing so could break an app that is deferring checking of errno. */ | ||
36 | old_errno = errno; | ||
37 | errno = 0; | ||
38 | port_long = strtol(port, &endptr, 10); | ||
39 | if (errno != 0 || *endptr!='\0' || endptr==port || port_long < 0 || port_long > 65535) { | ||
40 | struct servent *tserv = getservbyname(port, protocol); | ||
41 | if (tserv) { | ||
42 | port_nr = tserv->s_port; | ||
43 | } | ||
44 | } else { | ||
45 | port_nr = htons(port_long); | ||
46 | } | ||
47 | errno = old_errno; | ||
48 | } | ||
49 | return port_nr; | ||
50 | } | ||
51 | |||
52 | void bb_lookup_host(struct sockaddr_in *s_in, const char *host) | ||
53 | { | ||
54 | struct hostent *he; | ||
55 | |||
56 | memset(s_in, 0, sizeof(struct sockaddr_in)); | ||
57 | s_in->sin_family = AF_INET; | ||
58 | he = xgethostbyname(host); | ||
59 | memcpy(&(s_in->sin_addr), he->h_addr_list[0], he->h_length); | ||
60 | } | ||
61 | |||
62 | int xconnect(struct sockaddr_in *s_addr) | ||
63 | { | ||
64 | int s = socket(AF_INET, SOCK_STREAM, 0); | ||
65 | if (connect(s, (struct sockaddr_in *)s_addr, sizeof(struct sockaddr_in)) < 0) | ||
66 | { | ||
67 | bb_perror_msg_and_die("Unable to connect to remote host (%s)", | ||
68 | inet_ntoa(s_addr->sin_addr)); | ||
69 | } | ||
70 | return s; | ||
71 | } | ||