diff options
| author | Chris Sarra <chrissarra@google.com> | 2020-09-09 13:27:57 -0700 | 
|---|---|---|
| committer | Rob Landley <rob@landley.net> | 2020-09-10 00:58:57 -0500 | 
| commit | 2450930d8bc51f961ac1d2b92cccecd8a8e64a1c (patch) | |
| tree | c2cb63d27bbec443796ca2452ff3b53ff885cc75 | |
| parent | d294c99fe5bb4d0f8a5187e23c81b5a8fe7224e8 (diff) | |
| download | toybox-2450930d8bc51f961ac1d2b92cccecd8a8e64a1c.tar.gz | |
Add ipv6 support to wget.c
| -rw-r--r-- | toys/pending/wget.c | 48 | 
1 files changed, 40 insertions, 8 deletions
| diff --git a/toys/pending/wget.c b/toys/pending/wget.c index 75fad3f4..5c85889a 100644 --- a/toys/pending/wget.c +++ b/toys/pending/wget.c @@ -25,11 +25,11 @@ GLOBALS(    char *filename;  ) -// extract hostname from url +// extract hostname and port from url  static unsigned get_hn(const char *url, char *hostname) {    unsigned i; -  for (i = 0; url[i] != '\0' && url[i] != ':' && url[i] != '/'; i++) { +  for (i = 0; url[i] != '\0' && url[i] != '/'; i++) {      if(i >= 1024) error_exit("too long hostname in URL");      hostname[i] = url[i];    } @@ -41,7 +41,6 @@ static unsigned get_hn(const char *url, char *hostname) {  // extract port number  static unsigned get_port(const char *url, char *port, unsigned url_i) {    unsigned i; -    for (i = 0; url[i] != '\0' && url[i] != '/'; i++, url_i++) {      if('0' <= url[i] && url[i] <= '9') port[i] = url[i];      else error_exit("wrong decimal port number"); @@ -52,6 +51,20 @@ static unsigned get_port(const char *url, char *port, unsigned url_i) {    return url_i;  } +static void strip_v6_brackets(char* hostname) { +  size_t len = strlen(hostname); +  if (len > 1023) { +    error_exit("hostname too long, %d bytes\n", len); +  } +  char * closing_bracket = strchr(hostname, ']'); +  if (closing_bracket && closing_bracket == hostname + len - 1) { +    if (strchr(hostname, '[') == hostname) { +      hostname[len-1] = 0; +      memmove(hostname, hostname + 1, len - 1); +    } +  } +} +  // get http infos in URL  static void get_info(const char *url, char* hostname, char *port, char *path) {    unsigned i = 7, len; @@ -62,11 +75,30 @@ static void get_info(const char *url, char* hostname, char *port, char *path) {    len = get_hn(url+i, hostname);    i += len; -  // get port if exists -  if (url[i] == ':') { -    i++; -    i = get_port(url+i, port, i); -  } else strcpy(port, "80"); +  // `hostname` now contains `host:port`, where host can be any of: a raw IPv4 +  // address; a bracketed, raw IPv6 address, or a hostname. Extract port, if it exists, +  // by searching for the last ':' in the hostname string. +  char *port_delim = strrchr(hostname, ':'); +  char use_default_port = 1; +  if (port_delim) { +    // Found a colon; is there a closing bracket after it? If so, +    // then this colon was in the middle of a bracketed IPv6 address +    if (!strchr(port_delim, ']')) { +      // No closing bracket; this is a real port +      use_default_port = 0; +      get_port(port_delim + 1, port, 0); + +      // Mark the new end of the hostname string +      *port_delim = 0; +    } +  } + +  if (use_default_port) { +    strcpy(port, "80"); +  } + +  // This is a NOP if hostname is not a bracketed IPv6 address +  strip_v6_brackets(hostname);    // get uri in URL    if (url[i] == '\0') strcpy(path, "/"); | 
