next part of ipv6-ization is here: wget & httpd
This commit is contained in:
parent
f8138d1f91
commit
6536a9b583
@ -531,6 +531,7 @@ USE_DESKTOP(long long) int uncompress(int fd_in, int fd_out);
|
|||||||
int inflate(int in, int out);
|
int inflate(int in, int out);
|
||||||
|
|
||||||
|
|
||||||
|
/* NB: returns port in host byte order */
|
||||||
unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port);
|
unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port);
|
||||||
void bb_lookup_host(struct sockaddr_in *s_in, const char *host);
|
void bb_lookup_host(struct sockaddr_in *s_in, const char *host);
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen)
|
|||||||
* default_port */
|
* default_port */
|
||||||
unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port)
|
unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port)
|
||||||
{
|
{
|
||||||
unsigned port_nr = htons(default_port);
|
unsigned port_nr = default_port;
|
||||||
if (port) {
|
if (port) {
|
||||||
int old_errno;
|
int old_errno;
|
||||||
|
|
||||||
@ -49,13 +49,11 @@ unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default
|
|||||||
if (errno || port_nr > 65535) {
|
if (errno || port_nr > 65535) {
|
||||||
struct servent *tserv = getservbyname(port, protocol);
|
struct servent *tserv = getservbyname(port, protocol);
|
||||||
if (tserv)
|
if (tserv)
|
||||||
port_nr = tserv->s_port;
|
port_nr = ntohs(tserv->s_port);
|
||||||
} else {
|
|
||||||
port_nr = htons(port_nr);
|
|
||||||
}
|
}
|
||||||
errno = old_errno;
|
errno = old_errno;
|
||||||
}
|
}
|
||||||
return port_nr;
|
return (uint16_t)port_nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -148,7 +146,7 @@ static len_and_sockaddr* str2sockaddr(const char *host, int port, int ai_flags)
|
|||||||
r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen);
|
r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen);
|
||||||
r->len = result->ai_addrlen;
|
r->len = result->ai_addrlen;
|
||||||
memcpy(&r->sa, result->ai_addr, result->ai_addrlen);
|
memcpy(&r->sa, result->ai_addr, result->ai_addrlen);
|
||||||
set_port(r, port);
|
set_port(r, htons(port));
|
||||||
freeaddrinfo(result);
|
freeaddrinfo(result);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -237,6 +235,7 @@ static char* sockaddr2str(const struct sockaddr *sa, socklen_t salen, int flags)
|
|||||||
flags | NI_NUMERICSERV /* do not resolve port# */
|
flags | NI_NUMERICSERV /* do not resolve port# */
|
||||||
);
|
);
|
||||||
if (rc) return NULL;
|
if (rc) return NULL;
|
||||||
|
// We probably need to use [%s]:%s for IPv6...
|
||||||
return xasprintf("%s:%s", host, serv);
|
return xasprintf("%s:%s", host, serv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ typedef struct {
|
|||||||
|
|
||||||
unsigned int rmt_ip;
|
unsigned int rmt_ip;
|
||||||
#if ENABLE_FEATURE_HTTPD_CGI || DEBUG
|
#if ENABLE_FEATURE_HTTPD_CGI || DEBUG
|
||||||
char rmt_ip_str[16]; /* for set env REMOTE_ADDR */
|
char *rmt_ip_str; /* for set env REMOTE_ADDR */
|
||||||
#endif
|
#endif
|
||||||
unsigned port; /* server initial port and for
|
unsigned port; /* server initial port and for
|
||||||
set env REMOTE_PORT */
|
set env REMOTE_PORT */
|
||||||
@ -817,30 +817,11 @@ static void decodeBase64(char *Data)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static int openServer(void)
|
static int openServer(void)
|
||||||
{
|
{
|
||||||
struct sockaddr_in lsocket;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* create the socket right now */
|
/* create the socket right now */
|
||||||
/* inet_addr() returns a value that is already in network order */
|
fd = create_and_bind_stream_or_die(NULL, config->port);
|
||||||
memset(&lsocket, 0, sizeof(lsocket));
|
|
||||||
lsocket.sin_family = AF_INET;
|
|
||||||
lsocket.sin_addr.s_addr = INADDR_ANY;
|
|
||||||
lsocket.sin_port = htons(config->port);
|
|
||||||
fd = xsocket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
/* tell the OS it's OK to reuse a previous address even though */
|
|
||||||
/* it may still be in a close down state. Allows bind to succeed. */
|
|
||||||
#ifdef SO_REUSEPORT
|
|
||||||
{
|
|
||||||
static const int on = 1;
|
|
||||||
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT,
|
|
||||||
(void *)&on, sizeof(on));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
setsockopt_reuseaddr(fd);
|
|
||||||
#endif
|
|
||||||
xbind(fd, (struct sockaddr *)&lsocket, sizeof(lsocket));
|
|
||||||
xlisten(fd, 9);
|
xlisten(fd, 9);
|
||||||
signal(SIGCHLD, SIG_IGN); /* prevent zombie (defunct) processes */
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1070,7 +1051,19 @@ static int sendCgi(const char *url,
|
|||||||
setenv1("SERVER_SOFTWARE", httpdVersion);
|
setenv1("SERVER_SOFTWARE", httpdVersion);
|
||||||
putenv("SERVER_PROTOCOL=HTTP/1.0");
|
putenv("SERVER_PROTOCOL=HTTP/1.0");
|
||||||
putenv("GATEWAY_INTERFACE=CGI/1.1");
|
putenv("GATEWAY_INTERFACE=CGI/1.1");
|
||||||
setenv1("REMOTE_ADDR", config->rmt_ip_str);
|
/* Having _separate_ variables for IP and port defeats
|
||||||
|
* the purpose of having socket abstraction. Which "port"
|
||||||
|
* are you using on Unix domain socket?
|
||||||
|
* IOW - REMOTE_PEER="1.2.3.4:56" makes much more sense.
|
||||||
|
* Oh well... */
|
||||||
|
{
|
||||||
|
char *p = config->rmt_ip_str ? : "";
|
||||||
|
char *cp = strrchr(p, ':');
|
||||||
|
if (ENABLE_FEATURE_IPV6 && cp && strchr(cp, ']'))
|
||||||
|
cp = NULL;
|
||||||
|
if (cp) *cp = '\0'; /* delete :PORT */
|
||||||
|
setenv1("REMOTE_ADDR", p);
|
||||||
|
}
|
||||||
#if ENABLE_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
|
#if ENABLE_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
|
||||||
setenv_long("REMOTE_PORT", config->port);
|
setenv_long("REMOTE_PORT", config->port);
|
||||||
#endif
|
#endif
|
||||||
@ -1330,17 +1323,17 @@ static int checkPermIP(void)
|
|||||||
for (cur = config->ip_a_d; cur; cur = cur->next) {
|
for (cur = config->ip_a_d; cur; cur = cur->next) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
fprintf(stderr, "checkPermIP: '%s' ? ", config->rmt_ip_str);
|
fprintf(stderr, "checkPermIP: '%s' ? ", config->rmt_ip_str);
|
||||||
|
fprintf(stderr, "'%u.%u.%u.%u/%u.%u.%u.%u'\n",
|
||||||
|
(unsigned char)(cur->ip >> 24),
|
||||||
|
(unsigned char)(cur->ip >> 16),
|
||||||
|
(unsigned char)(cur->ip >> 8),
|
||||||
|
(unsigned char)(cur->ip),
|
||||||
|
(unsigned char)(cur->mask >> 24),
|
||||||
|
(unsigned char)(cur->mask >> 16),
|
||||||
|
(unsigned char)(cur->mask >> 8),
|
||||||
|
(unsigned char)(cur->mask)
|
||||||
|
);
|
||||||
#endif
|
#endif
|
||||||
if (DEBUG)
|
|
||||||
fprintf(stderr, "'%u.%u.%u.%u/%u.%u.%u.%u'\n",
|
|
||||||
(unsigned char)(cur->ip >> 24),
|
|
||||||
(unsigned char)(cur->ip >> 16),
|
|
||||||
(unsigned char)(cur->ip >> 8),
|
|
||||||
cur->ip & 0xff,
|
|
||||||
(unsigned char)(cur->mask >> 24),
|
|
||||||
(unsigned char)(cur->mask >> 16),
|
|
||||||
(unsigned char)(cur->mask >> 8),
|
|
||||||
cur->mask & 0xff);
|
|
||||||
if ((config->rmt_ip & cur->mask) == cur->ip)
|
if ((config->rmt_ip & cur->mask) == cur->ip)
|
||||||
return cur->allow_deny == 'A'; /* Allow/Deny */
|
return cur->allow_deny == 'A'; /* Allow/Deny */
|
||||||
}
|
}
|
||||||
@ -1765,6 +1758,8 @@ static void handleIncoming(void)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static int miniHttpd(int server)
|
static int miniHttpd(int server)
|
||||||
{
|
{
|
||||||
|
static const int on = 1;
|
||||||
|
|
||||||
fd_set readfd, portfd;
|
fd_set readfd, portfd;
|
||||||
|
|
||||||
FD_ZERO(&portfd);
|
FD_ZERO(&portfd);
|
||||||
@ -1772,9 +1767,13 @@ static int miniHttpd(int server)
|
|||||||
|
|
||||||
/* copy the ports we are watching to the readfd set */
|
/* copy the ports we are watching to the readfd set */
|
||||||
while (1) {
|
while (1) {
|
||||||
int on, s;
|
int s;
|
||||||
socklen_t fromAddrLen;
|
union {
|
||||||
struct sockaddr_in fromAddr;
|
struct sockaddr sa;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
USE_FEATURE_IPV6(struct sockaddr_in6 sin6;)
|
||||||
|
} fromAddr;
|
||||||
|
socklen_t fromAddrLen = sizeof(fromAddr);
|
||||||
|
|
||||||
/* Now wait INDEFINITELY on the set of sockets! */
|
/* Now wait INDEFINITELY on the set of sockets! */
|
||||||
readfd = portfd;
|
readfd = portfd;
|
||||||
@ -1782,27 +1781,31 @@ static int miniHttpd(int server)
|
|||||||
continue;
|
continue;
|
||||||
if (!FD_ISSET(server, &readfd))
|
if (!FD_ISSET(server, &readfd))
|
||||||
continue;
|
continue;
|
||||||
fromAddrLen = sizeof(fromAddr);
|
s = accept(server, &fromAddr.sa, &fromAddrLen);
|
||||||
s = accept(server, (struct sockaddr *)&fromAddr, &fromAddrLen);
|
|
||||||
if (s < 0)
|
if (s < 0)
|
||||||
continue;
|
continue;
|
||||||
config->accepted_socket = s;
|
config->accepted_socket = s;
|
||||||
config->rmt_ip = ntohl(fromAddr.sin_addr.s_addr);
|
config->rmt_ip = 0;
|
||||||
|
config->port = 0;
|
||||||
#if ENABLE_FEATURE_HTTPD_CGI || DEBUG
|
#if ENABLE_FEATURE_HTTPD_CGI || DEBUG
|
||||||
sprintf(config->rmt_ip_str, "%u.%u.%u.%u",
|
free(config->rmt_ip_str);
|
||||||
(unsigned char)(config->rmt_ip >> 24),
|
config->rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr.sa, fromAddrLen);
|
||||||
(unsigned char)(config->rmt_ip >> 16),
|
|
||||||
(unsigned char)(config->rmt_ip >> 8),
|
|
||||||
config->rmt_ip & 0xff);
|
|
||||||
config->port = ntohs(fromAddr.sin_port);
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
bb_error_msg("connection from IP=%s, port %u",
|
bb_error_msg("connection from '%s'", config->rmt_ip_str);
|
||||||
config->rmt_ip_str, config->port);
|
|
||||||
#endif
|
#endif
|
||||||
#endif /* FEATURE_HTTPD_CGI */
|
#endif /* FEATURE_HTTPD_CGI */
|
||||||
|
if (fromAddr.sa.sa_family == AF_INET) {
|
||||||
|
config->rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr);
|
||||||
|
config->port = ntohs(fromAddr.sin.sin_port);
|
||||||
|
}
|
||||||
|
#if ENABLE_FEATURE_IPV6
|
||||||
|
if (fromAddr.sa.sa_family == AF_INET6) {
|
||||||
|
//config->rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr);
|
||||||
|
config->port = ntohs(fromAddr.sin6.sin6_port);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* set the KEEPALIVE option to cull dead connections */
|
/* set the KEEPALIVE option to cull dead connections */
|
||||||
on = 1;
|
|
||||||
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
|
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
|
||||||
|
|
||||||
if (DEBUG || fork() == 0) {
|
if (DEBUG || fork() == 0) {
|
||||||
@ -1823,19 +1826,30 @@ static int miniHttpd(int server)
|
|||||||
/* from inetd */
|
/* from inetd */
|
||||||
static int miniHttpd_inetd(void)
|
static int miniHttpd_inetd(void)
|
||||||
{
|
{
|
||||||
struct sockaddr_in fromAddrLen;
|
union {
|
||||||
socklen_t sinlen = sizeof(struct sockaddr_in);
|
struct sockaddr sa;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
USE_FEATURE_IPV6(struct sockaddr_in6 sin6;)
|
||||||
|
} fromAddr;
|
||||||
|
socklen_t fromAddrLen = sizeof(fromAddr);
|
||||||
|
|
||||||
getpeername(0, (struct sockaddr *)&fromAddrLen, &sinlen);
|
getpeername(0, &fromAddr.sa, &fromAddrLen);
|
||||||
config->rmt_ip = ntohl(fromAddrLen.sin_addr.s_addr);
|
config->rmt_ip = 0;
|
||||||
#if ENABLE_FEATURE_HTTPD_CGI
|
config->port = 0;
|
||||||
sprintf(config->rmt_ip_str, "%u.%u.%u.%u",
|
#if ENABLE_FEATURE_HTTPD_CGI || DEBUG
|
||||||
(unsigned char)(config->rmt_ip >> 24),
|
free(config->rmt_ip_str);
|
||||||
(unsigned char)(config->rmt_ip >> 16),
|
config->rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr.sa, fromAddrLen);
|
||||||
(unsigned char)(config->rmt_ip >> 8),
|
#endif
|
||||||
config->rmt_ip & 0xff);
|
if (fromAddr.sa.sa_family == AF_INET) {
|
||||||
|
config->rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr);
|
||||||
|
config->port = ntohs(fromAddr.sin.sin_port);
|
||||||
|
}
|
||||||
|
#if ENABLE_FEATURE_IPV6
|
||||||
|
if (fromAddr.sa.sa_family == AF_INET6) {
|
||||||
|
//config->rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr);
|
||||||
|
config->port = ntohs(fromAddr.sin6.sin6_port);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
config->port = ntohs(fromAddrLen.sin_port);
|
|
||||||
handleIncoming();
|
handleIncoming();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1945,6 +1959,7 @@ int httpd_main(int argc, char *argv[])
|
|||||||
|
|
||||||
xchdir(home_httpd);
|
xchdir(home_httpd);
|
||||||
if (!(opt & OPT_INETD)) {
|
if (!(opt & OPT_INETD)) {
|
||||||
|
signal(SIGCHLD, SIG_IGN);
|
||||||
config->server_socket = openServer();
|
config->server_socket = openServer();
|
||||||
#if ENABLE_FEATURE_HTTPD_SETUID
|
#if ENABLE_FEATURE_HTTPD_SETUID
|
||||||
/* drop privileges */
|
/* drop privileges */
|
||||||
|
@ -37,7 +37,10 @@ int nc_main(int argc, char **argv)
|
|||||||
"" USE_NC_SERVER("lp:") USE_NC_EXTRA("w:i:f:e:") )) > 0
|
"" USE_NC_SERVER("lp:") USE_NC_EXTRA("w:i:f:e:") )) > 0
|
||||||
) {
|
) {
|
||||||
if (ENABLE_NC_SERVER && opt=='l') USE_NC_SERVER(do_listen++);
|
if (ENABLE_NC_SERVER && opt=='l') USE_NC_SERVER(do_listen++);
|
||||||
else if (ENABLE_NC_SERVER && opt=='p') USE_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0));
|
else if (ENABLE_NC_SERVER && opt=='p') {
|
||||||
|
USE_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0));
|
||||||
|
USE_NC_SERVER(lport = htons(lport));
|
||||||
|
}
|
||||||
else if (ENABLE_NC_EXTRA && opt=='w') USE_NC_EXTRA( wsecs = xatou(optarg));
|
else if (ENABLE_NC_EXTRA && opt=='w') USE_NC_EXTRA( wsecs = xatou(optarg));
|
||||||
else if (ENABLE_NC_EXTRA && opt=='i') USE_NC_EXTRA( delay = xatou(optarg));
|
else if (ENABLE_NC_EXTRA && opt=='i') USE_NC_EXTRA( delay = xatou(optarg));
|
||||||
else if (ENABLE_NC_EXTRA && opt=='f') USE_NC_EXTRA( cfd = xopen(optarg, O_RDWR));
|
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)
|
|||||||
|
|
||||||
address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
|
address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
|
||||||
address.sin_port = bb_lookup_port(argv[1], "tcp", 0);
|
address.sin_port = bb_lookup_port(argv[1], "tcp", 0);
|
||||||
|
address.sin_port = htons(address.sin_port);
|
||||||
|
|
||||||
xconnect(sfd, (struct sockaddr *) &address, sizeof(address));
|
xconnect(sfd, (struct sockaddr *) &address, sizeof(address));
|
||||||
cfd = sfd;
|
cfd = sfd;
|
||||||
|
@ -617,19 +617,17 @@ int telnet_main(int argc, char** argv)
|
|||||||
#ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN
|
#ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN
|
||||||
if (1 & getopt32(argc, argv, "al:", &autologin))
|
if (1 & getopt32(argc, argv, "al:", &autologin))
|
||||||
autologin = getenv("USER");
|
autologin = getenv("USER");
|
||||||
|
argv += optind;
|
||||||
if (optind < argc) {
|
|
||||||
host = argv[optind++];
|
|
||||||
port = bb_lookup_port((optind < argc) ? argv[optind++] :
|
|
||||||
"telnet", "tcp", 23);
|
|
||||||
if (optind < argc)
|
|
||||||
bb_show_usage();
|
|
||||||
} else
|
|
||||||
bb_show_usage();
|
|
||||||
#else
|
#else
|
||||||
host = argv[1];
|
argv++;
|
||||||
port = bb_lookup_port((argc > 2) ? argv[2] : "telnet", "tcp", 23);
|
|
||||||
#endif
|
#endif
|
||||||
|
if (!*argv)
|
||||||
|
bb_show_usage();
|
||||||
|
host = *argv++;
|
||||||
|
port = bb_lookup_port(*argv ? *argv++ : "telnet", "tcp", 23);
|
||||||
|
if (*argv) /* extra params?? */
|
||||||
|
bb_show_usage();
|
||||||
|
|
||||||
G.netfd = create_and_connect_stream_or_die(host, port);
|
G.netfd = create_and_connect_stream_or_die(host, port);
|
||||||
|
|
||||||
setsockopt(G.netfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one);
|
setsockopt(G.netfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one);
|
||||||
|
@ -132,7 +132,7 @@ static int tftp(
|
|||||||
#endif
|
#endif
|
||||||
const len_and_sockaddr *peer_lsa,
|
const len_and_sockaddr *peer_lsa,
|
||||||
const char *remotefile, const int localfd,
|
const char *remotefile, const int localfd,
|
||||||
const unsigned port, int tftp_bufsize)
|
unsigned port, int tftp_bufsize)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
@ -154,6 +154,8 @@ static int tftp(
|
|||||||
char *xbuf = xmalloc(tftp_bufsize += 4);
|
char *xbuf = xmalloc(tftp_bufsize += 4);
|
||||||
char *rbuf = xmalloc(tftp_bufsize);
|
char *rbuf = xmalloc(tftp_bufsize);
|
||||||
|
|
||||||
|
port = htons(port);
|
||||||
|
|
||||||
socketfd = xsocket(peer_lsa->sa.sa_family, SOCK_DGRAM, 0);
|
socketfd = xsocket(peer_lsa->sa.sa_family, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
/* build opcode */
|
/* build opcode */
|
||||||
|
@ -24,7 +24,7 @@ struct host_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void parse_url(char *url, struct host_info *h);
|
static void parse_url(char *url, struct host_info *h);
|
||||||
static FILE *open_socket(struct sockaddr_in *s_in);
|
static FILE *open_socket(len_and_sockaddr *lsa);
|
||||||
static char *gethdr(char *buf, size_t bufsiz, FILE *fp, int *istrunc);
|
static char *gethdr(char *buf, size_t bufsiz, FILE *fp, int *istrunc);
|
||||||
static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf);
|
static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf);
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ int wget_main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
char buf[512];
|
char buf[512];
|
||||||
struct host_info server, target;
|
struct host_info server, target;
|
||||||
struct sockaddr_in s_in;
|
len_and_sockaddr *lsa;
|
||||||
int n, status;
|
int n, status;
|
||||||
int port;
|
int port;
|
||||||
int try = 5;
|
int try = 5;
|
||||||
@ -189,7 +189,7 @@ int wget_main(int argc, char **argv)
|
|||||||
if (!fname_out) {
|
if (!fname_out) {
|
||||||
// Dirty hack. Needed because bb_get_last_path_component
|
// Dirty hack. Needed because bb_get_last_path_component
|
||||||
// will destroy trailing / by storing '\0' in last byte!
|
// will destroy trailing / by storing '\0' in last byte!
|
||||||
if (*target.path && target.path[strlen(target.path)-1] != '/') {
|
if (!last_char_is(target.path, '/')) {
|
||||||
fname_out =
|
fname_out =
|
||||||
#if ENABLE_FEATURE_WGET_STATUSBAR
|
#if ENABLE_FEATURE_WGET_STATUSBAR
|
||||||
curfile =
|
curfile =
|
||||||
@ -233,11 +233,11 @@ int wget_main(int argc, char **argv)
|
|||||||
/* We want to do exactly _one_ DNS lookup, since some
|
/* We want to do exactly _one_ DNS lookup, since some
|
||||||
* sites (i.e. ftp.us.debian.org) use round-robin DNS
|
* sites (i.e. ftp.us.debian.org) use round-robin DNS
|
||||||
* and we want to connect to only one IP... */
|
* and we want to connect to only one IP... */
|
||||||
bb_lookup_host(&s_in, server.host);
|
lsa = host2sockaddr(server.host, server.port);
|
||||||
s_in.sin_port = server.port;
|
|
||||||
if (!(opt & WGET_OPT_QUIET)) {
|
if (!(opt & WGET_OPT_QUIET)) {
|
||||||
fprintf(stderr, "Connecting to %s[%s]:%d\n",
|
fprintf(stderr, "Connecting to %s [%s]\n", server.host,
|
||||||
server.host, inet_ntoa(s_in.sin_addr), ntohs(server.port));
|
xmalloc_sockaddr2dotted(&lsa->sa, lsa->len));
|
||||||
|
/* We leak xmalloc_sockaddr2dotted result */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_proxy || !target.is_ftp) {
|
if (use_proxy || !target.is_ftp) {
|
||||||
@ -254,26 +254,29 @@ int wget_main(int argc, char **argv)
|
|||||||
* Open socket to http server
|
* Open socket to http server
|
||||||
*/
|
*/
|
||||||
if (sfp) fclose(sfp);
|
if (sfp) fclose(sfp);
|
||||||
sfp = open_socket(&s_in);
|
sfp = open_socket(lsa);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send HTTP request.
|
* Send HTTP request.
|
||||||
*/
|
*/
|
||||||
if (use_proxy) {
|
if (use_proxy) {
|
||||||
const char *format = "GET %stp://%s:%d/%s HTTP/1.1\r\n";
|
// const char *format = "GET %stp://%s:%d/%s HTTP/1.1\r\n";
|
||||||
#if ENABLE_FEATURE_WGET_IP6_LITERAL
|
//#if ENABLE_FEATURE_WGET_IP6_LITERAL
|
||||||
if (strchr(target.host, ':'))
|
// if (strchr(target.host, ':'))
|
||||||
format = "GET %stp://[%s]:%d/%s HTTP/1.1\r\n";
|
// format = "GET %stp://[%s]:%d/%s HTTP/1.1\r\n";
|
||||||
#endif
|
//#endif
|
||||||
fprintf(sfp, format,
|
// fprintf(sfp, format,
|
||||||
|
// target.is_ftp ? "f" : "ht", target.host,
|
||||||
|
// ntohs(target.port), target.path);
|
||||||
|
fprintf(sfp, "GET %stp://%s/%s HTTP/1.1\r\n",
|
||||||
target.is_ftp ? "f" : "ht", target.host,
|
target.is_ftp ? "f" : "ht", target.host,
|
||||||
ntohs(target.port), target.path);
|
target.path);
|
||||||
} else {
|
} else {
|
||||||
fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path);
|
fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(sfp, "Host: %s:%u\r\nUser-Agent: %s\r\n",
|
fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n",
|
||||||
target.host, target.port, user_agent);
|
target.host, user_agent);
|
||||||
|
|
||||||
#if ENABLE_FEATURE_WGET_AUTHENTICATION
|
#if ENABLE_FEATURE_WGET_AUTHENTICATION
|
||||||
if (target.user) {
|
if (target.user) {
|
||||||
@ -357,8 +360,8 @@ int wget_main(int argc, char **argv)
|
|||||||
server.host = target.host;
|
server.host = target.host;
|
||||||
server.port = target.port;
|
server.port = target.port;
|
||||||
}
|
}
|
||||||
bb_lookup_host(&s_in, server.host);
|
free(lsa);
|
||||||
s_in.sin_port = server.port;
|
lsa = host2sockaddr(server.host, server.port);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -375,7 +378,7 @@ int wget_main(int argc, char **argv)
|
|||||||
if (!target.user)
|
if (!target.user)
|
||||||
target.user = xstrdup("anonymous:busybox@");
|
target.user = xstrdup("anonymous:busybox@");
|
||||||
|
|
||||||
sfp = open_socket(&s_in);
|
sfp = open_socket(lsa);
|
||||||
if (ftpcmd(NULL, NULL, sfp, buf) != 220)
|
if (ftpcmd(NULL, NULL, sfp, buf) != 220)
|
||||||
bb_error_msg_and_die("%s", buf+4);
|
bb_error_msg_and_die("%s", buf+4);
|
||||||
|
|
||||||
@ -429,8 +432,8 @@ int wget_main(int argc, char **argv)
|
|||||||
s = strrchr(buf, ',');
|
s = strrchr(buf, ',');
|
||||||
if (!s) goto pasv_error;
|
if (!s) goto pasv_error;
|
||||||
port += xatou_range(s+1, 0, 255) * 256;
|
port += xatou_range(s+1, 0, 255) * 256;
|
||||||
s_in.sin_port = htons(port);
|
set_port(lsa, htons(port));
|
||||||
dfp = open_socket(&s_in);
|
dfp = open_socket(lsa);
|
||||||
|
|
||||||
if (beg_range) {
|
if (beg_range) {
|
||||||
sprintf(buf, "REST %"OFF_FMT"d", beg_range);
|
sprintf(buf, "REST %"OFF_FMT"d", beg_range);
|
||||||
@ -564,36 +567,37 @@ static void parse_url(char *src_url, struct host_info *h)
|
|||||||
|
|
||||||
sp = h->host;
|
sp = h->host;
|
||||||
|
|
||||||
#if ENABLE_FEATURE_WGET_IP6_LITERAL
|
//host2sockaddr does this itself
|
||||||
if (sp[0] == '[') {
|
//#if ENABLE_FEATURE_WGET_IP6_LITERAL
|
||||||
char *ep;
|
// if (sp[0] == '[') {
|
||||||
|
// char *ep;
|
||||||
ep = sp + 1;
|
//
|
||||||
while (*ep == ':' || isxdigit(*ep))
|
// ep = sp + 1;
|
||||||
ep++;
|
// while (*ep == ':' || isxdigit(*ep))
|
||||||
if (*ep == ']') {
|
// ep++;
|
||||||
h->host++;
|
// if (*ep == ']') {
|
||||||
*ep = '\0';
|
// h->host++;
|
||||||
sp = ep + 1;
|
// *ep = '\0';
|
||||||
}
|
// sp = ep + 1;
|
||||||
}
|
// }
|
||||||
#endif
|
// }
|
||||||
|
//#endif
|
||||||
p = strchr(sp, ':');
|
//
|
||||||
if (p != NULL) {
|
// p = strchr(sp, ':');
|
||||||
*p = '\0';
|
// if (p != NULL) {
|
||||||
h->port = htons(xatou16(p + 1));
|
// *p = '\0';
|
||||||
}
|
// h->port = htons(xatou16(p + 1));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static FILE *open_socket(struct sockaddr_in *s_in)
|
static FILE *open_socket(len_and_sockaddr *lsa)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
/* glibc 2.4 seems to try seeking on it - ??! */
|
/* glibc 2.4 seems to try seeking on it - ??! */
|
||||||
/* hopefully it understands what ESPIPE means... */
|
/* hopefully it understands what ESPIPE means... */
|
||||||
fp = fdopen(xconnect_tcp_v4(s_in), "r+");
|
fp = fdopen(xconnect_stream(lsa), "r+");
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
bb_perror_msg_and_die("fdopen");
|
bb_perror_msg_and_die("fdopen");
|
||||||
|
|
||||||
|
@ -580,7 +580,6 @@ CONFIG_VCONFIG=y
|
|||||||
CONFIG_WGET=y
|
CONFIG_WGET=y
|
||||||
CONFIG_FEATURE_WGET_STATUSBAR=y
|
CONFIG_FEATURE_WGET_STATUSBAR=y
|
||||||
CONFIG_FEATURE_WGET_AUTHENTICATION=y
|
CONFIG_FEATURE_WGET_AUTHENTICATION=y
|
||||||
CONFIG_FEATURE_WGET_IP6_LITERAL=y
|
|
||||||
CONFIG_FEATURE_WGET_LONG_OPTIONS=y
|
CONFIG_FEATURE_WGET_LONG_OPTIONS=y
|
||||||
CONFIG_ZCIP=y
|
CONFIG_ZCIP=y
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user