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 = bb_xsocket(AF_INET, SOCK_STREAM, 0);
|
---|
65 | if (connect(s, (struct sockaddr *)s_addr, sizeof(struct sockaddr_in)) < 0)
|
---|
66 | {
|
---|
67 | if (ENABLE_FEATURE_CLEAN_UP) close(s);
|
---|
68 | bb_perror_msg_and_die("Unable to connect to remote host (%s)",
|
---|
69 | inet_ntoa(s_addr->sin_addr));
|
---|
70 | }
|
---|
71 | return s;
|
---|
72 | }
|
---|