summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-07-03 11:51:44 +0000
committerEric Andersen <andersen@codepoet.org>2002-07-03 11:51:44 +0000
commit0b31586c7113b9b26ca0aeee9247a831b55b308c (patch)
tree7071145eeeea4dd92d18e05fce6d8e710dc67d52
parent51b8bd68bb22b1cc5d95e418813c2f08a194ec2b (diff)
downloadbusybox-w32-0b31586c7113b9b26ca0aeee9247a831b55b308c.tar.gz
busybox-w32-0b31586c7113b9b26ca0aeee9247a831b55b308c.tar.bz2
busybox-w32-0b31586c7113b9b26ca0aeee9247a831b55b308c.zip
A patch from Bart Visscher <magick@linux-fan.com> to add an
xconnect helper routine which does: -address and port resolving -tries to connect to all resolved addresses until connected -uses getaddrinfo, so works for IPv6 too This patch also ports rdate, telnet, and wget to use the new xconnect function. Thanks Bart!
-rw-r--r--libbb/xconnect.c78
-rw-r--r--networking/telnet.c96
-rw-r--r--networking/wget.c16
-rw-r--r--util-linux/rdate.c20
4 files changed, 93 insertions, 117 deletions
diff --git a/libbb/xconnect.c b/libbb/xconnect.c
new file mode 100644
index 000000000..0d670f286
--- /dev/null
+++ b/libbb/xconnect.c
@@ -0,0 +1,78 @@
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 <sys/types.h>
12#include <sys/socket.h>
13#include <netdb.h>
14#include <stdlib.h>
15#include "libbb.h"
16
17int xconnect(const char *host, const char *port)
18{
19#if CONFIG_FEATURE_IPV6
20 struct addrinfo hints;
21 struct addrinfo *res;
22 struct addrinfo *addr_info;
23 int error;
24 int s;
25
26 memset(&hints, 0, sizeof(hints));
27 /* set-up hints structure */
28 hints.ai_family = PF_UNSPEC;
29 hints.ai_socktype = SOCK_STREAM;
30 error = getaddrinfo(host, port, &hints, &res);
31 if (error||!res)
32 perror_msg_and_die(gai_strerror(error));
33 addr_info=res;
34 while (res) {
35 s=socket(res->ai_family, res->ai_socktype, res->ai_protocol);
36 if (s<0)
37 {
38 error=s;
39 res=res->ai_next;
40 continue;
41 }
42 /* try to connect() to res->ai_addr */
43 error = connect(s, res->ai_addr, res->ai_addrlen);
44 if (error >= 0)
45 break;
46 close(s);
47 res=res->ai_next;
48 }
49 freeaddrinfo(addr_info);
50 if (error < 0)
51 {
52 perror_msg_and_die("Unable to connect to remote host (%s)", host);
53 }
54 return s;
55#else
56 struct sockaddr_in s_addr;
57 int s = socket(AF_INET, SOCK_STREAM, 0);
58 struct servent *tserv;
59 int port_nr=atoi(port);
60 struct hostent * he;
61
62 if (port_nr==0 && (tserv = getservbyname(port, "tcp")) != NULL)
63 port_nr = tserv->s_port;
64
65 memset(&s_addr, 0, sizeof(struct sockaddr_in));
66 s_addr.sin_family = AF_INET;
67 s_addr.sin_port = htons(port_nr);
68
69 he = xgethostbyname(host);
70 memcpy(&s_addr.sin_addr, he->h_addr, sizeof s_addr.sin_addr);
71
72 if (connect(s, (struct sockaddr *)&s_addr, sizeof s_addr) < 0)
73 {
74 perror_msg_and_die("Unable to connect to remote host (%s)", host);
75 }
76 return s;
77#endif
78}
diff --git a/networking/telnet.c b/networking/telnet.c
index 53616c01d..86d672c2d 100644
--- a/networking/telnet.c
+++ b/networking/telnet.c
@@ -36,13 +36,11 @@
36#include <errno.h> 36#include <errno.h>
37#include <stdlib.h> 37#include <stdlib.h>
38#include <stdarg.h> 38#include <stdarg.h>
39#include <string.h>
40#include <signal.h> 39#include <signal.h>
41#include <arpa/telnet.h> 40#include <arpa/telnet.h>
42#include <sys/types.h> 41#include <sys/types.h>
43#include <sys/socket.h> 42#include <sys/socket.h>
44#include <netinet/in.h> 43#include <netinet/in.h>
45#include <netdb.h>
46#include "busybox.h" 44#include "busybox.h"
47 45
48#ifdef CONFIG_FEATURE_AUTOWIDTH 46#ifdef CONFIG_FEATURE_AUTOWIDTH
@@ -122,19 +120,12 @@ static inline void iacflush(void)
122} 120}
123 121
124/* Function prototypes */ 122/* Function prototypes */
125static int getport(char * p);
126static struct in_addr getserver(char * p);
127static void setup_sockaddr_in(struct sockaddr_in * addr, int port);
128static int remote_connect(struct in_addr addr, int port);
129static void rawmode(void); 123static void rawmode(void);
130static void cookmode(void); 124static void cookmode(void);
131static void do_linemode(void); 125static void do_linemode(void);
132static void will_charmode(void); 126static void will_charmode(void);
133static void telopt(byte c); 127static void telopt(byte c);
134static int subneg(byte c); 128static int subneg(byte c);
135#if 0
136static int local_bind(int port);
137#endif
138 129
139/* Some globals */ 130/* Some globals */
140static int one = 1; 131static int one = 1;
@@ -584,8 +575,8 @@ static void cookmode(void)
584 575
585extern int telnet_main(int argc, char** argv) 576extern int telnet_main(int argc, char** argv)
586{ 577{
587 struct in_addr host; 578 char *host;
588 int port; 579 char *port;
589 int len; 580 int len;
590#ifdef USE_POLL 581#ifdef USE_POLL
591 struct pollfd ufds[2]; 582 struct pollfd ufds[2];
@@ -615,11 +606,13 @@ extern int telnet_main(int argc, char** argv)
615 cfmakeraw(&G.termios_raw); 606 cfmakeraw(&G.termios_raw);
616 607
617 if (argc < 2) show_usage(); 608 if (argc < 2) show_usage();
618 port = (argc > 2)? getport(argv[2]): 23; 609 port = (argc > 2)? argv[2] : "23";
610
611 host = argv[1];
619 612
620 host = getserver(argv[1]); 613 G.netfd = xconnect(host, port);
621 614
622 G.netfd = remote_connect(host, port); 615 setsockopt(G.netfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one);
623 616
624 signal(SIGINT, fgotsig); 617 signal(SIGINT, fgotsig);
625 618
@@ -691,81 +684,6 @@ extern int telnet_main(int argc, char** argv)
691 } 684 }
692} 685}
693 686
694static int getport(char * p)
695{
696 unsigned int port = atoi(p);
697
698 if ((unsigned)(port - 1 ) > 65534)
699 {
700 error_msg_and_die("%s: bad port number", p);
701 }
702 return port;
703}
704
705static struct in_addr getserver(char * host)
706{
707 struct in_addr addr;
708
709 struct hostent * he;
710 he = xgethostbyname(host);
711 memcpy(&addr, he->h_addr, sizeof addr);
712
713 TRACE(1, ("addr: %s\n", inet_ntoa(addr)));
714
715 return addr;
716}
717
718static int create_socket(void)
719{
720 return socket(AF_INET, SOCK_STREAM, 0);
721}
722
723static void setup_sockaddr_in(struct sockaddr_in * addr, int port)
724{
725 memset(addr, 0, sizeof(struct sockaddr_in));
726 addr->sin_family = AF_INET;
727 addr->sin_port = htons(port);
728}
729
730#if 0
731static int local_bind(int port)
732{
733 struct sockaddr_in s_addr;
734 int s = create_socket();
735
736 setup_sockaddr_in(&s_addr, port);
737
738 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
739
740 if (bind(s, &s_addr, sizeof s_addr) < 0)
741 {
742 char * e = sys_errlist[errno];
743 syserrorexit("bind");
744 exit(1);
745 }
746 listen(s, 1);
747
748 return s;
749}
750#endif
751
752static int remote_connect(struct in_addr addr, int port)
753{
754 struct sockaddr_in s_addr;
755 int s = create_socket();
756
757 setup_sockaddr_in(&s_addr, port);
758 s_addr.sin_addr = addr;
759
760 setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one);
761
762 if (connect(s, (struct sockaddr *)&s_addr, sizeof s_addr) < 0)
763 {
764 perror_msg_and_die("Unable to connect to remote host");
765 }
766 return s;
767}
768
769/* 687/*
770Local Variables: 688Local Variables:
771c-file-style: "linux" 689c-file-style: "linux"
diff --git a/networking/wget.c b/networking/wget.c
index 6974c70a8..c6200219b 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -563,24 +563,16 @@ void parse_url(char *url, struct host_info *h)
563 563
564FILE *open_socket(char *host, int port) 564FILE *open_socket(char *host, int port)
565{ 565{
566 struct sockaddr_in s_in;
567 struct hostent *hp;
568 int fd; 566 int fd;
569 FILE *fp; 567 FILE *fp;
568 char port_str[10];
570 569
571 memset(&s_in, 0, sizeof(s_in)); 570 snprintf(port_str, sizeof(port_str), "%d", port);
572 s_in.sin_family = AF_INET; 571 fd=xconnect(host, port_str);
573 hp = xgethostbyname(host);
574 memcpy(&s_in.sin_addr, hp->h_addr_list[0], hp->h_length);
575 s_in.sin_port = htons(port);
576 572
577 /* 573 /*
578 * Get the server onto a stdio stream. 574 * Get the server onto a stdio stream.
579 */ 575 */
580 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
581 perror_msg_and_die("socket()");
582 if (connect(fd, (struct sockaddr *) &s_in, sizeof(s_in)) < 0)
583 perror_msg_and_die("connect(%s)", host);
584 if ((fp = fdopen(fd, "r+")) == NULL) 576 if ((fp = fdopen(fd, "r+")) == NULL)
585 perror_msg_and_die("fdopen()"); 577 perror_msg_and_die("fdopen()");
586 578
@@ -826,7 +818,7 @@ progressmeter(int flag)
826 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 818 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
827 * SUCH DAMAGE. 819 * SUCH DAMAGE.
828 * 820 *
829 * $Id: wget.c,v 1.49 2002/05/14 23:36:45 sandman Exp $ 821 * $Id: wget.c,v 1.50 2002/07/03 11:51:44 andersen Exp $
830 */ 822 */
831 823
832 824
diff --git a/util-linux/rdate.c b/util-linux/rdate.c
index 04a76129a..df7d7bbc4 100644
--- a/util-linux/rdate.c
+++ b/util-linux/rdate.c
@@ -39,26 +39,14 @@ static const int RFC_868_BIAS = 2208988800UL;
39 39
40static time_t askremotedate(const char *host) 40static time_t askremotedate(const char *host)
41{ 41{
42 struct hostent *h;
43 struct sockaddr_in s_in;
44 struct servent *tserv;
45 unsigned long int nett, localt; 42 unsigned long int nett, localt;
43 const char *port="37";
46 int fd; 44 int fd;
47 45
48 h = xgethostbyname(host); /* get the IP addr */ 46 if (getservbyname("time", "tcp") != NULL)
49 memcpy(&s_in.sin_addr, h->h_addr, sizeof(s_in.sin_addr)); 47 port="time";
50 48
51 s_in.sin_port = htons(37); /* find port # */ 49 fd = xconnect(host, port);
52 if ((tserv = getservbyname("time", "tcp")) != NULL)
53 s_in.sin_port = tserv->s_port;
54
55 s_in.sin_family = AF_INET;
56
57 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) /* get net connection */
58 perror_msg_and_die("socket");
59
60 if (connect(fd, (struct sockaddr *)&s_in, sizeof(s_in)) < 0) /* connect to time server */
61 perror_msg_and_die("%s", host);
62 50
63 if (read(fd, (void *)&nett, 4) != 4) /* read time from server */ 51 if (read(fd, (void *)&nett, 4) != 4) /* read time from server */
64 error_msg_and_die("%s did not send the complete time", host); 52 error_msg_and_die("%s did not send the complete time", host);