diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-03-05 10:08:16 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-03-05 10:08:16 +0900 |
commit | 0fd98397eab07f1ec3b1fad9890fd751298e1fe0 (patch) | |
tree | 2e6a21730db1973ea7b81847dbb181ce9c8cd2ce /src | |
parent | 24d4e855d95e02a5324c2f3d88cfd5cd19830c2c (diff) | |
download | wget-0fd98397eab07f1ec3b1fad9890fd751298e1fe0.tar.gz wget-0fd98397eab07f1ec3b1fad9890fd751298e1fe0.tar.bz2 wget-0fd98397eab07f1ec3b1fad9890fd751298e1fe0.zip |
Imported Upstream version 1.17.1upstream/1.17.1
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.in | 26 | ||||
-rw-r--r-- | src/build_info.c | 12 | ||||
-rw-r--r-- | src/build_info.c.in | 3 | ||||
-rw-r--r-- | src/config.h.in | 12 | ||||
-rw-r--r-- | src/ftp-basic.c | 118 | ||||
-rw-r--r-- | src/ftp.c | 18 | ||||
-rw-r--r-- | src/gnutls.c | 16 | ||||
-rw-r--r-- | src/hsts.c | 41 | ||||
-rw-r--r-- | src/http.c | 14 | ||||
-rw-r--r-- | src/init.c | 79 | ||||
-rw-r--r-- | src/main.c | 12 | ||||
-rw-r--r-- | src/metalink.c | 4 | ||||
-rw-r--r-- | src/openssl.c | 9 | ||||
-rw-r--r-- | src/options.h | 9 | ||||
-rw-r--r-- | src/progress.c | 114 | ||||
-rw-r--r-- | src/recur.c | 6 | ||||
-rw-r--r-- | src/retr.c | 18 | ||||
-rw-r--r-- | src/url.c | 6 | ||||
-rw-r--r-- | src/wget.h | 2 |
19 files changed, 325 insertions, 194 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index 85fbc9a..5357ddd 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -137,15 +137,15 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ $(top_srcdir)/m4/extern-inline.m4 \ $(top_srcdir)/m4/fatal-signal.m4 $(top_srcdir)/m4/fcntl-o.m4 \ $(top_srcdir)/m4/fcntl.m4 $(top_srcdir)/m4/fcntl_h.m4 \ - $(top_srcdir)/m4/float_h.m4 $(top_srcdir)/m4/fnmatch.m4 \ - $(top_srcdir)/m4/fseek.m4 $(top_srcdir)/m4/fseeko.m4 \ - $(top_srcdir)/m4/fstat.m4 $(top_srcdir)/m4/ftell.m4 \ - $(top_srcdir)/m4/ftello.m4 $(top_srcdir)/m4/futimens.m4 \ - $(top_srcdir)/m4/getaddrinfo.m4 $(top_srcdir)/m4/getdelim.m4 \ - $(top_srcdir)/m4/getdtablesize.m4 $(top_srcdir)/m4/getline.m4 \ - $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/getpass.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gettime.m4 \ - $(top_srcdir)/m4/gettimeofday.m4 \ + $(top_srcdir)/m4/float_h.m4 $(top_srcdir)/m4/flock.m4 \ + $(top_srcdir)/m4/fnmatch.m4 $(top_srcdir)/m4/fseek.m4 \ + $(top_srcdir)/m4/fseeko.m4 $(top_srcdir)/m4/fstat.m4 \ + $(top_srcdir)/m4/ftell.m4 $(top_srcdir)/m4/ftello.m4 \ + $(top_srcdir)/m4/futimens.m4 $(top_srcdir)/m4/getaddrinfo.m4 \ + $(top_srcdir)/m4/getdelim.m4 $(top_srcdir)/m4/getdtablesize.m4 \ + $(top_srcdir)/m4/getline.m4 $(top_srcdir)/m4/getopt.m4 \ + $(top_srcdir)/m4/getpass.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gettime.m4 $(top_srcdir)/m4/gettimeofday.m4 \ $(top_srcdir)/m4/gl-openssl.m4 $(top_srcdir)/m4/glibc21.m4 \ $(top_srcdir)/m4/gnulib-common.m4 \ $(top_srcdir)/m4/gnulib-comp.m4 $(top_srcdir)/m4/hostent.m4 \ @@ -201,7 +201,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ $(top_srcdir)/m4/string_h.m4 $(top_srcdir)/m4/strings_h.m4 \ $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/strnlen.m4 \ $(top_srcdir)/m4/strptime.m4 $(top_srcdir)/m4/strtok_r.m4 \ - $(top_srcdir)/m4/strtoll.m4 $(top_srcdir)/m4/sys_ioctl_h.m4 \ + $(top_srcdir)/m4/strtoll.m4 $(top_srcdir)/m4/sys_file_h.m4 \ + $(top_srcdir)/m4/sys_ioctl_h.m4 \ $(top_srcdir)/m4/sys_select_h.m4 \ $(top_srcdir)/m4/sys_socket_h.m4 \ $(top_srcdir)/m4/sys_stat_h.m4 $(top_srcdir)/m4/sys_time_h.m4 \ @@ -450,6 +451,7 @@ GNULIB_FFSL = @GNULIB_FFSL@ GNULIB_FFSLL = @GNULIB_FFSLL@ GNULIB_FGETC = @GNULIB_FGETC@ GNULIB_FGETS = @GNULIB_FGETS@ +GNULIB_FLOCK = @GNULIB_FLOCK@ GNULIB_FOPEN = @GNULIB_FOPEN@ GNULIB_FPRINTF = @GNULIB_FPRINTF@ GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@ @@ -777,6 +779,7 @@ HAVE_FEATURES_H = @HAVE_FEATURES_H@ HAVE_FFS = @HAVE_FFS@ HAVE_FFSL = @HAVE_FFSL@ HAVE_FFSLL = @HAVE_FFSLL@ +HAVE_FLOCK = @HAVE_FLOCK@ HAVE_FSEEKO = @HAVE_FSEEKO@ HAVE_FSTATAT = @HAVE_FSTATAT@ HAVE_FSYNC = @HAVE_FSYNC@ @@ -898,6 +901,7 @@ HAVE_STRVERSCMP = @HAVE_STRVERSCMP@ HAVE_SYMLINK = @HAVE_SYMLINK@ HAVE_SYMLINKAT = @HAVE_SYMLINKAT@ HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +HAVE_SYS_FILE_H = @HAVE_SYS_FILE_H@ HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ HAVE_SYS_IOCTL_H = @HAVE_SYS_IOCTL_H@ HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@ @@ -1043,6 +1047,7 @@ NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@ NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@ NEXT_AS_FIRST_DIRECTIVE_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@ NEXT_AS_FIRST_DIRECTIVE_STRING_H = @NEXT_AS_FIRST_DIRECTIVE_STRING_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_FILE_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_FILE_H@ NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H@ NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H@ NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H@ @@ -1073,6 +1078,7 @@ NEXT_STDIO_H = @NEXT_STDIO_H@ NEXT_STDLIB_H = @NEXT_STDLIB_H@ NEXT_STRINGS_H = @NEXT_STRINGS_H@ NEXT_STRING_H = @NEXT_STRING_H@ +NEXT_SYS_FILE_H = @NEXT_SYS_FILE_H@ NEXT_SYS_IOCTL_H = @NEXT_SYS_IOCTL_H@ NEXT_SYS_SELECT_H = @NEXT_SYS_SELECT_H@ NEXT_SYS_SOCKET_H = @NEXT_SYS_SOCKET_H@ diff --git a/src/build_info.c b/src/build_info.c index ee4ce82..067257e 100644 --- a/src/build_info.c +++ b/src/build_info.c @@ -19,6 +19,12 @@ const char *compiled_features[] = "-digest", #endif +#if defined HAVE_GPGME + "+gpgme", +#else + "-gpgme", +#endif + #if defined HAVE_SSL "+https", #else @@ -43,6 +49,12 @@ const char *compiled_features[] = "-large-file", #endif +#if defined HAVE_METALINK + "+metalink", +#else + "-metalink", +#endif + #if defined ENABLE_NLS "+nls", #else diff --git a/src/build_info.c.in b/src/build_info.c.in index ce1fe25..83b7664 100644 --- a/src/build_info.c.in +++ b/src/build_info.c.in @@ -9,6 +9,9 @@ ntlm defined ENABLE_NTLM opie defined ENABLE_OPIE psl defined HAVE_LIBPSL +metalink defined HAVE_METALINK +gpgme defined HAVE_GPGME + ssl choice: openssl defined HAVE_LIBSSL || defined HAVE_LIBSSL32 gnutls defined HAVE_LIBGNUTLS diff --git a/src/config.h.in b/src/config.h.in index 60f73be..e8f4170 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -629,6 +629,9 @@ /* Define to 1 if you have the <features.h> header file. */ #undef HAVE_FEATURES_H +/* Define to 1 if you have the `flock' function. */ +#undef HAVE_FLOCK + /* Define to 1 if you have the `flockfile' function. */ #undef HAVE_FLOCKFILE @@ -996,6 +999,9 @@ /* Define to 1 if ffsll is declared even after undefining macros. */ #undef HAVE_RAW_DECL_FFSLL +/* Define to 1 if flock is declared even after undefining macros. */ +#undef HAVE_RAW_DECL_FLOCK + /* Define to 1 if fpurge is declared even after undefining macros. */ #undef HAVE_RAW_DECL_FPURGE @@ -1765,6 +1771,9 @@ /* Define to 1 if the system has the type `struct addrinfo'. */ #undef HAVE_STRUCT_ADDRINFO +/* Define to 1 if `l_type' is a member of `struct flock'. */ +#undef HAVE_STRUCT_FLOCK_L_TYPE + /* Define to 1 if `decimal_point' is a member of `struct lconv'. */ #undef HAVE_STRUCT_LCONV_DECIMAL_POINT @@ -1813,6 +1822,9 @@ /* Define to 1 if you have the <sys/bitypes.h> header file. */ #undef HAVE_SYS_BITYPES_H +/* Define to 1 if you have the <sys/file.h> header file. */ +#undef HAVE_SYS_FILE_H + /* Define to 1 if you have the <sys/inttypes.h> header file. */ #undef HAVE_SYS_INTTYPES_H diff --git a/src/ftp-basic.c b/src/ftp-basic.c index bcb7847..378374c 100644 --- a/src/ftp-basic.c +++ b/src/ftp-basic.c @@ -429,6 +429,65 @@ ip_address_to_eprt_repr (const ip_address *addr, int port, char *buf, buf[buflen - 1] = '\0'; } +/* Bind a port and send the appropriate PORT command to the FTP + server. Use acceptport after RETR, to get the socket of data + connection. */ +uerr_t +ftp_eprt (int csock, int *local_sock) +{ + uerr_t err; + char *request, *respline; + ip_address addr; + int nwritten; + int port; + /* Must contain the argument of EPRT (of the form |af|addr|port|). + * 4 chars for the | separators, INET6_ADDRSTRLEN chars for addr + * 1 char for af (1-2) and 5 chars for port (0-65535) */ + char bytes[4 + INET6_ADDRSTRLEN + 1 + 5 + 1]; + + /* Get the address of this side of the connection. */ + if (!socket_ip_address (csock, &addr, ENDPOINT_LOCAL)) + return FTPSYSERR; + + /* Setting port to 0 lets the system choose a free port. */ + port = 0; + + /* Bind the port. */ + *local_sock = bind_local (&addr, &port); + if (*local_sock < 0) + return FTPSYSERR; + + /* Construct the argument of EPRT (of the form |af|addr|port|). */ + ip_address_to_eprt_repr (&addr, port, bytes, sizeof (bytes)); + + /* Send PORT request. */ + request = ftp_request ("EPRT", bytes); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + fd_close (*local_sock); + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + { + fd_close (*local_sock); + return err; + } + if (*respline != '2') + { + xfree (respline); + fd_close (*local_sock); + return FTPPORTERR; + } + xfree (respline); + return FTPOK; +} +#endif + #ifdef HAVE_SSL /* * The following three functions defined into this #ifdef block @@ -542,65 +601,6 @@ bail: } #endif /* HAVE_SSL */ -/* Bind a port and send the appropriate PORT command to the FTP - server. Use acceptport after RETR, to get the socket of data - connection. */ -uerr_t -ftp_eprt (int csock, int *local_sock) -{ - uerr_t err; - char *request, *respline; - ip_address addr; - int nwritten; - int port; - /* Must contain the argument of EPRT (of the form |af|addr|port|). - * 4 chars for the | separators, INET6_ADDRSTRLEN chars for addr - * 1 char for af (1-2) and 5 chars for port (0-65535) */ - char bytes[4 + INET6_ADDRSTRLEN + 1 + 5 + 1]; - - /* Get the address of this side of the connection. */ - if (!socket_ip_address (csock, &addr, ENDPOINT_LOCAL)) - return FTPSYSERR; - - /* Setting port to 0 lets the system choose a free port. */ - port = 0; - - /* Bind the port. */ - *local_sock = bind_local (&addr, &port); - if (*local_sock < 0) - return FTPSYSERR; - - /* Construct the argument of EPRT (of the form |af|addr|port|). */ - ip_address_to_eprt_repr (&addr, port, bytes, sizeof (bytes)); - - /* Send PORT request. */ - request = ftp_request ("EPRT", bytes); - nwritten = fd_write (csock, request, strlen (request), -1); - if (nwritten < 0) - { - xfree (request); - fd_close (*local_sock); - return WRITEFAILED; - } - xfree (request); - /* Get appropriate response. */ - err = ftp_response (csock, &respline); - if (err != FTPOK) - { - fd_close (*local_sock); - return err; - } - if (*respline != '2') - { - xfree (respline); - fd_close (*local_sock); - return FTPPORTERR; - } - xfree (respline); - return FTPOK; -} -#endif - /* Similar to ftp_port, but uses `PASV' to initiate the passive FTP transfer. Reads the response from server and parses it. Reads the host and port addresses and returns them. */ @@ -321,7 +321,8 @@ getftp (struct url *u, wgint passed_expected_bytes, wgint *qtyread, { int csock, dtsock, local_sock, res; uerr_t err = RETROK; /* appease the compiler */ - FILE *fp; + FILE *fp = NULL; + struct_fstat st; char *respline, *tms; const char *user, *passwd, *tmrate; int cmd = con->cmd; @@ -393,7 +394,9 @@ getftp (struct url *u, wgint passed_expected_bytes, wgint *qtyread, if (!(cmd & DO_LOGIN)) { csock = con->csock; +#ifdef HAVE_SSL using_data_security = con->st & DATA_CHANNEL_SECURITY; +#endif } else /* cmd & DO_LOGIN */ { @@ -1512,8 +1515,9 @@ Error in server response, closing control connection.\n")); { fd_close (csock); fd_close (dtsock); + err = CONERROR; logputs (LOG_NOTQUIET, "Could not perform SSL handshake.\n"); - return CONERROR; + goto exit_error; } } else @@ -1523,7 +1527,8 @@ Error in server response, closing control connection.\n")); { fd_close (csock); fd_close (dtsock); - return CONERROR; + err = CONERROR; + goto exit_error; } } #endif @@ -1760,6 +1765,13 @@ Error in server response, closing control connection.\n")); } } while (try_again); return RETRFINISHED; + +exit_error: + + /* If fp is a regular file, close and try to remove it */ + if (fp && !output_stream) + fclose (fp); + return err; } /* A one-file FTP loop. This is the part where FTP retrieval is diff --git a/src/gnutls.c b/src/gnutls.c index 828050b..d39371f 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -633,9 +633,13 @@ ssl_connect_wget (int fd, const char *hostname, int *continue_session) { if (!ctx || !ctx->session_data || gnutls_session_set_data (session, ctx->session_data->data, ctx->session_data->size)) { - /* server does not want to continue the session */ - gnutls_free (ctx->session_data->data); - gnutls_free (ctx->session_data); + if (ctx && ctx->session_data) + { + /* server does not want to continue the session */ + if (ctx->session_data->data) + gnutls_free (ctx->session_data->data); + gnutls_free (ctx->session_data); + } gnutls_deinit (session); return false; } @@ -688,6 +692,10 @@ ssl_check_certificate (int fd, const char *host) const char *severity = opt.check_cert ? _("ERROR") : _("WARNING"); bool success = true; + /* The user explicitly said to not check for the certificate. */ + if (opt.check_cert == CHECK_CERT_QUIET) + return success; + err = gnutls_certificate_verify_peers2 (ctx->session, &status); if (err < 0) { @@ -762,5 +770,5 @@ ssl_check_certificate (int fd, const char *host) } out: - return opt.check_cert ? success : true; + return opt.check_cert == CHECK_CERT_ON ? success : true; } @@ -148,13 +148,14 @@ hsts_find_entry (hsts_store_t store, end: /* restore pointer or we'll get a SEGV */ k->host = org_ptr; - xfree (k->host); /* copy parameters to previous frame */ if (match_type) *match_type = match; if (kh) memcpy (kh, k, sizeof (struct hsts_kh)); + else + xfree (k->host); xfree (k); return khi; @@ -236,8 +237,7 @@ hsts_new_entry (hsts_store_t store, static void hsts_remove_entry (hsts_store_t store, struct hsts_kh *kh) { - if (hash_table_remove (store->table, kh)) - xfree (kh->host); + hash_table_remove (store->table, kh); } static bool @@ -375,9 +375,10 @@ hsts_match (hsts_store_t store, struct url *u) else hsts_remove_entry (store, kh); } + xfree (kh->host); } - xfree(kh); + xfree (kh); return url_changed; } @@ -451,9 +452,10 @@ hsts_store_entry (hsts_store_t store, result = hsts_add_entry (store, host, port, max_age, include_subdomains); } /* we ignore new entries with max_age == 0 */ + xfree (kh->host); } - xfree(kh); + xfree (kh); return result; } @@ -462,7 +464,7 @@ hsts_store_t hsts_store_open (const char *filename) { hsts_store_t store = NULL; - struct stat st; + struct_stat st; FILE *fp = NULL; store = xnew0 (struct hsts_store); @@ -471,27 +473,29 @@ hsts_store_open (const char *filename) if (file_exists_p (filename)) { - if (stat (filename, &st) == 0) - store->last_mtime = st.st_mtime; - fp = fopen (filename, "r"); + if (!fp || !hsts_read_database (store, fp, false)) { /* abort! */ hsts_store_close (store); xfree (store); + goto out; } - if (fp) - fclose (fp); + + if (fstat (fileno (fp), &st) == 0) + store->last_mtime = st.st_mtime; + fclose (fp); } +out: return store; } void hsts_store_save (hsts_store_t store, const char *filename) { - struct stat st; + struct_stat st; FILE *fp = NULL; int fd = 0; @@ -613,7 +617,7 @@ test_url_rewrite (hsts_store_t s, const char *url, int port, bool rewrite) if (rewrite) { if (port == 80) - mu_assert("URL: port should've been rewritten to 443", u.port == 443); + mu_assert("URL: port should've been rewritten to 443", u.port == 443); else mu_assert("URL: port should've been left intact", u.port == port); mu_assert("URL: scheme should've been rewritten to HTTPS", u.scheme == SCHEME_HTTPS); @@ -686,7 +690,7 @@ test_hsts_url_rewrite_superdomain (void) s = open_hsts_test_store (); mu_assert("Could not open the HSTS store", s != NULL); - created = hsts_store_entry (s, SCHEME_HTTPS, "www.foo.com", 443, time(NULL) + 1234, true); + created = hsts_store_entry (s, SCHEME_HTTPS, "www.foo.com", 443, 1234, true); mu_assert("A new entry should've been created", created == true); TEST_URL_RW (s, "www.foo.com", 80); @@ -707,7 +711,7 @@ test_hsts_url_rewrite_congruent (void) s = open_hsts_test_store (); mu_assert("Could not open the HSTS store", s != NULL); - created = hsts_store_entry (s, SCHEME_HTTPS, "foo.com", 443, time(NULL) + 1234, false); + created = hsts_store_entry (s, SCHEME_HTTPS, "foo.com", 443, 1234, false); mu_assert("A new entry should've been created", created == true); TEST_URL_RW (s, "foo.com", 80); @@ -726,6 +730,7 @@ test_hsts_read_database (void) char *home = home_dir(); char *file = NULL; FILE *fp = NULL; + time_t created = time(NULL) - 10; if (home) { @@ -734,9 +739,9 @@ test_hsts_read_database (void) if (fp) { fputs ("# dummy comment\n", fp); - fputs ("foo.example.com\t0\t1\t1434224817\t123123123\n", fp); - fputs ("bar.example.com\t0\t0\t1434224817\t456456456\n", fp); - fputs ("test.example.com\t8080\t0\t1434224817\t789789789\n", fp); + fprintf (fp, "foo.example.com\t0\t1\t%ld\t123\n",(long) created); + fprintf (fp, "bar.example.com\t0\t0\t%ld\t456\n", (long) created); + fprintf (fp, "test.example.com\t8080\t0\t%ld\t789\n", (long) created); fclose (fp); table = hsts_store_open (file); @@ -1872,7 +1872,7 @@ initialize_request (struct url *u, struct http_stat *hs, int *dt, struct url *pr /* Find the username and password for authentication. */ *user = u->user; *passwd = u->passwd; - search_netrc (u->host, (const char **)&user, (const char **)&passwd, 0); + search_netrc (u->host, (const char **)user, (const char **)passwd, 0); *user = *user ? *user : (opt.http_user ? opt.http_user : opt.user); *passwd = *passwd ? *passwd : (opt.http_passwd ? opt.http_passwd : opt.passwd); @@ -3794,7 +3794,6 @@ http_loop (struct url *u, struct url *original_url, char **newloc, struct http_stat hstat; /* HTTP status */ struct_stat st; bool send_head_first = true; - char *file_name; bool force_full_retrieve = false; @@ -3864,11 +3863,6 @@ http_loop (struct url *u, struct url *original_url, char **newloc, if (opt.content_disposition && opt.always_rest) send_head_first = true; - if (!opt.output_document) - file_name = url_file_name (opt.trustservernames ? u : original_url, NULL); - else - file_name = xstrdup (opt.output_document); - #ifdef HAVE_METALINK if (opt.metalink_over_http) { @@ -3881,7 +3875,7 @@ http_loop (struct url *u, struct url *original_url, char **newloc, { /* Use conditional get request if requested * and if timestamp is known at this moment. */ - if (opt.if_modified_since && file_exists_p (file_name) && !send_head_first) + if (opt.if_modified_since && !send_head_first && got_name && file_exists_p (hstat.local_file)) { *dt |= IF_MODIFIED_SINCE; { @@ -3892,12 +3886,10 @@ http_loop (struct url *u, struct url *original_url, char **newloc, } /* Send preliminary HEAD request if -N is given and we have existing * destination file or content disposition is enabled. */ - else if (file_exists_p (file_name) || opt.content_disposition) + else if (opt.content_disposition || file_exists_p (hstat.local_file)) send_head_first = true; } - xfree (file_name); - /* THE loop */ do { @@ -115,6 +115,7 @@ CMD_DECLARE (cmd_spec_secure_protocol); CMD_DECLARE (cmd_spec_timeout); CMD_DECLARE (cmd_spec_useragent); CMD_DECLARE (cmd_spec_verbose); +CMD_DECLARE (cmd_check_cert); /* List of recognized commands, each consisting of name, place and function. When adding a new command, simply add it to the list, @@ -152,7 +153,7 @@ static const struct { { "cadirectory", &opt.ca_directory, cmd_directory }, { "certificate", &opt.cert_file, cmd_file }, { "certificatetype", &opt.cert_type, cmd_cert_type }, - { "checkcertificate", &opt.check_cert, cmd_boolean }, + { "checkcertificate", &opt.check_cert, cmd_check_cert }, #endif { "chooseconfig", &opt.choose_config, cmd_file }, { "connecttimeout", &opt.connect_timeout, cmd_time }, @@ -415,7 +416,7 @@ defaults (void) opt.retr_symlinks = true; #ifdef HAVE_SSL - opt.check_cert = true; + opt.check_cert = CHECK_CERT_ON; opt.ftps_resume_ssl = true; opt.ftps_fallback_to_ftp = false; opt.ftps_implicit = false; @@ -955,6 +956,18 @@ static bool simple_atof (const char *, const char *, double *); && (p)[3] == '\0') +static int +cmd_boolean_internal (const char *com _GL_UNUSED, const char *val, void *place _GL_UNUSED) +{ + if (CMP2 (val, 'o', 'n') || CMP3 (val, 'y', 'e', 's') || CMP1 (val, '1')) + /* "on", "yes" and "1" mean true. */ + return 1; + else if (CMP3 (val, 'o', 'f', 'f') || CMP2 (val, 'n', 'o') || CMP1 (val, '0')) + /* "off", "no" and "0" mean false. */ + return 0; + return -1; +} + /* Store the boolean value from VAL to PLACE. COM is ignored, except for error messages. */ static bool @@ -962,24 +975,62 @@ cmd_boolean (const char *com, const char *val, void *place) { bool value; - if (CMP2 (val, 'o', 'n') || CMP3 (val, 'y', 'e', 's') || CMP1 (val, '1')) - /* "on", "yes" and "1" mean true. */ - value = true; - else if (CMP3 (val, 'o', 'f', 'f') || CMP2 (val, 'n', 'o') || CMP1 (val, '0')) - /* "off", "no" and "0" mean false. */ - value = false; - else + switch (cmd_boolean_internal (com, val, place)) { - fprintf (stderr, - _("%s: %s: Invalid boolean %s; use `on' or `off'.\n"), - exec_name, com, quote (val)); - return false; - } + case 0: + value = false; + break; + case 1: + value = true; + break; + + default: + { + fprintf (stderr, + _("%s: %s: Invalid boolean %s; use `on' or `off'.\n"), + exec_name, com, quote (val)); + return false; + } + } *(bool *) place = value; return true; } +/* Store the check_cert value from VAL to PLACE. COM is ignored, + except for error messages. */ +static bool +cmd_check_cert (const char *com, const char *val, void *place) +{ + int value; + + switch (cmd_boolean_internal (com, val, place)) + { + case 0: + value = CHECK_CERT_OFF; + break; + + case 1: + value = CHECK_CERT_ON; + break; + + default: + { + if (!c_strcasecmp (val, "quiet")) + value = CHECK_CERT_QUIET; + else + { + fprintf (stderr, + _("%s: %s: Invalid %s; use `on', `off' or `quiet'.\n"), + exec_name, com, quote (val)); + return false; + } + } + } + *(int *) place = value; + return true; +} + /* Set the non-negative integer value from VAL to PLACE. With incorrect specification, the number remains unchanged. */ static bool @@ -1842,13 +1842,21 @@ only if outputting to a regular file.\n")); else { if ((opt.recursive || opt.page_requisites) - && ((url_scheme (*t) != SCHEME_FTP && url_scheme (*t) != SCHEME_FTPS) + && ((url_scheme (*t) != SCHEME_FTP +#ifdef HAVE_SSL + && url_scheme (*t) != SCHEME_FTPS +#endif + ) || url_uses_proxy (url_parsed))) { int old_follow_ftp = opt.follow_ftp; /* Turn opt.follow_ftp on in case of recursive FTP retrieval */ - if (url_scheme (*t) == SCHEME_FTP || url_scheme (*t) == SCHEME_FTPS) + if (url_scheme (*t) == SCHEME_FTP +#ifdef HAVE_SSL + || url_scheme (*t) == SCHEME_FTPS +#endif + ) opt.follow_ftp = 1; retrieve_tree (url_parsed, NULL); diff --git a/src/metalink.c b/src/metalink.c index bab549f..25737b3 100644 --- a/src/metalink.c +++ b/src/metalink.c @@ -36,7 +36,7 @@ as that of the covered work. */ #include "utils.h" #include "sha256.h" #include "xstrndup.h" -#include <sys/errno.h> +#include <errno.h> #include <unistd.h> /* For unlink. */ #include <metalink/metalink_parser.h> #ifdef HAVE_GPGME @@ -168,7 +168,7 @@ retrieve_from_metalink (const metalink_t* metalink) FILE *local_file; /* Check the digest. */ - local_file = fopen (filename, "r"); + local_file = fopen (filename, "rb"); if (!local_file) { logprintf (LOG_NOTQUIET, _("Could not open downloaded file.\n")); diff --git a/src/openssl.c b/src/openssl.c index 4876048..6701c0d 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -682,6 +682,10 @@ ssl_check_certificate (int fd, const char *host) SSL *conn = ctx->conn; assert (conn != NULL); + /* The user explicitly said to not check for the certificate. */ + if (opt.check_cert == CHECK_CERT_QUIET) + return success; + cert = SSL_get_peer_certificate (conn); if (!cert) { @@ -880,13 +884,12 @@ ssl_check_certificate (int fd, const char *host) X509_free (cert); no_cert: - if (opt.check_cert && !success) + if (opt.check_cert == CHECK_CERT_ON && !success) logprintf (LOG_NOTQUIET, _("\ To connect to %s insecurely, use `--no-check-certificate'.\n"), quotearg_style (escape_quoting_style, host)); - /* Allow --no-check-cert to disable certificate checking. */ - return opt.check_cert ? success : true; + return opt.check_cert == CHECK_CERT_ON ? success : true; } /* diff --git a/src/options.h b/src/options.h index dad08c1..5cd5fb1 100644 --- a/src/options.h +++ b/src/options.h @@ -29,6 +29,13 @@ Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ +enum CHECK_CERT_MODES +{ + CHECK_CERT_OFF, + CHECK_CERT_ON, + CHECK_CERT_QUIET +}; + struct options { int verbose; /* Are we verbose? (First set to -1, @@ -215,7 +222,7 @@ struct options secure_protocol_tlsv1_2, secure_protocol_pfs } secure_protocol; /* type of secure protocol to use. */ - bool check_cert; /* whether to validate the server's cert */ + int check_cert; /* whether to validate the server's cert */ char *cert_file; /* external client certificate to use. */ char *private_key; /* private key file (if not internal). */ enum keyfile_type { diff --git a/src/progress.c b/src/progress.c index 61b635d..93f6246 100644 --- a/src/progress.c +++ b/src/progress.c @@ -594,7 +594,8 @@ bar_create (const char *f_download, wgint initial, wgint total) bp->width = screen_width - 1; /* + enough space for the terminating zero, and hopefully enough room * for multibyte characters. */ - bp->buffer = xmalloc (bp->width + 100); +#define BUF_LEN (bp->width + 100) + bp->buffer = xmalloc (BUF_LEN); logputs (LOG_VERBOSE, "\n"); @@ -854,7 +855,7 @@ get_eta (int *bcd) { /* TRANSLATORS: "ETA" is English-centric, but this must be short, ideally 3 chars. Abbreviate if necessary. */ - static const char eta_str[] = N_(" eta %s"); + static const char eta_str[] = N_(" eta %s"); static const char *eta_trans; static int bytes_cols_diff; if (eta_trans == NULL) @@ -903,11 +904,11 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) char *p = bp->buffer; wgint size = bp->initial_length + bp->count; - int size_grouped_pad; /* Used to pad the field width for size_grouped. */ - struct bar_progress_hist *hist = &bp->hist; int orig_filename_cols = count_cols (bp->f_download); + int padding; + /* The progress bar should look like this: file xx% [=======> ] nnn.nnK 12.34KB/s eta 36m 51s @@ -928,12 +929,16 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) "=====>..." - progress bar - the rest */ + /* TODO: Ask the Turkish Translators to fix their translation for the "done" + * mode of progress bar. Use one less character. Once that is done, redice + * PROGRESS_ETA_LEN by 1. + */ #define PROGRESS_FILENAME_LEN MAX_FILENAME_COLS + 1 #define PROGRESS_PERCENT_LEN 4 #define PROGRESS_DECORAT_LEN 2 #define PROGRESS_FILESIZE_LEN 7 + 1 -#define PROGRESS_DWNLOAD_RATE 8 + 1 -#define PROGRESS_ETA_LEN 14 +#define PROGRESS_DWNLOAD_RATE 8 + 2 +#define PROGRESS_ETA_LEN 15 int progress_size = bp->width - (PROGRESS_FILENAME_LEN + PROGRESS_PERCENT_LEN + PROGRESS_DECORAT_LEN + PROGRESS_FILESIZE_LEN + @@ -945,23 +950,23 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) int cols_diff; const char *down_size; + memset (bp->buffer, '\0', BUF_LEN); + if (progress_size < 5) progress_size = 0; if (orig_filename_cols <= MAX_FILENAME_COLS) { - int padding = MAX_FILENAME_COLS - orig_filename_cols; - sprintf (p, "%s ", bp->f_download); - p += orig_filename_cols + 1; - for (;padding;padding--) - *p++ = ' '; + padding = MAX_FILENAME_COLS - orig_filename_cols; + p += sprintf (p, "%s ", bp->f_download); + memset (p, ' ', padding); + p += padding; } else { int offset_cols; int bytes_in_filename, offset_bytes, col; int *cols_ret = &col; - int padding; #define MIN_SCROLL_TEXT 5 if ((orig_filename_cols > MAX_FILENAME_COLS + MIN_SCROLL_TEXT) && @@ -992,9 +997,8 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) memcpy (p, bp->f_download + offset_bytes, bytes_in_filename); p += bytes_in_filename; padding = MAX_FILENAME_COLS - (padding + *cols_ret); - for (;padding;padding--) - *p++ = ' '; - *p++ = ' '; + memset (p, ' ', padding + 1); + p += padding + 1; } /* "xx% " */ @@ -1002,15 +1006,13 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) { int percentage = 100.0 * size / bp->total_length; assert (percentage <= 100); - - if (percentage < 100) - sprintf (p, "%3d%%", percentage); - else - strcpy (p, "100%"); - p += 4; + p += sprintf (p, "%3d%%", percentage); } else - APPEND_LITERAL (" "); + { + memset (p, ' ', PROGRESS_PERCENT_LEN); + p += PROGRESS_PERCENT_LEN; + } /* The progress bar: "[====> ]" or "[++==> ]". */ if (progress_size && bp->total_length > 0) @@ -1022,7 +1024,6 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) int dlsz = (double)size / bp->total_length * progress_size; char *begin; - int i; assert (dlsz <= progress_size); assert (insz <= dlsz); @@ -1032,18 +1033,19 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) /* Print the initial portion of the download with '+' chars, the rest with '=' and one '>'. */ - for (i = 0; i < insz; i++) - *p++ = '+'; + memset (p, '+', insz); + p += insz; + dlsz -= insz; if (dlsz > 0) { - for (i = 0; i < dlsz - 1; i++) - *p++ = '='; + memset (p, '=', dlsz-1); + p += dlsz - 1; *p++ = '>'; } - while (p - begin < progress_size) - *p++ = ' '; + memset (p, ' ', (progress_size - (p - begin))); + p += (progress_size - (p - begin)); *p++ = ']'; } else if (progress_size) @@ -1071,27 +1073,14 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) *p++ = ']'; } - ++bp->tick; + ++bp->tick; /* " 234.56M" */ down_size = human_readable (size, 1000, 2); - cols_diff = 7 - count_cols (down_size); - while (cols_diff > 0) - { - *p++=' '; - cols_diff--; - } - sprintf (p, " %s", down_size); - move_to_end (p); - /* Pad with spaces to 7 chars for the size_grouped field; - * couldn't use the field width specifier in sprintf, because - * it counts in bytes, not characters. */ - for (size_grouped_pad = PROGRESS_FILESIZE_LEN - 7; - size_grouped_pad > 0; - --size_grouped_pad) - { - *p++ = ' '; - } + cols_diff = PROGRESS_FILESIZE_LEN - count_cols (down_size); + memset (p, ' ', cols_diff); + p += cols_diff; + p += sprintf (p, "%s", down_size); /* " 12.52Kb/s or 12.52KB/s" */ if (hist->total_time > 0 && hist->total_bytes) @@ -1104,12 +1093,11 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) wgint dlquant = hist->total_bytes + bp->recent_bytes; double dltime = hist->total_time + (dl_total_time - bp->recent_start); double dlspeed = calc_rate (dlquant, dltime, &units); - sprintf (p, " %4.*f%s", dlspeed >= 99.95 ? 0 : dlspeed >= 9.995 ? 1 : 2, + p += sprintf (p, " %4.*f%s", dlspeed >= 99.95 ? 0 : dlspeed >= 9.995 ? 1 : 2, dlspeed, !opt.report_bps ? short_units[units] : short_units_bits[units]); - move_to_end (p); } else - APPEND_LITERAL (" --.-KB/s"); + APPEND_LITERAL (" --.-KB/s"); if (!done) { @@ -1144,14 +1132,14 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) bp->last_eta_time = dl_total_time; } - sprintf (p, get_eta(&bytes_cols_diff), + p += sprintf (p, get_eta(&bytes_cols_diff), eta_to_human_short (eta, false)); - move_to_end (p); } else if (bp->total_length > 0) { skip_eta: - APPEND_LITERAL (" "); + memset (p, ' ', PROGRESS_ETA_LEN); + p += PROGRESS_ETA_LEN; } } else @@ -1161,21 +1149,23 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) int ncols; /* Note to translators: this should not take up more room than - available here. Abbreviate if necessary. */ - strcpy (p, _(" in ")); + available here (6 columns). Abbreviate if necessary. */ + strcpy (p, _(" in ")); nbytes = strlen (p); ncols = count_cols (p); bytes_cols_diff = nbytes - ncols; - p += nbytes; if (dl_total_time >= 10) - strcpy (p, eta_to_human_short ((int) (dl_total_time + 0.5), false)); + ncols += sprintf (p + nbytes, "%s", eta_to_human_short ((int) (dl_total_time + 0.5), false)); else - sprintf (p, "%ss", print_decimal (dl_total_time)); - move_to_end (p); + ncols += sprintf (p + nbytes, "%ss", print_decimal (dl_total_time)); + p += ncols + bytes_cols_diff; + memset (p, ' ', PROGRESS_ETA_LEN - ncols); + p += PROGRESS_ETA_LEN - ncols; } - while (p - bp->buffer - bytes_cols_diff < bp->width) - *p++ = ' '; + padding = bp->width - count_cols (bp->buffer); + memset (p, ' ', padding); + p += padding; *p = '\0'; /* 2014-11-14 Darshit Shah <darnir@gmail.com> @@ -1185,7 +1175,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) * assertion fails. Instead Wget should continue downloading and display a * horrible and irritating progress bar that spams the screen with newlines. */ - assert (count_cols (bp->buffer) <= bp->width + 1); + assert (count_cols (bp->buffer) == bp->width); } /* Print the contents of the buffer as a one-line ASCII "image" so diff --git a/src/recur.c b/src/recur.c index 25cdbb7..b212ec6 100644 --- a/src/recur.c +++ b/src/recur.c @@ -610,7 +610,11 @@ download_child (const struct urlpos *upos, struct url *parent, int depth, u_scheme_like_http = schemes_are_similar_p (u->scheme, SCHEME_HTTP); /* 1. Schemes other than HTTP are normally not recursed into. */ - if (!u_scheme_like_http && !((u->scheme == SCHEME_FTP || u->scheme == SCHEME_FTPS) && opt.follow_ftp)) + if (!u_scheme_like_http && !((u->scheme == SCHEME_FTP +#ifdef HAVE_SSL + || u->scheme == SCHEME_FTPS +#endif + ) && opt.follow_ftp)) { DEBUGP (("Not following non-HTTP schemes.\n")); reason = WG_RR_NONHTTP; @@ -837,7 +837,11 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file, FTP. In these cases we must decide whether the text is HTML according to the suffix. The HTML suffixes are `.html', `.htm' and a few others, case-insensitive. */ - if (redirection_count && local_file && (u->scheme == SCHEME_FTP || u->scheme == SCHEME_FTPS)) + if (redirection_count && local_file && (u->scheme == SCHEME_FTP +#ifdef HAVE_SSL + || u->scheme == SCHEME_FTPS +#endif + )) { if (has_html_suffix_p (local_file)) *dt |= TEXTHTML; @@ -1099,12 +1103,20 @@ retrieve_from_file (const char *file, bool html, int *count) proxy = getproxy (cur_url->url); if ((opt.recursive || opt.page_requisites) - && ((cur_url->url->scheme != SCHEME_FTP && cur_url->url->scheme != SCHEME_FTPS) || proxy)) + && ((cur_url->url->scheme != SCHEME_FTP +#ifdef HAVE_SSL + && cur_url->url->scheme != SCHEME_FTPS +#endif + ) || proxy)) { int old_follow_ftp = opt.follow_ftp; /* Turn opt.follow_ftp on in case of recursive FTP retrieval */ - if (cur_url->url->scheme == SCHEME_FTP || cur_url->url->scheme == SCHEME_FTPS) + if (cur_url->url->scheme == SCHEME_FTP +#ifdef HAVE_SSL + || cur_url->url->scheme == SCHEME_FTPS +#endif + ) opt.follow_ftp = 1; status = retrieve_tree (parsed_url ? parsed_url : cur_url->url, @@ -1787,7 +1787,11 @@ path_simplify (enum url_scheme scheme, char *path) for (--t; t > beg && t[-1] != '/'; t--) ; } - else if (scheme == SCHEME_FTP || scheme == SCHEME_FTPS) + else if (scheme == SCHEME_FTP +#ifdef HAVE_SSL + || scheme == SCHEME_FTPS +#endif + ) { /* If we're at the beginning, copy the "../" literally and move the beginning so a later ".." doesn't remove @@ -48,8 +48,10 @@ as that of the covered work. */ /* Disable assertions when debug support is not compiled in. */ #ifndef ENABLE_DEBUG +#ifndef NDEBUG # define NDEBUG #endif +#endif /* Is OpenSSL or GNUTLS available? */ #if defined HAVE_LIBSSL || defined HAVE_LIBSSL32 || defined HAVE_LIBGNUTLS |