b3619fd0ee43cb312bcfbc38b0823346da319bf6
[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 /* 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, unsigned short default_port)
27 {
28         unsigned short port_nr = htons(default_port);
29         if (port) {
30         char *endptr;
31                 long port_long = strtol(port, &endptr, 10);
32
33                 if (errno != 0 || *endptr!='\0' || endptr==port || port_long < 0 || port_long > 65535) {
34                         struct servent *tserv = getservbyname(port, "tcp");
35                         if (tserv) {
36                         port_nr = tserv->s_port;
37                 }
38         } else {
39                         port_nr = htons(port_long);
40                 }
41         }
42         return port_nr;
43 }
44
45 void bb_lookup_host(struct sockaddr_in *s_in, const char *host)
46 {
47         struct hostent *he;
48
49         memset(s_in, 0, sizeof(struct sockaddr_in));
50         s_in->sin_family = AF_INET;
51         he = xgethostbyname(host);
52         memcpy(&(s_in->sin_addr), he->h_addr_list[0], he->h_length);
53 }
54
55 int xconnect(struct sockaddr_in *s_addr)
56 {
57         int s = socket(AF_INET, SOCK_STREAM, 0);
58         if (connect(s, (struct sockaddr_in *)s_addr, sizeof(struct sockaddr_in)) < 0)
59         {
60                 bb_perror_msg_and_die("Unable to connect to remote host (%s)", 
61                                 inet_ntoa(s_addr->sin_addr));
62         }
63         return s;
64 }