diff options
-rw-r--r-- | include/libbb.h | 1 | ||||
-rw-r--r-- | libbb/xconnect.c | 11 | ||||
-rw-r--r-- | networking/httpd.c | 133 | ||||
-rw-r--r-- | networking/nc.c | 6 | ||||
-rw-r--r-- | networking/telnet.c | 20 | ||||
-rw-r--r-- | networking/tftp.c | 4 | ||||
-rw-r--r-- | networking/wget.c | 92 | ||||
-rw-r--r-- | scripts/defconfig | 1 |
8 files changed, 145 insertions, 123 deletions
diff --git a/include/libbb.h b/include/libbb.h index 704f34e56..07b1d1158 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -531,6 +531,7 @@ USE_DESKTOP(long long) int uncompress(int fd_in, int fd_out); | |||
531 | int inflate(int in, int out); | 531 | int inflate(int in, int out); |
532 | 532 | ||
533 | 533 | ||
534 | /* NB: returns port in host byte order */ | ||
534 | unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port); | 535 | unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port); |
535 | void bb_lookup_host(struct sockaddr_in *s_in, const char *host); | 536 | void bb_lookup_host(struct sockaddr_in *s_in, const char *host); |
536 | 537 | ||
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index a5b16d982..f5a7e6dc8 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
@@ -38,7 +38,7 @@ void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) | |||
38 | * default_port */ | 38 | * default_port */ |
39 | unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port) | 39 | unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port) |
40 | { | 40 | { |
41 | unsigned port_nr = htons(default_port); | 41 | unsigned port_nr = default_port; |
42 | if (port) { | 42 | if (port) { |
43 | int old_errno; | 43 | int old_errno; |
44 | 44 | ||
@@ -49,13 +49,11 @@ unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default | |||
49 | if (errno || port_nr > 65535) { | 49 | if (errno || port_nr > 65535) { |
50 | struct servent *tserv = getservbyname(port, protocol); | 50 | struct servent *tserv = getservbyname(port, protocol); |
51 | if (tserv) | 51 | if (tserv) |
52 | port_nr = tserv->s_port; | 52 | port_nr = ntohs(tserv->s_port); |
53 | } else { | ||
54 | port_nr = htons(port_nr); | ||
55 | } | 53 | } |
56 | errno = old_errno; | 54 | errno = old_errno; |
57 | } | 55 | } |
58 | return port_nr; | 56 | return (uint16_t)port_nr; |
59 | } | 57 | } |
60 | 58 | ||
61 | 59 | ||
@@ -148,7 +146,7 @@ static len_and_sockaddr* str2sockaddr(const char *host, int port, int ai_flags) | |||
148 | r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); | 146 | r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); |
149 | r->len = result->ai_addrlen; | 147 | r->len = result->ai_addrlen; |
150 | memcpy(&r->sa, result->ai_addr, result->ai_addrlen); | 148 | memcpy(&r->sa, result->ai_addr, result->ai_addrlen); |
151 | set_port(r, port); | 149 | set_port(r, htons(port)); |
152 | freeaddrinfo(result); | 150 | freeaddrinfo(result); |
153 | return r; | 151 | return r; |
154 | } | 152 | } |
@@ -237,6 +235,7 @@ static char* sockaddr2str(const struct sockaddr *sa, socklen_t salen, int flags) | |||
237 | flags | NI_NUMERICSERV /* do not resolve port# */ | 235 | flags | NI_NUMERICSERV /* do not resolve port# */ |
238 | ); | 236 | ); |
239 | if (rc) return NULL; | 237 | if (rc) return NULL; |
238 | // We probably need to use [%s]:%s for IPv6... | ||
240 | return xasprintf("%s:%s", host, serv); | 239 | return xasprintf("%s:%s", host, serv); |
241 | } | 240 | } |
242 | 241 | ||
diff --git a/networking/httpd.c b/networking/httpd.c index 818590f78..f8773685e 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -142,7 +142,7 @@ typedef struct { | |||
142 | 142 | ||
143 | unsigned int rmt_ip; | 143 | unsigned int rmt_ip; |
144 | #if ENABLE_FEATURE_HTTPD_CGI || DEBUG | 144 | #if ENABLE_FEATURE_HTTPD_CGI || DEBUG |
145 | char rmt_ip_str[16]; /* for set env REMOTE_ADDR */ | 145 | char *rmt_ip_str; /* for set env REMOTE_ADDR */ |
146 | #endif | 146 | #endif |
147 | unsigned port; /* server initial port and for | 147 | unsigned port; /* server initial port and for |
148 | set env REMOTE_PORT */ | 148 | set env REMOTE_PORT */ |
@@ -817,30 +817,11 @@ static void decodeBase64(char *Data) | |||
817 | ****************************************************************************/ | 817 | ****************************************************************************/ |
818 | static int openServer(void) | 818 | static int openServer(void) |
819 | { | 819 | { |
820 | struct sockaddr_in lsocket; | ||
821 | int fd; | 820 | int fd; |
822 | 821 | ||
823 | /* create the socket right now */ | 822 | /* create the socket right now */ |
824 | /* inet_addr() returns a value that is already in network order */ | 823 | fd = create_and_bind_stream_or_die(NULL, config->port); |
825 | memset(&lsocket, 0, sizeof(lsocket)); | ||
826 | lsocket.sin_family = AF_INET; | ||
827 | lsocket.sin_addr.s_addr = INADDR_ANY; | ||
828 | lsocket.sin_port = htons(config->port); | ||
829 | fd = xsocket(AF_INET, SOCK_STREAM, 0); | ||
830 | /* tell the OS it's OK to reuse a previous address even though */ | ||
831 | /* it may still be in a close down state. Allows bind to succeed. */ | ||
832 | #ifdef SO_REUSEPORT | ||
833 | { | ||
834 | static const int on = 1; | ||
835 | setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, | ||
836 | (void *)&on, sizeof(on)); | ||
837 | } | ||
838 | #else | ||
839 | setsockopt_reuseaddr(fd); | ||
840 | #endif | ||
841 | xbind(fd, (struct sockaddr *)&lsocket, sizeof(lsocket)); | ||
842 | xlisten(fd, 9); | 824 | xlisten(fd, 9); |
843 | signal(SIGCHLD, SIG_IGN); /* prevent zombie (defunct) processes */ | ||
844 | return fd; | 825 | return fd; |
845 | } | 826 | } |
846 | 827 | ||
@@ -1070,7 +1051,19 @@ static int sendCgi(const char *url, | |||
1070 | setenv1("SERVER_SOFTWARE", httpdVersion); | 1051 | setenv1("SERVER_SOFTWARE", httpdVersion); |
1071 | putenv("SERVER_PROTOCOL=HTTP/1.0"); | 1052 | putenv("SERVER_PROTOCOL=HTTP/1.0"); |
1072 | putenv("GATEWAY_INTERFACE=CGI/1.1"); | 1053 | putenv("GATEWAY_INTERFACE=CGI/1.1"); |
1073 | setenv1("REMOTE_ADDR", config->rmt_ip_str); | 1054 | /* Having _separate_ variables for IP and port defeats |
1055 | * the purpose of having socket abstraction. Which "port" | ||
1056 | * are you using on Unix domain socket? | ||
1057 | * IOW - REMOTE_PEER="1.2.3.4:56" makes much more sense. | ||
1058 | * Oh well... */ | ||
1059 | { | ||
1060 | char *p = config->rmt_ip_str ? : ""; | ||
1061 | char *cp = strrchr(p, ':'); | ||
1062 | if (ENABLE_FEATURE_IPV6 && cp && strchr(cp, ']')) | ||
1063 | cp = NULL; | ||
1064 | if (cp) *cp = '\0'; /* delete :PORT */ | ||
1065 | setenv1("REMOTE_ADDR", p); | ||
1066 | } | ||
1074 | #if ENABLE_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV | 1067 | #if ENABLE_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV |
1075 | setenv_long("REMOTE_PORT", config->port); | 1068 | setenv_long("REMOTE_PORT", config->port); |
1076 | #endif | 1069 | #endif |
@@ -1330,17 +1323,17 @@ static int checkPermIP(void) | |||
1330 | for (cur = config->ip_a_d; cur; cur = cur->next) { | 1323 | for (cur = config->ip_a_d; cur; cur = cur->next) { |
1331 | #if DEBUG | 1324 | #if DEBUG |
1332 | fprintf(stderr, "checkPermIP: '%s' ? ", config->rmt_ip_str); | 1325 | fprintf(stderr, "checkPermIP: '%s' ? ", config->rmt_ip_str); |
1326 | fprintf(stderr, "'%u.%u.%u.%u/%u.%u.%u.%u'\n", | ||
1327 | (unsigned char)(cur->ip >> 24), | ||
1328 | (unsigned char)(cur->ip >> 16), | ||
1329 | (unsigned char)(cur->ip >> 8), | ||
1330 | (unsigned char)(cur->ip), | ||
1331 | (unsigned char)(cur->mask >> 24), | ||
1332 | (unsigned char)(cur->mask >> 16), | ||
1333 | (unsigned char)(cur->mask >> 8), | ||
1334 | (unsigned char)(cur->mask) | ||
1335 | ); | ||
1333 | #endif | 1336 | #endif |
1334 | if (DEBUG) | ||
1335 | fprintf(stderr, "'%u.%u.%u.%u/%u.%u.%u.%u'\n", | ||
1336 | (unsigned char)(cur->ip >> 24), | ||
1337 | (unsigned char)(cur->ip >> 16), | ||
1338 | (unsigned char)(cur->ip >> 8), | ||
1339 | cur->ip & 0xff, | ||
1340 | (unsigned char)(cur->mask >> 24), | ||
1341 | (unsigned char)(cur->mask >> 16), | ||
1342 | (unsigned char)(cur->mask >> 8), | ||
1343 | cur->mask & 0xff); | ||
1344 | if ((config->rmt_ip & cur->mask) == cur->ip) | 1337 | if ((config->rmt_ip & cur->mask) == cur->ip) |
1345 | return cur->allow_deny == 'A'; /* Allow/Deny */ | 1338 | return cur->allow_deny == 'A'; /* Allow/Deny */ |
1346 | } | 1339 | } |
@@ -1765,6 +1758,8 @@ static void handleIncoming(void) | |||
1765 | ****************************************************************************/ | 1758 | ****************************************************************************/ |
1766 | static int miniHttpd(int server) | 1759 | static int miniHttpd(int server) |
1767 | { | 1760 | { |
1761 | static const int on = 1; | ||
1762 | |||
1768 | fd_set readfd, portfd; | 1763 | fd_set readfd, portfd; |
1769 | 1764 | ||
1770 | FD_ZERO(&portfd); | 1765 | FD_ZERO(&portfd); |
@@ -1772,9 +1767,13 @@ static int miniHttpd(int server) | |||
1772 | 1767 | ||
1773 | /* copy the ports we are watching to the readfd set */ | 1768 | /* copy the ports we are watching to the readfd set */ |
1774 | while (1) { | 1769 | while (1) { |
1775 | int on, s; | 1770 | int s; |
1776 | socklen_t fromAddrLen; | 1771 | union { |
1777 | struct sockaddr_in fromAddr; | 1772 | struct sockaddr sa; |
1773 | struct sockaddr_in sin; | ||
1774 | USE_FEATURE_IPV6(struct sockaddr_in6 sin6;) | ||
1775 | } fromAddr; | ||
1776 | socklen_t fromAddrLen = sizeof(fromAddr); | ||
1778 | 1777 | ||
1779 | /* Now wait INDEFINITELY on the set of sockets! */ | 1778 | /* Now wait INDEFINITELY on the set of sockets! */ |
1780 | readfd = portfd; | 1779 | readfd = portfd; |
@@ -1782,27 +1781,31 @@ static int miniHttpd(int server) | |||
1782 | continue; | 1781 | continue; |
1783 | if (!FD_ISSET(server, &readfd)) | 1782 | if (!FD_ISSET(server, &readfd)) |
1784 | continue; | 1783 | continue; |
1785 | fromAddrLen = sizeof(fromAddr); | 1784 | s = accept(server, &fromAddr.sa, &fromAddrLen); |
1786 | s = accept(server, (struct sockaddr *)&fromAddr, &fromAddrLen); | ||
1787 | if (s < 0) | 1785 | if (s < 0) |
1788 | continue; | 1786 | continue; |
1789 | config->accepted_socket = s; | 1787 | config->accepted_socket = s; |
1790 | config->rmt_ip = ntohl(fromAddr.sin_addr.s_addr); | 1788 | config->rmt_ip = 0; |
1789 | config->port = 0; | ||
1791 | #if ENABLE_FEATURE_HTTPD_CGI || DEBUG | 1790 | #if ENABLE_FEATURE_HTTPD_CGI || DEBUG |
1792 | sprintf(config->rmt_ip_str, "%u.%u.%u.%u", | 1791 | free(config->rmt_ip_str); |
1793 | (unsigned char)(config->rmt_ip >> 24), | 1792 | config->rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr.sa, fromAddrLen); |
1794 | (unsigned char)(config->rmt_ip >> 16), | ||
1795 | (unsigned char)(config->rmt_ip >> 8), | ||
1796 | config->rmt_ip & 0xff); | ||
1797 | config->port = ntohs(fromAddr.sin_port); | ||
1798 | #if DEBUG | 1793 | #if DEBUG |
1799 | bb_error_msg("connection from IP=%s, port %u", | 1794 | bb_error_msg("connection from '%s'", config->rmt_ip_str); |
1800 | config->rmt_ip_str, config->port); | ||
1801 | #endif | 1795 | #endif |
1802 | #endif /* FEATURE_HTTPD_CGI */ | 1796 | #endif /* FEATURE_HTTPD_CGI */ |
1797 | if (fromAddr.sa.sa_family == AF_INET) { | ||
1798 | config->rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr); | ||
1799 | config->port = ntohs(fromAddr.sin.sin_port); | ||
1800 | } | ||
1801 | #if ENABLE_FEATURE_IPV6 | ||
1802 | if (fromAddr.sa.sa_family == AF_INET6) { | ||
1803 | //config->rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr); | ||
1804 | config->port = ntohs(fromAddr.sin6.sin6_port); | ||
1805 | } | ||
1806 | #endif | ||
1803 | 1807 | ||
1804 | /* set the KEEPALIVE option to cull dead connections */ | 1808 | /* set the KEEPALIVE option to cull dead connections */ |
1805 | on = 1; | ||
1806 | setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)); | 1809 | setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)); |
1807 | 1810 | ||
1808 | if (DEBUG || fork() == 0) { | 1811 | if (DEBUG || fork() == 0) { |
@@ -1823,19 +1826,30 @@ static int miniHttpd(int server) | |||
1823 | /* from inetd */ | 1826 | /* from inetd */ |
1824 | static int miniHttpd_inetd(void) | 1827 | static int miniHttpd_inetd(void) |
1825 | { | 1828 | { |
1826 | struct sockaddr_in fromAddrLen; | 1829 | union { |
1827 | socklen_t sinlen = sizeof(struct sockaddr_in); | 1830 | struct sockaddr sa; |
1828 | 1831 | struct sockaddr_in sin; | |
1829 | getpeername(0, (struct sockaddr *)&fromAddrLen, &sinlen); | 1832 | USE_FEATURE_IPV6(struct sockaddr_in6 sin6;) |
1830 | config->rmt_ip = ntohl(fromAddrLen.sin_addr.s_addr); | 1833 | } fromAddr; |
1831 | #if ENABLE_FEATURE_HTTPD_CGI | 1834 | socklen_t fromAddrLen = sizeof(fromAddr); |
1832 | sprintf(config->rmt_ip_str, "%u.%u.%u.%u", | 1835 | |
1833 | (unsigned char)(config->rmt_ip >> 24), | 1836 | getpeername(0, &fromAddr.sa, &fromAddrLen); |
1834 | (unsigned char)(config->rmt_ip >> 16), | 1837 | config->rmt_ip = 0; |
1835 | (unsigned char)(config->rmt_ip >> 8), | 1838 | config->port = 0; |
1836 | config->rmt_ip & 0xff); | 1839 | #if ENABLE_FEATURE_HTTPD_CGI || DEBUG |
1840 | free(config->rmt_ip_str); | ||
1841 | config->rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr.sa, fromAddrLen); | ||
1842 | #endif | ||
1843 | if (fromAddr.sa.sa_family == AF_INET) { | ||
1844 | config->rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr); | ||
1845 | config->port = ntohs(fromAddr.sin.sin_port); | ||
1846 | } | ||
1847 | #if ENABLE_FEATURE_IPV6 | ||
1848 | if (fromAddr.sa.sa_family == AF_INET6) { | ||
1849 | //config->rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr); | ||
1850 | config->port = ntohs(fromAddr.sin6.sin6_port); | ||
1851 | } | ||
1837 | #endif | 1852 | #endif |
1838 | config->port = ntohs(fromAddrLen.sin_port); | ||
1839 | handleIncoming(); | 1853 | handleIncoming(); |
1840 | return 0; | 1854 | return 0; |
1841 | } | 1855 | } |
@@ -1945,6 +1959,7 @@ int httpd_main(int argc, char *argv[]) | |||
1945 | 1959 | ||
1946 | xchdir(home_httpd); | 1960 | xchdir(home_httpd); |
1947 | if (!(opt & OPT_INETD)) { | 1961 | if (!(opt & OPT_INETD)) { |
1962 | signal(SIGCHLD, SIG_IGN); | ||
1948 | config->server_socket = openServer(); | 1963 | config->server_socket = openServer(); |
1949 | #if ENABLE_FEATURE_HTTPD_SETUID | 1964 | #if ENABLE_FEATURE_HTTPD_SETUID |
1950 | /* drop privileges */ | 1965 | /* drop privileges */ |
diff --git a/networking/nc.c b/networking/nc.c index 1419609e0..e1c22839c 100644 --- a/networking/nc.c +++ b/networking/nc.c | |||
@@ -37,7 +37,10 @@ int nc_main(int argc, char **argv) | |||
37 | "" USE_NC_SERVER("lp:") USE_NC_EXTRA("w:i:f:e:") )) > 0 | 37 | "" USE_NC_SERVER("lp:") USE_NC_EXTRA("w:i:f:e:") )) > 0 |
38 | ) { | 38 | ) { |
39 | if (ENABLE_NC_SERVER && opt=='l') USE_NC_SERVER(do_listen++); | 39 | if (ENABLE_NC_SERVER && opt=='l') USE_NC_SERVER(do_listen++); |
40 | else if (ENABLE_NC_SERVER && opt=='p') USE_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0)); | 40 | else if (ENABLE_NC_SERVER && opt=='p') { |
41 | USE_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0)); | ||
42 | USE_NC_SERVER(lport = htons(lport)); | ||
43 | } | ||
41 | else if (ENABLE_NC_EXTRA && opt=='w') USE_NC_EXTRA( wsecs = xatou(optarg)); | 44 | else if (ENABLE_NC_EXTRA && opt=='w') USE_NC_EXTRA( wsecs = xatou(optarg)); |
42 | else if (ENABLE_NC_EXTRA && opt=='i') USE_NC_EXTRA( delay = xatou(optarg)); | 45 | else if (ENABLE_NC_EXTRA && opt=='i') USE_NC_EXTRA( delay = xatou(optarg)); |
43 | else if (ENABLE_NC_EXTRA && opt=='f') USE_NC_EXTRA( cfd = xopen(optarg, O_RDWR)); | 46 | else if (ENABLE_NC_EXTRA && opt=='f') USE_NC_EXTRA( cfd = xopen(optarg, O_RDWR)); |
@@ -119,6 +122,7 @@ int nc_main(int argc, char **argv) | |||
119 | 122 | ||
120 | address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; | 123 | address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; |
121 | address.sin_port = bb_lookup_port(argv[1], "tcp", 0); | 124 | address.sin_port = bb_lookup_port(argv[1], "tcp", 0); |
125 | address.sin_port = htons(address.sin_port); | ||
122 | 126 | ||
123 | xconnect(sfd, (struct sockaddr *) &address, sizeof(address)); | 127 | xconnect(sfd, (struct sockaddr *) &address, sizeof(address)); |
124 | cfd = sfd; | 128 | cfd = sfd; |
diff --git a/networking/telnet.c b/networking/telnet.c index 5ca64e133..86586600b 100644 --- a/networking/telnet.c +++ b/networking/telnet.c | |||
@@ -617,19 +617,17 @@ int telnet_main(int argc, char** argv) | |||
617 | #ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN | 617 | #ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN |
618 | if (1 & getopt32(argc, argv, "al:", &autologin)) | 618 | if (1 & getopt32(argc, argv, "al:", &autologin)) |
619 | autologin = getenv("USER"); | 619 | autologin = getenv("USER"); |
620 | 620 | argv += optind; | |
621 | if (optind < argc) { | ||
622 | host = argv[optind++]; | ||
623 | port = bb_lookup_port((optind < argc) ? argv[optind++] : | ||
624 | "telnet", "tcp", 23); | ||
625 | if (optind < argc) | ||
626 | bb_show_usage(); | ||
627 | } else | ||
628 | bb_show_usage(); | ||
629 | #else | 621 | #else |
630 | host = argv[1]; | 622 | argv++; |
631 | port = bb_lookup_port((argc > 2) ? argv[2] : "telnet", "tcp", 23); | ||
632 | #endif | 623 | #endif |
624 | if (!*argv) | ||
625 | bb_show_usage(); | ||
626 | host = *argv++; | ||
627 | port = bb_lookup_port(*argv ? *argv++ : "telnet", "tcp", 23); | ||
628 | if (*argv) /* extra params?? */ | ||
629 | bb_show_usage(); | ||
630 | |||
633 | G.netfd = create_and_connect_stream_or_die(host, port); | 631 | G.netfd = create_and_connect_stream_or_die(host, port); |
634 | 632 | ||
635 | setsockopt(G.netfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one); | 633 | setsockopt(G.netfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one); |
diff --git a/networking/tftp.c b/networking/tftp.c index eaeb80857..43e835a5d 100644 --- a/networking/tftp.c +++ b/networking/tftp.c | |||
@@ -132,7 +132,7 @@ static int tftp( | |||
132 | #endif | 132 | #endif |
133 | const len_and_sockaddr *peer_lsa, | 133 | const len_and_sockaddr *peer_lsa, |
134 | const char *remotefile, const int localfd, | 134 | const char *remotefile, const int localfd, |
135 | const unsigned port, int tftp_bufsize) | 135 | unsigned port, int tftp_bufsize) |
136 | { | 136 | { |
137 | struct timeval tv; | 137 | struct timeval tv; |
138 | fd_set rfds; | 138 | fd_set rfds; |
@@ -154,6 +154,8 @@ static int tftp( | |||
154 | char *xbuf = xmalloc(tftp_bufsize += 4); | 154 | char *xbuf = xmalloc(tftp_bufsize += 4); |
155 | char *rbuf = xmalloc(tftp_bufsize); | 155 | char *rbuf = xmalloc(tftp_bufsize); |
156 | 156 | ||
157 | port = htons(port); | ||
158 | |||
157 | socketfd = xsocket(peer_lsa->sa.sa_family, SOCK_DGRAM, 0); | 159 | socketfd = xsocket(peer_lsa->sa.sa_family, SOCK_DGRAM, 0); |
158 | 160 | ||
159 | /* build opcode */ | 161 | /* build opcode */ |
diff --git a/networking/wget.c b/networking/wget.c index ee5aa63e9..22e610699 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -24,7 +24,7 @@ struct host_info { | |||
24 | }; | 24 | }; |
25 | 25 | ||
26 | static void parse_url(char *url, struct host_info *h); | 26 | static void parse_url(char *url, struct host_info *h); |
27 | static FILE *open_socket(struct sockaddr_in *s_in); | 27 | static FILE *open_socket(len_and_sockaddr *lsa); |
28 | static char *gethdr(char *buf, size_t bufsiz, FILE *fp, int *istrunc); | 28 | static char *gethdr(char *buf, size_t bufsiz, FILE *fp, int *istrunc); |
29 | static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf); | 29 | static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf); |
30 | 30 | ||
@@ -90,7 +90,7 @@ int wget_main(int argc, char **argv) | |||
90 | { | 90 | { |
91 | char buf[512]; | 91 | char buf[512]; |
92 | struct host_info server, target; | 92 | struct host_info server, target; |
93 | struct sockaddr_in s_in; | 93 | len_and_sockaddr *lsa; |
94 | int n, status; | 94 | int n, status; |
95 | int port; | 95 | int port; |
96 | int try = 5; | 96 | int try = 5; |
@@ -189,7 +189,7 @@ int wget_main(int argc, char **argv) | |||
189 | if (!fname_out) { | 189 | if (!fname_out) { |
190 | // Dirty hack. Needed because bb_get_last_path_component | 190 | // Dirty hack. Needed because bb_get_last_path_component |
191 | // will destroy trailing / by storing '\0' in last byte! | 191 | // will destroy trailing / by storing '\0' in last byte! |
192 | if (*target.path && target.path[strlen(target.path)-1] != '/') { | 192 | if (!last_char_is(target.path, '/')) { |
193 | fname_out = | 193 | fname_out = |
194 | #if ENABLE_FEATURE_WGET_STATUSBAR | 194 | #if ENABLE_FEATURE_WGET_STATUSBAR |
195 | curfile = | 195 | curfile = |
@@ -233,11 +233,11 @@ int wget_main(int argc, char **argv) | |||
233 | /* We want to do exactly _one_ DNS lookup, since some | 233 | /* We want to do exactly _one_ DNS lookup, since some |
234 | * sites (i.e. ftp.us.debian.org) use round-robin DNS | 234 | * sites (i.e. ftp.us.debian.org) use round-robin DNS |
235 | * and we want to connect to only one IP... */ | 235 | * and we want to connect to only one IP... */ |
236 | bb_lookup_host(&s_in, server.host); | 236 | lsa = host2sockaddr(server.host, server.port); |
237 | s_in.sin_port = server.port; | ||
238 | if (!(opt & WGET_OPT_QUIET)) { | 237 | if (!(opt & WGET_OPT_QUIET)) { |
239 | fprintf(stderr, "Connecting to %s[%s]:%d\n", | 238 | fprintf(stderr, "Connecting to %s [%s]\n", server.host, |
240 | server.host, inet_ntoa(s_in.sin_addr), ntohs(server.port)); | 239 | xmalloc_sockaddr2dotted(&lsa->sa, lsa->len)); |
240 | /* We leak xmalloc_sockaddr2dotted result */ | ||
241 | } | 241 | } |
242 | 242 | ||
243 | if (use_proxy || !target.is_ftp) { | 243 | if (use_proxy || !target.is_ftp) { |
@@ -254,26 +254,29 @@ int wget_main(int argc, char **argv) | |||
254 | * Open socket to http server | 254 | * Open socket to http server |
255 | */ | 255 | */ |
256 | if (sfp) fclose(sfp); | 256 | if (sfp) fclose(sfp); |
257 | sfp = open_socket(&s_in); | 257 | sfp = open_socket(lsa); |
258 | 258 | ||
259 | /* | 259 | /* |
260 | * Send HTTP request. | 260 | * Send HTTP request. |
261 | */ | 261 | */ |
262 | if (use_proxy) { | 262 | if (use_proxy) { |
263 | const char *format = "GET %stp://%s:%d/%s HTTP/1.1\r\n"; | 263 | // const char *format = "GET %stp://%s:%d/%s HTTP/1.1\r\n"; |
264 | #if ENABLE_FEATURE_WGET_IP6_LITERAL | 264 | //#if ENABLE_FEATURE_WGET_IP6_LITERAL |
265 | if (strchr(target.host, ':')) | 265 | // if (strchr(target.host, ':')) |
266 | format = "GET %stp://[%s]:%d/%s HTTP/1.1\r\n"; | 266 | // format = "GET %stp://[%s]:%d/%s HTTP/1.1\r\n"; |
267 | #endif | 267 | //#endif |
268 | fprintf(sfp, format, | 268 | // fprintf(sfp, format, |
269 | // target.is_ftp ? "f" : "ht", target.host, | ||
270 | // ntohs(target.port), target.path); | ||
271 | fprintf(sfp, "GET %stp://%s/%s HTTP/1.1\r\n", | ||
269 | target.is_ftp ? "f" : "ht", target.host, | 272 | target.is_ftp ? "f" : "ht", target.host, |
270 | ntohs(target.port), target.path); | 273 | target.path); |
271 | } else { | 274 | } else { |
272 | fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path); | 275 | fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path); |
273 | } | 276 | } |
274 | 277 | ||
275 | fprintf(sfp, "Host: %s:%u\r\nUser-Agent: %s\r\n", | 278 | fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n", |
276 | target.host, target.port, user_agent); | 279 | target.host, user_agent); |
277 | 280 | ||
278 | #if ENABLE_FEATURE_WGET_AUTHENTICATION | 281 | #if ENABLE_FEATURE_WGET_AUTHENTICATION |
279 | if (target.user) { | 282 | if (target.user) { |
@@ -357,8 +360,8 @@ int wget_main(int argc, char **argv) | |||
357 | server.host = target.host; | 360 | server.host = target.host; |
358 | server.port = target.port; | 361 | server.port = target.port; |
359 | } | 362 | } |
360 | bb_lookup_host(&s_in, server.host); | 363 | free(lsa); |
361 | s_in.sin_port = server.port; | 364 | lsa = host2sockaddr(server.host, server.port); |
362 | break; | 365 | break; |
363 | } | 366 | } |
364 | } | 367 | } |
@@ -375,7 +378,7 @@ int wget_main(int argc, char **argv) | |||
375 | if (!target.user) | 378 | if (!target.user) |
376 | target.user = xstrdup("anonymous:busybox@"); | 379 | target.user = xstrdup("anonymous:busybox@"); |
377 | 380 | ||
378 | sfp = open_socket(&s_in); | 381 | sfp = open_socket(lsa); |
379 | if (ftpcmd(NULL, NULL, sfp, buf) != 220) | 382 | if (ftpcmd(NULL, NULL, sfp, buf) != 220) |
380 | bb_error_msg_and_die("%s", buf+4); | 383 | bb_error_msg_and_die("%s", buf+4); |
381 | 384 | ||
@@ -429,8 +432,8 @@ int wget_main(int argc, char **argv) | |||
429 | s = strrchr(buf, ','); | 432 | s = strrchr(buf, ','); |
430 | if (!s) goto pasv_error; | 433 | if (!s) goto pasv_error; |
431 | port += xatou_range(s+1, 0, 255) * 256; | 434 | port += xatou_range(s+1, 0, 255) * 256; |
432 | s_in.sin_port = htons(port); | 435 | set_port(lsa, htons(port)); |
433 | dfp = open_socket(&s_in); | 436 | dfp = open_socket(lsa); |
434 | 437 | ||
435 | if (beg_range) { | 438 | if (beg_range) { |
436 | sprintf(buf, "REST %"OFF_FMT"d", beg_range); | 439 | sprintf(buf, "REST %"OFF_FMT"d", beg_range); |
@@ -564,36 +567,37 @@ static void parse_url(char *src_url, struct host_info *h) | |||
564 | 567 | ||
565 | sp = h->host; | 568 | sp = h->host; |
566 | 569 | ||
567 | #if ENABLE_FEATURE_WGET_IP6_LITERAL | 570 | //host2sockaddr does this itself |
568 | if (sp[0] == '[') { | 571 | //#if ENABLE_FEATURE_WGET_IP6_LITERAL |
569 | char *ep; | 572 | // if (sp[0] == '[') { |
570 | 573 | // char *ep; | |
571 | ep = sp + 1; | 574 | // |
572 | while (*ep == ':' || isxdigit(*ep)) | 575 | // ep = sp + 1; |
573 | ep++; | 576 | // while (*ep == ':' || isxdigit(*ep)) |
574 | if (*ep == ']') { | 577 | // ep++; |
575 | h->host++; | 578 | // if (*ep == ']') { |
576 | *ep = '\0'; | 579 | // h->host++; |
577 | sp = ep + 1; | 580 | // *ep = '\0'; |
578 | } | 581 | // sp = ep + 1; |
579 | } | 582 | // } |
580 | #endif | 583 | // } |
581 | 584 | //#endif | |
582 | p = strchr(sp, ':'); | 585 | // |
583 | if (p != NULL) { | 586 | // p = strchr(sp, ':'); |
584 | *p = '\0'; | 587 | // if (p != NULL) { |
585 | h->port = htons(xatou16(p + 1)); | 588 | // *p = '\0'; |
586 | } | 589 | // h->port = htons(xatou16(p + 1)); |
590 | // } | ||
587 | } | 591 | } |
588 | 592 | ||
589 | 593 | ||
590 | static FILE *open_socket(struct sockaddr_in *s_in) | 594 | static FILE *open_socket(len_and_sockaddr *lsa) |
591 | { | 595 | { |
592 | FILE *fp; | 596 | FILE *fp; |
593 | 597 | ||
594 | /* glibc 2.4 seems to try seeking on it - ??! */ | 598 | /* glibc 2.4 seems to try seeking on it - ??! */ |
595 | /* hopefully it understands what ESPIPE means... */ | 599 | /* hopefully it understands what ESPIPE means... */ |
596 | fp = fdopen(xconnect_tcp_v4(s_in), "r+"); | 600 | fp = fdopen(xconnect_stream(lsa), "r+"); |
597 | if (fp == NULL) | 601 | if (fp == NULL) |
598 | bb_perror_msg_and_die("fdopen"); | 602 | bb_perror_msg_and_die("fdopen"); |
599 | 603 | ||
diff --git a/scripts/defconfig b/scripts/defconfig index 5ef6cff29..2c82ed474 100644 --- a/scripts/defconfig +++ b/scripts/defconfig | |||
@@ -580,7 +580,6 @@ CONFIG_VCONFIG=y | |||
580 | CONFIG_WGET=y | 580 | CONFIG_WGET=y |
581 | CONFIG_FEATURE_WGET_STATUSBAR=y | 581 | CONFIG_FEATURE_WGET_STATUSBAR=y |
582 | CONFIG_FEATURE_WGET_AUTHENTICATION=y | 582 | CONFIG_FEATURE_WGET_AUTHENTICATION=y |
583 | CONFIG_FEATURE_WGET_IP6_LITERAL=y | ||
584 | CONFIG_FEATURE_WGET_LONG_OPTIONS=y | 583 | CONFIG_FEATURE_WGET_LONG_OPTIONS=y |
585 | CONFIG_ZCIP=y | 584 | CONFIG_ZCIP=y |
586 | 585 | ||