344 Commits

Author SHA1 Message Date
Darshit Shah
ab8a3c80df Update NEWS file for new release 2018-01-21 11:00:29 +01:00
Darshit Shah
11ecabcb3d Fix typo in documentation 2018-01-21 11:00:25 +01:00
Darshit Shah
d0a5d9f131 Switch off compression by default
Gzip compression has a number of bugs which need to be ironed out before
we can support it by default. Some of these stem from a misunderstanding
of the HTTP spec, but a lot of them are also due to many web servers not
being compliant with RFC 7231.

With this commit, I am marking GZip compression support as experimental
in GNU Wget pending further investigation and the addition of tests.

* src/init.c (defaults): Switch of compression support by default
* docs/wget.texi: State that compression is experimental
2018-01-21 10:51:11 +01:00
Darshit Shah
0ff71e5ff1 Pull gnulib module forward 2018-01-21 10:51:09 +01:00
Darshit Shah
0d0a95a01b Revert "* src/init.c (defaults): Set compression_none as the default compression"
This reverts commit 8283ac0846.
2018-01-21 10:50:44 +01:00
Darshit Shah
8283ac0846 * src/init.c (defaults): Set compression_none as the default compression 2018-01-21 10:17:39 +01:00
Reiji
a7cc4e2b37 * src/http.c (gethttp): Fix bug that prevented all files from being decompressed
Signed-off-by: Darshit Shah <darnir@gnu.org>
2018-01-20 14:04:28 +01:00
Tim Rühsen
55d25fc20c * src/host.c (sufmatch): Fix to domain matching 2018-01-19 19:32:01 +01:00
Gisle Vanem
513cc1c0c8 * src/netrc.c: Fix Standalone compilation of netrc file 2018-01-17 14:44:52 +01:00
Darshit Shah
3249045a91 * NEWS: Update NEWS file for new release 2018-01-14 12:17:31 +01:00
Darshit Shah
b1fc37f465 * bootstrap: Use the faster gnulib-tool.py script if possible 2018-01-14 11:33:52 +01:00
Darshit Shah
953bcdaba8 Sync the bootstrap script from gnulib 2018-01-14 11:28:51 +01:00
Darshit Shah
183fccdaad Update Copyright years 2018-01-14 11:24:43 +01:00
Darshit Shah
8240439e21 Replace HTTP urls with HTTPS where valid 2018-01-14 11:15:32 +01:00
Darshit Shah
a03716a0fe Update gnulib 2018-01-14 11:15:16 +01:00
Darshit Shah
d26c6c0028 * src/netrc.c: Search for the correct netrc file on Windows 2018-01-14 10:55:03 +01:00
Tim Rühsen
047746eb76 * src/http.c: Exclude *.gz and *.tgz from decompression 2018-01-10 15:46:13 +01:00
Tim Rühsen
d8df356d4b * src/utils.c (wg_pin_peer_pubkey): Fix format warning 2017-12-31 13:03:25 +01:00
Peter Wu
220c24ecb5 Avoid redirecting output to file when tcgetpgrp fails
* src/log.c (check_redirect_output): tcgetpgrp can return -1 (ENOTTY),
be sure to check whether a valid controlling terminal exists before
redirecting.

Fixes: #51181
2017-12-31 12:59:15 +01:00
Darshit Shah
3d2b2231cd Add new test for 416 responses
* testenv/server/http/http_server.py: If there are multiple requests in
which the requested range is unsatisfiable, then send a body in the in
the 2nd response onwards
* testenv/Test-416.py: New test to check how Wget handles 416 responses
2017-12-11 14:48:01 +01:00
Darshit Shah
693cee0109 Don't assume a 416 response has no body
* http.c(gethttp): In case of a 416 response, try to drain the socket of
any bytes before reusing the connection

Reported-By: Iru Cai <mytbk920423@gmail.com>
2017-12-08 18:44:17 +01:00
Tim Rühsen
6aa6b669ef Support building with OpenSSL 1.1 w/o deprecated features
* src/openssl.c (ssl_init): Fix code for the subject's issue

Reported-by: Matthew Thode
2017-11-26 18:59:47 +01:00
Tim Rühsen
8551ceccfe Avoid link conversion after 304 Not Modified
* src/http.c (gethttp): Handle 304 before setting document content type

Fixes: #52404
Reported-by: Ben Fuchs
2017-11-25 19:33:03 +01:00
YX Hao
19060db44f Fix printing mutibyte chars as unprintable chars on Windows
* src/log.c (get_warc_log_fp): Fix return value to stderr
* src/main.c (main): Init logging as soon as possible,
  fix locale/charset on Windows
2017-11-16 12:23:20 +01:00
Tim Rühsen
a30a5a9059 * tests/Test-https-weboftrust.px: Fix/add sslport 2017-11-16 12:12:16 +01:00
YX Hao
a9a953feee Convert remote path to local encoding
* src/url.c (url_file_name): Convert remote path to local encoding
2017-11-15 19:58:53 +01:00
Tim Rühsen
267cd51fff Do not use must-revalidate in Cache-Control header
As the bug report states, 'must-revalidate' is a request directive.

Fixes #52379
2017-11-10 10:57:46 +01:00
Darshit Shah
973c26ed7d Fix Segfault due to derefencing null ptr
* src/http.c(gethttp): When Encoding is gzip, ensure that the
Content-Type Header was actually seen. Without this, the "type" variable
is null causing a Segfault.

Reported-By: Noël Köthe <noel@debian.org>
2017-11-06 10:09:03 +01:00
Tim Rühsen
16d066f89c * src/http.c: Fix H_REDIRECTED 2017-11-03 22:23:04 +01:00
Tim Rühsen
a2477d487c * src/http.c: Add support for HTTP status code 308 2017-11-03 22:12:11 +01:00
Tim Rühsen
7ac72e063c Fix uninitialized value messages in tests
* tests/Test-https-*.px: Use correct variable in error message

Reported-by: Jeffrey Walton
2017-10-30 21:29:14 +01:00
Tim Rühsen
95891cbba3 Ignore dirmngr.conf, gpg.conf in test directories
* testenv/conf/expected_files.py: Ignore dirmngr.conf, gpg.conf

Libgpgme creates certain files if $HOME doesn't contain the .gnupg directory.
These files disturb some metalink tests if we don't ignore them.

Reported-by: Arkadiusz Miśkiewicz <arekm@maven.pl>
2017-10-30 13:04:09 +01:00
Tim Rühsen
2486320a2a * contrib/release: Cleanup, use lzip instead of xz 2017-10-27 11:26:37 +02:00
Tim Rühsen
ba6b44f674 Fix heap overflow in HTTP protocol handling (CVE-2017-13090)
* src/retr.c (fd_read_body): Stop processing on negative chunk size

Reported-by: Antti Levomäki, Christian Jalio, Joonas Pihlaja from Forcepoint
Reported-by: Juhani Eronen from Finnish National Cyber Security Centre
2017-10-26 17:29:38 +02:00
Tim Rühsen
d892291fb8 Fix stack overflow in HTTP protocol handling (CVE-2017-13089)
* src/http.c (skip_short_body): Return error on negative chunk size

Reported-by: Antti Levomäki, Christian Jalio, Joonas Pihlaja from Forcepoint
Reported-by: Juhani Eronen from Finnish National Cyber Security Centre
2017-10-26 17:29:38 +02:00
Tim Rühsen
bec4c215a8 Update for release 1.19.2
* NEWS: Add news for 1.19.2
* doc/wget.texi: Fix 1.20 to 1.19.2
2017-10-26 16:31:57 +02:00
YX Hao
27d78d944f Avoid unnecessary UTF-8 encoded fallback (trivial change)
* src/retr.c (retrieve_url): Check for changed URL on redirect
2017-10-25 14:26:36 +02:00
Tim Rühsen
60f033426f Add GNU extensions to .netrc parsing
src/netrc.c (parse_netrc): Add 'port' and 'force' extensions

Reported-by: September 20Tim Landscheidt
2017-09-27 12:42:06 +02:00
Josef Moellers
6f3b995993 Bail out on unexpected 416 server errors
* src/http.c (gethttp): Stop on 416 if file is incomplete
2017-09-18 16:45:49 +02:00
Tim Schlueter
c451eec155 Add gzip Content-Encoding decompression
* src/http.c (struct http_stat): Add remote_encoding field.
(read_response_body): Enable gzip decompression.
(initialize_request): Send gzip Accept-Encoding header.
(gethttp): Decompress files with gzip Content-Encoding.
* src/retr.c: include zlib.h.
(zalloc): New function.
(zfree): New function.
(fd_read_body): Decompress gzip data.
* src/retr.h (fd_read_body enum): Add rb_compressed_gzip flag.
2017-08-04 14:34:53 +02:00
Tim Schlueter
b543dfe783 Add --compression option
* doc/wget.texi: Add --compression documentation.
* src/init.c (cmd_spec_compression): New function.
(commands[]): Add opt.compression.
(defaults): Set default opt.compression value.
* src/main.c (option_data[]): Add struct for --compression.
(print_help, help[]): Add description for --compression.
(main): Add incompatibility checks for --compression.
* src/options.h (struct options): Add compression enum and field.
2017-08-04 14:34:53 +02:00
Tim Schlueter
08ed2a5530 Adjust Extension based on Content-Encoding
* doc/wget.texi (--adjust-extension, adjust_extension): Updated documentation.
* src/http.c (encoding_t): New enum.
(struct http_stat): Add local_encoding field.
(gethttp): --adjust-extension based on Content-Encoding.
2017-08-04 14:34:53 +02:00
Darshit Shah
951d3e4cdd Document gperf as a requirement 2017-07-31 14:56:32 +02:00
Tim Rühsen
3ad3b3e36c * src/url.c (url_scheme): Use ASCII version of strncasecmp 2017-07-28 17:11:26 +02:00
Tim Rühsen
5fb6b6bd68 Fix misuse of strncasecmp
* src/http.c (set_content_type): Use c_strcasecmp instead of strncasecmp

See issue bug #51576
2017-07-28 16:56:27 +02:00
Tim Rühsen
f42229b1fd Fix python test suite for GnuTLS 3.5.12+
* testenv/Test-*.py: Replace 127.0.0.1 by localhost
* testenv/certs/server-template.cfg: Likewise
* testenv/certs/server-cert.pem: Regenerate
* testenv/certs/server-crl.pem: Likewise
* testenv/test/base_test.py: Hardcode 'localhost' as server domain

Reported-by: Ludovic Courtès <ludo@gnu.org>
2017-07-09 11:39:05 +02:00
Tim Rühsen
21154bdc36 Check for 304 response before applying --adjust-extension
* src/http.c (gethttp): Move 304 code before --adjust-extension code

This fixes applying --adjust-extension in combination with 304
HTTP responses. It could lead to .html extensions to arbitrary
files.

Reported-by: anfractuosity
2017-06-13 11:25:20 +02:00
Tim Rühsen
ae293c945a Fix buffer overflow in Public Key Pinning
* src/utils.c (wget_base64_decode): Add param for destination size,
  (wg_pubkey_pem_to_der): Amend call to wget_base64_decode(),
  (wg_pin_peer_pubkey): Likewise and fix code style.
* src/utils.h: Add param to wget_base64_decode()
* src/http-ntlm.c (ntlm_input): Amend call to wget_base64_decode()
* src/http.c (skip_content_type): Likewise

Fixes #51227
2017-06-13 10:23:04 +02:00
Tim Rühsen
407c1f990a * doc/wget.texi: Mention --no-config 2017-06-02 10:13:22 +02:00
Tim Rühsen
86b46a34a5 * testenv/Test-recursive-basic.py: Check crawled files 2017-05-16 11:20:57 +02:00
Tim Rühsen
5d4ada1b7b Fix two Metalink tests if $HOME is changed
* conf/expected_files.py (gen_local_fs_snapshot): Skip processing
  of 'pubring.kbx'
2017-05-16 10:24:52 +02:00
Tomas Hozza
876def8ebe Add command line option to disable use of .netrc
Although internally code uses option for (not) reading .netrc for
credentials, it was not possible to turn this behavior off on command
line. Note that it was possible to turn it off using wgetrc.

Idea for this change came from Bruce Jerrick (bmj001@gmail.com).
Reference: https://bugzilla.redhat.com/show_bug.cgi?id=1425097

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2017-05-15 16:06:50 +02:00
Tomas Hozza
f8c3df1f40 Fixed getting of credentials from .netrc
There seemed to be a copy&paste error in http.c code, which decides
whether to get credentials from .netrc. In ftp.c "user" and "pass"
variables are char*, while in http.c, these are char**. For this reason
they should be dereferenced when determining if password and user login
is set to some value.

Also since both variables are dereferenced on lines above the changed
code, it does not really make sense to check if they are NULL.

This patch is based on fix from Bruce Jerrick <bmj001@gmail.com>.
Fedora bug: https://bugzilla.redhat.com/show_bug.cgi?id=1425097

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2017-05-15 16:06:50 +02:00
Tomas Hozza
17960b57d5 Added tests for HTTP authentication using credentials from .netrc
Getting credentials from .netrc has been broken from time to time, thus
adding a test coverage to prevent regressions.

Also added setting of "HOME" environment variable when executing wget,
to make sure LocalFiles like .netrc, which are created just for the
test, are actually used.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2017-05-15 16:06:50 +02:00
Tim Rühsen
40c0d30f5c Fix Test-https-badcerts.px
* util/createcerts.sh: Set date of invalid cert to +20 years
* tests/certs/invalid.crt: Re-generated
* tests/certs/invalid.key: Re-generated
2017-05-15 15:46:11 +02:00
Tim Rühsen
e2c702571f * util/createcerts.sh: Fix double equal (syntax-check) 2017-05-14 21:35:34 +02:00
Tim Rühsen
269fb6201d Fix Test-https-badcerts.px to work with GnuTLS
* tests/Test-https-badcerts.px: Remove OpenSSL requirement
* tests/certs/expired.crt: Re-created with valid dates
* tests/certs/expired.key: Likewise
* tests/certs/invalid.crt: Likewise
* tests/certs/invalid.key: Likewise
2017-05-14 11:10:15 +02:00
Vijo Cherian
c08778aeb3 New shell script to create the certs and keys required for TLS tests
* util/createcerts.sh: New file
2017-05-14 11:07:43 +02:00
Tim Rühsen
297c1e2ac3 Fix HTTPS testing for stricter OpenSSL
* testenv/certs/README: Amend cert creation extensions
* testenv/certs/ca-cert.pem: Created without OCSP signing purpose

Having the OCSP signing purpose set made newer versions of OpenSSL
fail due to stricter checking. Test version of OpenSSL was 1.1.0e.
2017-05-11 12:38:19 +02:00
Tim Rühsen
936efc3564 * src/iri.c (idn_encode): Better IDNA 2003 compatibility 2017-05-11 11:56:26 +02:00
Tim Rühsen
11d3de74ca * .gitlab-ci.yml: Also test OpenSSL build 2017-05-10 12:12:42 +02:00
Tim Rühsen
35d5b67cc1 * .gitlab-ci.yml: Remove installation of texlive 2017-05-10 10:41:42 +02:00
Tim Rühsen
da50a1ecc3 Add certs/wotca.pem to avoid temp. file creation
* tests/certs/wotca.pem: New file
* tests/Test-https-weboftrust.px: Remove creation of wotca.pem

This change let Test-https-weboftrust.px survive VPATH builds.
2017-05-10 10:34:42 +02:00
Tim Rühsen
1068ca07d3 * cfg.mk: Exclude ^tests/certs/.* from syntax-check 2017-05-10 10:05:18 +02:00
Tim Rühsen
0666e0f375 * po/POTFILES.in: Remove spider.c (syntax-check) 2017-05-10 10:04:34 +02:00
Tim Rühsen
0d9f8280e0 * tests/Test-https-selfsigned.px: Add newline at EOF (syntax-check) 2017-05-10 10:04:30 +02:00
Vijo Cherian
17f0e16ecc Removed all uses of temp files.
Added needed files to GIT
2017-05-09 16:45:13 -07:00
Vijo Cherian
cc74f8b7e2 Made CRL related files in the repo, instead of trying to generate them 2017-05-09 15:37:28 -07:00
Tim Rühsen
2894a37189 Cleanup on exit in Test-https-*.px
* tests/Test-https-*.px: Cleanup on exit
2017-05-09 16:58:33 +02:00
Tim Rühsen
4669ba5e0c Auto-generate interca.conf and rootca.conf
* configure.ac: Add interca.conf.in and rootca.conf.in to AC_CONFIG_FILES
* tests/certs/interca.conf: Removed
* tests/certs/rootca.conf: Removed
* tests/certs/interca.conf.in: New file
* tests/certs/rootca.conf.in: New file
2017-05-09 16:04:48 +02:00
Tim Rühsen
b5c2d083ea Fix path and VPATH issues of new https/TLS tests
* tests/SSLTest.pm: Use $srcdir in read-only files,
  (_setup_server): Remove unneeded path fixation code
* tests/Test-https-*.px: Use $srcdir for read-only files,
  use $cdir for writable files
* tests/certs/interca.conf: Adjust paths
* tests/certs/rootca.conf: Adjust paths
2017-05-09 15:21:23 +02:00
Tim Rühsen
466afc62b0 Check for test server name resolution in tests
* tests/Test-https-*.px: Skip if test server name resolution fails
2017-05-09 11:16:30 +02:00
Tim Rühsen
f68d001626 * tests/Makefile.am: Enable Test-https-badcerts again 2017-05-09 11:16:30 +02:00
Tim Rühsen
ffe75d0867 Fix WgetFeature.pm to allow multiple required features
* tests/WgetFeature.cfg: Remove file
* tests/WgetFeature.pm: Extend to multiple features, cleanup
2017-05-09 11:16:30 +02:00
Tim Rühsen
9aa894853f * .gitlab-ci.yml: Add wgettestingserver to /etc/hosts 2017-05-09 11:08:32 +02:00
Tim Rühsen
5337b94ce5 * tests/SSLServer.pm: Check for IO::Socket::SSL 2017-05-09 11:08:32 +02:00
Tim Rühsen
a26e6f3527 * tests/Test-https-*: Change server port to <= 32767 2017-05-09 11:08:32 +02:00
Tim Rühsen
b9fb74ddfa Move https test server ports from >32767 to <= 32767
* Test-https-badcerts.px: Change port
* Test-https-crl.px: Likewise
* Test-https-weboftrust.px: Likewise
2017-05-09 11:08:32 +02:00
Tim Rühsen
3132049ae4 * tests/Makefile.am: Add SSLTest.pm and SSLServer.pm to EXTRA_DIST 2017-05-09 11:08:32 +02:00
Tim Rühsen
c0c42da653 * tests//Makefile.am: Disable Test-https-badcerts.px 2017-05-09 11:08:32 +02:00
Tim Rühsen
888cc82c9d Add Gitlab CI (Debian)
* .gitlab-ci.yml: New file
2017-05-09 11:08:32 +02:00
Tim Rühsen
fce1b689e8 * .travis.yml: Use trusty for libidn2-dev 2017-05-06 13:03:28 +02:00
Tim Rühsen
580067d1e6 * tests/certs/test-ca-key.pem: Add newline at EOF 2017-05-04 16:51:49 +02:00
Tim Rühsen
5c4cc011fe Add static HOSTSALIAS file
* tests/certs/wgethosts: New file
* tests/Test-https-*.px: Remove creation of wgethosts file
2017-05-04 16:51:49 +02:00
Vijo Cherian
2a96249469 Added new tests for SSL
* tests/Test-https-badcerts.px : New file
* tests/Test-https-clientcert.px : New file
* tests/Test-https-crl.px : New file
* tests/Test-https-weboftrust.px : New file
* tests/certs/interca.conf : New file
* tests/certs/rootca.conf : New file
* tests/certs/test-ca-key.pem : New file

Added all new SSL / HTTPS tests to make check
Added Test for SSL Web of Trust, accept only if CA chain of trust is intact.
Added a test script for client certificate
Added Test for crlfile option of wget
Added test to make sure that wget doesn't accept expired or invalid certs

Some clean up : 1, Removed cause of warnings from perl & other cosmetic changes
                2, Fix  make -j 4 check such that it passes all tests
2017-05-04 16:51:49 +02:00
Tomas Hozza
0b41c7543a Mention TLSv1_1 and TLSv1_2 as secure-protocol values in help
* src/main.c: The --secure-protocol option accepts also values TLSv1_1
and TLSv1_2, as mentioned in the man page. However the help message
doesn't mention these two values. This patch adds TLSv1_1 and TLSv1_2 as
possible values to the help message.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2017-05-04 14:51:54 +02:00
Tim Rühsen
c4a2b2e77e * src/http.c (gethttp): Support Wayback Machine's X-Archive-Orig-last-modified 2017-05-03 16:37:11 +02:00
Vijo Cherian
f6376ac0dc Added new tests for SSL
* tests/Test-https-badcerts.px : New file
* tests/Test-https-clientcert.px : New file
* tests/Test-https-crl.px : New file
* tests/Test-https-weboftrust.px : New file
* tests/certs/interca.conf : New file
* tests/certs/rootca.conf : New file
* tests/certs/test-ca-key.pem : New file

Added all new SSL / HTTPS tests to make check
Added Test for SSL Web of Trust, accept only if CA chain of trust is intact.
Added a test script for client certificate
Added Test for crlfile option of wget
Added test to make sure that wget doesn't accept expired or invalid certs

Some clean up : Removed cause of warnings from perl & other cosmetic changes
2017-04-28 12:22:54 +02:00
Vijo Cherian
ac519c041e Added new tests for SSL
* tests/SSLServer.pm: New file
* tests/SSLTest.pm: New file
* tests/Test-https-pfs.px: New file
* tests/Test-https-selfsigned.px: New file
* tests/Test-https-tlsv1.px: New file
* tests/Test-https-tlsv1x.px: New file
* tests/certs/server.crt: New file
* tests/certs/server.key: New file
* tests/certs/test-ca-cert.pem: New file

Added 4 new test scripts all for SSL.
Added base pm for SSL testing.
Added SSL tests for TLSv1, TLSv1_1 and PFS.
Added test for self signed cert : check that it fails without
--no-check-certificate and passes with that flag.
2017-04-19 12:59:27 +02:00
Tim Rühsen
56c78c4b09 * src/utils.c: Remove non-portable __builtin_unreachable() 2017-04-18 13:22:25 +02:00
Tim Rühsen
0ec46cb109 Skip iconv() usage if HAVE_ICONV is not defined
This helps on broken iconv implementations, e.g. Solaris.

Reported-by: Mojca Miklavec
2017-04-18 13:17:19 +02:00
Tim Rühsen
67cb37ce5a Mention 'bash' for executing ./bootstrap
Reported-by: Mojca Miklavec
2017-04-18 10:47:15 +02:00
Tim Rühsen
0004d3ec22 * bootstrap.conf: Make 'sed' options more portable
'sed -i' works differently on FreeBSD.

Reported-by: Mojca Miklavec
2017-04-18 10:44:06 +02:00
Tim Rühsen
92bfe2a2e4 Fix charset transcoding issue for non-reversible codepoints
* src/url.c: Check iconv() against 0, not -1

On some libiconv implementations, unknown codepoints become
encoded as ?, e.g. when converting a non-ascii codepoint to ASCII.
This results in ambigious file names which also fails our tests.
2017-04-16 19:55:14 +02:00
Tim Rühsen
fc2f4233ed * src/iri.c: Fix WIN32 idn2_free, forgotten code 2017-04-16 19:50:10 +02:00
Darshit Shah
b2c38d33e1 * src/init.c: Set flstats correctly when using WGETRC env var 2017-04-14 01:16:49 +02:00
Tim Rühsen
6ef493b19e Fix use of idn2_free()
* src/connect.c (connect_to_ip): Use xfree() instead of idn2_free()
* src/host.c (lookup_host): Use xfree() instead of idn2_free()
* src/iri.h: Do not include idn2.h
* src/url.c (url_free): Use xfree() instead of idn2_free()
* src/url.h (struct url): Remove 'idn_allocated' from struct

Reported-by: Gisle Vanem
2017-04-08 11:05:55 +02:00
Anton Yuzhaninov
7ffe93cabb Fix perl warnings in tests
* tests/FTPServer.pm: Escape '{' in RE to fix warnings
* tests/FTPTest.pm: Likewise
* tests/HTTPServer.pm: Likewise
* tests/HTTPTest.pm: Likewise
* tests/Test-proxied-https-auth-keepalive.px: Likewise
* tests/Test-proxied-https-auth.px: Likewise
Escape '{' in RE to fix warnings:
Unescaped left brace in regex is deprecated, passed through in regex;
marked by <-- HERE in m/{{ <-- HERE port}}/
2017-04-05 20:04:12 +02:00
klemens
f381831d88 Fix typos in comments 2017-04-01 19:38:09 +02:00
Tim Rühsen
02d40a4676 * src/metalink.c (retrieve_from_metalink): Fix len in memset() 2017-03-31 13:15:27 +02:00
Tim Rühsen
e89267fbbc Add gnulib module group-member 2017-03-24 11:36:01 +01:00
Vijo Cherian
400b8eba6c Safeguards against TOCTTOU
* src/utils.h: Add struct file_stat_s declaration,
  change prototypes of file_exists_p(),
  add prototypes for fopen_stat() and open_stat().
* src/utils.c: Extend file_exists_p(),
  new function fopen_stat() and open_stat(),
  add new param for file_exists_p().
* src/init.h: Add param file_stats_t to run_wgetrc().
* src/ftp.c: Amend calls to extended functions.
* src/hsts.c: Likewise.
* src/http.c: Likewise.
* src/init.c: Likewise.
* src/main.c: Likewise.
* src/metalink.c: Likewise.
* src/retr.c: Likewise.
* src/url.c: Likewise.

Added fopen_stat() and open_stat() that checks to makes sure the file didn't
change underneath us.
Return error from file_exists_p().
Added a way to return error from this file without major surgery to the
callers.

Fixes: #20369
2017-03-24 09:39:09 +01:00
Tim Rühsen
90a0a7499c Update gnulib 2017-03-24 09:19:52 +01:00
Christof Horschitz
1d71645c06 * src/warc.c (warc_write_cdx_record): Escape URLs 2017-03-22 15:01:04 +01:00
Mike Frysinger
e249844143 Include libunistring headers only when used
* src/iri.c: Check for libidn2 < 0.14 to include libunistring headers

The unistring functions are used only when an older version of libidn2
is used, so don't include its headers either w/newer libdin2 versions.
2017-03-20 09:39:20 +01:00
Tim Rühsen
84a93f4127 Fix links to www.robotstxt.org
* NEWS: Fix links
* doc/wget.texi: Likewise
* src/res.c: Likewise

Reported-by: Noël Köthe
2017-03-18 19:05:38 +01:00
Tim Rühsen
f31b93424b * tests/WgetTests.pm: Add -d to Wget test options 2017-03-13 21:31:09 +01:00
Tim Rühsen
90b487369a Include <arpa/inet.h> for Windows
Reported-by: Gisle Vanem
2017-03-08 13:00:54 +01:00
Tim Rühsen
57d748117f Fix updating HSTS entries
* src/hsts.c (hsts_store_entry): Always update 'created' field

Fixes: #50490
Reported-by: Deian Stefan, Atyansh Jaiswal, Jonathan Luck
2017-03-08 10:56:12 +01:00
Tim Rühsen
4d729e322f Fix CRLF injection in Wget host part
* src/url.c (url_parse): Reject control characters in host part of URL

Reported-by: Orange Tsai
2017-03-06 10:04:22 +01:00
Benjamin Esham
63c2aea255 * src/warc.c: Use warc_write_header_uri for all WARC-Target-URI fields
The WARC spec requires that all URIs be enclosed in angle brackets. This
was being done in most cases, but not for "WARC-Target-URI" fields in
WARC blocks of type "response", "resource", "revisit", and "metadata".
2017-03-04 12:51:39 +01:00
Tim Rühsen
ac4fed3220 Fix 504 status handling
* src/http.c (gethttp): Move 504 handling to correct place.
  (http_loop): Fix memeory leak.
* testenv/server/http/http_server.py: Add Content-Length header on non-2xx
  status codes with a body

Reported-by: Adam Sampson
2017-02-16 15:53:56 +01:00
YX Hao
cf5df5593d * src/url.c (url_file_name): Do not charset convert local directory
In a non-ASCII environment, the local path may contain non-ASCII
characters. The server responded file name must be converted before
it is concatenated to the local path. Conversion after concatenation
may result in 'iconv' errors.
2017-02-16 12:52:16 +01:00
Tim Rühsen
2215ee8d10 * configure.ac: Remove manually resetting of LIBICONV variable
Fixes: #48193
Reported-by: ilovezfs
Reported-by: Charles
2017-02-15 20:03:58 +01:00
Tim Rühsen
32e26dc199 * bootstrap.conf: Call gperf to create lib/unicase/special-casing-table.h 2017-02-15 14:45:23 +01:00
Tim Rühsen
21ac4ae356 * bootstrap.conf: Fix latest gnulib to work with gperf < 3.1 2017-02-15 13:03:10 +01:00
Darshit Shah
838c185ca9 Pull GNULib to latest.
* gnulib: Pull to latest commit. This fixes an issue with Gperf 3.1
2017-02-14 15:08:50 +01:00
Tim Rühsen
ac9be9b756 * src/main.c: Remove double 'verbose' option
Fixes: #50290
2017-02-12 21:18:23 +01:00
Tim Rühsen
6620c5156f * NEWS: update 2017-02-11 12:03:54 +01:00
Tim Rühsen
aebd49d9d4 isrc/http.c (check_retry_on_http_error): Fix gcc warning 2017-02-11 11:54:21 +01:00
Tom Szilagyi
d6d00006a0 Add support for --retry-on-http-error
* doc/wget.text: Add documentation
* src/http.c: Add function check_retry_on_http_error ()
* src/init.c: Add opt.retry_on_http_error
* src/main.c: Add struct for retry-on-http-error to option_data[]
* src/options.h: Add retry_on_http_error to struct options
2017-02-11 11:50:24 +01:00
Tim Rühsen
05acf5d3f6 Revert "Add support for --retry-on-http-error"
This reverts commit 977276374d.
2017-02-11 11:45:11 +01:00
Tim Rühsen
80c62c238e Change libtool library deps to non-libtool deps
Reported-by: Yousong Zhou
Fixes: #50260
2017-02-10 17:20:42 +01:00
Tom Szilagyi
977276374d Add support for --retry-on-http-error
* doc/wget.texi: Add description for --retry-on-http-error
* src/http.c (gethttp):
Consider given HTTP response codes as non-fatal, transient errors.
Supply a comma-separated list of 3-digit HTTP response codes as
argument. Useful to work around special circumstances where retries
are required, but the server responds with an error code normally not
retried by Wget. Such errors might be 503 (Service Unavailable) and
429 (Too Many Requests). Retries enabled by this option are performed
subject to the normal retry timing and retry count limitations of
Wget.

Using this option is intended to support special use cases only and is
generally not recommended, as it can force retries even in cases where
the server is actually trying to decrease its load. Please use it
wisely and only if you know what you are doing.

Example use and a starting point for manual testing:
  wget --retry-on-http-error=429,503 http://httpbin.org/status/503
2017-02-09 21:17:20 +01:00
Tim Rühsen
785c4b92dd * tests/WgetTests.pm: Add --no-config to wget invocation
Without --no-config, wgetrc commands may disturb the tests.

Reported-by: Dagobert Michelsen
2017-02-09 16:34:27 +01:00
Tim Rühsen
d7c34dc0a8 * tests/WgetTests.pm (_verify_download): Fix failure message
Reported-by: Zhiming Wang
2017-02-06 23:01:08 +01:00
Tim Rühsen
d061e553a1 * src/http.c (initialize_request): Fix regression in .netrc auth
Reported-by: Axel Reinhold
2017-02-06 21:44:18 +01:00
Tim Rühsen
2ddd2b69e4 * src/iri.c (idn_encode): Fix memory leak 2017-02-06 21:39:44 +01:00
Tim Rühsen
990f3d67d3 Remove skipping libunistring with --disable-iri
* configure.ac: Remove checking for IRI=no

On certain systems, gnulib falls back to libunistring
for mbtowc() and wcwidth() (used in src/progress.c).

Reported-by: Zhiming Wang
2017-02-06 11:25:48 +01:00
Tim Rühsen
d680b0b551 * bootstrap.conf: Add gnulib module wcwidth 2017-02-04 19:30:38 +01:00
Tim Rühsen
31ac36e170 Fix include/define clash with gnulib's unlink module
* src/options.h: Rename options.unlink to options.unlink_requested
* src/init.c: Replace options unlink member by unlink_requested
* src/http.c: Likewise
* src/ftp.c: Likewise
2017-02-04 18:02:54 +01:00
Tim Rühsen
51b401f5c4 * bootstrap.conf: Specify unicode modules more exact 2017-02-04 18:01:44 +01:00
Tim Rühsen
f2c4289557 * src/xattr.h: Fix #define fsetxattr for MacOS and FreeBSD
Reported-by: Zhiming Wang
2017-02-04 15:29:44 +01:00
Tim Rühsen
58546e52e2 * contrib/release: New release helper script 2017-02-03 16:16:30 +01:00
Tim Rühsen
820f3fc2b4 * cfg.mk: Fix syntax-check 2017-02-03 16:16:30 +01:00
Tim Rühsen
cc8464206d * doc/announcement_1.19.txt: Add new file 2017-02-03 15:19:05 +01:00
Tim Rühsen
366d82f349 * src/utils.c: Move macro FMT_MAX_LENGTH into scope 2017-02-03 12:35:49 +01:00
Tim Rühsen
f2574e90b7 * src/utils.c: Fix -Wformat= warnings 2017-02-03 12:33:38 +01:00
Tim Rühsen
81b3aaf75c * src/gnutls.c: Fix -Wformat= warnings 2017-02-03 12:31:51 +01:00
Tim Rühsen
17d2f42a3d * src/iri.c: Remove unused macro IDNA_FLAGS 2017-02-03 12:28:37 +01:00
Tim Rühsen
638df40476 * src/iri.c: Remove use of __func__ macros 2017-02-03 12:28:05 +01:00
Tim Rühsen
00bafe72f1 * src/http.c: Fix -Wformat= warnings 2017-02-03 12:24:41 +01:00
Tim Rühsen
e777c01f43 * src/progress.c: Remove unused macro move_to_end 2017-02-03 12:18:14 +01:00
Tim Rühsen
3ba112ea57 * src/html-parse.c: Remove unused macro SKIP_NON_WS 2017-02-03 12:15:24 +01:00
Tim Rühsen
485fcfcc20 * src/hsts.c: Remove unused macro CHECK_EXPLICIT_PORT 2017-02-03 12:09:18 +01:00
Tim Rühsen
a5094731cd * src/hsts.c: Fix -Wformat= warnings 2017-02-03 12:08:08 +01:00
Tim Rühsen
3186eb2976 * src/hash.c: Explicitly convert float to int 2017-02-03 12:03:50 +01:00
Tim Rühsen
9947663af8 * src/ftp-ls.c: Fix -Wformat= warnings 2017-02-03 11:59:33 +01:00
Tim Rühsen
cfae085665 * src/ftp.c (ftp_retrieve_list): Add default to switch 2017-02-03 11:57:02 +01:00
Tim Rühsen
e69808256b * src/css-url.h: Remove redundant declaration 2017-02-03 11:53:28 +01:00
Tim Rühsen
11989ef669 * src/ftp.c: Fix -Wformat= warning 2017-02-03 11:52:08 +01:00
Tim Rühsen
5fceab6cb9 * src/http.c (test_parse_range_header): Fix constants 2017-02-03 10:32:42 +01:00
Dale R. Worley
d6eead1794 Improve documentation of --trust-server-names. 2017-02-02 12:10:43 +01:00
Tim Rühsen
d0e02a54ae * src/url.c (mkalldirs): Add newline to log message 2017-02-02 11:11:50 +01:00
Tim Rühsen
2e70409844 * src/cookies.c (check_domain_match): Add newline to DEBUG lines 2017-02-02 11:11:07 +01:00
Tim Rühsen
4734e8d4d7 * NEWS: update 2017-01-17 15:16:40 +01:00
Tim Rühsen
0fe8a5c40e * README.checkout: Link HTTPS where possible, update flex homepage 2017-01-17 14:25:15 +01:00
Tim Rühsen
1b9374ee59 * README.checkout: Fix libidn to libidn2 2017-01-17 14:07:16 +01:00
Tim Rühsen
6de24fe3c0 * src/iri.c: Use TR46 non-transitional for toASCII conversion 2017-01-13 15:53:03 +01:00
Tim Rühsen
0ab3d92c85 * src/main.c: Fix _Noreturn compiler warnings 2017-01-13 15:50:19 +01:00
Tim Rühsen
4cf8af84e0 * src/utils.c: Fix _Noreturn compiler warning 2017-01-13 15:49:05 +01:00
Tim Rühsen
42b8761cbc * src/init.c (setval_internal): Fix sign compare warning 2017-01-13 15:47:02 +01:00
Tim Rühsen
fd0f759597 Replace home-grown portability code by gnulib modules
* bootstrap.conf: Add intprops, inttypes, limits-h, signal-h,
  stat, sys_types
* src/ftp.c: Replace 'struct_stat' by 'struct stat'
* src/hsts.c: Likewise
* src/http.c: Likewise
* src/main.c: Likewise
* src/netrc.c: Likewise
* src/retr.c: Likewise
* src/url.c: Likewise
* src/utils.c: Likewise
* src/sysdep.h: Remove old portability code

Further portability issues should be addressed by gnulib.
2017-01-13 15:38:15 +01:00
Tim Rühsen
a384f5e2e9 Replace WGET_* m4 macros by gnulib modules
* bootstrap.conf: Add hostent, inet_ntop, nanosleep, utimens
* configure.ac: Remove WGET_STRUCT_UTIMBUF, WGET_FNMATCH,
  WGET_NANOSLEEP, WGET_POSIX_CLOCK, WGET_NSL_SOCKET
* m4/wget.m4: Likewise
* src/Makefile.am: Add $(LIB_NANOSLEEP) $(LIB_POSIX_SPAWN) to LDADD
* tests/Makefile.am: Likewise
* src/host.c (print_address): Use inet_ntop also for IPV4
2017-01-13 12:54:35 +01:00
Tim Rühsen
5ae1f37902 Remove libidn vulnerability work-around
* src/iri.c (_utf8_is_valid): Removed

Since we are using libidn2 for IDNs, we no longer need
this work-around.
2017-01-13 12:03:47 +01:00
Tim Rühsen
0eb4a21b6c * src/iri.c (idn_encode): Use TR46 transitional if available 2017-01-13 11:45:18 +01:00
Tim Rühsen
60dc3c21b2 * gnulibx: Update 2017-01-13 10:59:25 +01:00
Tim Rühsen
1a01a6b2d0 Fix previous commit 2427ca4ac0 2017-01-07 15:59:11 +01:00
vijeth-aradhya
2427ca4ac0 Fix http.c and ftp.c passwd logic error
* src/ftp.c (getftp): Fix password/user selection
* src/http.c (initialize_request): Likewise

Before, netrc password won over interactive
--ask-password but now --ask-password wins
after change of program logic

Fixes Issue #48811
2017-01-06 16:18:40 +01:00
Giuseppe Scrivano
42c2ce71bc * src/main.c (main): Add missing \n in error message 2016-12-31 17:11:01 +01:00
Giuseppe Scrivano
def133f26f Check that fd_set has not fds bigger than FD_SETSIZE
* src/connect.c: check that the fd is not bigger than FD_SETSIZE
  before using FD_SET.  An fd_set cannot hold fds bigger than
  FD_SETSIZE, causing out-of-bounds write to a buffer on the stack.

Reported by: Jann Horn <jannh@google.com>
2016-12-28 12:24:19 +01:00
Nikos Mavrogiannopoulos
b9ed06afd8 Avoid calling the gnutls priority functions multiple times
* src/gnutls.c (ssl_connect_wget): Call gnutls_set_default_priority()
  for --secure-protocol=auto (default).

The patch fixes a behavior that may have unintended side-effects in
certain gnutls versions. Instead use the default priorities when no
options are given.

Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
2016-12-20 14:48:31 +01:00
Tim Rühsen
1bdc20d774 Print debug message when skipping certain recursive downloads
* src/recur.c (retrieve_tree): Print debug message instead silently
  skipping recursive downloads.
2016-12-19 12:19:52 +01:00
Rahul Bedarkar
e4e9d3c1c8 Rename base64_{encode,decode} (trivial patch)
* src/http-ntlm.c: Rename base64_{encode,decode}
* src/http.c: Likewise
* src/utils.c: Likewise
* src/utils.h: Likewise

When statically linking with gnutls, we get definition clash error for
base64_encode which is also defined by gnutls.

To prevent definition clash, rename base64_{encode,decode}

Signed-off-by: Rahul Bedarkar <rahul.bedarkar@imgtec.com>
2016-12-14 15:52:52 +01:00
Tim Rühsen
dcdd618b18 Add support for psl_latest()
* configure.ac: Add check for psl_latest(),
  remove --with-psl-file
* src/cookies.c (check_domain_match): Use psl_latest() if available
2016-12-11 21:04:40 +01:00
Piotr Wajda
3c796b9a85 Respect -o parameter again
* log.c: don't choose log output dynamically when opt.lfilename is set

 Regression introduced by dd5c549f6a
 Reported-by: Dale R. Worley
2016-11-09 13:32:14 +01:00
Tim Rühsen
00ae9b4ee2 Move Wget from IDN2003 (libidn) to IDN2008 (libidn2)
* .travis.yml: Install libidn2-dev instead libidn11-dev.
* bootstrap.conf: Add modules libunistring-optional, unistr/base,
  unicase/tolower.
* configure.ac: Check for libidn2.
* src/Makefile.am: Add $(LTLIBUNISTRING) to LDADD.
* tests/Makefile.am: Set LDADD similar to LDADD in src/Makefile.am
* src/connect.c: Use libidn2 code instead of libidn.
* src/host.c: Likewise.
* src/iri.c: Likewise.
* src/iri.h: Likewise.
* src/options.h: Likewise.
* src/url.c: Likewise.
* src/url.h: Likewise.
* src/log.c: Fix C99 comment.

IDN2003 should not be used any more due to security concerns.
We use libunistring (resp. the unicode code from gnulib) for
lowercasing UTF-8 before we give data to libidn2.
TR#46 is missing, no support in libidn2 nor in libunistring.
2016-11-07 11:03:42 +01:00
Tim Rühsen
2242d5aee4 Use -O0 in contrib scripts
* contrib/check-hard: Use -O0 instead of -O2 to speed up script.
* contrib/travis-ci: Likewise.
2016-11-03 15:47:41 +01:00
Tim Rühsen
77a546348c Update gnulib 2016-11-03 13:28:17 +01:00
Tim Rühsen
be5517f98f * src/metalink.c: Fix typo 'suceeded' -> 'succeeded'
Reported-by: Göran Uddeborg <goeran@uddeborg.se>,
             Anders Jonsson <anders.jonsson@norsjovallen.se>
2016-10-22 22:21:39 +02:00
losgrandes
dd5c549f6a Fixes #45790: wget prints it's progress even when background
* src/log.c: Use tcgetpgrp(STDIN_FILENO) != getpgrp() to determine when to print to STD* or logfile.
  Deprecate log_request_redirect_output function.
  Use different file handles for STD* and logfile, to easily switch between them when changing fg/bg.
* src/log.h: Make redirect_output function externally linked.
* src/main.c: Don't use deprecated log_request_redirect_output function. Use redirect_output instead.
* src/mswindows.c: Don't use deprecated log_request_redirect_output function. Use redirect_output instead.
2016-10-21 19:33:29 +02:00
losgrandes
78e0ec5f03 Fixes #46584: wget --spider always returns zero exit status
* src/ftp.c: Return error as exit value if even one file doesn't exist
2016-10-21 10:24:28 +02:00
Tim Rühsen
807d1c7d94 * src/http.c (gethttp): Accept 206 for request w/o Range header
Fixes: #49319
2016-10-12 14:59:36 +02:00
Tim Rühsen
3d1d5b317b * tests/Makefile.am: Let WGETRC work on *nix and Windows 2016-10-07 13:27:07 +02:00
Tim Rühsen
517d799b6f Properly include iconv.h
* src/iri.c: Check HAVE_ICONV to include iconv.h
* src/url.c: Same
2016-10-07 13:24:15 +02:00
Tim Rühsen
f79bb20f1b * bootstrap.conf: Add pipe-posix for pipe() 2016-10-07 13:23:27 +02:00
Tim Rühsen
e5164a8260 Amend redirection behavior
* src/recur.c (descend_redirect): Ignore WG_RR_LIST and WG_RR_REGEX
  for redirections.
* testenv/Makefile.am: Add Test-recursive-redirect.py
* testenv/Test-recursive-redirect.py: New test

Test-recursive-redirect.py written by Dale R. Worley.

Reported-by: "Dale R. Worley" <worley@ariadne.com>
2016-10-07 11:49:07 +02:00
Matthew White
a35f3dd4f6 New: Metalink/XML v3 python class, update tests to use this class
* testenv/misc/metalinkv3_xml.py: New Metalink/XML v3 python class
* testenv/Test-metalink-xml-abspath-trust.py: Update test to use the
  new Metalink/XML v3 python class
* testenv/Test-metalink-xml-abspath.py: Update test to use the new
  Metalink/XML v3 python class
* testenv/Test-metalink-xml-absprefix-trust.py: Update test to use the
  new Metalink/XML v3 python class
* testenv/Test-metalink-xml-absprefix.py: Update test to use the new
  Metalink/XML v3 python class
* testenv/Test-metalink-xml-continue.py: Update test to use the new
  Metalink/XML v3 python class
* testenv/Test-metalink-xml-emptyprefix-trust.py: Update test to use
  the new Metalink/XML v3 python class
* testenv/Test-metalink-xml-homepath-trust.py: Update test to use the
  new Metalink/XML v3 python class
* testenv/Test-metalink-xml-homepath.py: Update test to use the new
  Metalink/XML v3 python class
* testenv/Test-metalink-xml-homeprefix-trust.py: Update test to use
  the new Metalink/XML v3 python class
* testenv/Test-metalink-xml-homeprefix.py: Update test to use the new
  Metalink/XML v3 python class
* testenv/Test-metalink-xml-nohash.py: Update test to use the new
  Metalink/XML v3 python class
* testenv/Test-metalink-xml-nourls.py: Update test to use the new
  Metalink/XML v3 python class
* testenv/Test-metalink-xml-prefix-trust.py: Update test to use the
  new Metalink/XML v3 python class
* testenv/Test-metalink-xml-prefix.py: Update test to use the new
  Metalink/XML v3 python class
* testenv/Test-metalink-xml-relpath-trust.py: Update test to use the
  new Metalink/XML v3 python class
* testenv/Test-metalink-xml-relpath.py: Update test to use the new
  Metalink/XML v3 python class
* testenv/Test-metalink-xml-relprefix-trust.py: Update test to use the
  new Metalink/XML v3 python class
* testenv/Test-metalink-xml-relprefix.py: Update test to use the new
  Metalink/XML v3 python class
* testenv/Test-metalink-xml-size.py: Update test to use the new
  Metalink/XML v3 python class
* testenv/Test-metalink-xml-trust.py: Update test to use the new
  Metalink/XML v3 python class
* testenv/Test-metalink-xml.py: Update test to use the new
  Metalink/XML v3 python class
2016-09-30 19:44:06 +02:00
Matthew White
c403e67935 New: --metalink-over-http Content-Type/Disposition Metalink/XML processing
* src/http.c (metalink_from_http): Process the Content-Type header.
  Add an application/metalink4+xml URL as metalink metaurl.  If the
  option opt.content_disposition is true, the Content-Disposition's
  filename is the metaurl's name
* doc/wget.texi: Update --content-disposition and --metalink-over-http
* doc/metalink-standard.txt: Update doc. Content-Type/Disposition
  processing through --metalink-over-http. Update download naming
  system about --trust-server-names and --content-disposition
* testenv/Makefile.am: Add new files
* testenv/Test-metalink-http-xml-type.py: New file. Metalink/HTTP
  Content-Type/Disposition header automated Metalink/XML tests
* testenv/Test-metalink-http-xml-type-trust.py: New file. Metalink/HTTP
  Content-Type/Disposition header with --trust-server-names automated
  Metalink/XML tests
* testenv/Test-metalink-http-xml-type-content.py: New file. Metalink/HTTP
  Content-Type/Disposition header with --content-disposition automated
  Metalink/XML tests
* testenv/Test-metalink-http-xml-type-trust-content.py: New file.
  Metalink/HTTP Content-Type/Disposition header with --trust-server-names
  and --content-disposition automated Metalink/XML tests

Process the Content-Type header, identify an application/metalink4+xml
file.  The Content-Disposition could provide an alternate name through
the "filename" field for the metalink xml file.  Respectively, the cli
options --metalink-over-http and --content-disposition are required.

When Metalink/XML auto-processing, to use the Content-Disposition's
filename, the cli option --trust-server-names is also required.
2016-09-30 19:44:06 +02:00
Matthew White
3021466817 Bugfix: Set NULL variable due to --content-disposition to Metalink origin
* src/http.c (http_loop): Prevent SIGSEGV when hstat.local_file is
  NULL, opt.content_disposition has a role in leaving the value unset
* src/http.c (gethttp): If hs->local_file is NULL (aka http_loop()'s
  hstat.local_file), set it to the value of hs->metalink->origin
2016-09-30 19:44:06 +02:00
Matthew White
c89767d8d1 New: --trust-server-names saves Metalink/HTTP xml files using the "name" field
* src/metalink.c (retrieve_from_metalink): If opt.trustservernames is
  true, use the basename of the metaurl's name to save the xml file
* doc/metalink-standard.txt: Update doc. With --trust-server-names any
  Metalink/HTTP Link application/metalink4+xml file is saved using the
  basename of the "name" field, if any. Update Metalink/HTTP examples
* testenv/Makefile.am: Add new file
* testenv/Test-metalink-http-xml-trust-name.py: New file. Metalink/HTTP
  automated Metalink/XML, save xml files using the "name" field tests
2016-09-30 19:44:06 +02:00
Matthew White
f030cdf8e2 Bugfix: Detect when a metalink:file doesn't have any hash
* src/metalink.c (retrieve_from_metalink): Reject any metalink:file
  without hashes. Prompt the error and switch to the next file
* testenv/Makefile.am: Add new file
* testenv/Test-metalink-xml-nohash.py: New file. Metalink/XML with no
  hashes tests

Prevent SIGSEGV.
2016-09-30 19:44:06 +02:00
Matthew White
5dccb2a9ce Bugfix: Detect malformed base64 Metalink/HTTP Digest header
* src/http.c (metalink_from_http): Fix hash_bin_len type. Use ssize_t
  instead than size_t. Reject -1 as base64_decode() return value
* testenv/Makefile.am: Add new file
* testenv/Test-metalink-http-baddigest.py: New file. Metalink/HTTP
  malformed base64 Digest header tests

On malformed base64 input, ssize_t base64_decode() returns -1. Such
value is too big for a size_t variable, and used as xmalloc() value
will exaust all the memory.
2016-09-30 19:44:06 +02:00
Matthew White
0538e791fb New option --metalink-index to process Metalink application/metalink4+xml
* NEWS: Mention the effect of --metalink-index over Metalink
* src/init.c: Add new option metalinkindex (opt.metalink_index),
  initialize to -1
* src/main.c: Add new option metalink-index (--metalink-index=NUMBER)
* src/options.h: Add new option metalink_index (int)
* src/metalink.h: Add declaration of functions fetch_metalink_file(),
  replace_metalink_basename()
* src/metalink.c: Add functions fetch_metalink_file() simple file
  fetch, replace_metalink_basename() replace file basename
* src/metalink.c (retrieve_from_metalink): New. Process Metalink
  application/metalink4+xml of opt.metalink_index ordinal number
* doc/wget.texi: Add new option metalink-index (--metalink-index)
  documentation
* doc/metalink-standard.txt: Updated doc. Add documentation about
  Metalink application/metalink4+xml metaurls download naming system
* doc/metalink-standard.txt: Update Metalink/XML and HTTP examples
* testenv/Makefile.am: Add new files
* testenv/Test-metalink-http-xml.py: New file. Metalink/HTTP automated
  Metalink/XML "application/metalink4+xml" --metalink-index tests
* testenv/Test-metalink-http-xml-trust.py: New file. Metalink/HTTP
  automated Metalink/XML "application/metalink4+xml" --metalink-index
  retrieval with --trust-server-names tests

WARNING: Do not use lib/dirname.c (dir_name) to get the directory
name, it may append a dot '.' character to the directory name.
2016-09-30 19:44:06 +02:00
Matthew White
acb1d1a668 Bugfix: Prevent sorting when there are less than two elements
* src/utils.c (stable_sort): Add condition nmemb > 1, sort only when
  there is more than one element

Prevent SIGSEGV.
2016-09-30 19:44:06 +02:00
Matthew White
628fb565c7 New: Parse Metalink/HTTP header for application/metalink4+xml
* src/http.c (metalink_from_http): Parse Metalink/HTTP header for
  metaurls application/metalink4+xml media types
* src/metalink.h: Add function declaration metalink_meta_cmp()
* src/metalink.c: Add function metalink_meta_cmp() compare metalink
  metaurls priorities

Add Metalink/HTTP application/metalink4+xml media types as metaurls to
the metalink variable that will be used to download the files.
2016-09-30 19:44:05 +02:00
Matthew White
64ab90ee66 New test: Metalink shall not concatenate '/' to an empty directory prefix
* testenv/Makefile.am: Add new file
* testenv/Test-metalink-xml-emptyprefix-trust.py: New file.
  Metalink/XML empty directory prefix (--directory-prefix '') tests

Detect a '/' character wrongfully concatenated to an empty directory
prefix '' (not NULL), resulting in an absolute path as '/dir/file',
instead than 'dir/file'.
2016-09-30 19:44:05 +02:00
Matthew White
9532861aef Bugfix: Remove surrounding quotes from Metalink/HTTP key's value
* src/metalink.h: Add declaration of function dequote_metalink_string()
* src/metalink.c: Add function dequote_metalink_string() remove
  surrounding quotes from string, \' or \"
* src/metalink.c (find_key_value, find_key_values): Call dequote_metalink_string()
  to remove the surrounding quotes from the parsed value
* src/metalink.c (test_find_key_value, test_find_key_values): Add
  quoted key's values for unit-tests
* testenv/Makefile.am: Add new file
* testenv/Test-metalink-http-quoted.py: New file. Metalink/HTTP quoted
  values tests

Some Metalink/HTTP keys, like "type" [2], may have a quoted value [1]:
Link: <http://example.com/example.ext.meta4>; rel=describedby;
type="application/metalink4+xml"

Wget was expecting a dequoted value from the Metalink module. This
patch addresses this problem.

References:
 [1] Metalink/HTTP: Mirrors and Hashes
     1.1. Example Metalink Server Response
     https://tools.ietf.org/html/rfc6249#section-1.1

 [2] Additional Link Relations
     6. "type"
     https://tools.ietf.org/html/rfc6903#section-6
2016-09-30 19:44:05 +02:00
Matthew White
8aca8fc80d Bugfix: Process Metalink/XML url strings containing white spaces and CRLF
* src/metalink.h: Add declaration of function clean_metalink_string()
* src/metalink.c: Add directive #include "xmemdup0.h"
* src/metalink.c: Add function clean_metalink_string() remove leading
  and trailing white spaces and CRLF from string
* src/metalink.c (retrieve_from_metalink): Remove leading and trailing
  white spaces and CRLF from url resource mres->url
* testenv/Makefile.am: Add new file
* testenv/Test-metalink-xml-urlbreak.py: New test. Metalink/XML white
  spaces and CRLF in url resources tests

White spaces and CRLF are not automatically removed by libmetalink
from url strings. The Wget's Metalink module was unable to process
such url strings. This patch implements the processing of such url
strings cleaning off leading and trailing white spaces and CRLF.

If a parsed Metalink/XML url string contains strings separated by
CRLF, only the first of the series is accepted.
2016-09-30 19:44:05 +02:00
Matthew White
ba82a47173 New test: Detect when there are no good Metalink url resources
* testenv/Makefile.am: Add new file
* testenv/Test-metalink-xml-nourls.py: New file. Metalink/XML unknown
  urls tests

Test if when there are no good Metalink url resources there is any
segmentation fault.
2016-09-30 19:44:05 +02:00
Matthew White
70360b3eab New: Metalink file size mismatch returns error code METALINK_SIZE_ERROR
* src/wget.h (uerr_t): Add error code METALINK_SIZE_ERROR to enum
* src/metalink.c (retrieve_from_metalink): Use boolean variable
  size_ok, when false set retr_err to METALINK_SIZE_ERROR
* testenv/Makefile.am: Add new file
* testenv/Test-metalink-xml-size.py: New file. Metalink/XML file size
  tests (<size></size>)

Before this patch, no appropriate error code was returned to inform a
file size mismatch.

This patch introduces the error code METALINK_SIZE_ERROR to inform a
file size mismatch.
2016-09-30 19:44:05 +02:00
Matthew White
c29983a044 New: Metalink/XML and Metalink/HTTP file naming safety rules
* NEWS: Mention the effect of --trust-server-names over Metalink
* src/metalink.h: Add declaration of function append_suffix_number()
* src/metalink.c: Add function append_suffix_number() append number to
  string
* src/metalink.c (retrieve_from_metalink): Safer Metalink/XML and
  Metalink/HTTP download naming system, opt.trustservernames based
* doc/metalink-standard.txt: Update doc. Explain new Metalink/XML and
  Metalin/HTTP download naming system and --trust-server-names role
* testenv/Makefile.am: Add new files
* testenv/Test-metalink-xml-continue.py: Update test. Metalink/XML
  continue/keep existing files (HTTP 416) with --continue tests
* testenv/Test-metalink-xml.py: Update test. Metalink/XML naming tests
* testenv/Test-metalink-xml-trust.py: New file. Metalink/XML naming
  tests with --trust-server-names
* testenv/Test-metalink-xml-abspath.py: Update test. Metalink/XML
  absolute path tests
* testenv/Test-metalink-xml-abspath-trust.py: New file. Metalink/XML
  absolute path tests with --trust-server-names
* testenv/Test-metalink-xml-relpath.py: Update test. Metalink/XML
  relative path tests
* testenv/Test-metalink-xml-relpath-trust.py: New file. Metalink/XML
  relative path tests with --trust-server-names
* testenv/Test-metalink-xml-homepath.py: Update test. Metalink/XML
  home path and ~ (tilde) tests
* testenv/Test-metalink-xml-homepath-trust.py: New file. Metalink/XML
  home path and ~ (tilde) tests with --trust-server-names
* testenv/Test-metalink-xml-prefix.py: New file. Metalink/XML naming
  tests with --directory-prefix
* testenv/Test-metalink-xml-prefix-trust.py: New file. Metalink/XML
  naming tests with --directory-prefix and --trust-server-names
* testenv/Test-metalink-xml-absprefix.py: New file. Metalink/XML
  absolute --directory-prefix tests
* testenv/Test-metalink-xml-absprefix-trust.py: New file. Metalink/XML
  absolute --directory-prefix tests with --trust-server-names
* testenv/Test-metalink-xml-relprefix.py: New file. Metalink/XML
  relative --directory-prefix tests
* testenv/Test-metalink-xml-relprefix-trust.py: New file. Metalink/XML
  relative --directory-prefix tests with --trust-server-names
* testenv/Test-metalink-xml-homeprefix.py: New file. Metalink/XML home
  --directory-prefix tests
* testenv/Test-metalink-xml-homeprefix-trust.py: New file. Metalink/XML
  home --directory-prefix tests with --trust-server-names

The option --trust-server-names allows to use the file names parsed
from a Metalink/XML file.  Without --trust-server-names, the safety
mechanism provides secure and predictable file names.
2016-09-30 19:44:05 +02:00
Matthew White
5f3ed5eec8 New document: Metalink/XML and Metalink/HTTP standard reference
* doc/metalink-standard.txt: New doc. Implemented and recommended
  Metalink/XML and Metalink/HTTP standard features
2016-09-30 19:44:05 +02:00
Matthew White
43ec7008f2 Enforce Metalink file name verification, strip directory if necessary
* NEWS: Mention the use of a safe Metalink destination path
* src/metalink.h: Add declaration of functions get_metalink_basename(),
  last_component(), metalink_check_safe_path()
* src/metalink.c: Add directive #include "dosname.h"
* src/metalink.c: Add function get_metalink_basename() to return the
  basename of a file name, strip w32's drive letter prefixes
* src/metalink.c (retrieve_from_metalink): Enforce Metalink file name
  verification, if the file name is unsafe try its basename
* doc/metalink.txt: Update document. Explain --directory-prefix

The function get_metalink_basename() uses FILE_SYSTEM_PREFIX_LEN to
catch any 'C:D:file' (w32 environment), then it removes each drive
letter prefix, i.e. 'C:' and 'D:'.

Unsafe file names contain an absolute, relative, or home path.  Safe
paths can be verified by libmetalink's metalink_check_safe_path().
2016-09-30 19:44:03 +02:00
Matthew White
7d4942864b Implement Metalink/XML --directory-prefix option in Metalink module
* NEWS: Mention the effect of --directory-prefix over Metalink
* src/metalink.c (retrieve_from_metalink): Add opt.dir_prefix as
  prefix to the metalink:file name mfile->name
* doc/metalink.txt: Update document. Explain --directory-prefix

When --directory-prefix=<prefix> is used, set the top of the retrieval
tree to prefix. The default is . (the current directory). Metalink/XML
and Metalink/HTTP files will be downloaded under prefix.
2016-09-27 20:29:03 +02:00
Matthew White
666b7862bf Change mfile->name to filename in Metalink module's messages
* src/metalink.c (retrieve_from_metalink): Change mfile->name to
  filename when referring to the downloaded file

The file name could have been changed by unique_create() (or by any
other mean) before downloading. Use the name of the downloaded file
(filename) when printing output which refer to it.
2016-09-27 20:29:03 +02:00
Matthew White
f3f349a0cf Add file size computation in Metalink module
* NEWS: Mention Metalink's file size verification
* src/metalink.c (retrieve_from_metalink): Add file size computation
* doc/metalink.txt: Update document. Remove resolved bugs

Reject downloaded files when they do not agree with their Metalink/XML
metalink:size: https://tools.ietf.org/html/rfc5854#section-4.2.14

At the moment of writing, Metalink/HTTP headers do not provide a file
size field. This information could be obtained from the Content-Length
header field: https://tools.ietf.org/html/rfc6249#section-7
2016-09-27 20:29:03 +02:00
Matthew White
6b1860da37 Update Metalink/XML tests and add a new test for home paths
* testenv/Test-metalink-xml-relpath.py: Update test
* testenv/Test-metalink-xml-homepath.py: New file. Reject home paths
* testenv/Makefile.am: Add new file

When --input-metalink=<file> is used, each metalink:file name is
verified by libmetalink's metalink_check_safe_path(). By design,
absolute, relative and home paths are rejected.

At the moment of writing, when --metalink-over-http is used, absolute,
relative, and home paths aren't a concern. The destination file name
is a combination of URL's file name and cli's "Directory Options"
handled by src/url.c (url_file_name).
2016-09-27 20:29:03 +02:00
Matthew White
ff444ebc2a Bugfix: Keep the download progress when alternating metalink:url
* NEWS: Mention the effects of --continue over Metalink
* src/metalink.c (retrieve_from_metalink): On download error, resume
  output_stream with the next mres->url. Keep fully downloaded files
  started with --continue, otherwise rename/remove the file
* testenv/Makefile.am: Add new file
* testenv/Test-metalink-xml-continue.py: New file. Metalink/XML
  continue/keep existing files (HTTP 416) with --continue tests

Before this patch, with --continue, existing and/or fully retrieved
files which fail the sanity tests were renamed (--keep-badhash), or
removed.

This patch ensures that --continue doesn't rename/remove existing
and/or fully retrieved files (HTTP 416) which fail the sanity tests.
2016-09-27 20:28:50 +02:00
Matthew White
96554861f9 Bugfix: Fix NULL filename and output_stream in Metalink module
* NEWS: Mention the Metalink "path/file" name format handling
* src/metalink.c (retrieve_from_metalink): Fix NULL filename, set
  filename to the right "path/file" value
* src/metalink.c (retrieve_from_metalink): Fix NULL output_stream, set
  output_stream to filename when it is created by retrieve_url()
* src/metalink.c (retrieve_from_metalink): Add RFC5854 comments about
  proper metalink:file "path/file" name format handling
* doc/metalink.txt: Update document. Remove resolved bugs

If unique_create() cannot create/open the destination file, filename
and output_stream remain NULL. If fopen() is used instead, filename
always remains NULL. Both functions cannot create "path/file" trees.

Setting filename to the right value is sufficient to prevent SIGSEGV
generating from testing a NULL value. This also allows retrieve_url()
to create a "path/file" tree through opt.output_document.

Reading NULL as output_stream, when it shall not be, leads to wrong
results. For instance, a non-NULL output_stream tells when a stream
was interrupted, reading NULL instead means to assume the contrary.

This patch conforms to the RFC5854 specification:
  The Metalink Download Description Format
  4.1.2.1.  The "name" Attribute
  https://tools.ietf.org/html/rfc5854#section-4.1.2.1
2016-09-27 20:17:08 +02:00
Matthew White
bcb9bf7ae4 Add metalink description
* doc/metalink.txt

Evaluation of "Directory Options" on the command line interacting with
the option '--input-metalink=file':

$ wget --input-metalink=file <directory options>
2016-09-19 05:56:40 +02:00
Matthew White
ea038006d1 Use python .replace instead than re.sub in Metalink tests
* testenv/Test-metalink-http.py: Use python .replace
* testenv/Test-metalink-xml.py: Use python .replace
* testenv/Test-metalink-xml-abspath.py: Use python .replace
* testenv/Test-metalink-xml-relpath.py: Use python .replace

Use python .replace instead than re.sub, remove 'import re'.
2016-09-19 05:56:40 +02:00
Matthew White
77e2c54991 Fix: Change Metalink/XML v3 file name into test.metalink
* testenv/Test-metalink-xml-abspath.py: Change Metalink/XML v3 file
  name from test.meta4 into test.metalink
* testenv/Test-metalink-xml-relpath.py: Change Metalink/XML v3 file
  name from test.meta4 into test.metalink
* testenv/Test-metalink-xml.py: Change Metalink/XML v3 file name from
  test.meta4 into test.metalink
2016-09-19 05:55:04 +02:00
Tim Rühsen
7ffbccec4c Add two Metalink/XML tests
* testenv/Test-metalink-xml-abspath.py: Reject absolute paths
* testenv/Test-metalink-xml-relpath.py: Reject relative paths
* testenv/Makefile.am: Add both new files to metalink tests
2016-09-13 11:45:02 +02:00
Tim Rühsen
a2c4849900 Fix crash on 'srcset' inline URIs
* src/html-url.c (tag_handle_img): Check append_url() for NULL
  return value before dereference.

Crashed reproducable with parsing srcset="data:..." inline data.
Reported-by: Coverity
2016-09-09 11:44:02 +02:00
Tim Rühsen
40870e1271 * src/hsts.c (hsts_store_open): NULL check param for fclose().
Reported-by: Coverity
2016-09-09 10:22:58 +02:00
Tim Rühsen
15c1e0eb7b * src/ftp-ls.c (ftp_parse_winnt_ls): Fix memset params 2016-09-09 10:22:58 +02:00
Tim Rühsen
eba724a128 * src/utils.c (stable_sort): Use xmalloc instead of malloc 2016-09-09 10:22:58 +02:00
Tim Rühsen
66a9883c8f * src/ftp-ls.c (ftp_parse_winnt_ls): Initialize struct fileinfo cur
Reported-by: Coverity
2016-09-08 16:51:15 +02:00
Tim Rühsen
4febe72bd2 Add const to url param of some functions
* src/http.c: Add const to first param of initialize_request(),
  initialize_proxy_configuration(), establish_connection(),
  check_file_output(), check_auth(), gethttp(), http_loop().
* src/http.h: Add const to first param of http_loop().
2016-09-08 16:13:54 +02:00
Tim Rühsen
c629ec7fd1 * Makefile.am: Remove trailing empty line 2016-09-08 14:20:33 +02:00
Tim Rühsen
03da900c5b * src/recur.c (retrieve_tree): Fix possible NULL dereference
Reported-by: Coverity
2016-09-08 13:04:37 +02:00
Tim Rühsen
b7b67e23cd * src/http.c (initialize_request): Fix check for user
Reported-by: Coverity
2016-09-08 12:48:32 +02:00
Tim Rühsen
22aed3ed4b * src/retr.c (retrieve_url): NULL check mynewloc
Reported-by: Coverity
2016-09-08 12:46:25 +02:00
Tim Rühsen
b4465afa8a * src/utils.c (stable_sort): Reduce tmp allocation size
Reported-by: Coverity
2016-09-08 12:44:17 +02:00
Tim Rühsen
a232835fd1 * Makefile.am: Add target 'check-valgrind' 2016-09-08 11:20:25 +02:00
Tim Rühsen
a78b83b1e9 Fix some issues detected by Coverity
* src/connect.c (connect_to_ip): Check return value of setsockopt.
* src/ftp.c (ftp_retrieve_list): Check return value of chmod.
* src/http.c (digest_authentication_encode): Cleanup code.
* src/init.c (setval_internal): Explicitely check comind range.
* src/main.c (main): Explicitely check optarg.
* src/retr.c (retr_rate): Use snprintf instead sprintf,
  (retrieve_from_file): More verbose error message,
  (rotate_backups): Use snprintf instead sprintf, check return
  value of rename().
* src/url.c (mkalldirs): Check return value of unlink().
* src/utils.c (strdupdelim): Explicitely check beg and end for NULL,
  (merge_vecs): Fix sizeof argument to char *,
  (stable_sort): Use malloc instead of alloca.
2016-09-08 10:12:02 +02:00
Tim Rühsen
37a5257c66 Code cleanup for --use-askpass
* bootstrap.conf: Add xmemdup0 and strpbrk.
* src/init.c (cmd_use_askpass): Add 'const' to char *,
  remove check for file existence.
* src/main.c (run_use_askpass): C89 compat init of argv,
  added \n to error messages,
  fixed stripping of \n and \r from input,
  make run_use_askpass and use_askpass static.
2016-09-08 09:07:32 +02:00
Tim Rühsen
49af22ca94 * src/http.c (check_file_output): Replace asprintf by aprint 2016-09-07 09:31:43 +02:00
Tim Rühsen
d505714a32 * testenv/README: Remove obsolete references to TEST_NAME 2016-09-04 14:56:06 +02:00
Liam R. Howlett
21e1725e12 Add --use-askpass=COMMAND support
* doc/wget.texi: Add --use-askpass to documentation.
* src/init.c: Add cmd_use_askpasss to set opt.use_askpass based on
argument, WGET_ASKPASS, and SSH_ASKPASS environment variables.
opt.wget-askpass is freed in cleanup ()
* src/main.c: Update options & add spawn process of opt.use_askpass
command.
* src/options.h: Addition of string use_askpass.
* src/url.c: Function scheme_leading_string to access the leading
string of a parsed url.
* src/url.h: Prototype for scheme_leading_string for returning the
leading string.
* bootstrap.conf: Add posix_spawn to gnulib_modules

This adds the --use-askpass option which is disabled by default.

--use-askpass=COMMAND will request the username and password for a given
URL by executing the external program COMMAND.  If COMMAND is left
blank, then the external program in the environment variable
WGET_ASKPASS will be used.  If WGET_ASKPASS is not set then the
environment variable SSH_ASKPASS is used.  If there is no value set, an
error is returned.  If an error occurs requesting the username or
password, wget will exit.

Signed-off-by: Liam R. Howlett <Liam.Howlett@WindRiver.com>
2016-09-03 21:01:24 +02:00
Dale R. Worley
796e30dcea Add tests for recursion and redirection.
* testenv/Test-recursive-basic.py: New file. Test basic recursion
    * testenv/Test-recursive-include.py: New File. Recursion test with
    include directories
    * testenv/Test-redirect.py: New File. Basic redirection tests
    * testenv/Makefile.am: Add new tests to makefile
2016-09-02 17:46:36 +02:00
Dale R. Worley
b919f988f2 Sort test names into order.
* testenv/Makefile.am: Sort all the python tests in alphabetical
    order
2016-09-02 17:45:19 +02:00
Dale R. Worley
ca1ee7d32f Corrections and amplifications to test documentation
* testenv/README: Update documentation to meet current project
    status
    * testenv/Test-Proto.py: Same
2016-09-02 17:44:10 +02:00
Giuseppe Scrivano
690c47e3b1 Append .tmp to temporary files
* src/http.c (struct http_stat): Add `temporary` flag.
(check_file_output): Append .tmp to temporary files.
(open_output_stream): Refactor condition to use hs->temporary instead.

Reported-by: "Misra, Deapesh" <dmisra@verisign.com>
Discovered by: Dawid Golunski (http://legalhackers.com)
2016-08-24 12:29:01 +02:00
Tim Rühsen
9ffb64ba6a Limit file mode to u=rw on temp. downloaded files
* bootstrap.conf: Add gnulib modules fopen, open.
* src/http.c (open_output_stream): Limit file mode to u=rw
on temporary downloaded files.

Reported-by: "Misra, Deapesh" <dmisra@verisign.com>
Discovered by: Dawid Golunski (http://legalhackers.com)
2016-08-24 12:28:55 +02:00
Giuseppe Scrivano
6698260f15 Fix some make syntax-check issues
cfg.mk: Skip .der files.
testenv/certs/server-template.cfg: Remove empty final line.
testenv/certs/ca-template.cfg: Likewise.
2016-08-21 15:35:36 +02:00
Tim Rühsen
0787d7253e * src/css-url.c (get_urls_css): Fix memory leak 2016-08-17 23:13:27 +02:00
Tim Rühsen
964f4646da * src/html-url.c (get_urls_html): Fix memory leak 2016-08-17 23:12:25 +02:00
Tim Rühsen
262baeb113 Improve PSL cookie checking
* configure.ac: Add --with-psl-file to set a PSL file
* src/cookies.c (check_domain_match): Load PSL_FILE with
  fallback to built-in data.

This change allows package maintainers to make Wget use the latest
PSL (DAFSA or plain text), without updating libpsl itself.

E.g. Debian now comes with a DAFSA binary within the 'publicsuffix'
package which allows very fast loading (no parsing or processing needed).
2016-08-17 16:32:26 +02:00
Tobias Stoeckmann
f4aeb41899 Fix stack overflow with way too many cookies
* src/cookies.c (cookie_header): Use heap instead of stack.
* src/http.c (request_send): Likewise.

If wget has to handle an insanely large amount of cookies (~700,000 on
32 bit systems or ~530,000 on 64 bit systems), the stack is not large
enough to hold these pointers, leading to undefined behaviour according
to POSIX; expect a segmentation fault in real life. ;)

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2016-08-10 19:59:25 +02:00
Tobias Stoeckmann
a9d49e5b15 Fix signal race condition
The signal handler for SIGALRM calls longjmp, but the handler is
installed before the jump target has been initialized. If another
process sends SIGALRM right between handler installation and target
initialization, the jump leads to undefined behavior.

This can easily be fixed by moving the signal handler installation
into the "SETJMP == 0" conditional block, which means that the target
has just been initialized.

* src/utils.c: call signal after SETJMP.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2016-08-09 17:38:29 +02:00
Jeffery To
0fe79eeacb Remove hyphens from command names
* src/init.c: Remove hyphens from command names
* src/main.c: Likewise

Options with hyphens (or underscores) in their command name cannot be
set in a wgetrc file.

Signed-off-by: Jeffery To <jeffery.to@gmail.com>
2016-08-05 09:45:09 +02:00
Tim Rühsen
e3fb4c3859 * src/metalink.c (badhash_suffix): Fix quoting 2016-08-04 13:09:28 +02:00
Matthew White
943a6d585f Add new option --keep-badhash to keep Metalink's files with a bad hash
* src/init.c: Add keepbadhash
* src/main.c: Add keep-badhash
* src/options.h: Add keep_badhash
* doc/wget.texi: Add docs for --keep-badhash
* src/metalink.h: Add prototypes badhash_suffix(), badhash_or_remove()
* src/metalink.c: New functions badhash_suffix(), badhash_or_remove().
  (retrieve_from_metalink): Call badhash_or_remove() on download error

With --keep-badhash, append .badhash to Metalink's files with checksum
mismatch. (retrieve_from_metalink): unique_create() may append another
suffix to avoid overwriting existing files.

Without --keep-badhash, remove downloaded files with checksum mismatch
(this conforms to the old behaviour).
2016-08-04 12:03:49 +02:00
Tim Rühsen
7fad76db4c * src/metalink.c: Remove C++ style comments 2016-08-03 13:48:07 +02:00
Matthew White
3e7e29f358 Add gnulib modules 'link', 'unlink' and 'symlink'
* bootstrap.conf: Add 'link', 'unlink' and 'symlink'
2016-08-03 13:44:34 +02:00
Matthew White
e0b60fd073 New: --continue continues partially downloaded Metalink's files
* src/metalink.c (retrieve_from_metalink): Continue file download if
  opt.always_rest is true

Without --continue, download as a new file with an unique name (this
conforms to the old behaviour).
2016-08-03 13:37:27 +02:00
Matthew White
9db02a0c46 Add support for Metalink's md2, and md4 hashes
* bootstrap.conf: Add crypto/md2, and crypto/md4
* src/metalink.c (retrieve_from_metalink): Add md2, and md4 support

This patch adds support for the deprecated (insecure) md2, and md4
Message-Digest algorithms to the Metalink module.
2016-08-03 12:58:43 +02:00
Matthew White
edad3c1df3 Add support for Metalink's md5, sha1, sha224, sha384, and sha512 hashes
* bootstrap.conf: Add crypto/sha512
* src/metalink.c (retrieve_from_metalink): Add md5, sha1, sha224,
  sha384, and sha512 support

Metalink's checksum verification was limited to sha256. This patch
adds support for md5, sha1, sha224, sha384, and sha512.
2016-08-03 12:49:26 +02:00
Sean Burford
20cac2c5ab Style fixes and DEBUG on setxattr failure.
* src/ftp.c: Fix style.
* src/http.c: Likewise.
* src/xattr.h: Likewise.
* src/xattr.c: Likewise,
  (write_xattr_metadata): Print debug msg on error.
2016-07-27 17:05:57 +02:00
Sean Burford
a933bdd31e Keep fetched URLs in POSIX extended attributes
* configure.ac: Check for xattr availability
* src/Makefile.am: Add xattr.c
* src/ftp.c: Include xattr.h.
  (getftp): Set attributes if enabled.
* src/http.c: Include xattr.h.
  (gethttp): Add parameter 'original_url',
  set attributes if enabled.
  (http_loop): Add 'original_url' to call of gethttp().
* src/init.c: Add new option --xattr.
* src/main.c: Add new option --xattr, add description to help text.
* src/options.h: Add new config member 'enable_xattr'.
* src/xatrr.c: New file.
* src/xattr.h: New file.

These attributes provide a lightweight method of later determining
where a file was downloaded from.

This patch changes:
*   autoconf detects whether extended attributes are available and
    enables the code if they are.
*   The new flags --xattr and --no-xattr control whether xattr is enabled.
*   The new command "xattr = (on|off)" can be used in ~/.wgetrc or /etc/wgetrc
*   The original and redirected URLs are recorded as shown below.
*   This works for both single fetches and recursive mode.

The attributes that are set are:
user.xdg.origin.url: The URL that the content was fetched from.
user.xdg.referrer.url: The URL that was originally requested.

Here is an example, where http://archive.org redirects to https://archive.org:
$ wget --xattr http://archive.org
...
$ getfattr -d index.html
user.xdg.origin.url="https://archive.org/"
user.xdg.referrer.url="http://archive.org/"

These attributes were chosen based on those stored by Google Chrome
https://bugs.chromium.org/p/chromium/issues/detail?id=45903
and curl https://github.com/curl/curl/blob/master/src/tool_xattr.c
2016-07-22 13:42:23 +02:00
Noël Köthe
ef372a4f27 Fix typos
* ChangeLog-2014-12-10: invokation -> invocation
* doc/wget.texi: invokation -> invocation
* src/main.c: seperated -> separated
* src/options.h: seperated -> separated
* testenv/README: invokation -> invocation
* testenv/conf/wget_commands.py: invokation -> invocation
2016-07-02 19:01:24 +02:00
Tim Rühsen
0b151f51eb Fix creating docs when make uses 'sh -e'
* doc/Makefile.am: Save fallback for pod2man --utf8

Reported-by: Jérémie Courrèges-Anglas <jca@wxcvbn.org>
2016-06-30 15:19:26 +02:00
Tim Rühsen
309e72c74f Fix compilation for OpenSSL 1.1.0
* src/openssl.c (ssl_init): Use SSL_is_init_finished() instead of
  SSL_state(), conditionally skip SSLeay function calls

The python test suite makes SSL_peek() hang, consuming 100% CPU time.
This does not happen on real world TLS connections, though, but needs
investigations.
2016-06-30 13:24:33 +02:00
Tim Rühsen
2318c309d4 Add script to generate test certs non-interactive
* Test-pinnedpubkey-hash-https.py: Read hashed pubkey from file
* Test-pinnedpubkey-hash-no-check-fail-https.py: Use invalid hash
* certs/make_ca.sh: New script to generate test certs non-interactive
* certs/ca-template.cfg: New file (template for CA cert)
* certs/server-template.cfg: New file (template for server cert)
* certs/server-pubkey-sha256.base64: New file (pubkey sha256 hash)
2016-06-29 12:54:06 +02:00
Ander Juaristi
cdc3e28d8e Bypass world-writable checks on Windows
* src/hsts.c (hsts_file_access_valid): we should check for "world-writable"
   files only on Unix-based systems. It's difficult to mimic the same behavior
   on Windows, so it's better to just not do it.

Reported-by: Gisle Vanem <gvanem@yahoo.no>
Reported-by: Eli Zaretskii <eliz@gnu.org>
2016-06-27 09:54:32 +02:00
Tim Rühsen
43359f47c4 Update gnulib and bootstrap
* gnulib: Sync gnulib submodule with upstream
* bootstrap: Update to latest version from gnulib/build-aux/
2016-06-14 09:27:58 +02:00
Tim Rühsen
e1e7afb210 Use ICONV_CONST to avoid type warning for iconv()
* src/iri.c (do_conversion): Cast 2. param of iconv() to
 'ICONV_CONST char **'
* src/url.c (convert_fname): Likewise
2016-06-12 21:51:34 +02:00
Tim Rühsen
7e585fe23d Remove check for HAVE_ICONV in src/url.c
* src/url.c: Remove check for HAVE_ICONV
2016-06-12 21:49:23 +02:00
Tim Rühsen
526e98f7c4 Add gnulib module 'langinfo'
* bootstrap.conf: Add 'langinfo'
2016-06-12 20:55:03 +02:00
Tim Rühsen
d75f43f083 Include gnulib fcntl.h instead of sys/fcntl.h
* src/gnutls.c: Include gnulib fcntl.h
2016-06-12 17:06:31 +02:00
Tim Rühsen
d4f97dc9af Add libraries to LDADD for wget
* src/Makefile.am: Add $(GETADDRINFO_LIB) $(HOSTENT_LIB) $(INET_NTOP_LIB)
 $(LIBSOCKET) $(LIB_CLOCK_GETTIME) $(LIB_CRYPTO) $(LIB_SELECT)
 $(LTLIBICONV) $(LTLIBINTL) $(LTLIBTHREAD) $(SERVENT_LIB) to LDADD
2016-06-12 17:02:12 +02:00
Tim Rühsen
ade62eb400 Explicitely mention Python3 in README.checkout
* README.checkout: Python test suite needs Python3
2016-06-10 15:14:43 +02:00
Giuseppe Scrivano
bd7f36705b NEWS: update 2016-06-09 17:31:57 +02:00
Giuseppe Scrivano
e996e322ff ftp: understand --trust-server-names on a HTTP->FTP redirect
If not --trust-server-names is used, FTP will also get the destination
file name from the original url specified by the user instead of the
redirected url.  Closes CVE-2016-4971.

* src/ftp.c (ftp_get_listing): Add argument original_url.
(getftp): Likewise.
(ftp_loop_internal): Likewise.  Use original_url to generate the
file name if --trust-server-names is not provided.
(ftp_retrieve_glob): Likewise.
(ftp_loop): Likewise.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2016-06-09 15:02:49 +02:00
Tim Rühsen
2bdfc4f521 Fix warnings for --disable-iri configure flag
* src/iri.h: Fix #define for parse_charset
* src/html-url.c: Surround some IRI code parts by #ifdef ENABLE_IRI
* src/http.c: Likewise
* src/iri.h: Likewise
* src/recur.c: Likewise
* src/retr.c: Likewise
2016-06-07 12:52:59 +02:00
Tim Rühsen
2c736abb4c Fix warning about redefinition of MAP_FAILED
* src/sysdep.h: Removed definition of MAP_FAILED
* src/utils.c: Check and define MAP_FAILED after including sys/mmap.h
2016-06-07 09:56:01 +02:00
Tim Rühsen
7c0752c4cb Add new Test for missing scheme behavior
* testenv/Makefile.am: Add Test-missing-scheme-retval.py
* testenv: New file Test-missing-scheme-retval.py

Idea and Perl implementation by Zdenek Dohnal <zdohnal@redhat.com>
2016-06-03 10:16:40 +02:00
Tim Rühsen
302aa79abb Fallback to pod2man without utf-8 on error
* doc/Makefile.am: Fallback to pod2man without utf-8 on error
2016-05-27 16:44:50 +02:00
Ander Juaristi
5224d752a5 Correct HSTS debug message
* src/main.c (save_hsts): save the in-memory HSTS database to a file
   only if something changed.
 * src/hsts.c (struct hsts_store): new field 'changed'.
   (hsts_match): update field 'changed' accordingly.
   (hsts_store_entry): update field 'changed' accordingly.
   (hsts_store_has_changed): new function.
 * src/hsts.h (hsts_store_has_changed): new function.
2016-05-26 16:37:51 +02:00
Ander Juaristi
2aaf12990c Check the HSTS file is not world-writable
* hsts.c (hsts_file_access_valid): check that the file is a regular
   file, and that it's not world-writable.
   (hsts_store_open): if the HSTS database file does not meet the
   above requirements, disable HSTS at all.
2016-05-26 16:29:29 +02:00
Tim Rühsen
2e6f629061 Improve description of Perl libraries needed for test suite
* README.checkout: Improve text about Perl libraries
2016-05-24 09:38:15 +02:00
Tim Rühsen
a952f81f3e Remove special handling for Emacs in progress bar code
* src/progress.c: Remove special 'emacs' code

Fixes #47989
2016-05-23 21:46:29 +02:00
Jernej Simončič
42cc84b6b6 Fix xsleep() for Windows (trivial change)
* src/mswindows.c (xsleep): Fix check for number of seconds
2016-04-25 15:50:23 +02:00
Sergio Gelato
96ab9cad88 More accurate log message from do_conversion()
* src/iri.c (do_conversion): More accurate log message
2016-04-17 15:28:48 +02:00
Tim Rühsen
268163444d Include sys/select.h if HAVE_LIBCARES
* src/hosts.c: Include sys/select.h if HAVE_LIBCARES

Reported-by: Gisle Vanem <gvanem@yahoo.no>
2016-04-17 14:18:55 +02:00
Gisle Vanem
53800415a9 Fix Windows gnulib/c-ares incompatibility of select()
* src/host.c: Undef 'select' on Windows
2016-04-17 14:15:51 +02:00
Tim Rühsen
528770ca8b Set X flags for python tests
* testenv/*.py: Set eXecute flags

Regression from commit 926e42d467
2016-04-15 21:36:51 +02:00
Ander Juaristi
2f1c6a05c8 Strictly comply with RFC 6797
* src/hsts.c (hsts_store_entry): strictly comply with RFC 6797.

RFC 6797 states in section 8.1 that the UA's cached information should
only be updated if:

    "either or both of the max-age and includeSubDomains header field
    value tokens are conveying information different than that already
    maintained by the UA."
2016-04-11 16:44:47 +02:00
Ander Juaristi
33d860e1ef Correct HSTS database file description
* src/hsts.c (hsts_store_dump): s/[:port]/<port>/
2016-04-11 16:44:41 +02:00
moparisthebest
99fc712f21 Implement tests for new pinnedpubkey option
* testenv/Makefile.am: Add new tests
* testenv/Test-pinnedpubkey-der-https.py: New test
* testenv/Test-pinnedpubkey-der-no-check-https.py: New Test
* testenv/Test-pinnedpubkey-hash-https.py: New test
* testenv/Test-pinnedpubkey-hash-no-check-fail-https.py: New test
* testenv/Test-pinnedpubkey-pem-fail-https.py: New test
* testenv/Test-pinnedpubkey-pem-https.py: New test
* testenv/certs/README: How to generate public keys with openssl tool
* testenv/certs/server-pubkey.der: New key file (DER format)
* testenv/certs/server-pubkey.pem: New key file (PEM format)
2016-04-11 16:25:09 +02:00
moparisthebest
54746578e9 Implement --pinnedpubkey option to pin public keys
* doc/wget.texi: Add description for --pinnedpubkey
* src/gnutls.c: New function pkp_pin_peer_pubkey(),
  (ssl_check_certificate): Check pinned cert via pkp_pin_peer_pubkey()
* src/init.c: Add option --pinnedpubkey
* src/main.c: Add option --pinnedpubkey
* src/openssl.c: New function pkp_pin_peer_pubkey(),
  (ssl_check_certificate): Check pinned cert via pkp_pin_peer_pubkey()
* src/options.h: Add new option variable 'pinnedpubkey'
* src/utils.c: New functions wg_pubkey_pem_to_der(), wg_pin_peer_pubkey()
* src/utils.h: Add prototype for wg_pin_peer_pubkey()
2016-04-11 16:18:05 +02:00
Tim Rühsen
926e42d467 Use test file name for temp working directory name
* testenv/test/base_test.py (__init__): Use test file name for name,
  remove 'name' parameter
* testenv/test/http_test.py (__init__): Remove 'name' parameter
* testenv/*.py: Remove TEST_NAME

Using a fixed string (TEST_NAME) to build the working directory
for testing caused random failures (or successes) when tests
share the same TEST_NAME value. Not easy to find without digging
into the python test suite code.
We now use the test file name, which is unique within the test
environment.
2016-04-11 15:35:05 +02:00
Tim Rühsen
d286d5408b Fix testenv/Test--rejected-log.py
* testenv/Test--rejected-log.py: Add missing tabs in expected output
2016-04-11 15:24:04 +02:00
Tim Rühsen
9883f9fb10 Fail python tests when post_hook errors
* testenv/test/base_test.py (__exit__): Return self.tests_passed
  (__test_cleanup): Set self.tests_passed to False on exception
2016-04-11 15:23:38 +02:00
Darshit Shah
d26377053d Print the fingerprint instead of the raw pointer in debugging message
* src/metalink.c (retrieve_from_metalink): Fix debug message to print the
fingerprint instead of a pointer.

* Do not delete the ChangeLog file since it is required by the Makefile
and breaks compilation
2016-03-29 15:09:04 +02:00
Darshit Shah
722675553c Revert "Print the fingerprint instead of the raw pointer in debugging message"
This reverts commit b916595168.
2016-03-29 15:07:29 +02:00
Tim Rühsen
281ad7dfb9 Fixed URLs and references in wget.texi
* wget.texi: Replace server.com by example.com,
  replace ftp://wuarchive.wustl.edu by https://example.com,
  use HTTPS instead of HTTP where possible,
  fix list archive reference,
  remove reference to wget-notify@addictivecode.org,
  change bugtracker URL to bugtracker on Savannah,
  replace yoyodyne.com by example.com,
  fix URL to VMS port
2016-03-28 18:33:33 +02:00
Giuseppe Scrivano
f3e63f0071 * metalink.c (retrieve_from_metalink): Fix typo 2016-03-25 16:46:39 +01:00
Giuseppe Scrivano
b916595168 Print the fingerprint instead of the raw pointer in debugging message
* src/metalink.c (retrieve_from_metalink): Fix debug message to print the
fingerprint instead of a pointer.
2016-03-25 16:23:19 +01:00
Tim Rühsen
76ef65b23c Add options --bind-dns-address and --dns-servers
* README.checkout: Add description for libares
* configure.ac: Add check for libares
* doc/wget.texi: Add docs for the new options
* src/build_info.c.in: Add +/-cares for --version output
* src/host.c:
  (merge_address_lists): New static function
  (address_list_from_hostent): New static function
  (wait_ares): New static function
  (callback): New static function
  (lookup_host): Add libares resolver code
* src/init.c: Add new options,
  (cleanup): Add cleanup code
* src/main.c: Add global libares channel variable
  (cmdline_option option_data): Add new options
  (print_help): Add short descriptions
  (main): Add libares init code
* src/options.h (struct options): Add option members

The new options allow to specify alternative DNS servers and
an alternate packet route for the resolver packets.
Wget has to built with libares, enabled at configure time by
./configure --with-cares.
2016-03-23 09:26:22 +01:00
Tim Rühsen
d7726f8a13 Fix SNI server names with trailing dot(s)
* src/gnutls.c (ssl_connect_wget, ssl_check_certificate): Fix SNI server name
* src/openssl.c (ssl_connect_wget, ssl_check_certificate): Fix SNI server name

Fixes #47408
2016-03-16 11:23:51 +01:00
Tim Rühsen
598445ebd1 Fix links to original Robots Exclusion Standard
* doc/wget.texi: Fix links
2016-03-10 16:20:05 +01:00
Darshit Shah
7cb9efa668 Fix assertion in Progress bar
* src/progress.c (create_image): Fix off-by-one error in assert()
    statement for progress bar width.
    Reported-By: Gisle Vanem <gvanem@yahoo.no>
2016-03-05 13:27:46 +01:00
Giuseppe Scrivano
44aedd8321 src/url.c: fix make syntax-check 2016-03-03 09:40:39 +01:00
Maks Orlovich
c28f51aadf Parse <img srcset> attributes, they have image URLs.
* src/convert.h: Add link_noquote_html_p to permit rewriting URLs deep
                 inside attributes without adding extraneous quoting
* src/convert.c (convert_links): Honor link_noquote_html_p
* src/html_url.c (tag_handle_img): New function. Add srcset parsing.
2016-03-03 09:38:45 +01:00
Darshit Shah
7099f48998 Sanitize value sent to memset to prevent SEGFAULT 2016-03-01 08:11:13 +01:00
Darshit Shah
75e5be7aad Update documentation about bahviour of -c
* docs/wget.texi: -c will restart download from scratch if server
    does not support RANGE.

    Reported-By: David Chavez
    http://stackoverflow.com/questions/30147332/unexpected-behavior-of-wget
2016-03-01 08:10:59 +01:00
Tim Rühsen
100da11312 Fix writing WARC-Target-URI value
src/warc.c: Add function warc_write_header_uri(),
            Use it for creating WARC-Target-URI

Fixes #47281
2016-02-27 23:08:28 +01:00
Darshit Shah
cceb5932b4 Remove pointer to unused Mailing List
* MAILING-LISTS: Remove pointer to old, unused mailing list for bug
    reports
2016-02-13 01:39:03 +01:00
Tim Rühsen
cacac6f996 Retain value of errno in logprintf(), logputs() even better
* src/log.c (logprintf,logputs): Save&Restore value of errno

Reported-by: Gisle Vanem <gvanem@yahoo.no>
2016-02-11 10:53:02 +01:00
Tim Rühsen
3056617e9c Retain value of errno in logprintf()
* src/log.c (logprintf): Save&Restore value of errno

Reported-by: Gisle Vanem <gvanem@yahoo.no>
2016-02-10 15:28:10 +01:00
Tim Rühsen
c190677cab Set AM_SILENT_RULES to yes by default
* configure.ac: Set AM_SILENT_RULES to yes by default
2016-02-01 21:10:33 +01:00
Ander Juaristi
4c2dc5010f Enforce 'RejectHeader' rule in tests
* server/http/http_server.py (_Handler.RejectHeader): enforce
   'RejectHeader' rule.
2016-02-01 20:48:00 +01:00
Tim Rühsen
b30500f0f4 Fix Test-iri-forced-remote
* tests/Test-iri-forced-remote.px: Fix encodings
2015-12-20 21:32:06 +01:00
Eli Zaretskii
59b920874d Support non-ASCII URLs
* src/url.c [HAVE_ICONV]: Include iconv.h and langinfo.h.
(convert_fname): New function.
[HAVE_ICONV]: Convert file name from remote encoding to local
encoding.
(url_file_name): Call convert_fname.
(filechr_table): Don't consider bytes in 128..159 as control
characters.

* tests/Test-ftp-iri.px: Fix the expected file name to match the
new file-name recoding.  State the remote encoding explicitly on
the Wget command line.

* NEWS: Mention the URI recoding when built with libiconv.
2015-12-18 20:54:39 +01:00
Giuseppe Scrivano
9a6e63bee9 * NEWS: Prepare new development cycle 2015-12-18 11:29:59 +01:00
Tim Rühsen
cbbeca2af4 Cleanup code
* src/iri.c (do_conversion): Code cleanup
2015-12-17 21:01:50 +01:00
Eli Zaretskii
93c1517c40 Set URI encoding when redirected
* src/retr.c (retrieve_url): Set URI on redirection
2015-12-17 15:27:43 +01:00
Tim Rühsen
bf5d7e9236 Remove requesting X/Open 5, POSIX 1995
* src/sysdep.h: Remove #define _XOPEN_SOURCE 500
2015-12-17 12:11:53 +01:00
Eli Zaretskii
94d9b68db9 Avoid hanging on MS-Windows when invoked with --connect-timeout
* src/connect.c (connect_to_ip) [WIN32]: Don't call fd_close if
the connection timed out, to avoid hanging.
2015-12-16 15:06:45 +01:00
Tim Rühsen
be7d19f478 Fix iconv conversion
* src/iri.c: Kick out the last converted character from iconv()

Thanks to Eli Zaretskii <eliz@gnu.org> for suggesting the fix.
Reported-by: "Andries E. Brouwer" <Andries.Brouwer@cwi.nl>
2015-12-15 10:55:41 +01:00
Tim Rühsen
358a3c330f Let Test-k survive on CygWin and Windows
* tests/Test-k.px: Use --restrict-file-names for CygWin/Windows
  filename requirements.
2015-12-14 09:36:40 +01:00
Ander Juaristi
478a584609 Fix leak in HSTS code
* src/hsts.c (hsts_store_open): close fp if open.
2015-12-13 16:10:16 +01:00
Ander Juaristi
994c4dcce7 Remove unused variable in ftp code
* src/ftp.c (getftp): fix compiler warning for unused variable.
2015-12-13 16:06:53 +01:00
Giuseppe Scrivano
f65f522f58 Tag release 1.17.1
* NEWS: Update.
* gnulib: sync from upstream.
2015-12-11 18:35:04 +01:00
Tim Rühsen
be84711ea4 Remove ABOUT-NLS from git
* ABOUT-NLS: Remove from repository, it will be autogenerated.
* .gitignore: Add ABOUT-NLS and build-aux/ar-lib
2015-12-11 12:11:55 +01:00
Jernej Simončič
bf56bf4560 * src/metalink.c: Specify 'rb' as mode to open file 2015-12-11 09:58:30 +01:00
Ángel González
3eddf5c173 * doc/wget.texi: add hint for self-signed certificates 2015-12-10 23:26:14 +01:00
Ander Juaristi
160f0e908f Fix Coverity issues
* src/ftp.c (getftp): on error, close the file and attempt to remove it
   before exiting.
 * src/hsts.c (hsts_store_open): update modification time in the end.
2015-12-10 23:21:27 +01:00
Darshit Shah
30b0705fa6 Faster Travis Builds
* contrib/travis-ci: Test under different languages only when all the
features are enabled. This covers the maximum number of strings. For the
other option permutations, test only in the default C locale
2015-12-10 22:43:31 +01:00
Darshit Shah
9933da2b9f Fix remaining bugs in progress bar implementation
* src/progress.c (create_image): Ensure that the entire screen width is
drawn everytime to prevent any artefacts from leaking through.
2015-12-10 13:43:45 +01:00
Darshit Shah
df7cb9a1b9 Add bug-wget to list of travis recipients
* .travis.yml: Add bug-wget to list of Travis Report Recipients
2015-12-09 09:28:58 +01:00
Darshit Shah
636a5f9a1c Eliminate more compiler warnings
* src/options.h (CHECK_CERT_MODES): Remove C99 style comma after last
value
* src/progress.c (create_image): Do not mix statements and declarations
* src/init.c (cmd_boolean_internal): Mark unused parameters
2015-12-09 09:26:24 +01:00
Darshit Shah
44937634a3 Re-enable test on multibyte locale in Travis
* .travis.yml: Use Russian locale instead of Japanese since it seems to
be more complete
* contrib/travis-ci: Re-enable testing on a Russian locale
2015-12-09 09:26:24 +01:00
Darshit Shah
2257d3ebf8 Fix progress bar assertion with multibyte locales
* src/progress.c (bar_create): Define size of progress buffer explicitly
  (create_image): Clean up progress bar image creation. Use memset
  instead of for loops to create arrays of the same byte.
2015-12-09 09:26:24 +01:00
Darshit Shah
b0d2fa5748 Introduce Travis Integration
* .travis.yml: Configuration file for Travis-CI
* contrib/travis-ci: Script to run on travis. Similar to check-hard but modified
  for travis.
* tests/valgrind-suppressions{-ssl}: Add extra suppressions to prevent a
Valgrind False Positive errors in an old version

Since Travis currently supports only public repositories on GitHub, the support
for automated testing through Travis will be done using my Clone of Wget on
GitHub at: https://github.com/darnir/wget.git
Any commits pushed to this repository will trigger a build on Travis.
2015-12-06 21:50:58 +01:00
Tim Rühsen
ca0c272eae SKIP SSL/TLS tests if configured without it
* testenv/Makefile.am: Set SSL_TESTS env variable
* testenv/Test--https-crl.py, testenv/Test--https.py,
  testenv/Test-hsts.py: Return 77 (SKIP) if SSL/TLS is not configured
2015-12-04 15:49:18 +01:00
Tim Rühsen
8977e63239 Add Test-hsts.py to SSL_TESTS
* testenv/Makefile.am: Add Test-hsts.py to SSL_TESTS
2015-12-03 16:14:24 +01:00
Ygal Blum
ad5a283528 Fix compilation when without-ssl is selected 2015-12-03 16:12:35 +01:00
Darshit Shah
3dd2e78256 Include Metalink and GPG information in version
* src/build_info.c.in: Include the presence of Metalink and GPGME features in
the output for wget --version
2015-12-03 16:02:51 +01:00
Giuseppe Scrivano
81061571d1 Add --check-certificate=quiet
* doc/wget.texi: Add documentation for  --check-certificate=quiet.
* src/options.h (enum CHECK_CERT_MODES): New enum.
* src/init.c (cmd_check_cert): New static function.
(cmd_boolean_internal): Likewise.
* src/gnutls.c (ssl_check_certificate): Handle CHECK_CERT_QUIET.
* src/openssl.c (ssl_check_certificate): Handle CHECK_CERT_QUIET.
2015-12-03 11:49:55 +01:00
Tim Rühsen
4e37fb6191 Fix regression in HTTP authentication
* src/http.c (initialize_request): Fix wrong params to search_netrc()

Regression introduced in commit 29850e77
Reported-by: Axel Reinhold <axel@freakout.de>
2015-11-24 10:39:39 +01:00
Tim Rühsen
218d81f6e5 Fix SIGSEGV in -N / --content-disposition combination
* src/http.c (http_loop): Fix SIGSEGV

Reported-by: "Schleusener, Jens" <Jens.Schleusener@t-online.de>
2015-11-23 15:10:00 +01:00
Ander Juaristi
46cd721c0f Fix potential NULL pointer dereference
* src/gnutls.c (ssl_connect_wget): check for NULL before calls
2015-11-20 19:22:25 +01:00
Giuseppe Scrivano
b1c7777037 * configure.ac: change gettext version to 0.18.1 2015-11-20 11:58:42 +01:00
Ikey Doherty
8c12260d4b configure.ac: Use correct gettext version
Signed-off-by: Ikey Doherty <michael.i.doherty@intel.com>
2015-11-19 23:14:07 +01:00
Tim Rühsen
99aa7b4f5e Fix HSTS memory issue + test code issue
* src/hsts.c (hsts_find_entry): Fix freeing memory
  (hsts_remove_entry): Remove freeing host member
  (hsts_match): Free host member here
  (hsts_store_entry): Free host member here
  (test_url_rewrite): Fix 'created' value
  (test_hsts_read_database): Fix 'created' value

Reported-by: Dagobert Michelsen <dam@opencsw.org>
2015-11-19 12:20:35 +01:00
Tim Rühsen
76da642aaf Include errno.h instead of sys/errno.h (Solaris issue)
* src/metalink.c: Include errno.h instead of sys/errno.h

Reported-by: Dagobert Michelsen <dam@opencsw.org>
2015-11-17 14:42:25 +01:00
Darshit Shah
2cfcadf5e6 Fix compile error when IPv6 is disabled
* src/ftp-basic.c: The code for the new FTPS functionality was unintentionally
inside a #ifdef IPV6 block. Move the code around so that it is defined even when
IPV6 isn't used
2015-11-17 13:40:44 +01:00
Darshit Shah
08ece891b5 Use gnulib module flock to provide function
* bootstrap.conf: Use module flock from gnulib to provide it on other platforms
such as Windows.
2015-11-17 00:36:06 +01:00
Darshit Shah
4ed540ddc7 Eliminate NDEBUG redefined warnings
* src/wget.h: Define NDEBUG only if it hasn't been defined before
2015-11-16 23:53:59 +01:00
Giuseppe Scrivano
d1a329536a NEWS: prepare new release cycle 2015-11-15 15:23:38 +01:00
255 changed files with 15406 additions and 2954 deletions

2
.gitignore vendored
View File

@@ -2,6 +2,7 @@
/.sc-start-sc_bindtextdomain
/.sc-start-sc_prohibit_HAVE_MBRTOWC
/.version
/ABOUT-NLS
/GNUmakefile
/INSTALL
/Makefile
@@ -25,6 +26,7 @@ testenv/*.log
testenv/*.trs
# build-aux/
build-aux/.gitignore
build-aux/ar-lib
build-aux/compile
build-aux/config.guess
build-aux/config.sub

124
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,124 @@
variables:
BUILD_IMAGES_PROJECT: gnuwget/build-images
DEBIAN_BUILD: buildenv-debian-stretch
FEDORA_BUILD: buildenv-f25
CENTOS7_BUILD: buildenv-centos7
GET_SOURCES_ATTEMPTS: "3"
# In this build we combine
# * syntax-check
# * abi-check
# * build/valgrind-check
# * build/asan-check
# * build w/Werror and ubsan-check
Debian GNU/Linux build:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$DEBIAN_BUILD
script:
- echo "127.0.0.1 wgettestingserver" >>/etc/hosts
- cat /etc/hosts
- touch .manywarnings
- alias make="make -j$(nproc)"
- ./bootstrap
- ./configure -C
- make syntax-check
- make check
# - make abi-check
- make distcheck
- make check-valgrind
- ./configure -C --with-ssl=openssl
- make clean
- make check
# - ./configure -C --enable-fsanitize-asan
# - make clean
# - make check
# - ./configure -C --enable-fsanitize-ubsan
# - make clean
# - make check
# - ./configure -C --enable-fsanitize-msan
# - make clean
# - make check
tags:
- shared
artifacts:
expire_in: 2 weeks
when: on_failure
paths:
- tests/*.log
# - compat_reports/
#Centos7 build:
# image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD
# script:
# - sed -i 's/AM_GNU_GETTEXT_VERSION(0.19.3)/AM_GNU_GETTEXT_VERSION(0.18.2)/g' configure.ac
# - ./bootstrap && ./configure --enable-gcc-warnings --disable-doc && make -j$(nproc) check
# tags:
# - shared
# artifacts:
# expire_in: 2 weeks
# when: on_failure
# paths:
# - tests/*.log
# - compat_reports/
#clang-analyzer/Fedora:
# image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
# script:
# - ./bootstrap
# - scan-build ./configure --disable-doc --enable-gcc-warnings
# - make -j$(nproc) -C gl
# - scan-build --status-bugs -o scan-build-lib make -j$(nproc) -C lib
# tags:
# - shared
# except:
# - tags
# artifacts:
# expire_in: 2 weeks
# when: on_failure
# paths:
# - scan-build-lib/*
#pages:
# image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$DEBIAN_BUILD
# script:
# - ./bootstrap
# - CFLAGS="-g -O0" ./configure --enable-gtk-doc --enable-code-coverage --disable-gcc-warnings
# - make -j$(nproc) check
# - make local-code-coverage-output
# - mkdir -p public
# - rm -rf public/coverage
# - mv libidn2-*-coverage public/coverage
# - rm -rf public/reference
# - mv doc/reference/html public/reference
# - make -C doc manual
# - rm -rf public/manual
# - mv doc/manual public/manual
# tags:
# - shared
# artifacts:
# when: on_success
# paths:
# - public
# only:
# - master
#MinGW64:
# image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
# before_script:
# - mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc &&
# echo ':DOSWin:M::MZ::/usr/bin/wine64:' > /proc/sys/fs/binfmt_misc/register
# script:
# - ./bootstrap
# - mingw64-configure --disable-valgrind-tests --disable-doc
# - mingw64-make -j$(nproc)
# - mingw64-make -j$(nproc) check
# tags:
# - shared
# - docker
# except:
# - tags
# artifacts:
# expire_in: 2 weeks
# when: on_failure
# paths:
# - ./*.log
# - tests/*.log

51
.travis.yml Normal file
View File

@@ -0,0 +1,51 @@
sudo: no
dist: trusty
language: c
compiler:
- gcc
notifications:
email:
recipients:
- darnir@gmail.com
- bug-wget@gnu.org
on_success: change
on_failure: always
env:
global:
- PERLLIB=$PERLLIB:../../tests
- PERL5LIB=$PERL5LIB:../../tests
matrix:
- SSL=""
- SSL="openssl"
- SSL="gnutls"
addons:
apt:
packages:
- automake
- autoconf
- autopoint
- flex
- texinfo
- pkg-config
- libgnutls-dev
- libssl-dev
- make
- libhttp-daemon-perl
- libio-socket-ssl-perl
- libidn2-dev
- gettext
- texlive
- python3
- valgrind
- language-pack-tr
- language-pack-ru
script:
- make distclean || true
- ./bootstrap
- ./contrib/travis-ci $SSL

1068
ABOUT-NLS

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
@@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<https://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@@ -729,7 +729,7 @@
* testenv/Makefile.am: Run the tests in Python's Optimizedmode
* testenv/conf/__init__.py (gen_hook): Use try..except instead of if..else
* testenv/misc/color_terminal.py: System and check will not change while a test is
run. Do not test for them on every invokation of printer()
run. Do not test for them on every invocation of printer()
* testenv/server/http/http_server.py: The ssl and re modules are required by
specific functions. Load them lazily
(HTTPSServer.__init__): Lazy load ssl module here

View File

@@ -7,30 +7,14 @@ Primary List
The primary mailinglist for discussion, bug-reports, or questions about
GNU Wget is at <bug-wget@gnu.org>. To subscribe, send an email to
<bug-wget-join@gnu.org>, or visit
`http://lists.gnu.org/mailman/listinfo/bug-wget'.
`https://lists.gnu.org/mailman/listinfo/bug-wget'.
You do not need to subscribe to send a message to the list; however,
please note that unsubscribed messages are moderated, and may take a
while before they hit the list--*usually around a day*. If you want
your message to show up immediately, please subscribe to the list
before posting. Archives for the list may be found at
`http://lists.gnu.org/pipermail/bug-wget/'.
An NNTP/Usenettish gateway is also available via Gmane
(http://gmane.org/about.php). You can see the Gmane archives at
`http://news.gmane.org/gmane.comp.web.wget.general'. Note that the
Gmane archives conveniently include messages from both the current
list, and the previous one. Messages also show up in the Gmane archives
sooner than they do at `lists.gnu.org'.
Bug Notices List
----------------
Additionally, there is the <wget-notify@addictivecode.org> mailing
list. This is a non-discussion list that receives bug report
notifications from the bug-tracker. To subscribe to this list, send an
email to <wget-notify-join@addictivecode.org>, or visit
`http://addictivecode.org/mailman/listinfo/wget-notify'.
`https://lists.gnu.org/pipermail/bug-wget/'.
Obsolete Lists
--------------
@@ -40,10 +24,7 @@ discussion list, and another list, <wget-patches@sunsite.dk> was used
for submitting and discussing patches to GNU Wget.
Messages from <wget@sunsite.dk> are archived at
`http://www.mail-archive.com/wget%40sunsite.dk/' and at
`http://news.gmane.org/gmane.comp.web.wget.general' (which also
continues to archive the current list, <bug-wget@gnu.org>).
`https://www.mail-archive.com/wget%40sunsite.dk/' and at
Messages from <wget-patches@sunsite.dk> are archived at
`http://news.gmane.org/gmane.comp.web.wget.patches'.
`https://news.gmane.org/gmane.comp.web.wget.patches'.

View File

@@ -1,6 +1,6 @@
# Makefile for `Wget' utility
# Copyright (C) 1995, 1996, 1997, 2006, 2007, 2008, 2009, 2010, 2011
# Free Software Foundation, Inc.
# Copyright (C) 1995-1997, 2006-2018 Free Software Foundation,
# Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -13,7 +13,7 @@
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Additional permission under GNU GPL version 3 section 7
@@ -77,3 +77,6 @@ gen-ChangeLog:
{ rm -f $(distdir)/ChangeLog && \
mv $(distdir)/cl-t $(distdir)/ChangeLog; } \
fi
check-valgrind:
TESTS_ENVIRONMENT="VALGRIND_TESTS=1" $(MAKE) check

142
NEWS
View File

@@ -1,12 +1,146 @@
GNU Wget NEWS -- history of user-visible changes.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Free
Software Foundation, Inc.
Copyright (C) 1997-2018 Free Software Foundation, Inc.
See the end for copying conditions.
Please send GNU Wget bug reports to <bug-wget@gnu.org>.
* Changes in Wget 1.19.4
* A major bug that caused GZip'ed pages to never be decompressed has been fixed
* Support for Content-Encoding and Transfer-Encoding have been marked as
experimental and disabled by default
* Changes in Wget 1.19.3
* Prevent erroneous decompression of .gz and .tgz files with broken servers
* Added support for HTTP 308 Permanent Redirect response
* Fix a segfault in some cases where the Content-Type header is not sent
* Support OpenSSL 1.1 builds without using deprecated features
* Fix netrc file detection on Windows
* Several minor bug fixes
* Changes in Wget 1.19.2
* Fix CVE-2017-13089 (Stack overflow in HTTP protocol handling)
* Fix CVE-2017-13090 (Heap overflow in HTTP protocol handling)
* New option --compression for gzip Content-Encoding
* New option --[no]-netrc to control .netrc parsing
* Added GNU extensions to .netrc parsing
* Improved IDNA 2003 compatibility
* Fix VPATH issues
* Improved and extended the test suite
* Support Wayback Machine's X-Archive-Orig-last-modified
* Several bug fixes
* Changes in Wget 1.19.1
* Fix bugs, a regression, portability/build issues
* Add new option --retry-on-http-error
* Changes in Wget 1.19
* New option --use-askpass=COMMAND. Fetch user/password by calling
an external program.
* Use IDNA2008 (+ TR46 if available) through libidn2
* When processing a Metalink header, --metalink-index=<number> allows
to process the header's application/metalink4+xml files.
* When processing a Metalink file, --trust-server-names enables the
use of the destination file names specified in the Metalink file,
otherwise a safe destination file name is computed.
* When processing a Metalink file, enforce a safe destination path.
Remove any drive letter prefix under w32, i.e. 'C:D:file'. Call
libmetalink's metalink_check_safe_path() to prevent absolute,
relative, or home paths:
https://tools.ietf.org/html/rfc5854#section-4.1.2.1
https://tools.ietf.org/html/rfc5854#section-4.2.8.3
* When processing a Metalink file, --directory-prefix=<prefix> sets
the top of the retrieval tree to prefix for Metalink downloads.
* When processing a Metalink file, reject downloaded files which don't
agree with their own metalink:size value:
https://tools.ietf.org/html/rfc5854#section-4.2.16
* When processing a Metalink file, with --continue resume partially
downloaded files and keep fully downloaded files even if they fail
the verification.
* When processing a Metalink file, create the parent directories of a
"path/file" destination file name:
https://tools.ietf.org/html/rfc5854#section-4.1.2.1
https://tools.ietf.org/html/rfc5854#section-4.2.8.3
* On a recursive download, append a .tmp suffix to temporary files
that will be deleted after being parsed, and create them
readable/writable only by the owner.
* New make target 'check-valgrind'
* Fix several bugs
* Fix compatibility issues
* Changes in Wget 1.18
* By default, on server redirects to a FTP resource, use the original
URL to get the local file name. Close CVE-2016-4971. This
introduces a backward-incompatibility for HTTP->FTP redirects and
any script that relies on the old behaviour must use
--trust-server-names.
* Check the HSTS file is not world-writable before using it.
* Parse <img srcset> attributes on a recursive download.
* Fix problem with SNI server names having trailing dot(s)
* New options --bind-dns-address and --dns-servers.
* When Wget is built with libiconv, it now converts non-ASCII URIs to
the locale's codeset when it creates files. The encoding of the
remote files and URIs is taken from --remote-encoding, defaulting to
UTF-8. The result is that non-ASCII URIs and files downloaded via
HTTP/HTTPS and FTP will have names on the local filesystem that
correspond to their remote names.
* Changes in Wget 1.17.1
* Fix compile error when IPv6 is disabled or SSL is not present.
* Fix HSTS memory leak.
* Fix progress output in non-C locales.
* Fix SIGSEGV when -N and --content-disposition are used together.
* Add --check-certificate=quiet to tell wget to not print any warning about
invalid certificates.
* Changes in Wget 1.17
** Remove FTP passive to active fallback due to privacy concerns.
@@ -610,7 +744,7 @@ addresses when accessing the first one fails.
non-standard port.
** Wget now supports the robots.txt directives specified in
<http://www.robotstxt.org/wc/norobots-rfc.txt>.
<http://www.robotstxt.org/norobots-rfc.txt>.
** URL parser has been fixed, especially the infamous overzealous
quoting. Wget no longer dequotes reserved characters, e.g. `%3F' is

6
README
View File

@@ -1,7 +1,7 @@
-*- text -*-
GNU Wget
========
Current Web home: http://www.gnu.org/software/wget/
Current Web home: https://www.gnu.org/software/wget/
GNU Wget is a free utility for non-interactive download of files from
the Web. It supports HTTP, HTTPS, and FTP protocols, as well as
@@ -50,10 +50,10 @@ resides at <ftp://ftp.gnu.org/pub/gnu/wget/>.
Please report bugs in Wget to <bug-wget@gnu.org>.
See the file `MAILING-LIST' for information about Wget mailing lists.
Wget's home page is at <http://www.gnu.org/software/wget/>.
Wget's home page is at <https://www.gnu.org/software/wget/>.
If you would like to contribute code for Wget, please read
http://wget.addictivecode.org/PatchGuidelines.
https://wget.addictivecode.org/PatchGuidelines.
Wget was originally written and mainained by Hrvoje Niksic. Please see
the file AUTHORS for a list of major contributors, and the ChangeLogs

View File

@@ -4,7 +4,7 @@ Compiling From Repository Sources
does not contain automatically-generated files, even when these are
normally present in the distribution tarballs. Therefore, to build GNU
Wget from the sources in the repository, you'll need to have one or
more of the following (note that gettext, OpenSSL, GnuTLS, libidn,
more of the following (note that gettext, OpenSSL, GnuTLS, libidn2,
libiconv, libpsl, libpcre, pkg-config, libmetalink and GnuPG are not
absolutely required):
@@ -25,14 +25,15 @@ Compiling From Repository Sources
tests in the tests/ sub directory. Tarball distributions include an
already-generated wget.1 manual. The command "make check" runs the
test suite written in perl and python (see below). To execute all the tests
you need [24]libwww-perl and libio-socket-ssl-perl perl library. If
"perl -MCPAN -e 'install Bundle::LWP'" fails then you most likely don't
have cpan module installed. First download [25]CPAN and [26]install it.
Then execute "perl -MCPAN -e 'install Bundle::LWP'".
you need libwww-perl and libio-socket-ssl-perl perl library.
GNU/Linux distros likely have these two libraries packaged.
If not, install them directly with "perl -MCPAN -e 'install Bundle::LWP'"[24].
If that fails then you most likely don't have the CPAN module installed.
First download [25]CPAN and [26]install it, then try again the above command.
Now "make check" should pass most of the tests in the test suite.
* [45]Python, if you want to run the tests in the testenv/ subdirectory.
Keep in mind that "make check" will try to run all the perl and python
* [45]Python3, if you want to run the tests in the testenv/ subdirectory.
Keep in mind that "make check" will try to run all the Perl and Python3
tests. More information about the test suite below in the section
"Testing and development".
@@ -68,7 +69,7 @@ Compiling From Repository Sources
If you want to compile+link a non-system library version use
--with-libssl-prefix (or if having pkg-config: see description below).
* [31]libidn is required for IDN/IRI support (non-ASCII characters
* [31]libidn2 is required for IDN/IRI support (non-ASCII characters
within what would otherwise be URLs).
* [32]libiconv is required on non-GNU systems, for IDN/IRI support.
@@ -99,6 +100,13 @@ Compiling From Repository Sources
* [47]GnuPG with GPGME is used to verify GPG-signed Metalink resources.
* [48]libcares is needed to bind DNS resolving to a given IP address.
The command line options --dns-servers and --bind-dns-address are
only available when configured with --with-cares.
* [49]Gpef is required by some gnulib modules, most notably "unicase". You
need the application installed on the machine to compile Wget from git.
For those who might be confused as to what to do once they check out
the source code, considering configure and Makefile do not yet exist at
@@ -112,7 +120,7 @@ Compiling From Repository Sources
$ cd wget # assumes you've cloned a repository to "./wget"
2. Generate all the automatically-generated files required prior to
configuring the package:
$ ./bootstrap
$ ./bootstrap (or: bash ./bootstrap)
3. Configure the package and compile it:
$ ./configure --enable-assert [some_parameters]
$ make
@@ -153,9 +161,10 @@ Testing and development
that bug, which might be tedious. Tests should only be run through GDB for that purpose.
Copyright (C) 2008,2010,2014,2015 Free Software Foundation, Inc.
Copyright (C) 2008, 2010, 2014-2015, 2018 Free Software Foundation,
Inc.
License GPLv3+: GNU GPL version 3 or later
<http://www.gnu.org/licenses/gpl.html>.
<https://www.gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
@@ -179,31 +188,33 @@ Testing and development
References
20. http://www.gnu.org/software/autoconf/
21. http://www.gnu.org/software/automake/
22. http://flex.sourceforge.net/
23. http://www.perl.org/
20. https://www.gnu.org/software/autoconf/
21. https://www.gnu.org/software/automake/
22. https://github.com/westes/flex
23. https://www.perl.org/
24. http://search.cpan.org/dist/libwww-perl/lib/Bundle/LWP.pm
25. http://search.cpan.org/CPAN/authors/id/A/AN/ANDK/CPAN-1.9402.tar.gz
26. http://apthorpe.cynistar.net/code/configuring_cpan.html
27. http://www.gnu.org/software/texinfo/
28. http://www.gnu.org/software/gettext/
29. http://www.gnu.org/software/gnutls/
30. http://www.openssl.org/
31. http://www.gnu.org/software/libidn/
32. http://www.gnu.org/software/libiconv/
33. http://git-scm.com/
27. https://www.gnu.org/software/texinfo/
28. https://www.gnu.org/software/gettext/
29. https://www.gnu.org/software/gnutls/
30. https://www.openssl.org/
31. https://www.gnu.org/software/libidn/#libidn2
32. https://www.gnu.org/software/libiconv/
33. https://git-scm.com/
34. https://github.com/rockdaboot/libpsl
35. http://www.pcre.org
35. https://www.pcre.org
36. http://wget.addictivecode.org/CompilingRepoSources?action=edit&editor=text
37. http://wget.addictivecode.org/CompilingRepoSources
38. http://wget.addictivecode.org/CompilingRepoSources?action=info
39. http://wget.addictivecode.org/CompilingRepoSources?action=AttachFile
40. http://moinmo.in/
41. http://moinmo.in/Python
42. http://moinmo.in/GPL
43. http://validator.w3.org/check?uri=referer
40. https://moinmo.in/
41. https://moinmo.in/Python
42. https://moinmo.in/GPL
43. https://validator.w3.org/check?uri=referer
44. http://wget.addictivecode.org/WikiLicense
45. https://www.python.org/
46. https://launchpad.net/libmetalink
47. https://www.gnupg.org
48. https://c-ares.haxx.se/
49. https://www.gnu.org/software/gperf/

View File

@@ -1,10 +1,10 @@
#! /bin/sh
# Print a version string.
scriptversion=2013-12-05.23; # UTC
scriptversion=2017-09-19.08; # UTC
# Bootstrap this package from checked-out sources.
# Copyright (C) 2003-2014 Free Software Foundation, Inc.
# Copyright (C) 2003-2018 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@ scriptversion=2013-12-05.23; # UTC
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Originally written by Paul Eggert. The canonical version of this
# script is maintained as build-aux/bootstrap in gnulib, however, to
@@ -42,6 +42,9 @@ export LC_ALL
local_gl_dir=gl
# Honor $PERL, but work even if there is none.
PERL="${PERL-perl}"
me=$0
usage() {
@@ -138,7 +141,7 @@ po_download_command_format=\
# Fallback for downloading .po files (if rsync fails).
po_download_command_format2=\
"wget --mirror -nd -q -np -A.po -P '%s' \
http://translationproject.org/latest/%s/"
https://translationproject.org/latest/%s/"
# Prefer a non-empty tarname (4th argument of AC_INIT if given), else
# fall back to the package name (1st argument with munging)
@@ -415,28 +418,30 @@ sort_ver() { # sort -V is not generally available
done
}
get_version_sed='
# Move version to start of line.
s/.*[v ]\([0-9]\)/\1/
# Skip lines that do not start with version.
/^[0-9]/!d
# Remove characters after the version.
s/[^.a-z0-9-].*//
# The first component must be digits only.
s/^\([0-9]*\)[a-z-].*/\1/
#the following essentially does s/5.005/5.5/
s/\.0*\([1-9]\)/.\1/g
p
q'
get_version() {
app=$1
$app --version >/dev/null 2>&1 || { $app --version; return 1; }
$app --version 2>&1 |
sed -n '# Move version to start of line.
s/.*[v ]\([0-9]\)/\1/
# Skip lines that do not start with version.
/^[0-9]/!d
# Remove characters after the version.
s/[^.a-z0-9-].*//
# The first component must be digits only.
s/^\([0-9]*\)[a-z-].*/\1/
#the following essentially does s/5.005/5.5/
s/\.0*\([1-9]\)/.\1/g
p
q'
$app --version 2>&1 | sed -n "$get_version_sed"
}
check_versions() {
@@ -456,6 +461,7 @@ check_versions() {
test "$appvar" = TAR && appvar=AMTAR
case $appvar in
GZIP) ;; # Do not use $GZIP: it contains gzip options.
PERL::*) ;; # Keep perl modules as-is
*) eval "app=\${$appvar-$app}" ;;
esac
@@ -473,6 +479,17 @@ check_versions() {
ret=1
continue
} ;;
# Another check is for perl modules. These can be written as
# e.g. perl::XML::XPath in case of XML::XPath module, etc.
perl::*)
# Extract module name
app="${app#perl::}"
if ! $PERL -m"$app" -e 'exit 0' >/dev/null 2>&1; then
warn_ "Error: perl module '$app' not found"
ret=1
fi
continue
;;
esac
if [ "$req_ver" = "-" ]; then
# Merely require app to exist; not all prereq apps are well-behaved
@@ -671,8 +688,11 @@ if $bootstrap_sync; then
}
fi
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
<$gnulib_tool || exit $?
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool.py
if ! <$gnulib_tool; then
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
<$gnulib_tool || exit $?
fi
# Get translations.
@@ -682,7 +702,7 @@ download_po_files() {
echo "$me: getting translations into $subdir for $domain..."
cmd=$(printf "$po_download_command_format" "$domain" "$subdir")
eval "$cmd" && return
# Fallback to HTTP.
# Fallback to HTTPS.
cmd=$(printf "$po_download_command_format2" "$subdir" "$domain")
eval "$cmd"
}
@@ -773,9 +793,9 @@ symlink_to_dir()
# Leave any existing symlink alone, if it already points to the source,
# so that broken build tools that care about symlink times
# aren't confused into doing unnecessary builds. Conversely, if the
# existing symlink's time stamp is older than the source, make it afresh,
# existing symlink's timestamp is older than the source, make it afresh,
# so that broken tools aren't confused into skipping needed builds. See
# <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00326.html>.
# <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00326.html>.
test -h "$dst" &&
src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 &&
dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 &&
@@ -900,7 +920,8 @@ if test $use_libtool = 1; then
esac
fi
echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
$gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
$gnulib_tool $gnulib_tool_options --import $gnulib_modules \
|| die "gnulib-tool failed"
for file in $gnulib_files; do
symlink_to_dir "$GNULIB_SRCDIR" $file \
@@ -1005,6 +1026,6 @@ echo "$0: done. Now you can run './configure'."
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@@ -1,6 +1,5 @@
# bootstrap.conf - Bootstrap configuration.
# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation,
# Inc.
# Copyright (C) 2007-2012, 2018 Free Software Foundation, Inc.
#
# This file is part of GNU Wget.
#
@@ -9,13 +8,13 @@
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# GNU Wgt is distributed in the hope that it will be useful, but
# GNU Wget is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see `http://www.gnu.org/licenses/'.
# along with this program. If not, see `https://www.gnu.org/licenses/'.
# gnulib library name
gnulib_name=libgnu
@@ -38,7 +37,9 @@ close
connect
dirname
fcntl
flock
fnmatch
fopen
futimens
ftello
getaddrinfo
@@ -51,9 +52,17 @@ gettext
gitlog-to-changelog
git-version-gen
gnupload
group-member
hostent
ioctl
iconv
iconv-h
inet_ntop
intprops
inttypes
langinfo
limits-h
link
listen
maintainer-makefile
mbiter
@@ -62,9 +71,16 @@ memrchr
mkdir
mkstemp
mkostemp
nanosleep
crypto/md2
crypto/md4
crypto/md5
crypto/sha1
crypto/sha256
crypto/sha512
open
pipe-posix
posix_spawn
quote
quotearg
recv
@@ -72,24 +88,37 @@ regex
select
send
setsockopt
signal-h
sigprocmask
sigpipe
snprintf
socket
spawn-pipe
stat
stdbool
stdint
strcase
strerror_r-posix
strpbrk
strptime
strtok_r
strtoll
symlink
sys_types
timegm
tmpdir
unlink
unlocked-io
update-copyright
libunistring-optional
unistr/u8-strlen
unicase/u8-tolower
utimens
vasprintf
vsnprintf
wcwidth
write
xmemdup0
xstrndup
"
@@ -117,4 +146,21 @@ rsync -
tar -
xz -
flex -
gperf -
"
bootstrap_post_import_hook ()
{
# We need to patch unicase/special-casing-table.h for gperf < 3.1
GPERF_VER=$(gperf --version | {
IFS=' .' read x y major minor bugfix _
printf "%d%02d%02d" $major $minor $bugfix
})
if [ $GPERF_VER -lt 30100 ]; then
echo "Creating lib/unicase/special-casing-table.h for gperf < 3.1"
gperf -m 10 lib/unicase/special-casing-table.gperf | \
sed -e "s/gl_unicase_special_lookup.*/gl_unicase_special_lookup\ \(const char \*str, size_t len\)/g" \
> lib/unicase/special-casing-table.h
fi
}

View File

@@ -2,7 +2,7 @@
# Generate build_info.c.
# Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
# Copyright (C) 2009-2011, 2018 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

8
cfg.mk
View File

@@ -1,4 +1,7 @@
export VC_LIST_EXCEPT_DEFAULT=^(lib/.*|m4/.*|md5/.*|build-aux/.*|src/gettext\.h|.*ChangeLog)$$
# Explicit syntax-check exceptions.
exclude_file_name_regexp--sc_trailing_blank = ^doc/annou.*$$
export VC_LIST_EXCEPT_DEFAULT=^(lib/.*|m4/.*|md5/.*|build-aux/.*|src/gettext\.h|.*ChangeLog|tests/certs/.*)$$
local-checks-to-skip = \
sc_const_long_option \
@@ -21,9 +24,10 @@ local-checks-to-skip = \
sc_program_name \
sc_makefile_at_at_check \
sc_cast_of_argument_to_free \
sc_prohibit_undesirable_word_seq
#SHELL=bash -x
show-vc-list-except:
@$(VC_LIST_EXCEPT)
VC_LIST_ALWAYS_EXCLUDE_REGEX = ^ABOUT-NLS|((msdos|vms)/.*)|ChangeLog-2014-12-10$$
VC_LIST_ALWAYS_EXCLUDE_REGEX = ^ABOUT-NLS|((msdos|vms)/.*)|ChangeLog-2014-12-10|/.*.der|^tests/certs/.*$$

View File

@@ -1,6 +1,6 @@
dnl Template file for GNU Autoconf
dnl Copyright (C) 1995, 1996, 1997, 2001, 2007, 2008, 2009, 2010, 2011, 2012,
dnl 2013, 2014 Free Software Foundation, Inc.
dnl Copyright (C) 1995-1997, 2001, 2007-2014, 2018 Free Software
dnl Foundation, Inc.
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
@@ -57,6 +57,8 @@ AC_CANONICAL_HOST
AC_DEFINE_UNQUOTED([OS_TYPE], "$host_os",
[Define to be the name of the operating system.])
dnl Non-verbose make
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
dnl
dnl Process External Libraries
@@ -70,7 +72,6 @@ dnl SSL: Configure SSL backend to use
AC_ARG_WITH([ssl],
[AS_HELP_STRING([--with-ssl={gnutls,openssl}], [specify SSL backend. GNU TLS is the default.])])
dnl Zlib: Configure use of zlib for compression
AC_ARG_WITH([zlib],
[AS_HELP_STRING([--without-zlib], [disable zlib.])])
@@ -79,6 +80,9 @@ dnl Metalink: Configure use of the Metalink library
AC_ARG_WITH([metalink],
[AS_HELP_STRING([--with-metalink], [enable support for metalinks.])])
dnl C-Ares: Configure use of the c-ares library for DNS lookup
AC_ARG_WITH(cares, AS_HELP_STRING([--with-cares], [enable support for C-Ares DNS lookup.]), with_cares=$withval, with_cares=no)
dnl
dnl Process features
dnl
@@ -180,7 +184,7 @@ dnl
dnl Gettext
dnl
AM_GNU_GETTEXT([external],[need-ngettext])
AM_GNU_GETTEXT_VERSION([0.17])
AM_GNU_GETTEXT_VERSION([0.18.1])
AC_PROG_RANLIB
@@ -286,15 +290,6 @@ AC_DEFINE([HAVE_STRNCASECMP], 1, [Define to 1 if you have the `strncasecmp' func
AC_DEFINE([HAVE_STRDUP], 1, [Define to 1 if you have the `strdup' function.])
AC_DEFINE([HAVE_ISATTY], 1, [Define to 1 if you have the `isatty' function.])
dnl
dnl Call Wget-specific macros defined in aclocal.
dnl
WGET_STRUCT_UTIMBUF
WGET_FNMATCH
WGET_NANOSLEEP
WGET_POSIX_CLOCK
WGET_NSL_SOCKET
dnl Deal with specific hosts
case $host_os in
*mingw32* )
@@ -325,6 +320,10 @@ AS_IF([test "x$with_libpsl" != xno], [
])
])
AS_IF([test x"$with_libpsl" = xyes], [
AC_CHECK_FUNCS(psl_latest)
])
AS_IF([test x"$with_zlib" != xno], [
with_zlib=yes
PKG_CHECK_MODULES([ZLIB], zlib, [
@@ -631,9 +630,6 @@ AC_ARG_ENABLE(iri,
]
)
AC_ARG_WITH(libidn, AC_HELP_STRING([--with-libidn=[DIR]],
[Support IDN/IRIs (needs GNU Libidn)]),
libidn=$withval, libidn="")
AS_IF([test "X$iri" != "Xno"],[
AM_ICONV
@@ -645,39 +641,23 @@ AS_IF([test "X$iri" != "Xno"],[
AC_MSG_NOTICE([disabling IRIs because libiconv wasn't found])
fi
fi
],[ # else
# For some reason, this seems to be set even when we don't check.
# Explicitly unset.
LIBICONV=
])
AC_ARG_WITH(libidn, AC_HELP_STRING([--with-libidn=[DIR]],
[Support IDN2008/IRIs (needs GNU libidn2 + libunicode)]),
libidn=$withval, libidn="")
if test "X$iri" != "Xno"; then
if test "$libidn" != ""; then
LDFLAGS="${LDFLAGS} -L$libidn/lib"
CPPFLAGS="${CPPFLAGS} -I$libidn/include"
fi
AS_IF([test "x$with_libidn2" != xno], [
AC_SEARCH_LIBS(idn2_lookup_u8, idn2,
[with_libidn2=yes; AC_DEFINE([ENABLE_IRI], 1, [Define if IRI support is enabled.])],
[with_libidn2=no; iri=no; AC_MSG_WARN(*** LIBIDN2 was not found. You will not be able to use IDN2008 support)])
# If idna.h can't be found, check to see if it was installed under
# /usr/include/idn (OpenSolaris, at least, places it there).
# Check for idn-int.h in that case, because idna.h won't find
# idn-int.h until we've decided to add -I/usr/include/idn.
AC_CHECK_HEADER(idna.h, ,
[AC_CHECK_HEADER(idn/idn-int.h,
[CPPFLAGS="${CPPFLAGS} -I/usr/include/idn"],
[iri=no])]
)
if test "X$iri" != "Xno"; then
AC_CHECK_LIB(idn, stringprep_check_version,
[iri=yes LIBS="${LIBS} -lidn"], iri=no)
fi
if test "X$iri" != "Xno" ; then
AC_DEFINE([ENABLE_IRI], 1, [Define if IRI support is enabled.])
AC_MSG_NOTICE([Enabling support for IRI.])
else
AC_MSG_WARN([Libidn not found])
fi
# AS_IF([test "x$with_libidn2" = xyes], [
# AC_SEARCH_LIBS(u8_tolower, unistring,
# [AC_DEFINE([ENABLE_IRI], 1, [Define if IRI support is enabled.])],
# [iri=no; AC_MSG_WARN(*** LIBUNISTRING was not found. You will not be able to use IDN2008 support)])
# ])
])
fi
dnl
@@ -742,18 +722,70 @@ AS_IF([test "X$enable_pcre" != "Xno"],[
])
])
dnl
dnl Check for libcares (resolver library)
dnl
AS_IF([test "X$with_cares" = "Xyes"],[
PKG_CHECK_MODULES([CARES], libcares, [
CFLAGS="$CARES_CFLAGS $CFLAGS"
AC_CHECK_HEADER(ares.h, [
LIBS="$CARES_LIBS $LIBS"
AC_DEFINE([HAVE_LIBCARES], [1], [Define if libcares is available.])
RESOLVER_INFO="libcares, --bind-dns-address and --dns-servers available"
])
], [
AC_CHECK_HEADER(ares.h, [
AC_CHECK_LIB(cares, ares_set_local_ip4, [
LIBS="-lcares ${LIBS}"
AC_DEFINE([HAVE_LIBCARES], 1, [Define if libcares is available.])
RESOLVER_INFO="libcares, --bind-dns-address and --dns-servers available"
])
])
])
], [
RESOLVER_INFO="libc, --bind-dns-address and --dns-servers not available"
])
dnl
dnl Extended Attribute support
dnl
AC_ARG_ENABLE([xattr],
[AS_HELP_STRING([--disable-xattr], [disable support for POSIX Extended Attributes])],
[ENABLE_XATTR=$enableval],
[ENABLE_XATTR=yes])
case "$host_os" in
*linux* | *darwin*) xattr_syscalls="fsetxattr" ;;
freebsd*) xattr_syscalls="extattr_set_fd" ;;
*) AC_MSG_NOTICE([Disabling Extended Attribute support: your system is not known to support extended attributes.])
ENABLE_XATTR=no
esac
if test "X${ENABLE_XATTR}" = "Xyes"; then
AC_CHECK_FUNCS([$xattr_syscalls], [], [
AC_MSG_NOTICE([Disabling Extended Attribute support: your system does not support $xattr_syscalls])
ENABLE_XATTR=no
])
fi
test "X${ENABLE_XATTR}" = "Xyes" && AC_DEFINE([ENABLE_XATTR], 1,
[Define if you want file meta-data storing into POSIX Extended Attributes compiled in.])
dnl Needed by src/Makefile.am
AM_CONDITIONAL([IRI_IS_ENABLED], [test "X$iri" != "Xno"])
AM_CONDITIONAL([WITH_SSL], [test "X$with_ssl" != "Xno"])
AM_CONDITIONAL([METALINK_IS_ENABLED], [test "X$with_metalink" != "Xno"])
AM_CONDITIONAL([WITH_XATTR], [test "X$ENABLE_XATTR" != "Xno"])
dnl
dnl Create output
dnl
AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile util/Makefile
po/Makefile.in tests/Makefile
lib/Makefile testenv/Makefile])
lib/Makefile testenv/Makefile
tests/certs/interca.conf tests/certs/rootca.conf])
AC_CONFIG_HEADERS([src/config.h])
AC_OUTPUT
@@ -772,9 +804,12 @@ AC_MSG_NOTICE([Summary of build options:
Digest: $ENABLE_DIGEST
NTLM: $ENABLE_NTLM
OPIE: $ENABLE_OPIE
POSIX xattr: $ENABLE_XATTR
Debugging: $ENABLE_DEBUG
Assertions: $ENABLE_ASSERTION
Valgrind: $VALGRIND_INFO
Metalink: $with_metalink
Resolver: $RESOLVER_INFO
GPGME: $have_gpg
IRI: $iri
])

View File

@@ -12,7 +12,8 @@ if [ $CORES -lt 1 ]; then CORES=1; fi
echo "Running: make distclean"
make distclean > /dev/null || true
CFLAGS="-std=c89 -pedantic -O2 -g -Wall -Wextra -Wstrict-prototypes -Wold-style-definition -Wwrite-strings -Wshadow -Wformat -Wformat-security -Wunreachable-code -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition"
#CFLAGS="-std=c89 -pedantic -O0 -g -Wall -Wextra -Wstrict-prototypes -Wold-style-definition -Wwrite-strings -Wshadow -Wformat -Wformat-security -Wunreachable-code -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition"
CFLAGS="-Wall -Wextra -O2 -g"
CACHEFILE=$PWD/config_check.cache
@@ -30,7 +31,7 @@ for CC in gcc clang; do
# the compiler changed, so we have to remove the cache file here
rm -f $CACHEFILE
for options in "" "--with-ssl=openssl"; do
for options in "" "--with-ssl=openssl" "--disable-iri"; do
export DISTCHECK_CONFIGURE_FLAGS="-C --cache-file=$CACHEFILE $options"
echo " ./configure $DISTCHECK_CONFIGURE_FLAGS"
./configure $DISTCHECK_CONFIGURE_FLAGS CFLAGS="$CFLAGS" > /dev/null

123
contrib/release Executable file
View File

@@ -0,0 +1,123 @@
#!/bin/bash -e
#
# Written 2016 by Tim Ruehsen
#
# To get the version number right: add a signed tag and
# make sure the working dir is clean (git diff).
# If that fails, put the version into '.tarball-version'.
export CFLAGS="-g -O2 -Wall"
echo
echo "* Bootstrap"
#./bootstrap >/dev/null
echo
echo "* Configure"
#./configure -q
extensions="gz lz"
app_name=$(grep "^PACKAGE_NAME='" configure|cut -d "'" -f2)
app_ver=$(grep "^PACKAGE_VERSION='" configure|cut -d "'" -f2)
echo "Current version of $app_name is $app_ver"
echo
echo -n "Is that OK ? [y/N] "
read x
[ "$x" != "y" -a "$x" != "Y" ] && exit 0
echo
grep -i "Changes in $app_name" NEWS|head -1
echo -n "Did you edit the NEWS file ? [y/N] "
read x
[ "$x" != "y" -a "$x" != "Y" ] && exit 0
echo
echo "* Make"
#make -s clean
#make -s
echo
echo "* Make distcheck"
#make -s distcheck >/dev/null
echo
echo "* Make dist"
for ext in $extensions; do
[[ $ext = 'gz' ]] && ext="gzip"
[[ $ext = 'lz' ]] && ext="lzip"
make -s dist-$ext >/dev/null
done
while true; do
echo "Alpha or Regular release ? [R/A] "
read x
if test "$x" = "r" || test "$x" = "R"; then
directory="/incoming/ftp"
break
elif test "$x" = "a" || test "$x" = "A"; then
directory="/incoming/alpha"
break
fi
done
x=$(gpg --list-secret-keys 2>/dev/null|grep ^sec|awk '{ print $2 }')
echo $x
if [ "$x" = "" ]; then
echo No signing key found - please check with 'gpg --list-secret-keys'
exit 1
fi
# arrays just work in Bash
keys=($x)
if [ ${#keys[@]} -eq 1 ]; then
IFS='/' arr=($x)
signing_key=${arr[1]}
else
for ((i=0; i < ${#keys[@]}; i++)); do
echo "$((i+1))) ${keys[i]}"
done
while true; do
echo -n "Enter 1-${#keys[@]}: "
read x
# check for digits only
if [ -n "${i//[0-9]/}" ]; then continue; fi
if test $x -ge 1 || test $x -le ${#keys[@]}; then
IFS='/' arr=(${keys[$((x-1))]})
signing_key=${arr[1]}
break
fi
done
fi
unset IFS
echo
echo -n "Really upload to ftp-upload.gnu.org/$directory ? "
read x
[ "$x" != "y" -a "$x" != "Y" ] && exit 0
for ext in $extensions; do
app_tarball="${app_name}-${app_ver}.tar.$ext"
gpg --default-key $signing_key --yes -b $app_tarball
echo -e "version: 1.2\nfilename: ${app_tarball}\ndirectory: ${app_name}\n" >${app_tarball}.directive
gpg --default-key $signing_key --yes --clearsign ${app_tarball}.directive
ftp -v -n -i -p ftp-upload.gnu.org <<EOF
user anonymous
cd $directory
put ${app_tarball}
put ${app_tarball}.sig
put ${app_tarball}.directive.asc
EOF
done
prev_tag=`git tag|tail -2|head -1`
echo "Don't forget to mention the following contributors in the announcement:"
(
git log ${prev_tag}.. --format="%aN" --reverse
git log ${prev_tag}.. --reverse|grep -i reported|cut -d':' -f2|cut -d'<' -f1|cut -d' ' -f2-|tr -d '"'
) | sort -u

60
contrib/travis-ci Executable file
View File

@@ -0,0 +1,60 @@
#!/bin/bash
# Set a stricter bash mode
set -e
set -u
# Set up the subset of tests this Matrix instance will run.
# One instance is forked for each of the SSL library possibilities
SSL=${1:-""}
case $SSL in
"") SSL_LIB="--without-ssl";;
"openssl") SSL_LIB="--with-ssl=openssl";;
"gnutls") SSL_LIB="--with-ssl=gnutls";;
esac
# For some reason. /proc/cpuinfo reports 16 cores on Travis, while the docs
# claim that each instance has only 2 cores. We believe the docs and force a
# value of n+1 here.
CORES=3
# Define a large number of Warning flags for the compiler. Hopefully, someone
# will sit and analyze the output to clean the warnings from the codebase.
CFLAGS="-std=c89 -pedantic -O0 -Wall -Wextra -Wstrict-prototypes -Wold-style-definition -Wwrite-strings -Wshadow -Wformat -Wformat-security -Wunreachable-code -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition"
# A cachefile for ./configure. Saves significant time when reconfiguring
CACHEFILE=$PWD/config_check.cache
# measure time consumed and print it at the end of the script
START=$(date +%s)
# Test different Permutations of Wget. Always under Valgrind
#
# Options:
# - All Features Enabled
# - C [Default Locale]
# - Russian [Multibyte / Multicolumn Locale]
# - Turkish [Special Test due to issues with language]
# - IPv6 Disabled
# - C
for options in "" "--disable-ipv6"; do
export DISTCHECK_CONFIGURE_FLAGS="-C --cache-file=$CACHEFILE --enable-assert --enable-valgrind-tests $SSL_LIB $options"
echo " ./configure $DISTCHECK_CONFIGURE_FLAGS CFLAGS=\"$CFLAGS\""
./configure $DISTCHECK_CONFIGURE_FLAGS CFLAGS="$CFLAGS"
if [[ -z $options ]]; then
LANG_ARR=("ru_RU.UTF-8" "tr_TR.UTF-8" "C")
else
LANG_ARR=("C")
fi
for xLCALL in "${LANG_ARR[@]}"; do
export TESTS_ENVIRONMENT="LC_ALL=$xLCALL VALGRIND_TESTS=1"
echo " TESTS_ENVIRONMENT=\"$TESTS_ENVIRONMENT\" make distcheck CFLAGS=$CFLAGS -j$CORES"
make distcheck CFLAGS="$CFLAGS" -j$CORES
done
done
END=$(date +%s)
echo "Duration: $((END-START))"

View File

@@ -1,6 +1,6 @@
# Makefile for `wget' utility
# Copyright (C) 1995, 1996, 1997, 2007, 2008, 2009, 2010, 2011, 2015
# Free Software Foundation, Inc.
# Copyright (C) 1995-1997, 2007-2011, 2015, 2018 Free Software
# Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -57,7 +57,8 @@ wget.pod: $(srcdir)/wget.texi version.texi
$(TEXI2POD) -D VERSION="$(VERSION)" $(srcdir)/wget.texi $@
$(MAN): wget.pod
$(POD2MAN) --center="GNU Wget" --release="GNU Wget @VERSION@" --utf8 $? > $@
$(POD2MAN) --center="GNU Wget" --release="GNU Wget @VERSION@" --utf8 $? > $@ || \
$(POD2MAN) --center="GNU Wget" --release="GNU Wget @VERSION@" $? > $@
#wget.cat: $(MAN)
# nroff -man $? > $@

104
doc/announcement_1.19.txt Normal file
View File

@@ -0,0 +1,104 @@
Hello,
we are pleased to announce the new version of GNU wget 1.19.
It comes with major improvements for Metalink, IDNA2008 for
international domain names, an option to call external tools
for fetching user/password, several bugfixes and improvements.
Many thanks go to all the contributors and list activists !
Contributors (from the git log):
Ander Juaristi
Dale R. Worley
Eli Zaretskii
Gisle Vanem
Giuseppe Scrivano
Göran Uddeborg
Jann Horn
Jeffery To
Jérémie Courrèges-Anglas
Liam R. Howlett
losgrandes
Matthew White
Misra, Deapesh
Nikos Mavrogiannopoulos
Noël Köthe
Piotr Wajda
Rahul Bedarkar
Sean Burford
Tim Rühsen
Tobias Stoeckmann
vijeth-aradhya
The new version is available for download here:
https://ftp.gnu.org/gnu/wget/wget-1.19.tar.gz
https://ftp.gnu.org/gnu/wget/wget-1.19.tar.xz
and the GPG detached signatures using the key 0x08302DB6A2670428:
https://ftp.gnu.org/gnu/wget/wget-1.19.tar.gz.sig
https://ftp.gnu.org/gnu/wget/wget-1.19.tar.xz.sig
To reduce load on the main server, you can use this redirector service
which automatically redirects you to a mirror:
http://ftpmirror.gnu.org/wget/wget-1.19.tar.gz
http://ftpmirror.gnu.org/wget/wget-1.19.tar.xz
Noteworthy changes:
* New option --use-askpass=COMMAND. Fetch user/password by calling
an external program.
* Use IDNA2008 (+ TR46 if available) through libidn2
* When processing a Metalink header, --metalink-index=<number> allows
to process the header's application/metalink4+xml files.
* When processing a Metalink file, --trust-server-names enables the
use of the destination file names specified in the Metalink file,
otherwise a safe destination file name is computed.
* When processing a Metalink file, enforce a safe destination path.
Remove any drive letter prefix under w32, i.e. 'C:D:file'. Call
libmetalink's metalink_check_safe_path() to prevent absolute,
relative, or home paths:
https://tools.ietf.org/html/rfc5854#section-4.1.2.1
https://tools.ietf.org/html/rfc5854#section-4.2.8.3
* When processing a Metalink file, --directory-prefix=<prefix> sets
the top of the retrieval tree to prefix for Metalink downloads.
* When processing a Metalink file, reject downloaded files which don't
agree with their own metalink:size value:
https://tools.ietf.org/html/rfc5854#section-4.2.16
* When processing a Metalink file, with --continue resume partially
downloaded files and keep fully downloaded files even if they fail
the verification.
* When processing a Metalink file, create the parent directories of a
"path/file" destination file name:
https://tools.ietf.org/html/rfc5854#section-4.1.2.1
https://tools.ietf.org/html/rfc5854#section-4.2.8.3
* On a recursive download, append a .tmp suffix to temporary files
that will be deleted after being parsed, and create them
readable/writable only by the owner.
* New make target 'check-valgrind'
* Fix several bugs
* Fix compatibility issues
Please report any problem you may experience to the bug-wget@gnu.org
mailing list.
For the maintainers of Wget,
Tim

View File

@@ -5,7 +5,7 @@
@c hence no sectioning command or @node.
@display
Copyright @copyright{} 2000, 2001, 2002, 2007, 2008, 2015 Free Software
Copyright @copyright{} 2000-2002, 2007-2008, 2015, 2018 Free Software
Foundation, Inc.
@uref{http://fsf.org/}

233
doc/metalink-standard.txt Normal file
View File

@@ -0,0 +1,233 @@
GNU Wget Metalink recommended behaviour
Metalink/XML and Metalink/HTTP standard reference
1. Security features
********************
Only metalink:file elements with safe "name" fields shall be accepted
[1 #section-4.1.2.1]. If unsafe metalink:file elements are saved, any
related test shall fail (see '2. Tests').
By design, libmetalink rejects unsafe metalink:file elements [3]:
* lib/metalink_helper.c (metalink_check_safe_path): Verify path
1.1 Exceptions
==============
The option --directory-prefix could allow to use an absolute, relative
or home path.
2. Tests
********
Saving a file to an unexpected path poses a security problem. We must
ensure that Wget's automated tests never modify the root and the home
paths or descend/escalate to a relative path unexpectedly.
2.1 Metalink/XML implemented tests
==================================
See testenv/Makefile.am (METALINK_TESTS).
2.2 Metalink/HTTP implemented tests
===================================
See testenv/Makefile.am (METALINK_TESTS).
3. Download file name
*********************
The download file name shall be decided by precise rules which prevent
any naming uncertainty and security issues.
3.1 Naming rules
================
The final name of downloaded files is computed starting from a trusted
name, which is then combined with the "Directory Options". The result
is verified and eventually made safer following security rules. If the
final name isn't found safe enough, then the file isn't downloaded.
Depending on the options used, a suffix could be appended to the final
name to not overwrite existing files.
3.1.1 The trusted name
======================
The option --trust-server-names decides what is the trusted name.
Any Metalink/XML element with an unsafe metalink:file "name" field is
ignored, see '1. Security features'.
3.1.1.1 Without --trust-server-names
====================================
When --trust-server-names is off, the basename of the --input-metalink
file, if available, or of the mother URL is trusted. This trusted name
is the radix of any subsequent file name.
When a Metalink/HTTP in encountered, any fetched Metalink/XML file has
its own ordinal number appended as suffix to the trusted name. In this
case scenario, an unique Metalink/XML file is saved each time applying
an additional suffix to the currently computed name when necessary.
The files described by a Metalink/XML file will be named sequentially
applying an additional suffix to the currently trusted/computed name.
3.1.1.2 With --trust-server-names
=================================
When --trust-server-names is on, the metalink:file "name" field parsed
from Metalink/XML files is trusted. When no Metalink/XML is available,
the mother URL is trusted.
Any Metalink/HTTP application/metalink4+xml file is saved using the
basename of its own Link header "name" field, if available.
In conjunction with the option --content-disposition, a 'Content-Type:
application/metalink4+xml' file is saved using the basename of its own
Content-Disposition header "filename" field, if available.
3.1.2 The final name
====================
The "Directory Options" are combined with the trusted name. The result
is evaluated again by the '1. Security features'. If the path is found
unsafe, only the basename of the final name is considered. If this is
found unsafe too, the file is not downloaded.
4. Metalink/XML
***************
4.1 Example files
=================
See [1 #section-1.1].
cat > bugus.meta4 << EOF
<?xml version="1.0" encoding="UTF-8"?>
<metalink xmlns="urn:ietf:params:xml:ns:metalink">
<file name="/dir/A/File1">
<size>1617</size>
<hash type="sha256">ecb3dff2648667513e31554b3ad054ccd89fce38e33367c9459ac3a285153742</hash>
<url>http://another.url/common_name</url>
<url>http://ftpmirror.gnu.org/bash/bash-4.3-patches/bash43-001</url>
</file>
<file name="dir/B/File2">
<size>1594</size>
<hash type="sha256">eee7cd7062ab29a9e4f02924d9c367264dcb8b162703f74ff6eb8f175a91502b</hash>
<url>http://another.url/again/common_name</url>
<url>http://ftpmirror.gnu.org/bash/bash-4.3-patches/bash43-002</url>
</file>
</metalink>
EOF
4.2 Command line example
========================
$ wget --input-metalink=bogus.meta4
4.3 Metalink/XML file parsing
=============================
The metalink xml file is parsed by one of the following libmetalink's
functions [3], depending upon the library configured to use:
* lib/libexpat_metalink_parser.c (metalink_parse_file): Expat [4]
* lib/libxml2_metalink_parser.c (metalink_parse_file): Libxml2 [5]
The result returned doesn't include unsafe metalink:file elements, as
stated at point '1. Security features'.
An empty result shall not be considered an error. Parsing errors will
be informed to the caller of libmetalink's metalink_parse_file().
4.4 Saving files
================
Fetched metalink:file elements shall be wrote using the unique "name"
field as file name [1 #section-4.1.2.1].
A metalink:file url's file name shall not substitute the "name" field.
Security exceptions are explained in '3. Download file name'.
4.5 Multi-Source download
=========================
Parallel range requests are allowed [1 #section-1].
5. Metalink/HTTP
****************
5.1 HTTP server
===============
The local server http://127.0.0.1 is used as reference in the course
of this chapter. Any server service capable of sending Metalink/HTTP
header answers may be used.
5.2 Command line example
========================
$ wget --metalink-over-http http://127.0.0.1/dir/file.ext
5.3 Metalink/HTTP header answer
===============================
See [2 #section-1.1].
Etag: "thvDyvhfIqlvFe+A9MYgxAfm1q5="
Link: <http://www2.example.com/example.ext>; rel=duplicate
Link: <ftp://ftp.example.com/example.ext>; rel=duplicate
Link: <http://example.com/example.ext.torrent>; rel=describedby;
type="application/x-bittorrent"
Link: <http://example.com/example.ext.meta4>; rel=describedby;
type="application/metalink4+xml"
Link: <http://example.com/example.ext.asc>; rel=describedby;
type="application/pgp-signature"
Digest: SHA-256=MWVkMWQxYTRiMzk5MDQ0MzI3NGU5NDEyZTk5OWY1ZGFmNzgyZTJlO
DYzYjRjYzFhOTlmNTQwYzI2M2QwM2U2MQ==
See [2 #section-4].
Link: <http://example.com/example.ext.torrent>; rel=describedby;
type="application/x-bittorrent"; name="differentname.ext"
Link: <http://example.com/example.ext.meta4>; rel=describedby;
type="application/metalink4+xml"
5.4 Saving files
================
When none of --output-document and/or --content-disposition is used,
the file name to wrote is computed from the cli's url hierarchy. The
purpose of the "Directory Options" is as usual, and the file name is
the cli's url file name, see wget(1).
The url followed to download the file shall not substitute the cli's
url to compute the file name to wrote, except when it redirects to a
Metalink/XML file, following the rules in '3. Download file name'.
5.5 Multi-Source download
=========================
Parallel range requests are allowed [2 #section-7].
4. References
*************
[1] The Metalink Download Description Format
https://tools.ietf.org/html/rfc5854
[2] Metalink/HTTP: Mirrors and Hashes
https://tools.ietf.org/html/rfc6249
[3] Libmetalink
https://github.com/metalink-dev/libmetalink
[4] Expat
http://www.libexpat.org
[5] Libxml2
http://xmlsoft.org

165
doc/metalink.txt Normal file
View File

@@ -0,0 +1,165 @@
GNU Wget Metalink module
Evaluation of the Metalink/XML and Metalink/HTTP implementations
1. Introduction
***************
This document, and the results contained in it, is focused over the
evaluation of the Metalink/XML and Metalink/HTTP implementations.
The "Directory Options" mentioned here are used on the command line in
conjunction with the option '--input-metalink=file' for Metalink/XML,
and '--metalink-over-http' for Metalink/HTTP.
$ wget --input-metalink=<file> [directory options]
$ wget --metalink-over-http [directory options] <url>
2. Notes
********
Tests for metalink:file names beginning with '/', '~/', './', or '../'
(e.g. "/path/file") shall be run manually due to security concerns.
3. Metalink files used as reference
***********************************
3.1 Test: metalink:file with "path/file" name format
====================================================
cat > test.meta4 << EOF
<?xml version="1.0" encoding="UTF-8"?>
<metalink xmlns="urn:ietf:params:xml:ns:metalink">
<file name="path/file">
<size>543</size>
<hash type="sha256">d37d3965f8e1a7b16504b4273b09c392776b7e4dd17e601256c7b2fd9ce5f56e</hash>
<hash type="md5">0f6ff5cdc15603f1b81227b5a296f001</hash>
<url>http://wrongurl.really/gnu/wget/wget-1.18.tar.xz.sig</url>
<url>http://ftpmirror.gnu.org/wget/wget-1.18.tar.xz.sig</url>
<url>http://ftp.gnu.org/gnu/wget/wget-1.18.tar.xz.sig</url>
<url>http://nl.mirror.babylon.network/gnu/wget/wget-1.18.tar.xz.sig</url>
</file>
</metalink>
EOF
4. `wget --input-metalink=test.meta4`
*************************************
4.1 Implemented safety features
===============================
Any metalink:file name containing an absolute, relative, or home path
(see '2. Notes') parsed from Metalink/XML files is rejected.
This is a libmetalink's design decision implemented in the function
metalink_check_safe_path(). This feature shall not be modified.
All the above conform to the RFC5854 standard.
References:
https://tools.ietf.org/html/rfc5854#section-4.1.2.1
https://tools.ietf.org/html/rfc5854#section-4.2.8.3
4.2 File download behaviour
===========================
When a Metalink/XML file is parsed:
1. create the metalink:file "path/file" tree;
2. download the metalink:url file as "path/file";
3. verify the "path/file" size, if declared;
4. verify the "path/file" checksum.
All the above conform to the RFC5854 standard.
References:
https://tools.ietf.org/html/rfc5854
4.3 Questionable behaviours
===========================
If more metalink:file elements are the same, wget downloads them all.
5. `wget --metalink-over-http`
******************************
5.1 Implemented safety features
===============================
The function url_file_name() is responsible of parsing the url's file
name and mixing in the "Directory Options" wrote on the command line.
The use of libmetalink's metalink_check_safe_path() shouldn't be
necessary (see '4.1 Implemented safety features').
All the above comform to the usual Wget's download behaviour.
References:
wget(1)
5.2 File download behaviour
===========================
When a Metalink/HTTP header is parsed:
1. extract metalink metadata from the header;
2. download the file from the mirror with the highest priority;
3. verify the file's size, if declared;
4. verify the file's checksum.
All the above comform to the usual Wget's download behaviour and to
the RFC6249 standard.
References:
wget(1)
https://tools.ietf.org/html/rfc6249
6. Directory Options
********************
'-nd'
'--no-directories'
Do not apply to Metalink/XML files (aka --input-metalink=<file>).
Apply to Metalink/HTTP urls as described in the Wget's manual, see
wget(1). The target url is the url wrote on the command line.
'-x'
'--force-directories'
Do not apply to Metalink/XML files (aka --input-metalink=<file>).
Apply to Metalink/HTTP urls as described in the Wget's manual, see
wget(1). The target url is the url wrote on the command line.
'-nH'
'--no-host-directories'
Do not apply to Metalink/XML files (aka --input-metalink=<file>).
Apply to Metalink/HTTP urls as described in the Wget's manual, see
wget(1). The target url is the url wrote on the command line.
'--protocol-directories'
Do not apply to Metalink/XML files (aka --input-metalink=<file>).
Apply to Metalink/HTTP urls as described in the Wget's manual, see
wget(1). The target url is the url wrote on the command line.
'--cut-dirs=number'
Do not apply to Metalink/XML files (aka --input-metalink=<file>).
Apply to Metalink/HTTP urls as described in the Wget's manual, see
wget(1). The target url is the url wrote on the command line.
'-P prefix'
'--directory-prefix=prefix'
Set the top of the retrieval tree to prefix for both Metalink/XML
and Metalink/HTTP downloads, see wget(1).
If combining the prefix with the file name results in an absolute,
relative, or home path, the directory components are stripped and
only the basename is used. See '4.1 Implemented safety features'.

View File

@@ -1,7 +1,7 @@
#! /usr/bin/env perl
# Copyright (C) 1999, 2000, 2001, 2003, 2007, 2009, 2010, 2011, 2015
# Free Software Foundation, Inc.
# Copyright (C) 1999-2001, 2003, 2007, 2009-2011, 2015, 2018 Free
# Software Foundation, Inc.
# This file is part of GCC.

View File

@@ -31,9 +31,8 @@ This file documents the GNU Wget utility for downloading network
data.
@c man begin COPYRIGHT
Copyright @copyright{} 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright @copyright{} 1996-2011, 2015, 2018 Free Software Foundation,
Inc.
@iftex
Permission is granted to make and distribute verbatim copies of
@@ -193,6 +192,8 @@ options, or via the initialization file @file{.wgetrc} (@pxref{Startup
File}). Wget allows you to define @dfn{global} startup files
(@file{/usr/local/etc/wgetrc} by default) for site settings. You can also
specify the location of a startup file with the --config option.
To disable the reading of config files, use --no-config.
If both --config and --no-config are given, --no-config is ignored.
@ignore
@@ -512,11 +513,27 @@ href if none was specified.
Downloads files covered in local Metalink @var{file}. Metalink version 3
and 4 are supported.
@cindex keep-badhash
@item --keep-badhash
Keeps downloaded Metalink's files with a bad hash. It appends .badhash
to the name of Metalink's files which have a checksum mismatch, except
without overwriting existing files.
@cindex metalink-over-http
@item --metalink-over-http
Issues HTTP HEAD request instead of GET and extracts Metalink metadata
from response headers. Then it switches to Metalink download.
If no valid Metalink metadata is found, it falls back to ordinary HTTP download.
Enables @samp{Content-Type: application/metalink4+xml} files download/processing.
@cindex metalink-index
@item --metalink-index=@var{number}
Set the Metalink @samp{application/metalink4+xml} metaurl ordinal
NUMBER. From 1 to the total number of ``application/metalink4+xml''
available. Specify 0 or @samp{inf} to choose the first good one.
Metaurls, such as those from a @samp{--metalink-over-http}, may have
been sorted by priority key's value; keep this in mind to choose the
right NUMBER.
@cindex preferred-location
@item --preferred-location
@@ -550,7 +567,10 @@ would be resolved to @samp{http://foo/baz/b.html}.
@cindex specify config
@item --config=@var{FILE}
Specify the location of a startup file you wish to use.
Specify the location of a startup file you wish to use instead of the
default one(s). Use --no-config to disable reading of config files.
If both --config and --no-config are given, --no-config is ignored.
@item --rejected-log=@var{logfile}
Logs all URL rejections to @var{logfile} as comma separated values. The values
@@ -571,6 +591,27 @@ the local machine. @var{ADDRESS} may be specified as a hostname or IP
address. This option can be useful if your machine is bound to multiple
IPs.
@cindex bind DNS address
@cindex client DNS address
@cindex DNS IP address, client, DNS
@item --bind-dns-address=@var{ADDRESS}
[libcares only]
This address overrides the route for DNS requests. If you ever need to
circumvent the standard settings from /etc/resolv.conf, this option together
with @samp{--dns-servers} is your friend.
@var{ADDRESS} must be specified either as IPv4 or IPv6 address.
Wget needs to be built with libcares for this option to be available.
@cindex DNS server
@cindex DNS IP address, client, DNS
@item --dns-servers=@var{ADDRESSES}
[libcares only]
The given address(es) override the standard nameserver
addresses, e.g. as configured in /etc/resolv.conf.
@var{ADDRESSES} may be specified either as IPv4 or IPv6 addresses,
comma-separated.
Wget needs to be built with libcares for this option to be available.
@cindex retries
@cindex tries
@cindex number of tries
@@ -666,6 +707,12 @@ Before (over)writing a file, back up an existing file by adding a
files are rotated to @samp{.2}, @samp{.3}, and so on, up to
@var{backups} (and lost beyond that).
@cindex authentication credentials
@item --no-netrc
Do not try to obtain credentials from @file{.netrc} file. By default
@file{.netrc} file is searched for credentials in case none have been
passed on command line and authentication is required.
@cindex continue retrieval
@cindex incomplete downloads
@cindex resume download
@@ -694,13 +741,11 @@ Without @samp{-c}, the previous example would just download the remote
file to @file{ls-lR.Z.1}, leaving the truncated @file{ls-lR.Z} file
alone.
Beginning with Wget 1.7, if you use @samp{-c} on a non-empty file, and
it turns out that the server does not support continued downloading,
Wget will refuse to start the download from scratch, which would
effectively ruin existing contents. If you really want the download to
start from scratch, remove the file.
If you use @samp{-c} on a non-empty file, and the server does not support
continued downloading, Wget will restart the download from scratch and overwrite
the existing file entirely.
Also beginning with Wget 1.7, if you use @samp{-c} on a file which is of
Beginning with Wget 1.7, if you use @samp{-c} on a file which is of
equal size as the one on the server, Wget will refuse to download the
file and print an explanatory message. The same happens when the file
is smaller on the server than locally (presumably because it was changed
@@ -783,7 +828,7 @@ With @samp{--progress=bar}, there are currently two possible parameters,
@var{force} and @var{noscroll}.
When the output is not a TTY, the progress bar always falls back to ``dot'',
even if @samp{--progress=bar} was passed to Wget during invokation. This
even if @samp{--progress=bar} was passed to Wget during invocation. This
behaviour can be overridden and the ``bar'' output forced by using the ``force''
parameter as @samp{--progress=bar:force}.
@@ -983,7 +1028,7 @@ specified in bytes (default), kilobytes (with @samp{k} suffix), or
megabytes (with @samp{m} suffix).
Note that quota will never affect downloading a single file. So if you
specify @samp{wget -Q10k ftp://wuarchive.wustl.edu/ls-lR.gz}, all of the
specify @samp{wget -Q10k https://example.com/ls-lR.gz}, all of the
@file{ls-lR.gz} will be downloaded. The same goes even when several
@sc{url}s are specified on the command-line. However, quota is
respected when retrieving either recursively, or from an input file.
@@ -1135,6 +1180,15 @@ options for @sc{http} connections.
Prompt for a password for each connection established. Cannot be specified
when @samp{--password} is being used, because they are mutually exclusive.
@item --use-askpass=@var{command}
Prompt for a user and password using the specified command. If no command is
specified then the command in the environment variable WGET_ASKPASS is used.
If WGET_ASKPASS is not set then the command in the environment variable
SSH_ASKPASS is used.
You can set the default command for use-askpass in the @file{.wgetrc}. That
setting may be overridden from the command line.
@cindex iri support
@cindex idn support
@item --no-iri
@@ -1291,6 +1345,11 @@ renamed from @samp{--html-extension}, to better reflect its new
behavior. The old option name is still acceptable, but should now be
considered deprecated.
As of version 1.19.2, Wget will also ensure that any downloaded files with
a @code{Content-Encoding} of @samp{br}, @samp{compress}, @samp{deflate}
or @samp{gzip} end in the suffix @samp{.br}, @samp{.Z}, @samp{.zlib}
and @samp{.gz} respectively.
At some point in the future, this option may well be expanded to
include suffixes for other types of content, including content types
that are not parsed by Wget.
@@ -1308,10 +1367,10 @@ the @code{digest}, or the Windows @code{NTLM} authentication scheme.
Another way to specify username and password is in the @sc{url} itself
(@pxref{URL Format}). Either method reveals your password to anyone who
bothers to run @code{ps}. To prevent the passwords from being seen,
store them in @file{.wgetrc} or @file{.netrc}, and make sure to protect
those files from other users with @code{chmod}. If the passwords are
really important, do not leave them lying in those files either---edit
the files and delete them after Wget has started the download.
use the @samp{--use-askpass} or store them in @file{.wgetrc} or @file{.netrc},
and make sure to protect those files from other users with @code{chmod}. If
the passwords are really important, do not leave them lying in those files
either---edit the files and delete them after Wget has started the download.
@iftex
@xref{Security Considerations}, for more information about security
@@ -1475,6 +1534,23 @@ wget --header="Host: foo.bar" http://localhost/
In versions of Wget prior to 1.10 such use of @samp{--header} caused
sending of duplicate headers.
@cindex Content-Encoding, choose
@item --compression=@var{type}
Choose the type of compression to be used. Legal values are
@samp{auto}, @samp{gzip} and @samp{none}.
If @samp{auto} or @samp{gzip} are specified, Wget asks the server to
compress the file using the gzip compression format. If the server
compresses the file and responds with the @code{Content-Encoding}
header field set appropriately, the file will be decompressed
automatically.
If @samp{none} is specified, wget will not ask the server to compress
the file and will not decompress any server responses. This is the default.
Compression support is currently experimental. In case it is turned on,
please report any bugs to @code{bug-wget@@gnu.org}.
@cindex redirect
@item --max-redirect=@var{number}
Specifies the maximum number of redirections to follow for a resource.
@@ -1586,11 +1662,11 @@ users:
# @r{Log in to the server. This can be done only once.}
wget --save-cookies cookies.txt \
--post-data 'user=foo&password=bar' \
http://server.com/auth.php
http://example.com/auth.php
# @r{Now grab the page or pages we care about.}
wget --load-cookies cookies.txt \
-p http://server.com/interesting/article.php
-p http://example.com/interesting/article.php
@end group
@end example
@@ -1643,6 +1719,10 @@ This option is useful for some file-downloading CGI programs that use
@code{Content-Disposition} headers to describe what the name of a
downloaded file should be.
When combined with @samp{--metalink-over-http} and @samp{--trust-server-names},
a @samp{Content-Type: application/metalink4+xml} file is named using the
@code{Content-Disposition} filename field, if available.
@cindex Content On Error
@item --content-on-error
@@ -1652,9 +1732,11 @@ with a http status code that indicates error.
@cindex Trust server names
@item --trust-server-names
If this is set to on, on a redirect the last component of the
redirection URL will be used as the local file name. By default it is
used the last component in the original URL.
If this is set, on a redirect, the local file name will be based
on the redirection URL. By default the local file name is based on
the original URL. When doing recursive retrieving this can be helpful
because in many web sites redirected URLs correspond to an underlying
file structure, while link URLs do not.
@cindex authentication
@item --auth-no-challenge
@@ -1668,6 +1750,21 @@ some few obscure servers, which never send HTTP authentication
challenges, but accept unsolicited auth info, say, in addition to
form-based authentication.
@item --retry-on-http-error=@var{code[,code,...]}
Consider given HTTP response codes as non-fatal, transient errors.
Supply a comma-separated list of 3-digit HTTP response codes as
argument. Useful to work around special circumstances where retries
are required, but the server responds with an error code normally not
retried by Wget. Such errors might be 503 (Service Unavailable) and
429 (Too Many Requests). Retries enabled by this option are performed
subject to the normal retry timing and retry count limitations of
Wget.
Using this option is intended to support special use cases only and is
generally not recommended, as it can force retries even in cases where
the server is actually trying to decrease its load. Please use wisely
and only if you know what you are doing.
@end table
@node HTTPS (SSL/TLS) Options, FTP Options, HTTP Options, Invoking
@@ -1725,6 +1822,12 @@ this option to bypass the verification and proceed with the download.
site's authenticity, or if you really don't care about the validity of
its certificate.} It is almost always a bad idea not to check the
certificates when transmitting confidential or important data.
For self-signed/internal certificates, you should download the certificate
and verify against that instead of forcing this insecure mode.
If you are really sure of not desiring any certificate verification, you
can specify --check-certificate=quiet to tell wget to not print any
warning about invalid certificates, albeit in most cases this is the
wrong thing to do.
@cindex SSL certificate
@item --certificate=@var{file}
@@ -1772,6 +1875,18 @@ system-specified locations, chosen at OpenSSL installation time.
Specifies a CRL file in @var{file}. This is needed for certificates
that have been revocated by the CAs.
@cindex SSL Public Key Pin
@item --pinnedpubkey=file/hashes
Tells wget to use the specified public key file (or hashes) to verify the peer.
This can be a path to a file which contains a single public key in PEM or DER
format, or any number of base64 encoded sha256 hashes preceded by ``sha256//''
and separated by ``;''
When negotiating a TLS or SSL connection, the server sends a certificate
indicating its identity. A public key is extracted from this certificate and if
it does not exactly match the public key(s) provided to this option, wget will
abort the connection before sending or receiving any data.
@cindex entropy, specifying source of
@cindex randomness, specifying source of
@item --random-file=@var{file}
@@ -2555,11 +2670,11 @@ The @samp{-D} option allows you to specify the domains that will be
followed, thus limiting the recursion only to the hosts that belong to
these domains. Obviously, this makes sense only in conjunction with
@samp{-H}. A typical example would be downloading the contents of
@samp{www.server.com}, but allowing downloads from
@samp{images.server.com}, etc.:
@samp{www.example.com}, but allowing downloads from
@samp{images.example.com}, etc.:
@example
wget -rH -Dserver.com http://www.server.com/
wget -rH -Dexample.com http://www.example.com/
@end example
You can specify more than one address by separating them with a comma,
@@ -2799,7 +2914,7 @@ These links are not relative:
@example
<a href="/foo.gif">
<a href="/foo/bar.gif">
<a href="http://www.server.com/foo/bar.gif">
<a href="http://www.example.com/foo/bar.gif">
@end example
Using this option guarantees that recursive retrieval will not span
@@ -3162,8 +3277,8 @@ Turn on recognition of the (non-standard) @samp{Content-Disposition}
HTTP header---if set to @samp{on}, the same as @samp{--content-disposition}.
@item trust_server_names = on/off
If set to on, use the last component of a redirection URL for the local
file name.
If set to on, construct the local file name from redirection URLs
rather than original URLs.
@item continue = on/off
If set to on, force continuation of preexistent partially retrieved
@@ -3269,10 +3384,16 @@ Turn globbing on/off---the same as @samp{--glob} and @samp{--no-glob}.
Define a header for HTTP downloads, like using
@samp{--header=@var{string}}.
@item compression = @var{string}
Choose the compression type to be used. Legal values are @samp{auto}
(the default), @samp{gzip}, and @samp{none}. The same as
@samp{--compression=@var{string}}.
@item adjust_extension = on/off
Add a @samp{.html} extension to @samp{text/html} or
@samp{application/xhtml+xml} files that lack one, or a @samp{.css}
extension to @samp{text/css} files that lack one, like
@samp{application/xhtml+xml} files that lack one, a @samp{.css}
extension to @samp{text/css} files that lack one, and a @samp{.br},
@samp{.Z}, @samp{.zlib} or @samp{.gz} to compressed files like
@samp{-E}. Previously named @samp{html_extension} (still acceptable,
but deprecated).
@@ -3669,7 +3790,7 @@ same directory structure the original has, with only one try per
document, saving the log of the activities to @file{gnulog}:
@example
wget -r http://www.gnu.org/ -o gnulog
wget -r https://www.gnu.org/ -o gnulog
@end example
@item
@@ -3677,7 +3798,7 @@ The same as the above, but convert the links in the downloaded files to
point to local files, so you can view the documents off-line:
@example
wget --convert-links -r http://www.gnu.org/ -o gnulog
wget --convert-links -r https://www.gnu.org/ -o gnulog
@end example
@item
@@ -3687,22 +3808,22 @@ sheets, are also downloaded. Also make sure the downloaded page
references the downloaded links.
@example
wget -p --convert-links http://www.server.com/dir/page.html
wget -p --convert-links http://www.example.com/dir/page.html
@end example
The @sc{html} page will be saved to @file{www.server.com/dir/page.html}, and
the images, stylesheets, etc., somewhere under @file{www.server.com/},
The @sc{html} page will be saved to @file{www.example.com/dir/page.html}, and
the images, stylesheets, etc., somewhere under @file{www.example.com/},
depending on where they were on the remote server.
@item
The same as the above, but without the @file{www.server.com/} directory.
The same as the above, but without the @file{www.example.com/} directory.
In fact, I don't want to have all those random server directories
anyway---just save @emph{all} those files under a @file{download/}
subdirectory of the current directory.
@example
wget -p --convert-links -nH -nd -Pdownload \
http://www.server.com/dir/page.html
http://www.example.com/dir/page.html
@end example
@item
@@ -3731,12 +3852,12 @@ wget -r -l2 -P/tmp ftp://wuarchive.wustl.edu/
@item
You want to download all the @sc{gif}s from a directory on an @sc{http}
server. You tried @samp{wget http://www.server.com/dir/*.gif}, but that
server. You tried @samp{wget http://www.example.com/dir/*.gif}, but that
didn't work because @sc{http} retrieval does not support globbing. In
that case, use:
@example
wget -r -l1 --no-parent -A.gif http://www.server.com/dir/
wget -r -l1 --no-parent -A.gif http://www.example.com/dir/
@end example
More verbose, but the effect is the same. @samp{-r -l1} means to
@@ -3752,7 +3873,7 @@ interrupted. Now you do not want to clobber the files already present.
It would be:
@example
wget -nc -r http://www.gnu.org/
wget -nc -r https://www.gnu.org/
@end example
@item
@@ -3760,7 +3881,7 @@ If you want to encode your own username and password to @sc{http} or
@sc{ftp}, use the appropriate @sc{url} syntax (@pxref{URL Format}).
@example
wget ftp://hniksic:mypassword@@unix.server.com/.emacs
wget ftp://hniksic:mypassword@@unix.example.com/.emacs
@end example
Note, however, that this usage is not advisable on multi-user systems
@@ -3797,7 +3918,7 @@ to recheck a site each Sunday:
@example
crontab
0 0 * * 0 wget --mirror http://www.gnu.org/ -o /home/me/weeklog
0 0 * * 0 wget --mirror https://www.gnu.org/ -o /home/me/weeklog
@end example
@item
@@ -3809,7 +3930,7 @@ would look like this:
@example
wget --mirror --convert-links --backup-converted \
http://www.gnu.org/ -o /home/me/weeklog
https://www.gnu.org/ -o /home/me/weeklog
@end example
@item
@@ -3822,13 +3943,13 @@ or @samp{application/xhtml+xml} to @file{@var{name}.html}.
@example
wget --mirror --convert-links --backup-converted \
--html-extension -o /home/me/weeklog \
http://www.gnu.org/
https://www.gnu.org/
@end example
Or, with less typing:
@example
wget -m -k -K -E http://www.gnu.org/ -o /home/me/weeklog
wget -m -k -K -E https://www.gnu.org/ -o /home/me/weeklog
@end example
@end itemize
@c man end
@@ -3935,14 +4056,14 @@ username and password.
Like all GNU utilities, the latest version of Wget can be found at the
master GNU archive site ftp.gnu.org, and its mirrors. For example,
Wget @value{VERSION} can be found at
@url{ftp://ftp.gnu.org/pub/gnu/wget/wget-@value{VERSION}.tar.gz}
@url{https://ftp.gnu.org/pub/gnu/wget/wget-@value{VERSION}.tar.gz}
@node Web Site, Mailing Lists, Distribution, Various
@section Web Site
@cindex web site
The official web site for GNU Wget is at
@url{http://www.gnu.org/software/wget/}. However, most useful
@url{https//www.gnu.org/software/wget/}. However, most useful
information resides at ``The Wget Wgiki'',
@url{http://wget.addictivecode.org/}.
@@ -3956,14 +4077,14 @@ information resides at ``The Wget Wgiki'',
The primary mailinglist for discussion, bug-reports, or questions
about GNU Wget is at @email{bug-wget@@gnu.org}. To subscribe, send an
email to @email{bug-wget-join@@gnu.org}, or visit
@url{http://lists.gnu.org/mailman/listinfo/bug-wget}.
@url{https://lists.gnu.org/mailman/listinfo/bug-wget}.
You do not need to subscribe to send a message to the list; however,
please note that unsubscribed messages are moderated, and may take a
while before they hit the list---@strong{usually around a day}. If
you want your message to show up immediately, please subscribe to the
list before posting. Archives for the list may be found at
@url{http://lists.gnu.org/pipermail/bug-wget/}.
@url{https://lists.gnu.org/archive/html/bug-wget/}.
An NNTP/Usenettish gateway is also available via
@uref{http://gmane.org/about.php,Gmane}. You can see the Gmane
@@ -3971,15 +4092,7 @@ archives at
@url{http://news.gmane.org/gmane.comp.web.wget.general}. Note that the
Gmane archives conveniently include messages from both the current
list, and the previous one. Messages also show up in the Gmane
archives sooner than they do at @url{lists.gnu.org}.
@unnumberedsubsec Bug Notices List
Additionally, there is the @email{wget-notify@@addictivecode.org} mailing
list. This is a non-discussion list that receives bug report
notifications from the bug-tracker. To subscribe to this list,
send an email to @email{wget-notify-join@@addictivecode.org},
or visit @url{http://addictivecode.org/mailman/listinfo/wget-notify}.
archives sooner than they do at @url{https://lists.gnu.org}.
@unnumberedsubsec Obsolete Lists
@@ -3991,7 +4104,7 @@ discussing patches to GNU Wget.
Messages from @email{wget@@sunsite.dk} are archived at
@itemize @tie{}
@item
@url{http://www.mail-archive.com/wget%40sunsite.dk/} and at
@url{https://www.mail-archive.com/wget%40sunsite.dk/} and at
@item
@url{http://news.gmane.org/gmane.comp.web.wget.general} (which also
continues to archive the current list, @email{bug-wget@@gnu.org}).
@@ -4020,7 +4133,7 @@ via IRC at @code{irc.freenode.org}, @code{#wget}. Come check it out!
@c man begin BUGS
You are welcome to submit bug reports via the GNU Wget bug tracker (see
@url{http://wget.addictivecode.org/BugTracker}).
@url{https://savannah.gnu.org/bugs/?func=additem&group=wget}).
Before actually submitting a bug report, please try to follow a few
simple guidelines.
@@ -4037,7 +4150,7 @@ Lists}).
@item
Try to repeat the bug in as simple circumstances as possible. E.g. if
Wget crashes while downloading @samp{wget -rl0 -kKE -t5 --no-proxy
http://yoyodyne.com -o /tmp/log}, you should try to see if the crash is
http://example.com -o /tmp/log}, you should try to see if the crash is
repeatable, and if will occur with a simpler set of options. You might
even try to start the download at the page where the crash occurred to
see if that page somehow triggered the crash.
@@ -4102,7 +4215,7 @@ Windows-related features might look at them.
Support for building on MS-DOS via DJGPP has been contributed by Gisle
Vanem; a port to VMS is maintained by Steven Schweda, and is available
at @url{http://antinode.org/}.
at @url{https://antinode.info/dec/sw/wget.html}.
@node Signals, , Portability, Various
@section Signals
@@ -4180,23 +4293,23 @@ download an individual page. Because of that, Wget honors RES when
downloading recursively. For instance, when you issue:
@example
wget -r http://www.server.com/
wget -r http://www.example.com/
@end example
First the index of @samp{www.server.com} will be downloaded. If Wget
First the index of @samp{www.example.com} will be downloaded. If Wget
finds that it wants to download more documents from that server, it will
request @samp{http://www.server.com/robots.txt} and, if found, use it
request @samp{http://www.example.com/robots.txt} and, if found, use it
for further downloads. @file{robots.txt} is loaded only once per each
server.
Until version 1.8, Wget supported the first version of the standard,
written by Martijn Koster in 1994 and available at
@url{http://www.robotstxt.org/wc/norobots.html}. As of version 1.8,
@url{http://www.robotstxt.org/orig.html}. As of version 1.8,
Wget has supported the additional directives specified in the internet
draft @samp{<draft-koster-robots-00.txt>} titled ``A Method for Web
Robots Control''. The draft, which has as far as I know never made to
an @sc{rfc}, is available at
@url{http://www.robotstxt.org/wc/norobots-rfc.txt}.
@url{http://www.robotstxt.org/norobots-rfc.txt}.
This manual no longer includes the text of the Robot Exclusion Standard.
@@ -4210,7 +4323,7 @@ this:
@end example
This is explained in some detail at
@url{http://www.robotstxt.org/wc/meta-user.html}. Wget supports this
@url{http://www.robotstxt.org/meta.html}. Wget supports this
method of robot exclusion in addition to the usual @file{/robots.txt}
exclusion.

2
gnulib

Submodule gnulib updated: 9c919a0643...73b4150cce

View File

@@ -1,5 +1,5 @@
# exitfail.m4 serial 6
dnl Copyright (C) 2002, 2003, 2005, 2006, 2010, 2011 Free Software
dnl Copyright (C) 2002-2003, 2005-2006, 2010-2011, 2018 Free Software
dnl Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,

View File

@@ -1,5 +1,5 @@
# getpagesize.m4 serial 7
dnl Copyright (C) 2002, 2004, 2005, 2007, 2010, 2011 Free Software
dnl Copyright (C) 2002, 2004-2005, 2007, 2010-2011, 2018 Free Software
dnl Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,

View File

@@ -1,7 +1,6 @@
dnl A placeholder for ISO C99 <wchar.h>, for platforms that have issues.
dnl Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
dnl Inc.
dnl Copyright (C) 2007-2011, 2018 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.

View File

@@ -2,7 +2,7 @@
dnl A placeholder for ISO C99 <wctype.h>, for platforms that lack it.
dnl Copyright (C) 2006, 2007, 2008, 2010, 2011 Free Software Foundation,
dnl Copyright (C) 2006-2008, 2010-2011, 2018 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,

View File

@@ -1,7 +1,5 @@
dnl Wget-specific Autoconf macros.
dnl Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
dnl 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
dnl Foundation, Inc.
dnl Copyright (C) 1995-2011, 2018 Free Software Foundation, Inc.
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
@@ -27,89 +25,6 @@ dnl Corresponding Source for a non-source form of such a combination
dnl shall include the source code for the parts of OpenSSL used as well
dnl as that of the covered work.
dnl
dnl Check for `struct utimbuf'.
dnl
AC_DEFUN([WGET_STRUCT_UTIMBUF], [
AC_CHECK_TYPES([struct utimbuf], [], [], [
#include <stdio.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_UTIME_H
# include <utime.h>
#endif
])
])
dnl Check whether fnmatch.h can be included. This doesn't use
dnl AC_FUNC_FNMATCH because Wget is already careful to only use
dnl fnmatch on certain OS'es. However, fnmatch.h is sometimes broken
dnl even on those because Apache installs its own fnmatch.h to
dnl /usr/local/include (!), which GCC uses before /usr/include.
AC_DEFUN([WGET_FNMATCH], [
AC_MSG_CHECKING([for working fnmatch.h])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([#include <fnmatch.h>
])], [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_WORKING_FNMATCH_H], 1,
[Define if fnmatch.h can be included.])
], [
AC_MSG_RESULT(no)
])
])
dnl Check for nanosleep. For nanosleep to work on Solaris, we must
dnl link with -lrt (recently) or with -lposix4 (older releases).
AC_DEFUN([WGET_NANOSLEEP], [
AC_CHECK_FUNCS(nanosleep, [], [
AC_CHECK_LIB(rt, nanosleep, [
AC_DEFINE([HAVE_NANOSLEEP], 1,
[Define if you have the nanosleep function.])
LIBS="-lrt $LIBS"
], [
AC_CHECK_LIB(posix4, nanosleep, [
AC_DEFINE([HAVE_NANOSLEEP], 1,
[Define if you have the nanosleep function.])
LIBS="-lposix4 $LIBS"
])
])
])
])
AC_DEFUN([WGET_POSIX_CLOCK], [
AC_CHECK_FUNCS(clock_gettime, [], [
AC_CHECK_LIB(rt, clock_gettime)
])
])
dnl Check whether we need to link with -lnsl and -lsocket, as is the
dnl case on e.g. Solaris.
AC_DEFUN([WGET_NSL_SOCKET], [
dnl On Solaris, -lnsl is needed to use gethostbyname. But checking
dnl for gethostbyname is not enough because on "NCR MP-RAS 3.0"
dnl gethostbyname is in libc, but -lnsl is still needed to use
dnl -lsocket, as well as for functions such as inet_ntoa. We look
dnl for such known offenders and if one of them is not found, we
dnl check if -lnsl is needed.
wget_check_in_nsl=NONE
AC_CHECK_FUNCS(gethostbyname, [], [
wget_check_in_nsl=gethostbyname
])
AC_CHECK_FUNCS(inet_ntoa, [], [
wget_check_in_nsl=inet_ntoa
])
if test $wget_check_in_nsl != NONE; then
AC_CHECK_LIB(nsl, $wget_check_in_nsl)
fi
AC_CHECK_LIB(socket, socket)
])
dnl ************************************************************
dnl START OF IPv6 AUTOCONFIGURATION SUPPORT MACROS
dnl ************************************************************

View File

@@ -1,7 +1,5 @@
# List of files which containing translatable strings.
# Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
# 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Foundation, Inc.
# Copyright (C) 1995-2011, 2018 Free Software Foundation, Inc.
# Package source files
lib/error.c
@@ -35,7 +33,6 @@ src/ptimer.c
src/recur.c
src/res.c
src/retr.c
src/spider.c
src/url.c
src/utils.c
src/warc.c

View File

@@ -1,7 +1,5 @@
# Makefile for `wget' utility
# Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
# 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
# Foundation, Inc.
# Copyright (C) 1995-2011, 2015, 2018 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -39,9 +37,12 @@ if METALINK_IS_ENABLED
METALINK_OBJ = metalink.c
endif
if WITH_XATTR
XATTR_OBJ = xattr.c
endif
# The following line is losing on some versions of make!
DEFS = @DEFS@ -DSYSTEM_WGETRC=\"$(sysconfdir)/wgetrc\" -DLOCALEDIR=\"$(localedir)\"
LIBS = @LIBICONV@ @LIBINTL@ @LIBS@ $(LIB_CLOCK_GETTIME)
EXTRA_DIST = css.l css.c css_.c build_info.c.in
@@ -50,17 +51,20 @@ wget_SOURCES = connect.c convert.c cookies.c ftp.c \
css_.c css-url.c \
ftp-basic.c ftp-ls.c hash.c host.c hsts.c html-parse.c html-url.c \
http.c init.c log.c main.c netrc.c progress.c ptimer.c \
recur.c res.c retr.c spider.c url.c warc.c \
recur.c res.c retr.c spider.c url.c warc.c $(XATTR_OBJ) \
utils.c exits.c build_info.c $(IRI_OBJ) $(METALINK_OBJ) \
css-url.h css-tokens.h connect.h convert.h cookies.h \
ftp.h hash.h host.h hsts.h html-parse.h html-url.h \
http.h http-ntlm.h init.h log.h mswindows.h netrc.h \
options.h progress.h ptimer.h recur.h res.h retr.h \
spider.h ssl.h sysdep.h url.h warc.h utils.h wget.h iri.h \
exits.h version.h metalink.h
exits.h version.h metalink.h xattr.h
nodist_wget_SOURCES = version.c
EXTRA_wget_SOURCES = iri.c
LDADD = $(LIBOBJS) ../lib/libgnu.a
LDADD = $(LIBOBJS) ../lib/libgnu.a $(GETADDRINFO_LIB) $(HOSTENT_LIB)\
$(INET_NTOP_LIB) $(LIBSOCKET) $(LIB_CLOCK_GETTIME) $(LIB_CRYPTO)\
$(LIB_NANOSLEEP) $(LIB_POSIX_SPAWN) $(LIB_SELECT) $(LIBICONV) $(LIBINTL)\
$(LIBTHREAD) $(LIBUNISTRING) $(SERVENT_LIB)
AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib

View File

@@ -8,6 +8,10 @@ nls defined ENABLE_NLS
ntlm defined ENABLE_NTLM
opie defined ENABLE_OPIE
psl defined HAVE_LIBPSL
cares defined HAVE_LIBCARES
metalink defined HAVE_METALINK
gpgme defined HAVE_GPGME
ssl choice:
openssl defined HAVE_LIBSSL || defined HAVE_LIBSSL32

View File

@@ -1,7 +1,5 @@
/* Establishing and handling network connections.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1995-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -31,6 +29,7 @@ as that of the covered work. */
#include "wget.h"
#include "exits.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -55,10 +54,6 @@ as that of the covered work. */
#include <string.h>
#include <sys/time.h>
#ifdef ENABLE_IRI
#include <idn-free.h>
#endif
#include "utils.h"
#include "host.h"
#include "connect.h"
@@ -279,11 +274,8 @@ connect_to_ip (const ip_address *ip, int port, const char *print)
if (opt.enable_iri && (name = idn_decode ((char *) print)) != NULL)
{
int len = strlen (print) + strlen (name) + 4;
str = xmalloc (len);
snprintf (str, len, "%s (%s)", name, print);
str[len-1] = '\0';
idn_free (name);
str = aprintf ("%s (%s)", name, print);
xfree (name);
}
logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "),
@@ -331,8 +323,10 @@ connect_to_ip (const ip_address *ip, int port, const char *print)
if (bufsize < 512)
bufsize = 512; /* avoid pathologically small values */
#ifdef SO_RCVBUF
setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
(void *)&bufsize, (socklen_t)sizeof (bufsize));
if (setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
(void *) &bufsize, (socklen_t) sizeof (bufsize)))
logprintf (LOG_NOTQUIET, _("setsockopt SO_RCVBUF failed: %s\n"),
strerror (errno));
#endif
/* When we add limit_rate support for writing, which is useful
for POST, we should also set SO_SNDBUF here. */
@@ -369,7 +363,14 @@ connect_to_ip (const ip_address *ip, int port, const char *print)
logprintf. */
int save_errno = errno;
if (sock >= 0)
fd_close (sock);
{
#ifdef WIN32
/* If the connection timed out, fd_close will hang in Gnulib's
close_fd_maybe_socket, inside the call to WSAEnumNetworkEvents. */
if (errno != ETIMEDOUT)
#endif
fd_close (sock);
}
if (print)
logprintf (LOG_NOTQUIET, _("failed: %s.\n"), strerror (errno));
errno = save_errno;
@@ -464,7 +465,9 @@ bind_local (const ip_address *bind_address, int *port)
return -1;
#ifdef SO_REUSEADDR
setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, setopt_ptr, setopt_size);
if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, setopt_ptr, setopt_size))
logprintf (LOG_NOTQUIET, _("setsockopt SO_REUSEADDR failed: %s\n"),
strerror (errno));
#endif
xzero (ss);
@@ -682,6 +685,11 @@ select_fd (int fd, double maxtime, int wait_for)
struct timeval tmout;
int result;
if (fd >= FD_SETSIZE)
{
logprintf (LOG_NOTQUIET, _("Too many fds open. Cannot use select on a fd >= %d\n"), FD_SETSIZE);
exit (WGET_EXIT_GENERIC_ERROR);
}
FD_ZERO (&fdset);
FD_SET (fd, &fdset);
if (wait_for & WAIT_FOR_READ)
@@ -724,6 +732,11 @@ test_socket_open (int sock)
struct timeval to;
int ret = 0;
if (sock >= FD_SETSIZE)
{
logprintf (LOG_NOTQUIET, _("Too many fds open. Cannot use select on a fd >= %d\n"), FD_SETSIZE);
exit (WGET_EXIT_GENERIC_ERROR);
}
/* Check if we still have a valid (non-EOF) connection. From Andrew
* Maholski's code in the Unix Socket FAQ. */

View File

@@ -1,7 +1,5 @@
/* Declarations for connect.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,6 +1,6 @@
/* Conversion of links to local files.
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
2014, 2015 Free Software Foundation, Inc.
Copyright (C) 2003-2011, 2014-2015, 2018 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -308,7 +308,7 @@ convert_links (const char *file, struct urlpos *links)
char *quoted_newname = local_quote_string (newname,
link->link_css_p);
if (link->link_css_p)
if (link->link_css_p || link->link_noquote_html_p)
p = replace_plain (p, link->size, fp, quoted_newname);
else if (!link->link_refresh_p)
p = replace_attr (p, link->size, fp, quoted_newname);
@@ -329,7 +329,7 @@ convert_links (const char *file, struct urlpos *links)
char *newname = convert_basename (p, link);
char *quoted_newname = local_quote_string (newname, link->link_css_p);
if (link->link_css_p)
if (link->link_css_p || link->link_noquote_html_p)
p = replace_plain (p, link->size, fp, quoted_newname);
else if (!link->link_refresh_p)
p = replace_attr (p, link->size, fp, quoted_newname);
@@ -352,7 +352,7 @@ convert_links (const char *file, struct urlpos *links)
char *newlink = link->url->url;
char *quoted_newlink = html_quote_string (newlink);
if (link->link_css_p)
if (link->link_css_p || link->link_noquote_html_p)
p = replace_plain (p, link->size, fp, newlink);
else if (!link->link_refresh_p)
p = replace_attr (p, link->size, fp, quoted_newlink);
@@ -1024,7 +1024,7 @@ convert_cleanup (void)
/* This table should really be merged with dl_file_url_map and
downloaded_html_files. This was originally a list, but I changed
it to a hash table beause it was actually taking a lot of time to
it to a hash table because it was actually taking a lot of time to
find things in it. */
static struct hash_table *downloaded_files_hash;

View File

@@ -1,6 +1,6 @@
/* Declarations for convert.c
Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
Copyright (C) 2003-2006, 2009-2011, 2015, 2018 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -69,6 +69,7 @@ struct urlpos {
unsigned int link_base_p :1; /* the url came from <base href=...> */
unsigned int link_inline_p :1; /* needed to render the page */
unsigned int link_css_p :1; /* the url came from CSS */
unsigned int link_noquote_html_p :1; /* from HTML, but doesn't need " */
unsigned int link_expect_html :1; /* expected to contain HTML */
unsigned int link_expect_css :1; /* expected to contain CSS */

View File

@@ -1,6 +1,5 @@
/* Support for cookies.
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010, 2011, 2015 Free Software Foundation, Inc.
Copyright (C) 2001-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -45,6 +44,7 @@ as that of the covered work. */
#include "wget.h"
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -484,7 +484,7 @@ parse_set_cookie (const char *set_cookie, bool silent)
/* Check whether ADDR matches <digits>.<digits>.<digits>.<digits>.
We don't want to call network functions like inet_addr() because
all we need is a check, preferrably one that is small, fast, and
all we need is a check, preferably one that is small, fast, and
well-defined. */
static bool
@@ -515,7 +515,7 @@ numeric_address_p (const char *addr)
psl on our own, if libpsl is compiled without a public suffix list,
fall back to using the original "tail matching" heuristic. Also if
libpsl is unable to convert the domain to lowercase, which means that
it doesnt have any runtime conversion support, we again fall back to
it doesn't have any runtime conversion support, we again fall back to
"tail matching" since libpsl states the results are unpredictable with
upper case strings.
*/
@@ -525,19 +525,51 @@ check_domain_match (const char *cookie_domain, const char *host)
{
#ifdef HAVE_LIBPSL
static int init_psl;
static const psl_ctx_t *psl;
char *cookie_domain_lower = NULL;
char *host_lower = NULL;
const psl_ctx_t *psl;
int is_acceptable;
DEBUGP (("cdm: 1"));
if (!(psl = psl_builtin()))
DEBUGP (("cdm: 1\n"));
if (!init_psl)
{
DEBUGP (("\nlibpsl not built with a public suffix list. "
"Falling back to simple heuristics.\n"));
goto no_psl;
}
init_psl = 1;
#ifdef HAVE_PSL_LATEST
if ((psl = psl_latest (NULL)))
goto have_psl;
DEBUGP (("\nPSL: Failed to load any PSL data. "
"Falling back to insecure heuristics.\n"));
#else
if ((psl = psl_builtin ()) && !psl_builtin_outdated ())
goto have_psl;
DEBUGP (("\nPSL: built-in data outdated. "
"Trying to load data from %s.\n",
quote (psl_builtin_filename ())));
if ((psl = psl_load_file (psl_builtin_filename ())))
goto have_psl;
DEBUGP (("\nPSL: %s not found or not readable. "
"Falling back to built-in data.\n",
quote (psl_builtin_filename ())));
if (!(psl = psl_builtin ()))
{
DEBUGP (("\nPSL: libpsl not built with a public suffix list. "
"Falling back to insecure heuristics.\n"));
goto no_psl;
}
#endif
}
else if (!psl)
goto no_psl;
have_psl:
if (psl_str_to_utf8lower (cookie_domain, NULL, NULL, &cookie_domain_lower) == PSL_SUCCESS &&
psl_str_to_utf8lower (host, NULL, NULL, &host_lower) == PSL_SUCCESS)
{
@@ -562,13 +594,13 @@ no_psl:
#endif
/* For efficiency make some elementary checks first */
DEBUGP (("cdm: 2"));
DEBUGP (("cdm: 2\n"));
/* For the sake of efficiency, check for exact match first. */
if (0 == strcasecmp (cookie_domain, host))
return true;
DEBUGP ((" 3"));
DEBUGP (("cdm: 3\n"));
/* HOST must match the tail of cookie_domain. */
if (!match_tail (host, cookie_domain, true))
@@ -608,7 +640,7 @@ no_psl:
if (*p == '.')
/* Ignore leading period in this calculation. */
++p;
DEBUGP ((" 4"));
DEBUGP (("cdm: 4\n"));
for (out = 0; !out; p++)
switch (*p)
{
@@ -634,12 +666,12 @@ no_psl:
++ldcl;
}
DEBUGP ((" 5"));
DEBUGP (("cdm: 5\n"));
if (dccount < 2)
return false;
DEBUGP ((" 6"));
DEBUGP (("cdm: 6\n"));
if (dccount == 2)
{
@@ -659,7 +691,7 @@ no_psl:
}
}
DEBUGP ((" 7"));
DEBUGP (("cdm: 7\n"));
/* Don't allow the host "foobar.com" to set a cookie for domain
"bar.com". */
@@ -674,7 +706,7 @@ no_psl:
return false;
}
DEBUGP ((" 8"));
DEBUGP (("cdm: 8\n"));
return true;
}
@@ -1018,7 +1050,7 @@ cookie_header (struct cookie_jar *jar, const char *host,
struct cookie *cookie;
struct weighed_cookie *outgoing;
int count, i, ocnt;
size_t count, i, ocnt;
char *result;
int result_size, pos;
PREPEND_SLASH (path); /* see cookie_handle_set_cookie */
@@ -1032,7 +1064,7 @@ cookie_header (struct cookie_jar *jar, const char *host,
chain_count = find_chains_of_host (jar, host, chains);
/* No cookies for this host. */
if (!chain_count)
if (chain_count <= 0)
return NULL;
cookies_now = time (NULL);
@@ -1043,7 +1075,7 @@ cookie_header (struct cookie_jar *jar, const char *host,
/* Count the number of matching cookies. */
count = 0;
for (i = 0; i < chain_count; i++)
for (i = 0; i < (unsigned) chain_count; i++)
for (cookie = chains[i]; cookie; cookie = cookie->next)
if (cookie_matches_url (cookie, host, port, path, secflag, NULL))
++count;
@@ -1051,12 +1083,14 @@ cookie_header (struct cookie_jar *jar, const char *host,
return NULL; /* no cookies matched */
/* Allocate the array. */
outgoing = alloca_array (struct weighed_cookie, count);
if (count > SIZE_MAX / sizeof (struct weighed_cookie))
return NULL; /* unable to process so many cookies */
outgoing = xmalloc (count * sizeof (struct weighed_cookie));
/* Fill the array with all the matching cookies from the chains that
match HOST. */
ocnt = 0;
for (i = 0; i < chain_count; i++)
for (i = 0; i < (unsigned) chain_count; i++)
for (cookie = chains[i]; cookie; cookie = cookie->next)
{
int pg;
@@ -1111,6 +1145,7 @@ cookie_header (struct cookie_jar *jar, const char *host,
}
}
result[pos++] = '\0';
xfree (outgoing);
assert (pos == result_size);
return result;
}

View File

@@ -1,6 +1,5 @@
/* Support for cookies.
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010, 2011, 2015 Free Software Foundation, Inc.
Copyright (C) 2001-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,5 +1,5 @@
/* Declarations for css.lex
Copyright (C) 2006, 2009, 2010, 2011, 2015 Free Software Foundation,
Copyright (C) 2006, 2009-2011, 2015, 2018 Free Software Foundation,
Inc.
This file is part of GNU Wget.

View File

@@ -1,6 +1,6 @@
/* Collect URLs from CSS source.
Copyright (C) 1998, 2000, 2001, 2002, 2003, 2009, 2010, 2011, 2014,
2015 Free Software Foundation, Inc.
Copyright (C) 1998, 2000-2003, 2009-2011, 2014-2015, 2018 Free
Software Foundation, Inc.
This file is part of GNU Wget.
@@ -59,6 +59,7 @@ extern char *yytext;
extern int yyleng;
typedef struct yy_buffer_state *YY_BUFFER_STATE;
extern YY_BUFFER_STATE yy_scan_bytes (const char *bytes,int len );
extern void yy_delete_buffer (YY_BUFFER_STATE b);
extern int yylex (void);
/*
@@ -109,9 +110,10 @@ get_urls_css (struct map_context *ctx, int offset, int buf_length)
int buffer_pos = 0;
int pos, length;
char *uri;
YY_BUFFER_STATE b;
/* tell flex to scan from this buffer */
yy_scan_bytes (ctx->text + offset, buf_length);
b = yy_scan_bytes (ctx->text + offset, buf_length);
while((token = yylex()) != CSSEOF)
{
@@ -188,6 +190,9 @@ get_urls_css (struct map_context *ctx, int offset, int buf_length)
}
buffer_pos += yyleng;
}
yy_delete_buffer(b);
DEBUGP (("\n"));
}

View File

@@ -1,5 +1,5 @@
/* Declarations for css-url.c.
Copyright (C) 2006, 2009, 2010, 2011, 2015 Free Software Foundation,
Copyright (C) 2006, 2009-2011, 2015, 2018 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -31,7 +31,6 @@ as that of the covered work. */
#ifndef CSS_URL_H
#define CSS_URL_H
void get_urls_css (struct map_context *, int, int);
void get_urls_css (struct map_context *, int, int);
struct urlpos *get_urls_css_file (const char *, const char *);

View File

@@ -6,7 +6,7 @@
%{
/* Lex source for CSS tokenizing.
Taken from http://www.w3.org/TR/CSS21/grammar.html#q2
Copyright (C) 2006, 2009, 2010, 2011, 2015 Free Software Foundation,
Copyright (C) 2006, 2009-2011, 2015, 2018 Free Software Foundation,
Inc.
This file is part of GNU Wget.

View File

@@ -1,6 +1,5 @@
/* Exit status handling.
Copyright (C) 2009, 2010, 2011, 2012, 2015 Free Software Foundation,
Inc.
Copyright (C) 2009-2012, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,6 +1,5 @@
/* Exit status related declarations.
Copyright (C) 2009, 2010, 2011, 2012, 2015 Free Software Foundation,
Inc.
Copyright (C) 2009-2012, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,7 +1,6 @@
/* Basic FTP routines.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2014-2015, 2018 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -429,6 +428,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 +600,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. */

View File

@@ -1,7 +1,5 @@
/* Parsing FTP `ls' output.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -167,12 +165,12 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
/*cur.perms = 1023;*/ /* #### What is this? --hniksic */
cur.perms = 0644;
}
DEBUGP (("implicit perms %0o; ", cur.perms));
DEBUGP (("implicit perms %0o; ", (unsigned) cur.perms));
}
else
{
cur.perms = symperms (tok + 1);
DEBUGP (("perms %0o; ", cur.perms));
DEBUGP (("perms %0o; ", (unsigned) cur.perms));
}
error = ignore = 0; /* Erroneous and ignoring entries are
@@ -478,6 +476,7 @@ ftp_parse_winnt_ls (const char *file)
}
/* Now it is possible to determine the position of the first symbol in
filename. */
memset(&cur, 0, sizeof (cur));
cur.name = xstrdup(filename);
DEBUGP (("Name: '%s'\n", cur.name));
@@ -931,7 +930,7 @@ ftp_parse_vms_ls (const char *file)
}
}
cur.perms = perms;
DEBUGP (("Prot. perms = %0o.\n", cur.perms));
DEBUGP (("Prot. perms = %0o.\n", (unsigned) cur.perms));
}
else
{

View File

@@ -1,6 +1,5 @@
/* Opie (s/key) support for FTP.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2015 Free Software Foundation, Inc.
Copyright (C) 1998-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

181
src/ftp.c
View File

@@ -1,7 +1,6 @@
/* File Transfer Protocol support.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2014-2015, 2018 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -52,6 +51,9 @@ as that of the covered work. */
#include "recur.h" /* for INFINITE_RECURSION */
#include "warc.h"
#include "c-strcase.h"
#ifdef ENABLE_XATTR
#include "xattr.h"
#endif
#ifdef __VMS
# include "vms.h"
@@ -236,10 +238,10 @@ print_length (wgint size, wgint start, bool authoritative)
logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
}
static uerr_t ftp_get_listing (struct url *, ccon *, struct fileinfo **);
static uerr_t ftp_get_listing (struct url *, struct url *, ccon *, struct fileinfo **);
static uerr_t
get_ftp_greeting(int csock, ccon *con)
get_ftp_greeting (int csock, ccon *con)
{
uerr_t err = 0;
@@ -315,13 +317,14 @@ init_control_ssl_connection (int csock, struct url *u, bool *using_control_secur
and closes the control connection in case of error. If warc_tmp
is non-NULL, the downloaded data will be written there as well. */
static uerr_t
getftp (struct url *u, wgint passed_expected_bytes, wgint *qtyread,
getftp (struct url *u, struct url *original_url,
wgint passed_expected_bytes, wgint *qtyread,
wgint restval, ccon *con, int count, wgint *last_expected_bytes,
FILE *warc_tmp)
{
int csock, dtsock, local_sock, res;
uerr_t err = RETROK; /* appease the compiler */
FILE *fp;
FILE *fp = NULL;
char *respline, *tms;
const char *user, *passwd, *tmrate;
int cmd = con->cmd;
@@ -355,12 +358,35 @@ getftp (struct url *u, wgint passed_expected_bytes, wgint *qtyread,
*qtyread = restval;
user = u->user;
passwd = u->passwd;
search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
user = user ? user : (opt.ftp_user ? opt.ftp_user : opt.user);
/* Find the username with priority */
if (u->user)
user = u->user;
else if (opt.user && (opt.use_askpass || opt.ask_passwd))
user = opt.user;
else if (opt.ftp_user)
user = opt.ftp_user;
else if (opt.user)
user = opt.user;
else
user = NULL;
/* Find the password with priority */
if (u->passwd)
passwd = u->passwd;
else if (opt.passwd && (opt.use_askpass || opt.ask_passwd))
passwd = opt.passwd;
else if (opt.ftp_passwd)
passwd = opt.ftp_passwd;
else if (opt.passwd)
passwd = opt.passwd;
else
passwd = NULL;
/* Check for ~/.netrc if none of the above match */
if (opt.netrc && (!user || !passwd))
search_netrc (u->host, (const char **) &user, (const char **) &passwd, 1);
if (!user) user = "anonymous";
passwd = passwd ? passwd : (opt.ftp_passwd ? opt.ftp_passwd : opt.passwd);
if (!passwd) passwd = "-wget@";
dtsock = -1;
@@ -393,7 +419,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 */
{
@@ -532,10 +560,10 @@ Error in server response, closing control connection.\n"));
logputs (LOG_VERBOSE, "done.");
if (!opt.server_response)
logprintf (LOG_VERBOSE, " ==> PROT %c ... ", prot);
logprintf (LOG_VERBOSE, " ==> PROT %c ... ", (int) prot);
if ((err = ftp_prot (csock, prot)) == FTPNOPROT)
{
logprintf (LOG_NOTQUIET, _("Server did not accept the 'PROT %c' command.\n"), prot);
logprintf (LOG_NOTQUIET, _("Server did not accept the 'PROT %c' command.\n"), (int) prot);
return err;
}
if (!opt.server_response)
@@ -869,7 +897,7 @@ Error in server response, closing control connection.\n"));
Unlike the rest of this block, this particular behavior
_is_ VMS-specific, so it gets its own VMS test.
*/
if ((con->rs == ST_VMS) && (strchr( target, '/') != NULL))
if ((con->rs == ST_VMS) && (strchr (target, '/') != NULL))
{
cwd_end = 3;
DEBUGP (("Using extra \"CWD []\" step for VMS server.\n"));
@@ -1185,8 +1213,9 @@ Error in server response, closing control connection.\n"));
if (opt.spider)
{
bool exists = false;
bool all_exist = true;
struct fileinfo *f;
uerr_t _res = ftp_get_listing (u, con, &f);
uerr_t _res = ftp_get_listing (u, original_url, con, &f);
/* Set the DO_RETR command flag again, because it gets unset when
calling ftp_get_listing() and would otherwise cause an assertion
failure earlier on when this function gets repeatedly called
@@ -1200,6 +1229,8 @@ Error in server response, closing control connection.\n"));
{
exists = true;
break;
} else {
all_exist = false;
}
f = f->next;
}
@@ -1220,7 +1251,11 @@ Error in server response, closing control connection.\n"));
con->csock = -1;
fd_close (dtsock);
fd_close (local_sock);
return RETRFINISHED;
if (all_exist) {
return RETRFINISHED;
} else {
return FTPNSFOD;
}
}
if (opt.verbose)
@@ -1427,7 +1462,7 @@ Error in server response, closing control connection.\n"));
else if (opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct
|| opt.output_document || count > 0)
{
if (opt.unlink && file_exists_p (con->target))
if (opt.unlink_requested && file_exists_p (con->target, NULL))
{
if (unlink (con->target) < 0)
{
@@ -1512,8 +1547,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 +1559,8 @@ Error in server response, closing control connection.\n"));
{
fd_close (csock);
fd_close (dtsock);
return CONERROR;
err = CONERROR;
goto exit_error;
}
}
#endif
@@ -1541,6 +1578,11 @@ Error in server response, closing control connection.\n"));
tmrate = retr_rate (rd_size, con->dltime);
total_download_time += con->dltime;
#ifdef ENABLE_XATTR
if (opt.enable_xattr)
set_file_metadata (u->url, NULL, fp);
#endif
fd_close (local_sock);
/* Close the local file. */
if (!output_stream || con->cmd & DO_LIST)
@@ -1636,10 +1678,10 @@ Error in server response, closing control connection.\n"));
#ifdef __VMS
char *targ;
targ = ods_conform( con->target);
targ = ods_conform (con->target);
if (targ != con->target)
{
xfree( con->target);
xfree (con->target);
con->target = targ;
}
#endif /* def __VMS */
@@ -1760,6 +1802,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
@@ -1768,15 +1817,15 @@ Error in server response, closing control connection.\n"));
This loop either gets commands from con, or (if ON_YOUR_OWN is
set), makes them up to retrieve the file given by the URL. */
static uerr_t
ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_file,
bool force_full_retrieve)
ftp_loop_internal (struct url *u, struct url *original_url, struct fileinfo *f,
ccon *con, char **local_file, bool force_full_retrieve)
{
int count, orig_lp;
wgint restval, len = 0, qtyread = 0;
char *tms, *locf;
const char *tmrate = NULL;
uerr_t err;
struct_stat st;
struct stat st;
/* Declare WARC variables. */
bool warc_enabled = (opt.warc_filename != NULL);
@@ -1794,7 +1843,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
{
/* URL-derived file. Consider "-O file" name. */
xfree (con->target);
con->target = url_file_name (u, NULL);
con->target = url_file_name (opt.trustservernames || !original_url ? u : original_url, NULL);
if (!opt.output_document)
locf = con->target;
else
@@ -1807,7 +1856,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
/* If we receive .listing file it is necessary to determine system type of the ftp
server even if opn.noclobber is given. Thus we must ignore opt.noclobber in
order to establish connection with the server and get system type. */
if (opt.noclobber && !opt.output_document && file_exists_p (con->target)
if (opt.noclobber && !opt.output_document && file_exists_p (con->target, NULL)
&& !((con->cmd & DO_LIST) && !(con->cmd & DO_RETR)))
{
logprintf (LOG_VERBOSE,
@@ -1912,8 +1961,8 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
/* If we are working on a WARC record, getftp should also write
to the warc_tmp file. */
err = getftp (u, len, &qtyread, restval, con, count, &last_expected_bytes,
warc_tmp);
err = getftp (u, original_url, len, &qtyread, restval, con, count,
&last_expected_bytes, warc_tmp);
if (con->csock == -1)
con->st &= ~DONE_CWD;
@@ -2079,9 +2128,10 @@ Removing file due to --delete-after in ftp_loop_internal():\n"));
}
/* Return the directory listing in a reusable format. The directory
is specifed in u->dir. */
is specified in u->dir. */
static uerr_t
ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
ftp_get_listing (struct url *u, struct url *original_url, ccon *con,
struct fileinfo **f)
{
uerr_t err;
char *uf; /* url file name */
@@ -2102,7 +2152,7 @@ ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
con->target = xstrdup (lf);
xfree (lf);
err = ftp_loop_internal (u, NULL, con, NULL, false);
err = ftp_loop_internal (u, original_url, NULL, con, NULL, false);
lf = xstrdup (con->target);
xfree (con->target);
con->target = old_target;
@@ -2125,8 +2175,9 @@ ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
return err;
}
static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
static uerr_t ftp_retrieve_dirs (struct url *, struct url *,
struct fileinfo *, ccon *);
static uerr_t ftp_retrieve_glob (struct url *, struct url *, ccon *, int);
static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
static void freefileinfo (struct fileinfo *f);
@@ -2138,7 +2189,8 @@ static void freefileinfo (struct fileinfo *f);
If opt.recursive is set, after all files have been retrieved,
ftp_retrieve_dirs will be called to retrieve the directories. */
static uerr_t
ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
ftp_retrieve_list (struct url *u, struct url *original_url,
struct fileinfo *f, ccon *con)
{
static int depth = 0;
uerr_t err;
@@ -2196,7 +2248,7 @@ ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
dlthis = true;
if (opt.timestamping && f->type == FT_PLAINFILE)
{
struct_stat st;
struct stat st;
/* If conversion of HTML files retrieved via FTP is ever implemented,
we'll need to stat() <file>.orig here when -K has been specified.
I'm not implementing it now since files on an FTP server are much
@@ -2259,7 +2311,7 @@ The sizes do not match (local %s) -- retrieving.\n\n"),
_("Invalid name of the symlink, skipping.\n"));
else
{
struct_stat st;
struct stat st;
/* Check whether we already have the correct
symbolic link. */
int rc = lstat (con->target, &st);
@@ -2299,7 +2351,10 @@ Already have correct symlink %s -> %s\n\n"),
else /* opt.retr_symlinks */
{
if (dlthis)
err = ftp_loop_internal (u, f, con, NULL, force_full_retrieve);
{
err = ftp_loop_internal (u, original_url, f, con, NULL,
force_full_retrieve);
}
} /* opt.retr_symlinks */
break;
case FT_DIRECTORY:
@@ -2310,9 +2365,13 @@ Already have correct symlink %s -> %s\n\n"),
case FT_PLAINFILE:
/* Call the retrieve loop. */
if (dlthis)
err = ftp_loop_internal (u, f, con, NULL, force_full_retrieve);
{
err = ftp_loop_internal (u, original_url, f, con, NULL,
force_full_retrieve);
}
break;
case FT_UNKNOWN:
default:
logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
quote (f->name));
break;
@@ -2334,7 +2393,12 @@ Already have correct symlink %s -> %s\n\n"),
(f->type == FT_PLAINFILE) && opt.preserve_perm)
{
if (f->perms)
chmod (actual_target, f->perms);
{
if (chmod (actual_target, f->perms))
logprintf (LOG_NOTQUIET,
_("Failed to set permissions for %s.\n"),
actual_target);
}
else
DEBUGP (("Unrecognized permissions for %s.\n", actual_target));
}
@@ -2348,7 +2412,7 @@ Already have correct symlink %s -> %s\n\n"),
&& !(f->type == FT_SYMLINK && !opt.retr_symlinks)
&& f->tstamp != -1
&& dlthis
&& file_exists_p (con->target))
&& file_exists_p (con->target, NULL))
{
touch (actual_target, f->tstamp);
}
@@ -2375,7 +2439,7 @@ Already have correct symlink %s -> %s\n\n"),
/* We do not want to call ftp_retrieve_dirs here */
if (opt.recursive &&
!(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
err = ftp_retrieve_dirs (u, orig, con);
err = ftp_retrieve_dirs (u, original_url, orig, con);
else if (opt.recursive)
DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
depth, opt.reclevel));
@@ -2388,7 +2452,8 @@ Already have correct symlink %s -> %s\n\n"),
ftp_retrieve_glob on each directory entry. The function knows
about excluded directories. */
static uerr_t
ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
ftp_retrieve_dirs (struct url *u, struct url *original_url,
struct fileinfo *f, ccon *con)
{
char *container = NULL;
int container_size = 0;
@@ -2438,7 +2503,7 @@ Not descending to %s as it is excluded/not-included.\n"),
odir = xstrdup (u->dir); /* because url_set_dir will free
u->dir. */
url_set_dir (u, newdir);
ftp_retrieve_glob (u, con, GLOB_GETALL);
ftp_retrieve_glob (u, original_url, con, GLOB_GETALL);
url_set_dir (u, odir);
xfree (odir);
@@ -2481,7 +2546,7 @@ is_invalid_entry (struct fileinfo *f)
while (cur->next)
{
cur = cur->next;
if (strcmp(f_name, cur->name) == 0)
if (strcmp (f_name, cur->name) == 0)
return true;
}
return false;
@@ -2497,14 +2562,15 @@ is_invalid_entry (struct fileinfo *f)
GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
directory. */
static uerr_t
ftp_retrieve_glob (struct url *u, ccon *con, int action)
ftp_retrieve_glob (struct url *u, struct url *original_url,
ccon *con, int action)
{
struct fileinfo *f, *start;
uerr_t res;
con->cmd |= LEAVE_PENDING;
res = ftp_get_listing (u, con, &start);
res = ftp_get_listing (u, original_url, con, &start);
if (res != RETROK)
return res;
/* First: weed out that do not conform the global rules given in
@@ -2600,7 +2666,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
if (start)
{
/* Just get everything. */
res = ftp_retrieve_list (u, start, con);
res = ftp_retrieve_list (u, original_url, start, con);
}
else
{
@@ -2616,7 +2682,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
{
/* Let's try retrieving it anyway. */
con->st |= ON_YOUR_OWN;
res = ftp_loop_internal (u, NULL, con, NULL, false);
res = ftp_loop_internal (u, original_url, NULL, con, NULL, false);
return res;
}
@@ -2636,8 +2702,8 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
of URL. Inherently, its capabilities are limited on what can be
encoded into a URL. */
uerr_t
ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
bool recursive, bool glob)
ftp_loop (struct url *u, struct url *original_url, char **local_file, int *dt,
struct url *proxy, bool recursive, bool glob)
{
ccon con; /* FTP connection */
uerr_t res;
@@ -2658,22 +2724,23 @@ ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
if (!*u->file && !recursive)
{
struct fileinfo *f;
res = ftp_get_listing (u, &con, &f);
res = ftp_get_listing (u, original_url, &con, &f);
if (res == RETROK)
{
if (opt.htmlify && !opt.spider)
{
struct url *url_file = opt.trustservernames ? u : original_url;
char *filename = (opt.output_document
? xstrdup (opt.output_document)
: (con.target ? xstrdup (con.target)
: url_file_name (u, NULL)));
: url_file_name (url_file, NULL)));
res = ftp_index (filename, u, f);
if (res == FTPOK && opt.verbose)
{
if (!opt.output_document)
{
struct_stat st;
struct stat st;
wgint sz;
if (stat (filename, &st) == 0)
sz = st.st_size;
@@ -2712,11 +2779,13 @@ ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
/* ftp_retrieve_glob is a catch-all function that gets called
if we need globbing, time-stamping, recursion or preserve
permissions. Its third argument is just what we really need. */
res = ftp_retrieve_glob (u, &con,
res = ftp_retrieve_glob (u, original_url, &con,
ispattern ? GLOB_GLOBALL : GLOB_GETONE);
}
else
res = ftp_loop_internal (u, NULL, &con, local_file, false);
{
res = ftp_loop_internal (u, original_url, NULL, &con, local_file, false);
}
}
if (res == FTPOK)
res = RETROK;

View File

@@ -1,7 +1,5 @@
/* Declarations for FTP support.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -169,7 +167,8 @@ enum wget_ftp_fstatus
};
struct fileinfo *ftp_parse_ls (const char *, const enum stype);
uerr_t ftp_loop (struct url *, char **, int *, struct url *, bool, bool);
uerr_t ftp_loop (struct url *, struct url *, char **, int *, struct url *,
bool, bool);
uerr_t ftp_index (const char *, struct url *, struct fileinfo *);

View File

@@ -1,6 +1,5 @@
/* SSL support via GnuTLS library.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2015
Free Software Foundation, Inc.
Copyright (C) 2005-2012, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -36,7 +35,9 @@ as that of the covered work. */
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <xalloc.h>
#include <gnutls/abstract.h>
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
#include <sys/ioctl.h>
@@ -48,7 +49,7 @@ as that of the covered work. */
#include "hash.h"
#include "ssl.h"
#include <sys/fcntl.h>
#include <fcntl.h>
#ifdef WIN32
# include "w32sock.h"
@@ -496,7 +497,7 @@ _do_handshake (gnutls_session_t session, int fd, double timeout)
{
gnutls_alert_description_t alert = gnutls_alert_get (session);
const char *str = gnutls_alert_get_name (alert);
logprintf (LOG_NOTQUIET, "GnuTLS: received alert [%d]: %s\n",
logprintf (LOG_NOTQUIET, "GnuTLS: received alert [%u]: %s\n",
alert, str ? str : "(unknown)");
}
}
@@ -518,6 +519,22 @@ _do_handshake (gnutls_session_t session, int fd, double timeout)
return err;
}
static const char *
_sni_hostname(const char *hostname)
{
size_t len = strlen(hostname);
char *sni_hostname = xmemdup(hostname, len + 1);
/* Remove trailing dot(s) to fix #47408.
* Regarding RFC 6066 (SNI): The hostname is represented as a byte
* string using ASCII encoding without a trailing dot. */
while (len && sni_hostname[--len] == '.')
sni_hostname[len] = 0;
return sni_hostname;
}
bool
ssl_connect_wget (int fd, const char *hostname, int *continue_session)
{
@@ -530,11 +547,14 @@ ssl_connect_wget (int fd, const char *hostname, int *continue_session)
/* We set the server name but only if it's not an IP address. */
if (! is_valid_ip_address (hostname))
{
gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname,
strlen (hostname));
/* GnuTLS 3.4.x (x<=10) disrespects the length parameter, we have to construct a new string */
/* see https://gitlab.com/gnutls/gnutls/issues/78 */
const char *sni_hostname = _sni_hostname(hostname);
gnutls_server_name_set (session, GNUTLS_NAME_DNS, sni_hostname, strlen(sni_hostname));
xfree(sni_hostname);
}
gnutls_set_default_priority (session);
gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, credentials);
#ifndef FD_TO_SOCKET
# define FD_TO_SOCKET(X) (X)
@@ -549,7 +569,8 @@ ssl_connect_wget (int fd, const char *hostname, int *continue_session)
switch (opt.secure_protocol)
{
case secure_protocol_auto:
err = gnutls_priority_set_direct (session, "NORMAL:%COMPAT:-VERS-SSL3.0", NULL);
err = gnutls_set_default_priority (session);
gnutls_session_enable_compatibility_mode(session);
break;
case secure_protocol_sslv2:
@@ -577,7 +598,8 @@ ssl_connect_wget (int fd, const char *hostname, int *continue_session)
break;
default:
logprintf (LOG_NOTQUIET, _("GnuTLS: unimplemented 'secure-protocol' option value %d\n"), opt.secure_protocol);
logprintf (LOG_NOTQUIET, _("GnuTLS: unimplemented 'secure-protocol' option value %u\n"),
(unsigned) opt.secure_protocol);
logprintf (LOG_NOTQUIET, _("Please report this issue to bug-wget@gnu.org\n"));
abort ();
}
@@ -586,6 +608,7 @@ ssl_connect_wget (int fd, const char *hostname, int *continue_session)
switch (opt.secure_protocol)
{
case secure_protocol_auto:
err = gnutls_set_default_priority (session);
break;
case secure_protocol_sslv2:
@@ -633,9 +656,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;
}
@@ -667,6 +694,59 @@ ssl_connect_wget (int fd, const char *hostname, int *continue_session)
return true;
}
static bool
pkp_pin_peer_pubkey (gnutls_x509_crt_t cert, const char *pinnedpubkey)
{
/* Scratch */
size_t len1 = 0, len2 = 0;
char *buff1 = NULL;
gnutls_pubkey_t key = NULL;
/* Result is returned to caller */
int ret = 0;
bool result = false;
/* if a path wasn't specified, don't pin */
if (NULL == pinnedpubkey)
return true;
if (NULL == cert)
return result;
/* Begin Gyrations to get the public key */
gnutls_pubkey_init (&key);
ret = gnutls_pubkey_import_x509 (key, cert, 0);
if (ret < 0)
goto cleanup; /* failed */
ret = gnutls_pubkey_export (key, GNUTLS_X509_FMT_DER, NULL, &len1);
if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0)
goto cleanup; /* failed */
buff1 = xmalloc (len1);
len2 = len1;
ret = gnutls_pubkey_export (key, GNUTLS_X509_FMT_DER, buff1, &len2);
if (ret < 0 || len1 != len2)
goto cleanup; /* failed */
/* End Gyrations */
/* The one good exit point */
result = wg_pin_peer_pubkey (pinnedpubkey, buff1, len1);
cleanup:
if (NULL != key)
gnutls_pubkey_deinit (key);
xfree (buff1);
return result;
}
#define _CHECK_CERT(flag,msg) \
if (status & (flag))\
{\
@@ -687,6 +767,11 @@ ssl_check_certificate (int fd, const char *host)
him about problems with the server's certificate. */
const char *severity = opt.check_cert ? _("ERROR") : _("WARNING");
bool success = true;
bool pinsuccess = opt.pinnedpubkey == NULL;
/* The user explicitly said to not check for the certificate. */
if (opt.check_cert == CHECK_CERT_QUIET && pinsuccess)
return success;
err = gnutls_certificate_verify_peers2 (ctx->session, &status);
if (err < 0)
@@ -711,6 +796,7 @@ ssl_check_certificate (int fd, const char *host)
gnutls_x509_crt_t cert;
const gnutls_datum_t *cert_list;
unsigned int cert_list_size;
const char *sni_hostname;
if ((err = gnutls_x509_crt_init (&cert)) < 0)
{
@@ -745,13 +831,23 @@ ssl_check_certificate (int fd, const char *host)
logprintf (LOG_NOTQUIET, _("The certificate has expired\n"));
success = false;
}
if (!gnutls_x509_crt_check_hostname (cert, host))
sni_hostname = _sni_hostname(host);
if (!gnutls_x509_crt_check_hostname (cert, sni_hostname))
{
logprintf (LOG_NOTQUIET,
_("The certificate's owner does not match hostname %s\n"),
quote (host));
quote (sni_hostname));
success = false;
}
xfree(sni_hostname);
pinsuccess = pkp_pin_peer_pubkey (cert, opt.pinnedpubkey);
if (!pinsuccess)
{
logprintf (LOG_ALWAYS, _("The public key does not match pinned public key!\n"));
success = false;
}
crt_deinit:
gnutls_x509_crt_deinit (cert);
}
@@ -762,5 +858,6 @@ ssl_check_certificate (int fd, const char *host)
}
out:
return opt.check_cert ? success : true;
/* never return true if pinsuccess fails */
return !pinsuccess ? false : (opt.check_cert == CHECK_CERT_ON ? success : true);
}

View File

@@ -1,6 +1,5 @@
/* Hash tables.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 2011, 2015 Free Software Foundation, Inc.
Copyright (C) 2000-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -283,10 +282,10 @@ hash_table_new (int items,
/* Calculate the size that ensures that the table will store at
least ITEMS keys without the need to resize. */
size = 1 + items / HASH_MAX_FULLNESS;
size = (int) (1 + items / HASH_MAX_FULLNESS);
size = prime_size (size, &ht->prime_offset);
ht->size = size;
ht->resize_threshold = size * HASH_MAX_FULLNESS;
ht->resize_threshold = (int) (size * HASH_MAX_FULLNESS);
/*assert (ht->resize_threshold >= items);*/
ht->cells = xnew_array (struct cell, ht->size);
@@ -394,7 +393,7 @@ grow_hash_table (struct hash_table *ht)
#endif
ht->size = newsize;
ht->resize_threshold = newsize * HASH_MAX_FULLNESS;
ht->resize_threshold = (int) (newsize * HASH_MAX_FULLNESS);
cells = xnew_array (struct cell, newsize);
memset (cells, INVALID_PTR_CHAR, newsize * sizeof (struct cell));

View File

@@ -1,6 +1,6 @@
/* Hash table declarations.
Copyright (C) 2000, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 2000, 2007-2011, 2015, 2018 Free Software Foundation,
Inc.
This file is part of GNU Wget.

View File

@@ -1,7 +1,5 @@
/* Host name resolution and matching.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2012, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -57,14 +55,11 @@ as that of the covered work. */
#include <errno.h>
#ifdef ENABLE_IRI
#include <idn-free.h>
#endif
#include "utils.h"
#include "host.h"
#include "url.h"
#include "hash.h"
#include "ptimer.h"
#ifndef NO_ADDRESS
# define NO_ADDRESS NO_DATA
@@ -427,14 +422,12 @@ getaddrinfo_with_timeout (const char *node, const char *service,
const char *
print_address (const ip_address *addr)
{
#ifdef ENABLE_IPV6
static char buf[64];
if (!inet_ntop (addr->family, IP_INADDR_DATA (addr), buf, sizeof buf))
snprintf (buf, sizeof buf, "<error: %s>", strerror (errno));
return buf;
#else
return inet_ntoa (addr->data.d4);
#endif
}
/* The following two functions were adapted from glibc's
@@ -649,6 +642,112 @@ cache_remove (const char *host)
}
}
#ifdef HAVE_LIBCARES
#include <sys/select.h>
#include <ares.h>
extern ares_channel ares;
static struct address_list *
merge_address_lists (struct address_list *al1, struct address_list *al2)
{
int count = al1->count + al2->count;
/* merge al2 into al1 */
al1->addresses = xrealloc (al1->addresses, sizeof (ip_address) * count);
memcpy (al1->addresses + al1->count, al2->addresses, sizeof (ip_address) * al2->count);
al1->count = count;
address_list_delete (al2);
return al1;
}
static struct address_list *
address_list_from_hostent (struct hostent *host)
{
int count, i;
struct address_list *al = xnew0 (struct address_list);
for (count = 0; host->h_addr_list[count]; count++)
;
assert (count > 0);
al->addresses = xnew_array (ip_address, count);
al->count = count;
al->refcount = 1;
for (i = 0; i < count; i++)
{
ip_address *ip = &al->addresses[i];
ip->family = host->h_addrtype;
memcpy (IP_INADDR_DATA (ip), host->h_addr_list[i], ip->family == AF_INET ? 4 : 16);
}
return al;
}
/* Since GnuLib's select() (i.e. rpl_select()) cannot handle socket-numbers
* returned from C-ares, we must use the original select() from Winsock.
*/
#ifdef WINDOWS
#undef select
#endif
static void
wait_ares (ares_channel channel)
{
struct ptimer *timer = NULL;
if (opt.dns_timeout)
timer = ptimer_new ();
for (;;)
{
struct timeval *tvp, tv;
fd_set read_fds, write_fds;
int nfds, rc;
FD_ZERO (&read_fds);
FD_ZERO (&write_fds);
nfds = ares_fds (channel, &read_fds, &write_fds);
if (nfds == 0)
break;
if (timer)
{
double max = opt.dns_timeout - ptimer_measure (timer);
tv.tv_sec = (long) max;
tv.tv_usec = 1000000 * (max - (long) max);
tvp = ares_timeout (channel, &tv, &tv);
}
else
tvp = ares_timeout (channel, NULL, &tv);
rc = select (nfds, &read_fds, &write_fds, NULL, tvp);
if (rc == 0 && timer && ptimer_measure (timer) >= opt.dns_timeout)
ares_cancel (channel);
else
ares_process (channel, &read_fds, &write_fds);
}
}
static void
callback (void *arg, int status, int timeouts _GL_UNUSED, struct hostent *host)
{
struct address_list **al = (struct address_list **) arg;
if (!host || status != ARES_SUCCESS)
{
*al = NULL;
return;
}
*al = address_list_from_hostent (host);
}
#endif
/* Look up HOST in DNS and return a list of IP addresses.
This function caches its result so that, if the same host is passed
@@ -741,11 +840,8 @@ lookup_host (const char *host, int flags)
if (opt.enable_iri && (name = idn_decode ((char *) host)) != NULL)
{
int len = strlen (host) + strlen (name) + 4;
str = xmalloc (len);
snprintf (str, len, "%s (%s)", name, host);
str[len-1] = '\0';
idn_free (name);
str = aprintf ("%s (%s)", name, host);
xfree (name);
}
logprintf (LOG_VERBOSE, _("Resolving %s... "),
@@ -755,80 +851,112 @@ lookup_host (const char *host, int flags)
}
#ifdef ENABLE_IPV6
{
int err;
struct addrinfo hints, *res;
#ifdef HAVE_LIBCARES
if (ares)
{
struct address_list *al4;
struct address_list *al6;
xzero (hints);
hints.ai_socktype = SOCK_STREAM;
if (opt.ipv4_only)
hints.ai_family = AF_INET;
else if (opt.ipv6_only)
hints.ai_family = AF_INET6;
else
/* We tried using AI_ADDRCONFIG, but removed it because: it
misinterprets IPv6 loopbacks, it is broken on AIX 5.1, and
it's unneeded since we sort the addresses anyway. */
if (opt.ipv4_only || !opt.ipv6_only)
ares_gethostbyname (ares, host, AF_INET, callback, &al4);
if (opt.ipv6_only || !opt.ipv4_only)
ares_gethostbyname (ares, host, AF_INET6, callback, &al6);
wait_ares (ares);
if (al4 && al6)
al = merge_address_lists (al4, al6);
else if (al4)
al = al4;
else
al = al6;
}
else
#endif
{
int err;
struct addrinfo hints, *res;
xzero (hints);
hints.ai_socktype = SOCK_STREAM;
if (opt.ipv4_only)
hints.ai_family = AF_INET;
else if (opt.ipv6_only)
hints.ai_family = AF_INET6;
else
/* We tried using AI_ADDRCONFIG, but removed it because: it
misinterprets IPv6 loopbacks, it is broken on AIX 5.1, and
it's unneeded since we sort the addresses anyway. */
hints.ai_family = AF_UNSPEC;
if (flags & LH_BIND)
hints.ai_flags |= AI_PASSIVE;
if (flags & LH_BIND)
hints.ai_flags |= AI_PASSIVE;
#ifdef AI_NUMERICHOST
if (numeric_address)
{
/* Where available, the AI_NUMERICHOST hint can prevent costly
access to DNS servers. */
hints.ai_flags |= AI_NUMERICHOST;
timeout = 0; /* no timeout needed when "resolving"
if (numeric_address)
{
/* Where available, the AI_NUMERICHOST hint can prevent costly
access to DNS servers. */
hints.ai_flags |= AI_NUMERICHOST;
timeout = 0; /* no timeout needed when "resolving"
numeric hosts -- avoid setting up
signal handlers and such. */
}
}
#endif
err = getaddrinfo_with_timeout (host, NULL, &hints, &res, timeout);
if (err != 0 || res == NULL)
{
if (!silent)
logprintf (LOG_VERBOSE, _("failed: %s.\n"),
err != EAI_SYSTEM ? gai_strerror (err) : strerror (errno));
return NULL;
}
al = address_list_from_addrinfo (res);
freeaddrinfo (res);
if (!al)
{
logprintf (LOG_VERBOSE,
_("failed: No IPv4/IPv6 addresses for host.\n"));
return NULL;
}
err = getaddrinfo_with_timeout (host, NULL, &hints, &res, timeout);
/* Reorder addresses so that IPv4 ones (or IPv6 ones, as per
--prefer-family) come first. Sorting is stable so the order of
the addresses with the same family is undisturbed. */
if (al->count > 1 && opt.prefer_family != prefer_none)
stable_sort (al->addresses, al->count, sizeof (ip_address),
opt.prefer_family == prefer_ipv4
? cmp_prefer_ipv4 : cmp_prefer_ipv6);
}
if (err != 0 || res == NULL)
{
if (!silent)
logprintf (LOG_VERBOSE, _ ("failed: %s.\n"),
err != EAI_SYSTEM ? gai_strerror (err) : strerror (errno));
return NULL;
}
al = address_list_from_addrinfo (res);
freeaddrinfo (res);
}
if (!al)
{
logprintf (LOG_VERBOSE,
_ ("failed: No IPv4/IPv6 addresses for host.\n"));
return NULL;
}
/* Reorder addresses so that IPv4 ones (or IPv6 ones, as per
--prefer-family) come first. Sorting is stable so the order of
the addresses with the same family is undisturbed. */
if (al->count > 1 && opt.prefer_family != prefer_none)
stable_sort (al->addresses, al->count, sizeof (ip_address),
opt.prefer_family == prefer_ipv4
? cmp_prefer_ipv4 : cmp_prefer_ipv6);
#else /* not ENABLE_IPV6 */
{
struct hostent *hptr = gethostbyname_with_timeout (host, timeout);
if (!hptr)
{
if (!silent)
{
if (errno != ETIMEDOUT)
logprintf (LOG_VERBOSE, _("failed: %s.\n"),
host_errstr (h_errno));
else
logputs (LOG_VERBOSE, _("failed: timed out.\n"));
}
return NULL;
}
/* Do older systems have h_addr_list? */
al = address_list_from_ipv4_addresses (hptr->h_addr_list);
}
#ifdef HAVE_LIBCARES
if (ares)
{
ares_gethostbyname (ares, host, AF_INET, callback, &al);
wait_ares (ares);
}
else
#endif
{
struct hostent *hptr = gethostbyname_with_timeout (host, timeout);
if (!hptr)
{
if (!silent)
{
if (errno != ETIMEDOUT)
logprintf (LOG_VERBOSE, _ ("failed: %s.\n"),
host_errstr (h_errno));
else
logputs (LOG_VERBOSE, _ ("failed: timed out.\n"));
}
return NULL;
}
/* Do older systems have h_addr_list? */
al = address_list_from_ipv4_addresses (hptr->h_addr_list);
}
#endif /* not ENABLE_IPV6 */
/* Print the addresses determined by DNS lookup, but no more than
@@ -889,18 +1017,25 @@ sufmatch (const char **list, const char *what)
int i, j, k, lw;
lw = strlen (what);
for (i = 0; list[i]; i++)
{
if (list[i][0] == '\0')
continue;
j = strlen (list[i]);
if (lw < j)
continue; /* what is no (sub)domain of list[i] */
for (j = strlen (list[i]), k = lw; j >= 0 && k >= 0; j--, k--)
for (k = lw; j >= 0 && k >= 0; j--, k--)
if (c_tolower (list[i][j]) != c_tolower (what[k]))
break;
/* The domain must be first to reach to beginning. */
if (j == -1)
/* Domain or subdomain match
* k == -1: exact match
* k >= 0 && what[k] == '.': subdomain match
*/
if (j == -1 && (k == -1 || what[k] == '.'))
return true;
}
return false;
}

View File

@@ -1,7 +1,5 @@
/* Declarations for host.c
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2012, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,7 +1,5 @@
/* HTTP Strict Transport Security (HSTS) support.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2012, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -32,9 +30,9 @@ as that of the covered work. */
#ifdef HAVE_HSTS
#include "hsts.h"
#include "utils.h"
#include "host.h" /* for is_valid_ip_address() */
#include "init.h" /* for home_dir() */
#include "utils.h"
#include "hash.h"
#include "c-ctype.h"
#ifdef TESTING
@@ -53,6 +51,7 @@ as that of the covered work. */
struct hsts_store {
struct hash_table *table;
time_t last_mtime;
bool changed;
};
struct hsts_kh {
@@ -79,7 +78,6 @@ enum hsts_kh_match {
#define DEFAULT_HTTP_PORT 80
#define DEFAULT_SSL_PORT 443
#define CHECK_EXPLICIT_PORT(p1, p2) (p1 == 0 || p1 == p2)
#define MAKE_EXPLICIT_PORT(s, p) (s == SCHEME_HTTPS ? (p == DEFAULT_SSL_PORT ? 0 : p) \
: (p == DEFAULT_HTTP_PORT ? 0 : p))
@@ -148,13 +146,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 +235,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
@@ -316,7 +314,7 @@ hsts_store_dump (hsts_store_t store, FILE *fp)
/* Print preliminary comments. We don't care if any of these fail. */
fputs ("# HSTS 1.0 Known Hosts database for GNU Wget.\n", fp);
fputs ("# Edit at your own risk.\n", fp);
fputs ("# <hostname>[:<port>]\t<incl. subdomains>\t<created>\t<max-age>\n", fp);
fputs ("# <hostname>\t<port>\t<incl. subdomains>\t<created>\t<max-age>\n", fp);
/* Now cycle through the HSTS store in memory and dump the entries */
for (hash_table_iterate (store->table, &it); hash_table_iter_next (&it);)
@@ -326,7 +324,8 @@ hsts_store_dump (hsts_store_t store, FILE *fp)
if (fprintf (fp, "%s\t%d\t%d\t%lu\t%lu\n",
kh->host, kh->explicit_port, khi->include_subdomains,
khi->created, khi->max_age) < 0)
(unsigned long) khi->created,
(unsigned long) khi->max_age) < 0)
{
logprintf (LOG_ALWAYS, "Could not write the HSTS database correctly.\n");
break;
@@ -334,6 +333,30 @@ hsts_store_dump (hsts_store_t store, FILE *fp)
}
}
/*
* Test:
* - The file is a regular file (ie. not a symlink), and
* - The file is not world-writable.
*/
static bool
hsts_file_access_valid (const char *filename)
{
struct stat st;
if (stat (filename, &st) == -1)
return false;
return
#ifndef WINDOWS
/*
* The world-writable concept is a Unix-centric notion.
* We bypass this test on Windows.
*/
!(st.st_mode & S_IWOTH) &&
#endif
S_ISREG (st.st_mode);
}
/* HSTS API */
/*
@@ -370,14 +393,19 @@ hsts_match (hsts_store_t store, struct url *u)
if (u->port == 80)
u->port = 443;
url_changed = true;
store->changed = true;
}
}
else
hsts_remove_entry (store, kh);
{
hsts_remove_entry (store, kh);
store->changed = true;
}
}
xfree (kh->host);
}
xfree(kh);
xfree (kh);
return url_changed;
}
@@ -413,7 +441,6 @@ hsts_store_entry (hsts_store_t store,
enum hsts_kh_match match = NO_MATCH;
struct hsts_kh *kh = xnew(struct hsts_kh);
struct hsts_kh_info *entry = NULL;
time_t t = 0;
if (hsts_is_host_eligible (scheme, host))
{
@@ -422,19 +449,25 @@ hsts_store_entry (hsts_store_t store,
if (entry && match == CONGRUENT_MATCH)
{
if (max_age == 0)
hsts_remove_entry (store, kh);
{
hsts_remove_entry (store, kh);
store->changed = true;
}
else if (max_age > 0)
{
entry->include_subdomains = include_subdomains;
/* RFC 6797 states that 'max_age' is a TTL relative to the
* reception of the STS header so we have to update the
* 'created' field too. The RFC also states that we have to
* update the entry each time we see HSTS header.
* See also Section 11.2. */
time_t t = time (NULL);
if (entry->max_age != max_age)
if (t != -1 && t != entry->created)
{
/* RFC 6797 states that 'max_age' is a TTL relative to the reception of the STS header
so we have to update the 'created' field too */
t = time (NULL);
if (t != -1)
entry->created = t;
entry->created = t;
entry->max_age = max_age;
entry->include_subdomains = include_subdomains;
store->changed = true;
}
}
/* we ignore negative max_ages */
@@ -449,11 +482,14 @@ hsts_store_entry (hsts_store_t store,
happen we got a non-existent entry with max_age == 0.
*/
result = hsts_add_entry (store, host, port, max_age, include_subdomains);
if (result)
store->changed = true;
}
/* we ignore new entries with max_age == 0 */
xfree (kh->host);
}
xfree(kh);
xfree (kh);
return result;
}
@@ -462,29 +498,50 @@ hsts_store_t
hsts_store_open (const char *filename)
{
hsts_store_t store = NULL;
struct stat st;
FILE *fp = NULL;
file_stats_t fstats;
store = xnew0 (struct hsts_store);
store->table = hash_table_new (0, hsts_hash_func, hsts_cmp_func);
store->last_mtime = 0;
store->changed = false;
if (file_exists_p (filename))
if (file_exists_p (filename, &fstats))
{
if (stat (filename, &st) == 0)
store->last_mtime = st.st_mtime;
fp = fopen (filename, "r");
if (!fp || !hsts_read_database (store, fp, false))
if (hsts_file_access_valid (filename))
{
/* abort! */
struct stat st;
FILE *fp = fopen_stat (filename, "r", &fstats);
if (!fp || !hsts_read_database (store, fp, false))
{
/* abort! */
hsts_store_close (store);
xfree (store);
if (fp)
fclose (fp);
goto out;
}
if (fstat (fileno (fp), &st) == 0)
store->last_mtime = st.st_mtime;
fclose (fp);
}
else
{
/*
* If we're not reading the HSTS database,
* then by all means act as if HSTS was disabled.
*/
hsts_store_close (store);
xfree (store);
logprintf (LOG_NOTQUIET, "Will not apply HSTS. "
"The HSTS database must be a regular and non-world-writable file.\n");
}
if (fp)
fclose (fp);
}
out:
return store;
}
@@ -525,6 +582,12 @@ hsts_store_save (hsts_store_t store, const char *filename)
}
}
bool
hsts_store_has_changed (hsts_store_t store)
{
return (store ? store->changed : false);
}
void
hsts_store_close (hsts_store_t store)
{
@@ -613,7 +676,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 +749,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 +770,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 +789,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 +798,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%lu\t123\n",(unsigned long) created);
fprintf (fp, "bar.example.com\t0\t0\t%lu\t456\n", (unsigned long) created);
fprintf (fp, "test.example.com\t8080\t0\t%lu\t789\n", (unsigned long) created);
fclose (fp);
table = hsts_store_open (file);

View File

@@ -1,7 +1,5 @@
/* Declarations for hsts.c
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2012, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -43,6 +41,7 @@ hsts_store_t hsts_store_open (const char *);
void hsts_store_save (hsts_store_t, const char *);
void hsts_store_close (hsts_store_t);
bool hsts_store_has_changed (hsts_store_t);
bool hsts_store_entry (hsts_store_t,
enum url_scheme, const char *, int,

View File

@@ -1,6 +1,5 @@
/* HTML parser for Wget.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2015 Free Software Foundation, Inc.
Copyright (C) 1998-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -176,8 +175,8 @@ struct pool {
P->orig_size = P->size; \
} while (0)
/* Grow the pool to accomodate at least SIZE new bytes. If the pool
already has room to accomodate SIZE bytes of data, this is a no-op. */
/* Grow the pool to accommodate at least SIZE new bytes. If the pool
already has room to accommodate SIZE bytes of data, this is a no-op. */
#define POOL_GROW(p, increase) \
GROW_ARRAY ((p)->contents, (p)->size, (p)->tail + (increase), \
@@ -801,14 +800,6 @@ name_allowed (const struct hash_table *ht, const char *b, const char *e)
} \
} while (0)
/* Skip non-whitespace, if any. */
#define SKIP_NON_WS(p) do { \
while (!c_isspace (*p)) { \
ADVANCE (p); \
} \
} while (0)
#ifdef STANDALONE
static int tag_backout_count;
#endif

View File

@@ -1,6 +1,5 @@
/* Declarations for html-parse.c.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2015 Free Software Foundation, Inc.
Copyright (C) 1998-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,7 +1,5 @@
/* Collect URLs from HTML source.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2012, 2015 Free Software Foundation,
Inc.
Copyright (C) 1998-2012, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -56,6 +54,7 @@ typedef void (*tag_handler_t) (int, struct taginfo *, struct map_context *);
DECLARE_TAG_HANDLER (tag_find_urls);
DECLARE_TAG_HANDLER (tag_handle_base);
DECLARE_TAG_HANDLER (tag_handle_form);
DECLARE_TAG_HANDLER (tag_handle_img);
DECLARE_TAG_HANDLER (tag_handle_link);
DECLARE_TAG_HANDLER (tag_handle_meta);
@@ -105,7 +104,7 @@ static struct known_tag {
{ TAG_FORM, "form", tag_handle_form },
{ TAG_FRAME, "frame", tag_find_urls },
{ TAG_IFRAME, "iframe", tag_find_urls },
{ TAG_IMG, "img", tag_find_urls },
{ TAG_IMG, "img", tag_handle_img },
{ TAG_INPUT, "input", tag_find_urls },
{ TAG_LAYER, "layer", tag_find_urls },
{ TAG_LINK, "link", tag_handle_link },
@@ -183,7 +182,8 @@ static const char *additional_attributes[] = {
"name", /* used by tag_handle_meta */
"content", /* used by tag_handle_meta */
"action", /* used by tag_handle_form */
"style" /* used by check_style_attr */
"style", /* used by check_style_attr */
"srcset", /* used by tag_handle_img */
};
static struct hash_table *interesting_tags;
@@ -674,6 +674,91 @@ tag_handle_meta (int tagid _GL_UNUSED, struct taginfo *tag, struct map_context *
}
}
/* Handle the IMG tag. This requires special handling for the srcset attr,
while the traditional src/lowsrc/href attributes can be handled generically.
*/
static void
tag_handle_img (int tagid, struct taginfo *tag, struct map_context *ctx) {
int attrind;
char *srcset;
/* Use the generic approach for the attributes without special syntax. */
tag_find_urls(tagid, tag, ctx);
srcset = find_attr (tag, "srcset", &attrind);
if (srcset)
{
/* These are relative to the input text. */
int base_ind = ATTR_POS (tag,attrind,ctx);
int size = strlen (srcset);
/* These are relative to srcset. */
int offset, url_start, url_end;
/* Make sure to line up base_ind with srcset[0], not outside quotes. */
if (ctx->text[base_ind] == '"' || ctx->text[base_ind] == '\'')
++base_ind;
offset = 0;
while (offset < size)
{
bool has_descriptor = true;
/* Skip over initial whitespace and commas. Note there is no \v
in HTML5 whitespace. */
url_start = offset + strspn (srcset + offset, " \f\n\r\t,");
if (url_start == size)
return;
/* URL is any non-whitespace chars (including commas) - but with
trailing commas removed. */
url_end = url_start + strcspn (srcset + url_start, " \f\n\r\t");
while ((url_end - 1) > url_start && srcset[url_end - 1] == ',')
{
has_descriptor = false;
--url_end;
}
if (url_end > url_start)
{
char *url_text = strdupdelim (srcset + url_start,
srcset + url_end);
struct urlpos *up = append_url (url_text, base_ind + url_start,
url_end - url_start, ctx);
if (up)
{
up->link_inline_p = 1;
up->link_noquote_html_p = 1;
}
xfree (url_text);
}
/* If the URL wasn't terminated by a , there may also be a descriptor
which we just skip. */
if (has_descriptor)
{
/* This is comma-terminated, except there may be one level of
parentheses escaping that. */
bool in_paren = false;
for (offset = url_end; offset < size; ++offset)
{
char c = srcset[offset];
if (c == '(')
in_paren = true;
else if (c == ')' && in_paren)
in_paren = false;
else if (c == ',' && !in_paren)
break;
}
}
else
offset = url_end;
}
}
}
/* Dispatch the tag handler appropriate for the tag we're mapping
over. See known_tags[] for definition of tag handlers. */
@@ -752,10 +837,13 @@ get_urls_html (const char *file, const char *url, bool *meta_disallow_follow,
map_html_tags (fm->content, fm->length, collect_tags_mapper, &ctx, flags,
NULL, interesting_attributes);
#ifdef ENABLE_IRI
/* Meta charset is only valid if there was no HTTP header Content-Type charset. */
/* This is true for HTTP 1.0 and 1.1. */
if (iri && !iri->content_encoding && meta_charset)
set_content_encoding (iri, meta_charset);
#endif
xfree (meta_charset);
DEBUGP (("no-follow in %s: %d\n", file, ctx.nofollow));
if (meta_disallow_follow)

View File

@@ -1,5 +1,5 @@
/* Declarations for html-url.c.
Copyright (C) 1995, 1996, 1997, 2009, 2010, 2011, 2015 Free Software
Copyright (C) 1995-1997, 2009-2011, 2015, 2018 Free Software
Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,6 +1,5 @@
/* NTLM code.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
Copyright (C) 2005-2011, 2015, 2018 Free Software Foundation, Inc.
Contributed by Daniel Stenberg.
This file is part of GNU Wget.
@@ -122,7 +121,7 @@ ntlm_input (struct ntlmdata *ntlm, const char *header)
DEBUGP (("Received a type-2 NTLM message.\n"));
size = base64_decode (header, buffer);
size = wget_base64_decode (header, buffer, strlen (header));
if (size < 0)
return false; /* malformed base64 from server */
@@ -411,7 +410,7 @@ ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
size = 32 + hostlen + domlen;
base64 = (char *) alloca (BASE64_LENGTH (size) + 1);
base64_encode (ntlmbuf, size, base64);
wget_base64_encode (ntlmbuf, size, base64);
output = concat_strings ("NTLM ", base64, (char *) 0);
break;
@@ -584,7 +583,7 @@ ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
/* convert the binary blob into base64 */
base64 = (char *) alloca (BASE64_LENGTH (size) + 1);
base64_encode (ntlmbuf, size, base64);
wget_base64_encode (ntlmbuf, size, base64);
output = concat_strings ("NTLM ", base64, (char *) 0);

View File

@@ -1,8 +1,8 @@
#ifndef __HTTP_NTLM_H
#define __HTTP_NTLM_H
/* Declarations for http_ntlm.c
Copyright (C) 1995, 1996, 1997, 2000, 2007, 2008, 2009, 2010, 2011,
2015 Free Software Foundation, Inc.
Copyright (C) 1995-1997, 2000, 2007-2011, 2015, 2018 Free Software
Foundation, Inc.
Contributed by Daniel Stenberg.
This file is part of GNU Wget.

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,5 @@
/* Declarations for HTTP.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
Copyright (C) 2005-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -35,7 +34,7 @@ as that of the covered work. */
struct url;
uerr_t http_loop (struct url *, struct url *, char **, char **, const char *,
uerr_t http_loop (const struct url *, struct url *, char **, char **, const char *,
int *, struct url *, struct iri *);
void save_cookies (void);
void http_cleanup (void);

View File

@@ -1,7 +1,6 @@
/* Reading/parsing the initialization file.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2014, 2015 Free
Software Foundation, Inc.
Copyright (C) 1996-2012, 2014-2015, 2018 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -97,6 +96,11 @@ CMD_DECLARE (cmd_directory);
CMD_DECLARE (cmd_time);
CMD_DECLARE (cmd_vector);
CMD_DECLARE (cmd_use_askpass);
#ifdef HAVE_LIBZ
CMD_DECLARE (cmd_spec_compression);
#endif
CMD_DECLARE (cmd_spec_dirstruct);
CMD_DECLARE (cmd_spec_header);
CMD_DECLARE (cmd_spec_warc_header);
@@ -115,6 +119,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,
@@ -142,6 +147,9 @@ static const struct {
{ "backups", &opt.backups, cmd_number },
{ "base", &opt.base_href, cmd_string },
{ "bindaddress", &opt.bind_address, cmd_string },
#ifdef HAVE_LIBCARES
{ "binddnsaddress", &opt.bind_dns_address, cmd_string },
#endif
{ "bodydata", &opt.body_data, cmd_string },
{ "bodyfile", &opt.body_file, cmd_string },
#ifdef HAVE_SSL
@@ -152,9 +160,12 @@ 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 },
#ifdef HAVE_LIBZ
{ "compression", &opt.compression, cmd_spec_compression },
#endif
{ "connecttimeout", &opt.connect_timeout, cmd_time },
{ "contentdisposition", &opt.content_disposition, cmd_boolean },
{ "contentonerror", &opt.content_on_error, cmd_boolean },
@@ -172,6 +183,9 @@ static const struct {
{ "dirprefix", &opt.dir_prefix, cmd_directory },
{ "dirstruct", NULL, cmd_spec_dirstruct },
{ "dnscache", &opt.dns_cache, cmd_boolean },
#ifdef HAVE_LIBCARES
{ "dnsservers", &opt.dns_servers, cmd_string },
#endif
{ "dnstimeout", &opt.dns_timeout, cmd_time },
{ "domains", &opt.domains, cmd_vector },
{ "dotbytes", &opt.dot_bytes, cmd_bytes },
@@ -203,7 +217,7 @@ static const struct {
{ "header", NULL, cmd_spec_header },
#ifdef HAVE_HSTS
{ "hsts", &opt.hsts, cmd_boolean },
{ "hsts-file", &opt.hsts_file, cmd_file },
{ "hstsfile", &opt.hsts_file, cmd_file },
#endif
{ "htmlextension", &opt.adjust_extension, cmd_boolean }, /* deprecated */
{ "htmlify", NULL, cmd_spec_htmlify },
@@ -216,7 +230,7 @@ static const struct {
#endif
{ "httpsproxy", &opt.https_proxy, cmd_string },
{ "httpuser", &opt.http_user, cmd_string },
{ "if-modified-since", &opt.if_modified_since, cmd_boolean },
{ "ifmodifiedsince", &opt.if_modified_since, cmd_boolean },
{ "ignorecase", &opt.ignore_case, cmd_boolean },
{ "ignorelength", &opt.ignore_length, cmd_boolean },
{ "ignoretags", &opt.ignore_tags, cmd_vector },
@@ -227,9 +241,10 @@ static const struct {
#endif
{ "input", &opt.input_filename, cmd_file },
#ifdef HAVE_METALINK
{ "input-metalink", &opt.input_metalink, cmd_file },
{ "inputmetalink", &opt.input_metalink, cmd_file },
#endif
{ "iri", &opt.enable_iri, cmd_boolean },
{ "keepbadhash", &opt.keep_badhash, cmd_boolean },
{ "keepsessioncookies", &opt.keep_session_cookies, cmd_boolean },
{ "limitrate", &opt.limit_rate, cmd_bytes },
{ "loadcookies", &opt.cookies_input, cmd_file },
@@ -238,7 +253,8 @@ static const struct {
{ "login", &opt.ftp_user, cmd_string },/* deprecated*/
{ "maxredirect", &opt.max_redirect, cmd_number },
#ifdef HAVE_METALINK
{ "metalink-over-http", &opt.metalink_over_http, cmd_boolean },
{ "metalinkindex", &opt.metalink_index, cmd_number_inf },
{ "metalinkoverhttp", &opt.metalink_over_http, cmd_boolean },
#endif
{ "method", &opt.method, cmd_string_uppercase },
{ "mirror", NULL, cmd_spec_mirror },
@@ -253,11 +269,14 @@ static const struct {
{ "passiveftp", &opt.ftp_pasv, cmd_boolean },
{ "passwd", &opt.ftp_passwd, cmd_string },/* deprecated*/
{ "password", &opt.passwd, cmd_string },
#ifdef HAVE_SSL
{ "pinnedpubkey", &opt.pinnedpubkey, cmd_string },
#endif
{ "postdata", &opt.post_data, cmd_string },
{ "postfile", &opt.post_file_name, cmd_file },
{ "preferfamily", NULL, cmd_spec_prefer_family },
#ifdef HAVE_METALINK
{ "preferred-location", &opt.preferred_location, cmd_string },
{ "preferredlocation", &opt.preferred_location, cmd_string },
#endif
{ "preservepermissions", &opt.preserve_perm, cmd_boolean },
#ifdef HAVE_SSL
@@ -290,6 +309,7 @@ static const struct {
{ "restrictfilenames", NULL, cmd_spec_restrict_file_names },
{ "retrsymlinks", &opt.retr_symlinks, cmd_boolean },
{ "retryconnrefused", &opt.retry_connrefused, cmd_boolean },
{ "retryonhttperror", &opt.retry_on_http_error, cmd_string },
{ "robots", &opt.use_robots, cmd_boolean },
{ "savecookies", &opt.cookies_output, cmd_file },
{ "saveheaders", &opt.save_headers, cmd_boolean },
@@ -307,7 +327,8 @@ static const struct {
{ "timestamping", &opt.timestamping, cmd_boolean },
{ "tries", &opt.ntry, cmd_number_inf },
{ "trustservernames", &opt.trustservernames, cmd_boolean },
{ "unlink", &opt.unlink, cmd_boolean },
{ "unlink", &opt.unlink_requested, cmd_boolean },
{ "useaskpass" , &opt.use_askpass, cmd_use_askpass },
{ "useproxy", &opt.use_proxy, cmd_boolean },
{ "user", &opt.user, cmd_string },
{ "useragent", NULL, cmd_spec_useragent },
@@ -329,6 +350,9 @@ static const struct {
#ifdef USE_WATT32
{ "wdebug", &opt.wdebug, cmd_boolean },
#endif
#ifdef ENABLE_XATTR
{ "xattr", &opt.enable_xattr, cmd_boolean },
#endif
};
/* Look up CMDNAME in the commands[] and return its position in the
@@ -368,6 +392,10 @@ defaults (void)
bit pattern will be the least of the implementors' worries. */
xzero (opt);
#ifdef HAVE_METALINK
opt.metalink_index = -1;
#endif
opt.cookies = true;
opt.verbose = -1;
opt.ntry = 20;
@@ -415,13 +443,17 @@ 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;
opt.ftps_clear_data_connection = false;
#endif
#ifdef HAVE_LIBZ
opt.compression = compression_none;
#endif
/* The default for file name restriction defaults to the OS type. */
#if defined(WINDOWS) || defined(MSDOS) || defined(__CYGWIN__)
opt.restrict_files_os = restrict_windows;
@@ -472,6 +504,12 @@ defaults (void)
/* HSTS is enabled by default */
opt.hsts = true;
#endif
#ifdef ENABLE_XATTR
opt.enable_xattr = true;
#else
opt.enable_xattr = false;
#endif
}
/* Return the user's home directory (strdup-ed), or NULL if none is
@@ -537,10 +575,11 @@ wgetrc_env_file_name (void)
char *env = getenv ("WGETRC");
if (env && *env)
{
if (!file_exists_p (env))
file_stats_t flstat;
if (!file_exists_p (env, &flstat))
{
fprintf (stderr, _("%s: WGETRC points to %s, which doesn't exist.\n"),
exec_name, env);
fprintf (stderr, _("%s: WGETRC points to %s, which couldn't be accessed because of error: %s.\n"),
exec_name, env, strerror(flstat.access_err));
exit (WGET_EXIT_GENERIC_ERROR);
}
return xstrdup (env);
@@ -548,7 +587,7 @@ wgetrc_env_file_name (void)
return NULL;
}
/* Check for the existance of '$HOME/.wgetrc' and return its path
/* Check for the existence of '$HOME/.wgetrc' and return its path
if it exists and is set. */
char *
wgetrc_user_file_name (void)
@@ -568,7 +607,7 @@ wgetrc_user_file_name (void)
if (!file)
return NULL;
if (!file_exists_p (file))
if (!file_exists_p (file, NULL))
{
xfree (file);
return NULL;
@@ -601,7 +640,7 @@ wgetrc_file_name (void)
if (home)
{
file = aprintf ("%s/wget.ini", home);
if (!file_exists_p (file))
if (!file_exists_p (file, NULL))
{
xfree (file);
}
@@ -629,7 +668,7 @@ static bool setval_internal_tilde (int, const char *, const char *);
there were errors in the file. */
bool
run_wgetrc (const char *file)
run_wgetrc (const char *file, file_stats_t *flstats)
{
FILE *fp;
char *line = NULL;
@@ -637,7 +676,7 @@ run_wgetrc (const char *file)
int ln;
int errcnt = 0;
fp = fopen (file, "r");
fp = fopen_stat (file, "r", flstats);
if (!fp)
{
fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
@@ -693,14 +732,16 @@ void
initialize (void)
{
char *file, *env_sysrc;
file_stats_t flstats;
bool ok = true;
memset(&flstats, 0, sizeof(flstats));
/* Run a non-standard system rc file when the according environment
variable has been set. For internal testing purposes only! */
env_sysrc = getenv ("SYSTEM_WGETRC");
if (env_sysrc && file_exists_p (env_sysrc))
if (env_sysrc && file_exists_p (env_sysrc, &flstats))
{
ok &= run_wgetrc (env_sysrc);
ok &= run_wgetrc (env_sysrc, &flstats);
/* If there are any problems parsing the system wgetrc file, tell
the user and exit */
if (! ok)
@@ -714,8 +755,8 @@ or specify a different file using --config.\n"), env_sysrc);
}
/* Otherwise, if SYSTEM_WGETRC is defined, use it. */
#ifdef SYSTEM_WGETRC
else if (file_exists_p (SYSTEM_WGETRC))
ok &= run_wgetrc (SYSTEM_WGETRC);
else if (file_exists_p (SYSTEM_WGETRC, &flstats))
ok &= run_wgetrc (SYSTEM_WGETRC, &flstats);
/* If there are any problems parsing the system wgetrc file, tell
the user and exit */
if (! ok)
@@ -742,7 +783,8 @@ or specify a different file using --config.\n"), SYSTEM_WGETRC);
}
else
#endif
ok &= run_wgetrc (file);
if (file_exists_p (file, &flstats))
ok &= run_wgetrc (file, &flstats);
/* If there were errors processing either `.wgetrc', abort. */
if (!ok)
@@ -849,6 +891,10 @@ static bool
setval_internal (int comind, const char *com, const char *val)
{
assert (0 <= comind && ((size_t) comind) < countof (commands));
if ((unsigned) comind >= countof (commands))
return NULL;
DEBUGP (("Setting %s (%s) to %s\n", com, commands[comind].name, val));
return commands[comind].action (com, val, commands[comind].place);
}
@@ -955,6 +1001,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 +1020,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
@@ -1311,6 +1407,32 @@ cmd_time (const char *com, const char *val, void *place)
return true;
}
static bool
cmd_use_askpass (const char *com _GL_UNUSED, const char *val, void *place)
{
const char *env_name = "WGET_ASKPASS";
const char *env;
if (val && *val)
return cmd_string (com, val, place);
env = getenv (env_name);
if (!(env && *env))
{
env_name = "SSH_ASKPASS";
env = getenv (env_name);
}
if (!(env && *env))
{
fprintf (stderr, _("use-askpass requires a string or either environment variable WGET_ASKPASS or SSH_ASKPASS to be set.\n"));
exit (WGET_EXIT_GENERIC_ERROR);
}
return cmd_string (com, env, place);
}
#ifdef HAVE_SSL
static bool
cmd_cert_type (const char *com, const char *val, void *place)
@@ -1332,6 +1454,25 @@ cmd_cert_type (const char *com, const char *val, void *place)
static bool check_user_specified_header (const char *);
#ifdef HAVE_LIBZ
static bool
cmd_spec_compression (const char *com, const char *val, void *place)
{
static const struct decode_item choices[] = {
{ "auto", compression_auto },
{ "gzip", compression_gzip },
{ "none", compression_none },
};
int ok = decode_string (val, choices, countof (choices), place);
if (!ok)
{
fprintf (stderr, _("%s: %s: Invalid value %s.\n"), exec_name, com,
quote (val));
}
return ok;
}
#endif
static bool
cmd_spec_dirstruct (const char *com, const char *val, void *place_ignored _GL_UNUSED)
{
@@ -1870,6 +2011,20 @@ cleanup (void)
xfree (opt.body_data);
xfree (opt.body_file);
xfree (opt.rejected_log);
xfree (opt.use_askpass);
xfree (opt.retry_on_http_error);
#ifdef HAVE_LIBCARES
#include <ares.h>
{
extern ares_channel ares;
xfree (opt.bind_dns_address);
xfree (opt.dns_servers);
ares_destroy (ares);
ares_library_cleanup ();
}
#endif
#endif /* DEBUG_MALLOC */
}

View File

@@ -1,7 +1,5 @@
/* Declarations for init.c.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -41,6 +39,6 @@ void setoptval (const char *, const char *, const char *);
char *home_dir (void);
void cleanup (void);
void defaults (void);
bool run_wgetrc (const char *file);
bool run_wgetrc (const char *file, file_stats_t *);
#endif /* INIT_H */

169
src/iri.c
View File

@@ -1,6 +1,5 @@
/* IRI related functions.
Copyright (C) 2008, 2009, 2010, 2011, 2015 Free Software Foundation,
Inc.
Copyright (C) 2008-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -33,11 +32,16 @@ as that of the covered work. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iconv.h>
#include <stringprep.h>
#include <idna.h>
#include <idn-free.h>
#include <langinfo.h>
#include <errno.h>
#ifdef HAVE_ICONV
# include <iconv.h>
#endif
#include <idn2.h>
#if IDN2_VERSION_NUMBER < 0x00140000
# include <unicase.h>
# include <unistr.h>
#endif
#include "utils.h"
#include "url.h"
@@ -45,9 +49,6 @@ as that of the covered work. */
#include "c-strcasestr.h"
#include "xstrndup.h"
/* RFC3987 section 3.1 mandates STD3 ASCII RULES */
#define IDNA_FLAGS IDNA_USE_STD3_ASCII_RULES
/* Note: locale encoding is kept in options struct (opt.locale) */
/* Given a string containing "charset=XXX", return the encoding if found,
@@ -88,10 +89,15 @@ parse_charset (const char *str)
}
/* Find the locale used, or fall back on a default value */
char *
const char *
find_locale (void)
{
return (char *) stringprep_locale_charset ();
const char *encoding = nl_langinfo(CODESET);
if (!encoding || !*encoding)
return "ASCII";
return encoding;
}
/* Basic check of an encoding name. */
@@ -114,6 +120,7 @@ check_encoding_name (const char *encoding)
return true;
}
#ifdef HAVE_ICONV
/* Do the conversion according to the passed conversion descriptor cd. *out
will contain the transcoded string on success. *out content is
unspecified otherwise. */
@@ -129,8 +136,8 @@ do_conversion (const char *tocode, const char *fromcode, char const *in_org, siz
cd = iconv_open (tocode, fromcode);
if (cd == (iconv_t)(-1))
{
logprintf (LOG_VERBOSE, _("Conversion from %s to UTF-8 isn't supported\n"),
quote (opt.locale));
logprintf (LOG_VERBOSE, _("Conversion from %s to %s isn't supported\n"),
quote (fromcode), quote (tocode));
*out = NULL;
return false;
}
@@ -146,7 +153,8 @@ do_conversion (const char *tocode, const char *fromcode, char const *in_org, siz
for (;;)
{
if (iconv (cd, &in, &inlen, out, &outlen) != (size_t)(-1))
if (iconv (cd, (ICONV_CONST char **) &in, &inlen, out, &outlen) != (size_t)(-1) &&
iconv (cd, NULL, NULL, out, &outlen) != (size_t)(-1))
{
*out = s;
*(s + len - outlen - done) = '\0';
@@ -158,7 +166,7 @@ do_conversion (const char *tocode, const char *fromcode, char const *in_org, siz
if (!strchr(in_org, '@') && !strchr(*out, '@'))
debug_logprintf ("converted '%s' (%s) -> '%s' (%s)\n", in_org, fromcode, *out, tocode);
else
debug_logprintf ("%s: logging suppressed, strings may contain password\n", __func__);
debug_logprintf ("logging suppressed, strings may contain password\n");
}
return true;
}
@@ -179,16 +187,10 @@ do_conversion (const char *tocode, const char *fromcode, char const *in_org, siz
}
else if (errno == E2BIG) /* Output buffer full */
{
char *new;
tooshort++;
done = len;
outlen = done + inlen * 2;
new = xmalloc (outlen + 1);
memcpy (new, s, done);
xfree (s);
s = new;
len = outlen;
len = outlen = done + inlen * 2;
s = xrealloc (s, outlen + 1);
*out = s + done;
}
else /* Weird, we got an unspecified error */
@@ -206,10 +208,19 @@ do_conversion (const char *tocode, const char *fromcode, char const *in_org, siz
if (!strchr(in_org, '@') && !strchr(*out, '@'))
debug_logprintf ("converted '%s' (%s) -> '%s' (%s)\n", in_org, fromcode, *out, tocode);
else
debug_logprintf ("%s: logging suppressed, strings may contain password\n", __func__);
debug_logprintf ("logging suppressed, strings may contain password\n");
}
return false;
}
#else
static bool
do_conversion (const char *tocode _GL_UNUSED, const char *fromcode _GL_UNUSED,
char const *in_org _GL_UNUSED, size_t inlen _GL_UNUSED, char **out)
{
*out = NULL;
return false;
}
#endif
/* Try converting string str from locale to UTF-8. Return a new string
on success, or str on error or if conversion isn't needed. */
@@ -235,50 +246,6 @@ locale_to_utf8 (const char *str)
return str;
}
/*
* Work around a libidn <= 1.30 vulnerability.
*
* The function checks for a valid UTF-8 character sequence before
* passing it to idna_to_ascii_8z().
*
* [1] http://lists.gnu.org/archive/html/help-libidn/2015-05/msg00002.html
* [2] https://lists.gnu.org/archive/html/bug-wget/2015-06/msg00002.html
* [3] http://curl.haxx.se/mail/lib-2015-06/0143.html
*/
static bool
_utf8_is_valid(const char *utf8)
{
const unsigned char *s = (const unsigned char *) utf8;
while (*s)
{
if ((*s & 0x80) == 0) /* 0xxxxxxx ASCII char */
s++;
else if ((*s & 0xE0) == 0xC0) /* 110xxxxx 10xxxxxx */
{
if ((s[1] & 0xC0) != 0x80)
return false;
s+=2;
}
else if ((*s & 0xF0) == 0xE0) /* 1110xxxx 10xxxxxx 10xxxxxx */
{
if ((s[1] & 0xC0) != 0x80 || (s[2] & 0xC0) != 0x80)
return false;
s+=3;
}
else if ((*s & 0xF8) == 0xF0) /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
{
if ((s[1] & 0xC0) != 0x80 || (s[2] & 0xC0) != 0x80 || (s[3] & 0xC0) != 0x80)
return false;
s+=4;
}
else
return false;
}
return true;
}
/* Try to "ASCII encode" UTF-8 host. Return the new domain on success or NULL
on error. */
char *
@@ -287,34 +254,62 @@ idn_encode (const struct iri *i, const char *host)
int ret;
char *ascii_encoded;
char *utf8_encoded = NULL;
const char *src;
#if IDN2_VERSION_NUMBER < 0x00140000
uint8_t *lower;
size_t len = 0;
#endif
/* Encode to UTF-8 if not done */
if (!i->utf8_encode)
{
if (!remote_to_utf8 (i, host, &utf8_encoded))
return NULL; /* Nothing to encode or an error occured */
return NULL; /* Nothing to encode or an error occurred */
src = utf8_encoded;
}
else
src = host;
if (!_utf8_is_valid(utf8_encoded ? utf8_encoded : host))
#if IDN2_VERSION_NUMBER >= 0x00140000
/* IDN2_TRANSITIONAL implies input NFC encoding */
ret = idn2_lookup_u8 ((uint8_t *) src, (uint8_t **) &ascii_encoded, IDN2_NONTRANSITIONAL);
if (ret != IDN2_OK)
/* fall back to TR46 Transitional mode, max IDNA2003 compatibility */
ret = idn2_lookup_u8 ((uint8_t *) src, (uint8_t **) &ascii_encoded, IDN2_TRANSITIONAL);
if (ret != IDN2_OK)
logprintf (LOG_VERBOSE, _("idn_encode failed (%d): %s\n"), ret,
quote (idn2_strerror (ret)));
#else
/* we need a conversion to lowercase */
lower = u8_tolower ((uint8_t *) src, u8_strlen ((uint8_t *) src) + 1, 0, UNINORM_NFKC, NULL, &len);
if (!lower)
{
logprintf (LOG_VERBOSE, _("Invalid UTF-8 sequence: %s\n"),
quote(utf8_encoded ? utf8_encoded : host));
logprintf (LOG_VERBOSE, _("Failed to convert to lower: %d: %s\n"),
errno, quote (src));
xfree (utf8_encoded);
return NULL;
}
/* Store in ascii_encoded the ASCII UTF-8 NULL terminated string */
ret = idna_to_ascii_8z (utf8_encoded ? utf8_encoded : host, &ascii_encoded, IDNA_FLAGS);
xfree (utf8_encoded);
if (ret != IDNA_SUCCESS)
if ((ret = idn2_lookup_u8 (lower, (uint8_t **) &ascii_encoded, IDN2_NFC_INPUT)) != IDN2_OK)
{
logprintf (LOG_VERBOSE, _("idn_encode failed (%d): %s\n"), ret,
quote (idna_strerror (ret)));
return NULL;
quote (idn2_strerror (ret)));
}
return ascii_encoded;
xfree (lower);
#endif
xfree (utf8_encoded);
if (ret == IDN2_OK && ascii_encoded)
{
char *tmp = xstrdup (ascii_encoded);
idn2_free (ascii_encoded);
ascii_encoded = tmp;
}
return ret == IDN2_OK ? ascii_encoded : NULL;
}
/* Try to decode an "ASCII encoded" host. Return the new domain in the locale
@@ -322,18 +317,24 @@ idn_encode (const struct iri *i, const char *host)
char *
idn_decode (const char *host)
{
/*
char *new;
int ret;
ret = idna_to_unicode_8zlz (host, &new, IDNA_FLAGS);
if (ret != IDNA_SUCCESS)
ret = idn2_register_u8 (NULL, host, (uint8_t **) &new, 0);
if (ret != IDN2_OK)
{
logprintf (LOG_VERBOSE, _("idn_decode failed (%d): %s\n"), ret,
quote (idna_strerror (ret)));
logprintf (LOG_VERBOSE, _("idn2_register_u8 failed (%d): %s: %s\n"), ret,
quote (idn2_strerror (ret)), host);
return NULL;
}
return new;
*/
/* idn2_register_u8() just works label by label.
* That is pretty much overhead for just displaying the original ulabels.
* To keep at least the debug output format, return a cloned host. */
return xstrdup(host);
}
/* Try to transcode string str from remote encoding to UTF-8. On success, *new

View File

@@ -1,6 +1,5 @@
/* Internationalization related declarations.
Copyright (C) 2008, 2009, 2010, 2011, 2015 Free Software Foundation,
Inc.
Copyright (C) 2008-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -40,11 +39,8 @@ struct iri {
#ifdef ENABLE_IRI
# include <idna.h>
# include <idn-free.h>
char *parse_charset (const char *str);
char *find_locale (void);
const char *find_locale (void);
bool check_encoding_name (const char *encoding);
const char *locale_to_utf8 (const char *str);
char *idn_encode (const struct iri *i, const char *host);
@@ -60,13 +56,13 @@ void set_content_encoding (struct iri *i, const char *charset);
extern struct iri dummy_iri;
#define parse_charset(str) (str, NULL)
#define parse_charset(str) NULL
#define find_locale() NULL
#define check_encoding_name(str) false
#define locale_to_utf8(str) (str)
#define idn_encode(a,b) NULL
#define idn_decode(str) NULL
#define idn_free(str) ((void)0)
#define idn2_free(str) ((void)0)
#define remote_to_utf8(a,b,c) false
#define iri_new() (&dummy_iri)
#define iri_dup(a) (&dummy_iri)

149
src/log.c
View File

@@ -1,6 +1,5 @@
/* Messages logging.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2015 Free Software Foundation, Inc.
Copyright (C) 1998-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -80,6 +79,18 @@ as that of the covered work. */
logging is inhibited, logfp is set back to NULL. */
static FILE *logfp;
/* Descriptor of the stdout|stderr */
static FILE *stdlogfp;
/* Descriptor of the wget.log* file (if created) */
static FILE *filelogfp;
/* Name of log file */
static char *logfile;
/* Is interactive shell ? */
static int shell_is_interactive;
/* A second file descriptor pointing to the temporary log file for the
WARC writer. If WARC writing is disabled, this is NULL. */
static FILE *warclogfp;
@@ -332,7 +343,9 @@ get_warc_log_fp (void)
return NULL;
if (warclogfp)
return warclogfp;
return NULL;
if (logfp)
return NULL;
return stderr;
}
/* Sets the file descriptor for the secondary log file. */
@@ -351,6 +364,7 @@ logputs (enum log_options o, const char *s)
{
FILE *fp;
FILE *warcfp;
int errno_save = errno;
check_redirect_output ();
if (o == LOG_PROGRESS)
@@ -358,10 +372,14 @@ logputs (enum log_options o, const char *s)
else
fp = get_log_fp ();
errno = errno_save;
if (fp == NULL)
return;
warcfp = get_warc_log_fp ();
errno = errno_save;
CHECK_VERBOSE (o);
FPUTS (s, fp);
@@ -373,6 +391,8 @@ logputs (enum log_options o, const char *s)
logflush ();
else
needs_flushing = true;
errno = errno_save;
}
struct logvprintf_state {
@@ -513,7 +533,7 @@ log_set_flush (bool flush)
}
else
{
/* Reenable flushing. If anything was printed in no-flush mode,
/* Re-enable flushing. If anything was printed in no-flush mode,
flush the log now. */
if (needs_flushing)
logflush ();
@@ -543,8 +563,10 @@ logprintf (enum log_options o, const char *fmt, ...)
va_list args;
struct logvprintf_state lpstate;
bool done;
int errno_saved = errno;
check_redirect_output ();
errno = errno_saved;
if (inhibit_logging)
return;
CHECK_VERBOSE (o);
@@ -561,6 +583,8 @@ logprintf (enum log_options o, const char *fmt, ...)
exit (WGET_EXIT_GENERIC_ERROR);
}
while (!done);
errno = errno_saved;
}
#ifdef ENABLE_DEBUG
@@ -600,16 +624,18 @@ log_init (const char *file, bool appendp)
{
if (HYPHENP (file))
{
logfp = stdout;
stdlogfp = stdout;
logfp = stdlogfp;
}
else
{
logfp = fopen (file, appendp ? "a" : "w");
if (!logfp)
filelogfp = fopen (file, appendp ? "a" : "w");
if (!filelogfp)
{
fprintf (stderr, "%s: %s: %s\n", exec_name, file, strerror (errno));
exit (WGET_EXIT_GENERIC_ERROR);
}
logfp = filelogfp;
}
}
else
@@ -620,7 +646,8 @@ log_init (const char *file, bool appendp)
stderr only if the user actually specifies `-O -'. He says
this inconsistency is harder to document, but is overall
easier on the user. */
logfp = stderr;
stdlogfp = stderr;
logfp = stdlogfp;
if (1
#ifdef HAVE_ISATTY
@@ -635,6 +662,11 @@ log_init (const char *file, bool appendp)
save_context_p = true;
}
}
#ifndef WINDOWS
/* Initialize this values so we don't have to ask every time we print line */
shell_is_interactive = isatty (STDIN_FILENO);
#endif
}
/* Close LOGFP (only if we opened it, not if it's stderr), inhibit
@@ -869,59 +901,80 @@ log_cleanup (void)
/* When SIGHUP or SIGUSR1 are received, the output is redirected
elsewhere. Such redirection is only allowed once. */
static enum { RR_NONE, RR_REQUESTED, RR_DONE } redirect_request = RR_NONE;
static const char *redirect_request_signal_name;
/* Redirect output to `wget-log'. */
/* Redirect output to `wget-log' or back to stdout/stderr. */
static void
redirect_output (void)
void
redirect_output (bool to_file, const char *signal_name)
{
char *logfile;
logfp = unique_create (DEFAULT_LOGFILE, false, &logfile);
if (logfp)
if (to_file && logfp != filelogfp)
{
fprintf (stderr, _("\n%s received, redirecting output to %s.\n"),
redirect_request_signal_name, quote (logfile));
xfree (logfile);
/* Dump the context output to the newly opened log. */
if (signal_name)
{
fprintf (stderr, "\n%s received.", signal_name);
}
if (!filelogfp)
{
filelogfp = unique_create (DEFAULT_LOGFILE, false, &logfile);
if (filelogfp)
{
fprintf (stderr, _("\nRedirecting output to %s.\n"),
quote (logfile));
/* Store signal name to tell wget it's permanent redirect to log file */
redirect_request_signal_name = signal_name;
logfp = filelogfp;
/* Dump the context output to the newly opened log. */
log_dump_context ();
}
else
{
/* Eek! Opening the alternate log file has failed. Nothing we
can do but disable printing completely. */
fprintf (stderr, _("%s: %s; disabling logging.\n"),
(logfile) ? logfile : DEFAULT_LOGFILE, strerror (errno));
inhibit_logging = true;
}
}
else
{
fprintf (stderr, _("\nRedirecting output to %s.\n"),
quote (logfile));
logfp = filelogfp;
log_dump_context ();
}
}
else if (!to_file && logfp != stdlogfp)
{
logfp = stdlogfp;
log_dump_context ();
}
else
{
/* Eek! Opening the alternate log file has failed. Nothing we
can do but disable printing completely. */
fprintf (stderr, _("\n%s received.\n"), redirect_request_signal_name);
fprintf (stderr, _("%s: %s; disabling logging.\n"),
(logfile) ? logfile : DEFAULT_LOGFILE, strerror (errno));
inhibit_logging = true;
}
save_context_p = false;
}
/* Check whether a signal handler requested the output to be
redirected. */
/* Check whether there's a need to redirect output. */
static void
check_redirect_output (void)
{
if (redirect_request == RR_REQUESTED)
#ifndef WINDOWS
/* If it was redirected already to log file by SIGHUP, SIGUSR1 or -o parameter,
* it was permanent.
* If there was no SIGHUP or SIGUSR1 and shell is interactive
* we check if process is fg or bg before every line is printed.*/
if (!redirect_request_signal_name && shell_is_interactive && !opt.lfilename)
{
redirect_request = RR_DONE;
redirect_output ();
pid_t foreground_pgrp = tcgetpgrp (STDIN_FILENO);
if (foreground_pgrp != -1 && foreground_pgrp != getpgrp ())
{
/* Process backgrounded */
redirect_output (true,NULL);
}
else
{
/* Process foregrounded */
redirect_output (false,NULL);
}
}
}
/* Request redirection at a convenient time. This may be called from
a signal handler. */
void
log_request_redirect_output (const char *signal_name)
{
if (redirect_request == RR_NONE && save_context_p)
/* Request output redirection. The request will be processed by
check_redirect_output(), which is called from entry point log
functions. */
redirect_request = RR_REQUESTED;
redirect_request_signal_name = signal_name;
#endif /* WINDOWS */
}

View File

@@ -1,6 +1,5 @@
/* Declarations for log.c.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2015 Free Software Foundation, Inc.
Copyright (C) 1998-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -52,6 +51,7 @@ void log_init (const char *, bool);
void log_close (void);
void log_cleanup (void);
void log_request_redirect_output (const char *);
void redirect_output (bool, const char *);
const char *escnonprint (const char *);
const char *escnonprint_uri (const char *);

View File

@@ -1,7 +1,5 @@
/* Command line parsing.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Free
Software Foundation, Inc.
Copyright (C) 1996-2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -36,7 +34,8 @@ as that of the covered work. */
#include <unistd.h>
#include <string.h>
#include <signal.h>
#ifdef ENABLE_NLS
#include <spawn.h>
#if defined(ENABLE_NLS) || defined(WINDOWS)
# include <locale.h>
#endif
#include <assert.h>
@@ -60,6 +59,7 @@ as that of the covered work. */
#include "version.h"
#include "c-strcase.h"
#include "dirname.h"
#include "xmemdup0.h"
#include <getopt.h>
#include <getpass.h>
#include <quote.h>
@@ -72,6 +72,9 @@ as that of the covered work. */
#ifdef WINDOWS
# include <io.h>
# include <fcntl.h>
#ifndef ENABLE_NLS
# include <mbctype.h>
#endif
#endif
#ifdef __VMS
@@ -86,6 +89,13 @@ as that of the covered work. */
struct iri dummy_iri;
#endif
#ifdef HAVE_LIBCARES
#include <ares.h>
ares_channel ares;
#else
void *ares;
#endif
struct options opt;
/* defined in version.c */
@@ -123,7 +133,7 @@ redirect_output_signal (int sig)
signal_name = "SIGUSR1";
#endif
log_request_redirect_output (signal_name);
redirect_output (true,signal_name);
progress_schedule_redirect ();
signal (sig, redirect_output_signal);
}
@@ -139,6 +149,14 @@ i18n_initialize (void)
/* Set the text message domain. */
bindtextdomain ("wget", LOCALEDIR);
textdomain ("wget");
#elif defined WINDOWS
char MBCP[16] = "";
int CP;
CP = _getmbcp(); /* Consider it's different from default. */
if (CP > 0)
snprintf(MBCP, sizeof(MBCP), ".%d", CP);
setlocale(LC_ALL, MBCP);
#endif /* ENABLE_NLS */
}
@@ -197,10 +215,12 @@ save_hsts (void)
{
char *filename = get_hsts_database ();
if (filename)
DEBUGP (("Saving HSTS entries to %s\n", filename));
if (filename && hsts_store_has_changed (hsts_store))
{
DEBUGP (("Saving HSTS entries to %s\n", filename));
hsts_store_save (hsts_store, filename);
}
hsts_store_save (hsts_store, filename);
hsts_store_close (hsts_store);
xfree (filename);
@@ -210,8 +230,8 @@ save_hsts (void)
/* Definition of command-line options. */
static void _Noreturn print_help (void);
static void _Noreturn print_version (void);
_Noreturn static void print_help (void);
_Noreturn static void print_version (void);
#ifdef HAVE_SSL
# define IF_SSL(x) x
@@ -252,6 +272,9 @@ static struct cmdline_option option_data[] =
{ "backups", 0, OPT_BOOLEAN, "backups", -1 },
{ "base", 'B', OPT_VALUE, "base", -1 },
{ "bind-address", 0, OPT_VALUE, "bindaddress", -1 },
#ifdef HAVE_LIBCARES
{ "bind-dns-address", 0, OPT_VALUE, "binddnsaddress", -1 },
#endif
{ "body-data", 0, OPT_VALUE, "bodydata", -1 },
{ "body-file", 0, OPT_VALUE, "bodyfile", -1 },
{ IF_SSL ("ca-certificate"), 0, OPT_VALUE, "cacertificate", -1 },
@@ -261,6 +284,9 @@ static struct cmdline_option option_data[] =
{ IF_SSL ("certificate-type"), 0, OPT_VALUE, "certificatetype", -1 },
{ IF_SSL ("check-certificate"), 0, OPT_BOOLEAN, "checkcertificate", -1 },
{ "clobber", 0, OPT__CLOBBER, NULL, optional_argument },
#ifdef HAVE_LIBZ
{ "compression", 0, OPT_VALUE, "compression", -1 },
#endif
{ "config", 0, OPT_VALUE, "chooseconfig", -1 },
{ "connect-timeout", 0, OPT_VALUE, "connecttimeout", -1 },
{ "continue", 'c', OPT_BOOLEAN, "continue", -1 },
@@ -277,6 +303,9 @@ static struct cmdline_option option_data[] =
{ "directories", 0, OPT_BOOLEAN, "dirstruct", -1 },
{ "directory-prefix", 'P', OPT_VALUE, "dirprefix", -1 },
{ "dns-cache", 0, OPT_BOOLEAN, "dnscache", -1 },
#ifdef HAVE_LIBCARES
{ "dns-servers", 0, OPT_VALUE, "dnsservers", -1 },
#endif
{ "dns-timeout", 0, OPT_VALUE, "dnstimeout", -1 },
{ "domains", 'D', OPT_VALUE, "domains", -1 },
{ "dont-remove-listing", 0, OPT__DONT_REMOVE_LISTING, NULL, no_argument },
@@ -306,7 +335,7 @@ static struct cmdline_option option_data[] =
{ "host-directories", 0, OPT_BOOLEAN, "addhostdir", -1 },
#ifdef HAVE_HSTS
{ "hsts", 0, OPT_BOOLEAN, "hsts", -1},
{ "hsts-file", 0, OPT_VALUE, "hsts-file", -1 },
{ "hsts-file", 0, OPT_VALUE, "hstsfile", -1 },
#endif
{ "html-extension", 'E', OPT_BOOLEAN, "adjustextension", -1 }, /* deprecated */
{ "htmlify", 0, OPT_BOOLEAN, "htmlify", -1 },
@@ -325,9 +354,10 @@ static struct cmdline_option option_data[] =
#endif
{ "input-file", 'i', OPT_VALUE, "input", -1 },
#ifdef HAVE_METALINK
{ "input-metalink", 0, OPT_VALUE, "input-metalink", -1 },
{ "input-metalink", 0, OPT_VALUE, "inputmetalink", -1 },
#endif
{ "iri", 0, OPT_BOOLEAN, "iri", -1 },
{ "keep-badhash", 0, OPT_BOOLEAN, "keepbadhash", -1 },
{ "keep-session-cookies", 0, OPT_BOOLEAN, "keepsessioncookies", -1 },
{ "level", 'l', OPT_VALUE, "reclevel", -1 },
{ "limit-rate", 0, OPT_VALUE, "limitrate", -1 },
@@ -336,10 +366,12 @@ static struct cmdline_option option_data[] =
{ "rejected-log", 0, OPT_VALUE, "rejectedlog", -1 },
{ "max-redirect", 0, OPT_VALUE, "maxredirect", -1 },
#ifdef HAVE_METALINK
{ "metalink-over-http", 0, OPT_BOOLEAN, "metalink-over-http", -1 },
{ "metalink-index", 0, OPT_VALUE, "metalinkindex", -1 },
{ "metalink-over-http", 0, OPT_BOOLEAN, "metalinkoverhttp", -1 },
#endif
{ "method", 0, OPT_VALUE, "method", -1 },
{ "mirror", 'm', OPT_BOOLEAN, "mirror", -1 },
{ "netrc", 0, OPT_BOOLEAN, "netrc", -1 },
{ "no", 'n', OPT__NO, NULL, required_argument },
{ "no-clobber", 0, OPT_BOOLEAN, "noclobber", -1 },
{ "no-config", 0, OPT_BOOLEAN, "noconfig", -1},
@@ -350,11 +382,12 @@ static struct cmdline_option option_data[] =
{ "parent", 0, OPT__PARENT, NULL, optional_argument },
{ "passive-ftp", 0, OPT_BOOLEAN, "passiveftp", -1 },
{ "password", 0, OPT_VALUE, "password", -1 },
{ IF_SSL ("pinnedpubkey"), 0, OPT_VALUE, "pinnedpubkey", -1 },
{ "post-data", 0, OPT_VALUE, "postdata", -1 },
{ "post-file", 0, OPT_VALUE, "postfile", -1 },
{ "prefer-family", 0, OPT_VALUE, "preferfamily", -1 },
#ifdef HAVE_METALINK
{ "preferred-location", 0, OPT_VALUE, "preferred-location", -1 },
{ "preferred-location", 0, OPT_VALUE, "preferredlocation", -1 },
#endif
{ "preserve-permissions", 0, OPT_BOOLEAN, "preservepermissions", -1 },
{ IF_SSL ("private-key"), 0, OPT_VALUE, "privatekey", -1 },
@@ -384,6 +417,7 @@ static struct cmdline_option option_data[] =
{ "restrict-file-names", 0, OPT_BOOLEAN, "restrictfilenames", -1 },
{ "retr-symlinks", 0, OPT_BOOLEAN, "retrsymlinks", -1 },
{ "retry-connrefused", 0, OPT_BOOLEAN, "retryconnrefused", -1 },
{ "retry-on-http-error", 0, OPT_VALUE, "retryonhttperror", -1 },
{ "save-cookies", 0, OPT_VALUE, "savecookies", -1 },
{ "save-headers", 0, OPT_BOOLEAN, "saveheaders", -1 },
{ IF_SSL ("secure-protocol"), 0, OPT_VALUE, "secureprotocol", -1 },
@@ -394,15 +428,15 @@ static struct cmdline_option option_data[] =
{ "strict-comments", 0, OPT_BOOLEAN, "strictcomments", -1 },
{ "timeout", 'T', OPT_VALUE, "timeout", -1 },
{ "timestamping", 'N', OPT_BOOLEAN, "timestamping", -1 },
{ "if-modified-since", 0, OPT_BOOLEAN, "if-modified-since", -1 },
{ "if-modified-since", 0, OPT_BOOLEAN, "ifmodifiedsince", -1 },
{ "tries", 't', OPT_VALUE, "tries", -1 },
{ "unlink", 0, OPT_BOOLEAN, "unlink", -1 },
{ "trust-server-names", 0, OPT_BOOLEAN, "trustservernames", -1 },
{ "use-askpass", 0, OPT_VALUE, "useaskpass", -1},
{ "use-server-timestamps", 0, OPT_BOOLEAN, "useservertimestamps", -1 },
{ "user", 0, OPT_VALUE, "user", -1 },
{ "user-agent", 'U', OPT_VALUE, "useragent", -1 },
{ "verbose", 'v', OPT_BOOLEAN, "verbose", -1 },
{ "verbose", 0, OPT_BOOLEAN, "verbose", -1 },
{ "version", 'V', OPT_FUNCALL, (void *) print_version, no_argument },
{ "wait", 'w', OPT_VALUE, "wait", -1 },
{ "waitretry", 0, OPT_VALUE, "waitretry", -1 },
@@ -419,6 +453,9 @@ static struct cmdline_option option_data[] =
{ "warc-tempdir", 0, OPT_VALUE, "warctempdir", -1 },
#ifdef USE_WATT32
{ "wdebug", 0, OPT_BOOLEAN, "wdebug", -1 },
#endif
#ifdef ENABLE_XATTR
{ "xattr", 0, OPT_BOOLEAN, "xattr", -1 },
#endif
};
@@ -531,7 +568,7 @@ print_usage (int error)
/* Print the help message, describing all the available options. If
you add an option, be sure to update this list. */
static void _Noreturn
_Noreturn static void
print_help (void)
{
/* We split the help text this way to ease translation of individual
@@ -604,6 +641,8 @@ Download:\n"),
N_("\
-nc, --no-clobber skip downloads that would download to\n\
existing files (overwriting them)\n"),
N_("\
--no-netrc don't try to obtain credentials from .netrc\n"),
N_("\
-c, --continue resume getting a partially-downloaded file\n"),
N_("\
@@ -627,6 +666,12 @@ Download:\n"),
--spider don't download anything\n"),
N_("\
-T, --timeout=SECONDS set all timeout values to SECONDS\n"),
#ifdef HAVE_LIBCARES
N_("\
--dns-servers=ADDRESSES list of DNS servers to query (comma separated)\n"),
N_("\
--bind-dns-address=ADDRESS bind DNS resolver to ADDRESS (hostname or IP) on local host\n"),
#endif
N_("\
--dns-timeout=SECS set the DNS lookup timeout to SECS\n"),
N_("\
@@ -668,6 +713,11 @@ Download:\n"),
--password=PASS set both ftp and http password to PASS\n"),
N_("\
--ask-password prompt for passwords\n"),
N_("\
--use-askpass=COMMAND specify credential handler for requesting \n\
username and password. If no COMMAND is \n\
specified the WGET_ASKPASS or the SSH_ASKPASS \n\
environment variable is used.\n"),
N_("\
--no-iri turn off IRI support\n"),
N_("\
@@ -677,10 +727,18 @@ Download:\n"),
N_("\
--unlink remove file before clobber\n"),
#ifdef HAVE_METALINK
N_("\
--keep-badhash keep files with checksum mismatch (append .badhash)\n"),
N_("\
--metalink-index=NUMBER Metalink application/metalink4+xml metaurl ordinal NUMBER\n"),
N_("\
--metalink-over-http use Metalink metadata from HTTP response headers\n"),
N_("\
--preferred-location preferred location for Metalink resources\n"),
#endif
#ifdef ENABLE_XATTR
N_("\
--no-xattr turn off storage of metadata in extended file attributes\n"),
#endif
"\n",
@@ -717,6 +775,10 @@ HTTP options:\n"),
--ignore-length ignore 'Content-Length' header field\n"),
N_("\
--header=STRING insert STRING among the headers\n"),
#ifdef HAVE_LIBZ
N_("\
--compression=TYPE choose compression, one of auto, gzip and none. (default: none)\n"),
#endif
N_("\
--max-redirect maximum redirections allowed per page\n"),
N_("\
@@ -765,7 +827,7 @@ HTTP options:\n"),
HTTPS (SSL/TLS) options:\n"),
N_("\
--secure-protocol=PR choose secure protocol, one of auto, SSLv2,\n\
SSLv3, TLSv1 and PFS\n"),
SSLv3, TLSv1, TLSv1_1, TLSv1_2 and PFS\n"),
N_("\
--https-only only follow secure HTTPS links\n"),
N_("\
@@ -784,6 +846,11 @@ HTTPS (SSL/TLS) options:\n"),
--ca-directory=DIR directory where hash list of CAs is stored\n"),
N_("\
--crl-file=FILE file with bundle of CRLs\n"),
N_("\
--pinnedpubkey=FILE/HASHES Public key (PEM/DER) file, or any number\n\
of base64 encoded sha256 hashes preceded by\n\
\'sha256//\' and separated by \';\', to verify\n\
peer against\n"),
#if defined(HAVE_LIBSSL) || defined(HAVE_LIBSSL32)
N_("\
--random-file=FILE file with random data for seeding the SSL PRNG\n"),
@@ -992,6 +1059,103 @@ prompt_for_password (void)
return getpass("");
}
/* Execute external application opt.use_askpass */
static void
run_use_askpass (char *question, char **answer)
{
char tmp[1024];
pid_t pid;
int status;
int com[2];
ssize_t bytes = 0;
char *argv[3], *p;
posix_spawn_file_actions_t fa;
if (pipe (com) == -1)
{
fprintf (stderr, _("Cannot create pipe\n"));
exit (WGET_EXIT_GENERIC_ERROR);
}
status = posix_spawn_file_actions_init (&fa);
if (status)
{
fprintf (stderr,
_("Error initializing spawn file actions for use-askpass: %d\n"),
status);
exit (WGET_EXIT_GENERIC_ERROR);
}
status = posix_spawn_file_actions_adddup2 (&fa, com[1], STDOUT_FILENO);
if (status)
{
fprintf (stderr,
_("Error setting spawn file actions for use-askpass: %d\n"),
status);
exit (WGET_EXIT_GENERIC_ERROR);
}
/* C89 initializer lists must be computable at load time,
* thus this explicit initialization. */
argv[0] = opt.use_askpass;
argv[1] = question;
argv[2] = NULL;
status = posix_spawnp (&pid, opt.use_askpass, &fa, NULL, argv, environ);
if (status)
{
fprintf (stderr, "Error spawning %s: %d\n", opt.use_askpass, status);
exit (WGET_EXIT_GENERIC_ERROR);
}
/* Parent process reads from child. */
close (com[1]);
bytes = read (com[0], tmp, sizeof (tmp) - 1);
if (bytes <= 0)
{
fprintf (stderr,
_("Error reading response from command \"%s %s\": %s\n"),
opt.use_askpass, question, strerror (errno));
exit (WGET_EXIT_GENERIC_ERROR);
}
/* Make sure there is a trailing 0 */
tmp[bytes] = '\0';
/* Remove a possible new line */
if ((p = strpbrk (tmp, "\r\n")))
bytes = p - tmp;
*answer = xmemdup0 (tmp, bytes);
}
/* set the user name and password*/
static void
use_askpass (struct url *u)
{
static char question[1024];
if (u->user == NULL || u->user[0] == '\0')
{
snprintf (question, sizeof (question), _("Username for '%s%s': "),
scheme_leading_string(u->scheme), u->host);
/* Prompt for username */
run_use_askpass (question, &u->user);
if (opt.recursive)
opt.user = xstrdup (u->user);
}
if (u->passwd == NULL || u->passwd[0] == '\0')
{
snprintf(question, sizeof (question), _("Password for '%s%s@%s': "),
scheme_leading_string (u->scheme), u->user, u->host);
/* Prompt for password */
run_use_askpass (question, &u->passwd);
if (opt.recursive)
opt.passwd = xstrdup (u->passwd);
}
}
/* Function that prints the line argument while limiting it
to at most line_length. prefix is printed on the first line
and an appropriate number of spaces are added on subsequent
@@ -1053,7 +1217,7 @@ format_and_print_line (const char *prefix, const char *line,
return 0;
}
static void _Noreturn
_Noreturn static void
print_version (void)
{
const char *wgetrc_title = _("Wgetrc: ");
@@ -1236,10 +1400,10 @@ main (int argc, char **argv)
}
else if (strcmp (config_opt->long_name, "config") == 0)
{
bool userrc_ret = true;
userrc_ret &= run_wgetrc (optarg);
file_stats_t flstats;
use_userconfig = true;
if (userrc_ret)
memset(&flstats, 0, sizeof(flstats));
if (file_exists_p(optarg, &flstats) && run_wgetrc (optarg, &flstats))
break;
else
{
@@ -1312,7 +1476,8 @@ main (int argc, char **argv)
append_to_log = true;
break;
case OPT__EXECUTE:
run_command (optarg);
if (optarg) /* check silences static analyzer */
run_command (optarg);
break;
case OPT__NO:
{
@@ -1373,6 +1538,9 @@ main (int argc, char **argv)
nurl = argc - optind;
/* Initialize logging ASAP. */
log_init (opt.lfilename, append_to_log);
/* If we do not have Debug support compiled in AND Wget is invoked with the
* --debug switch, instead of failing, we silently turn it into a no-op. For
* this no-op, we explicitly set opt.debug to false and hence none of the
@@ -1474,12 +1642,12 @@ WARNING: timestamping does nothing in combination with -O. See the manual\n\
for details.\n\n"));
opt.timestamping = false;
}
if (opt.noclobber && file_exists_p(opt.output_document))
if (opt.noclobber && file_exists_p(opt.output_document, NULL))
{
/* Check if output file exists; if it does, exit. */
logprintf (LOG_VERBOSE,
_("File `%s' already there; not retrieving.\n"),
opt.output_document);
_("File %s already there; not retrieving.\n"),
quote (opt.output_document));
exit (WGET_EXIT_GENERIC_ERROR);
}
}
@@ -1526,6 +1694,26 @@ for details.\n\n"));
}
}
#ifdef HAVE_LIBZ
if (opt.always_rest || opt.start_pos >= 0)
{
if (opt.compression == compression_auto)
{
/* Compression does not work with --continue or --start-pos.
Since compression was not explicitly set, it will be disabled. */
opt.compression = compression_none;
}
else if (opt.compression != compression_none)
{
fprintf (stderr,
_("Compression does not work with --continue or"
" --start-pos, they will be disabled.\n"));
opt.always_rest = false;
opt.start_pos = -1;
}
}
#endif
if (opt.ask_passwd && opt.passwd)
{
fprintf (stderr,
@@ -1596,7 +1784,7 @@ for details.\n\n"));
else if (opt.method)
{
fprintf (stderr, _("You cannot use --post-data or --post-file along with --method. "
"--method expects data through --body-data and --body-file options"));
"--method expects data through --body-data and --body-file options\n"));
exit (WGET_EXIT_GENERIC_ERROR);
}
}
@@ -1675,6 +1863,16 @@ for details.\n\n"));
exit (WGET_EXIT_GENERIC_ERROR);
}
if (opt.use_askpass)
{
if (opt.use_askpass[0] == '\0')
{
fprintf (stderr,
_("use-askpass requires a string or either environment variable WGET_ASKPASS or SSH_ASKPASS to be set.\n"));
exit (WGET_EXIT_GENERIC_ERROR);
}
}
#ifdef USE_WATT32
if (opt.wdebug)
dbug_init();
@@ -1706,9 +1904,6 @@ for details.\n\n"));
}
url[i] = NULL;
/* Initialize logging. */
log_init (opt.lfilename, append_to_log);
/* Open WARC file. */
if (opt.warc_filename != 0)
warc_init ();
@@ -1737,7 +1932,7 @@ for details.\n\n"));
}
else
{
struct_fstat st;
struct stat st;
#ifdef __VMS
/* Common fopen() optional arguments:
@@ -1774,6 +1969,58 @@ only if outputting to a regular file.\n"));
}
}
#ifdef HAVE_LIBCARES
if (opt.bind_dns_address || opt.dns_servers)
{
if (ares_library_init (ARES_LIB_INIT_ALL))
{
fprintf (stderr, _("Failed to init libcares\n"));
exit (WGET_EXIT_GENERIC_ERROR);
}
if (ares_init (&ares) != ARES_SUCCESS)
{
fprintf (stderr, _("Failed to init c-ares channel\n"));
exit (WGET_EXIT_GENERIC_ERROR);
}
if (opt.bind_dns_address)
{
struct in_addr a4;
#ifdef ENABLE_IPV6
struct in6_addr a6;
#endif
if (inet_pton (AF_INET, opt.bind_dns_address, &a4) == 1)
{
ares_set_local_ip4 (ares, ntohl (a4.s_addr));
}
#ifdef ENABLE_IPV6
else if (inet_pton (AF_INET6, opt.bind_dns_address, &a6) == 1)
{
ares_set_local_ip6 (ares, (unsigned char *) &a6);
}
#endif
else
{
fprintf (stderr, _("Failed to parse IP address '%s'\n"), opt.bind_dns_address);
exit (WGET_EXIT_GENERIC_ERROR);
}
}
if (opt.dns_servers)
{
int result;
if ((result = ares_set_servers_csv (ares, opt.dns_servers)) != ARES_SUCCESS)
{
fprintf (stderr, _("Failed to set DNS server(s) '%s' (%d)\n"), opt.dns_servers, result);
exit (WGET_EXIT_GENERIC_ERROR);
}
}
}
#endif
#ifdef __VMS
/* Set global ODS5 flag according to the specified destination (if
any), otherwise according to the current default device.
@@ -1841,14 +2088,26 @@ only if outputting to a regular file.\n"));
}
else
{
/* Request credentials if use_askpass is set. */
if (opt.use_askpass)
use_askpass (url_parsed);
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);
@@ -1861,7 +2120,7 @@ only if outputting to a regular file.\n"));
&dt, opt.recursive, iri, true);
}
if (opt.delete_after && filename != NULL && file_exists_p (filename))
if (opt.delete_after && filename != NULL && file_exists_p (filename, NULL))
{
DEBUGP (("Removing file due to --delete-after in main():\n"));
logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* Declarations for metalink.c.
Copyright (C) 2015 Free Software Foundation, Inc.
Copyright (C) 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -46,6 +46,21 @@ as that of the covered work. */
uerr_t retrieve_from_metalink (const metalink_t *metalink);
int metalink_res_cmp (const void *res1, const void *res2);
int metalink_meta_cmp (const void* meta1, const void* meta2);
int metalink_check_safe_path (const char *path);
char *last_component (char const *name);
void replace_metalink_basename (char **name, char *ref);
char *get_metalink_basename (char *name);
void append_suffix_number (char **str, const char *sep, wgint num);
void clean_metalink_string (char **str);
void dequote_metalink_string (char **str);
void badhash_suffix (char *name);
void badhash_or_remove (char *name);
uerr_t fetch_metalink_file (const char *url_str,
bool resume, bool metalink_http,
const char *filename, char **destname);
bool find_key_value (const char *start,
const char *end,

View File

@@ -1,7 +1,6 @@
/* mswindows.c -- Windows-specific support
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2014-2015, 2018 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -53,16 +52,13 @@ as that of the covered work. */
#endif
/* Defined in log.c. */
void log_request_redirect_output (const char *);
/* Windows version of xsleep in utils.c. */
void
xsleep (double seconds)
{
#if defined(HAVE_USLEEP) && defined(HAVE_SLEEP)
if (seconds > 1000)
if (seconds >= 1)
{
/* Explained in utils.c. */
sleep (seconds);
@@ -98,7 +94,7 @@ static void
ws_hangup (const char *reason)
{
fprintf (stderr, _("Continuing in background.\n"));
log_request_redirect_output (reason);
redirect_output (true, reason);
/* Detach process from the current console. Under Windows 9x, if we
were launched from a 16-bit process (which is usually the case;
@@ -583,7 +579,7 @@ run_with_timeout (double seconds, void (*fun) (void *), void *arg)
const char *
inet_ntop (int af, const void *src, char *dst, socklen_t cnt)
{
/* struct sockaddr can't accomodate struct sockaddr_in6. */
/* struct sockaddr can't accommodate struct sockaddr_in6. */
union {
struct sockaddr_in6 sin6;
struct sockaddr_in sin;

View File

@@ -1,7 +1,5 @@
/* Declarations for windows
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -57,6 +55,9 @@ as that of the covered work. */
/* Declares getpid(). */
#include <process.h>
/* Declares inet_ntop() and inet_pton(). */
#include <arpa/inet.h>
/* We have strcasecmp and strncasecmp, just under different names. */
#ifndef HAVE_STRCASECMP
# define strcasecmp stricmp
@@ -85,11 +86,6 @@ typedef __int64 wgint;
#define PATH_SEPARATOR '\\'
/* Additional declarations needed for IPv6: */
#ifdef ENABLE_IPV6
const char *inet_ntop (int, const void *, char *, socklen_t);
#endif
/* ioctl needed by set_windows_fd_as_blocking_socket() */
#include <sys/ioctl.h>

View File

@@ -1,6 +1,6 @@
/* Read and parse the .netrc file to get hosts, accounts, and passwords.
Copyright (C) 1996, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996, 2007-2011, 2015, 2018 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -42,7 +42,11 @@ as that of the covered work. */
#include "netrc.h"
#include "init.h"
#define NETRC_FILE_NAME ".netrc"
#ifdef WINDOWS
# define NETRC_FILE_NAME "_netrc"
#else
# define NETRC_FILE_NAME ".netrc"
#endif
static acc_t *netrc_list;
@@ -75,7 +79,7 @@ search_netrc (const char *host, const char **acc, const char **passwd,
#ifdef __VMS
int err;
struct_stat buf;
struct stat buf;
char *path = "SYS$LOGIN:.netrc";
netrc_list = NULL;
@@ -94,7 +98,7 @@ search_netrc (const char *host, const char **acc, const char **passwd,
if (home)
{
int err;
struct_stat buf;
struct stat buf;
char *path = (char *)alloca (strlen (home) + 1
+ strlen (NETRC_FILE_NAME) + 1);
sprintf (path, "%s/%s", home, NETRC_FILE_NAME);
@@ -235,7 +239,7 @@ parse_netrc (const char *path)
/* The latest token we've seen in the file. */
enum
{
tok_nothing, tok_account, tok_login, tok_macdef, tok_machine, tok_password
tok_nothing, tok_account, tok_login, tok_macdef, tok_machine, tok_password, tok_port, tok_force
} last_token = tok_nothing;
current = retval = NULL;
@@ -344,6 +348,18 @@ parse_netrc (const char *path)
premature_token = "account";
break;
/* We don't handle the port keyword at all. */
case tok_port:
if (!current)
premature_token = "port";
break;
/* We don't handle the force keyword at all. */
case tok_force:
if (!current)
premature_token = "force";
break;
/* We handle tok_nothing below this switch. */
case tok_nothing:
break;
@@ -365,10 +381,10 @@ parse_netrc (const char *path)
/* Fetch the next token. */
if (!strcmp (tok, "account"))
last_token = tok_account;
else if (!strcmp (tok, "default"))
{
maybe_add_to_list (&current, &retval);
}
else if (!strcmp (tok, "login"))
last_token = tok_login;
@@ -381,6 +397,16 @@ parse_netrc (const char *path)
else if (!strcmp (tok, "password"))
last_token = tok_password;
/* GNU extensions 'port' and 'force', not operational
* see https://www.gnu.org/software/emacs/manual/html_node/gnus/NNTP.html#index-nntp_002dauthinfo_002dfunction-2003
* see https://savannah.gnu.org/bugs/index.php?52066
*/
else if (!strcmp (tok, "port"))
last_token = tok_port;
else if (!strcmp (tok, "force"))
last_token = tok_force;
else
fprintf (stderr, _("%s: %s:%d: unknown token \"%s\"\n"),
exec_name, path, ln, tok);
@@ -435,11 +461,14 @@ free_netrc(acc_t *l)
#ifdef STANDALONE
#include <sys/types.h>
#include <sys/stat.h>
#include "exits.h"
const char *program_argstring = NULL; /* Needed by warc.c */
int
main (int argc, char **argv)
{
struct_stat sb;
struct stat sb;
char *program_name, *file, *target;
acc_t *head, *a;

View File

@@ -1,6 +1,6 @@
/* Declarations for netrc.c
Copyright (C) 1996, 1996, 1997, 2007, 2008, 2009, 2010, 2011, 2015
Free Software Foundation, Inc.
Copyright (C) 1996, 1996-1997, 2007-2011, 2015, 2018 Free Software
Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,6 +1,5 @@
/* SSL support via OpenSSL library.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 2011, 2012, 2015 Free Software Foundation, Inc.
Copyright (C) 2000-2012, 2015, 2018 Free Software Foundation, Inc.
Originally contributed by Christian Fraenkel.
This file is part of GNU Wget.
@@ -35,6 +34,7 @@ as that of the covered work. */
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <xalloc.h>
#include <openssl/ssl.h>
#include <openssl/x509v3.h>
@@ -173,11 +173,16 @@ ssl_init (void)
{
SSL_METHOD const *meth;
long ssl_options = 0;
#if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
int ssl_proto_version = 0;
#endif
#if OPENSSL_VERSION_NUMBER >= 0x00907000
if (ssl_true_initialized == 0)
{
#if OPENSSL_API_COMPAT < 0x10100000L
OPENSSL_config (NULL);
#endif
ssl_true_initialized = 1;
}
#endif
@@ -201,20 +206,26 @@ ssl_init (void)
CONF_modules_load_file(NULL, NULL,
CONF_MFLAGS_DEFAULT_SECTION|CONF_MFLAGS_IGNORE_MISSING_FILE);
#endif
#if OPENSSL_API_COMPAT >= 0x10100000L
OPENSSL_init_ssl(0, NULL);
#else
SSL_library_init ();
SSL_load_error_strings ();
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L
SSLeay_add_all_algorithms ();
SSLeay_add_ssl_algorithms ();
#endif
switch (opt.secure_protocol)
{
#ifndef OPENSSL_NO_SSL2
#if !defined OPENSSL_NO_SSL2 && OPENSSL_VERSION_NUMBER < 0x10100000L
case secure_protocol_sslv2:
meth = SSLv2_client_method ();
break;
#endif
#ifndef OPENSSL_NO_SSL3
#ifndef OPENSSL_NO_SSL3_METHOD
case secure_protocol_sslv3:
meth = SSLv3_client_method ();
break;
@@ -226,16 +237,31 @@ ssl_init (void)
ssl_options |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
break;
case secure_protocol_tlsv1:
#if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
meth = TLS_client_method();
ssl_proto_version = TLS1_VERSION;
#else
meth = TLSv1_client_method ();
#endif
break;
#if OPENSSL_VERSION_NUMBER >= 0x10001000
case secure_protocol_tlsv1_1:
#if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
meth = TLS_client_method();
ssl_proto_version = TLS1_1_VERSION;
#else
meth = TLSv1_1_client_method ();
#endif
break;
case secure_protocol_tlsv1_2:
#if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
meth = TLS_client_method();
ssl_proto_version = TLS1_2_VERSION;
#else
meth = TLSv1_2_client_method ();
#endif
break;
#else
case secure_protocol_tlsv1_1:
@@ -262,6 +288,11 @@ ssl_init (void)
if (ssl_options)
SSL_CTX_set_options (ssl_ctx, ssl_options);
#if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
if (ssl_proto_version)
SSL_CTX_set_min_proto_version(ssl_ctx, ssl_proto_version);
#endif
/* OpenSSL ciphers: https://www.openssl.org/docs/apps/ciphers.html
* Since we want a good protection, we also use HIGH (that excludes MD4 ciphers and some more)
*/
@@ -506,6 +537,22 @@ ssl_connect_with_timeout_callback(void *arg)
ctx->result = SSL_connect(ctx->ssl);
}
static const char *
_sni_hostname(const char *hostname)
{
size_t len = strlen(hostname);
char *sni_hostname = xmemdup(hostname, len + 1);
/* Remove trailing dot(s) to fix #47408.
* Regarding RFC 6066 (SNI): The hostname is represented as a byte
* string using ASCII encoding without a trailing dot. */
while (len && sni_hostname[--len] == '.')
sni_hostname[len] = 0;
return sni_hostname;
}
/* Perform the SSL handshake on file descriptor FD, which is assumed
to be connected to an SSL server. The SSL handle provided by
OpenSSL is registered with the file descriptor FD using
@@ -532,7 +579,12 @@ ssl_connect_wget (int fd, const char *hostname, int *continue_session)
then use it whenever we have a hostname. If not, don't, ever. */
if (! is_valid_ip_address (hostname))
{
if (! SSL_set_tlsext_host_name (conn, hostname))
const char *sni_hostname = _sni_hostname(hostname);
long rc = SSL_set_tlsext_host_name (conn, sni_hostname);
xfree(sni_hostname);
if (rc == 0)
{
DEBUGP (("Failed to set TLS server-name indication."));
goto error;
@@ -561,7 +613,7 @@ ssl_connect_wget (int fd, const char *hostname, int *continue_session)
DEBUGP (("SSL handshake timed out.\n"));
goto timeout;
}
if (scwt_ctx.result <= 0 || SSL_state(conn) != SSL_ST_OK)
if (scwt_ctx.result <= 0 || !SSL_is_init_finished(conn))
goto error;
ctx = xnew0 (struct openssl_transport_context);
@@ -650,6 +702,65 @@ static char *_get_rfc2253_formatted (X509_NAME *name)
return out ? out : xstrdup("");
}
/*
* Heavily modified from:
* https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
*/
static bool
pkp_pin_peer_pubkey (X509* cert, const char *pinnedpubkey)
{
/* Scratch */
int len1 = 0, len2 = 0;
char *buff1 = NULL, *temp = NULL;
/* Result is returned to caller */
bool result = false;
/* if a path wasn't specified, don't pin */
if (!pinnedpubkey)
return true;
if (!cert)
return result;
/* Begin Gyrations to get the subjectPublicKeyInfo */
/* Thanks to Viktor Dukhovni on the OpenSSL mailing list */
/* https://groups.google.com/group/mailing.openssl.users/browse_thread
/thread/d61858dae102c6c7 */
len1 = i2d_X509_PUBKEY (X509_get_X509_PUBKEY (cert), NULL);
if (len1 < 1)
goto cleanup; /* failed */
/* https://www.openssl.org/docs/crypto/buffer.html */
buff1 = temp = OPENSSL_malloc (len1);
if (!buff1)
goto cleanup; /* failed */
/* https://www.openssl.org/docs/crypto/d2i_X509.html */
len2 = i2d_X509_PUBKEY (X509_get_X509_PUBKEY (cert), (unsigned char **) &temp);
/*
* These checks are verifying we got back the same values as when we
* sized the buffer. It's pretty weak since they should always be the
* same. But it gives us something to test.
*/
if ((len1 != len2) || !temp || ((temp - buff1) != len1))
goto cleanup; /* failed */
/* End Gyrations */
/* The one good exit point */
result = wg_pin_peer_pubkey (pinnedpubkey, buff1, len1);
cleanup:
/* https://www.openssl.org/docs/crypto/buffer.html */
if (NULL != buff1)
OPENSSL_free (buff1);
return result;
}
/* Verify the validity of the certificate presented by the server.
Also check that the "common name" of the server, as presented by
its certificate, corresponds to HOST. (HOST typically comes from
@@ -673,6 +784,7 @@ ssl_check_certificate (int fd, const char *host)
long vresult;
bool success = true;
bool alt_name_checked = false;
bool pinsuccess = opt.pinnedpubkey == NULL;
/* If the user has specified --no-check-cert, we still want to warn
him about problems with the server's certificate. */
@@ -682,6 +794,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 && pinsuccess)
return success;
cert = SSL_get_peer_certificate (conn);
if (!cert)
{
@@ -758,9 +874,12 @@ ssl_check_certificate (int fd, const char *host)
{
/* Test subject alternative names */
/* SNI hostname must not have a trailing dot */
const char *sni_hostname = _sni_hostname(host);
/* Do we want to check for dNSNAmes or ipAddresses (see RFC 2818)?
* Signal it by host_in_octet_string. */
ASN1_OCTET_STRING *host_in_octet_string = a2i_IPADDRESS (host);
ASN1_OCTET_STRING *host_in_octet_string = a2i_IPADDRESS (sni_hostname);
int numaltnames = sk_GENERAL_NAME_num (subjectAltNames);
int i;
@@ -795,7 +914,7 @@ ssl_check_certificate (int fd, const char *host)
if (0 <= ASN1_STRING_to_UTF8 (&name_in_utf8, name->d.dNSName))
{
/* Compare and check for NULL attack in ASN1_STRING */
if (pattern_match ((char *)name_in_utf8, host) &&
if (pattern_match ((char *)name_in_utf8, sni_hostname) &&
(strlen ((char *)name_in_utf8) ==
(size_t) ASN1_STRING_length (name->d.dNSName)))
{
@@ -816,9 +935,11 @@ ssl_check_certificate (int fd, const char *host)
logprintf (LOG_NOTQUIET,
_("%s: no certificate subject alternative name matches\n"
"\trequested host name %s.\n"),
severity, quote_n (1, host));
severity, quote_n (1, sni_hostname));
success = false;
}
xfree(sni_hostname);
}
if (alt_name_checked == false)
@@ -873,6 +994,13 @@ ssl_check_certificate (int fd, const char *host)
}
}
pinsuccess = pkp_pin_peer_pubkey (cert, opt.pinnedpubkey);
if (!pinsuccess)
{
logprintf (LOG_ALWAYS, _("The public key does not match pinned public key!\n"));
success = false;
}
if (success)
DEBUGP (("X509 certificate successfully verified and matches host %s\n",
@@ -880,13 +1008,13 @@ 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;
/* never return true if pinsuccess fails */
return !pinsuccess ? false : (opt.check_cert == CHECK_CERT_ON ? success : true);
}
/*

View File

@@ -1,7 +1,5 @@
/* struct options.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -29,6 +27,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,
@@ -36,6 +41,7 @@ struct options
bool quiet; /* Are we quiet? */
int ntry; /* Number of tries per URL */
bool retry_connrefused; /* Treat CONNREFUSED as non-fatal. */
char *retry_on_http_error; /* Treat given HTTP errors as non-fatal. */
bool background; /* Whether we should work in background. */
bool ignore_length; /* Do we heed content-length at all? */
bool recursive; /* Are we recursive? */
@@ -54,12 +60,13 @@ struct options
bool add_hostdir; /* Do we add hostname directory? */
bool protocol_directories; /* Whether to prepend "http"/"ftp" to dirs. */
bool noclobber; /* Disables clobbering of existing data. */
bool unlink; /* remove file before clobbering */
bool unlink_requested; /* remove file before clobbering */
char *dir_prefix; /* The top of directory tree */
char *lfilename; /* Log filename */
char *input_filename; /* Input filename */
#ifdef HAVE_METALINK
char *input_metalink; /* Input metalink file */
int metalink_index; /* Metalink application/metalink4+xml metaurl ordinal number. */
bool metalink_over_http; /* Use Metalink if present in HTTP response */
char *preferred_location; /* Preferred location for Metalink resources */
#endif
@@ -92,6 +99,11 @@ struct options
void *(*regex_compile_fun)(const char *); /* Function to compile a regex. */
bool (*regex_match_fun)(const void *, const char *); /* Function to match a string to a regex. */
#ifdef HAVE_LIBCARES
char *bind_dns_address;
char *dns_servers;
#endif
char **domains; /* See host.c */
char **exclude_domains;
bool dns_cache; /* whether we cache DNS lookups. */
@@ -115,9 +127,12 @@ struct options
bool warc_keep_log; /* Store the log file in a WARC record. */
char **warc_user_headers; /* User-defined WARC header(s). */
bool enable_xattr; /* Store metadata in POSIX extended attributes. */
char *user; /* Generic username */
char *passwd; /* Generic password */
bool ask_passwd; /* Ask for password? */
char *use_askpass; /* value to use for use-askpass if WGET_ASKPASS is not set */
bool always_rest; /* Always use REST. */
wgint start_pos; /* Start position of a download. */
@@ -215,7 +230,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 {
@@ -229,6 +244,11 @@ struct options
char *ca_cert; /* CA certificate file to use */
char *crl_file; /* file with CRLs */
char *pinnedpubkey; /* Public key (PEM/DER) file, or any number
of base64 encoded sha256 hashes preceded by
\'sha256//\' and separated by \';\', to verify
peer against */
char *random_file; /* file with random data to seed the PRNG */
char *egd_file; /* file name of the egd daemon socket */
bool https_only; /* whether to follow HTTPS only */
@@ -241,6 +261,7 @@ struct options
bool cookies; /* whether cookies are used. */
char *cookies_input; /* file we're loading the cookies from. */
char *cookies_output; /* file we're saving the cookies to. */
bool keep_badhash; /* Keep files with checksum mismatch. */
bool keep_session_cookies; /* whether session cookies should be
saved and loaded. */
@@ -289,7 +310,7 @@ struct options
bool enable_iri;
char *encoding_remote;
char *locale;
const char *locale;
bool trustservernames;
#ifdef __VMS
@@ -303,6 +324,14 @@ struct options
name. */
bool report_bps; /*Output bandwidth in bits format*/
#ifdef HAVE_LIBZ
enum compression_options {
compression_auto,
compression_gzip,
compression_none
} compression; /* type of HTTP compression to use */
#endif
char *rejected_log; /* The file to log rejected URLS to. */
#ifdef HAVE_HSTS

View File

@@ -1,6 +1,5 @@
/* Download progress.
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010, 2011, 2015 Free Software Foundation, Inc.
Copyright (C) 2001-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -75,7 +74,7 @@ static struct progress_implementation implementations[] = {
static struct progress_implementation *current_impl;
static int current_impl_locked;
/* Progress implementation used by default. Can be overriden in
/* Progress implementation used by default. Can be overridden in
wgetrc or by the fallback one. */
#define DEFAULT_PROGRESS_IMPLEMENTATION "bar"
@@ -594,7 +593,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 +854,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)
@@ -891,11 +891,6 @@ get_eta (int *bcd)
p += sizeof (s) - 1; \
} while (0)
/* Use move_to_end (s) to get S to point the end of the string (the
terminating \0). This is faster than s+=strlen(s), but some people
are confused when they see strchr (s, '\0') in the code. */
#define move_to_end(s) s = strchr (s, '\0');
static void
create_image (struct bar_progress *bp, double dl_total_time, bool done)
{
@@ -903,11 +898,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 +923,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 +944,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 +991,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 +1000,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 +1018,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 +1027,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 +1067,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 +1087,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 +1126,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 +1143,25 @@ 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);
assert (padding >= 0 && "Padding length became non-positive!");
padding = padding > 0 ? padding : 0;
memset (p, ' ', padding);
p += padding;
*p = '\0';
/* 2014-11-14 Darshit Shah <darnir@gmail.com>
@@ -1184,8 +1170,11 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
* from the release code since we do not want Wget to crash and burn when the
* assertion fails. Instead Wget should continue downloading and display a
* horrible and irritating progress bar that spams the screen with newlines.
*
* By default, all assertions are disabled in a Wget build and are enabled
* only with the --enable-assert configure option.
*/
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
@@ -1203,8 +1192,6 @@ display_image (char *buf)
static void
bar_set_params (char *params)
{
char *term = getenv ("TERM");
if (params)
{
char *param = strtok (params, ":");
@@ -1224,12 +1211,6 @@ bar_set_params (char *params)
dots. */
|| !isatty (fileno (stderr))
#endif
/* Normally we don't depend on terminal type because the
progress bar only uses ^M to move the cursor to the
beginning of line, which works even on dumb terminals. But
Jamie Zawinski reports that ^M and ^H tricks don't work in
Emacs shell buffers, and only make a mess. */
|| (term && 0 == strcmp (term, "emacs"))
)
&& !current_impl_locked)
{

View File

@@ -1,6 +1,5 @@
/* Download progress.
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010, 2011, 2015 Free Software Foundation, Inc.
Copyright (C) 2001-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,6 +1,5 @@
/* Portable timers.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
Copyright (C) 2005-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,6 +1,5 @@
/* Declarations for ptimer.c.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
Copyright (C) 2005-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,7 +1,5 @@
/* Handling of recursive HTTP retrieving.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2012, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -234,17 +232,19 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
FILE *rejectedlog = NULL; /* Don't write a rejected log. */
#define COPYSTR(x) (x) ? xstrdup(x) : NULL;
/* Duplicate pi struct if not NULL */
if (pi)
{
#define COPYSTR(x) (x) ? xstrdup(x) : NULL;
i->uri_encoding = COPYSTR (pi->uri_encoding);
i->content_encoding = COPYSTR (pi->content_encoding);
i->utf8_encode = pi->utf8_encode;
#undef COPYSTR
}
#ifdef ENABLE_IRI
else
set_uri_encoding (i, opt.locale, true);
#undef COPYSTR
#endif
queue = url_queue_new ();
blacklist = make_string_hash_table (0);
@@ -436,10 +436,15 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
struct url *url_parsed = url_parse (url, NULL, i, true);
struct iri *ci;
char *referer_url = url;
bool strip_auth = (url_parsed != NULL
&& url_parsed->user != NULL);
bool strip_auth;
assert (url_parsed != NULL);
if (!url_parsed)
continue;
strip_auth = (url_parsed && url_parsed->user);
/* Strip auth info if present */
if (strip_auth)
referer_url = url_string (url_parsed, URL_AUTH_HIDE);
@@ -449,9 +454,16 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
reject_reason r;
if (child->ignore_when_downloading)
continue;
{
DEBUGP (("Not following due to 'ignore' flag: %s\n", child->url->url));
continue;
}
if (dash_p_leaf_HTML && !child->link_inline_p)
continue;
{
DEBUGP (("Not following due to 'link inline' flag: %s\n", child->url->url));
continue;
}
r = download_child (child, url_parsed, depth,
start_url_parsed, blacklist, i);
@@ -483,7 +495,7 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
if (file
&& (opt.delete_after
|| opt.spider /* opt.recursive is implicitely true */
|| opt.spider /* opt.recursive is implicitly true */
|| !acceptable (file)))
{
/* Either --delete-after was specified, or we loaded this
@@ -610,7 +622,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;
@@ -680,7 +696,7 @@ download_child (const struct urlpos *upos, struct url *parent, int depth,
for directories (no file name to match) and for non-leaf HTMLs,
which can lead to other files that do need to be downloaded. (-p
automatically implies non-leaf because with -p we can, if
necesary, overstep the maximum depth to get the page requisites.) */
necessary, overstep the maximum depth to get the page requisites.) */
if (u->file[0] != '\0'
&& !(has_html_suffix_p (u->file)
/* The exception only applies to non-leaf HTMLs (but -p
@@ -795,6 +811,12 @@ descend_redirect (const char *redirected, struct url *orig_parsed, int depth,
if (reason == WG_RR_SUCCESS)
blacklist_add (blacklist, upos->url->url);
else if (reason == WG_RR_LIST || reason == WG_RR_REGEX)
{
DEBUGP (("Ignoring decision for redirects, decided to load it.\n"));
blacklist_add (blacklist, upos->url->url);
reason = WG_RR_SUCCESS;
}
else
DEBUGP (("Redirection \"%s\" failed the test.\n", redirected));

View File

@@ -1,7 +1,5 @@
/* Declarations for recur.c.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,6 +1,6 @@
/* Support for Robot Exclusion Standard (RES).
Copyright (C) 2001, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
Copyright (C) 2001, 2006-2011, 2015, 2018 Free Software Foundation,
Inc.
This file is part of Wget.
@@ -37,12 +37,12 @@ as that of the covered work. */
disallow access to certain parts of the site.
The first specification was written by Martijn Koster in 1994, and
is still available at <http://www.robotstxt.org/wc/norobots.html>.
is still available at <http://www.robotstxt.org/orig.html>.
In 1996, Martijn wrote an Internet Draft specifying an improved RES
specification; however, that work was apparently abandoned since
the draft has expired in 1997 and hasn't been replaced since. The
draft is available at
<http://www.robotstxt.org/wc/norobots-rfc.html>.
<http://www.robotstxt.org/norobots-rfc.txt>.
This file implements RES as specified by the draft. Note that this
only handles the "robots.txt" support. The META tag that controls
@@ -428,7 +428,7 @@ free_specs (struct robot_specs *specs)
/* The inner matching engine: return true if RECORD_PATH matches
URL_PATH. The rules for matching are described at
<http://www.robotstxt.org/wc/norobots-rfc.txt>, section 3.2.2. */
<http://www.robotstxt.org/norobots-rfc.txt>, section 3.2.2. */
static bool
matches (const char *record_path, const char *url_path)

View File

@@ -1,6 +1,6 @@
/* Declarations for res.c.
Copyright (C) 2001, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 2001, 2007-2011, 2015, 2018 Free Software Foundation,
Inc.
This file is part of Wget.

View File

@@ -1,7 +1,6 @@
/* File retrieval.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2014-2015, 2018 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -41,6 +40,10 @@ as that of the covered work. */
# include <unixio.h> /* For delete(). */
#endif
#ifdef HAVE_LIBZ
# include <zlib.h>
#endif
#include "exits.h"
#include "utils.h"
#include "retr.h"
@@ -84,6 +87,22 @@ limit_bandwidth_reset (void)
xzero (limit_data);
}
#ifdef HAVE_LIBZ
static voidpf
zalloc (voidpf opaque, unsigned int items, unsigned int size)
{
(void) opaque;
return (voidpf) xcalloc (items, size);
}
static void
zfree (voidpf opaque, voidpf address)
{
(void) opaque;
xfree (address);
}
#endif
/* Limit the bandwidth by pausing the download for an amount of time.
BYTES is the number of bytes received from the network, and TIMER
is the timer that started at the beginning of download. */
@@ -257,6 +276,44 @@ fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread,
wgint sum_written = 0;
wgint remaining_chunk_size = 0;
#ifdef HAVE_LIBZ
/* try to minimize the number of calls to inflate() and write_data() per
call to fd_read() */
unsigned int gzbufsize = dlbufsize * 4;
char *gzbuf = NULL;
z_stream gzstream;
if (flags & rb_compressed_gzip)
{
gzbuf = xmalloc (gzbufsize);
if (gzbuf != NULL)
{
gzstream.zalloc = zalloc;
gzstream.zfree = zfree;
gzstream.opaque = Z_NULL;
gzstream.next_in = Z_NULL;
gzstream.avail_in = 0;
#define GZIP_DETECT 32 /* gzip format detection */
#define GZIP_WINDOW 15 /* logarithmic window size (default: 15) */
ret = inflateInit2 (&gzstream, GZIP_DETECT | GZIP_WINDOW);
if (ret != Z_OK)
{
xfree (gzbuf);
errno = (ret == Z_MEM_ERROR) ? ENOMEM : EINVAL;
ret = -1;
goto out;
}
}
else
{
errno = ENOMEM;
ret = -1;
goto out;
}
}
#endif
if (flags & rb_skip_startpos)
skip = startpos;
@@ -320,6 +377,12 @@ fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread,
remaining_chunk_size = strtol (line, &endl, 16);
xfree (line);
if (remaining_chunk_size < 0)
{
ret = -1;
break;
}
if (remaining_chunk_size == 0)
{
ret = 0;
@@ -383,12 +446,64 @@ fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread,
int write_res;
sum_read += ret;
write_res = write_data (out, out2, dlbuf, ret, &skip, &sum_written);
if (write_res < 0)
#ifdef HAVE_LIBZ
if (gzbuf != NULL)
{
ret = (write_res == -3) ? -3 : -2;
goto out;
int err;
int towrite;
gzstream.avail_in = ret;
gzstream.next_in = (unsigned char *) dlbuf;
do
{
gzstream.avail_out = gzbufsize;
gzstream.next_out = (unsigned char *) gzbuf;
err = inflate (&gzstream, Z_NO_FLUSH);
switch (err)
{
case Z_MEM_ERROR:
errno = ENOMEM;
ret = -1;
goto out;
case Z_NEED_DICT:
case Z_DATA_ERROR:
errno = EINVAL;
ret = -1;
goto out;
case Z_STREAM_END:
if (exact && sum_read != toread)
{
DEBUGP(("zlib stream ended unexpectedly after "
"%ld/%ld bytes\n", sum_read, toread));
}
}
towrite = gzbufsize - gzstream.avail_out;
write_res = write_data (out, out2, gzbuf, towrite, &skip,
&sum_written);
if (write_res < 0)
{
ret = (write_res == -3) ? -3 : -2;
goto out;
}
}
while (gzstream.avail_out == 0);
}
else
#endif
{
write_res = write_data (out, out2, dlbuf, ret, &skip,
&sum_written);
if (write_res < 0)
{
ret = (write_res == -3) ? -3 : -2;
goto out;
}
}
if (chunked)
{
remaining_chunk_size -= ret;
@@ -433,6 +548,31 @@ fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread,
if (timer)
ptimer_destroy (timer);
#ifdef HAVE_LIBZ
if (gzbuf != NULL)
{
int err = inflateEnd (&gzstream);
if (ret >= 0)
{
/* with compression enabled, ret must be 0 if successful */
if (err == Z_OK)
ret = 0;
else
{
errno = EINVAL;
ret = -1;
}
}
xfree (gzbuf);
if (gzstream.total_in != sum_read)
{
DEBUGP(("zlib read size differs from raw read size (%lu/%lu)\n",
gzstream.total_in, sum_read));
}
}
#endif
if (qtyread)
*qtyread += sum_read;
if (qtywritten)
@@ -634,7 +774,7 @@ retr_rate (wgint bytes, double secs)
double dlrate = calc_rate (bytes, secs, &units);
/* Use more digits for smaller numbers (regardless of unit used),
e.g. "1022", "247", "12.5", "2.38". */
sprintf (res, "%.*f %s",
snprintf (res, sizeof(res), "%.*f %s",
dlrate >= 99.95 ? 0 : dlrate >= 9.995 ? 1 : 2,
dlrate, !opt.report_bps ? rate_names[units]: rate_names_bits[units]);
@@ -830,14 +970,19 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
if (redirection_count)
oldrec = glob = false;
result = ftp_loop (u, &local_file, dt, proxy_url, recursive, glob);
result = ftp_loop (u, orig_parsed, &local_file, dt, proxy_url,
recursive, glob);
recursive = oldrec;
/* There is a possibility of having HTTP being redirected to
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;
@@ -864,15 +1009,19 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
redirects, but a ton of boneheaded webservers and CGIs out
there break the rules and use relative URLs, and popular
browsers are lenient about this, so wget should be too. */
construced_newloc = uri_merge (url, mynewloc);
construced_newloc = uri_merge (url, mynewloc ? mynewloc : "");
xfree (mynewloc);
mynewloc = construced_newloc;
/* Reset UTF-8 encoding state, keep the URI encoding and reset
#ifdef ENABLE_IRI
/* Reset UTF-8 encoding state, set the URI encoding and reset
the content encoding. */
iri->utf8_encode = opt.enable_iri;
if (opt.encoding_remote)
set_uri_encoding (iri, opt.encoding_remote, true);
set_content_encoding (iri, NULL);
xfree (iri->orig_url);
#endif
/* Now, see if this new location makes sense. */
newloc_parsed = url_parse (mynewloc, &up_error_code, iri, true);
@@ -954,11 +1103,16 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
u = url_parse (origurl, NULL, iri, true);
if (u)
{
DEBUGP (("[IRI fallbacking to non-utf8 for %s\n", quote (url)));
xfree (url);
url = xstrdup (u->url);
iri_fallbacked = 1;
goto redirected;
if (strcmp(u->url, orig_parsed->url))
{
DEBUGP (("[IRI fallbacking to non-utf8 for %s\n", quote (url)));
xfree (url);
url = xstrdup (u->url);
iri_fallbacked = 1;
goto redirected;
}
else
DEBUGP (("[Needn't fallback to non-utf8 for %s\n", quote (url)));
}
else
DEBUGP (("[Couldn't fallback to non-utf8 for %s\n", quote (url)));
@@ -1060,10 +1214,12 @@ retrieve_from_file (const char *file, bool html, int *count)
if (dt & TEXTHTML)
html = true;
#ifdef ENABLE_IRI
/* If we have a found a content encoding, use it.
* ( == is okay, because we're checking for identical object) */
if (iri->content_encoding != opt.locale)
set_uri_encoding (iri, iri->content_encoding, false);
#endif
/* Reset UTF-8 encode status */
iri->utf8_encode = opt.enable_iri;
@@ -1099,12 +1255,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,
@@ -1122,13 +1286,13 @@ retrieve_from_file (const char *file, bool html, int *count)
if (parsed_url)
url_free (parsed_url);
if (filename && opt.delete_after && file_exists_p (filename))
if (filename && opt.delete_after && file_exists_p (filename, NULL))
{
DEBUGP (("\
Removing file due to --delete-after in retrieve_from_file():\n"));
logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
if (unlink (filename))
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
logprintf (LOG_NOTQUIET, "Failed to unlink %s: (%d) %s\n", filename, errno, strerror (errno));
dt &= ~RETROKF;
}
@@ -1229,9 +1393,9 @@ rotate_backups(const char *fname)
#endif
int maxlen = strlen (fname) + sizeof (SEP) + numdigit (opt.backups) + AVSL;
char *from = (char *)alloca (maxlen);
char *to = (char *)alloca (maxlen);
struct_stat sb;
char *from = alloca (maxlen);
char *to = alloca (maxlen);
struct stat sb;
int i;
if (stat (fname, &sb) == 0)
@@ -1248,17 +1412,21 @@ rotate_backups(const char *fname)
*/
if (i == opt.backups)
{
sprintf (to, "%s%s%d%s", fname, SEP, i, AVS);
snprintf (to, sizeof(to), "%s%s%d%s", fname, SEP, i, AVS);
delete (to);
}
#endif
sprintf (to, "%s%s%d", fname, SEP, i);
sprintf (from, "%s%s%d", fname, SEP, i - 1);
rename (from, to);
snprintf (to, maxlen, "%s%s%d", fname, SEP, i);
snprintf (from, maxlen, "%s%s%d", fname, SEP, i - 1);
if (rename (from, to))
logprintf (LOG_NOTQUIET, "Failed to rename %s to %s: (%d) %s\n",
from, to, errno, strerror (errno));
}
sprintf (to, "%s%s%d", fname, SEP, 1);
rename(fname, to);
snprintf (to, maxlen, "%s%s%d", fname, SEP, 1);
if (rename(fname, to))
logprintf (LOG_NOTQUIET, "Failed to rename %s to %s: (%d) %s\n",
fname, to, errno, strerror (errno));
}
static bool no_proxy_match (const char *, const char **);

View File

@@ -1,7 +1,5 @@
/* Declarations for retr.c.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -49,7 +47,9 @@ enum {
rb_skip_startpos = 2,
/* Used by HTTP/HTTPS*/
rb_chunked_transfer_encoding = 4
rb_chunked_transfer_encoding = 4,
rb_compressed_gzip = 8
};
int fd_read_body (const char *, int, FILE *, wgint, wgint, wgint *, wgint *, double *, int, FILE *);

View File

@@ -1,6 +1,5 @@
/* SSL support.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 2011, 2012, 2015 Free Software Foundation, Inc.
Copyright (C) 2000-2012, 2015, 2018 Free Software Foundation, Inc.
Originally contributed by Christian Fraenkel.
This file is part of GNU Wget.

View File

@@ -1,7 +1,5 @@
/* Dirty system-dependent hacks.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -35,56 +33,11 @@ as that of the covered work. */
#ifndef SYSDEP_H
#define SYSDEP_H
/* Testing for __sun is not enough because it's also defined on SunOS. */
#ifdef __sun
# ifdef __SVR4
# define solaris
# endif
#endif
#if defined(__INTERIX) && !defined(_ALL_SOURCE)
# define _ALL_SOURCE
#endif
/* The "namespace tweaks" below attempt to set a friendly "compilation
environment" under popular operating systems. Default compilation
environment often means that some functions that are "extensions"
are not declared -- `strptime' is one example.
But non-default environments can expose bugs in the system header
files, crippling compilation in _very_ non-obvious ways. Because
of that, we define them only on well-tested architectures where we
know they will work. */
#undef NAMESPACE_TWEAKS
#ifdef solaris
# define NAMESPACE_TWEAKS
#endif
#if defined(__linux__) || defined(__GLIBC__)
# define NAMESPACE_TWEAKS
#endif
#ifdef NAMESPACE_TWEAKS
/* Request the "Unix 98 compilation environment". */
#define _XOPEN_SOURCE 500
#endif /* NAMESPACE_TWEAKS */
/* Alloca declaration, based on recommendation in the Autoconf manual.
These have to be after the above namespace tweaks, but before any
non-preprocessor code. */
/* Provided by gnulib on systems that don't have it: */
#include <alloca.h>
/* Must include these, so we can test for the missing stat macros and
define them as necessary. */
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <inttypes.h>
@@ -98,108 +51,9 @@ as that of the covered work. */
# include "mswindows.h"
#endif
/* Provided by gnulib on systems that don't have it: */
# include <stdbool.h>
#ifndef struct_stat
# define struct_stat struct stat
#endif
#ifndef struct_fstat
# define struct_fstat struct stat
#endif
#include <intprops.h>
/* For CHAR_BIT, LONG_MAX, etc. */
#include <stdbool.h>
#include <limits.h>
#ifndef CHAR_BIT
# define CHAR_BIT 8
#endif
/* These are defined in cmpt.c if missing, so we must declare
them. */
#ifndef HAVE_STRCASECMP
int strcasecmp ();
#endif
#ifndef HAVE_STRNCASECMP
int strncasecmp ();
#endif
#ifndef HAVE_STRPTIME
char *strptime ();
#endif
#ifndef HAVE_TIMEGM
# include <time.h>
time_t timegm (struct tm *);
#endif
#ifndef HAVE_MEMRCHR
void *memrchr (const void *, int, size_t);
#endif
/* These are defined in snprintf.c. It would be nice to have an
snprintf.h, though. */
#ifndef HAVE_SNPRINTF
int snprintf (char *str, size_t count, const char *fmt, ...);
#endif
#ifndef HAVE_VSNPRINTF
#include <stdarg.h>
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
#endif
/* Some systems (Linux libc5, "NCR MP-RAS 3.0", and others) don't
provide MAP_FAILED, a symbolic constant for the value returned by
mmap() when it doesn't work. Usually, this constant should be -1.
This only makes sense for files that use mmap() and include
sys/mman.h *before* sysdep.h, but doesn't hurt others. */
#ifndef MAP_FAILED
# define MAP_FAILED ((void *) -1)
#endif
/* Enable system fnmatch only on systems where fnmatch.h is usable.
If the fnmatch on your system is buggy, undef this symbol and a
replacement implementation will be used instead. */
#ifdef HAVE_WORKING_FNMATCH_H
# define SYSTEM_FNMATCH
#endif
#include <fnmatch.h>
/* Provide sig_atomic_t if the system doesn't. */
#ifndef HAVE_SIG_ATOMIC_T
typedef int sig_atomic_t;
#endif
/* Provide uint32_t on the platforms that don't define it. Although
most code should be agnostic about integer sizes, some code really
does need a 32-bit integral type. Such code should use uint32_t.
(The exception is gnu-md5.[ch], which uses its own detection for
portability across platforms.) */
#ifndef HAVE_UINT32_T
# if SIZEOF_INT == 4
typedef unsigned int uint32_t;
# else
# if SIZEOF_LONG == 4
typedef unsigned long uint32_t;
# else
# if SIZEOF_SHORT == 4
typedef unsigned short uint32_t;
# else
#error "Cannot determine a 32-bit unsigned integer type"
# endif
# endif
# endif
#endif
/* If uintptr_t isn't defined, simply typedef it to unsigned long. */
#ifndef HAVE_UINTPTR_T
typedef unsigned long uintptr_t;
#endif
/* If intptr_t isn't defined, simply typedef it to long. */
#ifndef HAVE_INTPTR_T
typedef long intptr_t;
#endif
#include "intprops.h"
#endif /* SYSDEP_H */

View File

@@ -1,6 +1,5 @@
/* Unit testing.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
Copyright (C) 2005-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,6 +1,5 @@
/* Unit testing declarations.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
Copyright (C) 2005-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.

184
src/url.c
View File

@@ -1,7 +1,5 @@
/* URL handling.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -43,6 +41,11 @@ as that of the covered work. */
#include "host.h" /* for is_valid_ipv6_address */
#include "c-strcase.h"
#ifdef HAVE_ICONV
# include <iconv.h>
#endif
#include <langinfo.h>
#ifdef __VMS
#include "vms.h"
#endif /* def __VMS */
@@ -454,7 +457,7 @@ url_scheme (const char *url)
int i;
for (i = 0; supported_schemes[i].leading_string; i++)
if (0 == strncasecmp (url, supported_schemes[i].leading_string,
if (0 == c_strncasecmp (url, supported_schemes[i].leading_string,
strlen (supported_schemes[i].leading_string)))
{
if (!(supported_schemes[i].flags & scm_disabled))
@@ -507,6 +510,12 @@ scheme_disable (enum url_scheme scheme)
supported_schemes[scheme].flags |= scm_disabled;
}
const char *
scheme_leading_string (enum url_scheme scheme)
{
return supported_schemes[scheme].leading_string;
}
/* Skip the username and password, if present in the URL. The
function should *not* be called with the complete URL, but with the
portion after the scheme.
@@ -914,6 +923,17 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
url_unescape (u->host);
host_modified = true;
/* check for invalid control characters in host name */
for (p = u->host; *p; p++)
{
if (c_iscntrl(*p))
{
url_free(u);
error_code = PE_INVALID_HOST_NAME;
goto error;
}
}
/* Apply IDNA regardless of iri->utf8_encode status */
if (opt.enable_iri && iri)
{
@@ -922,7 +942,6 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
{
xfree (u->host);
u->host = new;
u->idn_allocated = true;
host_modified = true;
}
}
@@ -1201,12 +1220,7 @@ url_free (struct url *url)
{
if (url)
{
if (url->idn_allocated) {
idn_free (url->host); /* A dummy if !defined(ENABLE_IRI) */
url->host = NULL;
}
else
xfree (url->host);
xfree (url->host);
xfree (url->path);
xfree (url->url);
@@ -1231,7 +1245,7 @@ mkalldirs (const char *path)
{
const char *p;
char *t;
struct_stat st;
struct stat st;
int res;
p = path + strlen (path);
@@ -1266,12 +1280,14 @@ mkalldirs (const char *path)
name exists, we just remove it and create the directory
anyway. */
DEBUGP (("Removing %s because of directory danger!\n", t));
unlink (t);
if (unlink (t))
logprintf (LOG_NOTQUIET, "Failed to unlink %s (%d): %s\n",
t, errno, strerror(errno));
}
}
res = make_directory (t);
if (res != 0)
logprintf (LOG_NOTQUIET, "%s: %s", t, strerror (errno));
logprintf (LOG_NOTQUIET, "%s: %s\n", t, strerror (errno));
xfree (t);
return res;
}
@@ -1399,8 +1415,8 @@ UVWC, VC, VC, VC, VC, VC, VC, VC, /* NUL SOH STX ETX EOT ENQ ACK BEL */
0, 0, 0, 0, 0, 0, 0, 0, /* p q r s t u v w */
0, 0, 0, 0, W, 0, 0, C, /* x y z { | } ~ DEL */
C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, /* 128-143 */
C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, /* 144-159 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1531,6 +1547,93 @@ append_uri_pathel (const char *b, const char *e, bool escaped,
append_null (dest);
}
#ifdef HAVE_ICONV
static char *
convert_fname (char *fname)
{
char *converted_fname = fname;
const char *from_encoding = opt.encoding_remote;
const char *to_encoding = opt.locale;
iconv_t cd;
size_t len, done, inlen, outlen;
char *s;
const char *orig_fname = fname;
/* Defaults for remote and local encodings. */
if (!from_encoding)
from_encoding = "UTF-8";
if (!to_encoding)
to_encoding = nl_langinfo (CODESET);
cd = iconv_open (to_encoding, from_encoding);
if (cd == (iconv_t) (-1))
logprintf (LOG_VERBOSE, _ ("Conversion from %s to %s isn't supported\n"),
quote (from_encoding), quote (to_encoding));
else
{
inlen = strlen (fname);
len = outlen = inlen * 2;
converted_fname = s = xmalloc (outlen + 1);
done = 0;
for (;;)
{
errno = 0;
if (iconv (cd, (ICONV_CONST char **) &fname, &inlen, &s, &outlen) == 0
&& iconv (cd, NULL, NULL, &s, &outlen) == 0)
{
*(converted_fname + len - outlen - done) = '\0';
iconv_close (cd);
DEBUGP (("Converted file name '%s' (%s) -> '%s' (%s)\n",
orig_fname, from_encoding, converted_fname, to_encoding));
xfree (orig_fname);
return converted_fname;
}
/* Incomplete or invalid multibyte sequence */
if (errno == EINVAL || errno == EILSEQ || errno == 0)
{
if (errno)
logprintf (LOG_VERBOSE,
_ ("Incomplete or invalid multibyte sequence encountered\n"));
else
logprintf (LOG_VERBOSE,
_ ("Unconvertable multibyte sequence encountered\n"));
xfree (converted_fname);
converted_fname = (char *) orig_fname;
break;
}
else if (errno == E2BIG) /* Output buffer full */
{
done = len;
len = outlen = done + inlen * 2;
converted_fname = xrealloc (converted_fname, outlen + 1);
s = converted_fname + done;
}
else /* Weird, we got an unspecified error */
{
logprintf (LOG_VERBOSE, _ ("Unhandled errno %d\n"), errno);
xfree (converted_fname);
converted_fname = (char *) orig_fname;
break;
}
}
DEBUGP (("Failed to convert file name '%s' (%s) -> '?' (%s)\n",
orig_fname, from_encoding, to_encoding));
}
iconv_close(cd);
return converted_fname;
}
#else
static char *
convert_fname (char *fname)
{
return fname;
}
#endif
/* Append to DEST the directory structure that corresponds the
directory part of URL's path. For example, if the URL is
http://server/dir1/dir2/file, this appends "/dir1/dir2".
@@ -1603,35 +1706,43 @@ url_file_name (const struct url *u, char *replaced_filename)
/* If "dirstruct" is turned on (typically the case with -r), add
the host and port (unless those have been turned off) and
directory structure. */
/* All safe remote chars are unescaped and stored in temp_fnres,
then converted to local and appended to fnres.
Internationalized URL/IDN will produce punycode to lookup IP from DNS:
https://en.wikipedia.org/wiki/URL
https://en.wikipedia.org/wiki/Internationalized_domain_name
Non-ASCII code chars in the path:
https://en.wikipedia.org/wiki/List_of_Unicode_characters
https://en.wikipedia.org/wiki/List_of_writing_systems */
if (opt.dirstruct)
{
if (opt.protocol_directories)
{
if (fnres.tail)
append_char ('/', &fnres);
append_string (supported_schemes[u->scheme].name, &fnres);
if (temp_fnres.tail)
append_char ('/', &temp_fnres);
append_string (supported_schemes[u->scheme].name, &temp_fnres);
}
if (opt.add_hostdir)
{
if (fnres.tail)
append_char ('/', &fnres);
if (temp_fnres.tail)
append_char ('/', &temp_fnres);
if (0 != strcmp (u->host, ".."))
append_string (u->host, &fnres);
append_string (u->host, &temp_fnres);
else
/* Host name can come from the network; malicious DNS may
allow ".." to be resolved, causing us to write to
"../<file>". Defang such host names. */
append_string ("%2E%2E", &fnres);
append_string ("%2E%2E", &temp_fnres);
if (u->port != scheme_default_port (u->scheme))
{
char portstr[24];
number_to_string (portstr, u->port);
append_char (FN_PORT_SEP, &fnres);
append_string (portstr, &fnres);
append_char (FN_PORT_SEP, &temp_fnres);
append_string (portstr, &temp_fnres);
}
}
append_dir_structure (u, &fnres);
append_dir_structure (u, &temp_fnres);
}
if (!replaced_filename)
@@ -1652,12 +1763,23 @@ url_file_name (const struct url *u, char *replaced_filename)
fname_len_check = strdupdelim (u_file, u_file + strlen (u_file));
}
if (temp_fnres.tail)
append_char ('/', &temp_fnres);
append_uri_pathel (fname_len_check,
fname_len_check + strlen (fname_len_check), false, &temp_fnres);
fname_len_check + strlen (fname_len_check), true, &temp_fnres);
/* Zero-terminate the temporary file name. */
append_char ('\0', &temp_fnres);
/* convert all remote chars before length check and appending to local path */
fname = convert_fname (temp_fnres.base);
temp_fnres.base = NULL;
temp_fnres.size = 0;
temp_fnres.tail = 0;
append_string (fname, &temp_fnres);
xfree (fname);
/* Check that the length of the file name is acceptable. */
#ifdef WINDOWS
if (MAX_PATH > (fnres.tail + CHOMP_BUFFER + 2))
@@ -1717,7 +1839,7 @@ url_file_name (const struct url *u, char *replaced_filename)
directory (see `mkalldirs' for explanation). */
if (ALLOW_CLOBBER
&& !(file_exists_p (fname) && !file_non_directory_p (fname)))
&& !(file_exists_p (fname, NULL) && !file_non_directory_p (fname)))
{
unique = fname;
}
@@ -1787,7 +1909,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

View File

@@ -1,7 +1,5 @@
/* Declarations for url.c.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -99,10 +97,6 @@ struct url
/* Username and password (unquoted). */
char *user;
char *passwd;
/* 'host' is allocated by idna_to_ascii_8z() via idn_encode().
* Call 'idn_free()' to free this memory. */
bool idn_allocated;
};
/* Function declarations */
@@ -124,6 +118,7 @@ bool url_has_scheme (const char *);
bool url_valid_scheme (const char *);
int scheme_default_port (enum url_scheme);
void scheme_disable (enum url_scheme);
const char *scheme_leading_string (enum url_scheme);
char *url_string (const struct url *, enum url_auth_mode);
char *url_file_name (const struct url *, char *);

View File

@@ -1,7 +1,5 @@
/* Various utility functions.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -31,14 +29,12 @@ as that of the covered work. */
#include "wget.h"
#include "sha256.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#ifdef HAVE_MMAP
# include <sys/mman.h>
#endif
#ifdef HAVE_PROCESS_H
# include <process.h> /* getpid() */
#endif
@@ -47,13 +43,11 @@ as that of the covered work. */
#include <assert.h>
#include <stdarg.h>
#include <locale.h>
#include <errno.h>
#if HAVE_UTIME
# include <sys/types.h>
# ifdef HAVE_UTIME_H
# include <utime.h>
# endif
# include <utime.h>
# ifdef HAVE_SYS_UTIME_H
# include <sys/utime.h>
# endif
@@ -89,6 +83,18 @@ as that of the covered work. */
# define USE_SIGNAL_TIMEOUT
#endif
/* Some systems (Linux libc5, "NCR MP-RAS 3.0", and others) don't
provide MAP_FAILED, a symbolic constant for the value returned by
mmap() when it doesn't work. Usually, this constant should be -1.
This only makes sense for files that use mmap() and include
sys/mman.h *before* sysdep.h, but doesn't hurt others. */
#ifdef HAVE_MMAP
# include <sys/mman.h>
# ifndef MAP_FAILED
# define MAP_FAILED ((void *) -1)
# endif
#endif
#include "utils.h"
#include "hash.h"
@@ -103,7 +109,7 @@ as that of the covered work. */
#include "exits.h"
#include "c-strcase.h"
static void _Noreturn
_Noreturn static void
memfatal (const char *context, long attempted_size)
{
/* Make sure we don't try to store part of the log line, and thus
@@ -225,14 +231,20 @@ xstrdup_lower (const char *s)
/* Copy the string formed by two pointers (one on the beginning, other
on the char after the last char) to a new, malloc-ed location.
0-terminate it. */
0-terminate it.
If both pointers are NULL, the function returns an empty string. */
char *
strdupdelim (const char *beg, const char *end)
{
char *res = xmalloc (end - beg + 1);
memcpy (res, beg, end - beg);
res[end - beg] = '\0';
return res;
if (beg && beg <= end)
{
char *res = xmalloc (end - beg + 1);
memcpy (res, beg, end - beg);
res[end - beg] = '\0';
return res;
}
return xstrdup("");
}
/* Parse a string containing comma-separated elements, and return a
@@ -282,13 +294,6 @@ sepstring (const char *s)
vsnprintf until the correct size is found. Since Wget also ships a
fallback implementation of vsnprintf, this should be portable. */
/* Constant is using for limits memory allocation for text buffer.
Applicable in situation when: vasprintf is not available in the system
and vsnprintf return -1 when long line is truncated (in old versions of
glibc and in other system where C99 doesn`t support) */
#define FMT_MAX_LENGTH 1048576
char *
aprintf (const char *fmt, ...)
{
@@ -308,6 +313,13 @@ aprintf (const char *fmt, ...)
return str;
#else /* not HAVE_VASPRINTF */
/* Constant is using for limits memory allocation for text buffer.
Applicable in situation when: vasprintf is not available in the system
and vsnprintf return -1 when long line is truncated (in old versions of
glibc and in other system where C99 doesn`t support) */
#define FMT_MAX_LENGTH 1048576
/* vasprintf is unavailable. snprintf into a small buffer and
resize it as necessary. */
int size = 32;
@@ -557,7 +569,7 @@ int
remove_link (const char *file)
{
int err = 0;
struct_stat st;
struct stat st;
if (lstat (file, &st) == 0 && S_ISLNK (st.st_mode))
{
@@ -570,21 +582,42 @@ remove_link (const char *file)
return err;
}
/* Does FILENAME exist? This is quite a lousy implementation, since
it supplies no error codes -- only a yes-or-no answer. Thus it
will return that a file does not exist if, e.g., the directory is
unreadable. I don't mind it too much currently, though. The
proper way should, of course, be to have a third, error state,
other than true/false, but that would introduce uncalled-for
additional complexity to the callers. */
/* Does FILENAME exist? */
bool
file_exists_p (const char *filename)
file_exists_p (const char *filename, file_stats_t *fstats)
{
#ifdef HAVE_ACCESS
return access (filename, F_OK) >= 0;
struct stat buf;
#if defined(WINDOWS) || defined(__VMS)
int ret = stat (filename, &buf);
if (ret >= 0)
{
if (fstats != NULL)
fstats->access_err = errno;
}
return ret >= 0;
#else
struct_stat buf;
return stat (filename, &buf) >= 0;
errno = 0;
if (stat (filename, &buf) == 0 && S_ISREG(buf.st_mode) &&
(((S_IRUSR & buf.st_mode) && (getuid() == buf.st_uid)) ||
((S_IRGRP & buf.st_mode) && group_member(buf.st_gid)) ||
(S_IROTH & buf.st_mode))) {
if (fstats != NULL)
{
fstats->access_err = 0;
fstats->st_ino = buf.st_ino;
fstats->st_dev = buf.st_dev;
}
return true;
}
else
{
if (fstats != NULL)
fstats->access_err = (errno == 0 ? EACCES : errno);
errno = 0;
return false;
}
/* NOTREACHED */
#endif
}
@@ -593,7 +626,7 @@ file_exists_p (const char *filename)
bool
file_non_directory_p (const char *path)
{
struct_stat buf;
struct stat buf;
/* Use lstat() rather than stat() so that symbolic links pointing to
directories can be identified correctly. */
if (lstat (path, &buf) != 0)
@@ -620,7 +653,7 @@ file_size (const char *filename)
fclose (fp);
return size;
#else
struct_stat st;
struct stat st;
if (stat (filename, &st) < 0)
return -1;
return st.st_size;
@@ -652,7 +685,7 @@ unique_name_1 (const char *prefix)
do
number_to_string (template_tail, count++);
while (file_exists_p (template));
while (file_exists_p (template, NULL));
return xstrdup (template);
}
@@ -680,7 +713,7 @@ unique_name (const char *file, bool allow_passthrough)
{
/* If the FILE itself doesn't exist, return it without
modification. */
if (!file_exists_p (file))
if (!file_exists_p (file, NULL))
return allow_passthrough ? (char *)file : xstrdup (file);
/* Otherwise, find a numeric suffix that results in unused file name
@@ -809,7 +842,7 @@ fopen_excl (const char *fname, int binary)
/* Manually check whether the file exists. This is prone to race
conditions, but systems without O_EXCL haven't deserved
better. */
if (file_exists_p (fname))
if (file_exists_p (fname, NULL))
{
errno = EEXIST;
return NULL;
@@ -818,6 +851,113 @@ fopen_excl (const char *fname, int binary)
#endif /* not O_EXCL */
}
/* fopen_stat() assumes that file_exists_p() was called earlier.
file_stats_t passed to this function was returned from file_exists_p()
This is to prevent TOCTTOU race condition.
Details : FIO45-C from https://www.securecoding.cert.org/
Note that for creating a new file, this check is not useful
Input:
fname => Name of file to open
mode => File open mode
fstats => Saved file_stats_t about file that was checked for existence
Returns:
NULL if there was an error
FILE * of opened file stream
*/
FILE *
fopen_stat(const char *fname, const char *mode, file_stats_t *fstats)
{
int fd;
FILE *fp;
struct stat fdstats;
fp = fopen (fname, mode);
if (fp == NULL)
{
logprintf (LOG_NOTQUIET, _("Failed to Fopen file %s\n"), fname);
return NULL;
}
fd = fileno (fp);
if (fd < 0)
{
logprintf (LOG_NOTQUIET, _("Failed to get FD for file %s\n"), fname);
fclose (fp);
return NULL;
}
memset(&fdstats, 0, sizeof(fdstats));
if (fstat (fd, &fdstats) == -1)
{
logprintf (LOG_NOTQUIET, _("Failed to stat file %s, (check permissions)\n"), fname);
fclose (fp);
return NULL;
}
#if !(defined(WINDOWS) || defined(__VMS))
if (fstats != NULL &&
(fdstats.st_dev != fstats->st_dev ||
fdstats.st_ino != fstats->st_ino))
{
/* File changed since file_exists_p() : NOT SAFE */
logprintf (LOG_NOTQUIET, _("File %s changed since the last check. Security check failed."), fname);
fclose (fp);
return NULL;
}
#endif
return fp;
}
/* open_stat assumes that file_exists_p() was called earlier to save file_stats
file_stats_t passed to this function was returned from file_exists_p()
This is to prevent TOCTTOU race condition.
Details : FIO45-C from https://www.securecoding.cert.org/
Note that for creating a new file, this check is not useful
Input:
fname => Name of file to open
flags => File open flags
mode => File open mode
fstats => Saved file_stats_t about file that was checked for existence
Returns:
-1 if there was an error
file descriptor of opened file stream
*/
int
open_stat(const char *fname, int flags, mode_t mode, file_stats_t *fstats)
{
int fd;
struct stat fdstats;
fd = open (fname, flags, mode);
if (fd < 0)
{
logprintf (LOG_NOTQUIET, _("Failed to open file %s, reason :%s\n"), fname, strerror(errno));
return -1;
}
memset(&fdstats, 0, sizeof(fdstats));
if (fstat (fd, &fdstats) == -1)
{
logprintf (LOG_NOTQUIET, _("Failed to stat file %s, error: %s\n"), fname, strerror(errno));
return -1;
}
#if !(defined(WINDOWS) || defined(__VMS))
if (fstats != NULL &&
(fdstats.st_dev != fstats->st_dev ||
fdstats.st_ino != fstats->st_ino))
{
/* File changed since file_exists_p() : NOT SAFE */
logprintf (LOG_NOTQUIET, _("Trying to open file %s but it changed since last check. Security check failed."), fname);
close (fd);
return -1;
}
#endif
return fd;
}
/* Create DIRECTORY. If some of the pathname components of DIRECTORY
are missing, create them first. In case any mkdir() call fails,
return its error status. Returns 0 on successful completion.
@@ -846,7 +986,7 @@ make_directory (const char *directory)
/* Check whether the directory already exists. Allow creation of
of intermediate directories to fail, as the initial path components
are not necessarily directories! */
if (!file_exists_p (dir))
if (!file_exists_p (dir, NULL))
ret = mkdir (dir, 0777);
else
ret = 0;
@@ -1174,7 +1314,7 @@ wget_read_file (const char *file)
#ifdef HAVE_MMAP
{
struct_fstat buf;
struct stat buf;
if (fstat (fd, &buf) < 0)
goto mmap_lose;
fm->length = buf.st_size;
@@ -1317,7 +1457,7 @@ merge_vecs (char **v1, char **v2)
for (j = 0; v2[j]; j++)
;
/* Reallocate v1. */
v1 = xrealloc (v1, (i + j + 1) * sizeof (char **));
v1 = xrealloc (v1, (i + j + 1) * sizeof (char *));
memcpy (v1 + i, v2, (j + 1) * sizeof (char *));
xfree (v2);
return v1;
@@ -1590,7 +1730,7 @@ numdigit (wgint number)
{
int cnt = 1;
if (number < 0)
++cnt; /* accomodate '-' */
++cnt; /* accommodate '-' */
while ((number /= 10) != 0)
++cnt;
return cnt;
@@ -1920,7 +2060,7 @@ random_float (void)
static sigjmp_buf run_with_timeout_env;
static void _Noreturn
_Noreturn static void
abort_run_with_timeout (int sig _GL_UNUSED)
{
assert (sig == SIGALRM);
@@ -2035,13 +2175,16 @@ run_with_timeout (double timeout, void (*fun) (void *), void *arg)
return false;
}
signal (SIGALRM, abort_run_with_timeout);
if (SETJMP (run_with_timeout_env) != 0)
{
/* Longjumped out of FUN with a timeout. */
signal (SIGALRM, SIG_DFL);
return true;
}
else
{
signal (SIGALRM, abort_run_with_timeout);
}
alarm_set (timeout);
fun (arg);
@@ -2130,7 +2273,7 @@ xsleep (double seconds)
base64 data. */
size_t
base64_encode (const void *data, size_t length, char *dest)
wget_base64_encode (const void *data, size_t length, char *dest)
{
/* Conversion table. */
static const char tbl[64] = {
@@ -2187,7 +2330,7 @@ base64_encode (const void *data, size_t length, char *dest)
/* Decode data from BASE64 (a null-terminated string) into memory
pointed to by DEST. DEST is assumed to be large enough to
accomodate the decoded data, which is guaranteed to be no more than
accommodate the decoded data, which is guaranteed to be no more than
3/4*strlen(base64).
Since DEST is assumed to contain binary data, it is not
@@ -2198,7 +2341,7 @@ base64_encode (const void *data, size_t length, char *dest)
This function originates from Free Recode. */
ssize_t
base64_decode (const char *base64, void *dest)
wget_base64_decode (const char *base64, void *dest, size_t size)
{
/* Table of base64 values for first 128 characters. Note that this
assumes ASCII (but so does Wget in other places). */
@@ -2222,7 +2365,8 @@ base64_decode (const char *base64, void *dest)
#define IS_BASE64(c) ((IS_ASCII (c) && BASE64_CHAR_TO_VALUE (c) >= 0) || c == '=')
const char *p = base64;
char *q = dest;
unsigned char *q = dest;
ssize_t n = 0;
while (1)
{
@@ -2244,7 +2388,12 @@ base64_decode (const char *base64, void *dest)
if (c == '=' || !IS_BASE64 (c))
return -1; /* illegal char while decoding base64 */
value |= BASE64_CHAR_TO_VALUE (c) << 12;
*q++ = value >> 16;
if (size)
{
*q++ = value >> 16;
size--;
}
n++;
/* Process third byte of a quadruplet. */
NEXT_CHAR (c, p);
@@ -2264,7 +2413,12 @@ base64_decode (const char *base64, void *dest)
}
value |= BASE64_CHAR_TO_VALUE (c) << 6;
*q++ = 0xff & value >> 8;
if (size)
{
*q++ = 0xff & value >> 8;
size--;
}
n++;
/* Process fourth byte of a quadruplet. */
NEXT_CHAR (c, p);
@@ -2276,12 +2430,17 @@ base64_decode (const char *base64, void *dest)
return -1; /* illegal char while decoding base64 */
value |= BASE64_CHAR_TO_VALUE (c);
*q++ = 0xff & value;
if (size)
{
*q++ = 0xff & value;
size--;
}
n++;
}
#undef IS_BASE64
#undef BASE64_CHAR_TO_VALUE
return q - (char *) dest;
return n;
}
#ifdef HAVE_LIBPCRE
@@ -2403,17 +2562,17 @@ mergesort_internal (void *base, void *temp, size_t size, size_t from, size_t to,
}
/* Stable sort with interface exactly like standard library's qsort.
Uses mergesort internally, allocating temporary storage with
alloca. */
Uses mergesort internally. */
void
stable_sort (void *base, size_t nmemb, size_t size,
int (*cmpfun) (const void *, const void *))
{
if (size > 1)
if (nmemb > 1 && size > 1)
{
void *temp = alloca (nmemb * size * sizeof (void *));
void *temp = xmalloc (nmemb * size);
mergesort_internal (base, temp, size, 0, nmemb - 1, cmpfun);
xfree(temp);
}
}
@@ -2514,13 +2673,224 @@ wg_hex_to_string (char *str_buffer, const char *hex_buffer, size_t hex_len)
for (i = 0; i < hex_len; i++)
{
/* Each byte takes 2 characters. */
sprintf (str_buffer + 2 * i, "%02x", hex_buffer[i] & 0xFF);
sprintf (str_buffer + 2 * i, "%02x", (unsigned) (hex_buffer[i] & 0xFF));
}
/* Null-terminate result. */
str_buffer[2 * i] = '\0';
}
#ifdef HAVE_SSL
/*
* Public key pem to der conversion
*/
static bool
wg_pubkey_pem_to_der (const char *pem, unsigned char **der, size_t *der_len)
{
char *stripped_pem, *begin_pos, *end_pos;
size_t pem_count, stripped_pem_count = 0, pem_len;
ssize_t size;
unsigned char *base64data;
*der = NULL;
*der_len = 0;
/* if no pem, exit. */
if (!pem)
return false;
begin_pos = strstr (pem, "-----BEGIN PUBLIC KEY-----");
if (!begin_pos)
return false;
pem_count = begin_pos - pem;
/* Invalid if not at beginning AND not directly following \n */
if (0 != pem_count && '\n' != pem[pem_count - 1])
return false;
/* 26 is length of "-----BEGIN PUBLIC KEY-----" */
pem_count += 26;
/* Invalid if not directly following \n */
end_pos = strstr (pem + pem_count, "\n-----END PUBLIC KEY-----");
if (!end_pos)
return false;
pem_len = end_pos - pem;
stripped_pem = xmalloc (pem_len - pem_count + 1);
/*
* Here we loop through the pem array one character at a time between the
* correct indices, and place each character that is not '\n' or '\r'
* into the stripped_pem array, which should represent the raw base64 string
*/
while (pem_count < pem_len) {
if ('\n' != pem[pem_count] && '\r' != pem[pem_count])
stripped_pem[stripped_pem_count++] = pem[pem_count];
++pem_count;
}
/* Place the null terminator in the correct place */
stripped_pem[stripped_pem_count] = '\0';
base64data = xmalloc (BASE64_LENGTH(stripped_pem_count));
size = wget_base64_decode (stripped_pem, base64data, BASE64_LENGTH(stripped_pem_count));
if (size < 0) {
xfree (base64data); /* malformed base64 from server */
} else {
*der = base64data;
*der_len = (size_t) size;
}
xfree (stripped_pem);
return *der_len > 0;
}
/*
* Generic pinned public key check.
*/
bool
wg_pin_peer_pubkey (const char *pinnedpubkey, const char *pubkey, size_t pubkeylen)
{
struct file_memory *fm;
unsigned char *buf = NULL, *pem_ptr = NULL;
size_t size, pem_len;
bool pem_read;
bool result = false;
size_t pinkeylen;
ssize_t decoded_hash_length;
char *pinkeycopy, *begin_pos, *end_pos;
unsigned char *sha256sumdigest = NULL, *expectedsha256sumdigest = NULL;
/* if a path wasn't specified, don't pin */
if (!pinnedpubkey)
return true;
if (!pubkey || !pubkeylen)
return result;
/* only do this if pinnedpubkey starts with "sha256//", length 8 */
if (strncmp (pinnedpubkey, "sha256//", 8) == 0)
{
/* compute sha256sum of public key */
sha256sumdigest = xmalloc (SHA256_DIGEST_SIZE);
sha256_buffer (pubkey, pubkeylen, sha256sumdigest);
expectedsha256sumdigest = xmalloc (SHA256_DIGEST_SIZE);
/* it starts with sha256//, copy so we can modify it */
pinkeylen = strlen (pinnedpubkey) + 1;
pinkeycopy = xmalloc (pinkeylen);
memcpy (pinkeycopy, pinnedpubkey, pinkeylen);
/* point begin_pos to the copy, and start extracting keys */
begin_pos = pinkeycopy;
do
{
end_pos = strstr (begin_pos, ";sha256//");
/*
* if there is an end_pos, null terminate,
* otherwise it'll go to the end of the original string
*/
if (end_pos)
end_pos[0] = '\0';
/* decode base64 pinnedpubkey, 8 is length of "sha256//" */
decoded_hash_length = wget_base64_decode (begin_pos + 8, expectedsha256sumdigest, SHA256_DIGEST_SIZE);
/* if valid base64, compare sha256 digests directly */
if (SHA256_DIGEST_SIZE == decoded_hash_length)
{
if (!memcmp (sha256sumdigest, expectedsha256sumdigest, SHA256_DIGEST_SIZE))
{
result = true;
break;
}
}
else
logprintf (LOG_VERBOSE, _ ("Skipping key with wrong size (%d/%d): %s\n"),
(int) (strlen (begin_pos + 8) * 3) / 4, SHA256_DIGEST_SIZE,
quote (begin_pos + 8));
/*
* change back the null-terminator we changed earlier,
* and look for next begin
*/
if (end_pos)
{
end_pos[0] = ';';
begin_pos = strstr (end_pos, "sha256//");
}
}
while (end_pos && begin_pos);
xfree (sha256sumdigest);
xfree (expectedsha256sumdigest);
xfree (pinkeycopy);
return result;
}
/* fall back to assuming this is a file path */
fm = wget_read_file (pinnedpubkey);
if (!fm)
return result;
/* Check the file's size */
if (fm->length < 0 || fm->length > MAX_PINNED_PUBKEY_SIZE)
goto cleanup;
/*
* if the size of our certificate is bigger than the file
* size then it can't match
*/
size = (size_t) fm->length;
if (pubkeylen > size)
goto cleanup;
/* If the sizes are the same, it can't be base64 encoded, must be der */
if (pubkeylen == size)
{
if (!memcmp (pubkey, fm->content, pubkeylen))
result = true;
goto cleanup;
}
/*
* Otherwise we will assume it's PEM and try to decode it
* after placing null terminator
*/
buf = xmalloc (size + 1);
memcpy (buf, fm->content, size);
buf[size] = '\0';
pem_read = wg_pubkey_pem_to_der ((const char *) buf, &pem_ptr, &pem_len);
/* if it wasn't read successfully, exit */
if (!pem_read)
goto cleanup;
/*
* if the size of our certificate doesn't match the size of
* the decoded file, they can't be the same, otherwise compare
*/
if (pubkeylen == pem_len && !memcmp (pubkey, pem_ptr, pubkeylen))
result = true;
cleanup:
xfree (buf);
xfree (pem_ptr);
wget_read_file_free (fm);
return result;
}
#endif /* HAVE_SSL */
#ifdef TESTING
const char *

View File

@@ -1,7 +1,5 @@
/* Declarations for utils.c.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
Copyright (C) 1996-2011, 2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -37,6 +35,10 @@ as that of the covered work. */
/* Constant is using when we don`t know attempted size exactly */
#define UNKNOWN_ATTEMPTED_SIZE -3
#ifndef MAX_PINNED_PUBKEY_SIZE
#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
#endif
/* Macros that interface to malloc, but know about type sizes, and
cast the result to the appropriate type. The casts are not
necessary in standard C, but Wget performs them anyway for the sake
@@ -74,15 +76,23 @@ void fork_to_background (void);
char *aprintf (const char *, ...) GCC_FORMAT_ATTR (1, 2);
char *concat_strings (const char *, ...);
typedef struct file_stat_s {
int access_err; /* Error in accecssing file : Not present vs permission */
ino_t st_ino; /* st_ino from stats() on the file before open() */
dev_t st_dev; /* st_dev from stats() on the file before open() */
} file_stats_t;
void touch (const char *, time_t);
int remove_link (const char *);
bool file_exists_p (const char *);
bool file_exists_p (const char *, file_stats_t *);
bool file_non_directory_p (const char *);
wgint file_size (const char *);
int make_directory (const char *);
char *unique_name (const char *, bool);
FILE *unique_create (const char *, bool, char **);
FILE *fopen_excl (const char *, int);
FILE *fopen_stat (const char *, const char *, file_stats_t *);
int open_stat (const char *, int, mode_t, file_stats_t *);
char *file_merge (const char *, const char *);
int fnmatch_nocase (const char *, const char *, int);
@@ -136,8 +146,8 @@ void xsleep (double);
/* How many bytes it will take to store LEN bytes in base64. */
#define BASE64_LENGTH(len) (4 * (((len) + 2) / 3))
size_t base64_encode (const void *, size_t, char *);
ssize_t base64_decode (const char *, void *);
size_t wget_base64_encode (const void *, size_t, char *);
ssize_t wget_base64_decode (const char *, void *, size_t);
#ifdef HAVE_LIBPCRE
void *compile_pcre_regex (const char *);
@@ -161,4 +171,9 @@ void wg_hex_to_string (char *str_buffer, const char *hex_buffer, size_t hex_len)
extern unsigned char char_prop[];
#ifdef HAVE_SSL
/* Check pinned public key. */
bool wg_pin_peer_pubkey (const char *pinnedpubkey, const char *pubkey, size_t pubkeylen);
#endif
#endif /* UTILS_H */

Some files were not shown because too many files have changed in this diff Show More