544 Commits

Author SHA1 Message Date
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
Giuseppe Scrivano
2b418d1146 Prepare release 1.17
* gnulib: sync with upstream.
* NEWS: Update.
* src/main.c: Change the copyright year.
2015-11-15 15:00:55 +01:00
Tim Rühsen
b041658451 Document combination of -nc and -O
Fixes #46359
2015-11-03 15:13:28 +01:00
Tim Rühsen
6cdfc9c143 Do not download/save file on error when --spider enabled
* src/http.c (gethttp,http_loop):
  Do not download/save file on error when --spider is enabled and not
  working recursive.

Reported-by: Сковорода Никита Андреевич chalkerx@gmail.com
Fixes #45821
2015-11-03 14:29:36 +01:00
Tim Rühsen
b14eeb5aee Fix URL conversion for colons in filenames
* src/convert.c (construct_relative): Prepend './' to filename
* tests/Test-k.px: Amend test to succeed
2015-10-27 13:13:54 +01:00
Tim Rühsen
71979f1643 Adjust indentation of --no-use-server-timestamps in help output
* src/main.c: Adjust indentation of --no-use-server-timestamps
2015-10-15 21:09:59 +02:00
Ander Juaristi
4ad201a7e7 Added --convert-file-only option
* src/convert.c (convert_links_in_hashtable, convert_links):
   test for CO_CONVERT_BASENAME_ONLY.
   (convert_basename): new function.
 * src/convert.h: new constant CO_CONVERT_BASENAME_ONLY.
 * src/init.c, src/main.c, src/options.h: new option "--convert-file-only".
 * doc/wget.texi: updated documentation.

 Reviewed-by: Gabriel Somlo <somlo@cmu.edu>
2015-10-13 16:17:20 +02:00
Darshit Shah
3608c3001c Fix Test-ftp-pasv-not-supported.px
* tests/Test-ftp-pasv-not-supported.px: We do *NOT* expect any
    downloaded files. Also, do not negate the Test response.

    The test originally expected a downloaded file, but this is not
    true. As a result, the test would fail and return exit code 1. This
    was presumably the reason why the test result was negated before
    returning to the shell. Fix this issue, so that the test runs
    correctly without any hacks.
2015-10-12 22:05:49 +05:30
Darshit Shah
d484b14174 Fix make distcheck failures in Perl SSL Tests
* tests/Makefile.am: Add valgrind-suppressions-ssl to EXTRA_DIST
    * tests/Test-proxied-https-auth-keepalive.px: Find valgrind in
    correct path during make distcheck
    * tests/Test-proxied-https-auth.px: Same
2015-10-12 22:05:44 +05:30
christian fafard
b8ee370571 Skip HTTPS perl tests if IO::Socket::SSL not installed
* tests/Test-proxied-https-auth-keepalive.px: Skip test if perl module
  IO::Socket::SSL is not installed (trivial change).
* tests/Test-proxied-https-auth.px: Skip test if perl module
  IO::Socket::SSL is not installed (trivial change).
2015-10-12 10:03:30 +02:00
Ander Juaristi
f5a63e3100 Fix potential race condition
* src/hsts.c (hsts_read_database): get an open file handle
   instead of a file name.
   (hsts_store_dump): get an open file handle
   instead of a file name.
   (hsts_store_open): open the file and pass the open file handle.
   (hsts_store_save): lock the file before the read-merge-dump
   process.

 Reported-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
2015-10-09 10:13:51 +02:00
Ander Juaristi
077e897819 Fix HSTS merge bug
* src/hsts.c (hsts_store_merge): call hsts_new_entry() if the entry
   does not exist in the database.

When merging the existing HSTS database on disk with the one on memory,
the entries that were on disk but not on memory were ignored. Thus,
only the existing entries were merged. This behavior was only triggered
when more than one Wget processes were using the same HSTS database
simultaneously. This commit fixes the bug by adding the new entries
to the on-memory database if they were not found there.
2015-10-09 10:13:23 +02:00
Giuseppe Scrivano
1e7ccfe275 testenv/Test--rejected-log.py: Remove trailing white spaces 2015-09-28 16:31:11 +02:00
Tim Rühsen
26fadc55c2 Handle TLS rehandshakes in GnuTLS code
* src/gnutls.c: New static function _do_handshake()
* src/gnutls.c (wgnutls_read_timeout): Handle rehandshake
* src/gnutls.c (wgnutls_write): Handle rehandshake
* src/gnutls.c (ssl_connect_wget): Move handshake code into _do_handshake()

Fixes #46061
2015-09-28 16:18:33 +02:00
Darshit Shah
e51076e683 Add tests for missing qop in digest auth
* testenv/test-auth-both.py: Add qop parameter for digest auth
    * testenv/test-auth-digest.py: Same
    * testenv/conf/authentication.py: Support additional parameters for
    authentication
    * testenv/servers/http/http_server.py: Same
2015-09-22 16:38:40 +05:30
Darshit Shah
c387db6451 Do not test for impossible qop value
* http.c (digest_authentication_encode): Wget already errors out if
    qop != "auth". Then it makes no sense to test for qop == "auth-int"
    later on. Currently, Wget does not support the "auth-int" qop value
    and till nobidy requests, it may remain so.
2015-09-22 16:36:40 +05:30
Darshit Shah
12dfc03116 Fix #46024. Support RFC 2069 Digest Authentication
* http.c (digest_authentication_encode): Some servers are still
    using the obsolete RFC 2069 Digest Authentication. Allow Digest
    authentication without the qop parameter for this.

    Reported-by: Andreas Longwitz  <longwitz@incore.de>
2015-09-22 15:41:22 +05:30
Darshit Shah
3ea0beec6f Revert "Disable progress bar when wget is backgrounded (trivial patch)"
This reverts commit e624732563.
2015-09-21 19:41:38 +05:30
Giuseppe Scrivano
b50300a7a2 NEWS: cite FTPS support 2015-09-20 15:15:12 +02:00
Ander Juaristi
f8901af4e0 Added support for FTPS
* doc/wget.texi: updated documentation to reflect the new FTPS functionality.
 * src/ftp-basic.c (ftp_greeting): new function to read the server's greeting.
   (ftp_login): greeting code was previously here. Moved to ftp_greeting to
   support FTPS implicit mode.
   (ftp_auth): wrapper around the AUTH TLS command.
   (ftp_ccc): wrapper around the CCC command.
   (ftp_pbsz): wrapper around the PBSZ command.
   (ftp_prot): wraooer around the PROT command.
 * src/ftp.c (get_ftp_greeting): new static function.
   (init_control_ssl_connection): new static function to start SSL/TLS on the
   control channel.
   (getftp): added hooks to support FTPS commands (RFCs 2228 and 4217).
   (ftp_loop_internal): test for new FTPS error codes.
 * src/ftp.h: new enum 'prot_level' with available FTPS protection levels +
   prototypes of previous functions. New flag for enum 'wget_ftp_fstatus' to track
   whether the data channel has some security mechanism enabled or not.
 * src/gnutls.c (struct wgnutls_transport_context): new field 'session_data'.
   (wgnutls_close): free GnuTLS session data before exiting.
   (ssl_connect_wget): save/resume SSL/TLS session.
 * src/http.c (establish_connection): refactor ssl_connect_wget call.
   (metalink_from_http): take into account SCHEME_FTPS as well.
 * src/init.c, src/main.c, src/options.h: new command line/wgetrc options.
   (main): in recursive downloads, check for SCHEME_FTPS as well.
 * src/openssl.c (struct openssl_transport_context): new field 'sess'.
   (ssl_connect_wget): save/resume SSL/TLS session.
 * src/retr.c (retrieve_url): check new scheme SCHEME_FTPS.
 * src/ssl.h (ssl_connect_wget): refactor. New parameter of type 'int *'.
 * src/url.c. src/url.h: new scheme SCHEME_FTPS.
 * src/wget.h: new FTPS error codes.
 * src/metalink.h: support FTPS scheme.
2015-09-14 10:16:44 +02:00
Christian Neukirchen
e624732563 Disable progress bar when wget is backgrounded (trivial patch)
* src/progress.c (create_image): progress only when in foreground

Sometimes I start wget, but the remote site is too slow, so I rather
want to run it in background, however when I simply use job control
for that, wget will keep spewing the progress bar all over my
terminal.  I have found the SIGHUP/SIGUSR1 feature to redirect output
to a log file, but I think the following small patch is even more
useful, since the progress bar will simply resume when wget is
foregrounded again (also, the final message is still printed to the
terminal in any case):
2015-09-10 10:26:29 +02:00
Hubert Tarasiuk
f2cb6e050a Add information about libmetalink and GnuPG
* README.checkout: Optional dependencies and URL references.
2015-09-04 08:01:11 +02:00
Hubert Tarasiuk
84b9abbf3c Do not free Metalink structure if not initialized
* src/main.c (main): Move metalink_delete to the conditional block.
2015-09-02 09:17:37 +02:00
Ander Juaristi
58917dcde1 Updated HSTS documentation
* doc/wget.texi: updated HSTS documentation.

   Reported-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
2015-09-01 13:50:40 +02:00
Ander Juaristi
ab47d9fa3a Extra debug traces for HSTS.
* src/main.c (load_hsts, save_hsts): added DEBUGP() calls to signal
   reads and saves of the HSTS database file.
2015-09-01 13:50:40 +02:00
Darshit Shah
187edb604a Fix coding style violation in last commit
* http.c (test_parse_range_header): Declare loop variable
    explicitly. Not in gnu99 standard.
2015-08-31 21:04:54 +05:30
Darshit Shah
b06fca60ac Add unit test for parse_content_range() method
* http.c (test_parse_range_header): New function to test the
    function for parsing the HTTP/1.1 Content-Range header.
    * test.[ch]: Same
    * http.c (parse_content_range): Fix parsing code. Fail on scenarios
    mentioned in rfc 7233.
2015-08-30 21:34:32 +05:30
Tim Rühsen
c809398e8c Fix null pointer dereference
* src/metalink.c (gpg_skip_verification):
  Check output_stream before fclose
2015-08-30 14:17:47 +02:00
Tim Rühsen
88a1a79bc1 Fix leaks found by Coverity
* src/http.c (parse_strict_transport_security): Free c_max_age
             (open_output_stream): Fix indentation
* src/iri.c (locale_to_utf8): Free new
2015-08-30 14:10:25 +02:00
Tim Rühsen
398699c438 Fix two leaks foudn by Coverity
* src/http.c (gethttp): Do not leak 'message'.
* src/main.c (format_and_print_line): Do not leak 'line_dup'.
2015-08-29 22:35:29 +02:00
Tim Rühsen
d3504b9261 Fix resource leak discovered by Coverity
* src/retr.c (retrieve_url): Don't leak local_file.
2015-08-29 22:15:34 +02:00
Darshit Shah
6b5acff566 Fix memory leaks in unit-test
* hsts.c (get_hsts_store_filename): Free the homedir value
    (close_hsts_test_store): Actually free the store struct too
    (test_hsts_new_entry): Pass store to close_hsts_test_store()
    (test_hsts_url_rewrite_superdomain): Same
    (test_hsts_url_rewrite_congruent): Same
    (test_hsts_read_database): Same and homedir and store filename
    * http.c (test_parse_content_disposition): Free the returned
    filename
    * url.c (test_append_uri_pathel): Free allocated string
2015-08-29 22:52:49 +05:30
Darshit Shah
5c4489db9b Fix mixed-indentation in http.c
* http.c: Fix mix indentation. Visual change only.
2015-08-29 09:45:13 +05:30
Tim Rühsen
7bed9a6f8f Suppress debug output when strings may contain password
* iri.c (do_conversion): Do not print out converted strings if they
  contain an '@'. That could be an URL with embedded password.

Fixes #45825
2015-08-27 09:55:13 +02:00
Ander Juaristi
d080a70a3a Fix resource leak.
* src/http.c (parse_strict_transport_security): Freed memory to avoid resource leak.
   Comply with GNU coding style.
2015-08-26 17:50:26 +05:30
Tim Rühsen
2d2ddb25d8 Fix typo in NEWS
* NEWS: Change typo --accept-reject into --accept-regex

Reported-by: grarpamp <grarpamp@gmail.com>
2015-08-22 22:34:33 +02:00
Jookia
030c3379d1 Clarify that links are being converted.
* src/convert.c: Add 'links in' after 'Converted %d' and 'Converting %s'.
2015-08-21 20:58:55 +02:00
Jookia
d3d8de8223 Removed useless TODOs.
* testenv/Test--reject-log.py: Remove TODOs.
2015-08-21 20:58:39 +02:00
Miquel Llobet
e04c5989ff Fixed #44516 -o- not logging to stdout
src/log.c (log_init): check for hypen on filename, set stdout
2015-08-16 00:20:20 +05:30
Daniele Calore
12bae50b28 Fix #40426: Allow -r -O- only if FILE is regular
* main.c: added check of "-r -O FILE" option combination
    allow only if FILE is a regular file (bug #40426)
2015-08-16 00:16:12 +05:30
Darshit Shah
f71887bbe5 Fix var name conflicts with math.h and wingdi.h
* src/recur.c (reject_reason): Rename all enum members to WG_RR_xx.
    * src/recur.c (retrieve_tree, download_child,
    write_reject_log_reason): Same
2015-08-15 15:43:33 +05:30
Tim Rühsen
84c405e690 Let bootstrap/autoreconf work without GPGME installed
* configure.ac: Check for existance of AM_PATH_GPGME
2015-08-14 10:17:52 +02:00
Tim Rühsen
075d755696 Fix IP address exposure in FTP code
* src/ftp.c (getftp): Do not use PORT when PASV fails.
* tests/FTPServer.px: Add pasv_not_supported server flag.
* tests/Makefile.am: Add Test-ftp-pasv-not-supported.px
* tests/Test-ftp-pasv-not-supported.px: New test

Fix IP address exposure when automatically falling back from
passive mode to active mode (using the PORT command). A behavior that
may be used to expose a client's privacy even when using a proxy.
2015-08-11 17:38:33 +02:00
Tim Rühsen
7578e47d49 Fix C89 compliancy in HSTS test code
* src/hsts.c (test_hsts_new_entry):
  Move variable assignment before code
2015-08-07 14:03:00 +02:00
Tim Rühsen
3a708f7ef8 Fix C89 compliancy in latest code
* src/recur.c: Declare variables before code
  (write_reject_log_url):
    Use const keyword where appropriate
    Use the 'default' switch statement
    Use xfree() instead of free()
    Renamed variable f -> fp
  (write_reject_log_reason):
    Use const keyword where appropriate
    Use the 'default' switch statement
    Renamed variable f -> fp
    Renamed variable r -> reason
2015-08-07 13:42:30 +02:00
Tim Rühsen
474935665e Remove redundant definition of _GNU_SOURCE
* src/warc.c: Remove definition of _GNU_SOURCE

_GNU_SOURCE is already defined in config.h
2015-08-07 13:24:14 +02:00
Giuseppe Scrivano
f8519b52f0 NEWS: update 2015-08-07 08:32:34 +02:00
Jookia
98272d2c8d Rewrite the --rejected-log test using the new framework.
* tests/Test--rejected-log.px: Remove old test.
 * testenv/Test--rejected-log.py: Create new test.
2015-08-07 08:20:47 +02:00
Jookia
7e5079c40f Replace variables before comparing expected files.
* expected_files.py: Use formatted_content instead of file.content.
2015-08-07 08:20:46 +02:00
Jookia
e4db00d74d Add option to write URL rejections to a tab-delimited CSV log.
* main.c: Add "--rejected-log" option.
 * init.c: Add "rejectedlog" command.
 * options.h: Add "rejected_log" parameter string.
 * wget.texi: Add brief documentation on new --rejected-log option.
 * recur.c: Optionally log details of URLs not traversed.
   Add reject_reason enum.
   (download_child_p -> download_child): Return a reject_reason.
   (descend_redirect_p -> descend_redirect): Return a reject_reason.
   (retrieve_tree): Support logging reasons for rejection.
   Add write_reject_log_header that writes a CSV format header to a file.
   Add write_reject_log_url that writes a url struct to a file in CSV format.
   Add write_reject_log_reason that writes the URL and parent URL as well as the
   rejection reason to a CSV file.
 * Test--rejected-log.px: Add a basic test for the --rejected-log command.
 * tests/Makefile.am: Run Test--rejected-log.px.

This allows you to figure out why URLs are being rejected and some context
around it. CSV is used as the output format since it can be used easily parsed,
it's delimited by tabs instead of commas to allow using all (quoted) URL
characters and includes column names which may be used for compatibility.
2015-08-06 08:10:55 +02:00
Tim Rühsen
670eb924e7 Fix memory leak in HSTS code
* src/main.c (get_hsts_database): Free 'home' variable
2015-08-04 17:41:54 +02:00
Tim Rühsen
5d55018ce6 void uninitialized variable in metalink code
* src/metalink.c: Init retr_err with METALINK_MISSING_RESOURCE
* src/wget.h: Add enum METALINK_MISSING_RESOURCE
2015-08-04 17:24:59 +02:00
Darshit Shah
4e56a91001 Fix function name collision with OpenSSL library
* src/utils.[ch], src/http.c, src/metalink.c: Rename function
    hex_to_string() to wg_hex_to_string sine it collides with a
    similarly named function in OpenSSL Library.
2015-07-24 23:52:43 +05:30
Darshit Shah
595f219a17 Fix configure options for metalink
* configure.ac: Ensure metalink support can be properly disabled
2015-07-24 23:42:20 +05:30
Alex Henrie
b6e242cd6f Make the filename marquee a proper marquee
* src/progress.c: Start the marquee in the middle of the available space
  and do not restart it until all of the text has scrolled out of view.
2015-07-22 16:52:20 +05:30
Giuseppe Scrivano
207006ef25 NEWS: cite HSTS 2015-07-20 16:31:17 +02:00
Giuseppe Scrivano
843634db59 Fix metalink tests
testenv/Test-metalink-http.py: initialize HTTP test server
testenv/Test-metalink-xml.py: initialize HTTP test server
2015-07-20 16:29:05 +02:00
Ander Juaristi
54058d2b18 Enhancements in testsuite engine + new HSTS test.
* testenv/Makefile.am: added new test 'Test-hsts.py'.
 * testenv/Test-hsts.py: new test for HSTS.
 * testenv/conf/domains.py: new hook to override domain list.
 * testenv/test/base_test.py: (__init__): new optional parameter
   for tests 'req_protocols'.
   (get_domain_addr): set the instance variables 'addr' and 'port'.
   Return address as an array (domain, port) instead of string.
   (gen_cmd_line): take into account domain and port.
 * testenv/test/http_test.py (__init__): new optional parameter
   'req_protocols'.
   (setup): new function. Call to server_setup() decoupled from
   begin() and moved here.
   (begin): call to superclass to maintain backward compatibility.
   Removed call to server_setup().

This patch adds a new parameter to the test suite called 'req_protocols',
and a new function called 'setup'. The ability for tests to be able to set some
extra parameters such as the actual requested protocols (with 'req_protocols')
became obvious when support for HSTS was added to Wget, where the requested URI
and the actual executed URI do not have to be the same. This new parameter is optional
and if not specified, the test suite behaves as before. Also, the new function 'setup'
is provided as a means to start the test HTTP server, but not launch the test yet
(this is done when calling 'begin', as usual), in case we want to query the address
and port in which the test server listens. If 'setup' is not called, it is automatically
invoked when calling 'begin'. With these measures, we preserve backward-compatibility with
existing tests.
2015-07-20 16:06:40 +02:00
Ander Juaristi
b60131a399 Added support for HSTS.
* Makefile.am: Added new source files hsts.c and hsts.h.
 * http.c (parse_strict_transport_security): new function for STS header
   parsing.
   (gethttp): update the HSTS store.
 * http.h: new include "hsts.h".
 * init.c: new options --hsts and --hsts-file.
 * main.c (get_hsts_database, load_hsts, save_hsts): new functions.
   New options --no-hsts and --hsts-file added to help.
   (main): load and save HSTS store.
 * options.h: new variables for supporting --hsts and --hsts-file.
 * retr.c (retrieve_url): rewrite the URI according to the HSTS policy before
   entering http_loop.
 * test.c, test.h: new unit tests for HSTS.
 * utils.c, utils.h (countchars): new function.
 * wget.h: new preprocessor check.
 * hsts.c, hsts.h: new files with the HSTS engine implementation.

Added support for HTTP Strict Transport Security (HSTS), as defined by RFC
6797.
2015-07-20 15:55:57 +02:00
Giuseppe Scrivano
fc8a545bfd NEWS: cite metalink support 2015-07-20 15:50:29 +02:00
Giuseppe Scrivano
9e12b8ca39 fix compiler warnings
* src/utils.h: Include <stdlib.h>
* src/recur.c: Include "exits.h"
2015-07-20 15:37:52 +02:00
Hubert Tarasiuk
4c3043d19d Test preferred location in Metalink-over-HTTP test case.
* testenv/Test-metalink-http.py: Ensure preferred location is handled
properly.
2015-07-20 15:31:06 +02:00
Hubert Tarasiuk
6064f21c66 Geolocation support for Metalink resources.
* doc/wget.text: Add information about --preferred-location.
* src/init.c: Add --preferred-location option.
* src/main.c (option_data): Handle --preferred-location argument.
(main): Sort resources based on location if requested.
* src/metalink.c (metalink_res_cmp): Compare based on location if
priority and preference are equal.
* src/options.h (options): Add preferred_location option.
2015-07-20 15:31:06 +02:00
Hubert Tarasiuk
97389a7497 Support at most one file signature. Adapt comments to libmetalink 0.13.
* src/metalink.c (retrieve_from_metalink): Add comment about new
libmetalink version. Do not iterate over signatures - support just one.
2015-07-20 15:31:06 +02:00
Hubert Tarasiuk
225a87d4a2 Move some Metalink-related code from http.c to metalink.c.
* src/http.c: Move find_key_value, has_key, find_key_values.
* src/metalink.c: To here.
* src/metalink.h: Make them non-static and add prototypes here.
2015-07-20 15:31:06 +02:00
Hubert Tarasiuk
92a889b278 Unit test for find_key_values.
* src/http.c: Add test_find_key_values.
* src/test.c (main): Run new test.
* src/test.h: Add test_find_key_values.
2015-07-20 15:31:06 +02:00
Hubert Tarasiuk
1113e78534 Unit test for has_key.
* src/http.c: Add test_has_key.
* src/test.c (main): Run new test.
* src/test.h: Add test_has_key.
2015-07-20 15:31:06 +02:00
Hubert Tarasiuk
70cbd59ed6 Unit test for find_key_value.
* src/http.c: Add test_find_key_value.
* src/test.c (main): Run new test.
* src/test.h: Add test_find_key_value.
2015-07-20 15:31:06 +02:00
Hubert Tarasiuk
0e7aff7623 Test case for Metalink over HTTP.
* testenv/Test-metalink-http.py: New test.
* testenv/Makefile.am: Add to test list.
2015-07-20 15:31:06 +02:00
Hubert Tarasiuk
792dd09a87 Support multiple headers with same name in Python test suite.
* testenv/README: Describe how to use repeated header name.
* testenv/server/http/http_server.py (finish_headers): Send all
values from list if the header value is a Python list.
2015-07-20 15:31:06 +02:00
Hubert Tarasiuk
a4f5ced797 Test case for Metalink in XML.
* testenv/Test-metalink-xml.py: New test.
* testenv/Makefile.am: Add file for automake.
2015-07-20 15:31:06 +02:00
Hubert Tarasiuk
05c30c3b1b Start HTTP test only when calling begin().
* testenv/test/http_test.py: Move self.do_test() from __init__ to
begin().
2015-07-20 15:30:39 +02:00
Hubert Tarasiuk
37b58e3976 Metalink support.
* bootstrap.conf: Add crypto/sha256
* configure.ac: Look for libmetalink and GPGME
* doc/wget.texi: Add --input-metalink and --metalink-over-http
options description.
* po/POTFILES.in: Add metalink.c
* src/Makefile.am: Add new translation unit (metalink.c)
* src/http.c (http_stat): Add metalink field.
(free_stat): Free metalink field.
(find_key_value): Find value of given key in header string.
(has_key): Check if token exists in header string.
(find_key_values): Find all key=value pairs in header string.
(metalink_from_http): Obtain Metalink metadata from HTTP response.
(gethttp): Call metalink_from_http if requested.
(http_loop): Request Metalink metadata from HTTP response if should be.
Fall back to regular download if no Metalink metadata found.
* src/init.c: Add --input-metalink and --metalink-over-http options
* src/main.c (option_data): Handle --input-metalink and
--metalink-over-http cmd arguments.
(print_help): Print --input-metalink option description.
(main): Retrieve files from Metalink file
* src/metalink.c (retrieve_from_metalink): Download files described by
metalink.
(metalink_res_cmp): Comparator for resources priority-sorting.
* src/metalink.h: Create header for metalink.c
(RES_TYPE_SUPPORTED): Define supported resources media.
(DEFAULT_PRI): Default mirror priority for Metalink over HTTP.
(VALID_PRI_RANGE): Valid priority range.
* src/options.h (options): Add input_metalink option and metalink_over_http
options.
* src/utils.c (hex_to_string): Convert binary data to ASCII-hex.
* src/utils.h (hex_to_string): Add prototype.
* src/wget.h: Add metalink-related error enums
Add METALINK_METADATA flag for document type.
2015-07-20 15:30:39 +02:00
Romain Bentz
80303366ae Add NULL value check to fix #45289
* src/recur.c (retrieve_tree): Check return value of url_parse()
2015-07-15 18:10:08 +02:00
Tim Rühsen
bd0ffcf8bc Let HTTPS tests XFAIL when no TLS support configured
* configure.ac: Export WITH_SSL for use in Makefile.am
* testenv/Makefile.am: Add HTTPS tests to XFAIL_TESTS when !WITH_SSL

Reported-by: Ander Juaristi <ajuaristi@gmx.es>
2015-07-14 07:54:03 +02:00
Tim Rühsen
25c9b462bf Change function params to const in src/iri.[ch]
* iri.h, iri.c: Added const attribute for params of parse_charsset(),
	check_encoding_name(), idn_encode(), idn_decode(),
	remote_to_utf8(), set_uri_encoding(), set_content_encoding().
2015-07-01 17:15:10 +02:00
Tim Rühsen
77f5a27e65 Work around a libidn <= 1.30 vulnerability
* src/iri.c: Add _utf8_is_valid() to check UTF-8 sequences before
  passing them to idna_to_ascii_8z().
2015-07-01 17:15:05 +02:00
Ángel González
ae58d8a78b Fix wgetrc filename creation for Windows
* init.c/wgetrc_file_name: Remove obsolete code in WINDOWS code path

Reported-by: Gisle Vanem <gvanem@yahoo.no>
2015-06-27 21:32:48 +02:00
Darshit Shah
58702ffd4f Add valgrind suppression files for HTTPS tests
* testenv/test/base_test.py: Use Valgrind SSL suppressions file for
    tests
    * testenv/valgrind-suppression-ssl, tests/valgrind-suppression-ssl:
    Add new suppression files to suppress OpenSSL errors in valgrind
    * tests/test-proxied-https-auth.px: Use the valgrind SSL
    suppressions file for the test
    * tests/test-proxied-https-auth-keepalive.px: Same
2015-06-16 20:31:00 +05:30
Darshit Shah
103f940950 contrib/check-hard: Indentation and spacing cleanup
* contrib/check-hard: Reduce the amount of text output to the
    screen. Also implement some indentation and whitespace cleanups.
2015-06-15 01:35:53 +05:30
Tim Rühsen
5f0818d9f1 Fix usage of CFLAGS in contrib/check-hard
* contrib/check-hard: Set CFLAGS per command line instead of using export.

'make distcheck' changes CFLAGS. So using ./configure -C together with
exported CFLAGS fails. Setting CFLAGS per command line works smoothly.
2015-06-14 20:30:07 +02:00
Tim Rühsen
c6ac51d5bc Move test_* function protoypes from test.c to test.h
* src/test.c: Remove test_* function prototypes, make tests_run static
* src/test.h: Add test_* function protoypes
2015-06-13 22:34:36 +02:00
Giuseppe Scrivano
fd3a3245eb NEWS: cite --if-modified-since 2015-05-23 14:54:17 +02:00
Giuseppe Scrivano
48acb6693d gnulib: update gnulib 2015-05-23 14:51:52 +02:00
Hubert Tarasiuk
885eaaa214 Include --if-modified-since option in user manual.
* doc/wget.texi: Add --if-modified-since section.
2015-05-22 11:08:30 +02:00
Hubert Tarasiuk
8a8d138dcc Support If-Modified-Since header in timestamping mode.
* src/wget.h: Add IF_MODIFIED_SINCE enum for dt. Add TIMECONV_ERR
enum to uerr_t.
* src/http.c (time_to_rfc1123): Convert time_t do http time.
* src/http.c (initialize_request): Include If-Modified-Since header
if appropriate.
* src/http.c (set_file_timestamp): Separate this code from check_file_output.
* src/http.c (check_file_output): Use set_file_timestamp.
* src/http.c (gethttp): Handle properly 304 return code and 200 if server
ignores If-Modified-Since headers.
* src/http.c (http_loop): Load filename to hstat if condget was requested,
use IF_MODIFIED_SINCE if requested and current timestamp can be obtained.
2015-05-22 11:08:30 +02:00
Hubert Tarasiuk
0e8d2d4251 Add --if-modified-since option
* src/init.c: Add to commands array.
* src/main.c: Add to cmdline_option. Add to help message.
* src/options.h: Add to options struct.
2015-05-22 11:08:30 +02:00
Hubert Tarasiuk
be4f91737a Add test for condget requests.
* testenv/Test-condget.py: the test
* testenv/Makefile.am: add to tests list
2015-05-22 11:08:30 +02:00
Hubert Tarasiuk
901bc98edf Support conditional GET in testenv server.
* src/exc/server_error.py: Add exception for GET to HEAD fallback.
* src/server/http/http_server.py: Do not send body if 304 return
code requested for a file.
2015-05-22 11:08:30 +02:00
Hubert Tarasiuk
e397a48f6a Implement timestamp support for local files in testenv
* testenv/README: Change timestamp format definition
* testenv/conf/local_files.py: Set proper timestamps
2015-05-22 11:08:30 +02:00
Pär Karlsson
83537f2415 Fix undeclared loop variable in Perl test suite
Reported-by: Hubert Tarasiuk <hubert.tarasiuk@gmail.com>
2015-05-20 10:04:07 +02:00
Ander Juaristi
8682c2612f Make sure Wget does not unescape reserved chars.
* testenv/Test-reserved-chars.py: New file.

* testenv/Makefile.am: Added new test Test-reserved-chars.py.

When following redirections, Wget should not unescape the reserved
characters that might appear in target URLs.
2015-05-12 21:24:11 +02:00
Ander Juaristi
b0820d553b Fixed incorrect handling of reserved chars.
* src/iri.c (do_conversion): Call url_unescape_except_reserved,
instead of url_unescape.

* src/url.c (url_unescape_1): New static function.
(url_unescape): Calls url_unescape_1 with mask zero. Preserves
same behavior as before. Only code changes.
(url_unescape_except_reserved): New function.

* src/url.h: Added prototype for url_unescape_except_reserved().

When the locale is US-ASCII, URIs that contain special characters
in them are converted to IRIs according to RFC 3987, section 3.2
"Converting URIs to IRIs".
2015-05-12 21:24:06 +02:00
Darshit Shah
b6b1388fb7 Fix documentation for update_speed_ring()
* progress.c (update_speed_ring): The comment for the function
    incorrectly stated that the function uses thirty samples from the
    past instead of twenty.

    Reported-By: Yi Li <lovelylich@gmail.com>
2015-05-07 11:29:07 +05:30
Darshit Shah
9b1dd6dab8 Remove shadowed variable in http.c
* http.c (gethttp): Rename err to conn_err to prevent shadowed
    variable
2015-05-04 21:45:26 +05:30
Steven Schubiger
1cc835dc5b paramcheck: use explicit quoting for here-docs
* util/paramcheck.pl: Adjust here-docs
2015-05-04 10:13:24 +05:30
Tim Ruehsen
6b8dfe1d6e Fix format specifier warning
* src/utils.c (aprintf): Use %d for int argument
2015-05-03 21:18:47 +02:00
Nikolay Merinov
0e6d6ca963 Fix timestamping and continue behaviour with ftp protocol.
* src/ftp.c (ftp_loop_internal): Add option `force_full_retrieve' that force to
retrieve full file.
(ftp_retrieve_list): Pass `true' as `force_full_retrieve' option to
`ftp_loop_internal' if we want to download file with newer timestamp than local
copy.
2015-05-01 00:28:08 +02:00
Rohit Mathulla
3765a1b266 openssl: Read cert from private key file when needed
* src/openssl.c (ssl_init): Assign opt.cert_{file, type}
  from opt.private_key(_type)
2015-04-27 19:52:18 +02:00
Rohit Mathulla
8654f7e2e7 Fix double free bug in SSL code
* src/openssl.c, src/gnutls.c (ssl_init): Copy options using xstrdup
2015-04-27 19:48:51 +02:00
Hubert Tarasiuk
566696cb82 Single exit point and common cleanup code in gethttp
* src/http.c (gethttp): Common cleanup for type, message,
  req, resp, head.  Single exit point.
2015-04-20 10:54:34 +02:00
Tim Rühsen
bebe462a67 Silence warning in perl test suite
* tests/WgetTests.pm: Use string comparisons for $valgrind variable
2015-04-17 22:42:59 +02:00
Tim Rühsen
c579c7bf1e Check memory allocations in WARC code
* src/warc.c: Remove some memory allocations,
              use xmalloc instead of malloc

Reported-by: Bill Parker <wp02855@gmail.com>
2015-04-17 22:42:59 +02:00
Tim Rühsen
4dde3e200f Add more const usage to function params
* warc.c, warc.h: Add const specifier to several function args
2015-04-17 22:42:59 +02:00
Darshit Shah
8e0dd0d870 PEP8'ify the Python Test Suite
* testenv/conf/{__init__,authentication,files_crawled,
      hook_sample,reject_header,server_files}.py: Aesthetic changes to
      meet Python PEP8 guidelines
    * testenv/exc/{server_error,test_failed}.py: Same
    * testenv/misc/{colour_terminal,wget_file}.py: Same
    * testenv/server/http/http_server.py: Same
    * testenv/test/base_test.py: Same
2015-04-14 10:59:17 +05:30
Ander Juaristi
c6af2fddee Improved test suite documentation
* README.checkout: Added reference to Python. New section
  "Testing and development". Updated information about test suites.
2015-04-13 19:36:39 +02:00
Ander Juaristi
e7e3227b34 Added support for GDB in Python tests
* base_test.py (gen_cmd_line): Check GDB_TESTS environment variable.
2015-04-13 19:32:57 +02:00
Tim Ruehsen
5c5d45ae49 Added GDB support to Perl tests
* WgetTests.pm (run): Check GDB_TESTS environment variable.
2015-04-13 19:29:43 +02:00
Hubert Tarasiuk
f4072e5d0b Add Valgrind suppression for libidn.so at idna_to_ascii_4z
* tests/WgetTests.pm (run): Include suppression file when running Valgrind.
* tests/valgrind-suppressions: Add suppression for idn_to_ascii_4z.
* tests/Makefile.am: Add valgrind-suppressions to EXTRA_DIST.
2015-04-11 23:16:32 +02:00
Ángel González
bef5945202 Remove memory leak in idn_encode.
* src/iri.c (idn_encode): Free buffer from remote_to_utf8
when needed; give meaningful names to variables;
remove excessive comment.
2015-04-11 21:55:17 +02:00
Hubert Tarasiuk
ac40b84ee1 Fix error in free_vec.
* src/utils.c (free_vec): Increment pointer instead of its value.

Reported-by: Gisle Vanem <gvanem@yahoo.no>
2015-04-10 18:06:14 +02:00
Ángel González
45463eaad7 Fix const usage in iri.c
* src/iri.c (remote_to_utf8): Do not qualify with const the output pointer.
(do_conversion): Use the provided input parameter as const.
(idn_encode): casts to remote_to_utf8 parameters are no longer needed.
* src/iri.h: Adjusted remote_to_utf8 prototype.
* src/url.c: It is no longer necessary to cast new_url to const char.
2015-04-10 10:23:01 +02:00
Miquel Llobet
d03b40e31e Fixed #44628 honoring RFC 6266 content-disposition
src/http.c (parse_content_disposition): stores filename* and filename
separately and choses filename* if available.
(test_parse_content_disposition): added new tests.
2015-04-06 10:30:30 +02:00
Giuseppe Scrivano
268e6aef72 NEWS: cite last change 2015-04-02 15:39:02 +02:00
Steven M. Schweda
5efb24e4a2 Add option to restrict filenames used VMS.
* src/options.h (enum restrict_files_os): Define "restrict_vms".
* src/init.c (defaults) [__VMS]: Set "opt.restrict_files_os" to
"restrict_vms".
(cmd_spec_restrict_file_names): honor "vms".
* src/url.c (filechr_not_unix): Define "filechr_not_vms".
(filechr_table): Update for VMS.
(append_uri_pathel): Honor opt.restrict_files_os.
(FN_QUERY_SEP): Update for VMS.
(FN_QUERY_SEP_STR): Update for VMS.
2015-04-02 15:36:42 +02:00
Hubert Tarasiuk
eae8b1d565 Change semantics of resp_free and request_free in http.c
* src/http.c (resp_free): Change the semantics of this function.
(request_free): Change the semantics of this function.
(initialize_request): Adjust request_free call.
(establish_connection): Adjust request_free, resp_free calls.
(gethttp): Adjust request_free, resp_free calls.
2015-04-01 17:01:07 +02:00
Hubert Tarasiuk
045463b814 Do not free request in establish_connection; do it in gethttp
* src/http.c (establish_connection): Do not free request here (it is
* never allocated here).
* src/http.c (gethttp): Free request before returning if error in
* establish_connection encountered.
2015-04-01 17:01:07 +02:00
Hubert Tarasiuk
621c313b94 Transform read_header label and goto into a loop
* src/http.c (gethttp): Replace label and goto statement with a do
loop.
2015-04-01 17:00:40 +02:00
Hubert Tarasiuk
52a7d0ad85 Factor out set_content_type function from gethttp
* src/http.c (gethttp): Move some code in...
(set_content_type): ... a new function.
2015-03-31 17:00:07 +02:00
Giuseppe Scrivano
59e9ef00e6 Factor out some gethttp code
* src/http.c (gethttp): Move some code in...
(open_output_stream): ... a new function.
2015-03-18 12:09:55 +01:00
Giuseppe Scrivano
14bbc18512 Factor out some auth gethttp code
* src/http.c (gethttp): Move some code in...
(check_auth): ... a new function.
2015-03-18 12:09:55 +01:00
Giuseppe Scrivano
8aa63e482e Factor out some gethttp code
* src/http.c (gethttp): Move some code in...
(check_file_output): ... a new function.
2015-03-18 12:09:55 +01:00
Giuseppe Scrivano
0bc2757713 Factor out some connection initialization code for gethttp
* src/http.c (gethttp): Move some initialization code in...
(establish_connection): ... a new function.
2015-03-18 12:09:55 +01:00
Giuseppe Scrivano
f8abb9dd00 Factor out some proxy initialization code for gethttp
* src/http.c (gethttp): Move some initialization code in...
(initialize_proxy_configuration): ... a new function.
2015-03-18 12:09:55 +01:00
Giuseppe Scrivano
29850e77d0 Factor out some initialization code for gethttp
* src/http.c (gethttp): Move some initialization code in...
(initialize_request): ... a new function.
2015-03-18 12:09:54 +01:00
Tim Ruehsen
799c545722 src/ftp.c: make sure warc_tmp becomes closed before return
Reported-by: Coverity bug #1188044
2015-03-18 10:46:11 +01:00
Tim Ruehsen
014b1d6041 src/http.c: fix error return of digest_authentication_encode()
Reported-by: Coverity bug #1188036
2015-03-18 10:46:05 +01:00
Rohan Prinja
8d4bb928b9 Convert wget.texi to UTF-8
* doc/wget.texi: convert to UTF-8 by adding @documentencoding
* doc/Makefile.am: Pass argument --utf8 to pod2man.
2015-03-17 09:52:23 +01:00
Ander Juaristi Alamos
d0f406a13f * doc/wget.texi: The default is GnuTLS, not OpenSSL. 2015-03-16 22:46:08 +01:00
Darshit Shah
87b52e510c testenv/http_server: Allow overriding Headers
We would like to override existing headers in the response from the
server to allow the test cases to define their own headers. This patch
allows this behaviour through the use of the add_header() method while
also allowing sending multiple headers of the same name.
2015-03-16 23:24:14 +05:30
Darshit Shah
cc9f76c5a4 retr.c: Fix memory leak in retrieve_from_file()
Reported by: Coverity Bug 1188045
2015-03-14 16:48:30 +05:30
Darshit Shah
53b22974cb html-url.c: Fix potential memory leaks
Reported by: Coverity Bug 1188050
2015-03-14 16:48:30 +05:30
Darshit Shah
7d5a7ef9ca main.c: Fix two potential memory leaks
Reported by: Coverity bug 1188048
2015-03-14 16:48:30 +05:30
Darshit Shah
735cc220e3 retr.c: Fix two memory leaks when proxy URL is bad
Reported by: Coverity bug 1188047
2015-03-14 16:48:29 +05:30
Darshit Shah
524f26a200 Docs: --post-file is binary data
Wget considers the file mentioned in the --post-file argument as a
binary file and does not strip any control characters. The lack of this
information in the documentation can cause a lot of headaches debugging
for a simple issue
2015-03-13 23:51:59 +05:30
Giuseppe Scrivano
16f1fb1d1f maint: update copyright year ranges to include 2015 2015-03-09 16:32:01 +01:00
Giuseppe Scrivano
b74ac4c7e0 NEWS: Prepare new development cycle 2015-03-09 16:28:16 +01:00
Yousong Zhou
91e9a20752 Fix --content-on-error option handling.
* src/http.c: Log --content-on-error downloads.
* src/retr.c (retrieve_url): Register the download of an error page
when --content-on-error is specified.
2015-03-09 11:45:01 +01:00
Yousong Zhou
4a214bc9a3 testenv: add test case Test--convert-links--content-on-error.py.
* testenv/Makefile.am: Register the new test.
* testenv/Test--convert-links--content-on-error.py: Add test case for
the combination of --convert-links and --content-on-error.py.
2015-03-09 11:42:11 +01:00
Yousong Zhou
b7b6d7fd89 testenv: fix http_server.py with Response and Authentication.
* testenv/exc/server_error.py: Try writing file content for GET
request even if there is a Response rule present.
* testenv/server/http/http_server.py: Likewise.
2015-03-09 11:41:08 +01:00
Yousong Zhou
3a00b37bc2 testenv: improve color output a bit.
* testenv/misc/colour_terminal.py: Only print color codes when stdout
isatty().
2015-03-09 11:40:44 +01:00
Yousong Zhou
adcc793a26 testenv: typo and style fix.
* testenv/server/http/http_server.py(BaseTest): Add docstring; use raw
string for regex.
* testenv/server/http/http_server.py(_Handler): Typo fix.
* testenv/conf/server_files.py(ServerFiles): Code style change for
readability plus another typo fix.
2015-03-09 11:40:05 +01:00
Giuseppe Scrivano
d94d9cd98b NEWS: tag 1.16.3 2015-03-09 10:01:08 +01:00
Anderson Goulart
882ed28d59 src/main.c (--no-verbose): don't show progress bar
Fixes #44431
2015-03-09 00:44:23 +05:30
Darshit Shah
e316d253fa main.c: Use assertion to test buffer size 2015-03-07 00:38:04 +05:30
Darshit Shah
9dde436dd6 main.c: Need to explicitly disallow show_progress in -q 2015-03-02 21:40:57 +05:30
Giuseppe Scrivano
bf868e8840 NEWS: add other items and tag 1.16.2 2015-02-28 15:40:18 +01:00
Giuseppe Scrivano
5352eac8fa gnulib: sync gnulib 2015-02-28 15:39:44 +01:00
Giuseppe Scrivano
d419cd7c0c NEWS: Update file 2015-02-27 17:36:50 +01:00
Eli Zaretskii
33c5d979ce warc.c: native uuid generation on Windows
* warc.c (windows_uuid_str) [WINDOWS]: New function specific to
MS-Windows.
(warc_uuid_str) [WINDOWS]: If windows_uuid_str succeeds, use its
result; otherwise use the fallback method.
2015-02-23 23:36:02 +01:00
Gisle Vanem
9df2250f4c idn: use idn_free() to free allocated libidn memory
xfree() might crash on libidn memory on Windows.

From 'man idn_free':
"Under Windows, different parts of the same application may use different
 heap memory, and then it is important to deallocate memory allocated within
 the same  module  that  allocated it. This function makes that possible."
2015-02-18 12:50:57 +01:00
Tim Rühsen
3d8e765c1d gettext: Use gnulib's gettext.h for compatibility
Fixes issues with gettext on Solaris
Reported-by: Kiyoshi KANAZAWA <yoi_no_myoujou@yahoo.co.jp>
2015-02-10 09:56:32 +01:00
Tim Rühsen
c83f344564 src/openssl.c: Use SSL_state() instead of ssl_st.state
Changes in OpenSSL 1.0.2 API hides ssl_st structure members.
Reported-by: Gisle Vanem <gvanem@yahoo.no>
2015-02-10 09:53:42 +01:00
Giuseppe Scrivano
07a350d30c * README.checkout: Remove duplicated word 2015-01-31 00:32:06 +01:00
Giuseppe Scrivano
875d0819c4 * cfg.mk (VC_LIST_ALWAYS_EXCLUDE_REGEX): Add ChangeLog-2014-12-10. 2015-01-31 00:30:26 +01:00
Tim Rühsen
b25fbe5afc README.checkout: Mention libio-socket-ssl-perl to be installed 2015-01-27 16:25:11 +01:00
Dagobert Michelsen
4e8e159289 tests/Makefile.am: Solaris needs libintl and libiconv for testsuite 2015-01-22 16:13:26 +01:00
Darshit Shah
8705e27e20 progress bar: Allow display on stderr alongwith -o
This commit causes the --show-progress option to print the progress bar
to stderr even when a logfile was explicitly provided on the command
line. Such a combination allows a user to log the output of Wget while
simultaneously keeping track of the download status.
2015-01-20 20:16:20 +01:00
Darshit Shah
a7e9a05a89 gnulib: Pull submodule forward 2015-01-18 15:40:46 +05:30
Mathieu Parent
87f4fee8c9 src/connect.c: More verbose error message (tiny change)
This fixes Debian bug #144076.
2015-01-16 10:18:13 +01:00
Tim Ruehsen
5e3a760731 src/ftp-basic.c: Accept 5-digit port numbers in EPSV responses
Reported-by: Adam Sampson <ats@offog.org>
2015-01-04 20:57:15 +01:00
Tim Rühsen
01d5177f7a README.checkout: Add libpcre, pkg-config, libgnutls
Add description for libpcre
Add description for pkg-config
Add description of GnuTLS
Add 2014,2015 copyright year
Use ASCII copyright characters
2015-01-02 13:03:44 +01:00
Tim Ruehsen
103cbf1751 src/http.c: Revert commit d81a8d5f56
The removal of the 'redundant' condition was a failure.
Fixes: #43876
Reported-by: Sean Jensen-Grey <seanj@xyke.com>
2014-12-27 23:27:20 +01:00
Tim Ruehsen
6f62bc5cd8 configure.ac: Skip pkg-config for opensl and gnutls when prefix is given
Make --with-libssl-prefix and --with-libgnutls-prefix do the right thing,
no matter if pkg-config is installed or not.

Reported-by: Charles Diza <chdiza@gmail.com>
2014-12-25 15:21:44 +01:00
Tim Ruehsen
f6b28575cc src/main.c, src/warc.c: Use gnulib's base_name() instead of basename()
Reported-by: Eli Zaretskii <eliz@gnu.org>
2014-12-25 12:07:42 +01:00
Giuseppe Scrivano
5de8ab2a0b Generate distributed ChangeLog from git log
* bootstrap.conf (gnulib_modules): Add "gitlog-to-changelog".
* Makefile.am: Generate the ChangeLog file from the git log and
the old ChangeLog data.
2014-12-24 11:04:30 +01:00
Giuseppe Scrivano
a8d437d827 merge ChangeLog files in ChangeLog-2014-12-10.
* ChangeLog: truncate file.
* ChangeLog.README: Likewise.
* doc/ChangeLog: Likewise.
* msdos/ChangeLog: Likewise.
* src/ChangeLog: Likewise.
* testenv/ChangeLog: Likewise.
* tests/ChangeLog: Likewise.
* ChangeLog-2014-12-10: New file.
* Makefile.am: Distribute ChangeLog-2014-12-10.
2014-12-24 11:04:30 +01:00
Eli Zaretskii
fc336758ab src/utils.c: Don't include termios.h on Windows 2014-12-21 19:10:26 +01:00
Tim Ruehsen
9ee2fdd50d tests/FTPServer.pm: Fix ftp tests for Windows
The Single Unix strftime format specifier %e is not supported by
MS Windows. Instead we now use %d.

Reported-By: Eli Zaretskii <eliz@gnu.org>
2014-12-21 18:12:17 +01:00
Tim Rühsen
cfe7589397 gnulib: Use basename() from gnulib module 'dirname'
Avoid basename incompatibilities between POSIX and GNU implementations.
Also, libgen.h isn't needed any more which increases compatibility.
2014-12-21 17:34:14 +01:00
Giuseppe Scrivano
15f18e7606 contrib/check-hard: delete trailing whitespaces and repeated word 2014-12-21 14:14:19 +01:00
Benno Schulenberg
ee196f6fe5 * src/main.c (print_help): Indent description continuation lines by two spaces. 2014-12-21 14:10:40 +01:00
Benno Schulenberg
0417ef8b50 * src/main.c (print_help): Don't use a possessive instead of a plural. 2014-12-21 14:10:35 +01:00
Benno Schulenberg
56c0098063 * src/main.c (print_help): Don't use the backtick as a left quote mark in the help text. 2014-12-21 14:10:31 +01:00
Benno Schulenberg
712d607f9b * src/main.c (print_help): Remove the full stops from option descriptions.
And use semicolons to separate multiple phrases in a description.
2014-12-21 14:10:25 +01:00
Benno Schulenberg
32499e717d * src/main.c (print_help): Make all option descriptions start with a lowercase letter.
Also spell URL consistently in all uppercase, and fix the grammar.
2014-12-21 14:09:51 +01:00
Tim Ruehsen
b147fb1638 doc/wget.texi: Add 'https_only' in 'wgetrc commands' section
Reported-By: Eli Zaretskii <eliz@gnu.org>
2014-12-20 17:42:00 +01:00
Eli Zaretskii
365aeba704 tests/WgetTests.pm: Print timestamps when tests fail due to wrong timestamps 2014-12-20 12:07:42 +01:00
Tim Rühsen
b0893e84b3 sample.wgetrc: Fix wrong command 'locale' into 'localencoding'
Reported-by: Eli Zaretskii <eliz@gnu.org>
2014-12-19 17:05:33 +01:00
Tim Rühsen
f0de37cc27 wget.texi: Clarify wgetrc command syntax
Reported-by: Eli Zaretskii <eliz@gnu.org>
2014-12-19 16:56:35 +01:00
Tim Rühsen
05d73a926a configure.ac: Fix libuuid and uuid_create detection
--with-libuuid now explictly asks for libuuid.
--without-libuuid ignores libuuid and tries to use libc builtin functions.
Else try builtin functions first, libuuid second and fallback to Wget's own
function.
2014-12-18 10:42:26 +01:00
Yuriy M. Kaminskiy
ec5e0f421c src/log.c: Fix unexpected termination in logprintf (tiny change)
When errno was set to EPIPE before call to logprintf (e.g. during close of
SSL connection that was reset by peer), it will unexpectedly terminate wget.
It should exit only when EPIPE was triggered by logging code.

Regression by 0b5b100fc9
2014-12-17 12:50:06 +01:00
Tim Rühsen
0d9615292e configure.ac: Check for RAND_egd() in pkg-config success code 2014-12-17 12:39:00 +01:00
Tim Rühsen
6bc2620592 src/main.c: Conditionally print help for --random-file and --egd-file
--random-file is only relevant when compiled with either OpenSSL or LibreSSL.
--egd-file is only relevant when compiled with OpenSSL
2014-12-17 12:39:00 +01:00
Tim Rühsen
b0b1cde6e2 src/init.c: Fix indentation for crlfile option 2014-12-17 12:39:00 +01:00
Tim Rühsen
f37dd1aa2d wget.texi: Document --random-file and --egd-file as OpenSSL only 2014-12-17 12:39:00 +01:00
Jérémie Courrèges-Anglas
b5778699f0 openssl: Detect the availability of RAND_egd (tiny change)
Alternatives like LibreSSL don't provide RAND_egd() anymore.
Fixes compilation on OpenBSD.
2014-12-17 11:47:15 +01:00
Jérémie Courrèges-Anglas
b8c567a3ef Fix use of uuid libc functions (tiny change)
* Always attempt to detect uuid.h and uuid_create().
* Split libuuid and uuid.h implementations of warc_uuid_str(), since
  those APIs vary significantly.
* Correctly use the uuid.h functions
2014-12-17 09:24:31 +01:00
Darshit Shah
425368c602 Revert "ChangeLog: Move all ChangeLog files to .pre-gitlog"
This reverts commit fcd3b3c473.

Turns out that removing the ChangeLog files causes the Wget build to
fail. While this issue is investigated and sorted out, the commit is
reversed to allow people to be able to build Wget from master
2014-12-16 23:31:36 +05:30
Tim Rühsen
1ca88a4208 contrib: Added script contrib/check-hard to check Wget status
This script automates some tests, e.g. testing with and without valgrind,
using different configure options. It is aimed at developers to execute
before pushing commits.
2014-12-16 17:10:52 +01:00
Cong Ma
26790c3583 ftp: fix invalid pointer dereference in getftp() (tiny change)
The pointer respline in use after being passed to ftp_response() may be
uninitialized if ftp_response() fails.  Ensure that respline be used
after checking the return value of ftp_response().
2014-12-16 15:51:36 +01:00
Darshit Shah
fcd3b3c473 ChangeLog: Move all ChangeLog files to .pre-gitlog
From v1.16.1 onwards, Wget no longer maintains an active ChangeLog file.
Instead the ChangeLog will be automatically generated on each release
through gnulib's gitlog-to-changelog script. However, the old versions
of the ChangeLog files are retained for reference. These files are
renamed with a .pre-gitlog appended to their filenames.
Also removed ChangeLog.README file which is not required anymore
2014-12-16 00:51:56 +05:30
Tim Rühsen
eb0789d43f src/iri.c: Call xstrndup instead of strndup
strndup() does not exist in some older C libraries, also xstrndup()
exits on memory allocation failures.
2014-12-12 16:15:51 +01:00
Tim Rühsen
ab2d5d83d2 bootstrap.conf: Add module 'getline'
This function does not exist in some older C libraries.
2014-12-12 16:11:31 +01:00
Tim Rühsen
cbaabe78e8 src/iri.c: Use c_strcasestr instead of strcasestr
This also fixes a problem with strcasestr not being in the
boostrap.conf module list.

Reported-by: Kiyoshi KANAZAWA <yoi_no_myoujou@yahoo.co.jp>
2014-12-12 15:45:32 +01:00
Friedrich Haubensak
0a4826f4a1 Add support for older versions of flex (tiny change)
E.g. flex 2.5.4 (Solaris 10) does not like a space after -o.
2014-12-11 15:18:57 +01:00
Tim Rühsen
71425f1bb3 Check for pcre.h in configure.ac 2014-12-10 10:22:39 +01:00
Giuseppe Scrivano
f59dac3023 Tag new release 1.16.1 2014-12-08 11:30:12 +01:00
Giuseppe Scrivano
8b50cd4b61 cfg.mk (local-checks-to-skip): Add sc_cast_of_argument_to_free 2014-12-08 11:30:12 +01:00
Tim Rühsen
a80986a8c9 Fix message in configure.ac for when GnuTLS has not been found 2014-12-05 12:18:30 +01:00
Tim Rühsen
94447e31a6 Replace compatibility functions by gnulib functions 2014-12-05 11:57:28 +01:00
Darshit Shah
e6713474c0 Fix indentation in ftp.c (getftp) 2014-12-04 19:24:04 +05:30
Darshit Shah
aaefe8bc83 Remove illogical assertion in ftp.c
A call to assert(1) will always fail and cause Wget to crash. If such a
situation does arise, Wget should invoke abort() and provide a useful
error message to the user prior to exiting.
2014-12-04 19:24:04 +05:30
Darshit Shah
4b845615fa Define MIN and MAx macros in a single location
MIN and MAx are macros that a developer will universally expect
throughout the source. Yet, they were being defined in multiple places
across the source. Instead, define them in a single location in the
common wget.h header file and use them consistently everywhere.
2014-12-04 18:36:54 +05:30
Gisle Vanem
aeca2c33c0 Fix C89 warning in src/openssl.c 2014-12-03 20:23:54 +01:00
Gisle Vanem
11c6dcb705 Fix compilation error in src/mswindows.c 2014-12-03 15:04:11 +01:00
Jérémie Courrèges-Anglas
ce088c2b9e openssl backend: repair use of TLSv1+ protocols
The use of TLSv1_client_method() means that the protocol used will be
limited to TLSv1.0.  This is not desirable for --secure-protocol values
of "auto" (default) and "pfs".  Fix by using SSLv23_client_method() and
disabling SSLv[23].

Issue reported by Mikolaj Kucharski.
2014-12-03 09:24:20 +05:30
Giuseppe Scrivano
d9ab65abd2 testenv: add test to stress wget 1.16 crash 2014-12-02 08:49:38 +01:00
Tim Rühsen
e4583ab364 Fix issues reported by static code analysis tool 'parfait'
Closes: #41235
Reported-by: Jiri Kukacka
2014-12-01 20:39:44 +01:00
Tim Ruehsen
4850e9c873 Replaced xfree_null() by xfree() and nullify argument after freeing. 2014-12-01 16:15:37 +01:00
Tim Ruehsen
d9325f5db5 Fix length of program_argstring in main.c 2014-11-28 22:40:19 +01:00
Tim Ruehsen
5d3b52d0b8 Remove gettext.h from Makefile.am 2014-11-28 21:39:31 +01:00
Tim Rühsen
e194c1dfd3 Get rid of gettext.h 2014-11-28 11:27:58 +01:00
Darshit Shah
3e609a1192 Replace all occurences of free() with xfree() 2014-11-27 11:11:34 +05:30
Tim Ruehsen
5edc97f3f8 Select most secure challenge from WWW-Authenticate
This patch also adds support for multiple challenges per
WWW-Authenticate header line.
The test Test-auth-both.py now succeeds and thus is taken away
from XFAIL_TESTS (expected to fail tests).
2014-11-26 16:41:56 +01:00
Tim Rühsen
007bee88d8 GnuTLS support for --secure-protocol=TLSv1_1|TLSv1_2
The code seemed to be forgotten.
Also added a message before aborting Wget in such a case.
2014-11-26 12:49:21 +01:00
Tim Rühsen
d87fdecd55 Add space after function names 2014-11-26 12:39:47 +01:00
Tim Rühsen
f0e7326c20 Perl test suite: Substitue server port in HTTP headers 2014-11-26 12:25:40 +01:00
Tim Rühsen
54227091b8 Fix blacklisting of URLs to download
Fixes a reported crash and prevents multiple downloads of the
same file in case the URL is escaped in different ways.

Reported-by: Frédéric <vfrederix@gmail.com>
2014-11-26 11:19:41 +01:00
Pär Karlsson
1853e425f5 Added missing version.h to Makefile.am 2014-11-26 09:27:47 +01:00
Darshit Shah
fe0bfb5ee9 Check for flex when compiling from repository sources 2014-11-25 14:22:40 +05:30
Tim Rühsen
255133326b Fix possibly uninitialized variable 2014-11-24 12:00:21 +01:00
Tim Rühsen
0c18773308 Add size of buffer to warc_timestamp() 2014-11-24 10:41:08 +01:00
Tim Rühsen
9217b864d8 Make program_name and program_argstring const 2014-11-24 10:20:51 +01:00
Tim Rühsen
5e2ecaf277 Fix C89 compile errors using ./configure --without-libuuid 2014-11-24 09:44:48 +01:00
Darshit Shah
cd23c7fe0e Supplement logical assumption assert with error message 2014-11-22 21:27:55 +05:30
Darshit Shah
ed996fe32f Remove defensive assert in cookies.c 2014-11-22 21:25:38 +05:30
Darshit Shah
1b8e54b808 Add extern declaration for program_arsgstring
In test.c, this patch changes the type of program_argstring to char *
from a const char *. This is because, we use a char * string in the rest
of the program and declare an extern accordingly. Removing the const
type helps in keeping the code cleaner at no extra cost.
2014-11-22 17:26:06 +05:30
Darshit Shah
eab0f5d222 Make extern declaration for program_name 2014-11-22 17:26:06 +05:30
Darshit Shah
e94a542d0f Declare extern numurls in common header 2014-11-22 17:26:06 +05:30
Darshit Shah
b6de436547 Fix missing extern declaration error for build_info.pl 2014-11-22 17:26:06 +05:30
Darshit Shah
c6b750061a Add extern declaration for version.c strings 2014-11-22 17:26:06 +05:30
Darshit Shah
b41a3a6568 Mark unused paramter in utils.c 2014-11-22 17:26:05 +05:30
Tim Rühsen
f687547d6e Fixed typo in testenv/server/http/http_server.py 2014-11-21 16:19:23 +01:00
Darshit Shah
841efb0108 Assertions are now disabled by default 2014-11-21 17:45:19 +05:30
Daniel Stenberg
09d47ead18 Fix compiler warning in src/iri.c 2014-11-21 10:43:14 +01:00
Darshit Shah
00203b2888 Revert "remote_to_utf8: cut off part of condition always false"
This reverts commit 1553c70961.

Some architectures like arm64 and ppc64 have unsigned chars where this
commit will cause problems.
2014-11-21 14:19:48 +05:30
Daniel Stenberg
1553c70961 remote_to_utf8: cut off part of condition always false
A signed char is never larger than 127.
2014-11-21 13:59:04 +05:30
Tim Ruehsen
bc75d2ecdf Fix code for undefined USE_NLS_PROGRESS_BAR in progress.c
Reported-by: Gisle Vanem
2014-11-20 21:48:04 +01:00
Gisle Vanem
e15ef0b4da Assume large-file support for WINDOWS 2014-11-20 21:37:24 +01:00
Tim Ruehsen
b19d8032c2 Fix libpsl<0.6.0 detection in configure.ac 2014-11-20 21:08:21 +01:00
Tim Rühsen
3c51ad7f02 Removed form feeds from sources and NEWS 2014-11-20 16:35:34 +01:00
Gisle Vanem
6a9b2d36e1 Fix C89 issue in http.c found by MSVC 16 2014-11-20 16:20:20 +01:00
Darshit Shah
40f3613b67 Add po/stamp-po to gitignore 2014-11-20 18:57:37 +05:30
Darshit Shah
acc76b1e02 Use pkg-config for libpsl checking 2014-11-20 16:57:45 +05:30
Darshit Shah
e4be5e3b9a Autotoolize configure.ac 2014-11-20 16:49:28 +05:30
Darshit Shah
bfbc2866c5 Add the -Wextra flag by default
After the Spring Cleaning on warnings in early 2014, GCC and Clang emit
only about two warnings when compiling Wget with -Wall -Wextra.

Enable both these flags by default so that new warnings in these areas
are more prominent.
2014-11-20 16:45:34 +05:30
Darshit Shah
d9f21b4b95 Aesthetic changes to progress bar 2014-11-20 16:43:47 +05:30
Tim Rühsen
7b43510fe3 Fixes possible issues with Wget running in a turkish locale 2014-11-20 10:56:21 +01:00
Tim Rühsen
1356e90a14 Trivial fixes for C89 compliancy 2014-11-20 09:56:57 +01:00
Darshit Shah
f9646a0c14 Fix potential memory leak in main.c 2014-11-19 23:39:22 +05:30
Darshit Shah
1ce1a40f94 Fix memory leak in utils.c 2014-11-19 21:55:30 +05:30
Tim Rühsen
7a7a241e5b Use random() and srandom() if available.
Reported-by: Coverity scanner
2014-11-19 16:06:19 +01:00
Tim Rühsen
18fe274e1c Fix loop check in FTP code
Reported-by: Coverity scanner
2014-11-19 16:05:55 +01:00
Darshit Shah
c6ee033425 Make 504 Gateway Timeout non fatal 2014-11-19 18:03:17 +05:30
Tim Rühsen
0c1bff841b Fix memory leak in OpenSSL code 2014-11-19 12:09:04 +01:00
Tim Rühsen
f518d6cea1 Report load failure of cert files only with --debug
Fixes #41331
2014-11-19 11:26:20 +01:00
Tim Ruehsen
50ec4d9c3d Fix warnings from clang-analyzer 3.6 2014-11-18 20:44:56 +01:00
Tim Rühsen
94b8458af1 Fix possible authentication problem with turkish locale
The test server now treats authentication schemes case-independent.
2014-11-18 12:49:52 +01:00
Tim Rühsen
db621341a4 Code cleanup for redirect_output_signal()
Also fixes a compiler warning for 'make check'.
2014-11-17 11:46:57 +01:00
Tim Rühsen
2ece0cc425 Remove 'make check'compiler warnings 2014-11-17 11:28:20 +01:00
Darshit Shah
0ae74cde39 Remove autogenerated file from sources
po/stamp-po is automatically generated / downloaded upon running make
and hence should not be a part of the checked out sources
2014-11-16 15:15:47 +05:30
Darshit Shah
2bac75dbc5 Update bootstrap script 2014-11-16 15:00:24 +05:30
Darshit Shah
6ab8659ff5 gnulib: Pull submodule forward 2014-11-16 14:56:24 +05:30
Darshit Shah
bd8893a76c Fix mangled gitignore file 2014-11-16 12:30:57 +05:30
Tom Li
6c989c7131 Scroll to last character of filename in progress 2014-11-16 12:03:10 +05:30
Darshit Shah
425584b61e Fix make syntax-check. 2014-11-15 13:39:36 +05:30
Darshit Shah
ff6fc1f8dd Add a configure option to disable assertions
Adds a --disable-assert configure option. We **highly recommend** the
use of this option by distro maintainers so as to ensure a smooth
experience with Wget. Sometimes an assertion may fail even though Wget
continues to work perfectly. In such scenarios, we do not wish for
client installations of Wget to crash. Hence, for a stable experience,
please use the --disable-assert configure flag.
2014-11-15 13:39:25 +05:30
Darshit Shah
94805ad55a Fix progress bar assertion 2014-11-15 00:13:13 +05:30
Tim Rühsen
897ef07712 Fix error handling for CRL loading in OpenSSL code 2014-11-12 15:38:21 +01:00
Witchakorn Kamolpornwijit
6e259b76b7 Fix range check in map_html_tags() 2014-11-12 15:22:15 +01:00
Tim Rühsen
cf4991d602 Added OpenSSL support for --crl-file 2014-11-12 10:00:51 +01:00
Tim Rühsen
176c2b17fc Add 'Accept-Encoding: identity' to request header
Fixes bug #40819
Reported-by: Noël Köthe <noel@debian.org>
2014-11-11 20:05:21 +01:00
Tim Rühsen
9823dc1989 Fix missing _Noreturn declaration specifiers in src/main.c
Reported-by: Gisle Vanem <gvanem@yahoo.no>
2014-11-11 16:34:57 +01:00
Tim Rühsen
2457715e7d Fix OpenSSL compile-time check for TLSv1.1 and TLSv1.2
Reported-by: Velemas Vosak <velemas@gmail.com>
2014-11-11 15:09:41 +01:00
Tim Rühsen
a0c30fc72b Added new test Test--https-crl.py to check --crl-file
For this test, a proper CA and server key/cert infrastructure
was needed. E.g. without CN being 127.0.0.1 a matching CRL file
couldn't be generated.
2014-11-11 15:07:20 +01:00
Tim Rühsen
e4a8fe84e2 Added --crl-file to load a Certificate Revocation List (CRL) file
Reported-by: Noël Köthe <noel@debian.org>
2014-11-11 15:06:51 +01:00
Darshit Shah
170a469533 Honour Keep-Alive when range not satisfiable 2014-11-09 14:33:13 +05:30
Darshit Shah
d81a8d5f56 Remove redundant condition eval 2014-11-09 14:20:22 +05:30
Tim Ruehsen
831b9d1880 Skip python tests if python3 is not available
Reported-by: kdevel@vogtner.de
2014-11-06 11:07:33 +01:00
Tim Ruehsen
7259c30929 Fix segmentation fault on do_conversion() failure
Having an unknown local encoding made Wget crash.
We also fix a wrong 'Conversion from ...' message and
changed two logging messages into debug messages.

Reported-by: Mikael Magnusson <mikachu@gmail.com>
2014-11-05 21:57:18 +01:00
Tim Rühsen
b6d8e1e707 Added $(LIB_CLOCK_GETTIME) to unit test linkage
On systems with separate librt we need this to successfully
link the unit test program.

Reported-by: kdevel@vogtner.de
2014-11-05 16:42:21 +01:00
Tim Rühsen
43e5f022e2 Fix skip exit code to 77 in tests/Test-stdouterr.px 2014-11-05 12:10:57 +01:00
Giuseppe Scrivano
51415ad5d6 Remove empty new-line 2014-11-05 09:19:21 +01:00
Matthew Atkinson
e0f149d29d Always send Content-Length with POST, PUT, PATCH 2014-11-05 08:42:51 +01:00
Darshit Shah
375b671f01 Fix name of bootstrap script in documentation 2014-11-04 16:21:09 +05:30
Jakub Čajka
981c7456ff * iri.c (remote_to_utf8): Fixed assumption that char is signed.
Fixes fellowing test case failures idn-cmd-utf8, idn-robots-utf8,
if char is unsigned.
2014-11-03 15:43:55 +01:00
Pär Karlsson
5e71d5aea1 * WgetFeature.pm: Fixed finding of WgetFeature.cfg when using separate
build dirs.
 * WgetFeature.pm: Fixed warning from BLOCK eval, made it indo EXPR eval

This fixes 'make distcheck' and removes a warning.
2014-11-03 14:23:29 +01:00
Tim Rühsen
c6300a3ac7 * added new test Test-proxied-https-auth-keepalive.px
This test similar to Test-proxied-https-auth except that his test
 simulates a persistent connection to the destination server.
2014-11-03 11:37:02 +01:00
Tim Rühsen
2303793a62 * Test-proxied-https-auth.px:
add valgrind support,
   sync parent / child (client / server)

Fixed the missing synchronization between server and client.
Without this, we experienced random test failures.
Also added valgrind support.
2014-11-03 11:33:53 +01:00
Tim Rühsen
e52879514f * src/log.c: turn on automatic format check for log_vprintf_internal() 2014-11-03 09:22:47 +01:00
Darshit Shah
fdd8b8c997 Fix libpsl configure code 2014-11-01 23:49:55 +05:30
Darshit Shah
35bfcb34b0 Remove extra padding from the progress bar 2014-11-01 23:38:07 +05:30
Pär Karlsson
8078adee7f Stylistic and idiomatic cleanups in Perl tests 2014-11-01 22:37:57 +05:30
Giuseppe Scrivano
9f83e0e13c NEWS: add pkg-config support 2014-11-01 17:31:40 +01:00
Mike Frysinger
f48be4e0c6 use pkg-config to check gnutls deps if available
Newer versions of these packages ship with pkg-config files, so if we can
detect it via those, do so.  If that fails, fall back to the old methods.
2014-11-01 17:09:24 +01:00
Mike Frysinger
5ae5d2eaeb use pkg-config to check openssl deps if available
Newer versions of these packages ship with pkg-config files, so if we can
detect it via those, do so.  If that fails, fall back to the old methods.
2014-11-01 17:09:10 +01:00
Mike Frysinger
47d0d4c331 use pkg-config to check pcre deps if available
Newer versions of these packages ship with pkg-config files, so if we can
detect it via those, do so.  If that fails, fall back to the old methods.

Also add a configure flag to explicitly control its usage.
2014-11-01 17:08:52 +01:00
Mike Frysinger
d272339fda use pkg-config to check libuuid deps if available
Newer versions of these packages ship with pkg-config files, so if we can
detect it via those, do so.  If that fails, fall back to the old methods.

Also add a configure flag to explicitly control its usage.
2014-11-01 17:07:08 +01:00
Mike Frysinger
297d040ce1 use pkg-config to check zlib deps if available
Newer versions of these packages ship with pkg-config files, so if we can
detect it via those, do so.  If that fails, fall back to the old methods.
2014-11-01 17:06:33 +01:00
Giuseppe Scrivano
ea97693b54 http: Always check for "Connection: close" presence 2014-11-01 13:22:07 +01:00
Tim Rühsen
fb8f81040a make _get_rfc2253_formatted static 2014-10-31 09:25:21 +01:00
Tim Rühsen
4ea40809cb fix implicit decl warning 2014-10-30 15:44:04 +01:00
Tim Rühsen
64a3d521de fix skip exit code 77 2014-10-30 15:41:07 +01:00
Tim Rühsen
c2bb6bc875 fix memory leak 2014-10-30 11:05:07 +01:00
Tim Rühsen
a5c6ae8f28 use CLOSE_INVALIDATE instead of fd_close 2014-10-30 11:05:07 +01:00
Tim Rühsen
42333c4a5e always set fd invalid after close 2014-10-30 11:05:07 +01:00
Tim Rühsen
a6c2ba73d9 fix memory leak in openssl.c 2014-10-30 11:04:52 +01:00
Giuseppe Scrivano
9dd6ea7481 NEWS: Update copyright years 2014-10-30 10:40:52 +01:00
Peter Meiser
c81e3df2bc Add guard for OpenSSL without SSLv3 2014-10-29 19:27:11 +01:00
Tim Rühsen
148065bc00 content for commit 6092205538 2014-10-29 16:18:01 +01:00
Tim Ruehsen
4152e98bb0 content for commit 605d9053e5 2014-10-28 20:21:33 +01:00
Ángel González
3e2c95b0dd Add wrapper for using wget with a socks proxy. 2014-10-28 17:14:22 +01:00
Tim Ruehsen
605d9053e5 added strlcpy(), concat_strings() rewritten
Signed-off-by: Tim Ruehsen <tim.ruehsen@gmx.de>
2014-10-28 17:05:44 +01:00
Tim Rühsen
6092205538 fixing several memory leaks 2014-10-28 16:56:34 +01:00
Tim Rühsen
9c34d4ed09 add ./configure valgrind support to test suites 2014-10-28 12:32:12 +01:00
Tim Rühsen
3eff3ad69a synchronize client and server in Test-proxied-https-auth.px 2014-10-28 11:40:34 +01:00
Giuseppe Scrivano
56a02c1a44 syntax-check: skip sc_makefile_at_at_check 2014-10-28 10:45:38 +01:00
Giuseppe Scrivano
e5cb0f77e6 Revert "Replace @VAR@ in Makefile.am files with $VAR"
This reverts commit d1ab00cab4.

Conflicts:
	tests/Makefile.am
2014-10-28 10:42:50 +01:00
Giuseppe Scrivano
3697fd9451 Prepare new development cycle 2014-10-27 11:09:39 +01:00
Giuseppe Scrivano
b4440d96cf Prepare new release 1.16 2014-10-27 09:56:47 +01:00
Darshit Shah
69c45cba43 Add checks for valid listing file in FTP
When Wget retrieves a file through FTP, it first downloads a .listing
file and parses it for information about the files and other metadata.
Some servers may serve invalid .listing files. This patch checks for one
such known inconsistency wherein multiple lines in a listing file have
the same name. Such a filesystem is clearly not possible and hence we
eliminate duplicate entries here.

Signed-off-by: Darshit Shah <darnir@gmail.com>
2014-10-27 09:18:13 +01:00
Darshit Shah
18b0979357 CVE-2014-4877: Arbitrary Symlink Access
Wget was susceptible to a symlink attack which could create arbitrary
files, directories or symbolic links and set their permissions when
retrieving a directory recursively through FTP. This commit changes the
default settings in Wget such that Wget no longer creates local symbolic
links, but rather traverses them and retrieves the pointed-to file in
such a retrieval.

The old behaviour can be attained by passing the --retr-symlinks=no
option to the Wget invokation command.
2014-10-27 09:18:13 +01:00
Giuseppe Scrivano
c986ea790c Fix ChangeLog entry 2014-10-27 09:14:56 +01:00
Tim Ruehsen
3e3073ca7b add TLSv1_1 and TLSv1_2 to --secure-protocol 2014-10-23 21:16:37 +02:00
Darshit Shah
796da8da3a Minor optimizations of Python tests 2014-10-23 20:39:25 +02:00
Darshit Shah
7cd528a4e9 Fix make distcheck for Python tests 2014-10-23 19:02:11 +02:00
Ángel González
601b282cd8 css-url.c (get_uri_string): Fix regression from 8e6de1fb5
Solves the issue discovered by Gabriel Somlo and reported in the ml thread
"Regression in git master branch (commit 8e6de1fb5f)"
2014-10-22 20:26:28 +02:00
Tim Rühsen
bc347cc36f fixed IRI misbehaviour(s) 2014-10-20 08:53:12 +02:00
Tim Ruehsen
6fc11e46ec do not use SSLv3 except explicitely requested 2014-10-19 21:57:06 +02:00
Tim Rühsen
ff876a3710 use test filename as default test name 2014-10-02 15:01:19 +02:00
Tim Rühsen
21fc7546ef remove run-px from tests/makefile.am 2014-10-02 10:08:31 +02:00
Tim Rühsen
afbcaaecba fixed test suite race conditions due to double usage of names 2014-10-01 21:40:19 +02:00
Tim Rühsen
b64fa2eb84 Switched to parallel test harness 2014-10-01 14:41:32 +05:30
Tim Rühsen
8c2d9afd08 fixed memleak in retrieve_url() 2014-09-30 20:50:06 +05:30
Tim Rühsen
b36c3e48c4 track origins when testing with valgrind 2014-09-30 20:38:51 +05:30
Darshit Shah
efe090df89 Handle multibyte characters in progressbar
This commit fixes a bug in the progressbar implementation wherein
filenames with multibyte characters were not handled correctly.
2014-09-14 16:17:00 +05:30
318 changed files with 42232 additions and 28574 deletions

6
.gitignore vendored
View File

@@ -2,6 +2,7 @@
/.sc-start-sc_bindtextdomain
/.sc-start-sc_prohibit_HAVE_MBRTOWC
/.version
/ABOUT-NLS
/GNUmakefile
/INSTALL
/Makefile
@@ -19,10 +20,13 @@
po/*.gmo*
po/*.po*
src/*.o
tests/*.log
tests/*.trs
testenv/*.log
testenv/*.trs
# build-aux/
build-aux/.gitignore
build-aux/ar-lib
build-aux/compile
build-aux/config.guess
build-aux/config.sub
@@ -54,6 +58,7 @@ po/Makefile.in
po/Makevars
po/POTFILES
po/wget.pot
po/stamp-po
# src/
src/.deps/
src/Makefile
@@ -81,7 +86,6 @@ testenv/Makefile.in
# tests/
tests/Makefile
tests/Makefile.in
tests/WgetTest.pm
tests/unit-tests
# util/
util/Makefile

50
.travis.yml Normal file
View File

@@ -0,0 +1,50 @@
sudo: no
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

1067
ABOUT-NLS

File diff suppressed because it is too large Load Diff

3147
ChangeLog

File diff suppressed because it is too large Load Diff

21536
ChangeLog-2014-12-10 Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +0,0 @@
Please note that Wget has more than one ChangeLog file:
./ChangeLog: documents changes to files in the top-level directory
and to files in subdirectories like po/ that don't have
their own ChangeLogs
src/ChangeLog: documents only changes to files in the src directory
doc/ChangeLog: documents only changes to files in the doc directory
windows/ChangeLog: documents only changes to files in the windows directory
msdos/ChangeLog: documents only changes to files in the msdos directory
When checking to see if a patch you sent in has been applied, please
look in the appropriate ChangeLog(s).

View File

@@ -23,15 +23,6 @@ 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'.
Obsolete Lists
--------------

View File

@@ -27,7 +27,7 @@
# as that of the covered work.
#
# Version: $(VERSION)
# Version: @VERSION@
#
@@ -43,8 +43,8 @@ ACLOCAL_AMFLAGS = -I m4
# subdirectories in the distribution
SUBDIRS = lib src doc po tests util testenv
EXTRA_DIST = ChangeLog.README MAILING-LIST \
msdos/ChangeLog msdos/config.h msdos/Makefile.DJ \
EXTRA_DIST = MAILING-LIST \
msdos/config.h msdos/Makefile.DJ \
msdos/Makefile.WC ABOUT-NLS \
build-aux/build_info.pl build-aux/git-version-gen .version
@@ -60,5 +60,23 @@ clean-generic:
# Arrange so that .tarball-version appears only in the distribution
# tarball, and never in a checked-out repository.
dist-hook:
dist-hook: gen-ChangeLog
$(AM_V_GEN)echo $(VERSION) > $(distdir)/.tarball-version
gen_start_date = 2014-12-10
.PHONY: gen-ChangeLog
gen-ChangeLog:
$(AM_V_GEN)if test -d .git; then \
log_fix="$(srcdir)/build-aux/git-log-fix"; \
test -e "$$log_fix" \
|| amend_git_log=; \
$(top_srcdir)/build-aux/gitlog-to-changelog \
$$amend_git_log --since=$(gen_start_date) > $(distdir)/cl-t && \
echo >> $(distdir)/cl-t && \
cat ChangeLog-2014-12-10 >> $(distdir)/cl-t && \
{ rm -f $(distdir)/ChangeLog && \
mv $(distdir)/cl-t $(distdir)/ChangeLog; } \
fi
check-valgrind:
TESTS_ENVIRONMENT="VALGRIND_TESTS=1" $(MAKE) check

233
NEWS
View File

@@ -1,25 +1,174 @@
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 Free Software Foundation, Inc.
Copyright (C) 1997-2017 Free Software Foundation, Inc.
See the end for copying conditions.
Please send GNU Wget bug reports to <bug-wget@gnu.org>.
* Changes in Wget X.Y.Z
** Use libpsl for verifying cookie domains
* Changes in Wget 1.19
** Default progress bar output changed
* New option --use-askpass=COMMAND. Fetch user/password by calling
an external program.
** Introduce --show-progress to force display the progress bar
* Use IDNA2008 (+ TR46 if available) through libidn2
** Introduce --no-config.
* 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.
** Add support for --if-modified-since.
** Add support for metalink through --input-metalink and --metalink-over-http.
** Add support for HSTS through --hsts and --hsts-file.
** Add option to restrict filenames under VMS.
** Add support for --rejected-log which logs to a separate file the reasons why
URLs are being rejected and some context around it.
** Add support for FTPS.
** Do not download/save file on error when --spider enabled
** Add --convert-file-only option. This option converts only the
filename part of the URLs, leaving the rest of the URLs untouched.
* Changes in Wget 1.16.3
** Fix a regression introduced by wget 1.16.2 that --quiet is not
really quiet anymore.
* Changes in Wget 1.16.2
** Native uuid generation on Windows
** Fix build on Solaris
** Allow progress bar on stderr when -o is used
** Accept 5-digit port numbers in FTP EPSV responses.
** Support older versions of flex.
** Updated translations.
* Changes in Wget 1.16.1
** Add --enable-assert configure option.
** Use pkg-config to check for libraries presence.
** Do not limit --secure-protocol=auto|pfs to TLSv1.0.
** Add --secure-protocol=TLSv1_1|TLSv1_2 .
** Full C89 source code compliance.
** Select and use the most secure authentication scheme with HTTP connections.
** Fix issues with turkish locales.
** Handle 504 Gateway Timeout.
** New option --crl-file to load Certificate Revocation Lists.
** Add valgrind support to tests suite.
** Fix an off-by-one problem in the progress bar (introduced in 1.16).
* Changes in Wget 1.16
** No longer create local symbolic links by default. Closes CVE-2014-4877.
** Use libpsl for verifying cookie domains.
** Default progress bar output changed.
** Introduce --show-progress to force display the progress bar.
** Introduce --no-config. The wgetrc files will not be read.
** Introduce --start-pos to allow starting downloads from a specified position.
** Fix a problem with ISA Server Proxy and keep-alive connections.
* Changes in Wget 1.15
** Add support for --method.
@@ -51,7 +200,7 @@ Please send GNU Wget bug reports to <bug-wget@gnu.org>.
** Specify Host with the HTTP CONNECT method.
** Use the correct HTTP method on a redirection.
* Changes in Wget 1.14
** Add support for content-on-error. It allows to store the HTTP
@@ -73,12 +222,12 @@ Please send GNU Wget bug reports to <bug-wget@gnu.org>.
** Add support for TLS Server Name Indication.
** Accept the arguments --accept-reject and --reject-regex.
** Accept the arguments --accept-regex and --reject-regex.
** The GNU TLS backend honors correctly the timeout value.
** Add support for RFC 2617 Digest Access Authentication.
* Changes in Wget 1.13.4
** Now --version and --help work again.
@@ -91,7 +240,7 @@ Please send GNU Wget bug reports to <bug-wget@gnu.org>.
is specified.
** Fix a segfault on an incomplete STYLE tag.
* Changes in Wget 1.13.3
** Support HTTP/1.1
@@ -157,7 +306,7 @@ Please send GNU Wget bug reports to <bug-wget@gnu.org>.
** Introduce `show_all_dns_entries' to print all IP addresses corresponding to
a DNS name when it is resolved.
* Changes in Wget 1.12
** Mailing list MOVED to bug-wget@gnu.org
@@ -211,7 +360,7 @@ forces the percent-encoding of all non-ASCII bytes
now documented: save_headers, spider, and user_agent,
auth_no_challenge, and keep_session_cookies. Also added documentation
for the "lowercase" and "uppercase" values for --restrict-file-names, which had been present since Wget 1.11.
* Changes in Wget 1.11.4
** Fixed an issue (apparently a regression) where -O would refuse to
@@ -225,13 +374,13 @@ locally with content.
to a pointer-to-time_t.
** Translation updates for Catalan.
* Changes in Wget 1.11.3
** Downgraded -N with -O to a warning, rather than an error.
** Translation updates
* Changes in Wget 1.11.2
** Fixed a problem in authenticating over HTTPS through a proxy.
@@ -253,7 +402,7 @@ multiple times. This has been fixed in 1.11.2.
for improved conformance with RFC 3986. However, this behavior presents
problems for some FTP setups, and so they are now preserved again, for
FTP URLs only.
* Changes in Wget 1.11.1.
** Interrupted downloads no longer result in renaming the file
@@ -275,7 +424,7 @@ be surprising, and notes that they may change in the future.
** Documentation of --no-parents now explains how a trailing slash, or
lack thereof, in the specified URL, will affect behavior.
* Changes in Wget 1.11.
** Timestamping now uses the value from the most recent HTTP response,
@@ -321,7 +470,7 @@ available at http://hg.addictivecode.org/. Prior to this, the source
code was hosted on Subversion (migrated from the original CVS); you can
still get access to older tags and branches for Wget in the Subversion
repository at http://addictivecode.org/svn/wget/.
* Changes in Wget 1.10.
** Downloading files larger than 2GB, sometimes referred to as "large
@@ -432,9 +581,9 @@ http_password and proxy_password respectively. The login and passwd
.wgetrc commands have been deprecated.
* `wget -b' now works correctly under Windows.
* Wget 1.9.1 is a bugfix release with no user-visible changes.
* Changes in Wget 1.9.
** It is now possible to specify that POST method be used for HTTP
@@ -486,11 +635,11 @@ values "yes" and "no" along with the traditional "on" and "off".
** It is now possible to specify decimal values for timeouts, waiting
periods, and download rate. For instance, `--wait=0.5' now works as
expected, as does `--dns-timeout=0.5' and even `--limit-rate=2.5k'.
* Wget 1.8.2 is a bugfix release with no user-visible changes.
* Wget 1.8.1 is a bugfix release with no user-visible changes.
* Changes in Wget 1.8.
** A new progress indicator is now available and used by default.
@@ -550,9 +699,9 @@ no longer translated to `?', nor `%2B' to `+'. Unsafe characters
which are not reserved are still escaped, of course.
** No more than 20 successive redirections are allowed.
* Wget 1.7.1 is a bugfix release with no user-visible changes.
* Changes in Wget 1.7.
** SSL (`https') pages now work if you compile Wget with SSL support;
@@ -594,7 +743,7 @@ large sites (thousands of documents).
documentation. (The last version that shipped with a man page was
1.4.5). To get this, you need to have pod2man from the Perl
distribution installed on your system.
* Changes in Wget 1.6
** Administrative changes.
@@ -645,13 +794,13 @@ passive_ftp is the only .wgetrc command which takes a lockable Boolean.
bound to multiple IP addresses.
** wget now accepts (illegal per HTTP spec) relative URLs in HTTP redirects.
* Wget 1.5.3 is a bugfix release with no user-visible changes.
* Wget 1.5.2 is a bugfix release with no user-visible changes.
* Wget 1.5.1 is a bugfix release with no user-visible changes.
* Changes in Wget 1.5.0
** Wget speaks many languages!
@@ -697,11 +846,11 @@ download.
** The manual page, now hopelessly out of date, is no longer
distributed with Wget.
* Wget 1.4.5 is a bugfix release with no user-visible changes.
* Wget 1.4.4 is a bugfix release with no user-visible changes.
* Changes in Wget 1.4.3
** Wget is now a GNU utility.
@@ -717,7 +866,7 @@ distributed with Wget.
** Global wgetrc now goes to /usr/local/etc (i.e. $sysconfdir).
** Lots of bugfixes.
* Changes in Wget 1.4.2
** New mirror site at ftp://sunsite.auc.dk/pub/infosystems/wget/,
@@ -735,7 +884,7 @@ files.
** --convert-links should work now.
** Minor bugfixes.
* Changes in Wget 1.4.1
** Minor bugfixes.
@@ -743,7 +892,7 @@ files.
** Added -I (the opposite of -X).
** Dot tracing is now customizable; try wget --dot-style=binary
* Changes in Wget 1.4.0
** Wget 1.4.0 [formerly known as Geturl] is an extensive rewrite of
@@ -824,7 +973,7 @@ turn on mirroring options).
** Lots of small features I can't remember. :-)
** A host of bugfixes.
* Changes in Geturl 1.3
** Added FTP globbing support (ftp://fly.cc.fer.hr/*)
@@ -842,9 +991,9 @@ turn on mirroring options).
** Added support for robots.txt
** Fixed some minor bugs
* Geturl 1.2 is a bugfix release with no user-visible changes.
* Changes in Geturl 1.1
** REST supported in FTP
@@ -862,7 +1011,7 @@ geturl -vo log http://fly.cc.fer.hr/
** <base href="xxx"> supported
** autoconf supported
----------------------------------------------------------------------
Copyright information:

View File

@@ -4,8 +4,9 @@ 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, libidn, libiconv
and libpsl are not absolutely required):
more of the following (note that gettext, OpenSSL, GnuTLS, libidn2,
libiconv, libpsl, libpcre, pkg-config, libmetalink and GnuPG are not
absolutely required):
* [20]autoconf (currently, GNU Wget requires version 2.61). This is
needed to generate the configure script from configure.in. This is
@@ -23,12 +24,18 @@ Compiling From Repository Sources
* [23]Perl, if you wish to generate the wget(1) manpage, or run the
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. To execute all the tests you need
[24]libwww-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'". Now "make check" should
pass most of the tests in the test suite.
test suite written in perl and python (see below). To execute all the tests
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]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".
* [27]texinfo in order to generate Info, PostScript and/or HTML
documentation. You don't need texinfo in order to generate the
@@ -46,35 +53,61 @@ Compiling From Repository Sources
to export M4=<new m4 path>, to be sure that autoconf/automake use
it instead of the old one.
* [29]OpenSSL to handle encrypted web sessions. You almost certainly
want this. It is not enough to have the library installed; you need
to have the header files available to compile against as well. For
GNU/Linux systems, this usually means installing a "developer"
package for openssl (for example, [30]Debian systems require
installation of the libssl-dev package). Alternatively, you can
compile GNU Wget against the [31]GNUTLS library instead, by
specifying --with-ssl=gnutls to the ./configure script; however,
building against GNUTLS is currently experimental, and not
officially supported. If you have OpenSSL and its development
headers installed, but don't want to build Wget with it, specify
--without-ssl to the ./configure script.
* [29]GnuTLS to allow encrypted data transfer (HTTPS).
You need the header files and the library installed.
As an alternative, you can use [30]OpenSSL by specifying
--with-ssl=openssl to the ./configure script.
If you do not want HTTPS support, specify --without-ssl to the
./configure script.
If you want to compile+link a non-system library version use
--with-libgnutls-prefix (or if having pkg-config: see description
below).
* [32]libidn is required for IDN/IRI support (non-ASCII characters
* [30]OpenSSL to allow encrypted data transfer (HTTPS) an
alternative to [31]GnuTLS.
You need the header files and the library installed.
If you want to compile+link a non-system library version use
--with-libssl-prefix (or if having pkg-config: see description below).
* [31]libidn2 is required for IDN/IRI support (non-ASCII characters
within what would otherwise be URLs).
* [33]libiconv is required on non-GNU systems, for IDN/IRI support.
* [32]libiconv is required on non-GNU systems, for IDN/IRI support.
On GNU systems, the functionality provided by libiconv is already
present in the system libraries.
* [34]git is used to fetch gnulib files trough the bootstrap.sh script.
* [33]git is used to fetch gnulib files trough the bootstrap.sh script.
* [35]libpsl is required for using a public suffix list to check for valid
cookie domains.
* [34]libpsl is required for using a public suffix list to check for valid
cookie domains. You need the header files and the library installed.
* [35]libpcre is required for using Perl-compatible regular expressions
with --accept-regex and --reject-regex. You need the header files and
the library installed to compile and link Wget with PCRE support.
* [36]pkg-config helps the ./configure script to find installed libraries.
Most libraries provide a pkg-config file (.pc extension) with
information about dependencies, header file and library locations.
Distributions deliver their specific .pc file to each library.
If you want to compile+link against your own library version, make a
copy of the appropriate .pc file and amend it to your needs (e.g. edit
the line starting with prefix=). Before you execute the ./configure
script, set (and export) PKG_CONFIG_PATH to the directory where you
saved the .pc file. Example:
$ PKG_CONFIG_PATH="." ./configure
* [46]libmetalink is needed to enable Metalink files support.
* [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.
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
that point, a shell script called bootstrap.sh has been provided. After
calling ./bootstrap.sh you're ready to build GNU Wget in the normal
that point, a shell script called bootstrap has been provided. After
calling ./bootstrap you're ready to build GNU Wget in the normal
fashion, with ./configure and make.
So, to sum up, after checking out the source code as described above,
@@ -83,17 +116,50 @@ 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.sh
$ ./bootstrap
3. Configure the package and compile it:
$ ./configure [some_parameters]
$ ./configure --enable-assert [some_parameters]
$ make
4. Hack, compile, test, hack, compile, test...
$ src/wget --version
GNU Wget 1.12-devel (9cb2563197bc)
Copyright © 2008,2010 Free Software Foundation, Inc.
Testing and development
All developers are requested to enable the assertions on their development
builds to ensure a stable codebase. Assertions are added to state certain
assumptions about the code and its data which all developers should be mindful
of. To enable assertions, run the configure command with the --enable-assert
option, like this:
$ ./configure --enable-assert [other configure options]
Both the Perl and Python test suites (test/ and testenv/) include support for GDB and Valgrind.
The environment variables GDB_TESTS and VALGRIND_TESTS are available to
enable such wrappers. If specified, Wget would be run through either of them
during the test. For example:
$ cd testenv
$ VALGRIND_TESTS=1 ./Test-O.py
That would execute Test-O.py test case, but running Wget through Valgrind.
GDB has preference over Valgrind. If both variables have been asserted,
Wget would be run through GDB.
If you run a test case through GDB, please bear in mind that it could give
a false negative. This is because some tests that expect Wget to fail
rely on Wget's return code. However, when run through GDB, its return code
will always be zero, causing the test to claim failure. This wrapper for
GDB is, however, very useful to tackle bugs, allowing one to write a test case
for some specific bug and then using GDB to fix it more easily. Otherwise,
a dedicated server would have to be set up and write a custom CGI just to reproduce
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.
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.
@@ -112,33 +178,37 @@ Compiling From Repository Sources
* [43]Valid HTML 4.01
__________________________________________________________________
All content © 2007 Free Software Foundation. For terms of use,
redistribution, and modification, please see the [44]WikiLicense page.
All content (C) 2007 Free Software Foundation. For terms of use,
redistribution, and modification, please see the [45]WikiLicense page.
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.openssl.org/
30. http://www.debian.org/
31. http://www.gnu.org/software/gnutls/
32. http://www.gnu.org/software/libidn/
33. http://www.gnu.org/software/libiconv/
34. http://git-scm.com/
35. https://github.com/rockdaboot/libpsl
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
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/

210
bootstrap
View File

@@ -1,10 +1,10 @@
#! /bin/sh
# Print a version string.
scriptversion=2012-07-19.14; # UTC
scriptversion=2016-01-24.06; # UTC
# Bootstrap this package from checked-out sources.
# Copyright (C) 2003-2012 Free Software Foundation, Inc.
# Copyright (C) 2003-2016 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
@@ -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() {
@@ -140,20 +143,21 @@ po_download_command_format2=\
"wget --mirror -nd -q -np -A.po -P '%s' \
http://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)
extract_package_name='
/^AC_INIT(/{
/.*,.*,.*, */{
s///
s/[][]//g
s/)$//
/^AC_INIT(\[*/{
s///
/^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{
s//\1/
s/[],)].*//
p
q
}
s/AC_INIT(\[*//
s/]*,.*//
s/[],)].*//
s/^GNU //
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
s/[^A-Za-z0-9_]/-/g
s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g
p
}
'
@@ -208,12 +212,26 @@ bootstrap_sync=false
# Use git to update gnulib sources
use_git=true
check_exists() {
if test "$1" = "--verbose"; then
($2 --version </dev/null) >/dev/null 2>&1
if test $? -ge 126; then
# If not found, run with diagnostics as one may be
# presented with env variables to set to find the right version
($2 --version </dev/null)
fi
else
($1 --version </dev/null) >/dev/null 2>&1
fi
test $? -lt 126
}
# find_tool ENVVAR NAMES...
# -------------------------
# Search for a required program. Use the value of ENVVAR, if set,
# otherwise find the first of the NAMES that can be run (i.e.,
# supports --version). If found, set ENVVAR to the program name,
# die otherwise.
# otherwise find the first of the NAMES that can be run.
# If found, set ENVVAR to the program name, die otherwise.
#
# FIXME: code duplication, see also gnu-web-doc-update.
find_tool ()
@@ -223,27 +241,21 @@ find_tool ()
find_tool_names=$@
eval "find_tool_res=\$$find_tool_envvar"
if test x"$find_tool_res" = x; then
for i
do
if ($i --version </dev/null) >/dev/null 2>&1; then
find_tool_res=$i
break
for i; do
if check_exists $i; then
find_tool_res=$i
break
fi
done
else
find_tool_error_prefix="\$$find_tool_envvar: "
fi
test x"$find_tool_res" != x \
|| die "one of these is required: $find_tool_names"
($find_tool_res --version </dev/null) >/dev/null 2>&1 \
|| die "${find_tool_error_prefix}cannot run $find_tool_res --version"
if test x"$find_tool_res" = x; then
warn_ "one of these is required: $find_tool_names;"
die "alternatively set $find_tool_envvar to a compatible tool"
fi
eval "$find_tool_envvar=\$find_tool_res"
eval "export $find_tool_envvar"
}
# Find sha1sum, named gsha1sum on MacPorts, and shasum on Mac OS X 10.6.
find_tool SHA1SUM sha1sum gsha1sum shasum
# Override the default configuration, if necessary.
# Make sure that bootstrap.conf is sourced from the current directory
# if we were invoked as "sh bootstrap".
@@ -255,12 +267,12 @@ esac
# Extra files from gnulib, which override files from other sources.
test -z "${gnulib_extra_files}" && \
gnulib_extra_files="
$build_aux/install-sh
$build_aux/mdate-sh
$build_aux/texinfo.tex
$build_aux/depcomp
$build_aux/config.guess
$build_aux/config.sub
build-aux/install-sh
build-aux/mdate-sh
build-aux/texinfo.tex
build-aux/depcomp
build-aux/config.guess
build-aux/config.sub
doc/INSTALL
"
@@ -306,34 +318,34 @@ if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
die "Bootstrapping from a non-checked-out distribution is risky."
fi
# Ensure that lines starting with ! sort last, per gitignore conventions
# for whitelisting exceptions after a more generic blacklist pattern.
sort_patterns() {
sort -u "$@" | sed '/^!/ {
H
d
}
$ {
P
x
s/^\n//
}' | sed '/^$/d'
# Strip blank and comment lines to leave significant entries.
gitignore_entries() {
sed '/^#/d; /^$/d' "$@"
}
# If $STR is not already on a line by itself in $FILE, insert it,
# sorting the new contents of the file and replacing $FILE with the result.
insert_sorted_if_absent() {
# If $STR is not already on a line by itself in $FILE, insert it at the start.
# Entries are inserted at the start of the ignore list to ensure existing
# entries starting with ! are not overridden. Such entries support
# whitelisting exceptions after a more generic blacklist pattern.
insert_if_absent() {
file=$1
str=$2
test -f $file || touch $file
echo "$str" | sort_patterns - $file | cmp -s - $file > /dev/null \
|| { echo "$str" | sort_patterns - $file > $file.bak \
&& mv $file.bak $file; } \
|| die "insert_sorted_if_absent $file $str: failed"
test -r $file || die "Error: failed to read ignore file: $file"
duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
if [ "$duplicate_entries" ] ; then
die "Error: Duplicate entries in $file: " $duplicate_entries
fi
linesold=$(gitignore_entries $file | wc -l)
linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l)
if [ $linesold != $linesnew ] ; then
{ echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
|| die "insert_if_absent $file $str: failed"
fi
}
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
# insert_sorted_if_absent.
# insert_if_absent.
insert_vc_ignore() {
vc_ignore_file="$1"
pattern="$2"
@@ -344,7 +356,7 @@ insert_vc_ignore() {
# .gitignore entry.
pattern=$(echo "$pattern" | sed s,^,/,);;
esac
insert_sorted_if_absent "$vc_ignore_file" "$pattern"
insert_if_absent "$vc_ignore_file" "$pattern"
}
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
@@ -409,7 +421,7 @@ sort_ver() { # sort -V is not generally available
get_version() {
app=$1
$app --version >/dev/null 2>&1 || return 1
$app --version >/dev/null 2>&1 || { $app --version; return 1; }
$app --version 2>&1 |
sed -n '# Move version to start of line.
@@ -447,6 +459,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
@@ -464,12 +477,22 @@ 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
# so we have to rely on $? rather than get_version.
$app --version >/dev/null 2>&1
if [ 126 -le $? ]; then
if ! check_exists --verbose $app; then
warn_ "Error: '$app' not found"
ret=1
fi
@@ -502,6 +525,12 @@ print_versions() {
# can't depend on column -t
}
# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
# Also find the compatible sha1 utility on the BSDs
if test x"$SKIP_PO" = x; then
find_tool SHA1SUM sha1sum gsha1sum shasum sha1
fi
use_libtool=0
# We'd like to use grep -E, to see if any of LT_INIT,
# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
@@ -547,13 +576,21 @@ if ! printf "$buildreq" | check_versions; then
fi
fi
# Warn the user if autom4te appears to be broken; this causes known
# issues with at least gettext 0.18.3.
probe=$(echo 'm4_quote([hi])' | autom4te -l M4sugar -t 'm4_quote:$%' -)
if test "x$probe" != xhi; then
warn_ "WARNING: your autom4te wrapper eats stdin;"
warn_ "if bootstrap fails, consider upgrading your autotools"
fi
echo "$0: Bootstrapping from checked-out $package sources..."
# See if we can use gnulib's git-merge-changelog merge driver.
if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
if $use_git && test -d .git && check_exists git; then
if git config merge.merge-changelog.driver >/dev/null ; then
:
elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
elif check_exists git-merge-changelog; then
echo "$0: initializing git-merge-changelog driver"
git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
@@ -573,17 +610,21 @@ git_modules_config () {
test -f .gitmodules && git config --file .gitmodules "$@"
}
gnulib_path=$(git_modules_config submodule.gnulib.path)
test -z "$gnulib_path" && gnulib_path=gnulib
if $use_git; then
gnulib_path=$(git_modules_config submodule.gnulib.path)
test -z "$gnulib_path" && gnulib_path=gnulib
fi
# Get gnulib files.
# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a
# submodule, for use in the rest of the script.
case ${GNULIB_SRCDIR--} in
-)
# Note that $use_git is necessarily true in this case.
if git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
git submodule init || exit $?
git submodule update || exit $?
git submodule init -- "$gnulib_path" || exit $?
git submodule update -- "$gnulib_path" || exit $?
elif [ ! -d "$gnulib_path" ]; then
echo "$0: getting gnulib files..."
@@ -600,8 +641,8 @@ case ${GNULIB_SRCDIR--} in
GNULIB_SRCDIR=$gnulib_path
;;
*)
# Use GNULIB_SRCDIR as a reference.
if test -d "$GNULIB_SRCDIR"/.git && \
# Use GNULIB_SRCDIR directly or as a reference.
if $use_git && test -d "$GNULIB_SRCDIR"/.git && \
git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
if git submodule -h|grep -- --reference > /dev/null; then
@@ -612,13 +653,14 @@ case ${GNULIB_SRCDIR--} in
# This fallback allows at least git 1.5.5.
if test -f "$gnulib_path"/gnulib-tool; then
# Since file already exists, assume submodule init already complete.
git submodule update || exit $?
git submodule update -- "$gnulib_path" || exit $?
else
# Older git can't clone into an empty directory.
rmdir "$gnulib_path" 2>/dev/null
git clone --reference "$GNULIB_SRCDIR" \
"$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \
&& git submodule init && git submodule update \
&& git submodule init -- "$gnulib_path" \
&& git submodule update -- "$gnulib_path" \
|| exit $?
fi
fi
@@ -627,12 +669,19 @@ case ${GNULIB_SRCDIR--} in
;;
esac
# $GNULIB_SRCDIR now points to the version of gnulib to use, and
# we no longer need to use git or $gnulib_path below here.
if $bootstrap_sync; then
cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
echo "$0: updating bootstrap and restarting..."
case $(sh -c 'echo "$1"' -- a) in
a) ignored=--;;
*) ignored=ignored;;
esac
exec sh -c \
'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
-- "$GNULIB_SRCDIR/build-aux/bootstrap" \
$ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \
"$0" "$@" --no-bootstrap-sync
}
fi
@@ -680,11 +729,10 @@ update_po_files() {
cksum_file="$ref_po_dir/$po.s1"
if ! test -f "$cksum_file" ||
! test -f "$po_dir/$po.po" ||
! $SHA1SUM -c --status "$cksum_file" \
< "$new_po" > /dev/null; then
! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
echo "$me: updated $po_dir/$po.po..."
cp "$new_po" "$po_dir/$po.po" \
&& $SHA1SUM < "$new_po" > "$cksum_file"
&& $SHA1SUM < "$new_po" > "$cksum_file" || return
fi
done
}
@@ -867,7 +915,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 \
@@ -889,20 +938,21 @@ find "$m4_base" "$source_base" \
-depth \( -name '*.m4' -o -name '*.[ch]' \) \
-type l -xtype l -delete > /dev/null 2>&1
# Invoke autoreconf with --force --install to ensure upgrades of tools
# such as ylwrap.
AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS"
# Some systems (RHEL 5) are using ancient autotools, for which the
# --no-recursive option had not been invented. Detect that lack and
# omit the option when it's not supported. FIXME in 2017: remove this
# hack when RHEL 5 autotools are updated, or when they become irrelevant.
no_recursive=
case $($AUTORECONF --help) in
*--no-recursive*) no_recursive=--no-recursive;;
*--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";;
esac
# Tell autoreconf not to invoke autopoint or libtoolize; they were run above.
echo "running: AUTOPOINT=true LIBTOOLIZE=true " \
"$AUTORECONF --verbose --install $no_recursive -I $m4_base $ACLOCAL_FLAGS"
AUTOPOINT=true LIBTOOLIZE=true \
$AUTORECONF --verbose --install $no_recursive -I $m4_base $ACLOCAL_FLAGS \
echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS"
AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \
|| die "autoreconf failed"
# Get some extra files from gnulib, overriding existing files.
@@ -971,6 +1021,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

@@ -31,31 +31,56 @@ announce-gen
base32
bind
c-ctype
c-strcase
c-strcasestr
clock-time
close
connect
dirname
fcntl
flock
fnmatch
fopen
futimens
ftello
getaddrinfo
getline
getopt-gnu
getpass-gnu
getpeername
getsockname
gettext
gitlog-to-changelog
git-version-gen
gnupload
hostent
ioctl
iconv
iconv-h
inet_ntop
intprops
inttypes
langinfo
limits-h
link
listen
maintainer-makefile
mbiter
mbtowc
memrchr
mkdir
mkstemp
mkostemp
nanosleep
crypto/md2
crypto/md4
crypto/md5
crypto/sha1
pipe
crypto/sha256
crypto/sha512
open
pipe-posix
posix_spawn
quote
quotearg
recv
@@ -63,20 +88,37 @@ regex
select
send
setsockopt
signal-h
sigprocmask
sigpipe
snprintf
socket
spawn-pipe
stat
stdbool
strcasestr
stdint
strcase
strerror_r-posix
strpbrk
strptime
strtok_r
strtoll
symlink
sys_types
timegm
tmpdir
unlink
unlocked-io
update-copyright
libunistring-optional
unistr/base
unicase/tolower
utimens
vasprintf
vsnprintf
write
xmemdup0
xstrndup
"
gnulib_extra_files="
@@ -102,4 +144,5 @@ perl 5.5
rsync -
tar -
xz -
flex -
"

View File

@@ -137,3 +137,4 @@ __DATA__
#include "wget.h"
#include <stdio.h>
#include "version.h"

5
cfg.mk
View File

@@ -19,10 +19,11 @@ local-checks-to-skip = \
sc_prohibit_S_IS_definition \
\
sc_program_name \
sc_makefile_at_at_check \
sc_cast_of_argument_to_free \
#SHELL=bash -x
show-vc-list-except:
@$(VC_LIST_EXCEPT)
VC_LIST_ALWAYS_EXCLUDE_REGEX = ^ABOUT-NLS|((msdos|vms)/.*)$$
VC_LIST_ALWAYS_EXCLUDE_REGEX = ^ABOUT-NLS|((msdos|vms)/.*)|ChangeLog-2014-12-10|/.*.der$$

View File

@@ -57,48 +57,108 @@ 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 features.
dnl Process External Libraries
dnl
ENABLE_PSL=no
AC_ARG_WITH(libpsl,
AS_HELP_STRING([--without-libpsl],
[disable support for libpsl cookie checking.]),
[],
[AC_SEARCH_LIBS(psl_builtin, psl,
[ENABLE_PSL=yes; AC_DEFINE([HAVE_LIBPSL], [1], [PSL Support Enabled])],
[AC_MSG_WARN(*** libpsl not found. Falling back to Wget builtin cookie checking.)])
])
dnl Libpsl: Public Suffix List checking
AC_ARG_WITH([libpsl],
[AS_HELP_STRING([--without-libpsl], [disable support for libpsl cookie checking.])])
AC_ARG_WITH(ssl,
[[ --without-ssl disable SSL autodetection
--with-ssl={gnutls,openssl} specify the SSL backend. GNU TLS is the default.]])
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.])])
AC_ARG_WITH(zlib,
[[ --without-zlib disable zlib ]])
dnl Zlib: Configure use of zlib for compression
AC_ARG_WITH([zlib],
[AS_HELP_STRING([--without-zlib], [disable zlib.])])
AC_ARG_ENABLE(opie,
[ --disable-opie disable support for opie or s/key FTP login],
ENABLE_OPIE=$enableval, ENABLE_OPIE=yes)
test x"${ENABLE_OPIE}" = xyes && AC_DEFINE([ENABLE_OPIE], 1,
[Define if you want the Opie support for FTP compiled in.])
dnl Metalink: Configure use of the Metalink library
AC_ARG_WITH([metalink],
[AS_HELP_STRING([--with-metalink], [enable support for metalinks.])])
AC_ARG_ENABLE(digest,
[ --disable-digest disable support for HTTP digest authorization],
ENABLE_DIGEST=$enableval, ENABLE_DIGEST=yes)
test x"${ENABLE_DIGEST}" = xyes && AC_DEFINE([ENABLE_DIGEST], 1,
[Define if you want the HTTP Digest Authorization compiled in.])
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)
AC_ARG_ENABLE(ntlm,
[ --disable-ntlm disable support for NTLM authorization],
[ENABLE_NTLM=$enableval], [ENABLE_NTLM=auto])
dnl
dnl Process features
dnl
AC_ARG_ENABLE(debug,
[ --disable-debug disable support for debugging output],
ENABLE_DEBUG=$enableval, ENABLE_DEBUG=yes)
test x"${ENABLE_DEBUG}" = xyes && AC_DEFINE([ENABLE_DEBUG], 1,
[Define if you want the debug output support compiled in.])
dnl Opie: Support for opie s/key FTP logins
AC_ARG_ENABLE([opie],
[AS_HELP_STRING([--disable-opie], [disable support for opie or s/key FTP login])],
[ENABLE_OPIE=$enableval],
[ENABLE_OPIE=yes])
AS_IF([test "x$ENABLE_OPIE" = xyes],
[AC_DEFINE([ENABLE_OPIE], [1], [Define if you want Opie support for FTP compiled in.])],
[]
)
dnl Digest: Support for HTTP Digest Authentication
AC_ARG_ENABLE([digest],
[AS_HELP_STRING([--disable-digest], [disable support for HTTP digest authorization])],
[ENABLE_DIGEST=$enableval],
[ENABLE_DIGEST=yes])
AS_IF([test "x$ENABLE_DIGEST" = xyes],
[AC_DEFINE([ENABLE_DIGEST], [1], [Define if you want the HTTP Digest Authorization compiled in.])],
[]
)
dnl NTLM: Support for HTTP NTLM Authentication
AC_ARG_ENABLE([ntlm],
[AS_HELP_STRING([--disable-ntlm], [disable support for NTLM authorization])],
[ENABLE_NTLM=$enableval],
[ENABLE_NTLM=auto]
)
dnl Debug: Support for printing debugging output
AC_ARG_ENABLE([debug],
[AS_HELP_STRING([--disable-debug], [disable support for debugging output])],
[ENABLE_DEBUG=$enableval],
[ENABLE_DEBUG=yes])
AS_IF([test "x$ENABLE_DEBUG" = xyes],
[AC_DEFINE([ENABLE_DEBUG], [1], [Define if you want the debug output support compiled in.])],
[]
)
dnl Valgrind-tests: Should test suite be run under valgrind?
AC_ARG_ENABLE(valgrind-tests,
[AS_HELP_STRING([--enable-valgrind-tests], [enable using Valgrind for tests])],
[ENABLE_VALGRIND=$enableval],
[ENABLE_VALGRIND=no])
AS_IF([test "x$ENABLE_VALGRIND" != xno], [
AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
AS_IF([test "x$HAVE_VALGRIND" = xyes], [
VALGRIND_TESTS="1"
AC_SUBST(VALGRIND_TESTS)
VALGRIND_INFO="Test suite will be run under Valgrind"
], [
VALGRIND_INFO="Valgrind not found"
])
], [
VALGRIND_INFO="Valgrind testing not enabled"
])
AC_ARG_ENABLE(assert,
[AS_HELP_STRING([--enable-assert], [enable assertions in code base])],
[ENABLE_ASSERTION=$enableval],
[ENABLE_ASSERTION=no]
)
AS_IF([test "x$ENABLE_ASSERTION" != xyes], [
CFLAGS="-DNDEBUG $CFLAGS"
],
[])
dnl
dnl Find the compiler
@@ -114,11 +174,17 @@ AC_AIX
gl_EARLY
dnl
dnl Find python3
dnl
AM_PATH_PYTHON([3.0],,[:])
AM_CONDITIONAL([HAVE_PYTHON3], [test "$PYTHON" != :])
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
@@ -131,9 +197,11 @@ dnl if compiler is gcc, then
dnl use -O2 and some warning flags
dnl else
dnl use os-specific flags or -O
dnl
dnl For these tests, the system considers clang to be gcc
if test -n "$auto_cflags"; then
if test -n "$GCC"; then
CFLAGS="$CFLAGS -O2 -Wall"
CFLAGS="$CFLAGS -O2 -Wall -Wextra"
else
case "$host_os" in
*hpux*) CFLAGS="$CFLAGS +O3" ;;
@@ -207,7 +275,7 @@ AC_FUNC_MMAP
AC_FUNC_FSEEKO
AC_CHECK_FUNCS(strptime timegm vsnprintf vasprintf drand48 pathconf)
AC_CHECK_FUNCS(strtoll usleep ftello sigblock sigsetjmp memrchr wcwidth mbtowc)
AC_CHECK_FUNCS(sleep symlink utime)
AC_CHECK_FUNCS(sleep symlink utime strlcpy random)
if test x"$ENABLE_OPIE" = xyes; then
AC_LIBOBJ([ftp-opie])
@@ -222,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* )
@@ -244,48 +303,88 @@ dnl
dnl Checks for libraries.
dnl
PKG_PROG_PKG_CONFIG
AS_IF([test "x$with_libpsl" != xno], [
PKG_CHECK_MODULES([LIBPSL], libpsl, [
with_libpsl=yes
# correct $LIBPSL_LIBS (in libpsl <= 0.6.0)
AS_IF([test "x$LIBPSL_LIBS" = "x-llibpsl "], [LIBPSL_LIBS="-lpsl"])
LIBS="$LIBPSL_LIBS $LIBS"
CFLAGS="$LIBPSL_CFLAGS $CFLAGS"
AC_DEFINE([HAVE_LIBPSL], [1], [PSL support enabled])
], [
AC_SEARCH_LIBS(psl_builtin, psl,
[with_libpsl=yes; AC_DEFINE([HAVE_LIBPSL], [1], [PSL support enabled])],
[with_libpsl=no; AC_MSG_WARN(*** libpsl was not found. Fallback to builtin cookie checking.)])
])
])
AS_IF([test x"$with_libpsl" = xyes], [
AC_CHECK_FUNCS(psl_latest)
])
AS_IF([test x"$with_zlib" != xno], [
with_zlib=yes
AC_CHECK_LIB(z, compress)
PKG_CHECK_MODULES([ZLIB], zlib, [
LIBS="$ZLIB_LIBS $LIBS"
CFLAGS="$ZLIB_CFLAGS $CFLAGS"
AC_DEFINE([HAVE_LIBZ], [1], [Define if using zlib.])
], [
AC_CHECK_LIB(z, compress)
])
])
AS_IF([test x"$with_ssl" = xopenssl], [
dnl As of this writing (OpenSSL 0.9.6), the libcrypto shared library
dnl doesn't record its dependency on libdl, so we need to make sure
dnl -ldl ends up in LIBS on systems that have it. Most OSes use
dnl dlopen(), but HP-UX uses shl_load().
AC_CHECK_LIB(dl, dlopen, [], [
AC_CHECK_LIB(dl, shl_load)
])
if [test x"$with_libssl_prefix" = x]; then
PKG_CHECK_MODULES([OPENSSL], [openssl], [
AC_MSG_NOTICE([compiling in support for SSL via OpenSSL])
AC_LIBOBJ([openssl])
LIBS="$OPENSSL_LIBS $LIBS"
CFLAGS="$OPENSSL_CFLAGS -DHAVE_LIBSSL $CFLAGS"
LIBSSL=" " # ntlm check below wants this
AC_CHECK_FUNCS([RAND_egd])
AC_DEFINE([HAVE_LIBSSL], [1], [Define if using openssl.])
ssl_found=yes
])
fi
if [test x"$ssl_found" != xyes]; then
dnl As of this writing (OpenSSL 0.9.6), the libcrypto shared library
dnl doesn't record its dependency on libdl, so we need to make sure
dnl -ldl ends up in LIBS on systems that have it. Most OSes use
dnl dlopen(), but HP-UX uses shl_load().
AC_CHECK_LIB(dl, dlopen, [], [
AC_CHECK_LIB(dl, shl_load)
])
ssl_found=no
case $host_os in
*mingw32* )
dnl prefer link to openssl dlls if possible. if not then fallback on static libs. if not then error
ssl_found=no
case $host_os in
*mingw32* )
dnl prefer link to openssl dlls if possible. if not then fallback on static libs. if not then error
AC_CHECK_LIB(eay32, EVP_MD_CTX_init)
if test x"$ac_cv_lib_eay32_EVP_MD_CTX_init" != xno
then
AC_CHECK_LIB(ssl32, SSL_connect, [
ssl_found=yes
AC_MSG_NOTICE([Enabling support for SSL via OpenSSL (shared)])
AC_LIBOBJ([openssl])
LIBS="${LIBS} -lssl32"
AC_DEFINE([HAVE_LIBSSL32], [1], [Define to 1 if you have the `ssl32' library (-lssl32).])
],
AC_MSG_ERROR([openssl not found: shared lib eay32 found but ssl32 not found]))
AC_CHECK_LIB(eay32, EVP_MD_CTX_init)
if test x"$ac_cv_lib_eay32_EVP_MD_CTX_init" != xno
then
AC_CHECK_LIB(ssl32, SSL_connect, [
ssl_found=yes
AC_MSG_NOTICE([Enabling support for SSL via OpenSSL (shared)])
AC_LIBOBJ([openssl])
LIBS="${LIBS} -lssl32"
AC_DEFINE([HAVE_LIBSSL32], [1], [Define to 1 if you have the `ssl32' library (-lssl32).])
],
AC_MSG_ERROR([openssl not found: shared lib eay32 found but ssl32 not found]))
else
LIBS+=' -lgdi32'
dnl fallback and test static libs
fi
dnl add zdll lib as dep for above tests?
;;
esac
else
LIBS+=' -lgdi32'
dnl fallback and test static libs
fi
dnl add zdll lib as dep for above tests?
;;
esac
AS_IF([test x$ssl_found != xyes], [
dnl Now actually check for -lssl if it wasn't already found
AC_LIB_HAVE_LINKFLAGS([ssl], [crypto], [
AS_IF([test x$ssl_found != xyes], [
dnl Now actually check for -lssl if it wasn't already found
AC_LIB_HAVE_LINKFLAGS([ssl], [crypto], [
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/err.h>
@@ -293,19 +392,20 @@ AS_IF([test x"$with_ssl" = xopenssl], [
#include <openssl/des.h>
#include <openssl/md4.h>
#include <openssl/md5.h>
], [SSL_library_init ()])
if test x"$LIBSSL" != x
then
ssl_found=yes
AC_MSG_NOTICE([compiling in support for SSL via OpenSSL])
AC_LIBOBJ([openssl])
LIBS="$LIBSSL $LIBS"
elif test x"$with_ssl" != x
then
AC_MSG_ERROR([--with-ssl=openssl was given, but SSL is not available.])
fi
])
], [SSL_library_init ()])
if test x"$LIBSSL" != x
then
ssl_found=yes
AC_MSG_NOTICE([compiling in support for SSL via OpenSSL])
AC_LIBOBJ([openssl])
LIBS="$LIBSSL $LIBS"
AC_CHECK_FUNCS([RAND_egd])
elif test x"$with_ssl" != x
then
AC_MSG_ERROR([--with-ssl=openssl was given, but SSL is not available.])
fi
])
fi
], [
# --with-ssl is not openssl: check if it's no
AS_IF([test x"$with_ssl" != xno], [
@@ -313,17 +413,29 @@ AS_IF([test x"$with_ssl" = xopenssl], [
with_ssl=gnutls
dnl Now actually check for -lgnutls
AC_LIB_HAVE_LINKFLAGS([gnutls], [], [
if [test x"$with_libgnutls_prefix" = x]; then
PKG_CHECK_MODULES([GNUTLS], [gnutls], [
AC_MSG_NOTICE([compiling in support for SSL via GnuTLS])
AC_LIBOBJ([gnutls])
LIBS="$GNUTLS_LIBS $LIBS"
CFLAGS="$GNUTLS_CFLAGS -DHAVE_LIBGNUTLS $CFLAGS"
AC_DEFINE([HAVE_LIBGNUTLS], [1], [Define if using gnutls.])
ssl_found=yes
])
fi
if [test x"$ssl_found" != xyes]; then
AC_LIB_HAVE_LINKFLAGS([gnutls], [], [
#include <gnutls/gnutls.h>
], [gnutls_global_init()])
if test x"$LIBGNUTLS" != x
then
ssl_found=yes
AC_MSG_NOTICE([compiling in support for SSL via GnuTLS])
AC_LIBOBJ([gnutls])
LIBS="$LIBGNUTLS $LIBS"
else
AC_MSG_ERROR([--with-ssl=gnutls was given, but GNUTLS is not available.])
], [gnutls_global_init()])
if test x"$LIBGNUTLS" != x
then
ssl_found=yes
AC_MSG_NOTICE([compiling in support for SSL via GnuTLS])
AC_LIBOBJ([gnutls])
LIBS="$LIBGNUTLS $LIBS"
else
AC_MSG_ERROR([GnuTLS has not been found. Use --with-ssl=openssl if you explicitly want OpenSSL.])
fi
fi
AC_CHECK_FUNCS(gnutls_priority_set_direct)
@@ -365,6 +477,34 @@ else
fi
fi
dnl
dnl Check for libmetalink
dnl
AS_IF([test x"$with_metalink" != xno], [
PKG_CHECK_MODULES([METALINK], libmetalink, [
LIBS="$METALINK_LIBS $LIBS"
CFLAGS="$METALINK_CFLAGS $CFLAGS"
AC_DEFINE([HAVE_METALINK], [1], [Define if using metalink.])
with_metalink=yes
], [
with_metalink=no
])
have_gpg=no
AS_IF([test x"$with_metalink" = xyes], [
dnl
dnl Check for GPGME
dnl
m4_ifdef([AM_PATH_GPGME], [
AM_PATH_GPGME([], [
LIBS="$GPGME_LIBS $LIBS"
CFLAGS="$GPGME_CFLAGS $CFLAGS"
AC_DEFINE([HAVE_GPGME], [1], [Define if GPGME is available.])
have_gpg=yes
])
])
])
])
dnl **********************************************************************
dnl Checks for IPv6
@@ -490,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
@@ -510,75 +647,152 @@ AS_IF([test "X$iri" != "Xno"],[
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
if test "X$iri" = "Xno"; then
# we don't need libunistring - clear settings from gnulib module
LIBUNISTRING=""
LTLIBUNISTRING=""
fi
dnl
dnl Check for UUID
dnl
AC_CHECK_HEADER(uuid.h,
AC_CHECK_FUNC(uuid, uuid_create,
[AC_DEFINE([HAVE_UUID_CREATE], 1,
[Define if uuid_create is available.])
])
)
AC_CHECK_HEADER(uuid/uuid.h,
AC_CHECK_LIB(uuid, uuid_generate,
[LIBS="${LIBS} -luuid"
AC_DEFINE([HAVE_LIBUUID], 1,
[Define if libuuid is available.])
])
)
AC_ARG_WITH(libuuid, AC_HELP_STRING([--without-libuuid],
[Generate UUIDs for WARC files via libuuid]))
AS_IF([test "x$with_libuuid" = xyes], [
# libuuid was explicitly requested
PKG_CHECK_MODULES([UUID], uuid, [
LIBS="$UUID_LIBS $LIBS"
CFLAGS="$UUID_CFLAGS $CFLAGS"
uuid_mode=1
], [
AC_SEARCH_LIBS(uuid_generate, uuid,
[uuid_mode=1],
[AC_MSG_ERROR(*** libuuid was explicitly requested but wasn't found.)])
])
], [test "x$with_libuuid" = xno], [
# libuuid was explicitly *not* requested
AC_CHECK_HEADER(uuid.h,
AC_CHECK_FUNC(uuid_create, [uuid_mode=2]))
], [
# default:
AC_CHECK_HEADER(uuid.h, [
AC_CHECK_FUNC(uuid_create, [uuid_mode=2])
], [
AC_CHECK_HEADER(uuid/uuid.h,
AC_SEARCH_LIBS(uuid_generate, uuid, [uuid_mode=1]))
])
])
AS_IF([test "x$uuid_mode" = x1], [
AC_DEFINE([HAVE_LIBUUID], [1], [Define if using libuuid.])
], [test "x$uuid_mode" = x2], [
AC_DEFINE([HAVE_UUID_CREATE], 1, [Define if uuid_create is available.])
])
dnl
dnl Check for PCRE
dnl
AC_CHECK_HEADER(pcre.h,
AC_CHECK_LIB(pcre, pcre_compile,
[LIBS="${LIBS} -lpcre"
AC_DEFINE([HAVE_LIBPCRE], 1,
[Define if libpcre is available.])
])
)
AC_ARG_ENABLE(pcre, AC_HELP_STRING([--disable-pcre],
[Disable PCRE style regular expressions]))
AS_IF([test "X$enable_pcre" != "Xno"],[
PKG_CHECK_MODULES([PCRE], libpcre, [
CFLAGS="$PCRE_CFLAGS $CFLAGS"
AC_CHECK_HEADER(pcre.h, [
LIBS="$PCRE_LIBS $LIBS"
AC_DEFINE([HAVE_LIBPCRE], [1], [Define if libpcre is available.])
])
], [
AC_CHECK_HEADER(pcre.h, [
AC_CHECK_LIB(pcre, pcre_compile, [
LIBS="${LIBS} -lpcre"
AC_DEFINE([HAVE_LIBPCRE], 1, [Define if libpcre is available.])
])
])
])
])
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 tests/WgetTest.pm
po/Makefile.in tests/Makefile
lib/Makefile testenv/Makefile])
AC_CONFIG_HEADERS([src/config.h])
AC_OUTPUT
@@ -594,9 +808,16 @@ AC_MSG_NOTICE([Summary of build options:
Libs: $LIBS
SSL: $with_ssl
Zlib: $with_zlib
PSL: $ENABLE_PSL
PSL: $with_libpsl
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
])

54
contrib/check-hard Executable file
View File

@@ -0,0 +1,54 @@
#!/bin/sh
#
# Do some checking before 'git push'.
# Set a stricter bash mode
set -e
set -u
CORES=$(grep -c ^processor /proc/cpuinfo 2> /dev/null || echo 0)
if [ $CORES -lt 1 ]; then CORES=1; fi
echo "Running: make distclean"
make distclean > /dev/null || true
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"
CACHEFILE=$PWD/config_check.cache
# measure time consumed and print it at the end of the script
START=$(date +%s.%N)
echo "Running: ./bootstrap"
./bootstrap > /dev/null
echo
for CC in gcc clang; do
export CC
echo "*** Testing with CC=$CC"
# the compiler changed, so we have to remove the cache file here
rm -f $CACHEFILE
for options in "" "--with-ssl=openssl"; do
export DISTCHECK_CONFIGURE_FLAGS="-C --cache-file=$CACHEFILE $options"
echo " ./configure $DISTCHECK_CONFIGURE_FLAGS"
./configure $DISTCHECK_CONFIGURE_FLAGS CFLAGS="$CFLAGS" > /dev/null
for xVALGRIND in 0 1; do
for xLCALL in C tr_TR.utf8; do
export TESTS_ENVIRONMENT="LC_ALL=$xLCALL VALGRIND_TESTS=$xVALGRIND"
echo " TESTS_ENVIRONMENT=\"$TESTS_ENVIRONMENT\"" make check -j$CORES
make check -j$CORES > /dev/null
done
done
unset TESTS_ENVIRONMENT
export TESTS_ENVIRONMENT
echo " make distcheck CFLAGS=$CFLAGS -j$CORES"
make distcheck CFLAGS="$CFLAGS" -j$CORES > /dev/null
done
done
END=$(date +%s.%N)
echo "Duration: "$(echo "$END - $START" | bc)

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))"

90
contrib/tsocked-wget Executable file
View File

@@ -0,0 +1,90 @@
#!/bin/bash
# Script that executes wget using a socks proxy if the environment variable
# socks_proxy is set.
#
# The socks_proxy variable shall have one of the forms:
# socks://username:password@host:port
# socks4://username:password@host:port
# socks5://username:password@host:port
# with username, password and port fields being optional
#
# As socksification applies to the whole process, domains defined in the
# no_proxy setting are *not* excluded.
#
# Requisites: bash (version 3.2.3 or later), tsocks and wget
####################################
# Copyright (C) 2014 Ángel González
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
set -eu
# Binary to be executed. Use an absolute path if installing this script as 'wget'
WGET=wget
if [ -z "${socks_proxy:-}" ]; then
exec "$WGET" "$@"
fi
CONFIG=""
if [[ "${socks_proxy}" =~ ^socks[45]?:// ]]; then
if [[ "${socks_proxy:5:1}" != ":" ]]; then
CONFIG+="server_type = ${socks_proxy:5:1}"
socks_proxy="${socks_proxy:9}"
else
socks_proxy="${socks_proxy:8}"
fi
elif [[ "${socks_proxy}" =~ ^[[:alnum:]]*:// ]]; then
echo "Bad value specified for socks_proxy: $socks_proxy" >&2
exit 2
fi
if [[ "${socks_proxy}" =~ ^([^@:]*)(:([^@]*))?@ ]]; then
unset TSOCKS_USERNAME
CONFIG+="
default_user = ${BASH_REMATCH[1]}"
if [ ! -z "${BASH_REMATCH[3]}" ]; then
unset TSOCKS_PASSWORD
CONFIG+="
default_pass = ${BASH_REMATCH[3]}"
fi
socks_proxy="${socks_proxy:${#BASH_REMATCH[0]}}"
fi
# Get rid of trailing slashes
if [[ "${socks_proxy}" =~ ^([^/]*)/ ]]; then
socks_proxy="${socks_proxy:0:${#BASH_REMATCH[1]}}"
fi
if [[ "${socks_proxy}" =~ :([0-9]+)$ ]]; then
CONFIG+="
server_port = ${BASH_REMATCH[1]}"
socks_proxy=${socks_proxy:0:${#socks_proxy} - ${#BASH_REMATCH[0]}}
fi
CONFIG+="
server = ${socks_proxy}"
TSOCKS_CONF_FILE=<(echo "$CONFIG") exec tsocks "$WGET" --no-proxy "$@"

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
# Makefile for `wget' utility
# Copyright (C) 1995, 1996, 1997, 2007, 2008, 2009, 2010, 2011 Free
# Software Foundation, Inc.
# Copyright (C) 1995, 1996, 1997, 2007, 2008, 2009, 2010, 2011, 2015
# 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
@@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Version: $(VERSION)
# Version: @VERSION@
#
# Program to convert DVI files to PostScript
@@ -28,6 +28,7 @@ manext = 1
RM = rm -f
TEXI2POD = $(srcdir)/texi2pod.pl
POD2MAN = @POD2MAN@
MAN = wget.$(manext)
WGETRC = $(sysconfdir)/wgetrc
SAMPLERCTEXI = sample.wgetrc.munged_for_texi_inclusion
@@ -38,7 +39,7 @@ SAMPLERCTEXI = sample.wgetrc.munged_for_texi_inclusion
man_MANS = $(MAN)
all: wget.info $(COMMENT_IF_NO_POD2MAN)$(MAN)
all: wget.info @COMMENT_IF_NO_POD2MAN@$(MAN)
everything: all wget_us.ps wget_a4.ps wget_toc.html
@@ -56,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)" $? > $@
$(POD2MAN) --center="GNU Wget" --release="GNU Wget @VERSION@" --utf8 $? > $@ || \
$(POD2MAN) --center="GNU Wget" --release="GNU Wget @VERSION@" $? > $@
#wget.cat: $(MAN)
# nroff -man $? > $@
@@ -75,10 +77,10 @@ wget_toc.html: $(srcdir)/wget.texi
#
# install all the documentation
install-data-local: install.wgetrc $(COMMENT_IF_NO_POD2MAN)install.man
install-data-local: install.wgetrc @COMMENT_IF_NO_POD2MAN@install.man
# uninstall all the documentation
uninstall-local: $(COMMENT_IF_NO_POD2MAN)uninstall.man
uninstall-local: @COMMENT_IF_NO_POD2MAN@uninstall.man
# install man page, creating install directory if necessary

View File

@@ -5,7 +5,8 @@
@c hence no sectioning command or @node.
@display
Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
Copyright @copyright{} 2000, 2001, 2002, 2007, 2008, 2015 Free Software
Foundation, Inc.
@uref{http://fsf.org/}
Everyone is permitted to copy and distribute verbatim copies

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

@@ -16,6 +16,9 @@
## To use the settings in this file, you will have to uncomment them,
## as well as change them, in most cases, as the values on the
## commented-out lines are the default values (e.g. "off").
##
## Command are case-, underscore- and minus-insensitive.
## For example ftp_proxy, ftp-proxy and ftpproxy are the same.
##
@@ -122,7 +125,7 @@
#iri = off
# Force the default system encoding
#locale = UTF-8
#localencoding = UTF-8
# Force the default remote server encoding
#remoteencoding = UTF-8

View File

@@ -1,7 +1,7 @@
#! /usr/bin/env perl
# Copyright (C) 1999, 2000, 2001, 2003, 2007, 2009, 2010, 2011 Free
# Software Foundation, Inc.
# Copyright (C) 1999, 2000, 2001, 2003, 2007, 2009, 2010, 2011, 2015
# Free Software Foundation, Inc.
# This file is part of GCC.
@@ -315,6 +315,8 @@ die "No filename or title\n" unless defined $fn && defined $tl;
$sects{NAME} = "$fn \- $tl\n";
$sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES};
print "=encoding utf-8\n\n";
for $sect (qw(NAME SYNOPSIS DESCRIPTION OPTIONS ENVIRONMENT EXITSTATUS
FILES BUGS NOTES FOOTNOTES SEEALSO AUTHOR COPYRIGHT)) {
if(exists $sects{$sect}) {

File diff suppressed because it is too large Load Diff

2
gnulib

Submodule gnulib updated: 98ca2c063c...916a632413

View File

@@ -27,89 +27,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,61 +0,0 @@
2014-06-11 Giuseppe Scrivano <gscrivan@redhat.com>
* Makefile.DJ: Remove terminating empty lines.
* Makefile.WC: Likewise.
* msdos.c: Likewise.
2009-09-06 Gisle Vanem <gvanem@broadpark.no>
* Makefile.WC: Added compilation of new file msdos.c.
Simplified; no need to have explicit rules for files in ./lib and
./md5. Just use the suffix search path mechanism in wmake.
2009-09-06 Gisle Vanem <gvanem@broadpark.no>
* Makefile.DJ: Added compilation of new file msdos.c.
2009-09-05 Gisle Vanem <gvanem@broadpark.no>
* config.h: Added 'HAVE_ALLOCA_H' for Watcom 1.5+. Added
'USE_WATT32' since all DOS-targets use the Watt-32 tcp/ip stack.
Added meaningless dummy LOCALEDIR.
* Makefile.WC: A much needed update. Added rules for many files
in ./lib, css.c and version.c.
* Makefile.DJ: A much needed update. Added rules for css.c and
version.c.
2008-01-25 Micah Cowan <micah@cowan.name>
* config.h: Updated copyright year.
2007-11-28 Micah Cowan <micah@cowan.name>
* config.h: Updated license exception for OpenSSL, per the SFLC.
2007-10-15 Gisle Vanem <gvanem@broadpark.no>
* config.h: Added some HAVE_* for djgpp 2.04 and Watcom 1.7+.
* Makefile.DJ: rewritten for including some files from ../lib.
* Makefile.WC: Ditto. Handling source-files out-of current
directory makes compliation a bit more painfull. AFAICS, one
must use explicit rules.
2007-10-02 Gisle Vanem <gvanem@broadpark.no>
* config.h: Removed unused defines, added needed 'HAVE_*' defines.
* Makefile.DJ: rewritten to be used from './src' directory.
Added '-DOPENSSL_NO_KRB5' for OpenSSL build. Target is
now wget.exe.
* Makefile.WC: Added for building with OpenWatcom targeting
32-bit DOS (DOS32A extender).
2007-09-24 Gisle Vanem <giva@bgnett.no>
* Makefile.DJ, config.h: Added to support building on MS-DOS via
DJGPP.

View File

@@ -1,6 +1,6 @@
/* Configuration header file for MS-DOS/Watt-32
Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
Inc.
Copyright (C) 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,5 +1,5 @@
/* MSDOS utility functions.
Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
Copyright (C) 2009, 2010, 2011, 2015 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -26,6 +26,7 @@ src/init.c
src/iri.c
src/log.c
src/main.c
src/metalink.c
src/mswindows.c
src/netrc.c
src/openssl.c

View File

@@ -1 +0,0 @@
timestamp

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
# Makefile for `wget' utility
# Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
# 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
# Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
@@ -28,35 +28,45 @@
# as that of the covered work.
#
# Version: $(VERSION)
# Version: @VERSION@
#
if IRI_IS_ENABLED
IRI_OBJ = iri.c
endif
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 += -DSYSTEM_WGETRC=\"$(sysconfdir)/wgetrc\" -DLOCALEDIR=\"$(localedir)\"
LIBS += $(LIBICONV) $(LIBINTL) $(LIB_CLOCK_GETTIME)
DEFS = @DEFS@ -DSYSTEM_WGETRC=\"$(sysconfdir)/wgetrc\" -DLOCALEDIR=\"$(localedir)\"
EXTRA_DIST = css.l css.c css_.c build_info.c.in
bin_PROGRAMS = wget
wget_SOURCES = cmpt.c connect.c convert.c cookies.c ftp.c \
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 html-parse.c html-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 \
utils.c exits.c build_info.c $(IRI_OBJ) \
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 html-parse.h html-url.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 gettext.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) $(LTLIBICONV) $(LTLIBINTL)\
$(LTLIBTHREAD) $(LTLIBUNISTRING) $(SERVENT_LIB)
AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib
@@ -74,7 +84,8 @@ version.c: $(wget_SOURCES) ../lib/libgnu.a
echo '/* version.c */' > $@
echo '/* Autogenerated by Makefile - DO NOT EDIT */' >> $@
echo '' >> $@
echo 'const char *version_string = "$(VERSION)";' >> $@
echo '#include "version.h"' >> $@
echo 'const char *version_string = "@VERSION@";' >> $@
echo 'const char *compilation_string = "'$(COMPILE)'";' \
| $(ESCAPEQUOTE) >> $@
echo 'const char *link_string = "'$(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -82,7 +93,7 @@ version.c: $(wget_SOURCES) ../lib/libgnu.a
| $(ESCAPEQUOTE) >> $@
css.c: $(srcdir)/css.l
$(LEX) $(LFLAGS) -o $@ $^
$(LEX) $(LFLAGS) -o$@ $^
css_.c: css.c
echo '#include "wget.h"' > $@

View File

@@ -2,12 +2,16 @@ digest defined ENABLE_DIGEST
https defined HAVE_SSL
ipv6 defined ENABLE_IPV6
iri defined ENABLE_IRI
large-file SIZEOF_OFF_T >= 8
large-file SIZEOF_OFF_T >= 8 || defined WINDOWS
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

1427
src/cmpt.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* Establishing and handling network connections.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -31,6 +31,7 @@ as that of the covered work. */
#include "wget.h"
#include "exits.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -54,6 +55,11 @@ as that of the covered work. */
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#ifdef ENABLE_IRI
#include <idn2.h>
#endif
#include "utils.h"
#include "host.h"
#include "connect.h"
@@ -168,7 +174,7 @@ sockaddr_size (const struct sockaddr *sa)
abort ();
}
}
/* Resolve the bind address specified via --bind-address and store it
to SA. The resolved value is stored in a static variable and
reused after the first invocation of this function.
@@ -213,7 +219,7 @@ resolve_bind_address (struct sockaddr *sa)
should_bind = true;
return true;
}
struct cwt_context {
int fd;
const struct sockaddr *addr;
@@ -250,7 +256,7 @@ connect_with_timeout (int fd, const struct sockaddr *addr, socklen_t addrlen,
errno = ETIMEDOUT;
return ctx.result;
}
/* Connect via TCP to the specified address and port.
If PRINT is non-NULL, it is the host name to print that we're
@@ -278,14 +284,13 @@ connect_to_ip (const ip_address *ip, int port, const char *print)
str = xmalloc (len);
snprintf (str, len, "%s (%s)", name, print);
str[len-1] = '\0';
xfree (name);
idn2_free (name);
}
logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "),
str ? str : escnonprint_uri (print), txt_addr, port);
if (str)
xfree (str);
xfree (str);
}
else
{
@@ -327,8 +332,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. */
@@ -365,9 +372,16 @@ 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_VERBOSE, _("failed: %s.\n"), strerror (errno));
logprintf (LOG_NOTQUIET, _("failed: %s.\n"), strerror (errno));
errno = save_errno;
return -1;
}
@@ -429,7 +443,7 @@ connect_to_host (const char *host, int port)
return -1;
}
/* Create a socket, bind it to local interface BIND_ADDRESS on port
*PORT, set up a listen backlog, and return the resulting socket, or
-1 in case of error.
@@ -460,7 +474,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);
@@ -678,6 +694,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)
@@ -720,6 +741,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. */
@@ -746,7 +772,7 @@ wget uses blocking sockets so we must convert them back to blocking
or EOF/error. */
return false;
}
/* Basic socket operations, mostly EINTR wrappers. */
static int
@@ -794,7 +820,7 @@ sock_close (int fd)
#undef read
#undef write
#undef close
/* Reading and writing from the network. We build around the socket
(file descriptor) API, but support "extended" operations for things
that are not mere file descriptors under the hood, such as SSL
@@ -845,7 +871,7 @@ void *
fd_transport_context (int fd)
{
struct transport_info *info = hash_table_get (transport_map, (void *)(intptr_t) fd);
return info->ctx;
return info ? info->ctx : NULL;
}
/* When fd_read/fd_write are called multiple times in a loop, they should

View File

@@ -1,7 +1,7 @@
/* Declarations for connect.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 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
Free Software Foundation, Inc.
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
2014, 2015 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -46,6 +46,7 @@ as that of the covered work. */
#include "html-url.h"
#include "css-url.h"
#include "iri.h"
#include "xstrndup.h"
static struct hash_table *dl_file_url_map;
struct hash_table *dl_url_file_map;
@@ -136,8 +137,9 @@ convert_links_in_hashtable (struct hash_table *downloaded_set,
form. We do this even if the URL already is in
relative form, because our directory structure may
not be identical to that on the server (think `-nd',
`--cut-dirs', etc.) */
cur_url->convert = CO_CONVERT_TO_RELATIVE;
`--cut-dirs', etc.). If --convert-file-only was passed,
we only convert the basename portion of the URL. */
cur_url->convert = (opt.convert_file_only ? CO_CONVERT_BASENAME_ONLY : CO_CONVERT_TO_RELATIVE);
cur_url->local_name = xstrdup (local_name);
DEBUGP (("will convert url %s to local %s\n", u->url, local_name));
}
@@ -193,7 +195,7 @@ convert_all_links (void)
convert_links_in_hashtable (downloaded_css_set, 1, &file_count);
secs = ptimer_measure (timer);
logprintf (LOG_VERBOSE, _("Converted %d files in %s seconds.\n"),
logprintf (LOG_VERBOSE, _("Converted links in %d files in %s seconds.\n"),
file_count, print_decimal (secs));
ptimer_destroy (timer);
@@ -206,6 +208,7 @@ static const char *replace_attr_refresh_hack (const char *, int, FILE *,
const char *, int);
static char *local_quote_string (const char *, bool);
static char *construct_relative (const char *, const char *);
static char *convert_basename (const char *, const struct urlpos *);
/* Change the links in one file. LINKS is a list of links in the
document, along with their positions and the desired direction of
@@ -221,7 +224,7 @@ convert_links (const char *file, struct urlpos *links)
struct urlpos *link;
int to_url_count = 0, to_file_count = 0;
logprintf (LOG_VERBOSE, _("Converting %s... "), file);
logprintf (LOG_VERBOSE, _("Converting links in %s... "), file);
{
/* First we do a "dry run": go through the list L and see whether
@@ -305,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);
@@ -315,9 +318,32 @@ convert_links (const char *file, struct urlpos *links)
DEBUGP (("TO_RELATIVE: %s to %s at position %d in %s.\n",
link->url->url, newname, link->pos, file));
xfree (newname);
xfree (quoted_newname);
++to_file_count;
break;
}
case CO_CONVERT_BASENAME_ONLY:
{
char *newname = convert_basename (p, link);
char *quoted_newname = local_quote_string (newname, 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);
else
p = replace_attr_refresh_hack (p, link->size, fp, quoted_newname,
link->refresh_timeout);
DEBUGP (("Converted file part only: %s to %s at position %d in %s.\n",
link->url->url, newname, link->pos, file));
xfree (newname);
xfree (quoted_newname);
++to_file_count;
break;
}
case CO_CONVERT_TO_COMPLETE:
@@ -326,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);
@@ -336,6 +362,7 @@ convert_links (const char *file, struct urlpos *links)
DEBUGP (("TO_COMPLETE: <something> to %s at position %d in %s.\n",
newlink, link->pos, file));
xfree (quoted_newlink);
++to_url_count;
break;
@@ -414,14 +441,89 @@ construct_relative (const char *basefile, const char *linkfile)
++basedirs;
}
/* Construct LINK as explained above. */
link = xmalloc (3 * basedirs + strlen (linkfile) + 1);
for (i = 0; i < basedirs; i++)
memcpy (link + 3 * i, "../", 3);
strcpy (link + 3 * i, linkfile);
if (!basedirs && (b = strpbrk (linkfile, "/:")) && *b == ':')
{
link = xmalloc (2 + strlen (linkfile) + 1);
memcpy (link, "./", 2);
strcpy (link + 2, linkfile);
}
else
{
/* Construct LINK as explained above. */
link = xmalloc (3 * basedirs + strlen (linkfile) + 1);
for (i = 0; i < basedirs; i++)
memcpy (link + 3 * i, "../", 3);
strcpy (link + 3 * i, linkfile);
}
return link;
}
/* Construct and return a "transparent proxy" URL
reflecting changes made by --adjust-extension to the file component
(i.e., "basename") of the original URL, but leaving the "dirname"
of the URL (protocol://hostname... portion) untouched.
Think: populating a squid cache via a recursive wget scrape, where
changing URLs to work locally with "file://..." is NOT desirable.
Example:
if
p = "//foo.com/bar.cgi?xyz"
and
link->local_name = "docroot/foo.com/bar.cgi?xyz.css"
then
new_construct_func(p, link);
will return
"//foo.com/bar.cgi?xyz.css"
Essentially, we do s/$(basename orig_url)/$(basename link->local_name)/
*/
static char *
convert_basename (const char *p, const struct urlpos *link)
{
int len = link->size;
char *url = NULL;
char *org_basename = NULL, *local_basename = NULL;
char *result = NULL;
if (*p == '"' || *p == '\'')
{
len -= 2;
p++;
}
url = xstrndup (p, len);
org_basename = strrchr (url, '/');
if (org_basename)
org_basename++;
else
org_basename = url;
local_basename = strrchr (link->local_name, '/');
if (local_basename)
local_basename++;
else
local_basename = url;
/*
* If the basenames differ, graft the adjusted basename (local_basename)
* onto the original URL.
*/
if (strcmp (org_basename, local_basename) == 0)
result = url;
else
{
result = uri_merge (url, local_basename);
xfree (url);
}
return result;
}
/* Used by write_backup_file to remember which files have been
written. */
static struct hash_table *converted_files;
@@ -661,7 +763,7 @@ local_quote_string (const char *file, bool no_html_quote)
return no_html_quote ? strdup (newname) : html_quote_string (newname);
}
/* Book-keeping code for dl_file_url_map, dl_url_file_map,
downloaded_html_list, and downloaded_html_set. Other code calls
these functions to let us know that a file has been downloaded. */
@@ -916,7 +1018,7 @@ convert_cleanup (void)
if (converted_files)
string_set_free (converted_files);
}
/* Book-keeping code for downloaded files that enables extension
hacks. */
@@ -1012,7 +1114,7 @@ downloaded_files_free (void)
downloaded_files_hash = NULL;
}
}
/* The function returns the pointer to the malloc-ed quoted version of
string s. It will recognize and quote numeric and special graphic
entities, as per RFC1866:

View File

@@ -1,6 +1,6 @@
/* Declarations for convert.c
Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010, 2011 Free Software
Foundation, Inc.
Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
This file is part of GNU Wget.
@@ -40,6 +40,8 @@ enum convert_options {
CO_NOCONVERT = 0, /* don't convert this URL */
CO_CONVERT_TO_RELATIVE, /* convert to relative, e.g. to
"../../otherdir/foo.gif" */
CO_CONVERT_BASENAME_ONLY, /* convert the file portion only (basename)
leaving the rest of the URL unchanged */
CO_CONVERT_TO_COMPLETE, /* convert to absolute, e.g. to
"http://orighost/somedir/bar.jpg". */
CO_NULLIFY_BASE /* change to empty string. */
@@ -67,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,6 @@
/* Support for cookies.
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010, 2011 Free Software Foundation, Inc.
2010, 2011, 2015 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -45,6 +45,7 @@ as that of the covered work. */
#include "wget.h"
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -58,7 +59,9 @@ as that of the covered work. */
#include "hash.h"
#include "cookies.h"
#include "http.h" /* for http_atotm */
#include "c-strcase.h"
/* Declarations of `struct cookie' and the most basic functions. */
/* Cookie jar serves as cookie storage and a means of retrieving
@@ -151,13 +154,13 @@ cookie_expired_p (const struct cookie *c)
static void
delete_cookie (struct cookie *cookie)
{
xfree_null (cookie->domain);
xfree_null (cookie->path);
xfree_null (cookie->attr);
xfree_null (cookie->value);
xfree (cookie->domain);
xfree (cookie->path);
xfree (cookie->attr);
xfree (cookie->value);
xfree (cookie);
}
/* Functions for storing cookies.
All cookies can be reached beginning with jar->chains. The key in
@@ -302,7 +305,12 @@ discard_matching_cookie (struct cookie_jar *jar, struct cookie *cookie)
res = hash_table_get_pair (jar->chains, victim->domain,
&chain_key, NULL);
assert (res != 0);
if (res == 0)
{
logprintf (LOG_VERBOSE, _("Unable to get cookie for %s\n"),
victim->domain);
}
if (!victim->next)
{
/* VICTIM was the only cookie in the chain. Destroy the
@@ -317,7 +325,7 @@ discard_matching_cookie (struct cookie_jar *jar, struct cookie *cookie)
DEBUGP (("Discarded old cookie.\n"));
}
}
/* Functions for parsing the `Set-Cookie' header, and creating new
cookies from the wire. */
@@ -369,7 +377,7 @@ parse_set_cookie (const char *set_cookie, bool silent)
{
if (!TOKEN_NON_EMPTY (value))
goto error;
xfree_null (cookie->domain);
xfree (cookie->domain);
/* Strictly speaking, we should set cookie->domain_exact if the
domain doesn't begin with a dot. But many sites set the
domain to "foo.com" and expect "subhost.foo.com" to get the
@@ -382,7 +390,7 @@ parse_set_cookie (const char *set_cookie, bool silent)
{
if (!TOKEN_NON_EMPTY (value))
goto error;
xfree_null (cookie->path);
xfree (cookie->path);
cookie->path = strdupdelim (value.b, value.e);
}
else if (TOKEN_IS (name, "expires"))
@@ -456,7 +464,7 @@ parse_set_cookie (const char *set_cookie, bool silent)
#undef TOKEN_IS
#undef TOKEN_NON_EMPTY
/* Sanity checks. These are important, otherwise it is possible for
mailcious attackers to destroy important cookie information and/or
violate your privacy. */
@@ -518,19 +526,51 @@ check_domain_match (const char *cookie_domain, const char *host)
{
#ifdef HAVE_LIBPSL
DEBUGP (("cdm: 1"));
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;
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)
{
@@ -555,13 +595,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))
@@ -601,7 +641,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)
{
@@ -627,12 +667,12 @@ no_psl:
++ldcl;
}
DEBUGP ((" 5"));
DEBUGP (("cdm: 5\n"));
if (dccount < 2)
return false;
DEBUGP ((" 6"));
DEBUGP (("cdm: 6\n"));
if (dccount == 2)
{
@@ -652,7 +692,7 @@ no_psl:
}
}
DEBUGP ((" 7"));
DEBUGP (("cdm: 7\n"));
/* Don't allow the host "foobar.com" to set a cookie for domain
"bar.com". */
@@ -667,7 +707,7 @@ no_psl:
return false;
}
DEBUGP ((" 8"));
DEBUGP (("cdm: 8\n"));
return true;
}
@@ -692,7 +732,7 @@ check_path_match (const char *cookie_path, const char *path)
s = PS_newstr; \
} while (0)
/* Process the HTTP `Set-Cookie' header. This results in storing the
cookie or discarding a matching one, or ignoring it completely, all
depending on the contents. */
@@ -776,7 +816,7 @@ cookie_handle_set_cookie (struct cookie_jar *jar,
if (cookie)
delete_cookie (cookie);
}
/* Support for sending out cookies in HTTP requests, based on
previously stored cookies. Entry point is
`build_cookies_request'. */
@@ -1011,7 +1051,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 */
@@ -1025,7 +1065,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);
@@ -1036,7 +1076,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;
@@ -1044,12 +1084,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;
@@ -1104,10 +1146,11 @@ cookie_header (struct cookie_jar *jar, const char *host,
}
}
result[pos++] = '\0';
xfree (outgoing);
assert (pos == result_size);
return result;
}
/* Support for loading and saving cookies. The format used for
loading and saving should be the format of the `cookies.txt' file
used by Netscape and Mozilla, at least the Unix versions.
@@ -1346,7 +1389,7 @@ cookie_jar_save (struct cookie_jar *jar, const char *file)
DEBUGP (("Done saving cookies.\n"));
}
/* Clean up cookie-related data. */
void
@@ -1369,7 +1412,7 @@ cookie_jar_delete (struct cookie_jar *jar)
hash_table_destroy (jar->chains);
xfree (jar);
}
/* Test cases. Currently this is only tests parse_set_cookies. To
use, recompile Wget with -DTEST_COOKIES and call test_cookies()
from main. */
@@ -1438,8 +1481,8 @@ test_cookies (void)
printf ("Invalid value %d for '%s' (expected '%s', got '%s')\n",
j / 2 + 1, data, expected[j + 1], v);
j += 2;
free (n);
free (v);
xfree (n);
xfree (v);
}
if (expected[j])
printf ("Too few parameters for '%s'\n", data);

View File

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

View File

@@ -1,5 +1,6 @@
/* Declarations for css.lex
Copyright (C) 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
Copyright (C) 2006, 2009, 2010, 2011, 2015 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 Free
Software Foundation, Inc.
Copyright (C) 1998, 2000, 2001, 2002, 2003, 2009, 2010, 2011, 2014,
2015 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -52,12 +52,14 @@ as that of the covered work. */
#include "html-url.h"
#include "css-tokens.h"
#include "css-url.h"
#include "xstrndup.h"
/* from lex.yy.c */
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);
/*
@@ -97,7 +99,7 @@ get_uri_string (const char *at, int *pos, int *length)
*length -= 2;
}
return xstrdup (at + *pos);
return xstrndup (at + *pos, *length);
}
void
@@ -108,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)
{
@@ -187,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,6 @@
/* Declarations for css-url.c.
Copyright (C) 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
Copyright (C) 2006, 2009, 2010, 2011, 2015 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -30,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,8 @@
%{
/* Lex source for CSS tokenizing.
Taken from http://www.w3.org/TR/CSS21/grammar.html#q2
Copyright (C) 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
Copyright (C) 2006, 2009, 2010, 2011, 2015 Free Software Foundation,
Inc.
This file is part of GNU Wget.

View File

@@ -1,5 +1,6 @@
/* Exit status handling.
Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
Copyright (C) 2009, 2010, 2011, 2012, 2015 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -56,7 +57,7 @@ get_status_for_err (uerr_t err)
case FTPNSFOD: case FTPUNKNOWNTYPE: case FTPSRVERR:
case FTPRETRINT: case FTPRESTFAIL: case FTPNOPASV:
case CONTNOTSUPPORTED: case RANGEERR: case RETRBADPATTERN:
case PROXERR:
case PROXERR: case GATEWAYTIMEOUT:
return WGET_EXIT_SERVER_ERROR;
case URLERROR: case QUOTEXC: case SSLINITFAILED: case UNKNOWNATTR:
default:

View File

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

View File

@@ -1,7 +1,7 @@
/* Basic FTP routines.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -43,8 +43,9 @@ as that of the covered work. */
#include "host.h"
#include "ftp.h"
#include "retr.h"
#include "c-strcase.h"
/* Get the response of FTP server and allocate enough room to handle
it. <CR> and <LF> characters are stripped from the line, and the
line is 0-terminated. All the response lines but the last one are
@@ -134,6 +135,23 @@ ftp_request (const char *command, const char *value)
return res;
}
uerr_t
ftp_greeting (int csock)
{
uerr_t err = FTPOK;
char *response = NULL;
err = ftp_response (csock, &response);
if (err != FTPOK)
goto bail;
if (*response != '2')
err = FTPSRVERR;
bail:
if (response)
xfree (response);
return err;
}
/* Sends the USER and PASS commands to the server, to control
connection socket csock. */
uerr_t
@@ -143,16 +161,6 @@ ftp_login (int csock, const char *acc, const char *pass)
char *request, *respline;
int nwritten;
/* Get greeting. */
err = ftp_response (csock, &respline);
if (err != FTPOK)
return err;
if (*respline != '2')
{
xfree (respline);
return FTPSRVERR;
}
xfree (respline);
/* Send USER username. */
request = ftp_request ("USER", acc);
nwritten = fd_write (csock, request, strlen (request), -1);
@@ -190,7 +198,7 @@ ftp_login (int csock, const char *acc, const char *pass)
for (i = 0; i < countof (skey_head); i++)
{
int l = strlen (skey_head[i]);
if (0 == strncasecmp (skey_head[i], respline, l))
if (0 == c_strncasecmp (skey_head[i], respline, l))
{
seed = respline + l;
break;
@@ -480,6 +488,119 @@ ftp_eprt (int csock, int *local_sock)
}
#endif
#ifdef HAVE_SSL
/*
* The following three functions defined into this #ifdef block
* wrap the extended FTP commands defined in RFC 2228 (FTP Security Extensions).
* Currently, only FTPS is supported, so these functions are only compiled when SSL
* support is available, because there's no point in using FTPS when there's no SSL.
* Shall someone add new secure FTP protocols in the future, feel free to remove this
* #ifdef, or add new constants to it.
*/
/*
* Sends an AUTH command as defined by RFC 2228,
* deriving its argument from the scheme. For example, if the provided scheme
* is SCHEME_FTPS, the command sent will be "AUTH TLS". Currently, this is the only
* scheme supported, so this function will return FTPNOAUTH when supplied a different
* one. It will also return FTPNOAUTH if the target server does not support FTPS.
*/
uerr_t
ftp_auth (int csock, enum url_scheme scheme)
{
uerr_t err = 0;
int written = 0;
char *request = NULL, *response = NULL;
if (scheme == SCHEME_FTPS)
{
request = ftp_request ("AUTH", "TLS");
written = fd_write (csock, request, strlen (request), -1);
if (written < 0)
{
err = WRITEFAILED;
goto bail;
}
err = ftp_response (csock, &response);
if (err != FTPOK)
goto bail;
if (*response != '2')
err = FTPNOAUTH;
}
else
err = FTPNOAUTH;
bail:
xfree (request);
xfree (response);
return err;
}
uerr_t
ftp_pbsz (int csock, int pbsz)
{
uerr_t err = 0;
int written = 0;
char spbsz[5];
char *request = NULL, *response = NULL;
snprintf (spbsz, 5, "%d", pbsz);
request = ftp_request ("PBSZ", spbsz);
written = fd_write (csock, request, strlen (request), -1);
if (written < 0)
{
err = WRITEFAILED;
goto bail;
}
err = ftp_response (csock, &response);
if (err != FTPOK)
goto bail;
if (*response != '2')
err = FTPNOPBSZ;
bail:
xfree (request);
xfree (response);
return err;
}
uerr_t
ftp_prot (int csock, enum prot_level prot)
{
uerr_t err = 0;
int written = 0;
char *request = NULL, *response = NULL;
/* value must be a single character value */
char value[2];
value[0] = prot;
value[1] = '\0';
request = ftp_request ("PROT", value);
written = fd_write (csock, request, strlen (request), -1);
if (written < 0)
{
err = WRITEFAILED;
goto bail;
}
err = ftp_response (csock, &response);
if (err != FTPOK)
goto bail;
if (*response != '2')
err = FTPNOPROT;
bail:
xfree (request);
xfree (response);
return err;
}
#endif /* HAVE_SSL */
/* 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. */
@@ -784,16 +905,8 @@ ftp_epsv (int csock, ip_address *ip, int *port)
}
/* Finally, get the port number */
tport = 0;
for (i = 1; c_isdigit (*s); s++)
{
if (i > 5)
{
xfree (respline);
return FTPINVPASV;
}
for (tport = 0, i = 0; i < 5 && c_isdigit (*s); i++, s++)
tport = (*s - '0') + 10 * tport;
}
/* Make sure that the response terminates correcty */
if (*s++ != delim)
@@ -965,16 +1078,18 @@ ftp_list (int csock, const char *file, bool avoid_list_a, bool avoid_list,
bool ok = false;
size_t i = 0;
*list_a_used = false;
/* 2013-10-12 Andrea Urbani (matfanjol)
For more information about LIST and "LIST -a" please look at ftp.c,
function getftp, text "__LIST_A_EXPLANATION__".
If somebody changes the following commands, please, checks also the
later "i" variable. */
const char *list_commands[] = { "LIST -a",
"LIST" };
static const char *list_commands[] = {
"LIST -a",
"LIST"
};
*list_a_used = false;
if (avoid_list_a)
{
@@ -1068,25 +1183,25 @@ ftp_syst (int csock, enum stype *server_type, enum ustype *unix_type)
if (request == NULL)
*server_type = ST_OTHER;
else if (!strcasecmp (request, "VMS"))
else if (!c_strcasecmp (request, "VMS"))
*server_type = ST_VMS;
else if (!strcasecmp (request, "UNIX"))
else if (!c_strcasecmp (request, "UNIX"))
{
*server_type = ST_UNIX;
/* 2013-10-17 Andrea Urbani (matfanjol)
I check more in depth the system type */
if (!strncasecmp (ftp_last_respline, "215 UNIX Type: L8", 17))
if (!c_strncasecmp (ftp_last_respline, "215 UNIX Type: L8", 17))
*unix_type = UST_TYPE_L8;
else if (!strncasecmp (ftp_last_respline,
else if (!c_strncasecmp (ftp_last_respline,
"215 UNIX MultiNet Unix Emulation V5.3(93)", 41))
*unix_type = UST_MULTINET;
}
else if (!strcasecmp (request, "WINDOWS_NT")
|| !strcasecmp (request, "WINDOWS2000"))
else if (!c_strcasecmp (request, "WINDOWS_NT")
|| !c_strcasecmp (request, "WINDOWS2000"))
*server_type = ST_WINNT;
else if (!strcasecmp (request, "MACOS"))
else if (!c_strcasecmp (request, "MACOS"))
*server_type = ST_MACOS;
else if (!strcasecmp (request, "OS/400"))
else if (!c_strcasecmp (request, "OS/400"))
*server_type = ST_OS400;
else
*server_type = ST_OTHER;
@@ -1135,7 +1250,7 @@ ftp_pwd (int csock, char **pwd)
goto err;
/* Has the `pwd' been already allocated? Free! */
xfree_null (*pwd);
xfree (*pwd);
*pwd = xstrdup (request);

View File

@@ -1,7 +1,7 @@
/* Parsing FTP `ls' output.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -42,6 +42,7 @@ as that of the covered work. */
#include "url.h"
#include "convert.h" /* for html_quote_string prototype */
#include "retr.h" /* for output_stream */
#include "c-strcase.h"
/* Converts symbolic permissions to number-style ones, e.g. string
rwxr-xr-x to 755. For now, it knows nothing of
@@ -121,7 +122,7 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
{
len = clean_line (line, len);
/* Skip if total... */
if (!strncasecmp (line, "total", 5))
if (!c_strncasecmp (line, "total", 5))
continue;
/* Get the first token (permissions). */
tok = strtok (line, " ");
@@ -166,12 +167,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
@@ -199,7 +200,7 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
if (next < 0) /* a month name was not encountered */
{
for (i = 0; i < 12; i++)
if (!strcasecmp (tok, months[i]))
if (!c_strcasecmp (tok, months[i]))
break;
/* If we got a month, it means the token before it is the
size, and the filename is three tokens away. */
@@ -362,8 +363,8 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
if (error || ignore)
{
DEBUGP (("Skipping.\n"));
xfree_null (cur.name);
xfree_null (cur.linkto);
xfree (cur.name);
xfree (cur.linkto);
continue;
}
@@ -477,6 +478,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));
@@ -775,14 +777,14 @@ ftp_parse_vms_ls (const char *file)
what will work in a CWD command.
*/
len = strlen (tok);
if (!strncasecmp((tok + (len - 4)), ".DIR", 4))
if (!c_strncasecmp((tok + (len - 4)), ".DIR", 4))
{
*(tok+ (len - 4)) = '\0'; /* Discard ".DIR". */
cur.type = FT_DIRECTORY;
cur.perms = VMS_DEFAULT_PROT_DIR;
DEBUGP (("Directory (nv)\n"));
}
else if (!strncasecmp ((tok + (len - 6)), ".DIR;1", 6))
else if (!c_strncasecmp ((tok + (len - 6)), ".DIR;1", 6))
{
*(tok+ (len - 6)) = '\0'; /* Discard ".DIR;1". */
cur.type = FT_DIRECTORY;
@@ -930,7 +932,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
{
@@ -1051,7 +1053,7 @@ Unsupported listing type, trying Unix listing parser.\n"));
return ftp_parse_unix_ls (file, 0);
}
}
/* Stuff for creating FTP index. */
/* The function creates an HTML index containing references to given
@@ -1088,7 +1090,7 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
else
upwd = concat_strings (tmpu, "@", (char *) 0);
xfree (tmpu);
xfree_null (tmpp);
xfree (tmpp);
}
else
upwd = xstrdup ("");

View File

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

604
src/ftp.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/* Declarations for FTP support.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -33,6 +33,7 @@ as that of the covered work. */
#define FTP_H
#include "host.h"
#include "url.h"
/* System types. */
enum stype
@@ -53,12 +54,27 @@ enum ustype
UST_OTHER
};
extern char ftp_last_respline[];
#ifdef HAVE_SSL
/* Data channel protection levels (to be used with PBSZ) */
enum prot_level
{
PROT_CLEAR = 'C',
PROT_SAFE = 'S',
PROT_CONFIDENTIAL = 'E',
PROT_PRIVATE = 'P'
};
#endif
uerr_t ftp_response (int, char **);
uerr_t ftp_greeting (int);
uerr_t ftp_login (int, const char *, const char *);
uerr_t ftp_port (int, int *);
uerr_t ftp_pasv (int, ip_address *, int *);
#ifdef HAVE_SSL
uerr_t ftp_auth (int, enum url_scheme);
uerr_t ftp_pbsz (int, int);
uerr_t ftp_prot (int, enum prot_level);
#endif
#ifdef ENABLE_IPV6
uerr_t ftp_lprt (int, int *);
uerr_t ftp_lpsv (int, ip_address *, int *);
@@ -144,15 +160,17 @@ enum wget_ftp_fstatus
AVOID_LIST = 0x0008, /* It tells us if during this
session we have to avoid to use
"LIST". */
LIST_AFTER_LIST_A_CHECK_DONE = 0x0010
LIST_AFTER_LIST_A_CHECK_DONE = 0x0010,
/* It tells us if we have already
checked "LIST" after the first
"LIST -a" to handle the case of
file/folders named "-a". */
DATA_CHANNEL_SECURITY = 0x0020 /* Establish a secure data channel */
};
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,272 +0,0 @@
/* Convenience header for conditional use of GNU <libintl.h>.
Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2004, 2005,
2006, 2009, 2010, 2011 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 the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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
Library General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA. */
#ifndef _LIBGETTEXT_H
#define _LIBGETTEXT_H 1
/* NLS can be disabled through the configure --disable-nls option. */
#if ENABLE_NLS
/* Get declarations of GNU message catalog functions. */
# include <libintl.h>
/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
the gettext() and ngettext() macros. This is an alternative to calling
textdomain(), and is useful for libraries. */
# ifdef DEFAULT_TEXT_DOMAIN
# undef gettext
# define gettext(Msgid) \
dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
# undef ngettext
# define ngettext(Msgid1, Msgid2, N) \
dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
# endif
#else
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
chokes if dcgettext is defined as a macro. So include it now, to make
later inclusions of <locale.h> a NOP. We don't include <libintl.h>
as well because people using "gettext.h" will not include <libintl.h>,
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
is OK. */
#if defined(__sun)
# include <locale.h>
#endif
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
<libintl.h>, which chokes if dcgettext is defined as a macro. So include
it now, to make later inclusions of <libintl.h> a NOP. */
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
# include <cstdlib>
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
# include <libintl.h>
# endif
#endif
/* Disabled NLS.
The casts to 'const char *' serve the purpose of producing warnings
for invalid uses of the value returned from these functions.
On pre-ANSI systems without 'const', the config.h file is supposed to
contain "#define const". */
# define gettext(Msgid) ((const char *) (Msgid))
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
# define dcgettext(Domainname, Msgid, Category) \
((void) (Category), dgettext (Domainname, Msgid))
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 \
? ((void) (Msgid2), (const char *) (Msgid1)) \
: ((void) (Msgid1), (const char *) (Msgid2)))
# define dngettext(Domainname, Msgid1, Msgid2, N) \
((void) (Domainname), ngettext (Msgid1, Msgid2, N))
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
# define textdomain(Domainname) ((const char *) (Domainname))
# define bindtextdomain(Domainname, Dirname) \
((void) (Domainname), (const char *) (Dirname))
# define bind_textdomain_codeset(Domainname, Codeset) \
((void) (Domainname), (const char *) (Codeset))
#endif
/* A pseudo function call that serves as a marker for the automated
extraction of messages, but does not call gettext(). The run-time
translation is done at a different place in the code.
The argument, String, should be a literal string. Concatenated strings
and other string expressions won't work.
The macro's expansion is not parenthesized, so that it is suitable as
initializer for static 'char[]' or 'const char[]' variables. */
#define gettext_noop(String) String
/* The separator between msgctxt and msgid in a .mo file. */
#define GETTEXT_CONTEXT_GLUE "\004"
/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
short and rarely need to change.
The letter 'p' stands for 'particular' or 'special'. */
#ifdef DEFAULT_TEXT_DOMAIN
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#else
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#endif
#define dpgettext(Domainname, Msgctxt, Msgid) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
#ifdef DEFAULT_TEXT_DOMAIN
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#else
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#endif
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
pgettext_aux (const char *domain,
const char *msg_ctxt_id, const char *msgid,
int category)
{
const char *translation = dcgettext (domain, msg_ctxt_id, category);
if (translation == msg_ctxt_id)
return msgid;
else
return translation;
}
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
npgettext_aux (const char *domain,
const char *msg_ctxt_id, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
const char *translation =
dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
if (translation == msg_ctxt_id || translation == msgid_plural)
return (n == 1 ? msgid : msgid_plural);
else
return translation;
}
/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
can be arbitrary expressions. But for string literals these macros are
less efficient than those above. */
#include <string.h>
#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
(((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
/* || __STDC_VERSION__ >= 199901L */ )
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
#include <stdlib.h>
#endif
#define pgettext_expr(Msgctxt, Msgid) \
dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
dcpgettext_expr (const char *domain,
const char *msgctxt, const char *msgid,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcgettext (domain, msg_ctxt_id, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
#endif
if (translation != msg_ctxt_id)
return translation;
}
return msgid;
}
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
dcnpgettext_expr (const char *domain,
const char *msgctxt, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
#endif
if (!(translation == msg_ctxt_id || translation == msgid_plural))
return translation;
}
return (n == 1 ? msgid : msgid_plural);
}
#endif /* _LIBGETTEXT_H */

View File

@@ -1,6 +1,6 @@
/* SSL support via GnuTLS library.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software
Foundation, Inc.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2015
Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -36,7 +36,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 +50,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"
@@ -56,6 +58,9 @@ as that of the covered work. */
#include "host.h"
static int
_do_handshake (gnutls_session_t session, int fd, double timeout);
static int
key_type_to_gnutls_type (enum keyfile_type type)
{
@@ -122,9 +127,10 @@ ssl_init (void)
while ((dent = readdir (dir)) != NULL)
{
struct stat st;
char ca_file[dirlen + strlen(dent->d_name) + 2];
size_t ca_file_length = dirlen + strlen(dent->d_name) + 2;
char *ca_file = alloca(ca_file_length);
snprintf (ca_file, sizeof(ca_file), "%s/%s", ca_directory, dent->d_name);
snprintf (ca_file, ca_file_length, "%s/%s", ca_directory, dent->d_name);
if (stat (ca_file, &st) != 0)
continue;
@@ -138,8 +144,7 @@ ssl_init (void)
hash_table_put (inode_map, (void *)(intptr_t) st.st_ino, NULL);
if ((rc = gnutls_certificate_set_x509_trust_file (credentials, ca_file,
GNUTLS_X509_FMT_PEM)) <= 0)
logprintf (LOG_NOTQUIET, _("ERROR: Failed to open cert %s: (%d).\n"),
ca_file, rc);
DEBUGP (("WARNING: Failed to open cert %s: (%d).\n", ca_file, rc));
else
ncerts += rc;
}
@@ -149,18 +154,48 @@ ssl_init (void)
}
}
if (opt.ca_cert)
{
int rc;
ncerts = 0;
if ((rc = gnutls_certificate_set_x509_trust_file (credentials, opt.ca_cert,
GNUTLS_X509_FMT_PEM)) <= 0)
logprintf (LOG_NOTQUIET, _ ("ERROR: Failed to open cert %s: (%d).\n"),
opt.ca_cert, rc);
else
{
ncerts += rc;
logprintf (LOG_NOTQUIET, _ ("Loaded CA certificate '%s'\n"), opt.ca_cert);
}
}
if (opt.crl_file)
{
int rc;
if ((rc = gnutls_certificate_set_x509_crl_file (credentials, opt.crl_file, GNUTLS_X509_FMT_PEM)) <= 0)
{
logprintf (LOG_NOTQUIET, _("ERROR: Failed to load CRL file '%s': (%d)\n"), opt.crl_file, rc);
return false;
}
logprintf (LOG_NOTQUIET, _ ("Loaded CRL file '%s'\n"), opt.crl_file);
}
DEBUGP (("Certificates loaded: %d\n", ncerts));
/* Use the private key from the cert file unless otherwise specified. */
if (opt.cert_file && !opt.private_key)
{
opt.private_key = opt.cert_file;
opt.private_key = xstrdup (opt.cert_file);
opt.private_key_type = opt.cert_type;
}
/* Use the cert from the private key file unless otherwise specified. */
if (!opt.cert_file && opt.private_key)
{
opt.cert_file = opt.private_key;
opt.cert_file = xstrdup (opt.private_key);
opt.cert_type = opt.private_key_type;
}
@@ -181,10 +216,6 @@ cert to be of the same type.\n"));
type);
}
if (opt.ca_cert)
gnutls_certificate_set_x509_trust_file (credentials, opt.ca_cert,
GNUTLS_X509_FMT_PEM);
ssl_initialized = true;
return true;
@@ -193,6 +224,7 @@ cert to be of the same type.\n"));
struct wgnutls_transport_context
{
gnutls_session_t session; /* GnuTLS session handle */
gnutls_datum_t *session_data;
int last_error; /* last error returned by read/write/... */
/* Since GnuTLS doesn't support the equivalent to recv(...,
@@ -203,11 +235,6 @@ struct wgnutls_transport_context
int peeklen;
};
#ifndef MIN
# define MIN(i, j) ((i) <= (j) ? (i) : (j))
#endif
static int
wgnutls_read_timeout (int fd, char *buf, int bufsize, void *arg, double timeout)
{
@@ -255,6 +282,12 @@ wgnutls_read_timeout (int fd, char *buf, int bufsize, void *arg, double timeout)
{
ret = gnutls_record_recv (ctx->session, buf, bufsize);
timed_out = timeout && ptimer_measure (timer) >= timeout;
if (!timed_out && ret == GNUTLS_E_REHANDSHAKE)
{
DEBUGP (("GnuTLS: *** REHANDSHAKE while reading\n"));
if ((ret = _do_handshake (ctx->session, fd, timeout)) == 0)
ret = GNUTLS_E_AGAIN; /* restart reading */
}
}
}
while (ret == GNUTLS_E_INTERRUPTED || (ret == GNUTLS_E_AGAIN && !timed_out));
@@ -384,6 +417,11 @@ wgnutls_close (int fd, void *arg)
{
struct wgnutls_transport_context *ctx = arg;
/*gnutls_bye (ctx->session, GNUTLS_SHUT_RDWR);*/
if (ctx->session_data)
{
gnutls_free (ctx->session_data->data);
gnutls_free (ctx->session_data);
}
gnutls_deinit (ctx->session);
xfree (ctx);
close (fd);
@@ -398,90 +436,15 @@ static struct transport_implementation wgnutls_transport =
wgnutls_peek, wgnutls_errstr, wgnutls_close
};
bool
ssl_connect_wget (int fd, const char *hostname)
static int
_do_handshake (gnutls_session_t session, int fd, double timeout)
{
#ifdef F_GETFL
int flags = 0;
#endif
struct wgnutls_transport_context *ctx;
gnutls_session_t session;
int err,alert;
gnutls_init (&session, GNUTLS_CLIENT);
const char *str;
int err;
/* 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_set_default_priority (session);
gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, credentials);
#ifndef FD_TO_SOCKET
# define FD_TO_SOCKET(X) (X)
#endif
#ifdef HAVE_INTPTR_T
gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) (intptr_t) FD_TO_SOCKET (fd));
#else
gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) FD_TO_SOCKET (fd));
#endif
err = 0;
#if HAVE_GNUTLS_PRIORITY_SET_DIRECT
switch (opt.secure_protocol)
{
case secure_protocol_auto:
break;
case secure_protocol_sslv2:
case secure_protocol_sslv3:
err = gnutls_priority_set_direct (session, "NORMAL:-VERS-TLS-ALL:+VERS-SSL3.0", NULL);
break;
case secure_protocol_tlsv1:
err = gnutls_priority_set_direct (session, "NORMAL:-VERS-SSL3.0", NULL);
break;
case secure_protocol_pfs:
err = gnutls_priority_set_direct (session, "PFS", NULL);
if (err != GNUTLS_E_SUCCESS)
/* fallback if PFS is not available */
err = gnutls_priority_set_direct (session, "NORMAL:-RSA", NULL);
break;
default:
abort ();
}
#else
int allowed_protocols[4] = {0, 0, 0, 0};
switch (opt.secure_protocol)
{
case secure_protocol_auto:
break;
case secure_protocol_sslv2:
case secure_protocol_sslv3:
allowed_protocols[0] = GNUTLS_SSL3;
err = gnutls_protocol_set_priority (session, allowed_protocols);
break;
case secure_protocol_tlsv1:
allowed_protocols[0] = GNUTLS_TLS1_0;
allowed_protocols[1] = GNUTLS_TLS1_1;
allowed_protocols[2] = GNUTLS_TLS1_2;
err = gnutls_protocol_set_priority (session, allowed_protocols);
break;
default:
abort ();
}
#endif
if (err < 0)
{
logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err));
gnutls_deinit (session);
return false;
}
if (opt.connect_timeout)
if (timeout)
{
#ifdef F_GETFL
flags = fcntl (fd, F_GETFL, 0);
@@ -502,17 +465,17 @@ ssl_connect_wget (int fd, const char *hostname)
{
err = gnutls_handshake (session);
if (opt.connect_timeout && err == GNUTLS_E_AGAIN)
if (timeout && err == GNUTLS_E_AGAIN)
{
if (gnutls_record_get_direction (session))
{
/* wait for writeability */
err = select_fd (fd, opt.connect_timeout, WAIT_FOR_WRITE);
err = select_fd (fd, timeout, WAIT_FOR_WRITE);
}
else
{
/* wait for readability */
err = select_fd (fd, opt.connect_timeout, WAIT_FOR_READ);
err = select_fd (fd, timeout, WAIT_FOR_READ);
}
if (err <= 0)
@@ -533,17 +496,16 @@ ssl_connect_wget (int fd, const char *hostname)
if (err == GNUTLS_E_WARNING_ALERT_RECEIVED ||
err == GNUTLS_E_FATAL_ALERT_RECEIVED)
{
alert = gnutls_alert_get (session);
str = gnutls_alert_get_name (alert);
if (str == NULL)
str = "(unknown)";
logprintf (LOG_NOTQUIET, "GnuTLS: received alert [%d]: %s\n", alert, str);
gnutls_alert_description_t alert = gnutls_alert_get (session);
const char *str = gnutls_alert_get_name (alert);
logprintf (LOG_NOTQUIET, "GnuTLS: received alert [%u]: %s\n",
alert, str ? str : "(unknown)");
}
}
}
while (err && gnutls_error_is_fatal (err) == 0);
if (opt.connect_timeout)
if (timeout)
{
#ifdef F_GETFL
if (fcntl (fd, F_SETFL, flags) < 0)
@@ -555,6 +517,166 @@ ssl_connect_wget (int fd, const char *hostname)
#endif
}
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)
{
struct wgnutls_transport_context *ctx;
gnutls_session_t session;
int err;
gnutls_init (&session, GNUTLS_CLIENT);
/* We set the server name but only if it's not an IP address. */
if (! is_valid_ip_address (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_credentials_set (session, GNUTLS_CRD_CERTIFICATE, credentials);
#ifndef FD_TO_SOCKET
# define FD_TO_SOCKET(X) (X)
#endif
#ifdef HAVE_INTPTR_T
gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) (intptr_t) FD_TO_SOCKET (fd));
#else
gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) FD_TO_SOCKET (fd));
#endif
#if HAVE_GNUTLS_PRIORITY_SET_DIRECT
switch (opt.secure_protocol)
{
case secure_protocol_auto:
err = gnutls_set_default_priority (session);
gnutls_session_enable_compatibility_mode(session);
break;
case secure_protocol_sslv2:
case secure_protocol_sslv3:
err = gnutls_priority_set_direct (session, "NORMAL:-VERS-TLS-ALL:+VERS-SSL3.0", NULL);
break;
case secure_protocol_tlsv1:
err = gnutls_priority_set_direct (session, "NORMAL:-VERS-SSL3.0", NULL);
break;
case secure_protocol_tlsv1_1:
err = gnutls_priority_set_direct (session, "NORMAL:-VERS-SSL3.0:-VERS-TLS1.0", NULL);
break;
case secure_protocol_tlsv1_2:
err = gnutls_priority_set_direct (session, "NORMAL:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1", NULL);
break;
case secure_protocol_pfs:
err = gnutls_priority_set_direct (session, "PFS:-VERS-SSL3.0", NULL);
if (err != GNUTLS_E_SUCCESS)
/* fallback if PFS is not available */
err = gnutls_priority_set_direct (session, "NORMAL:-RSA:-VERS-SSL3.0", NULL);
break;
default:
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 ();
}
#else
int allowed_protocols[4] = {0, 0, 0, 0};
switch (opt.secure_protocol)
{
case secure_protocol_auto:
err = gnutls_set_default_priority (session);
break;
case secure_protocol_sslv2:
case secure_protocol_sslv3:
allowed_protocols[0] = GNUTLS_SSL3;
err = gnutls_protocol_set_priority (session, allowed_protocols);
break;
case secure_protocol_tlsv1:
allowed_protocols[0] = GNUTLS_TLS1_0;
allowed_protocols[1] = GNUTLS_TLS1_1;
allowed_protocols[2] = GNUTLS_TLS1_2;
err = gnutls_protocol_set_priority (session, allowed_protocols);
break;
case secure_protocol_tlsv1_1:
allowed_protocols[0] = GNUTLS_TLS1_1;
allowed_protocols[1] = GNUTLS_TLS1_2;
err = gnutls_protocol_set_priority (session, allowed_protocols);
break;
case secure_protocol_tlsv1_2:
allowed_protocols[0] = GNUTLS_TLS1_2;
err = gnutls_protocol_set_priority (session, allowed_protocols);
break;
default:
logprintf (LOG_NOTQUIET, _("GnuTLS: unimplemented 'secure-protocol' option value %d\n"), opt.secure_protocol);
logprintf (LOG_NOTQUIET, _("Please report this issue to bug-wget@gnu.org\n"));
abort ();
}
#endif
if (err < 0)
{
logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err));
gnutls_deinit (session);
return false;
}
if (continue_session)
{
ctx = (struct wgnutls_transport_context *) fd_transport_context (*continue_session);
if (!gnutls_session_is_resumed (session))
{
if (!ctx || !ctx->session_data || gnutls_session_set_data (session, ctx->session_data->data, ctx->session_data->size))
{
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;
}
}
else
{
logputs (LOG_ALWAYS, "SSL session has already been resumed. Continuing.\n");
continue_session = NULL;
}
}
err = _do_handshake (session, fd, opt.connect_timeout);
if (err < 0)
{
gnutls_deinit (session);
@@ -562,11 +684,70 @@ ssl_connect_wget (int fd, const char *hostname)
}
ctx = xnew0 (struct wgnutls_transport_context);
ctx->session_data = xnew0 (gnutls_datum_t);
ctx->session = session;
if (gnutls_session_get_data2 (session, ctx->session_data))
{
xfree (ctx->session_data);
logprintf (LOG_NOTQUIET, "WARNING: Could not save SSL session data for socket %d\n", fd);
}
fd_register_transport (fd, &wgnutls_transport, ctx);
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))\
{\
@@ -587,6 +768,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)
@@ -611,6 +797,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)
{
@@ -645,13 +832,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);
}
@@ -662,5 +859,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,6 @@
/* Hash tables.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 2011 Free Software Foundation, Inc.
2009, 2010, 2011, 2015 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -46,10 +46,11 @@ as that of the covered work. */
# include "utils.h"
#else
/* Make do without them. */
# define xnew(x) xmalloc (sizeof (x))
# define xnew_array(type, x) xmalloc (sizeof (type) * (x))
# define xmalloc malloc
# define xfree free
# define xnew(type) (xmalloc (sizeof (type)))
# define xnew0(type) (xcalloc (1, sizeof (type)))
# define xnew_array(type, len) (xmalloc ((len) * sizeof (type)))
# define xfree(p) do { free ((void *) (p)); p = NULL; } while (0)
# ifndef countof
# define countof(x) (sizeof (x) / sizeof ((x)[0]))
# endif
@@ -282,10 +283,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);
@@ -393,7 +394,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));
@@ -585,7 +586,7 @@ hash_table_count (const struct hash_table *ht)
{
return ht->count;
}
/* Functions from this point onward are meant for convenience and
don't strictly belong to this file. However, this is as good a
place for them as any. */
@@ -740,7 +741,7 @@ cmp_pointer (const void *ptr1, const void *ptr2)
{
return ptr1 == ptr2;
}
#ifdef TEST
#include <stdio.h>

View File

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

View File

@@ -1,7 +1,7 @@
/* Host name resolution and matching.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -57,10 +57,15 @@ as that of the covered work. */
#include <errno.h>
#ifdef ENABLE_IRI
#include <idn2.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
@@ -151,6 +156,13 @@ address_list_set_faulty (struct address_list *al, int index)
"faulty" attempt is always preceded with all-faulty addresses,
and this is how Wget uses it. */
assert (index == al->faulty);
if (index != al->faulty)
{
logprintf (LOG_ALWAYS, "index: %d\nal->faulty: %d\n", index, al->faulty);
logprintf (LOG_ALWAYS, _("Error in handling the address list.\n"));
logprintf (LOG_ALWAYS, _("Please report this issue to bug-wget@gnu.org\n"));
abort();
}
++al->faulty;
if (al->faulty >= al->count)
@@ -309,7 +321,7 @@ address_list_release (struct address_list *al)
address_list_delete (al);
}
}
/* Versions of gethostbyname and getaddrinfo that support timeout. */
#ifndef ENABLE_IPV6
@@ -408,7 +420,7 @@ getaddrinfo_with_timeout (const char *node, const char *service,
}
#endif /* ENABLE_IPV6 */
/* Return a textual representation of ADDR, i.e. the dotted quad for
IPv4 addresses, and the colon-separated list of hex words (with all
zeros omitted, etc.) for IPv6 addresses. */
@@ -416,14 +428,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
@@ -570,7 +580,7 @@ is_valid_ipv6_address (const char *str, const char *end)
return true;
}
/* Simple host cache, used by lookup_host to speed up resolving. The
cache doesn't handle TTL because Wget is a fairly short-lived
application. Refreshing is attempted when connect fails, though --
@@ -592,7 +602,7 @@ cache_query (const char *host)
al = hash_table_get (host_name_addresses_map, host);
if (al)
{
DEBUGP (("Found %s in host_name_addresses_map (%p)\n", host, al));
DEBUGP (("Found %s in host_name_addresses_map (%p)\n", host, (void *) al));
++al->refcount;
return al;
}
@@ -637,7 +647,113 @@ cache_remove (const char *host)
hash_table_remove (host_name_addresses_map, 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
@@ -734,91 +850,122 @@ lookup_host (const char *host, int flags)
str = xmalloc (len);
snprintf (str, len, "%s (%s)", name, host);
str[len-1] = '\0';
xfree (name);
idn2_free (name);
}
logprintf (LOG_VERBOSE, _("Resolving %s... "),
quotearg_style (escape_quoting_style, str ? str : host));
if (str)
xfree (str);
xfree (str);
}
#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
@@ -848,7 +995,7 @@ lookup_host (const char *host, int flags)
return al;
}
/* Determine whether a URL is acceptable to be followed, according to
a list of domains to accept. */
bool

View File

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

828
src/hsts.c Normal file
View File

@@ -0,0 +1,828 @@
/* 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.
This file is part of GNU Wget.
GNU Wget is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
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 Wget. If not, see <http://www.gnu.org/licenses/>.
Additional permission under GNU GPL version 3 section 7
If you modify this program, or any covered work, by linking or
combining it with the OpenSSL project's OpenSSL library (or a
modified version of that library), containing parts covered by the
terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
grants you additional permission to convey the resulting work.
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. */
#include "wget.h"
#ifdef HAVE_HSTS
#include "hsts.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
#include "test.h"
#endif
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <sys/file.h>
struct hsts_store {
struct hash_table *table;
time_t last_mtime;
bool changed;
};
struct hsts_kh {
char *host;
int explicit_port;
};
struct hsts_kh_info {
time_t created;
time_t max_age;
bool include_subdomains;
};
enum hsts_kh_match {
NO_MATCH,
SUPERDOMAIN_MATCH,
CONGRUENT_MATCH
};
#define hsts_is_host_name_valid(host) (!is_valid_ip_address (host))
#define hsts_is_scheme_valid(scheme) (scheme == SCHEME_HTTPS)
#define hsts_is_host_eligible(scheme, host) \
(hsts_is_scheme_valid (scheme) && hsts_is_host_name_valid (host))
#define DEFAULT_HTTP_PORT 80
#define DEFAULT_SSL_PORT 443
#define MAKE_EXPLICIT_PORT(s, p) (s == SCHEME_HTTPS ? (p == DEFAULT_SSL_PORT ? 0 : p) \
: (p == DEFAULT_HTTP_PORT ? 0 : p))
/* Hashing and comparison functions for the hash table */
static unsigned long
hsts_hash_func (const void *key)
{
struct hsts_kh *k = (struct hsts_kh *) key;
const char *h = NULL;
unsigned int hash = k->explicit_port;
for (h = k->host; *h; h++)
hash = hash * 31 + *h;
return hash;
}
static int
hsts_cmp_func (const void *h1, const void *h2)
{
struct hsts_kh *kh1 = (struct hsts_kh *) h1,
*kh2 = (struct hsts_kh *) h2;
return (!strcmp (kh1->host, kh2->host)) && (kh1->explicit_port == kh2->explicit_port);
}
/* Private functions. Feel free to make some of these public when needed. */
static struct hsts_kh_info *
hsts_find_entry (hsts_store_t store,
const char *host, int explicit_port,
enum hsts_kh_match *match_type,
struct hsts_kh *kh)
{
struct hsts_kh *k = NULL;
struct hsts_kh_info *khi = NULL;
enum hsts_kh_match match = NO_MATCH;
char *pos = NULL;
char *org_ptr = NULL;
k = (struct hsts_kh *) xnew (struct hsts_kh);
k->host = xstrdup_lower (host);
k->explicit_port = explicit_port;
/* save pointer so that we don't get into trouble later when freeing */
org_ptr = k->host;
khi = (struct hsts_kh_info *) hash_table_get (store->table, k);
if (khi)
{
match = CONGRUENT_MATCH;
goto end;
}
while (match == NO_MATCH &&
(pos = strchr (k->host, '.')) && pos - k->host > 0 &&
strchr (pos + 1, '.'))
{
k->host += (pos - k->host + 1);
khi = (struct hsts_kh_info *) hash_table_get (store->table, k);
if (khi)
match = SUPERDOMAIN_MATCH;
}
end:
/* restore pointer or we'll get a SEGV */
k->host = org_ptr;
/* 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;
}
static bool
hsts_new_entry_internal (hsts_store_t store,
const char *host, int port,
time_t created, time_t max_age,
bool include_subdomains,
bool check_validity,
bool check_expired,
bool check_duplicates)
{
struct hsts_kh *kh = xnew (struct hsts_kh);
struct hsts_kh_info *khi = xnew0 (struct hsts_kh_info);
bool success = false;
kh->host = xstrdup_lower (host);
kh->explicit_port = MAKE_EXPLICIT_PORT (SCHEME_HTTPS, port);
khi->created = created;
khi->max_age = max_age;
khi->include_subdomains = include_subdomains;
/* Check validity */
if (check_validity && !hsts_is_host_name_valid (host))
goto bail;
if (check_expired && ((khi->created + khi->max_age) < khi->created))
goto bail;
if (check_duplicates && hash_table_contains (store->table, kh))
goto bail;
/* Now store the new entry */
hash_table_put (store->table, kh, khi);
success = true;
bail:
if (!success)
{
/* abort! */
xfree (kh->host);
xfree (kh);
xfree (khi);
}
return success;
}
/*
Creates a new entry, but does not check whether that entry already exists.
This function assumes that check has already been done by the caller.
*/
static bool
hsts_add_entry (hsts_store_t store,
const char *host, int port,
time_t max_age, bool include_subdomains)
{
time_t t = time (NULL);
/* It might happen time() returned -1 */
return (t < 0 ?
false :
hsts_new_entry_internal (store, host, port, t, max_age, include_subdomains, false, true, false));
}
/* Creates a new entry, unless an identical one already exists. */
static bool
hsts_new_entry (hsts_store_t store,
const char *host, int port,
time_t created, time_t max_age,
bool include_subdomains)
{
return hsts_new_entry_internal (store, host, port, created, max_age, include_subdomains, true, true, true);
}
static void
hsts_remove_entry (hsts_store_t store, struct hsts_kh *kh)
{
hash_table_remove (store->table, kh);
}
static bool
hsts_store_merge (hsts_store_t store,
const char *host, int port,
time_t created, time_t max_age,
bool include_subdomains)
{
enum hsts_kh_match match_type = NO_MATCH;
struct hsts_kh_info *khi = NULL;
bool success = false;
port = MAKE_EXPLICIT_PORT (SCHEME_HTTPS, port);
khi = hsts_find_entry (store, host, port, &match_type, NULL);
if (khi && match_type == CONGRUENT_MATCH && created > khi->created)
{
/* update the entry with the new info */
khi->created = created;
khi->max_age = max_age;
khi->include_subdomains = include_subdomains;
success = true;
}
else if (!khi)
success = hsts_new_entry (store, host, port, created, max_age, include_subdomains);
return success;
}
static bool
hsts_read_database (hsts_store_t store, FILE *fp, bool merge_with_existing_entries)
{
char *line = NULL, *p;
size_t len = 0;
int items_read;
bool result = false;
bool (*func)(hsts_store_t, const char *, int, time_t, time_t, bool);
char host[256];
int port;
time_t created, max_age;
int include_subdomains;
func = (merge_with_existing_entries ? hsts_store_merge : hsts_new_entry);
while (getline (&line, &len, fp) > 0)
{
for (p = line; c_isspace (*p); p++)
;
if (*p == '#')
continue;
items_read = sscanf (p, "%255s %d %d %lu %lu",
host,
&port,
&include_subdomains,
(unsigned long *) &created,
(unsigned long *) &max_age);
if (items_read == 5)
func (store, host, port, created, max_age, !!include_subdomains);
}
xfree (line);
result = true;
return result;
}
static void
hsts_store_dump (hsts_store_t store, FILE *fp)
{
hash_table_iterator it;
/* 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>\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);)
{
struct hsts_kh *kh = (struct hsts_kh *) it.key;
struct hsts_kh_info *khi = (struct hsts_kh_info *) it.value;
if (fprintf (fp, "%s\t%d\t%d\t%lu\t%lu\n",
kh->host, kh->explicit_port, khi->include_subdomains,
(unsigned long) khi->created,
(unsigned long) khi->max_age) < 0)
{
logprintf (LOG_ALWAYS, "Could not write the HSTS database correctly.\n");
break;
}
}
}
/*
* 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 */
/*
Changes the given URLs according to the HSTS policy.
If there's no host in the store that either congruently
or not, matches the given URL, no changes are made.
Returns true if the URL was changed, or false
if it was left intact.
*/
bool
hsts_match (hsts_store_t store, struct url *u)
{
bool url_changed = false;
struct hsts_kh_info *entry = NULL;
struct hsts_kh *kh = xnew(struct hsts_kh);
enum hsts_kh_match match = NO_MATCH;
int port = MAKE_EXPLICIT_PORT (u->scheme, u->port);
/* avoid doing any computation if we're already in HTTPS */
if (!hsts_is_scheme_valid (u->scheme))
{
entry = hsts_find_entry (store, u->host, port, &match, kh);
if (entry)
{
if ((entry->created + entry->max_age) >= time(NULL))
{
if ((match == CONGRUENT_MATCH) ||
(match == SUPERDOMAIN_MATCH && entry->include_subdomains))
{
/* we found a matching Known HSTS Host
rewrite the URL */
u->scheme = SCHEME_HTTPS;
if (u->port == 80)
u->port = 443;
url_changed = true;
store->changed = true;
}
}
else
{
hsts_remove_entry (store, kh);
store->changed = true;
}
}
xfree (kh->host);
}
xfree (kh);
return url_changed;
}
/*
Add a new HSTS Known Host to the HSTS store.
If the host already exists, its information is updated,
or it'll be removed from the store if max_age is zero.
Bear in mind that the store is kept in memory, and will not
be written to disk until hsts_store_save is called.
This function regrows the in-memory HSTS store if necessary.
Currently, for a host to be taken into consideration,
two conditions have to be met:
- Connection must be through a secure channel (HTTPS).
- The host must not be an IPv4 or IPv6 address.
The RFC 6797 states that hosts that match IPv4 or IPv6 format
should be discarded at URI rewrite time. But we short-circuit
that check here, since there's no point in storing a host that
will never be matched.
Returns true if a new entry was actually created, or false
if an existing entry was updated/deleted. */
bool
hsts_store_entry (hsts_store_t store,
enum url_scheme scheme, const char *host, int port,
time_t max_age, bool include_subdomains)
{
bool result = false;
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))
{
port = MAKE_EXPLICIT_PORT (scheme, port);
entry = hsts_find_entry (store, host, port, &match, kh);
if (entry && match == CONGRUENT_MATCH)
{
if (max_age == 0)
{
hsts_remove_entry (store, kh);
store->changed = true;
}
else if (max_age > 0)
{
if (entry->max_age != max_age ||
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 */
t = time (NULL);
if (t != -1)
entry->created = t;
entry->max_age = max_age;
entry->include_subdomains = include_subdomains;
store->changed = true;
}
}
/* we ignore negative max_ages */
}
else if (entry == NULL || match == SUPERDOMAIN_MATCH)
{
/* Either we didn't find a matching host,
or we got a superdomain match.
In either case, we create a new entry.
We have to perform an explicit check because it might
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);
return result;
}
hsts_store_t
hsts_store_open (const char *filename)
{
hsts_store_t store = NULL;
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 (hsts_file_access_valid (filename))
{
struct stat st;
FILE *fp = fopen (filename, "r");
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");
}
}
out:
return store;
}
void
hsts_store_save (hsts_store_t store, const char *filename)
{
struct stat st;
FILE *fp = NULL;
int fd = 0;
if (filename && hash_table_count (store->table) > 0)
{
fp = fopen (filename, "a+");
if (fp)
{
/* Lock the file to avoid potential race conditions */
fd = fileno (fp);
flock (fd, LOCK_EX);
/* If the file has changed, merge the changes with our in-memory data
before dumping them to the file.
Otherwise we could potentially overwrite the data stored by other Wget processes.
*/
if (store->last_mtime && stat (filename, &st) == 0 && st.st_mtime > store->last_mtime)
hsts_read_database (store, fp, true);
/* We've merged the latest changes so we can now truncate the file
and dump everything. */
fseek (fp, 0, SEEK_SET);
ftruncate (fd, 0);
/* now dump to the file */
hsts_store_dump (store, fp);
/* fclose is expected to unlock the file for us */
fclose (fp);
}
}
}
bool
hsts_store_has_changed (hsts_store_t store)
{
return (store ? store->changed : false);
}
void
hsts_store_close (hsts_store_t store)
{
hash_table_iterator it;
/* free all the host fields */
for (hash_table_iterate (store->table, &it); hash_table_iter_next (&it);)
{
xfree (((struct hsts_kh *) it.key)->host);
xfree (it.key);
xfree (it.value);
}
hash_table_destroy (store->table);
}
#ifdef TESTING
/* I know I'm really evil because I'm writing macros
that change control flow. But we're testing, who will tell? :D
*/
#define TEST_URL_RW(s, u, p) do { \
if (test_url_rewrite (s, u, p, true)) \
return test_url_rewrite (s, u, p, true); \
} while (0)
#define TEST_URL_NORW(s, u, p) do { \
if (test_url_rewrite (s, u, p, false)) \
return test_url_rewrite (s, u, p, false); \
} while (0)
static char *
get_hsts_store_filename (void)
{
char *home = NULL, *filename = NULL;
FILE *fp = NULL;
home = home_dir ();
if (home)
{
filename = aprintf ("%s/.wget-hsts-test", home);
fp = fopen (filename, "w");
if (fp)
fclose (fp);
}
xfree (home);
return filename;
}
static hsts_store_t
open_hsts_test_store (void)
{
char *filename = NULL;
hsts_store_t table = NULL;
filename = get_hsts_store_filename ();
table = hsts_store_open (filename);
xfree (filename);
return table;
}
static void
close_hsts_test_store (hsts_store_t store)
{
char *filename = NULL;
filename = get_hsts_store_filename ();
unlink (filename);
xfree (filename);
xfree (store);
}
static const char*
test_url_rewrite (hsts_store_t s, const char *url, int port, bool rewrite)
{
bool result;
struct url u;
u.host = xstrdup (url);
u.port = port;
u.scheme = SCHEME_HTTP;
result = hsts_match (s, &u);
if (rewrite)
{
if (port == 80)
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);
mu_assert("result should've been true", result == true);
}
else
{
mu_assert("URL: port should've been left intact", u.port == port);
mu_assert("URL: scheme should've been left intact", u.scheme == SCHEME_HTTP);
mu_assert("result should've been false", result == false);
}
xfree (u.host);
return NULL;
}
const char *
test_hsts_new_entry (void)
{
enum hsts_kh_match match = NO_MATCH;
struct hsts_kh_info *khi;
hsts_store_t s;
bool created;
s = open_hsts_test_store ();
mu_assert("Could not open the HSTS store. This could be due to lack of memory.", s != NULL);
created = hsts_store_entry (s, SCHEME_HTTP, "www.foo.com", 80, 1234, true);
mu_assert("No entry should have been created.", created == false);
created = hsts_store_entry (s, SCHEME_HTTPS, "www.foo.com", 443, 1234, true);
mu_assert("A new entry should have been created", created == true);
khi = hsts_find_entry (s, "www.foo.com", MAKE_EXPLICIT_PORT (SCHEME_HTTPS, 443), &match, NULL);
mu_assert("Should've been a congruent match", match == CONGRUENT_MATCH);
mu_assert("No valid HSTS info was returned", khi != NULL);
mu_assert("Variable 'max_age' should be 1234", khi->max_age == 1234);
mu_assert("Variable 'include_subdomains' should be asserted", khi->include_subdomains == true);
khi = hsts_find_entry (s, "b.www.foo.com", MAKE_EXPLICIT_PORT (SCHEME_HTTPS, 443), &match, NULL);
mu_assert("Should've been a superdomain match", match == SUPERDOMAIN_MATCH);
mu_assert("No valid HSTS info was returned", khi != NULL);
mu_assert("Variable 'max_age' should be 1234", khi->max_age == 1234);
mu_assert("Variable 'include_subdomains' should be asserted", khi->include_subdomains == true);
khi = hsts_find_entry (s, "ww.foo.com", MAKE_EXPLICIT_PORT (SCHEME_HTTPS, 443), &match, NULL);
mu_assert("Should've been no match", match == NO_MATCH);
khi = hsts_find_entry (s, "foo.com", MAKE_EXPLICIT_PORT (SCHEME_HTTPS, 443), &match, NULL);
mu_assert("Should've been no match", match == NO_MATCH);
khi = hsts_find_entry (s, ".foo.com", MAKE_EXPLICIT_PORT (SCHEME_HTTPS, 443), &match, NULL);
mu_assert("Should've been no match", match == NO_MATCH);
khi = hsts_find_entry (s, ".www.foo.com", MAKE_EXPLICIT_PORT (SCHEME_HTTPS, 443), &match, NULL);
mu_assert("Should've been no match", match == NO_MATCH);
hsts_store_close (s);
close_hsts_test_store (s);
return NULL;
}
const char*
test_hsts_url_rewrite_superdomain (void)
{
hsts_store_t s;
bool created;
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, 1234, true);
mu_assert("A new entry should've been created", created == true);
TEST_URL_RW (s, "www.foo.com", 80);
TEST_URL_RW (s, "bar.www.foo.com", 80);
hsts_store_close (s);
close_hsts_test_store (s);
return NULL;
}
const char*
test_hsts_url_rewrite_congruent (void)
{
hsts_store_t s;
bool created;
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, 1234, false);
mu_assert("A new entry should've been created", created == true);
TEST_URL_RW (s, "foo.com", 80);
TEST_URL_NORW (s, "www.foo.com", 80);
hsts_store_close (s);
close_hsts_test_store (s);
return NULL;
}
const char*
test_hsts_read_database (void)
{
hsts_store_t table;
char *home = home_dir();
char *file = NULL;
FILE *fp = NULL;
time_t created = time(NULL) - 10;
if (home)
{
file = aprintf ("%s/.wget-hsts-testing", home);
fp = fopen (file, "w");
if (fp)
{
fputs ("# dummy comment\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);
TEST_URL_RW (table, "foo.example.com", 80);
TEST_URL_RW (table, "www.foo.example.com", 80);
TEST_URL_RW (table, "bar.example.com", 80);
TEST_URL_NORW(table, "www.bar.example.com", 80);
TEST_URL_RW (table, "test.example.com", 8080);
hsts_store_close (table);
close_hsts_test_store (table);
unlink (file);
}
xfree (file);
xfree (home);
}
return NULL;
}
#endif /* TESTING */
#endif /* HAVE_HSTS */

54
src/hsts.h Normal file
View File

@@ -0,0 +1,54 @@
/* 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.
This file is part of GNU Wget.
GNU Wget is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
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 Wget. If not, see <http://www.gnu.org/licenses/>.
Additional permission under GNU GPL version 3 section 7
If you modify this program, or any covered work, by linking or
combining it with the OpenSSL project's OpenSSL library (or a
modified version of that library), containing parts covered by the
terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
grants you additional permission to convey the resulting work.
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. */
#include "wget.h"
#ifdef HAVE_HSTS
#ifndef HSTS_H
#define HSTS_H
#include "url.h"
typedef struct hsts_store *hsts_store_t;
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,
time_t, bool);
bool hsts_match (hsts_store_t, struct url *);
#endif /* HSTS_H */
#endif /* HAVE_HSTS */

View File

@@ -1,6 +1,6 @@
/* HTML parser for Wget.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
2007, 2008, 2009, 2010, 2011, 2015 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -253,7 +253,7 @@ struct pool {
(sizevar) = ga_newsize; \
} \
} while (0)
/* Test whether n+1-sized entity name fits in P. We don't support
IE-style non-terminated entities, e.g. "&ltfoo" -> "<foo".
However, "&lt;foo" will work, as will "&lt!foo", "&lt", etc. In
@@ -517,7 +517,7 @@ convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags
*p = c_tolower (*p);
}
}
/* Originally we used to adhere to rfc 1866 here, and allowed only
letters, digits, periods, and hyphens as names (of tags or
attributes). However, this broke too many pages which used
@@ -770,7 +770,7 @@ find_comment_end (const char *beg, const char *end)
}
return NULL;
}
/* Return true if the string containing of characters inside [b, e) is
present in hash table HT. */
@@ -801,14 +801,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
@@ -881,7 +873,7 @@ map_html_tags (const char *text, int size,
if (*p == '!')
{
if (!(flags & MHT_STRICT_COMMENTS)
&& p < end + 3 && p[1] == '-' && p[2] == '-')
&& p + 3 < end && p[1] == '-' && p[2] == '-')
{
/* If strict comments are not enforced and if we know
we're looking at a comment, simply look for the
@@ -1167,7 +1159,7 @@ map_html_tags (const char *text, int size,
#undef ADVANCE
#undef SKIP_WS
#undef SKIP_NON_WS
#ifdef STANDALONE
static void
test_mapper (struct taginfo *taginfo, void *arg)

View File

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

View File

@@ -1,6 +1,7 @@
/* Collect URLs from HTML source.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
2007, 2008, 2009, 2010, 2011, 2012, 2015 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -45,6 +46,7 @@ as that of the covered work. */
#include "recur.h"
#include "html-url.h"
#include "css-url.h"
#include "c-strcase.h"
typedef void (*tag_handler_t) (int, struct taginfo *, struct map_context *);
@@ -54,6 +56,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);
@@ -103,7 +106,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 },
@@ -181,7 +184,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;
@@ -255,7 +259,7 @@ find_attr (struct taginfo *tag, const char *name, int *attrind)
{
int i;
for (i = 0; i < tag->nattrs; i++)
if (!strcasecmp (tag->attrs[i].name, name))
if (!c_strcasecmp (tag->attrs[i].name, name))
{
if (attrind)
*attrind = i;
@@ -302,6 +306,7 @@ append_url (const char *link_uri, int position, int size,
logprintf (LOG_NOTQUIET,
_("%s: Cannot resolve incomplete link %s.\n"),
ctx->document_file, link_uri);
iri_free (iri);
return NULL;
}
@@ -310,6 +315,7 @@ append_url (const char *link_uri, int position, int size,
{
DEBUGP (("%s: link \"%s\" doesn't parse.\n",
ctx->document_file, link_uri));
iri_free (iri);
return NULL;
}
}
@@ -333,6 +339,7 @@ append_url (const char *link_uri, int position, int size,
DEBUGP (("%s: merged link \"%s\" doesn't parse.\n",
ctx->document_file, complete_uri));
xfree (complete_uri);
iri_free (iri);
return NULL;
}
xfree (complete_uri);
@@ -378,7 +385,7 @@ append_url (const char *link_uri, int position, int size,
return newel;
}
static void
check_style_attr (struct taginfo *tag, struct map_context *ctx)
{
@@ -487,8 +494,7 @@ tag_handle_base (int tagid _GL_UNUSED, struct taginfo *tag, struct map_context *
base_urlpos->ignore_when_downloading = 1;
base_urlpos->link_base_p = 1;
if (ctx->base)
xfree (ctx->base);
xfree (ctx->base);
if (ctx->parent_base)
ctx->base = uri_merge (ctx->parent_base, newbase);
else
@@ -536,12 +542,12 @@ tag_handle_link (int tagid _GL_UNUSED, struct taginfo *tag, struct map_context *
char *rel = find_attr (tag, "rel", NULL);
if (rel)
{
if (0 == strcasecmp (rel, "stylesheet"))
if (0 == c_strcasecmp (rel, "stylesheet"))
{
up->link_inline_p = 1;
up->link_expect_css = 1;
}
else if (0 == strcasecmp (rel, "shortcut icon"))
else if (0 == c_strcasecmp (rel, "shortcut icon"))
{
up->link_inline_p = 1;
}
@@ -553,7 +559,7 @@ tag_handle_link (int tagid _GL_UNUSED, struct taginfo *tag, struct map_context *
<link rel="alternate" type="application/rss+xml" href=".../?feed=rss2" />
*/
char *type = find_attr (tag, "type", NULL);
if (!type || strcasecmp (type, "text/html") == 0)
if (!type || c_strcasecmp (type, "text/html") == 0)
up->link_expect_html = 1;
}
}
@@ -570,7 +576,7 @@ tag_handle_meta (int tagid _GL_UNUSED, struct taginfo *tag, struct map_context *
char *name = find_attr (tag, "name", NULL);
char *http_equiv = find_attr (tag, "http-equiv", NULL);
if (http_equiv && 0 == strcasecmp (http_equiv, "refresh"))
if (http_equiv && 0 == c_strcasecmp (http_equiv, "refresh"))
{
/* Some pages use a META tag to specify that the page be
refreshed by a new page after a given number of seconds. The
@@ -615,7 +621,7 @@ tag_handle_meta (int tagid _GL_UNUSED, struct taginfo *tag, struct map_context *
entry->link_expect_html = 1;
}
}
else if (http_equiv && 0 == strcasecmp (http_equiv, "content-type"))
else if (http_equiv && 0 == c_strcasecmp (http_equiv, "content-type"))
{
/* Handle stuff like:
<meta http-equiv="Content-Type" content="text/html; charset=CHARSET"> */
@@ -629,17 +635,17 @@ tag_handle_meta (int tagid _GL_UNUSED, struct taginfo *tag, struct map_context *
if (!mcharset)
return;
xfree_null (meta_charset);
xfree (meta_charset);
meta_charset = mcharset;
}
else if (name && 0 == strcasecmp (name, "robots"))
else if (name && 0 == c_strcasecmp (name, "robots"))
{
/* Handle stuff like:
<meta name="robots" content="index,nofollow"> */
char *content = find_attr (tag, "content", NULL);
if (!content)
return;
if (!strcasecmp (content, "none"))
if (!c_strcasecmp (content, "none"))
ctx->nofollow = true;
else
{
@@ -651,7 +657,7 @@ tag_handle_meta (int tagid _GL_UNUSED, struct taginfo *tag, struct map_context *
/* Find the next occurrence of ',' or whitespace,
* or the end of the string. */
end = content + strcspn (content, ", \f\n\r\t\v");
if (!strncasecmp (content, "nofollow", end - content))
if (!c_strncasecmp (content, "nofollow", end - content))
ctx->nofollow = true;
/* Skip past the next comma, if any. */
if (*end == ',')
@@ -670,6 +676,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. */
@@ -692,7 +783,7 @@ collect_tags_mapper (struct taginfo *tag, void *arg)
check_style_attr (tag, ctx);
if (tag->end_tag_p && (0 == strcasecmp (tag->name, "style"))
if (tag->end_tag_p && (0 == c_strcasecmp (tag->name, "style"))
&& tag->contents_begin && tag->contents_end
&& tag->contents_begin <= tag->contents_end)
{
@@ -701,7 +792,7 @@ collect_tags_mapper (struct taginfo *tag, void *arg)
tag->contents_end - tag->contents_begin);
}
}
/* Analyze HTML tags FILE and construct a list of URLs referenced from
it. It merges relative links in FILE with URL. It is aware of
<base href=...> and does the right thing. */
@@ -748,15 +839,19 @@ 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);
/* If meta charset isn't null, override content encoding */
if (iri && meta_charset)
#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)
*meta_disallow_follow = ctx.nofollow;
xfree_null (ctx.base);
xfree (ctx.base);
wget_read_file_free (fm);
return ctx.head;
}
@@ -787,6 +882,7 @@ get_urls_file (const char *file)
{
int up_error_code;
char *url_text;
char *new_url;
struct urlpos *entry;
struct url *url;
@@ -821,7 +917,7 @@ get_urls_file (const char *file)
url_text = merged;
}
char *new_url = rewrite_shorthand_url (url_text);
new_url = rewrite_shorthand_url (url_text);
if (new_url)
{
xfree (url_text);

View File

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

View File

@@ -1,6 +1,6 @@
/* NTLM code.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
Foundation, Inc.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
Contributed by Daniel Stenberg.
This file is part of GNU Wget.
@@ -74,13 +74,13 @@ as that of the covered work. */
/* Define this to make the type-3 message include the NT response message */
#define USE_NTRESPONSES 1
/* Flag bits definitions available at on
http://davenport.sourceforge.net/ntlm.html */
#define NTLMFLAG_NEGOTIATE_OEM (1<<1)
#define NTLMFLAG_NEGOTIATE_NTLM_KEY (1<<9)
/*
(*) = A "security buffer" is a triplet consisting of two shorts and one
long:
@@ -122,7 +122,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);
if (size < 0)
return false; /* malformed base64 from server */
@@ -411,7 +411,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;
@@ -474,82 +474,82 @@ ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
/* Create the big type-3 message binary blob */
size = (size_t) snprintf (ntlmbuf, sizeof(ntlmbuf),
"NTLMSSP%c"
"\x03%c%c%c" /* type-3, 32 bits */
snprintf (ntlmbuf, sizeof (ntlmbuf),
"NTLMSSP%c"
"\x03%c%c%c" /* type-3, 32 bits */
"%c%c%c%c" /* LanManager length + allocated space */
"%c%c" /* LanManager offset */
"%c%c" /* 2 zeroes */
"%c%c%c%c" /* LanManager length + allocated space */
"%c%c" /* LanManager offset */
"%c%c" /* 2 zeroes */
"%c%c" /* NT-response length */
"%c%c" /* NT-response allocated space */
"%c%c" /* NT-response offset */
"%c%c" /* 2 zeroes */
"%c%c" /* NT-response length */
"%c%c" /* NT-response allocated space */
"%c%c" /* NT-response offset */
"%c%c" /* 2 zeroes */
"%c%c" /* domain length */
"%c%c" /* domain allocated space */
"%c%c" /* domain name offset */
"%c%c" /* 2 zeroes */
"%c%c" /* domain length */
"%c%c" /* domain allocated space */
"%c%c" /* domain name offset */
"%c%c" /* 2 zeroes */
"%c%c" /* user length */
"%c%c" /* user allocated space */
"%c%c" /* user offset */
"%c%c" /* 2 zeroes */
"%c%c" /* user length */
"%c%c" /* user allocated space */
"%c%c" /* user offset */
"%c%c" /* 2 zeroes */
"%c%c" /* host length */
"%c%c" /* host allocated space */
"%c%c" /* host offset */
"%c%c%c%c%c%c" /* 6 zeroes */
"%c%c" /* host length */
"%c%c" /* host allocated space */
"%c%c" /* host offset */
"%c%c%c%c%c%c" /* 6 zeroes */
"\xff\xff" /* message length */
"%c%c" /* 2 zeroes */
"\xff\xff" /* message length */
"%c%c" /* 2 zeroes */
"\x01\x82" /* flags */
"%c%c" /* 2 zeroes */
"\x01\x82" /* flags */
"%c%c" /* 2 zeroes */
/* domain string */
/* user string */
/* host string */
/* LanManager response */
/* NT response */
,
0, /* zero termination */
0,0,0, /* type-3 long, the 24 upper bits */
/* domain string */
/* user string */
/* host string */
/* LanManager response */
/* NT response */
,
0, /* zero termination */
0, 0, 0, /* type-3 long, the 24 upper bits */
SHORTPAIR(0x18), /* LanManager response length, twice */
SHORTPAIR(0x18),
SHORTPAIR(lmrespoff),
0x0, 0x0,
SHORTPAIR (0x18), /* LanManager response length, twice */
SHORTPAIR (0x18),
SHORTPAIR (lmrespoff),
0x0, 0x0,
#ifdef USE_NTRESPONSES
SHORTPAIR(0x18), /* NT-response length, twice */
SHORTPAIR(0x18),
SHORTPAIR (0x18), /* NT-response length, twice */
SHORTPAIR (0x18),
#else
0x0, 0x0,
0x0, 0x0,
0x0, 0x0,
0x0, 0x0,
#endif
SHORTPAIR(ntrespoff),
0x0, 0x0,
SHORTPAIR (ntrespoff),
0x0, 0x0,
SHORTPAIR(domlen),
SHORTPAIR(domlen),
SHORTPAIR(domoff),
0x0, 0x0,
SHORTPAIR (domlen),
SHORTPAIR (domlen),
SHORTPAIR (domoff),
0x0, 0x0,
SHORTPAIR(userlen),
SHORTPAIR(userlen),
SHORTPAIR(useroff),
0x0, 0x0,
SHORTPAIR (userlen),
SHORTPAIR (userlen),
SHORTPAIR (useroff),
0x0, 0x0,
SHORTPAIR(hostlen),
SHORTPAIR(hostlen),
SHORTPAIR(hostoff),
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
SHORTPAIR (hostlen),
SHORTPAIR (hostlen),
SHORTPAIR (hostoff),
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0,
0x0, 0x0,
0x0, 0x0);
0x0, 0x0);
/* size is now 64 */
size=64;
@@ -584,7 +584,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
Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1997, 2000, 2007, 2008, 2009, 2010, 2011,
2015 Free Software Foundation, Inc.
Contributed by Daniel Stenberg.
This file is part of GNU Wget.

2736
src/http.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* Declarations for HTTP.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
Foundation, Inc.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
This file is part of GNU Wget.
@@ -31,9 +31,11 @@ as that of the covered work. */
#ifndef HTTP_H
#define HTTP_H
#include "hsts.h"
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,7 @@
/* 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 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2014, 2015 Free
Software Foundation, Inc.
This file is part of GNU Wget.
@@ -69,6 +69,8 @@ as that of the covered work. */
#include "retr.h" /* for output_stream */
#include "warc.h" /* for warc_close */
#include "spider.h" /* for spider_cleanup */
#include "html-url.h" /* for cleanup_html_url */
#include "c-strcase.h"
#ifdef TESTING
#include "test.h"
@@ -90,10 +92,13 @@ CMD_DECLARE (cmd_number_inf);
CMD_DECLARE (cmd_string);
CMD_DECLARE (cmd_string_uppercase);
CMD_DECLARE (cmd_file);
CMD_DECLARE (cmd_file_once);
CMD_DECLARE (cmd_directory);
CMD_DECLARE (cmd_time);
CMD_DECLARE (cmd_vector);
CMD_DECLARE (cmd_use_askpass);
CMD_DECLARE (cmd_spec_dirstruct);
CMD_DECLARE (cmd_spec_header);
CMD_DECLARE (cmd_spec_warc_header);
@@ -101,6 +106,7 @@ CMD_DECLARE (cmd_spec_htmlify);
CMD_DECLARE (cmd_spec_mirror);
CMD_DECLARE (cmd_spec_prefer_family);
CMD_DECLARE (cmd_spec_progress);
CMD_DECLARE (cmd_spec_progressdisp);
CMD_DECLARE (cmd_spec_recursive);
CMD_DECLARE (cmd_spec_regex_type);
CMD_DECLARE (cmd_spec_restrict_file_names);
@@ -111,6 +117,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,
@@ -138,6 +145,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
@@ -148,15 +158,19 @@ static const struct {
{ "cadirectory", &opt.ca_directory, cmd_directory },
{ "certificate", &opt.cert_file, cmd_file },
{ "certificatetype", &opt.cert_type, cmd_cert_type },
{ "checkcertificate", &opt.check_cert, cmd_boolean },
{ "checkcertificate", &opt.check_cert, cmd_check_cert },
#endif
{ "chooseconfig", &opt.choose_config, cmd_file },
{ "connecttimeout", &opt.connect_timeout, cmd_time },
{ "contentdisposition", &opt.content_disposition, cmd_boolean },
{ "contentonerror", &opt.content_on_error, cmd_boolean },
{ "continue", &opt.always_rest, cmd_boolean },
{ "convertfileonly", &opt.convert_file_only, cmd_boolean },
{ "convertlinks", &opt.convert_links, cmd_boolean },
{ "cookies", &opt.cookies, cmd_boolean },
#ifdef HAVE_SSL
{ "crlfile", &opt.crl_file, cmd_file_once },
#endif
{ "cutdirs", &opt.cut_dirs, cmd_number },
{ "debug", &opt.debug, cmd_boolean },
{ "defaultpage", &opt.default_page, cmd_string },
@@ -164,6 +178,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 },
@@ -181,12 +198,22 @@ static const struct {
{ "ftppasswd", &opt.ftp_passwd, cmd_string }, /* deprecated */
{ "ftppassword", &opt.ftp_passwd, cmd_string },
{ "ftpproxy", &opt.ftp_proxy, cmd_string },
#ifdef HAVE_SSL
{ "ftpscleardataconnection", &opt.ftps_clear_data_connection, cmd_boolean },
{ "ftpsfallbacktoftp", &opt.ftps_fallback_to_ftp, cmd_boolean },
{ "ftpsimplicit", &opt.ftps_implicit, cmd_boolean },
{ "ftpsresumessl", &opt.ftps_resume_ssl, cmd_boolean },
#endif
#ifdef __VMS
{ "ftpstmlf", &opt.ftp_stmlf, cmd_boolean },
#endif /* def __VMS */
{ "ftpuser", &opt.ftp_user, cmd_string },
{ "glob", &opt.ftp_glob, cmd_boolean },
{ "header", NULL, cmd_spec_header },
#ifdef HAVE_HSTS
{ "hsts", &opt.hsts, cmd_boolean },
{ "hstsfile", &opt.hsts_file, cmd_file },
#endif
{ "htmlextension", &opt.adjust_extension, cmd_boolean }, /* deprecated */
{ "htmlify", NULL, cmd_spec_htmlify },
{ "httpkeepalive", &opt.http_keep_alive, cmd_boolean },
@@ -198,6 +225,7 @@ static const struct {
#endif
{ "httpsproxy", &opt.https_proxy, cmd_string },
{ "httpuser", &opt.http_user, cmd_string },
{ "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 },
@@ -207,7 +235,11 @@ static const struct {
{ "inet6only", &opt.ipv6_only, cmd_boolean },
#endif
{ "input", &opt.input_filename, cmd_file },
#ifdef HAVE_METALINK
{ "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 },
@@ -215,6 +247,10 @@ static const struct {
{ "logfile", &opt.lfilename, cmd_file },
{ "login", &opt.ftp_user, cmd_string },/* deprecated*/
{ "maxredirect", &opt.max_redirect, cmd_number },
#ifdef HAVE_METALINK
{ "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 },
{ "netrc", &opt.netrc, cmd_boolean },
@@ -228,9 +264,15 @@ 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
{ "preferredlocation", &opt.preferred_location, cmd_string },
#endif
{ "preservepermissions", &opt.preserve_perm, cmd_boolean },
#ifdef HAVE_SSL
{ "privatekey", &opt.private_key, cmd_file },
@@ -253,6 +295,7 @@ static const struct {
{ "referer", &opt.referer, cmd_string },
{ "regextype", &opt.regex_type, cmd_spec_regex_type },
{ "reject", &opt.rejects, cmd_vector },
{ "rejectedlog", &opt.rejected_log, cmd_file },
{ "rejectregex", &opt.rejectregex_s, cmd_string },
{ "relativeonly", &opt.relative_only, cmd_boolean },
{ "remoteencoding", &opt.encoding_remote, cmd_string },
@@ -269,7 +312,7 @@ static const struct {
#endif
{ "serverresponse", &opt.server_response, cmd_boolean },
{ "showalldnsentries", &opt.show_all_dns_entries, cmd_boolean },
{ "showprogress", &opt.show_progress, cmd_boolean },
{ "showprogress", &opt.show_progress, cmd_spec_progressdisp },
{ "spanhosts", &opt.spanhost, cmd_boolean },
{ "spider", &opt.spider, cmd_boolean },
{ "startpos", &opt.start_pos, cmd_bytes },
@@ -279,6 +322,7 @@ static const struct {
{ "tries", &opt.ntry, cmd_number_inf },
{ "trustservernames", &opt.trustservernames, cmd_boolean },
{ "unlink", &opt.unlink, 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 },
@@ -300,6 +344,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
@@ -315,7 +362,7 @@ command_by_name (const char *cmdname)
while (lo <= hi)
{
int mid = (lo + hi) >> 1;
int cmp = strcasecmp (cmdname, commands[mid].name);
int cmp = c_strcasecmp (cmdname, commands[mid].name);
if (cmp < 0)
hi = mid - 1;
else if (cmp > 0)
@@ -325,7 +372,7 @@ command_by_name (const char *cmdname)
}
return -1;
}
/* Reset the variables to default values. */
void
defaults (void)
@@ -339,6 +386,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;
@@ -349,11 +400,13 @@ defaults (void)
opt.htmlify = true;
opt.http_keep_alive = true;
opt.use_proxy = true;
opt.convert_file_only = false;
tmp = getenv ("no_proxy");
if (tmp)
opt.no_proxy = sepstring (tmp);
opt.prefer_family = prefer_none;
opt.allow_cache = true;
opt.if_modified_since = true;
opt.read_timeout = 900;
opt.use_robots = true;
@@ -366,14 +419,36 @@ defaults (void)
opt.dns_cache = true;
opt.ftp_pasv = true;
/* 2014-09-07 Darshit Shah <darnir@gmail.com>
* opt.retr_symlinks is set to true by default. Creating symbolic links on the
* local filesystem pose a security threat by malicious FTP Servers that
* server a specially crafted .listing file akin to this:
*
* lrwxrwxrwx 1 root root 33 Dec 25 2012 JoCxl6d8rFU -> /
* drwxrwxr-x 15 1024 106 4096 Aug 28 02:02 JoCxl6d8rFU
*
* A .listing file in this fashion makes Wget susceptiple to a symlink attack
* wherein the attacker is able to create arbitrary files, directories and
* symbolic links on the target system and even set permissions.
*
* Hence, by default Wget attempts to retrieve the pointed-to files and does
* not create the symbolic links locally.
*/
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
/* The default for file name restriction defaults to the OS type. */
#if defined(WINDOWS) || defined(MSDOS) || defined(__CYGWIN__)
opt.restrict_files_os = restrict_windows;
#elif defined(__VMS)
opt.restrict_files_os = restrict_vms;
#else
opt.restrict_files_os = restrict_unix;
#endif
@@ -412,10 +487,21 @@ defaults (void)
/* Use a negative value to mark the absence of --start-pos option */
opt.start_pos = -1;
opt.show_progress = false;
opt.show_progress = -1;
opt.noscroll = false;
#ifdef HAVE_HSTS
/* 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
found. */
char *
@@ -464,7 +550,7 @@ home_dir (void)
}
ret = home ? xstrdup (home) : NULL;
free (buf);
xfree (buf);
return ret;
}
@@ -505,7 +591,7 @@ wgetrc_user_file_name (void)
home = home_dir ();
if (home)
file = aprintf ("%s/.wgetrc", home);
xfree_null (home);
xfree (home);
#endif /* def __VMS [else] */
if (!file)
@@ -539,17 +625,13 @@ wgetrc_file_name (void)
SYSTEM_WGETRC should not be defined under WINDOWS. */
if (!file)
{
char *home = home_dir ();
xfree_null (file);
file = NULL;
home = ws_mypath ();
char *home = ws_mypath ();
if (home)
{
file = aprintf ("%s/wget.ini", home);
if (!file_exists_p (file))
{
xfree (file);
file = NULL;
}
xfree (home);
}
@@ -623,8 +705,8 @@ run_wgetrc (const char *file)
default:
abort ();
}
xfree_null (com);
xfree_null (val);
xfree (com);
xfree (val);
++ln;
}
xfree (line);
@@ -795,6 +877,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);
}
@@ -877,7 +963,7 @@ run_command (const char *cmdopt)
exit (WGET_EXIT_PARSE_ERROR);
}
}
/* Generic helper functions, for use with `commands'. */
/* Forward declarations: */
@@ -901,6 +987,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
@@ -908,24 +1006,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
@@ -945,7 +1081,7 @@ cmd_number (const char *com, const char *val, void *place)
static bool
cmd_number_inf (const char *com, const char *val, void *place)
{
if (!strcasecmp (val, "inf"))
if (!c_strcasecmp (val, "inf"))
{
*(int *) place = 0;
return true;
@@ -960,7 +1096,7 @@ cmd_string (const char *com _GL_UNUSED, const char *val, void *place)
{
char **pstring = (char **)place;
xfree_null (*pstring);
xfree (*pstring);
*pstring = xstrdup (val);
return true;
}
@@ -971,7 +1107,7 @@ cmd_string_uppercase (const char *com _GL_UNUSED, const char *val, void *place)
{
char *q, **pstring;
pstring = (char **)place;
xfree_null (*pstring);
xfree (*pstring);
*pstring = xmalloc (strlen (val) + 1);
@@ -991,7 +1127,7 @@ cmd_file (const char *com _GL_UNUSED, const char *val, void *place)
{
char **pstring = (char **)place;
xfree_null (*pstring);
xfree (*pstring);
/* #### If VAL is empty, perhaps should set *PLACE to NULL. */
@@ -1009,6 +1145,20 @@ cmd_file (const char *com _GL_UNUSED, const char *val, void *place)
return true;
}
/* like cmd_file, but insist on just a single option usage */
static bool
cmd_file_once (const char *com _GL_UNUSED, const char *val, void *place)
{
if (*(char **)place)
{
fprintf (stderr, _("%s: %s must only be used once\n"),
exec_name, com);
return false;
}
return cmd_file(com, val, place);
}
/* Like cmd_file, but strips trailing '/' characters. */
static bool
cmd_directory (const char *com, const char *val, void *place)
@@ -1243,6 +1393,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)
@@ -1258,7 +1434,7 @@ cmd_cert_type (const char *com, const char *val, void *place)
return ok;
}
#endif
/* Specialized helper functions, used by `commands' to handle some
options specially. */
@@ -1382,7 +1558,7 @@ cmd_spec_progress (const char *com, const char *val, void *place_ignored _GL_UNU
exec_name, com, quote (val));
return false;
}
xfree_null (opt.progress_type);
xfree (opt.progress_type);
/* Don't call set_progress_implementation here. It will be called
in main when it becomes clear what the log output is. */
@@ -1446,6 +1622,8 @@ cmd_spec_restrict_file_names (const char *com, const char *val, void *place_igno
if (VAL_IS ("unix"))
restrict_os = restrict_unix;
else if (VAL_IS ("vms"))
restrict_os = restrict_vms;
else if (VAL_IS ("windows"))
restrict_os = restrict_windows;
else if (VAL_IS ("lowercase"))
@@ -1460,7 +1638,7 @@ cmd_spec_restrict_file_names (const char *com, const char *val, void *place_igno
{
fprintf (stderr, _("\
%s: %s: Invalid restriction %s,\n\
use [unix|windows],[lowercase|uppercase],[nocontrol],[ascii].\n"),
use [unix|vms|windows],[lowercase|uppercase],[nocontrol],[ascii].\n"),
exec_name, com, quote (val));
return false;
}
@@ -1483,7 +1661,7 @@ cmd_spec_restrict_file_names (const char *com, const char *val, void *place_igno
static bool
cmd_spec_report_speed (const char *com, const char *val, void *place_ignored _GL_UNUSED)
{
opt.report_bps = strcasecmp (val, "bits") == 0;
opt.report_bps = c_strcasecmp (val, "bits") == 0;
if (!opt.report_bps)
fprintf (stderr, _("%s: %s: Invalid value %s.\n"), exec_name, com, quote (val));
return opt.report_bps;
@@ -1498,6 +1676,8 @@ cmd_spec_secure_protocol (const char *com, const char *val, void *place)
{ "sslv2", secure_protocol_sslv2 },
{ "sslv3", secure_protocol_sslv3 },
{ "tlsv1", secure_protocol_tlsv1 },
{ "tlsv1_1", secure_protocol_tlsv1_1 },
{ "tlsv1_2", secure_protocol_tlsv1_2 },
{ "pfs", secure_protocol_pfs },
};
int ok = decode_string (val, choices, countof (choices), place);
@@ -1531,11 +1711,27 @@ cmd_spec_useragent (const char *com, const char *val, void *place_ignored _GL_UN
exec_name, com, quote (val));
return false;
}
xfree_null (opt.useragent);
xfree (opt.useragent);
opt.useragent = xstrdup (val);
return true;
}
/* The --show-progress option is not a cmd_boolean since we need to keep track
* of whether the user explicitly requested the option or not. -1 means
* uninitialized. */
static bool
cmd_spec_progressdisp (const char *com, const char *val, void *place _GL_UNUSED)
{
bool flag;
if (cmd_boolean (com, val, &flag))
{
opt.show_progress = flag;
return true;
}
return false;
}
/* The "verbose" option cannot be cmd_boolean because the variable is
not bool -- it's of type int (-1 means uninitialized because of
some random hackery for disallowing -q -v). */
@@ -1547,11 +1743,12 @@ cmd_spec_verbose (const char *com, const char *val, void *place_ignored _GL_UNUS
if (cmd_boolean (com, val, &flag))
{
opt.verbose = flag;
opt.show_progress = -1;
return true;
}
return false;
}
/* Miscellaneous useful routines. */
/* A very simple atoi clone, more useful than atoi because it works on
@@ -1686,7 +1883,7 @@ decode_string (const char *val, const struct decode_item *items, int itemcount,
{
int i;
for (i = 0; i < itemcount; i++)
if (0 == strcasecmp (val, items[i].name))
if (0 == c_strcasecmp (val, items[i].name))
{
*place = items[i].code;
return true;
@@ -1729,55 +1926,75 @@ cleanup (void)
spider_cleanup ();
host_cleanup ();
log_cleanup ();
netrc_cleanup (netrc_list);
netrc_cleanup ();
for (i = 0; i < nurl; i++)
xfree (url[i]);
xfree_null (opt.choose_config);
xfree_null (opt.lfilename);
xfree_null (opt.dir_prefix);
xfree_null (opt.input_filename);
xfree_null (opt.output_document);
xfree (opt.choose_config);
xfree (opt.lfilename);
xfree (opt.dir_prefix);
xfree (opt.input_filename);
#ifdef HAVE_METALINK
xfree (opt.input_metalink);
xfree (opt.preferred_location);
#endif
xfree (opt.output_document);
free_vec (opt.accepts);
free_vec (opt.rejects);
free_vec (opt.excludes);
free_vec (opt.includes);
free_vec ((char **)opt.excludes);
free_vec ((char **)opt.includes);
free_vec (opt.domains);
free_vec (opt.follow_tags);
free_vec (opt.ignore_tags);
xfree_null (opt.progress_type);
xfree_null (opt.ftp_user);
xfree_null (opt.ftp_passwd);
xfree_null (opt.ftp_proxy);
xfree_null (opt.https_proxy);
xfree_null (opt.http_proxy);
xfree (opt.progress_type);
xfree (opt.ftp_user);
xfree (opt.ftp_passwd);
xfree (opt.ftp_proxy);
xfree (opt.https_proxy);
xfree (opt.http_proxy);
free_vec (opt.no_proxy);
xfree_null (opt.useragent);
xfree_null (opt.referer);
xfree_null (opt.http_user);
xfree_null (opt.http_passwd);
xfree (opt.useragent);
xfree (opt.referer);
xfree (opt.http_user);
xfree (opt.http_passwd);
free_vec (opt.user_headers);
free_vec (opt.warc_user_headers);
# ifdef HAVE_SSL
xfree_null (opt.cert_file);
xfree_null (opt.private_key);
xfree_null (opt.ca_directory);
xfree_null (opt.ca_cert);
xfree_null (opt.random_file);
xfree_null (opt.egd_file);
xfree (opt.cert_file);
xfree (opt.private_key);
xfree (opt.ca_directory);
xfree (opt.ca_cert);
xfree (opt.crl_file);
xfree (opt.random_file);
xfree (opt.egd_file);
# endif
xfree_null (opt.bind_address);
xfree_null (opt.cookies_input);
xfree_null (opt.cookies_output);
xfree_null (opt.user);
xfree_null (opt.passwd);
xfree_null (opt.base_href);
xfree_null (opt.method);
xfree (opt.bind_address);
xfree (opt.cookies_input);
xfree (opt.cookies_output);
xfree (opt.user);
xfree (opt.passwd);
xfree (opt.base_href);
xfree (opt.method);
xfree (opt.post_file_name);
xfree (opt.post_data);
xfree (opt.body_data);
xfree (opt.body_file);
xfree (opt.rejected_log);
xfree (opt.use_askpass);
#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 */
}
/* Unit testing routines. */
#ifdef TESTING
@@ -1789,7 +2006,7 @@ test_commands_sorted(void)
for (i = 1; i < countof(commands); ++i)
{
if (strcasecmp (commands[i - 1].name, commands[i].name) > 0)
if (c_strcasecmp (commands[i - 1].name, commands[i].name) > 0)
{
mu_assert ("FAILED", false);
break;
@@ -1805,7 +2022,7 @@ test_cmd_spec_restrict_file_names(void)
static const struct {
const char *val;
int expected_restrict_files_os;
int expected_restrict_files_ctrl;
bool expected_restrict_files_ctrl;
int expected_restrict_files_case;
bool result;
} test_array[] = {
@@ -1830,9 +2047,9 @@ test_cmd_spec_restrict_file_names(void)
*/
mu_assert ("test_cmd_spec_restrict_file_names: wrong result",
res == test_array[i].result
&& opt.restrict_files_os == test_array[i].expected_restrict_files_os
&& (int) opt.restrict_files_os == test_array[i].expected_restrict_files_os
&& opt.restrict_files_ctrl == test_array[i].expected_restrict_files_ctrl
&& opt.restrict_files_case == test_array[i].expected_restrict_files_case);
&& (int) opt.restrict_files_case == test_array[i].expected_restrict_files_case);
}
return NULL;

View File

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

267
src/iri.c
View File

@@ -1,5 +1,6 @@
/* IRI related functions.
Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
Copyright (C) 2008, 2009, 2010, 2011, 2015 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -32,44 +33,47 @@ 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 <langinfo.h>
#include <errno.h>
#ifdef HAVE_ICONV
# include <iconv.h>
#endif
#include <idn2.h>
#include <unicase.h>
#include <unistr.h>
#include "utils.h"
/* RFC3987 section 3.1 mandates STD3 ASCII RULES */
#define IDNA_FLAGS IDNA_USE_STD3_ASCII_RULES
#include "url.h"
#include "c-strcase.h"
#include "c-strcasestr.h"
#include "xstrndup.h"
/* Note: locale encoding is kept in options struct (opt.locale) */
static bool do_conversion (iconv_t cd, char *in, size_t inlen, char **out);
/* Given a string containing "charset=XXX", return the encoding if found,
or NULL otherwise */
char *
parse_charset (char *str)
parse_charset (const char *str)
{
const char *end;
char *charset;
if (!str || !*str)
return NULL;
str = strcasestr (str, "charset=");
str = c_strcasestr (str, "charset=");
if (!str)
return NULL;
str += 8;
charset = str;
end = str;
/* sXXXav: which chars should be banned ??? */
while (*charset && !c_isspace (*charset))
charset++;
while (*end && !c_isspace (*end))
end++;
/* sXXXav: could strdupdelim return NULL ? */
charset = strdupdelim (str, charset);
charset = strdupdelim (str, end);
/* Do a minimum check on the charset value */
if (!check_encoding_name (charset))
@@ -84,17 +88,22 @@ parse_charset (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. */
bool
check_encoding_name (char *encoding)
check_encoding_name (const char *encoding)
{
char *s = encoding;
const char *s = encoding;
while (*s)
{
@@ -110,60 +119,53 @@ check_encoding_name (char *encoding)
return true;
}
/* 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. */
const char *
locale_to_utf8 (const char *str)
{
iconv_t l2u;
char *new;
/* That shouldn't happen, just in case */
if (!opt.locale)
{
logprintf (LOG_VERBOSE, _("locale_to_utf8: locale is unset\n"));
opt.locale = find_locale ();
}
if (!opt.locale || !strcasecmp (opt.locale, "utf-8"))
return str;
l2u = iconv_open ("UTF-8", opt.locale);
if (l2u == (iconv_t)(-1))
{
logprintf (LOG_VERBOSE, _("Conversion from %s to %s isn't supported\n"),
quote (opt.locale), quote ("UTF-8"));
return str;
}
if (do_conversion (l2u, (char *) str, strlen ((char *) str), &new))
return (const char *) new;
return str;
}
/* Do the conversion according to the passed conversion descriptor cd. *out
will contain the transcoded string on success. *out content is
unspecified otherwise. */
static bool
do_conversion (iconv_t cd, char *in, size_t inlen, char **out)
do_conversion (const char *tocode, const char *fromcode, char const *in_org, size_t inlen, char **out)
{
iconv_t cd;
/* sXXXav : hummm hard to guess... */
size_t len, done, outlen = inlen * 2;
size_t len, done, outlen;
int invalid = 0, tooshort = 0;
char *s;
char *s, *in, *in_save;
s = xmalloc (outlen + 1);
*out = s;
len = outlen;
cd = iconv_open (tocode, fromcode);
if (cd == (iconv_t)(-1))
{
logprintf (LOG_VERBOSE, _("Conversion from %s to %s isn't supported\n"),
quote (fromcode), quote (tocode));
*out = NULL;
return false;
}
/* iconv() has to work on an unescaped string */
in_save = in = xstrndup (in_org, inlen);
url_unescape_except_reserved (in);
inlen = strlen(in);
len = outlen = inlen * 2;
*out = s = xmalloc (outlen + 1);
done = 0;
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';
xfree(in_save);
iconv_close(cd);
IF_DEBUG
{
/* not not print out embedded passwords, in_org might be an URL */
if (!strchr(in_org, '@') && !strchr(*out, '@'))
debug_logprintf ("converted '%s' (%s) -> '%s' (%s)\n", in_org, fromcode, *out, tocode);
else
debug_logprintf ("logging suppressed, strings may contain password\n");
}
return true;
}
@@ -183,16 +185,10 @@ do_conversion (iconv_t cd, char *in, size_t inlen, char **out)
}
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 */
@@ -202,63 +198,127 @@ do_conversion (iconv_t cd, char *in, size_t inlen, char **out)
}
}
xfree(in_save);
iconv_close(cd);
IF_DEBUG
{
/* not not print out embedded passwords, in_org might be an URL */
if (!strchr(in_org, '@') && !strchr(*out, '@'))
debug_logprintf ("converted '%s' (%s) -> '%s' (%s)\n", in_org, fromcode, *out, tocode);
else
debug_logprintf ("logging suppressed, strings may contain password\n");
}
return false;
}
/* 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. */
const char *
locale_to_utf8 (const char *str)
{
char *new;
/* That shouldn't happen, just in case */
if (!opt.locale)
{
logprintf (LOG_VERBOSE, _("locale_to_utf8: locale is unset\n"));
opt.locale = find_locale ();
}
if (!opt.locale || !c_strcasecmp (opt.locale, "utf-8"))
return str;
if (do_conversion ("UTF-8", opt.locale, (char *) str, strlen ((char *) str), &new))
return (const char *) new;
xfree (new);
return str;
}
/* Try to "ASCII encode" UTF-8 host. Return the new domain on success or NULL
on error. */
char *
idn_encode (struct iri *i, char *host)
idn_encode (const struct iri *i, const char *host)
{
char *new;
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, (const char *) host, (const char **) &new))
if (!remote_to_utf8 (i, host, &utf8_encoded))
return NULL; /* Nothing to encode or an error occured */
host = new;
src = utf8_encoded;
}
else
src = host;
/* toASCII UTF-8 NULL terminated string */
ret = idna_to_ascii_8z (host, &new, IDNA_FLAGS);
if (ret != IDNA_SUCCESS)
#if IDN2_VERSION_NUMBER >= 0x00140000
/* IDN2_TRANSITIONAL implies input NFC encoding */
if ((ret = idn2_lookup_u8 ((uint8_t *) src, (uint8_t **) &ascii_encoded, IDN2_NONTRANSITIONAL)) != IDN2_OK)
{
/* sXXXav : free new when needed ! */
logprintf (LOG_VERBOSE, _("idn_encode failed (%d): %s\n"), ret,
quote (idna_strerror (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, _("Failed to convert to lower: %d: %s\n"),
errno, quote (src));
xfree (utf8_encoded);
return NULL;
}
return new;
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 (idn2_strerror (ret)));
}
xfree (lower);
#endif
return ret == IDN2_OK ? ascii_encoded : NULL;
}
/* Try to decode an "ASCII encoded" host. Return the new domain in the locale
on success or NULL on error. */
char *
idn_decode (char *host)
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
contains the transcoded string. *new content is unspecified otherwise. */
bool
remote_to_utf8 (struct iri *iri, const char *str, const char **new)
remote_to_utf8 (const struct iri *iri, const char *str, char **new)
{
iconv_t cd;
bool ret = false;
if (!iri->uri_encoding)
@@ -267,11 +327,11 @@ remote_to_utf8 (struct iri *iri, const char *str, const char **new)
/* When `i->uri_encoding' == "UTF-8" there is nothing to convert. But we must
test for non-ASCII symbols for correct hostname processing in `idn_encode'
function. */
if (!strcmp (iri->uri_encoding, "UTF-8"))
if (!c_strcasecmp (iri->uri_encoding, "UTF-8"))
{
const char *p = str;
for (p = str; *p; p++)
if (*p < 0)
const unsigned char *p;
for (p = (unsigned char *) str; *p; p++)
if (*p > 127)
{
*new = strdup (str);
return true;
@@ -279,19 +339,13 @@ remote_to_utf8 (struct iri *iri, const char *str, const char **new)
return false;
}
cd = iconv_open ("UTF-8", iri->uri_encoding);
if (cd == (iconv_t)(-1))
return false;
if (do_conversion (cd, (char *) str, strlen ((char *) str), (char **) new))
if (do_conversion ("UTF-8", iri->uri_encoding, str, strlen (str), new))
ret = true;
iconv_close (cd);
/* Test if something was converted */
if (!strcmp (str, *new))
if (*new && !strcmp (str, *new))
{
xfree ((char *) *new);
xfree (*new);
return false;
}
@@ -325,23 +379,26 @@ struct iri *iri_dup (const struct iri *src)
void
iri_free (struct iri *i)
{
xfree_null (i->uri_encoding);
xfree_null (i->content_encoding);
xfree_null (i->orig_url);
xfree (i);
if (i)
{
xfree (i->uri_encoding);
xfree (i->content_encoding);
xfree (i->orig_url);
xfree (i);
}
}
/* Set uri_encoding of struct iri i. If a remote encoding was specified, use
it unless force is true. */
void
set_uri_encoding (struct iri *i, char *charset, bool force)
set_uri_encoding (struct iri *i, const char *charset, bool force)
{
DEBUGP (("URI encoding = %s\n", charset ? quote (charset) : "None"));
if (!force && opt.encoding_remote)
return;
if (i->uri_encoding)
{
if (charset && !strcasecmp (i->uri_encoding, charset))
if (charset && !c_strcasecmp (i->uri_encoding, charset))
return;
xfree (i->uri_encoding);
}
@@ -351,14 +408,14 @@ set_uri_encoding (struct iri *i, char *charset, bool force)
/* Set content_encoding of struct iri i. */
void
set_content_encoding (struct iri *i, char *charset)
set_content_encoding (struct iri *i, const char *charset)
{
DEBUGP (("URI content encoding = %s\n", charset ? quote (charset) : "None"));
if (opt.encoding_remote)
return;
if (i->content_encoding)
{
if (charset && !strcasecmp (i->content_encoding, charset))
if (charset && !c_strcasecmp (i->content_encoding, charset))
return;
xfree (i->content_encoding);
}

View File

@@ -1,5 +1,6 @@
/* Internationalization related declarations.
Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
Copyright (C) 2008, 2009, 2010, 2011, 2015 Free Software Foundation,
Inc.
This file is part of GNU Wget.
@@ -39,29 +40,32 @@ struct iri {
#ifdef ENABLE_IRI
char *parse_charset (char *str);
char *find_locale (void);
bool check_encoding_name (char *encoding);
# include <idn2.h>
char *parse_charset (const char *str);
const char *find_locale (void);
bool check_encoding_name (const char *encoding);
const char *locale_to_utf8 (const char *str);
char *idn_encode (struct iri *i, char *host);
char *idn_decode (char *host);
bool remote_to_utf8 (struct iri *i, const char *str, const char **new);
char *idn_encode (const struct iri *i, const char *host);
char *idn_decode (const char *host);
bool remote_to_utf8 (const struct iri *i, const char *str, char **new);
struct iri *iri_new (void);
struct iri *iri_dup (const struct iri *);
void iri_free (struct iri *i);
void set_uri_encoding (struct iri *i, char *charset, bool force);
void set_content_encoding (struct iri *i, char *charset);
void set_uri_encoding (struct iri *i, const char *charset, bool force);
void set_content_encoding (struct iri *i, const char *charset);
#else /* ENABLE_IRI */
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 idn2_free(str) ((void)0)
#define remote_to_utf8(a,b,c) false
#define iri_new() (&dummy_iri)
#define iri_dup(a) (&dummy_iri)

193
src/log.c
View File

@@ -1,6 +1,6 @@
/* Messages logging.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
2007, 2008, 2009, 2010, 2011, 2015 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -73,13 +73,25 @@ as that of the covered work. */
- Inhibiting output. When Wget receives SIGHUP, but redirecting
the output fails, logging is inhibited. */
/* The file descriptor used for logging. This is NULL before log_init
is called; logging functions log to stderr then. log_init sets it
either to stderr or to a file pointer obtained from fopen(). If
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;
@@ -142,7 +154,7 @@ static int log_line_current = -1;
static bool trailing_line;
static void check_redirect_output (void);
#define ROT_ADVANCE(num) do { \
if (++num >= SAVED_LOG_LINES) \
num = 0; \
@@ -156,11 +168,7 @@ static void
free_log_line (int num)
{
struct log_ln *ln = log_lines + num;
if (ln->malloced_line)
{
xfree (ln->malloced_line);
ln->malloced_line = NULL;
}
xfree (ln->malloced_line);
ln->content = NULL;
}
@@ -265,7 +273,7 @@ saved_append (const char *s)
s = end;
}
}
/* Check X against opt.verbose and opt.quiet. The semantics is as
follows:
@@ -314,6 +322,14 @@ get_log_fp (void)
return stderr;
}
static FILE *
get_progress_fp (void)
{
if (opt.show_progress == true)
return stderr;
return get_log_fp();
}
/* Returns the file descriptor for the secondary log file. This is
WARCLOGFP, except if called before log_init, in which case it
returns stderr. This is useful in case someone calls a logging
@@ -338,7 +354,7 @@ log_set_warc_log_fp (FILE * fp)
{
warclogfp = fp;
}
/* Log a literal string S. The string is logged as-is, without a
newline appended. */
@@ -347,11 +363,22 @@ logputs (enum log_options o, const char *s)
{
FILE *fp;
FILE *warcfp;
int errno_save = errno;
check_redirect_output ();
if ((fp = get_log_fp ()) == NULL)
if (o == LOG_PROGRESS)
fp = get_progress_fp ();
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);
@@ -363,6 +390,8 @@ logputs (enum log_options o, const char *s)
logflush ();
else
needs_flushing = true;
errno = errno_save;
}
struct logvprintf_state {
@@ -385,7 +414,7 @@ struct logvprintf_state {
(An alternative approach would be to use va_copy, but that's not
portable.) */
static bool
static bool GCC_FORMAT_ATTR (2, 0)
log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
va_list args)
{
@@ -451,8 +480,7 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
FPUTS (write_ptr, fp);
if (warcfp != NULL)
FPUTS (write_ptr, warcfp);
if (state->bigmsg)
xfree (state->bigmsg);
xfree (state->bigmsg);
flush:
if (flush_log_p)
@@ -534,13 +562,16 @@ 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);
xzero (lpstate);
errno = 0;
do
{
va_start (args, fmt);
@@ -551,6 +582,8 @@ logprintf (enum log_options o, const char *fmt, ...)
exit (WGET_EXIT_GENERIC_ERROR);
}
while (!done);
errno = errno_saved;
}
#ifdef ENABLE_DEBUG
@@ -580,7 +613,7 @@ debug_logprintf (const char *fmt, ...)
}
}
#endif /* ENABLE_DEBUG */
/* Open FILE and set up a logging stream. If FILE cannot be opened,
exit with status of 1. */
void
@@ -588,11 +621,20 @@ log_init (const char *file, bool appendp)
{
if (file)
{
logfp = fopen (file, appendp ? "a" : "w");
if (!logfp)
if (HYPHENP (file))
{
fprintf (stderr, "%s: %s: %s\n", exec_name, file, strerror (errno));
exit (WGET_EXIT_GENERIC_ERROR);
stdlogfp = stdout;
logfp = stdlogfp;
}
else
{
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
@@ -603,7 +645,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
@@ -618,6 +661,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
@@ -675,7 +723,7 @@ log_dump_context (void)
fflush (fp);
fflush (warcfp);
}
/* String escape functions. */
/* Return the number of non-printable characters in SOURCE.
@@ -847,64 +895,83 @@ log_cleanup (void)
{
size_t i;
for (i = 0; i < countof (ring); i++)
xfree_null (ring[i].buffer);
xfree (ring[i].buffer);
}
/* 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 ();
if (tcgetpgrp (STDIN_FILENO) != 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,6 @@
/* Declarations for log.c.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
2007, 2008, 2009, 2010, 2011, 2015 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -52,6 +52,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 *);

File diff suppressed because it is too large Load Diff

1599
src/metalink.c Normal file

File diff suppressed because it is too large Load Diff

75
src/metalink.h Normal file
View File

@@ -0,0 +1,75 @@
/* Declarations for metalink.c.
Copyright (C) 2015 Free Software Foundation, Inc.
This file is part of GNU Wget.
GNU Wget is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
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 Wget. If not, see <http://www.gnu.org/licenses/>.
Additional permission under GNU GPL version 3 section 7
If you modify this program, or any covered work, by linking or
combining it with the OpenSSL project's OpenSSL library (or a
modified version of that library), containing parts covered by the
terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
grants you additional permission to convey the resulting work.
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. */
#if ! defined METALINK_H && defined HAVE_METALINK
#define METALINK_H
#include <metalink/metalink_types.h>
#include "wget.h"
#ifdef HAVE_SSL
# define RES_TYPE_SUPPORTED(x)\
((!x) || !strcmp (x, "http") || !strcmp (x, "https") || !strcmp (x, "ftp") || !strcmp (x, "ftps"))
#else
# define RES_TYPE_SUPPORTED(x)\
((!x) || !strcmp (x, "ftp") || !strcmp (x, "http"))
#endif
#define DEFAULT_PRI 999999
#define VALID_PRI_RANGE(x) ((x) > 0 && (x) < 1000000)
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,
const char *key,
char **value);
bool has_key (const char *start, const char *end, const char *key);
const char *find_key_values (const char *start,
const char *end,
char **key,
char **value);
#endif /* METALINK_H */

View File

@@ -1,7 +1,7 @@
/* mswindows.c -- Windows-specific support
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -53,16 +53,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);
@@ -85,11 +82,11 @@ windows_main (char **exec_name)
if (p)
*p = '\0';
}
static void
ws_cleanup (void)
{
xfree ((char*)exec_name);
xfree (exec_name);
WSACleanup ();
}
@@ -98,7 +95,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;
@@ -367,8 +364,8 @@ static int old_percentage = -1;
void
ws_changetitle (const char *url)
{
xfree_null (title_buf);
xfree_null (curr_url);
xfree (title_buf);
xfree (curr_url);
title_buf = xmalloc (strlen (url) + 20);
curr_url = xstrdup (url);
old_percentage = -1;
@@ -477,7 +474,7 @@ ws_startup (void)
set_sleep_mode ();
SetConsoleCtrlHandler (ws_handler, TRUE);
}
/* run_with_timeout Windows implementation. */
/* Stack size 0 uses default thread stack-size (reserve+commit).

View File

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

View File

@@ -1,5 +1,5 @@
/* Read and parse the .netrc file to get hosts, accounts, and passwords.
Copyright (C) 1996, 2007, 2008, 2009, 2010, 2011 Free Software
Copyright (C) 1996, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -75,7 +75,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 +94,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);
@@ -163,7 +163,7 @@ search_netrc (const char *host, const char **acc, const char **passwd,
/* Normally, these functions would be defined by your package. */
# define xmalloc malloc
# define xfree free
# define xfree(p) do { free ((void *) (p)); p = NULL; } while (0)
# define xstrdup strdup
# define xrealloc realloc
@@ -183,9 +183,9 @@ maybe_add_to_list (acc_t **newentry, acc_t **list)
if (a && ! a->acc)
{
/* Free any allocated space. */
xfree_null (a->host);
xfree_null (a->acc);
xfree_null (a->passwd);
xfree (a->host);
xfree (a->acc);
xfree (a->passwd);
}
else
{
@@ -424,9 +424,9 @@ free_netrc(acc_t *l)
while (l)
{
t = l->next;
xfree_null (l->acc);
xfree_null (l->passwd);
xfree_null (l->host);
xfree (l->acc);
xfree (l->passwd);
xfree (l->host);
xfree (l);
l = t;
}
@@ -439,7 +439,7 @@ free_netrc(acc_t *l)
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 Free
Software Foundation, Inc.
Copyright (C) 1996, 1996, 1997, 2007, 2008, 2009, 2010, 2011, 2015
Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,6 +1,6 @@
/* SSL support via OpenSSL library.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 2011, 2012 Free Software Foundation, Inc.
2009, 2010, 2011, 2012, 2015 Free Software Foundation, Inc.
Originally contributed by Christian Fraenkel.
This file is part of GNU Wget.
@@ -35,11 +35,17 @@ 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>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
#if OPENSSL_VERSION_NUMBER >= 0x00907000
#include <openssl/conf.h>
#include <openssl/engine.h>
#endif
#include "utils.h"
#include "connect.h"
@@ -86,9 +92,11 @@ init_prng (void)
if (RAND_status ())
return;
#ifdef HAVE_RAND_EGD
/* Get random data from EGD if opt.egd_file was used. */
if (opt.egd_file && *opt.egd_file)
RAND_egd (opt.egd_file);
#endif
if (RAND_status ())
return;
@@ -164,6 +172,9 @@ static int ssl_true_initialized = 0;
bool
ssl_init (void)
{
SSL_METHOD const *meth;
long ssl_options = 0;
#if OPENSSL_VERSION_NUMBER >= 0x00907000
if (ssl_true_initialized == 0)
{
@@ -172,8 +183,6 @@ ssl_init (void)
}
#endif
SSL_METHOD const *meth;
if (ssl_ctx)
/* The SSL has already been initialized. */
return true;
@@ -187,29 +196,63 @@ ssl_init (void)
goto error;
}
#if OPENSSL_VERSION_NUMBER >= 0x00907000
OPENSSL_load_builtin_modules();
ENGINE_load_builtin_engines();
CONF_modules_load_file(NULL, NULL,
CONF_MFLAGS_DEFAULT_SECTION|CONF_MFLAGS_IGNORE_MISSING_FILE);
#endif
SSL_library_init ();
SSL_load_error_strings ();
#if OPENSSL_VERSION_NUMBER < 0x10100000L
SSLeay_add_all_algorithms ();
SSLeay_add_ssl_algorithms ();
#endif
switch (opt.secure_protocol)
{
case secure_protocol_auto:
meth = SSLv23_client_method ();
break;
#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_METHOD
case secure_protocol_sslv3:
meth = SSLv3_client_method ();
break;
#endif
case secure_protocol_auto:
case secure_protocol_pfs:
meth = SSLv23_client_method ();
ssl_options |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
break;
case secure_protocol_tlsv1:
meth = TLSv1_client_method ();
break;
#if OPENSSL_VERSION_NUMBER >= 0x10001000
case secure_protocol_tlsv1_1:
meth = TLSv1_1_client_method ();
break;
case secure_protocol_tlsv1_2:
meth = TLSv1_2_client_method ();
break;
#else
case secure_protocol_tlsv1_1:
logprintf (LOG_NOTQUIET, _("Your OpenSSL version is too old to support TLSv1.1\n"));
goto error;
case secure_protocol_tlsv1_2:
logprintf (LOG_NOTQUIET, _("Your OpenSSL version is too old to support TLSv1.2\n"));
goto error;
#endif
default:
logprintf (LOG_NOTQUIET, _("OpenSSL: unimplemented 'secure-protocol' option value %d\n"), opt.secure_protocol);
logprintf (LOG_NOTQUIET, _("Please report this issue to bug-wget@gnu.org\n"));
abort ();
}
@@ -219,6 +262,9 @@ ssl_init (void)
if (!ssl_ctx)
goto error;
if (ssl_options)
SSL_CTX_set_options (ssl_ctx, ssl_options);
/* 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)
*/
@@ -228,6 +274,18 @@ ssl_init (void)
SSL_CTX_set_default_verify_paths (ssl_ctx);
SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory);
if (opt.crl_file)
{
X509_STORE *store = SSL_CTX_get_cert_store (ssl_ctx);
X509_LOOKUP *lookup;
if (!(lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ()))
|| (!X509_load_crl_file (lookup, opt.crl_file, X509_FILETYPE_PEM)))
goto error;
X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
}
/* SSL_VERIFY_NONE instructs OpenSSL not to abort SSL_connect if the
certificate is invalid. We verify the certificate separately in
ssl_check_certificate, which provides much better diagnostics
@@ -237,10 +295,17 @@ ssl_init (void)
/* Use the private key from the cert file unless otherwise specified. */
if (opt.cert_file && !opt.private_key)
{
opt.private_key = opt.cert_file;
opt.private_key = xstrdup (opt.cert_file);
opt.private_key_type = opt.cert_type;
}
/* Use cert from private key file unless otherwise specified. */
if (opt.private_key && !opt.cert_file)
{
opt.cert_file = xstrdup (opt.private_key);
opt.cert_type = opt.private_key_type;
}
if (opt.cert_file)
if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
key_type_to_ssl_type (opt.cert_type))
@@ -272,6 +337,7 @@ ssl_init (void)
struct openssl_transport_context
{
SSL *conn; /* SSL connection handle */
SSL_SESSION *sess; /* SSL session info */
char *last_error; /* last error printed with openssl_errstr */
};
@@ -370,7 +436,7 @@ openssl_errstr (int fd _GL_UNUSED, void *arg)
return NULL;
/* Get rid of previous contents of ctx->last_error, if any. */
xfree_null (ctx->last_error);
xfree (ctx->last_error);
/* Iterate over OpenSSL's error stack and accumulate errors in the
last_error buffer, separated by "; ". This is better than using
@@ -414,7 +480,7 @@ openssl_close (int fd, void *arg)
SSL_shutdown (conn);
SSL_free (conn);
xfree_null (ctx->last_error);
xfree (ctx->last_error);
xfree (ctx);
close (fd);
@@ -443,6 +509,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
@@ -452,7 +534,7 @@ ssl_connect_with_timeout_callback(void *arg)
Returns true on success, false on failure. */
bool
ssl_connect_wget (int fd, const char *hostname)
ssl_connect_wget (int fd, const char *hostname, int *continue_session)
{
SSL *conn;
struct scwt_context scwt_ctx;
@@ -465,11 +547,16 @@ ssl_connect_wget (int fd, const char *hostname)
if (!conn)
goto error;
#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
/* If the SSL library was build with support for ServerNameIndication
/* If the SSL library was built with support for ServerNameIndication
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;
@@ -477,6 +564,14 @@ ssl_connect_wget (int fd, const char *hostname)
}
#endif
if (continue_session)
{
/* attempt to resume a previous SSL session */
ctx = (struct openssl_transport_context *) fd_transport_context (*continue_session);
if (!ctx || !ctx->sess || !SSL_set_session (conn, ctx->sess))
goto error;
}
#ifndef FD_TO_SOCKET
# define FD_TO_SOCKET(X) (X)
#endif
@@ -490,11 +585,14 @@ ssl_connect_wget (int fd, const char *hostname)
DEBUGP (("SSL handshake timed out.\n"));
goto timeout;
}
if (scwt_ctx.result <= 0 || conn->state != SSL_ST_OK)
if (scwt_ctx.result <= 0 || !SSL_is_init_finished(conn))
goto error;
ctx = xnew0 (struct openssl_transport_context);
ctx->conn = conn;
ctx->sess = SSL_get0_session (conn);
if (!ctx->sess)
logprintf (LOG_NOTQUIET, "WARNING: Could not save SSL session data for socket %d\n", fd);
/* Register FD with Wget's transport layer, i.e. arrange that our
functions are used for reading, writing, and polling. */
@@ -555,6 +653,86 @@ pattern_match (const char *pattern, const char *string)
return *n == '\0';
}
static char *_get_rfc2253_formatted (X509_NAME *name)
{
int len;
char *out = NULL;
BIO* b;
if ((b = BIO_new (BIO_s_mem ())))
{
if (X509_NAME_print_ex (b, name, 0, XN_FLAG_RFC2253) >= 0
&& (len = BIO_number_written (b)) > 0)
{
out = xmalloc (len + 1);
BIO_read (b, out, len);
out[len] = 0;
}
BIO_free (b);
}
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
@@ -578,6 +756,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. */
@@ -587,6 +766,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)
{
@@ -598,23 +781,25 @@ ssl_check_certificate (int fd, const char *host)
IF_DEBUG
{
char *subject = X509_NAME_oneline (X509_get_subject_name (cert), 0, 0);
char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
char *subject = _get_rfc2253_formatted (X509_get_subject_name (cert));
char *issuer = _get_rfc2253_formatted (X509_get_issuer_name (cert));
DEBUGP (("certificate:\n subject: %s\n issuer: %s\n",
quotearg_n_style (0, escape_quoting_style, subject),
quotearg_n_style (1, escape_quoting_style, issuer)));
OPENSSL_free (subject);
OPENSSL_free (issuer);
xfree (subject);
xfree (issuer);
}
vresult = SSL_get_verify_result (conn);
if (vresult != X509_V_OK)
{
char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
char *issuer = _get_rfc2253_formatted (X509_get_issuer_name (cert));
logprintf (LOG_NOTQUIET,
_("%s: cannot verify %s's certificate, issued by %s:\n"),
severity, quotearg_n_style (0, escape_quoting_style, host),
quote_n (1, issuer));
xfree(issuer);
/* Try to print more user-friendly (and translated) messages for
the frequent verification errors. */
switch (vresult)
@@ -661,9 +846,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;
@@ -698,7 +886,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)))
{
@@ -710,7 +898,7 @@ ssl_check_certificate (int fd, const char *host)
}
}
}
sk_GENERAL_NAME_free (subjectAltNames);
sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
if (host_in_octet_string)
ASN1_OCTET_STRING_free(host_in_octet_string);
@@ -719,9 +907,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)
@@ -776,6 +966,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",
@@ -783,13 +980,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,7 @@
/* struct options.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -29,6 +29,13 @@ Corresponding Source for a non-source form of such a combination
shall include the source code for the parts of OpenSSL used as well
as that of the covered work. */
enum CHECK_CERT_MODES
{
CHECK_CERT_OFF,
CHECK_CERT_ON,
CHECK_CERT_QUIET
};
struct options
{
int verbose; /* Are we verbose? (First set to -1,
@@ -58,6 +65,12 @@ struct options
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
char *choose_config; /* Specified config file */
bool noconfig; /* Ignore all config files? */
bool force_html; /* Is the input file an HTML file? */
@@ -87,6 +100,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. */
@@ -110,9 +128,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. */
@@ -133,7 +154,7 @@ struct options
char **no_proxy;
char *base_href;
char *progress_type; /* progress indicator type. */
bool show_progress; /* Show only the progress bar */
int show_progress; /* Show only the progress bar */
bool noscroll; /* Don't scroll the filename in the progressbar */
char *proxy_user; /*oli*/
char *proxy_passwd;
@@ -165,6 +186,7 @@ struct options
#endif
bool timestamping; /* Whether to use time-stamping. */
bool if_modified_since; /* Whether to use conditional get requests. */
bool backup_converted; /* Do we save pre-converted files as *.orig? */
int backups; /* Are numeric backups made? */
@@ -176,6 +198,9 @@ struct options
NULL. */
bool convert_links; /* Will the links be converted
locally? */
bool convert_file_only; /* Convert only the file portion of the URI (i.e. basename).
Leave everything else untouched. */
bool remove_listing; /* Do we remove .listing files
generated by FTP? */
bool htmlify; /* Do we HTML-ify the OS-dependent
@@ -202,9 +227,11 @@ struct options
secure_protocol_sslv2,
secure_protocol_sslv3,
secure_protocol_tlsv1,
secure_protocol_tlsv1_1,
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 {
@@ -216,15 +243,26 @@ struct options
char *ca_directory; /* CA directory (hash files) */
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 */
bool ftps_resume_ssl;
bool ftps_fallback_to_ftp;
bool ftps_implicit;
bool ftps_clear_data_connection;
#endif /* HAVE_SSL */
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. */
@@ -236,6 +274,7 @@ struct options
enum {
restrict_unix,
restrict_vms,
restrict_windows
} restrict_files_os; /* file name restriction ruleset. */
bool restrict_files_ctrl; /* non-zero if control chars in URLs
@@ -272,7 +311,7 @@ struct options
bool enable_iri;
char *encoding_remote;
char *locale;
const char *locale;
bool trustservernames;
#ifdef __VMS
@@ -285,6 +324,13 @@ struct options
bool show_all_dns_entries; /* Show all the DNS entries when resolving a
name. */
bool report_bps; /*Output bandwidth in bits format*/
char *rejected_log; /* The file to log rejected URLS to. */
#ifdef HAVE_HSTS
bool hsts;
char *hsts_file;
#endif
};
extern struct options opt;

View File

@@ -1,6 +1,6 @@
/* Download progress.
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010, 2011 Free Software Foundation, Inc.
2010, 2011, 2015 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -37,10 +37,12 @@ as that of the covered work. */
#include <unistd.h>
#include <signal.h>
#include <wchar.h>
#include <mbiter.h>
#include "progress.h"
#include "utils.h"
#include "retr.h"
#include "c-strcase.h"
struct progress_implementation {
const char *name;
@@ -194,7 +196,7 @@ progress_finish (void *progress, double dltime)
{
current_impl->finish (progress, dltime);
}
/* Dot-printing. */
struct dot_progress {
@@ -426,7 +428,7 @@ dot_set_params (char *params)
return;
/* We use this to set the retrieval style. */
if (!strcasecmp (params, "default"))
if (!c_strcasecmp (params, "default"))
{
/* Default style: 1K dots, 10 dots in a cluster, 50 dots in a
line. */
@@ -434,7 +436,7 @@ dot_set_params (char *params)
opt.dot_spacing = 10;
opt.dots_in_line = 50;
}
else if (!strcasecmp (params, "binary"))
else if (!c_strcasecmp (params, "binary"))
{
/* "Binary" retrieval: 8K dots, 16 dots in a cluster, 48 dots
(384K) in a line. */
@@ -442,7 +444,7 @@ dot_set_params (char *params)
opt.dot_spacing = 16;
opt.dots_in_line = 48;
}
else if (!strcasecmp (params, "mega"))
else if (!c_strcasecmp (params, "mega"))
{
/* "Mega" retrieval, for retrieving very long files; each dot is
64K, 8 dots in a cluster, 6 clusters (3M) in a line. */
@@ -450,7 +452,7 @@ dot_set_params (char *params)
opt.dot_spacing = 8;
opt.dots_in_line = 48;
}
else if (!strcasecmp (params, "giga"))
else if (!c_strcasecmp (params, "giga"))
{
/* "Giga" retrieval, for retrieving very very *very* long files;
each dot is 1M, 8 dots in a cluster, 4 clusters (32M) in a
@@ -464,7 +466,7 @@ dot_set_params (char *params)
_("Invalid dot style specification %s; leaving unchanged.\n"),
quote (params));
}
/* "Thermometer" (bar) progress. */
/* Assumed screen width if we can't find the real value. */
@@ -592,7 +594,8 @@ bar_create (const char *f_download, wgint initial, wgint total)
bp->width = screen_width - 1;
/* + enough space for the terminating zero, and hopefully enough room
* for multibyte characters. */
bp->buffer = xmalloc (bp->width + 100);
#define BUF_LEN (bp->width + 100)
bp->buffer = xmalloc (BUF_LEN);
logputs (LOG_VERBOSE, "\n");
@@ -691,7 +694,7 @@ bar_finish (void *progress, double dltime)
The idea is that for fast downloads, we get the speed over exactly
the last three seconds. For slow downloads (where a network read
takes more than 150ms to complete), we get the speed over a larger
time period, as large as it takes to complete thirty reads. This
time period, as large as it takes to complete twenty reads. This
is good because slow downloads tend to fluctuate more and a
3-second average would be too erratic. */
@@ -812,8 +815,39 @@ count_cols (const char *mbs)
}
return cols;
}
static int
cols_to_bytes (const char *mbs, const int cols, int *ncols)
{
int p_cols = 0, bytes = 0;
mbchar_t mbc;
mbi_iterator_t iter;
mbi_init (iter, mbs, strlen(mbs));
while (p_cols < cols && mbi_avail (iter))
{
mbc = mbi_cur (iter);
p_cols += mb_width (mbc);
/* The multibyte character has exceeded the total number of columns we
* have available. The remaining bytes will be padded with a space. */
if (p_cols > cols)
{
p_cols -= mb_width (mbc);
break;
}
bytes += mb_len (mbc);
mbi_advance (iter);
}
*ncols = p_cols;
return bytes;
}
#else
# define count_cols(mbs) ((int)(strlen(mbs)))
static int count_cols (const char *mbs) { return (int) strlen(mbs); }
static int
cols_to_bytes (const char *mbs _GL_UNUSED, const int cols, int *ncols)
{
*ncols = cols;
return cols;
}
#endif
static const char *
@@ -821,7 +855,7 @@ get_eta (int *bcd)
{
/* TRANSLATORS: "ETA" is English-centric, but this must
be short, ideally 3 chars. Abbreviate if necessary. */
static const char eta_str[] = N_(" eta %s");
static const char eta_str[] = N_(" eta %s");
static const char *eta_trans;
static int bytes_cols_diff;
if (eta_trans == NULL)
@@ -858,33 +892,17 @@ 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');
#ifndef MAX
# define MAX(a, b) ((a) >= (b) ? (a) : (b))
#endif
#ifndef MIN
# define MIN(a, b) ((a) <= (b) ? (a) : (b))
#endif
static void
create_image (struct bar_progress *bp, double dl_total_time, bool done)
{
const int MAX_FILENAME_LEN = bp->width / 4;
const int MAX_FILENAME_COLS = bp->width / 4;
char *p = bp->buffer;
wgint size = bp->initial_length + bp->count;
const char *size_grouped = with_thousand_seps (size);
int size_grouped_len = count_cols (size_grouped);
/* Difference between num cols and num bytes: */
int size_grouped_diff = strlen (size_grouped) - size_grouped_len;
int size_grouped_pad; /* Used to pad the field width for size_grouped. */
struct bar_progress_hist *hist = &bp->hist;
int orig_filename_len = strlen (bp->f_download);
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
@@ -896,7 +914,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
It would be especially bad for the progress bar to be resized
randomly.
"file " - Downloaded filename - MAX_FILENAME_LEN chars + 1
"file " - Downloaded filename - MAX_FILENAME_COLS chars + 1
"xx% " or "100%" - percentage - 4 chars
"[]" - progress bar decorations - 2 chars
" nnn.nnK" - downloaded bytes - 7 chars + 1
@@ -906,12 +924,16 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
"=====>..." - progress bar - the rest
*/
#define PROGRESS_FILENAME_LEN MAX_FILENAME_LEN + 1
/* 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 +
@@ -920,29 +942,58 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
/* The difference between the number of bytes used,
and the number of columns used. */
int bytes_cols_diff = 0;
int cols_diff;
const char *down_size;
memset (bp->buffer, '\0', BUF_LEN);
if (progress_size < 5)
progress_size = 0;
if (orig_filename_len <= MAX_FILENAME_LEN)
if (orig_filename_cols <= MAX_FILENAME_COLS)
{
int padding = MAX_FILENAME_LEN - orig_filename_len;
sprintf (p, "%s ", bp->f_download);
p += orig_filename_len + 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;
int offset_cols;
int bytes_in_filename, offset_bytes, col;
int *cols_ret = &col;
if (((orig_filename_len > MAX_FILENAME_LEN) && !opt.noscroll) && !done)
offset = ((int) bp->tick) % (orig_filename_len - MAX_FILENAME_LEN);
#define MIN_SCROLL_TEXT 5
if ((orig_filename_cols > MAX_FILENAME_COLS + MIN_SCROLL_TEXT) &&
!opt.noscroll &&
!done)
{
offset_cols = ((int) bp->tick + orig_filename_cols + MAX_FILENAME_COLS / 2)
% (orig_filename_cols + MAX_FILENAME_COLS);
if (offset_cols > orig_filename_cols)
{
padding = MAX_FILENAME_COLS - (offset_cols - orig_filename_cols);
memset(p, ' ', padding);
p += padding;
offset_cols = 0;
}
else
padding = 0;
}
else
offset = 0;
memcpy (p, bp->f_download + offset, MAX_FILENAME_LEN);
p += MAX_FILENAME_LEN;
*p++ = ' ';
{
padding = 0;
offset_cols = 0;
}
offset_bytes = cols_to_bytes (bp->f_download, offset_cols, cols_ret);
bytes_in_filename = cols_to_bytes (bp->f_download + offset_bytes,
MAX_FILENAME_COLS - padding,
cols_ret);
memcpy (p, bp->f_download + offset_bytes, bytes_in_filename);
p += bytes_in_filename;
padding = MAX_FILENAME_COLS - (padding + *cols_ret);
memset (p, ' ', padding + 1);
p += padding + 1;
}
/* "xx% " */
@@ -950,15 +1001,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)
@@ -970,7 +1019,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);
@@ -980,18 +1028,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)
@@ -1019,27 +1068,14 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
*p++ = ']';
}
++bp->tick;
++bp->tick;
/* " 234.56M" */
const char * down_size = human_readable (size, 1000, 2);
int 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++ = ' ';
}
down_size = human_readable (size, 1000, 2);
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)
@@ -1052,12 +1088,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)
{
@@ -1092,14 +1127,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
@@ -1109,22 +1144,38 @@ 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 - size_grouped_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>
* Assert that the length of the progress bar is lesser than the size of the
* screen with which we are dealing. This assertion *MUST* always be removed
* 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);
}
/* Print the contents of the buffer as a one-line ASCII "image" so
@@ -1142,8 +1193,6 @@ display_image (char *buf)
static void
bar_set_params (char *params)
{
char *term = getenv ("TERM");
if (params)
{
char *param = strtok (params, ":");
@@ -1156,19 +1205,13 @@ bar_set_params (char *params)
} while ((param = strtok (NULL, ":")) != NULL);
}
if ((opt.lfilename
if (((opt.lfilename && opt.show_progress != 1)
#ifdef HAVE_ISATTY
/* The progress bar doesn't make sense if the output is not a
TTY -- when logging to file, it is better to review the
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,6 @@
/* Download progress.
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010, 2011 Free Software Foundation, Inc.
2010, 2011, 2015 Free Software Foundation, Inc.
This file is part of GNU Wget.

View File

@@ -1,6 +1,6 @@
/* Portable timers.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
Foundation, Inc.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
This file is part of GNU Wget.
@@ -291,7 +291,7 @@ windows_resolution (void)
return 10; /* according to MSDN */
}
#endif /* PTIMER_WINDOWS */
/* The code below this point is independent of timer implementation. */
struct ptimer {

View File

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

View File

@@ -1,7 +1,7 @@
/* Handling of recursive HTTP retrieving.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -50,7 +50,8 @@ as that of the covered work. */
#include "html-url.h"
#include "css-url.h"
#include "spider.h"
#include "exits.h"
/* Functions for maintaining the URL queue. */
struct queue_element {
@@ -159,12 +160,42 @@ url_dequeue (struct url_queue *queue, struct iri **i,
xfree (qel);
return true;
}
static bool download_child_p (const struct urlpos *, struct url *, int,
struct url *, struct hash_table *, struct iri *);
static bool descend_redirect_p (const char *, struct url *, int,
struct url *, struct hash_table *, struct iri *);
static void blacklist_add (struct hash_table *blacklist, const char *url)
{
char *url_unescaped = xstrdup (url);
url_unescape (url_unescaped);
string_set_add (blacklist, url_unescaped);
xfree (url_unescaped);
}
static int blacklist_contains (struct hash_table *blacklist, const char *url)
{
char *url_unescaped = xstrdup(url);
int ret;
url_unescape (url_unescaped);
ret = string_set_contains (blacklist, url_unescaped);
xfree (url_unescaped);
return ret;
}
typedef enum
{
WG_RR_SUCCESS, WG_RR_BLACKLIST, WG_RR_NOTHTTPS, WG_RR_NONHTTP, WG_RR_ABSOLUTE,
WG_RR_DOMAIN, WG_RR_PARENT, WG_RR_LIST, WG_RR_REGEX, WG_RR_RULES,
WG_RR_SPANNEDHOST, WG_RR_ROBOTS
} reject_reason;
static reject_reason download_child (const struct urlpos *, struct url *, int,
struct url *, struct hash_table *, struct iri *);
static reject_reason descend_redirect (const char *, struct url *, int,
struct url *, struct hash_table *, struct iri *);
static void write_reject_log_header (FILE *);
static void write_reject_log_reason (FILE *, reject_reason,
const struct url *, const struct url *);
/* Retrieve a part of the web beginning with START_URL. This used to
be called "recursive retrieval", because the old function was
@@ -201,17 +232,21 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
struct iri *i = iri_new ();
#define COPYSTR(x) (x) ? xstrdup(x) : NULL;
FILE *rejectedlog = NULL; /* Don't write a rejected log. */
/* 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);
@@ -220,7 +255,15 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
just URL so we enqueue the canonical form of the URL. */
url_enqueue (queue, i, xstrdup (start_url_parsed->url), NULL, 0, true,
false);
string_set_add (blacklist, start_url_parsed->url);
blacklist_add (blacklist, start_url_parsed->url);
if (opt.rejected_log)
{
rejectedlog = fopen (opt.rejected_log, "w");
write_reject_log_header (rejectedlog);
if (!rejectedlog)
logprintf (LOG_NOTQUIET, "%s: %s\n", opt.rejected_log, strerror (errno));
}
while (1)
{
@@ -244,9 +287,9 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
break;
/* ...and download it. Note that this download is in most cases
unconditional, as download_child_p already makes sure a file
unconditional, as download_child already makes sure a file
doesn't get enqueued twice -- and yet this check is here, and
not in download_child_p. This is so that if you run `wget -r
not in download_child. This is so that if you run `wget -r
URL1 URL2', and a random URL is encountered once under URL1
and again under URL2, but at a different (possibly smaller)
depth, we want the URL's children to be taken into account
@@ -277,52 +320,69 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
char *redirected = NULL;
struct url *url_parsed = url_parse (url, &url_err, i, true);
status = retrieve_url (url_parsed, url, &file, &redirected, referer,
&dt, false, i, true);
if (html_allowed && file && status == RETROK
&& (dt & RETROKF) && (dt & TEXTHTML))
if (!url_parsed)
{
descend = true;
is_css = false;
}
/* a little different, css_allowed can override content type
lots of web servers serve css with an incorrect content type
*/
if (file && status == RETROK
&& (dt & RETROKF) &&
((dt & TEXTCSS) || css_allowed))
{
descend = true;
is_css = true;
}
if (redirected)
{
/* We have been redirected, possibly to another host, or
different path, or wherever. Check whether we really
want to follow it. */
if (descend)
{
if (!descend_redirect_p (redirected, url_parsed, depth,
start_url_parsed, blacklist, i))
descend = false;
else
/* Make sure that the old pre-redirect form gets
blacklisted. */
string_set_add (blacklist, url);
}
xfree (url);
url = redirected;
char *error = url_error (url, url_err);
logprintf (LOG_NOTQUIET, "%s: %s.\n",url, error);
xfree (error);
inform_exit_status (URLERROR);
}
else
{
xfree (url);
url = xstrdup (url_parsed->url);
status = retrieve_url (url_parsed, url, &file, &redirected, referer,
&dt, false, i, true);
if (html_allowed && file && status == RETROK
&& (dt & RETROKF) && (dt & TEXTHTML))
{
descend = true;
is_css = false;
}
/* a little different, css_allowed can override content type
lots of web servers serve css with an incorrect content type
*/
if (file && status == RETROK
&& (dt & RETROKF) &&
((dt & TEXTCSS) || css_allowed))
{
descend = true;
is_css = true;
}
if (redirected)
{
/* We have been redirected, possibly to another host, or
different path, or wherever. Check whether we really
want to follow it. */
if (descend)
{
reject_reason r = descend_redirect (redirected, url_parsed,
depth, start_url_parsed, blacklist, i);
if (r == WG_RR_SUCCESS)
{
/* Make sure that the old pre-redirect form gets
blacklisted. */
blacklist_add (blacklist, url);
}
else
{
write_reject_log_reason (rejectedlog, r, url_parsed, start_url_parsed);
descend = false;
}
}
xfree (url);
url = redirected;
}
else
{
xfree (url);
url = xstrdup (url_parsed->url);
}
url_free (url_parsed);
}
url_free(url_parsed);
}
if (opt.spider)
@@ -378,22 +438,38 @@ 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);
for (; child; child = child->next)
{
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;
if (download_child_p (child, url_parsed, depth, start_url_parsed,
blacklist, i))
{
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);
if (r == WG_RR_SUCCESS)
{
ci = iri_new ();
set_uri_encoding (ci, i->content_encoding, false);
@@ -404,7 +480,11 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
/* We blacklist the URL we have enqueued, because we
don't want to enqueue (and hence download) the
same URL twice. */
string_set_add (blacklist, child->url->url);
blacklist_add (blacklist, child->url->url);
}
else
{
write_reject_log_reason (rejectedlog, r, child->url, url_parsed);
}
}
@@ -440,11 +520,14 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
}
xfree (url);
xfree_null (referer);
xfree_null (file);
xfree (referer);
xfree (file);
iri_free (i);
}
if (rejectedlog)
fclose (rejectedlog);
/* If anything is left of the queue due to a premature exit, free it
now. */
{
@@ -457,7 +540,7 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
{
iri_free (d6);
xfree (d1);
xfree_null (d2);
xfree (d2);
}
}
url_queue_delete (queue);
@@ -480,27 +563,29 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
by storing these URLs to BLACKLIST. This may or may not help. It
will help if those URLs are encountered many times. */
static bool
download_child_p (const struct urlpos *upos, struct url *parent, int depth,
static reject_reason
download_child (const struct urlpos *upos, struct url *parent, int depth,
struct url *start_url_parsed, struct hash_table *blacklist,
struct iri *iri)
{
struct url *u = upos->url;
const char *url = u->url;
bool u_scheme_like_http;
reject_reason reason = WG_RR_SUCCESS;
DEBUGP (("Deciding whether to enqueue \"%s\".\n", url));
if (string_set_contains (blacklist, url))
if (blacklist_contains (blacklist, url))
{
if (opt.spider)
{
char *referrer = url_string (parent, URL_AUTH_HIDE_PASSWD);
DEBUGP (("download_child_p: parent->url is: %s\n", quote (parent->url)));
DEBUGP (("download_child: parent->url is: %s\n", quote (parent->url)));
visited_url (url, referrer);
xfree (referrer);
}
DEBUGP (("Already on the black list.\n"));
reason = WG_RR_BLACKLIST;
goto out;
}
@@ -530,6 +615,7 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
if (opt.https_only && u->scheme != SCHEME_HTTPS)
{
DEBUGP (("Not following non-HTTPS links.\n"));
reason = WG_RR_NOTHTTPS;
goto out;
}
#endif
@@ -538,9 +624,14 @@ download_child_p (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 && 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;
goto out;
}
@@ -550,6 +641,7 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
if (opt.relative_only && !upos->link_relative_p)
{
DEBUGP (("It doesn't really look like a relative link.\n"));
reason = WG_RR_ABSOLUTE;
goto out;
}
@@ -558,6 +650,7 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
if (!accept_domain (u))
{
DEBUGP (("The domain was not accepted.\n"));
reason = WG_RR_DOMAIN;
goto out;
}
@@ -577,6 +670,7 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
{
DEBUGP (("Going to \"%s\" would escape \"%s\" with no_parent on.\n",
u->dir, start_url_parsed->dir));
reason = WG_RR_PARENT;
goto out;
}
}
@@ -589,12 +683,14 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
if (!accdir (u->dir))
{
DEBUGP (("%s (%s) is excluded/not-included.\n", url, u->dir));
reason = WG_RR_LIST;
goto out;
}
}
if (!accept_url (url))
{
DEBUGP (("%s is excluded/not-included through regex.\n", url));
reason = WG_RR_REGEX;
goto out;
}
@@ -619,6 +715,7 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
{
DEBUGP (("%s (%s) does not match acc/rej rules.\n",
url, u->file));
reason = WG_RR_RULES;
goto out;
}
}
@@ -629,6 +726,7 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
{
DEBUGP (("This is not the same hostname as the parent's (%s and %s).\n",
u->host, parent->host));
reason = WG_RR_SPANNEDHOST;
goto out;
}
@@ -670,36 +768,37 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
if (!res_match_path (specs, u->path))
{
DEBUGP (("Not following %s because robots.txt forbids it.\n", url));
string_set_add (blacklist, url);
blacklist_add (blacklist, url);
reason = WG_RR_ROBOTS;
goto out;
}
}
/* The URL has passed all the tests. It can be placed in the
download queue. */
DEBUGP (("Decided to load it.\n"));
out:
return true;
if (reason == WG_RR_SUCCESS)
/* The URL has passed all the tests. It can be placed in the
download queue. */
DEBUGP (("Decided to load it.\n"));
else
DEBUGP (("Decided NOT to load it.\n"));
out:
DEBUGP (("Decided NOT to load it.\n"));
return false;
return reason;
}
/* This function determines whether we will consider downloading the
children of a URL whose download resulted in a redirection,
possibly to another host, etc. It is needed very rarely, and thus
it is merely a simple-minded wrapper around download_child_p. */
it is merely a simple-minded wrapper around download_child. */
static bool
descend_redirect_p (const char *redirected, struct url *orig_parsed, int depth,
static reject_reason
descend_redirect (const char *redirected, struct url *orig_parsed, int depth,
struct url *start_url_parsed, struct hash_table *blacklist,
struct iri *iri)
{
struct url *new_parsed;
struct urlpos *upos;
bool success;
reject_reason reason;
assert (orig_parsed != NULL);
@@ -709,16 +808,110 @@ descend_redirect_p (const char *redirected, struct url *orig_parsed, int depth,
upos = xnew0 (struct urlpos);
upos->url = new_parsed;
success = download_child_p (upos, orig_parsed, depth,
reason = download_child (upos, orig_parsed, depth,
start_url_parsed, blacklist, iri);
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));
url_free (new_parsed);
xfree (upos);
if (!success)
DEBUGP (("Redirection \"%s\" failed the test.\n", redirected));
return reason;
}
return success;
/* This function writes the rejected log header. */
static void
write_reject_log_header (FILE *f)
{
if (!f)
return;
/* Note: Update this header when columns change in any way. */
fprintf (f, "REASON\t"
"U_URL\tU_SCHEME\tU_HOST\tU_PORT\tU_PATH\tU_PARAMS\tU_QUERY\tU_FRAGMENT\t"
"P_URL\tP_SCHEME\tP_HOST\tP_PORT\tP_PATH\tP_PARAMS\tP_QUERY\tP_FRAGMENT\n");
}
/* This function writes a URL to the reject log. Internal use only. */
static void
write_reject_log_url (FILE *fp, const struct url *url)
{
const char *escaped_str;
const char *scheme_str;
if (!fp)
return;
escaped_str = url_escape (url->url);
switch (url->scheme)
{
case SCHEME_HTTP: scheme_str = "SCHEME_HTTP"; break;
#ifdef HAVE_SSL
case SCHEME_HTTPS: scheme_str = "SCHEME_HTTPS"; break;
case SCHEME_FTPS: scheme_str = "SCHEME_FTPS"; break;
#endif
case SCHEME_FTP: scheme_str = "SCHEME_FTP"; break;
default: scheme_str = "SCHEME_INVALID"; break;
}
fprintf (fp, "%s\t%s\t%s\t%i\t%s\t%s\t%s\t%s",
escaped_str,
scheme_str,
url->host,
url->port,
url->path,
url->params ? url->params : "",
url->query ? url->query : "",
url->fragment ? url->fragment : "");
xfree (escaped_str);
}
/* This function writes out information on why a URL was rejected and its
context from download_child such as the URL being rejected and it's
parent's URL. The format it uses is comma separated values but with tabs. */
static void
write_reject_log_reason (FILE *fp, reject_reason reason,
const struct url *url, const struct url *parent)
{
const char *reason_str;
if (!fp)
return;
switch (reason)
{
case WG_RR_SUCCESS: reason_str = "SUCCESS"; break;
case WG_RR_BLACKLIST: reason_str = "BLACKLIST"; break;
case WG_RR_NOTHTTPS: reason_str = "NOTHTTPS"; break;
case WG_RR_NONHTTP: reason_str = "NONHTTP"; break;
case WG_RR_ABSOLUTE: reason_str = "ABSOLUTE"; break;
case WG_RR_DOMAIN: reason_str = "DOMAIN"; break;
case WG_RR_PARENT: reason_str = "PARENT"; break;
case WG_RR_LIST: reason_str = "LIST"; break;
case WG_RR_REGEX: reason_str = "REGEX"; break;
case WG_RR_RULES: reason_str = "RULES"; break;
case WG_RR_SPANNEDHOST: reason_str = "SPANNEDHOST"; break;
case WG_RR_ROBOTS: reason_str = "ROBOTS"; break;
default: reason_str = "UNKNOWN"; break;
}
fprintf (fp, "%s\t", reason_str);
write_reject_log_url (fp, url);
fprintf (fp, "\t");
write_reject_log_url (fp, parent);
fprintf (fp, "\n");
}
/* vim:set sts=2 sw=2 cino+={s: */

View File

@@ -1,7 +1,7 @@
/* Declarations for recur.c.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 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 Free Software
Foundation, Inc.
Copyright (C) 2001, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
This file is part of Wget.
@@ -81,6 +81,7 @@ as that of the covered work. */
#include "url.h"
#include "retr.h"
#include "res.h"
#include "c-strcase.h"
#ifdef TESTING
#include "test.h"
@@ -97,7 +98,7 @@ struct robot_specs {
int size;
struct path_info *paths;
};
/* Parsing the robot spec. */
/* Check whether AGENT (a string of length LENGTH) equals "wget" or
@@ -403,10 +404,10 @@ free_specs (struct robot_specs *specs)
int i;
for (i = 0; i < specs->count; i++)
xfree (specs->paths[i].path);
xfree_null (specs->paths);
xfree (specs->paths);
xfree (specs);
}
/* Matching of a path according to the specs. */
/* If C is '%' and (ptr[1], ptr[2]) form a hexadecimal number, and if
@@ -471,7 +472,7 @@ res_match_path (const struct robot_specs *specs, const char *path)
}
return true;
}
/* Registering the specs. */
static struct hash_table *registered_specs;
@@ -521,7 +522,7 @@ res_get_specs (const char *host, int port)
return NULL;
return hash_table_get (registered_specs, hp);
}
/* Loading the robots file. */
#define RES_SPECS_LOCATION "/robots.txt"
@@ -578,11 +579,10 @@ res_retrieve_file (const char *url, char **file, struct iri *iri)
allocated the file name, deallocate is here so that the
caller doesn't have to worry about it. */
xfree (*file);
*file = NULL;
}
return err == RETROK;
}
bool
is_robots_txt_url (const char *url)
{
@@ -593,7 +593,7 @@ is_robots_txt_url (const char *url)
return ret;
}
void
res_cleanup (void)
{
@@ -611,7 +611,7 @@ res_cleanup (void)
registered_specs = NULL;
}
}
#ifdef TESTING
const char *

View File

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

View File

@@ -1,7 +1,7 @@
/* File retrieval.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -56,6 +56,7 @@ as that of the covered work. */
#include "ptimer.h"
#include "html-url.h"
#include "iri.h"
#include "hsts.h"
/* Total size of downloaded files. Used to enforce quota. */
SUM_SIZE_INT total_downloaded_bytes;
@@ -70,7 +71,7 @@ FILE *output_stream;
/* Whether output_document is a regular file we can manipulate,
i.e. not `-' or a device file. */
bool output_stream_regular;
static struct {
wgint chunk_bytes;
double chunk_start;
@@ -136,10 +137,6 @@ limit_bandwidth (wgint bytes, struct ptimer *timer)
limit_data.chunk_start = ptimer_read (timer);
}
#ifndef MIN
# define MIN(i, j) ((i) <= (j) ? (i) : (j))
#endif
/* Write data in BUF to OUT. However, if *SKIP is non-zero, skip that
amount of data and decrease SKIP. Increment *TOTAL by the amount
of data written. If OUT2 is not NULL, also write BUF to OUT2.
@@ -265,11 +262,16 @@ fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread,
if (opt.show_progress)
{
const char *filename_progress;
/* If we're skipping STARTPOS bytes, pass 0 as the INITIAL
argument to progress_create because the indicator doesn't
(yet) know about "skipping" data. */
wgint start = skip ? 0 : startpos;
progress = progress_create (downloaded_filename, start, start + toread);
if (opt.dir_prefix)
filename_progress = downloaded_filename + strlen (opt.dir_prefix) + 1;
else
filename_progress = downloaded_filename;
progress = progress_create (filename_progress, start, start + toread);
progress_interactive = progress_interactive_p (progress);
}
@@ -378,8 +380,10 @@ fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread,
if (ret > 0)
{
int write_res;
sum_read += ret;
int write_res = write_data (out, out2, dlbuf, ret, &skip, &sum_written);
write_res = write_data (out, out2, dlbuf, ret, &skip, &sum_written);
if (write_res < 0)
{
ret = (write_res == -3) ? -3 : -2;
@@ -434,11 +438,11 @@ fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread,
if (qtywritten)
*qtywritten += sum_written;
free (dlbuf);
xfree (dlbuf);
return ret;
}
/* Read a hunk of data from FD, up until a terminator. The hunk is
limited by whatever the TERMINATOR callback chooses as its
terminator. For example, if terminator stops at newline, the hunk
@@ -543,7 +547,7 @@ fd_read_hunk (int fd, hunk_terminator_t terminator, long sizehint, long maxsize)
rdlen = fd_read (fd, hunk + tail, remain, 0);
if (rdlen < 0)
{
xfree_null (hunk);
xfree (hunk);
return NULL;
}
tail += rdlen;
@@ -615,7 +619,7 @@ fd_read_line (int fd)
{
return fd_read_hunk (fd, line_terminator, 128, FD_READ_LINE_MAX);
}
/* Return a printed representation of the download rate, along with
the units appropriate for the download speed. */
@@ -630,7 +634,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]);
@@ -679,7 +683,7 @@ calc_rate (wgint bytes, double secs, int *units)
return dlrate;
}
#define SUSPEND_METHOD do { \
method_suspended = true; \
@@ -722,7 +726,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
char *mynewloc, *proxy;
struct url *u = orig_parsed, *proxy_url;
int up_error_code; /* url parse error code */
char *local_file;
char *local_file = NULL;
int redirection_count = 0;
bool method_suspended = false;
@@ -750,7 +754,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
result = NOCONERROR;
mynewloc = NULL;
local_file = NULL;
xfree(local_file);
proxy_url = NULL;
proxy = getproxy (u);
@@ -761,7 +765,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
pi->utf8_encode = false;
/* Parse the proxy URL. */
proxy_url = url_parse (proxy, &up_error_code, NULL, true);
proxy_url = url_parse (proxy, &up_error_code, pi, true);
if (!proxy_url)
{
char *error = url_error (proxy, up_error_code);
@@ -769,6 +773,8 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
proxy, error);
xfree (url);
xfree (error);
xfree (proxy);
iri_free (pi);
RESTORE_METHOD;
result = PROXERR;
goto bail;
@@ -778,11 +784,14 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
logprintf (LOG_NOTQUIET, _("Error in proxy URL %s: Must be HTTP.\n"), proxy);
url_free (proxy_url);
xfree (url);
xfree (proxy);
iri_free (pi);
RESTORE_METHOD;
result = PROXERR;
goto bail;
}
free (proxy);
iri_free(pi);
xfree (proxy);
}
if (u->scheme == SCHEME_HTTP
@@ -791,10 +800,28 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
#endif
|| (proxy_url && proxy_url->scheme == SCHEME_HTTP))
{
#ifdef HAVE_HSTS
#ifdef TESTING
/* we don't link against main.o when we're testing */
hsts_store_t hsts_store = NULL;
#else
extern hsts_store_t hsts_store;
#endif
if (opt.hsts && hsts_store)
{
if (hsts_match (hsts_store, u))
logprintf (LOG_VERBOSE, "URL transformed to HTTPS due to an HSTS policy\n");
}
#endif
result = http_loop (u, orig_parsed, &mynewloc, &local_file, refurl, dt,
proxy_url, iri);
}
else if (u->scheme == SCHEME_FTP)
else if (u->scheme == SCHEME_FTP
#ifdef HAVE_SSL
|| u->scheme == SCHEME_FTPS
#endif
)
{
/* If this is a redirection, temporarily turn off opt.ftp_glob
and opt.recursive, both being undesirable when following
@@ -803,14 +830,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)
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;
@@ -831,23 +863,25 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
assert (mynewloc != NULL);
if (local_file)
xfree (local_file);
xfree (local_file);
/* The HTTP specs only allow absolute URLs to appear in
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_null (iri->orig_url);
iri->orig_url = NULL;
xfree (iri->orig_url);
#endif
/* Now, see if this new location makes sense. */
newloc_parsed = url_parse (mynewloc, &up_error_code, iri, true);
@@ -913,6 +947,10 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
goto redirected;
}
else
{
xfree(mynewloc);
}
/* Try to not encode in UTF-8 if fetching failed */
if (!(*dt & RETROKF) && iri->utf8_encode)
@@ -926,6 +964,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
if (u)
{
DEBUGP (("[IRI fallbacking to non-utf8 for %s\n", quote (url)));
xfree (url);
url = xstrdup (u->url);
iri_fallbacked = 1;
goto redirected;
@@ -934,7 +973,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
DEBUGP (("[Couldn't fallback to non-utf8 for %s\n", quote (url)));
}
if (local_file && u && *dt & RETROKF)
if (local_file && u && (*dt & RETROKF || opt.content_on_error))
{
register_download (u->url, local_file);
@@ -951,7 +990,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
if (file)
*file = local_file ? local_file : NULL;
else
xfree_null (local_file);
xfree (local_file);
if (orig_parsed != u)
{
@@ -977,6 +1016,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
bail:
if (register_status)
inform_exit_status (result);
return result;
}
@@ -1012,6 +1052,7 @@ retrieve_from_file (const char *file, bool html, int *count)
char *error = url_error (url, url_err);
logprintf (LOG_NOTQUIET, "%s: %s.\n", url, error);
xfree (error);
iri_free (iri);
return URLERROR;
}
@@ -1028,15 +1069,16 @@ 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;
xfree_null (iri->orig_url);
iri->orig_url = NULL;
xfree (iri->orig_url);
input_file = url_file;
}
@@ -1046,12 +1088,12 @@ retrieve_from_file (const char *file, bool html, int *count)
url_list = (html ? get_urls_html (input_file, NULL, NULL, iri)
: get_urls_file (input_file));
xfree_null (url_file);
xfree (url_file);
for (cur_url = url_list; cur_url; cur_url = cur_url->next, ++*count)
{
char *filename = NULL, *new_file = NULL;
int dt;
char *filename = NULL, *new_file = NULL, *proxy;
int dt = 0;
struct iri *tmpiri = iri_dup (iri);
struct url *parsed_url = NULL;
@@ -1066,14 +1108,22 @@ retrieve_from_file (const char *file, bool html, int *count)
parsed_url = url_parse (cur_url->url->url, NULL, tmpiri, true);
char *proxy = getproxy (cur_url->url);
proxy = getproxy (cur_url->url);
if ((opt.recursive || opt.page_requisites)
&& (cur_url->url->scheme != SCHEME_FTP || 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)
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,
@@ -1086,7 +1136,7 @@ retrieve_from_file (const char *file, bool html, int *count)
cur_url->url->url, &filename,
&new_file, NULL, &dt, opt.recursive, tmpiri,
true);
free(proxy);
xfree (proxy);
if (parsed_url)
url_free (parsed_url);
@@ -1097,12 +1147,12 @@ retrieve_from_file (const char *file, bool html, int *count)
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;
}
xfree_null (new_file);
xfree_null (filename);
xfree (new_file);
xfree (filename);
iri_free (tmpiri);
}
@@ -1178,7 +1228,7 @@ free_urlpos (struct urlpos *l)
struct urlpos *next = l->next;
if (l->url)
url_free (l->url);
xfree_null (l->local_name);
xfree (l->local_name);
xfree (l);
l = next;
}
@@ -1198,9 +1248,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)
@@ -1217,17 +1267,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 **);
@@ -1254,6 +1308,9 @@ getproxy (struct url *u)
case SCHEME_HTTPS:
proxy = opt.https_proxy ? opt.https_proxy : getenv ("https_proxy");
break;
case SCHEME_FTPS:
proxy = opt.ftp_proxy ? opt.ftp_proxy : getenv ("ftps_proxy");
break;
#endif
case SCHEME_FTP:
proxy = opt.ftp_proxy ? opt.ftp_proxy : getenv ("ftp_proxy");
@@ -1279,11 +1336,13 @@ bool
url_uses_proxy (struct url * u)
{
bool ret;
char *proxy;
if (!u)
return false;
char *proxy = getproxy (u);
proxy = getproxy (u);
ret = proxy != NULL;
free(proxy);
xfree (proxy);
return ret;
}

View File

@@ -1,7 +1,7 @@
/* Declarations for retr.c.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -34,6 +34,8 @@ as that of the covered work. */
#include "url.h"
extern int numurls;
/* These global vars should be made static to retr.c and exported via
functions! */
extern SUM_SIZE_INT total_downloaded_bytes;

View File

@@ -1,5 +1,5 @@
/* Keep track of visited URLs in spider mode.
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Free Software
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -51,7 +51,7 @@ spider_cleanup (void)
if (nonexisting_urls_set)
string_set_free (nonexisting_urls_set);
}
/* Remembers broken links. */
void
nonexisting_url (const char *url)

View File

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

View File

@@ -1,6 +1,6 @@
/* SSL support.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 2011, 2012 Free Software Foundation, Inc.
2009, 2010, 2011, 2012, 2015 Free Software Foundation, Inc.
Originally contributed by Christian Fraenkel.
This file is part of GNU Wget.
@@ -33,7 +33,7 @@ as that of the covered work. */
#define GEN_SSLFUNC_H
bool ssl_init (void);
bool ssl_connect_wget (int, const char *);
bool ssl_connect_wget (int, const char *, int *);
bool ssl_check_certificate (int, const char *);
#endif /* GEN_SSLFUNC_H */

View File

@@ -1,7 +1,7 @@
/* Dirty system-dependent hacks.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
Inc.
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free Software
Foundation, Inc.
This file is part of GNU Wget.
@@ -35,56 +35,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 +53,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,6 @@
/* Unit testing.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
Foundation, Inc.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Free
Software Foundation, Inc.
This file is part of GNU Wget.
@@ -41,24 +41,20 @@ as that of the covered work. */
#error "TESTING not set!!!"
#endif
const char *test_parse_content_disposition();
const char *test_subdir_p();
const char *test_dir_matches_p();
const char *test_commands_sorted();
const char *test_cmd_spec_restrict_file_names();
const char *test_path_simplify ();
const char *test_append_uri_pathel();
const char *test_are_urls_equal();
const char *test_is_robots_txt_url();
const char *program_argstring = "TEST";
int tests_run;
static int tests_run;
static const char *
all_tests()
all_tests(void)
{
#ifdef HAVE_METALINK
mu_run_test (test_find_key_value);
mu_run_test (test_find_key_values);
mu_run_test (test_has_key);
#endif
mu_run_test (test_parse_content_disposition);
mu_run_test (test_parse_range_header);
mu_run_test (test_subdir_p);
mu_run_test (test_dir_matches_p);
mu_run_test (test_commands_sorted);
@@ -67,17 +63,24 @@ all_tests()
mu_run_test (test_append_uri_pathel);
mu_run_test (test_are_urls_equal);
mu_run_test (test_is_robots_txt_url);
#ifdef HAVE_HSTS
mu_run_test (test_hsts_new_entry);
mu_run_test (test_hsts_url_rewrite_superdomain);
mu_run_test (test_hsts_url_rewrite_congruent);
mu_run_test (test_hsts_read_database);
#endif
return NULL;
}
char *program_name; /* Needed by lib/error.c. */
const char *program_name; /* Needed by lib/error.c. */
int
main (int argc _GL_UNUSED, char *argv[])
main (int argc _GL_UNUSED, const char *argv[])
{
const char *result;
printf ("[DEBUG] Testing...\n\n");
#ifdef ENABLE_NLS
/* Set the current locale. */
setlocale (LC_ALL, "");

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