mirror of
https://github.com/mirror/wget.git
synced 2026-08-21 02:13:27 +08:00
Compare commits
160 Commits
v1.16.3
...
parallel-w
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af702340a1 | ||
|
|
6140b1b6e3 | ||
|
|
c22b806ee0 | ||
|
|
ca69294c8a | ||
|
|
87a5922141 | ||
|
|
99ccc492f4 | ||
|
|
825716399c | ||
|
|
21908a4b13 | ||
|
|
ecd69778bf | ||
|
|
d26c8ebb16 | ||
|
|
507383df07 | ||
|
|
195393bf41 | ||
|
|
42e482ad99 | ||
|
|
82f44f303a | ||
|
|
31e5f33b5e | ||
|
|
422171da81 | ||
|
|
df96c81cf3 | ||
|
|
60a95d8393 | ||
|
|
35ab8cdd7a | ||
|
|
9020b71c18 | ||
|
|
b31e6e4674 | ||
|
|
b828a6e4a7 | ||
|
|
7effa90359 | ||
|
|
7e1f4c1abc | ||
|
|
f616192dfd | ||
|
|
31868fed6c | ||
|
|
59a03f15dd | ||
|
|
fa670282ee | ||
|
|
0d58672dc6 | ||
|
|
93597efe7b | ||
|
|
3010d9c281 | ||
|
|
ebfae2c353 | ||
|
|
15d167e264 | ||
|
|
b87cee3763 | ||
|
|
1a48da4cdc | ||
|
|
349cbd0dd5 | ||
|
|
d9f1cd05c1 | ||
|
|
921a23d60c | ||
|
|
7d18fd1025 | ||
|
|
43ca403306 | ||
|
|
93ad38686a | ||
|
|
89024dda4f | ||
|
|
00c93a0625 | ||
|
|
44c821227c | ||
|
|
cb5c287f02 | ||
|
|
3dfba0bec8 | ||
|
|
fd80f6e878 | ||
|
|
db4262d6dd | ||
|
|
7743384820 | ||
|
|
b703633715 | ||
|
|
0758f47954 | ||
|
|
43bb61b4e3 | ||
|
|
d4d0e6378c | ||
|
|
f5785003b1 | ||
|
|
8b1a9b6de7 | ||
|
|
e84192a8d3 | ||
|
|
99659f3295 | ||
|
|
cb94e52d0f | ||
|
|
886ac1a89b | ||
|
|
e74c2ec25e | ||
|
|
48644f174e | ||
|
|
b6f9efe7b5 | ||
|
|
4c9e6b4f71 | ||
|
|
e13bc90211 | ||
|
|
60d1f4d1ad | ||
|
|
738b299419 | ||
|
|
9b9d16b2f3 | ||
|
|
ae958db622 | ||
|
|
50b4f0c72b | ||
|
|
dccc154a0e | ||
|
|
4445d48471 | ||
|
|
f29fded6f4 | ||
|
|
a528894d13 | ||
|
|
7bb672a487 | ||
|
|
747023c476 | ||
|
|
29cf6bb9d1 | ||
|
|
3595b9de52 | ||
|
|
2d1196b116 | ||
|
|
74d5c8bfb7 | ||
|
|
fec5bb9e93 | ||
|
|
5f48ec1500 | ||
|
|
8560182d57 | ||
|
|
8e5038747b | ||
|
|
82126ccb67 | ||
|
|
ced4c1de82 | ||
|
|
04fcd759fd | ||
|
|
e9058befae | ||
|
|
c1a44a16ef | ||
|
|
5a0f05423a | ||
|
|
3217905144 | ||
|
|
e23e8101db | ||
|
|
2dd255596a | ||
|
|
979a485a9a | ||
|
|
617bb37d6e | ||
|
|
0717a886c2 | ||
|
|
2f2483214c | ||
|
|
e6d8e165c5 | ||
|
|
7c8735a6ee | ||
|
|
c24dce1d07 | ||
|
|
e7e869f951 | ||
|
|
bfe30ea754 | ||
|
|
dcc6abee90 | ||
|
|
4cd6292b31 | ||
|
|
6b59fab021 | ||
|
|
1d18db4bac | ||
|
|
ed8335aa76 | ||
|
|
87a2b8dcb6 | ||
|
|
a41525e5c2 | ||
|
|
76790a386a | ||
|
|
c25d01feb7 | ||
|
|
f51826d9d8 | ||
|
|
721697aef6 | ||
|
|
270460da98 | ||
|
|
fa9aaf2ce6 | ||
|
|
eb01e9d442 | ||
|
|
2807c5c56d | ||
|
|
e37ea16957 | ||
|
|
5abb1dc188 | ||
|
|
54e5b5d373 | ||
|
|
768202bf88 | ||
|
|
5e2c6fefe4 | ||
|
|
0ea58b0c31 | ||
|
|
3d19087207 | ||
|
|
dc7e47d4d1 | ||
|
|
b1bc6efc8a | ||
|
|
d65343a57b | ||
|
|
68dbb9ead7 | ||
|
|
98db799759 | ||
|
|
8cfac52713 | ||
|
|
11d09dd001 | ||
|
|
159c371492 | ||
|
|
38b1df95f9 | ||
|
|
f07e0a67b4 | ||
|
|
47bd180ab0 | ||
|
|
198acf4844 | ||
|
|
5090e0c433 | ||
|
|
bb28bda88f | ||
|
|
9fd1e97e40 | ||
|
|
40493a76fe | ||
|
|
6f102902ad | ||
|
|
26ca40970a | ||
|
|
2f6ef8922b | ||
|
|
39aaaf57f8 | ||
|
|
5f4debb6f8 | ||
|
|
2b8e2f8879 | ||
|
|
b5a8d663f7 | ||
|
|
44f75a1955 | ||
|
|
f4c42b94d8 | ||
|
|
1e1054db8a | ||
|
|
5c608df4e1 | ||
|
|
8bc3dbf2d4 | ||
|
|
7ccf4210f6 | ||
|
|
8c66c94989 | ||
|
|
15bfd733f9 | ||
|
|
f63e2230d7 | ||
|
|
693b791082 | ||
|
|
02d225b5ca | ||
|
|
671d681304 | ||
|
|
6ceea0d064 | ||
|
|
fc220632fb |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -19,8 +19,6 @@
|
||||
po/*.gmo*
|
||||
po/*.po*
|
||||
src/*.o
|
||||
tests/*.log
|
||||
tests/*.trs
|
||||
testenv/*.log
|
||||
testenv/*.trs
|
||||
# build-aux/
|
||||
@@ -56,7 +54,6 @@ po/Makefile.in
|
||||
po/Makevars
|
||||
po/POTFILES
|
||||
po/wget.pot
|
||||
po/stamp-po
|
||||
# src/
|
||||
src/.deps/
|
||||
src/Makefile
|
||||
@@ -84,6 +81,7 @@ testenv/Makefile.in
|
||||
# tests/
|
||||
tests/Makefile
|
||||
tests/Makefile.in
|
||||
tests/WgetTest.pm
|
||||
tests/unit-tests
|
||||
# util/
|
||||
util/Makefile
|
||||
|
||||
@@ -1065,4 +1065,3 @@ developed inside the GNU project. Therefore the information given above
|
||||
applies also for every other Free Software Project. Contact
|
||||
`coordinator@translationproject.org' to make the `.pot' files available
|
||||
to the translation teams.
|
||||
|
||||
|
||||
21536
ChangeLog-2014-12-10
21536
ChangeLog-2014-12-10
File diff suppressed because it is too large
Load Diff
16
ChangeLog.README
Normal file
16
ChangeLog.README
Normal file
@@ -0,0 +1,16 @@
|
||||
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).
|
||||
23
Makefile.am
23
Makefile.am
@@ -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 = MAILING-LIST \
|
||||
msdos/config.h msdos/Makefile.DJ \
|
||||
EXTRA_DIST = ChangeLog.README MAILING-LIST \
|
||||
msdos/ChangeLog msdos/config.h msdos/Makefile.DJ \
|
||||
msdos/Makefile.WC ABOUT-NLS \
|
||||
build-aux/build_info.pl build-aux/git-version-gen .version
|
||||
|
||||
@@ -60,20 +60,5 @@ clean-generic:
|
||||
|
||||
# Arrange so that .tarball-version appears only in the distribution
|
||||
# tarball, and never in a checked-out repository.
|
||||
dist-hook: gen-ChangeLog
|
||||
dist-hook:
|
||||
$(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
|
||||
|
||||
126
NEWS
126
NEWS
@@ -1,71 +1,25 @@
|
||||
GNU Wget NEWS -- history of user-visible changes.
|
||||
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software
|
||||
Foundation, Inc.
|
||||
2006, 2007, 2008, 2009, 2010, 2011, 2012 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
|
||||
|
||||
* Changes in Wget 1.16.3
|
||||
** Use libpsl for verifying cookie domains
|
||||
|
||||
** Fix a regression introduced by wget 1.16.2 that --quiet is not
|
||||
really quiet anymore.
|
||||
** Default progress bar output changed
|
||||
|
||||
* Changes in Wget 1.16.2
|
||||
** Introduce --show-progress to force display the progress bar
|
||||
|
||||
** 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 --no-config.
|
||||
|
||||
** 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.
|
||||
@@ -97,7 +51,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
|
||||
@@ -124,7 +78,7 @@ Please send GNU Wget bug reports to <bug-wget@gnu.org>.
|
||||
** 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.
|
||||
@@ -137,7 +91,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
|
||||
@@ -203,7 +157,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
|
||||
@@ -257,7 +211,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
|
||||
@@ -271,13 +225,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.
|
||||
@@ -299,7 +253,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
|
||||
@@ -321,7 +275,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,
|
||||
@@ -367,7 +321,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
|
||||
@@ -478,9 +432,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
|
||||
@@ -532,11 +486,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.
|
||||
@@ -596,9 +550,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;
|
||||
@@ -640,7 +594,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.
|
||||
@@ -691,13 +645,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!
|
||||
@@ -743,11 +697,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.
|
||||
@@ -763,7 +717,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/,
|
||||
@@ -781,7 +735,7 @@ files.
|
||||
** --convert-links should work now.
|
||||
|
||||
** Minor bugfixes.
|
||||
|
||||
|
||||
* Changes in Wget 1.4.1
|
||||
|
||||
** Minor bugfixes.
|
||||
@@ -789,7 +743,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
|
||||
@@ -870,7 +824,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/*)
|
||||
@@ -888,9 +842,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
|
||||
@@ -908,7 +862,7 @@ geturl -vo log http://fly.cc.fer.hr/
|
||||
** <base href="xxx"> supported
|
||||
|
||||
** autoconf supported
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Copyright information:
|
||||
|
||||
|
||||
104
README.checkout
104
README.checkout
@@ -4,8 +4,8 @@ Compiling From Repository Sources
|
||||
does not contain automatically-generated files, even when these are
|
||||
normally present in the distribution tarballs. Therefore, to build GNU
|
||||
Wget from the sources in the repository, you'll need to have one or
|
||||
more of the following (note that gettext, OpenSSL, GnuTLS, libidn,
|
||||
libiconv, libpsl, libpcre and pkg-config are not absolutely required):
|
||||
more of the following (note that gettext, OpenSSL, libidn, libiconv,
|
||||
libpsl and libmetalink 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
|
||||
@@ -24,11 +24,11 @@ Compiling From Repository Sources
|
||||
tests in the tests/ sub directory. Tarball distributions include an
|
||||
already-generated wget.1 manual. The command "make check" runs the
|
||||
test suite written in perl. To execute all the tests you need
|
||||
[24]libwww-perl and libio-socket-ssl-perl perl library. If
|
||||
"perl -MCPAN -e 'install Bundle::LWP'" fails then you most likely don't
|
||||
have cpan module installed. First download [25]CPAN and [26]install it.
|
||||
Then execute "perl -MCPAN -e 'install Bundle::LWP'".
|
||||
Now "make check" should pass most of the tests in the test suite.
|
||||
[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.
|
||||
|
||||
* [27]texinfo in order to generate Info, PostScript and/or HTML
|
||||
documentation. You don't need texinfo in order to generate the
|
||||
@@ -46,54 +46,37 @@ Compiling From Repository Sources
|
||||
to export M4=<new m4 path>, to be sure that autoconf/automake use
|
||||
it instead of the old one.
|
||||
|
||||
* [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).
|
||||
* [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.
|
||||
|
||||
* [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]libidn is required for IDN/IRI support (non-ASCII characters
|
||||
* [32]libidn is required for IDN/IRI support (non-ASCII characters
|
||||
within what would otherwise be URLs).
|
||||
|
||||
* [32]libiconv is required on non-GNU systems, for IDN/IRI support.
|
||||
* [33]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.
|
||||
|
||||
* [33]git is used to fetch gnulib files trough the bootstrap.sh script.
|
||||
* [34]git is used to fetch gnulib files trough the bootstrap.sh script.
|
||||
|
||||
* [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
|
||||
* [45]libmetalink is required for compiling with Metalink support.
|
||||
|
||||
* [35]libpsl is required for using a public suffix list to check for valid
|
||||
cookie domains.
|
||||
|
||||
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 has been provided. After
|
||||
calling ./bootstrap you're ready to build GNU Wget in the normal
|
||||
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
|
||||
fashion, with ./configure and make.
|
||||
|
||||
So, to sum up, after checking out the source code as described above,
|
||||
@@ -102,23 +85,15 @@ Compiling From Repository Sources
|
||||
$ cd wget # assumes you've cloned a repository to "./wget"
|
||||
2. Generate all the automatically-generated files required prior to
|
||||
configuring the package:
|
||||
$ ./bootstrap
|
||||
$ ./bootstrap.sh
|
||||
3. Configure the package and compile it:
|
||||
$ ./configure --enable-assert [some_parameters]
|
||||
$ ./configure [some_parameters]
|
||||
$ make
|
||||
4. Hack, compile, test, hack, compile, test...
|
||||
$ src/wget --version
|
||||
GNU Wget 1.12-devel (9cb2563197bc)
|
||||
|
||||
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]
|
||||
|
||||
Copyright (C) 2008,2010,2014,2015 Free Software Foundation, Inc.
|
||||
Copyright © 2008,2010 Free Software Foundation, Inc.
|
||||
License GPLv3+: GNU GPL version 3 or later
|
||||
<http://www.gnu.org/licenses/gpl.html>.
|
||||
This is free software: you are free to change and redistribute it.
|
||||
@@ -139,8 +114,8 @@ Compiling From Repository Sources
|
||||
* [43]Valid HTML 4.01
|
||||
__________________________________________________________________
|
||||
|
||||
All content (C) 2007 Free Software Foundation. For terms of use,
|
||||
redistribution, and modification, please see the [45]WikiLicense page.
|
||||
All content © 2007 Free Software Foundation. For terms of use,
|
||||
redistribution, and modification, please see the [44]WikiLicense page.
|
||||
|
||||
References
|
||||
|
||||
@@ -153,13 +128,13 @@ References
|
||||
26. http://apthorpe.cynistar.net/code/configuring_cpan.html
|
||||
27. http://www.gnu.org/software/texinfo/
|
||||
28. http://www.gnu.org/software/gettext/
|
||||
29. http://www.gnu.org/software/gnutls/
|
||||
30. http://www.openssl.org/
|
||||
31. http://www.gnu.org/software/libidn/
|
||||
32. http://www.gnu.org/software/libiconv/
|
||||
33. http://git-scm.com/
|
||||
34. https://github.com/rockdaboot/libpsl
|
||||
35. http://www.pcre.org
|
||||
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
|
||||
36. http://wget.addictivecode.org/CompilingRepoSources?action=edit&editor=text
|
||||
37. http://wget.addictivecode.org/CompilingRepoSources
|
||||
38. http://wget.addictivecode.org/CompilingRepoSources?action=info
|
||||
@@ -169,3 +144,4 @@ References
|
||||
42. http://moinmo.in/GPL
|
||||
43. http://validator.w3.org/check?uri=referer
|
||||
44. http://wget.addictivecode.org/WikiLicense
|
||||
45. https://launchpad.net/libmetalink
|
||||
|
||||
190
bootstrap
190
bootstrap
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2013-12-05.23; # UTC
|
||||
scriptversion=2012-07-19.14; # UTC
|
||||
|
||||
# Bootstrap this package from checked-out sources.
|
||||
|
||||
# Copyright (C) 2003-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2003-2012 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
|
||||
@@ -140,21 +140,20 @@ 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//\1/
|
||||
s/[],)].*//
|
||||
/^AC_INIT(/{
|
||||
/.*,.*,.*, */{
|
||||
s///
|
||||
s/[][]//g
|
||||
s/)$//
|
||||
p
|
||||
q
|
||||
}
|
||||
s/[],)].*//
|
||||
s/AC_INIT(\[*//
|
||||
s/]*,.*//
|
||||
s/^GNU //
|
||||
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
|
||||
s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g
|
||||
s/[^A-Za-z0-9_]/-/g
|
||||
p
|
||||
}
|
||||
'
|
||||
@@ -209,26 +208,12 @@ 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.
|
||||
# If found, set ENVVAR to the program name, die otherwise.
|
||||
# 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.
|
||||
#
|
||||
# FIXME: code duplication, see also gnu-web-doc-update.
|
||||
find_tool ()
|
||||
@@ -238,21 +223,27 @@ find_tool ()
|
||||
find_tool_names=$@
|
||||
eval "find_tool_res=\$$find_tool_envvar"
|
||||
if test x"$find_tool_res" = x; then
|
||||
for i; do
|
||||
if check_exists $i; then
|
||||
find_tool_res=$i
|
||||
break
|
||||
for i
|
||||
do
|
||||
if ($i --version </dev/null) >/dev/null 2>&1; then
|
||||
find_tool_res=$i
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
find_tool_error_prefix="\$$find_tool_envvar: "
|
||||
fi
|
||||
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
|
||||
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"
|
||||
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".
|
||||
@@ -264,12 +255,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
|
||||
"
|
||||
|
||||
@@ -315,34 +306,34 @@ if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
|
||||
die "Bootstrapping from a non-checked-out distribution is risky."
|
||||
fi
|
||||
|
||||
# Strip blank and comment lines to leave significant entries.
|
||||
gitignore_entries() {
|
||||
sed '/^#/d; /^$/d' "$@"
|
||||
# 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'
|
||||
}
|
||||
|
||||
# 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() {
|
||||
# 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() {
|
||||
file=$1
|
||||
str=$2
|
||||
test -f $file || touch $file
|
||||
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
|
||||
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"
|
||||
}
|
||||
|
||||
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
|
||||
# insert_if_absent.
|
||||
# insert_sorted_if_absent.
|
||||
insert_vc_ignore() {
|
||||
vc_ignore_file="$1"
|
||||
pattern="$2"
|
||||
@@ -353,7 +344,7 @@ insert_vc_ignore() {
|
||||
# .gitignore entry.
|
||||
pattern=$(echo "$pattern" | sed s,^,/,);;
|
||||
esac
|
||||
insert_if_absent "$vc_ignore_file" "$pattern"
|
||||
insert_sorted_if_absent "$vc_ignore_file" "$pattern"
|
||||
}
|
||||
|
||||
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
|
||||
@@ -418,7 +409,7 @@ sort_ver() { # sort -V is not generally available
|
||||
get_version() {
|
||||
app=$1
|
||||
|
||||
$app --version >/dev/null 2>&1 || { $app --version; return 1; }
|
||||
$app --version >/dev/null 2>&1 || return 1
|
||||
|
||||
$app --version 2>&1 |
|
||||
sed -n '# Move version to start of line.
|
||||
@@ -477,7 +468,8 @@ check_versions() {
|
||||
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.
|
||||
if ! check_exists --verbose $app; then
|
||||
$app --version >/dev/null 2>&1
|
||||
if [ 126 -le $? ]; then
|
||||
warn_ "Error: '$app' not found"
|
||||
ret=1
|
||||
fi
|
||||
@@ -510,12 +502,6 @@ 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,
|
||||
@@ -561,21 +547,13 @@ 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 $use_git && test -d .git && check_exists git; then
|
||||
if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
|
||||
if git config merge.merge-changelog.driver >/dev/null ; then
|
||||
:
|
||||
elif check_exists git-merge-changelog; then
|
||||
elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; 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'
|
||||
@@ -595,21 +573,17 @@ git_modules_config () {
|
||||
test -f .gitmodules && git config --file .gitmodules "$@"
|
||||
}
|
||||
|
||||
if $use_git; then
|
||||
gnulib_path=$(git_modules_config submodule.gnulib.path)
|
||||
test -z "$gnulib_path" && gnulib_path=gnulib
|
||||
fi
|
||||
gnulib_path=$(git_modules_config submodule.gnulib.path)
|
||||
test -z "$gnulib_path" && gnulib_path=gnulib
|
||||
|
||||
# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a
|
||||
# submodule, for use in the rest of the script.
|
||||
# Get gnulib files.
|
||||
|
||||
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 -- "$gnulib_path" || exit $?
|
||||
git submodule update -- "$gnulib_path" || exit $?
|
||||
git submodule init || exit $?
|
||||
git submodule update || exit $?
|
||||
|
||||
elif [ ! -d "$gnulib_path" ]; then
|
||||
echo "$0: getting gnulib files..."
|
||||
@@ -626,8 +600,8 @@ case ${GNULIB_SRCDIR--} in
|
||||
GNULIB_SRCDIR=$gnulib_path
|
||||
;;
|
||||
*)
|
||||
# Use GNULIB_SRCDIR directly or as a reference.
|
||||
if $use_git && test -d "$GNULIB_SRCDIR"/.git && \
|
||||
# Use GNULIB_SRCDIR as a reference.
|
||||
if 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
|
||||
@@ -638,14 +612,13 @@ 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 -- "$gnulib_path" || exit $?
|
||||
git submodule update || 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 -- "$gnulib_path" \
|
||||
&& git submodule update -- "$gnulib_path" \
|
||||
&& git submodule init && git submodule update \
|
||||
|| exit $?
|
||||
fi
|
||||
fi
|
||||
@@ -654,19 +627,12 @@ 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}" "$@"' \
|
||||
$ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \
|
||||
-- "$GNULIB_SRCDIR/build-aux/bootstrap" \
|
||||
"$0" "$@" --no-bootstrap-sync
|
||||
}
|
||||
fi
|
||||
@@ -714,10 +680,11 @@ update_po_files() {
|
||||
cksum_file="$ref_po_dir/$po.s1"
|
||||
if ! test -f "$cksum_file" ||
|
||||
! test -f "$po_dir/$po.po" ||
|
||||
! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
|
||||
! $SHA1SUM -c --status "$cksum_file" \
|
||||
< "$new_po" > /dev/null; then
|
||||
echo "$me: updated $po_dir/$po.po..."
|
||||
cp "$new_po" "$po_dir/$po.po" \
|
||||
&& $SHA1SUM < "$new_po" > "$cksum_file" || return
|
||||
&& $SHA1SUM < "$new_po" > "$cksum_file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -922,21 +889,20 @@ 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*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";;
|
||||
*--no-recursive*) no_recursive=--no-recursive;;
|
||||
esac
|
||||
|
||||
# Tell autoreconf not to invoke autopoint or libtoolize; they were run above.
|
||||
echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS"
|
||||
AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \
|
||||
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 \
|
||||
|| die "autoreconf failed"
|
||||
|
||||
# Get some extra files from gnulib, overriding existing files.
|
||||
|
||||
@@ -31,24 +31,17 @@ announce-gen
|
||||
base32
|
||||
bind
|
||||
c-ctype
|
||||
c-strcase
|
||||
c-strcasestr
|
||||
clock-time
|
||||
close
|
||||
connect
|
||||
dirname
|
||||
fcntl
|
||||
fnmatch
|
||||
futimens
|
||||
ftello
|
||||
getaddrinfo
|
||||
getline
|
||||
getopt-gnu
|
||||
getpass-gnu
|
||||
getpeername
|
||||
getsockname
|
||||
gettext
|
||||
gitlog-to-changelog
|
||||
git-version-gen
|
||||
gnupload
|
||||
ioctl
|
||||
@@ -56,14 +49,14 @@ iconv
|
||||
iconv-h
|
||||
listen
|
||||
maintainer-makefile
|
||||
mbiter
|
||||
mbtowc
|
||||
memrchr
|
||||
mkdir
|
||||
mkstemp
|
||||
mkostemp
|
||||
crypto/md5
|
||||
crypto/sha1
|
||||
crypto/sha256
|
||||
pipe
|
||||
quote
|
||||
quotearg
|
||||
recv
|
||||
@@ -75,21 +68,16 @@ sigprocmask
|
||||
sigpipe
|
||||
snprintf
|
||||
socket
|
||||
spawn-pipe
|
||||
stdbool
|
||||
strcase
|
||||
strcasestr
|
||||
strerror_r-posix
|
||||
strptime
|
||||
strtok_r
|
||||
strtoll
|
||||
timegm
|
||||
tmpdir
|
||||
unlocked-io
|
||||
update-copyright
|
||||
vasprintf
|
||||
vsnprintf
|
||||
write
|
||||
xstrndup
|
||||
"
|
||||
|
||||
gnulib_extra_files="
|
||||
@@ -115,5 +103,4 @@ perl 5.5
|
||||
rsync -
|
||||
tar -
|
||||
xz -
|
||||
flex -
|
||||
"
|
||||
|
||||
@@ -137,4 +137,3 @@ __DATA__
|
||||
|
||||
#include "wget.h"
|
||||
#include <stdio.h>
|
||||
#include "version.h"
|
||||
|
||||
5
cfg.mk
5
cfg.mk
@@ -19,11 +19,10 @@ 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)/.*)|ChangeLog-2014-12-10$$
|
||||
VC_LIST_ALWAYS_EXCLUDE_REGEX = ^ABOUT-NLS|((msdos|vms)/.*)$$
|
||||
|
||||
454
configure.ac
454
configure.ac
@@ -57,101 +57,60 @@ AC_CANONICAL_HOST
|
||||
AC_DEFINE_UNQUOTED([OS_TYPE], "$host_os",
|
||||
[Define to be the name of the operating system.])
|
||||
|
||||
|
||||
dnl
|
||||
dnl Process External Libraries
|
||||
dnl Process features.
|
||||
dnl
|
||||
|
||||
dnl Libpsl: Public Suffix List checking
|
||||
AC_ARG_WITH([libpsl],
|
||||
[AS_HELP_STRING([--without-libpsl], [disable support for libpsl cookie checking.])])
|
||||
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 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(ssl,
|
||||
[[ --without-ssl disable SSL autodetection
|
||||
--with-ssl={gnutls,openssl} specify the SSL backend. GNU TLS is the default.]])
|
||||
|
||||
AC_ARG_WITH(zlib,
|
||||
[[ --without-zlib disable zlib ]])
|
||||
|
||||
dnl Zlib: Configure use iof 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.])
|
||||
|
||||
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
|
||||
dnl Process features
|
||||
dnl
|
||||
AC_ARG_ENABLE(ntlm,
|
||||
[ --disable-ntlm disable support for NTLM authorization],
|
||||
[ENABLE_NTLM=$enableval], [ENABLE_NTLM=auto])
|
||||
|
||||
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])
|
||||
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.])
|
||||
|
||||
AS_IF([test "x$ENABLE_OPIE" = xyes],
|
||||
[AC_DEFINE([ENABLE_OPIE], [1], [Define if you want Opie support for FTP compiled in.])],
|
||||
[]
|
||||
)
|
||||
AC_ARG_ENABLE(metalink,
|
||||
[ --disable-metalink disable support for metalink file format],
|
||||
ENABLE_METALINK=$enableval, ENABLE_METALINK=no)
|
||||
test x"${ENABLE_METALINK}" = xyes && AC_DEFINE([ENABLE_METALINK], 1,
|
||||
[Define if you want the metalink file format support 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"
|
||||
],
|
||||
[])
|
||||
AC_ARG_ENABLE(race-detection,
|
||||
[ --enable-race-detection enable support for detecting race conditions],
|
||||
ENABLE_RACES=$enableval, ENABLE_RACES=no)
|
||||
test x"${ENABLE_RACES}" = xyes && AC_DEFINE([ENABLE_RACES], 1,
|
||||
[Define if you want runtime Race Detection enabled.])
|
||||
|
||||
dnl
|
||||
dnl Find the compiler
|
||||
@@ -167,12 +126,6 @@ AC_AIX
|
||||
|
||||
gl_EARLY
|
||||
|
||||
dnl
|
||||
dnl Find python3
|
||||
dnl
|
||||
AM_PATH_PYTHON([3.0],,[:])
|
||||
AM_CONDITIONAL([HAVE_PYTHON3], [test "$PYTHON" != :])
|
||||
|
||||
dnl
|
||||
dnl Gettext
|
||||
dnl
|
||||
@@ -190,11 +143,9 @@ 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 -Wextra"
|
||||
CFLAGS="$CFLAGS -O2 -Wall"
|
||||
else
|
||||
case "$host_os" in
|
||||
*hpux*) CFLAGS="$CFLAGS +O3" ;;
|
||||
@@ -268,7 +219,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 strlcpy random)
|
||||
AC_CHECK_FUNCS(sleep symlink utime)
|
||||
|
||||
if test x"$ENABLE_OPIE" = xyes; then
|
||||
AC_LIBOBJ([ftp-opie])
|
||||
@@ -305,84 +256,48 @@ 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_zlib" != xno], [
|
||||
with_zlib=yes
|
||||
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)
|
||||
])
|
||||
AC_CHECK_LIB(z, compress)
|
||||
])
|
||||
|
||||
AS_IF([test x"$with_ssl" = xopenssl], [
|
||||
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)
|
||||
])
|
||||
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>
|
||||
@@ -390,20 +305,19 @@ 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"
|
||||
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
|
||||
], [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
|
||||
])
|
||||
|
||||
], [
|
||||
# --with-ssl is not openssl: check if it's no
|
||||
AS_IF([test x"$with_ssl" != xno], [
|
||||
@@ -411,29 +325,17 @@ AS_IF([test x"$with_ssl" = xopenssl], [
|
||||
with_ssl=gnutls
|
||||
|
||||
dnl Now actually check for -lgnutls
|
||||
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], [], [
|
||||
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([GnuTLS has not been found. Use --with-ssl=openssl if you explicitly want OpenSSL.])
|
||||
fi
|
||||
], [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.])
|
||||
fi
|
||||
|
||||
AC_CHECK_FUNCS(gnutls_priority_set_direct)
|
||||
@@ -475,6 +377,74 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
AS_IF([test x"$ENABLE_THREADS" != xno],[
|
||||
AC_CHECK_LIB(pthread, pthread_create, [
|
||||
dnl AC_CHECK_LIB(semaphore, sem_init, [
|
||||
threads=yes
|
||||
LIBS="${LIBS} -lpthread"
|
||||
AC_DEFINE([ENABLE_THREADS], 1,
|
||||
[Define if you want the thread support compiled in.])
|
||||
AC_MSG_NOTICE([compiling with support for threads])
|
||||
dnl ],[
|
||||
dnl threads=no
|
||||
dnl if test x"$ENABLE_THREADS" == xyes
|
||||
dnl then
|
||||
dnl AC_MSG_ERROR([Could not find the sem_init function in semaphore.])
|
||||
dnl fi
|
||||
dnl ])
|
||||
],[
|
||||
threads=no
|
||||
if test x"$ENABLE_THREADS" == xyes
|
||||
then
|
||||
AC_MSG_ERROR([Could not find the pthread_create function in pthread.])
|
||||
fi
|
||||
])
|
||||
])
|
||||
|
||||
AS_IF([test x"$ENABLE_RACES" != xno],[
|
||||
CFLAGS="$CFLAGS -fsanitize=thread -fPIE";
|
||||
LDFLAGS="$LDFLAGS -fsanitize=thread -pie";
|
||||
])
|
||||
|
||||
AS_IF([test x"$ENABLE_METALINK" != xno],[
|
||||
dnl If metalink support is requested
|
||||
PKG_CHECK_MODULES(LIBMETALINK, libmetalink, [
|
||||
dnl If metalink module is found
|
||||
LIBS="$LIBMETALINK_LIBS $LIBS"
|
||||
CFLAGS="$LIBMETALINK_CFLAGS $CFLAGS"
|
||||
AC_DEFINE([ENABLE_METALINK], 1,
|
||||
[Define if you want the metalink support compiled in.])
|
||||
|
||||
AC_CHECK_LIB(metalink, metalink_parse_file, [
|
||||
if test x"$DISABLE_THREADS" == xyes
|
||||
then
|
||||
AC_MSG_ERROR([Metalink support depends on threads, which are requested to be disabled.])
|
||||
elif test "X$threads" != "Xyes"
|
||||
then
|
||||
AC_MSG_ERROR([Metalink support depends on threads, support for which could not be enabled.])
|
||||
else
|
||||
metalink=yes
|
||||
AC_MSG_NOTICE([compiling in support for metalink])
|
||||
fi
|
||||
], [
|
||||
if test x"$ENABLE_METALINK" == xyes
|
||||
then
|
||||
AC_MSG_ERROR([Could not find the metalink_parse_file function in libmetalink.])
|
||||
fi
|
||||
])
|
||||
], [
|
||||
dnl If metalink module is not found
|
||||
if test x"$ENABLE_METALINK" == xyes
|
||||
then
|
||||
AC_MSG_ERROR([libmetalink not found])
|
||||
fi
|
||||
])
|
||||
],[
|
||||
dnl If metalink support is not requested
|
||||
metalink=no
|
||||
AC_MSG_NOTICE([compiling without support for metalink])
|
||||
])
|
||||
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Checks for IPv6
|
||||
@@ -652,75 +622,45 @@ 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_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.])
|
||||
])
|
||||
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.])
|
||||
])
|
||||
)
|
||||
|
||||
dnl
|
||||
dnl Check for PCRE
|
||||
dnl
|
||||
|
||||
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.])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
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 Needed by src/Makefile.am
|
||||
AM_CONDITIONAL([IRI_IS_ENABLED], [test "X$iri" != "Xno"])
|
||||
|
||||
AM_CONDITIONAL([IRI_IS_ENABLED], [test "X$iri" == "Xyes"])
|
||||
AM_CONDITIONAL([METALINK_IS_ENABLED], [test "X$metalink" == "Xyes"])
|
||||
AM_CONDITIONAL([THREADS_ARE_ENABLED], [test "X$threads" == "Xyes"])
|
||||
AM_CONDITIONAL([RACE_CHECKING_IS_ENABLED], [test "X$race-detection" == "Xyes"])
|
||||
|
||||
dnl
|
||||
dnl Create output
|
||||
dnl
|
||||
AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile util/Makefile
|
||||
po/Makefile.in tests/Makefile
|
||||
po/Makefile.in tests/Makefile tests/WgetTest.pm
|
||||
lib/Makefile testenv/Makefile])
|
||||
AC_CONFIG_HEADERS([src/config.h])
|
||||
AC_OUTPUT
|
||||
@@ -736,11 +676,11 @@ AC_MSG_NOTICE([Summary of build options:
|
||||
Libs: $LIBS
|
||||
SSL: $with_ssl
|
||||
Zlib: $with_zlib
|
||||
PSL: $with_libpsl
|
||||
PSL: $ENABLE_PSL
|
||||
Digest: $ENABLE_DIGEST
|
||||
NTLM: $ENABLE_NTLM
|
||||
OPIE: $ENABLE_OPIE
|
||||
Metalink: $ENABLE_METALINK
|
||||
Debugging: $ENABLE_DEBUG
|
||||
Assertions: $ENABLE_ASSERTION
|
||||
Valgrind: $VALGRIND_INFO
|
||||
Race Detection: $ENABLE_RACES
|
||||
])
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Do some checking before 'git push'.
|
||||
|
||||
CORES=`grep -c ^processor /proc/cpuinfo 2>/dev/null || echo 0`
|
||||
if [ $CORES -lt 1 ]; then CORES=1; fi
|
||||
|
||||
make -f Makefile distclean 2>/dev/null
|
||||
|
||||
# automatically exit on error
|
||||
set -e
|
||||
|
||||
export CFLAGS="-std=c89 -pedantic -O2 -g -Wall -Wextra -Wstrict-prototypes -Wold-style-definition -Wwrite-strings -Wshadow -Wformat -Wformat-security -Wunreachable-code -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition"
|
||||
|
||||
CACHEFILE=$PWD/config_check.cache
|
||||
|
||||
# measure time consumed and print it at the end of the script
|
||||
START=$(date +%s.%N)
|
||||
|
||||
echo "./bootstrap"
|
||||
./bootstrap >/dev/null
|
||||
echo
|
||||
|
||||
for CC in gcc clang; do
|
||||
export CC
|
||||
echo "*** checking 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 >/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 -j$CORES"
|
||||
make distcheck -j$CORES
|
||||
done
|
||||
done
|
||||
|
||||
END=$(date +%s.%N)
|
||||
echo "Duration: "$(echo "$END - $START" | bc)
|
||||
@@ -1,90 +0,0 @@
|
||||
#!/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 "$@"
|
||||
1621
doc/ChangeLog
Normal file
1621
doc/ChangeLog
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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,7 +28,6 @@ manext = 1
|
||||
RM = rm -f
|
||||
|
||||
TEXI2POD = $(srcdir)/texi2pod.pl
|
||||
POD2MAN = @POD2MAN@
|
||||
MAN = wget.$(manext)
|
||||
WGETRC = $(sysconfdir)/wgetrc
|
||||
SAMPLERCTEXI = sample.wgetrc.munged_for_texi_inclusion
|
||||
@@ -39,7 +38,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
|
||||
|
||||
@@ -57,7 +56,7 @@ 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)" $? > $@
|
||||
|
||||
#wget.cat: $(MAN)
|
||||
# nroff -man $? > $@
|
||||
@@ -76,10 +75,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
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
## 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.
|
||||
|
||||
|
||||
##
|
||||
@@ -125,7 +122,7 @@
|
||||
#iri = off
|
||||
|
||||
# Force the default system encoding
|
||||
#localencoding = UTF-8
|
||||
#locale = UTF-8
|
||||
|
||||
# Force the default remote server encoding
|
||||
#remoteencoding = UTF-8
|
||||
|
||||
@@ -533,6 +533,22 @@ would be resolved to @samp{http://foo/baz/b.html}.
|
||||
@cindex specify config
|
||||
@item --config=@var{FILE}
|
||||
Specify the location of a startup file you wish to use.
|
||||
|
||||
@cindex metalink
|
||||
@item --metalink=@var{FILE}
|
||||
Read @sc{url}s from a local or external metalink @var{file}. If @samp{-} is
|
||||
specified as @var{file}, @sc{url}s are read from the standard input.
|
||||
(Use @samp{./-} to read from a file literally named @samp{-}.)
|
||||
|
||||
If this function is used, no @sc{url}s need be present on the command
|
||||
line.
|
||||
|
||||
If the @var{file} is an external one, the document will be automatically
|
||||
downloaded and will not be kept even after wget terminates.
|
||||
|
||||
See option @samp{--jobs} to enable multi-threaded downloads from metalink
|
||||
files, option @samp{--retries} to set a number of retries for downloading a @var{file}
|
||||
in case of failure.
|
||||
@end table
|
||||
|
||||
@node Download Options, Directory Options, Logging and Input File Options, Invoking
|
||||
@@ -558,6 +574,11 @@ infinite retrying. The default is to retry 20 times, with the exception
|
||||
of fatal errors like ``connection refused'' or ``not found'' (404),
|
||||
which are not retried.
|
||||
|
||||
@item --retries=@var{number}
|
||||
Set number of retries for a file specified in a metalink file to @var{number}.
|
||||
Specify 0 or @samp{inf} for no retrying in case of failed attempt. The default
|
||||
is to retry 1 time.
|
||||
|
||||
@item -O @var{file}
|
||||
@itemx --output-document=@var{file}
|
||||
The documents will not be written to the appropriate files, but all
|
||||
@@ -774,15 +795,12 @@ use @samp{--progress=bar:force:noscroll}.
|
||||
Force wget to display the progress bar in any verbosity.
|
||||
|
||||
By default, wget only displays the progress bar in verbose mode. One may
|
||||
however, want wget to display the progress bar on screen in conjunction with
|
||||
however want wget to display the progress bar on screen in conjunction with
|
||||
any other verbosity modes like @samp{--no-verbose} or @samp{--quiet}. This
|
||||
is often a desired a property when invoking wget to download several small/large
|
||||
files. In such a case, wget could simply be invoked with this parameter to get
|
||||
a much cleaner output on the screen.
|
||||
|
||||
This option will also force the progress bar to be printed to @file{stderr} when
|
||||
used alongside the @samp{--logfile} option.
|
||||
|
||||
@item -N
|
||||
@itemx --timestamping
|
||||
Turn on time-stamping. @xref{Time-Stamping}, for details.
|
||||
@@ -1148,6 +1166,14 @@ command line.
|
||||
Force Wget to unlink file instead of clobbering existing file. This
|
||||
option is useful for downloading to the directory with hardlinks.
|
||||
|
||||
@cindex jobs
|
||||
@item --jobs=@var{number}
|
||||
|
||||
Specify the @var{number} of threads to use. Unless specified, the number of
|
||||
threads used is 1.
|
||||
|
||||
Currently this option works only for recursive downloading and when specified with
|
||||
option @samp{--metalink}.
|
||||
@end table
|
||||
|
||||
@node Directory Options, HTTP Options, Download Options, Invoking
|
||||
@@ -1644,16 +1670,16 @@ without SSL support, none of these options are available.
|
||||
@cindex SSL protocol, choose
|
||||
@item --secure-protocol=@var{protocol}
|
||||
Choose the secure protocol to be used. Legal values are @samp{auto},
|
||||
@samp{SSLv2}, @samp{SSLv3}, @samp{TLSv1}, @samp{TLSv1_1}, @samp{TLSv1_2}
|
||||
and @samp{PFS}. If @samp{auto} is used, the SSL library is given the
|
||||
liberty of choosing the appropriate protocol automatically, which is
|
||||
achieved by sending a TLSv1 greeting. This is the default.
|
||||
@samp{SSLv2}, @samp{SSLv3}, @samp{TLSv1} and @samp{PFS}. If @samp{auto}
|
||||
is used, the SSL library is given the liberty of choosing the appropriate
|
||||
protocol automatically, which is achieved by sending an SSLv2 greeting
|
||||
and announcing support for SSLv3 and TLSv1. This is the default.
|
||||
|
||||
Specifying @samp{SSLv2}, @samp{SSLv3}, @samp{TLSv1}, @samp{TLSv1_1} or
|
||||
@samp{TLSv1_2} forces the use of the corresponding protocol. This is
|
||||
useful when talking to old and buggy SSL server implementations that
|
||||
make it hard for the underlying SSL library to choose the correct
|
||||
protocol version. Fortunately, such servers are quite rare.
|
||||
Specifying @samp{SSLv2}, @samp{SSLv3}, or @samp{TLSv1} forces the use
|
||||
of the corresponding protocol. This is useful when talking to old and
|
||||
buggy SSL server implementations that make it hard for the underlying
|
||||
SSL library to choose the correct protocol version. Fortunately, such
|
||||
servers are quite rare.
|
||||
|
||||
Specifying @samp{PFS} enforces the use of the so-called Perfect Forward
|
||||
Security cipher suites. In short, PFS adds security by creating a one-time
|
||||
@@ -1728,23 +1754,19 @@ it allows Wget to fetch certificates on demand.
|
||||
Without this option Wget looks for CA certificates at the
|
||||
system-specified locations, chosen at OpenSSL installation time.
|
||||
|
||||
@cindex SSL CRL, certificate revocation list
|
||||
@item --crl-file=@var{file}
|
||||
Specifies a CRL file in @var{file}. This is needed for certificates
|
||||
that have been revocated by the CAs.
|
||||
|
||||
@cindex entropy, specifying source of
|
||||
@cindex randomness, specifying source of
|
||||
@item --random-file=@var{file}
|
||||
[OpenSSL and LibreSSL only]
|
||||
Use @var{file} as the source of random data for seeding the
|
||||
pseudo-random number generator on systems without @file{/dev/urandom}.
|
||||
pseudo-random number generator on systems without @file{/dev/random}.
|
||||
|
||||
On such systems the SSL library needs an external source of randomness
|
||||
to initialize. Randomness may be provided by EGD (see
|
||||
@samp{--egd-file} below) or read from an external source specified by
|
||||
the user. If this option is not specified, Wget looks for random data
|
||||
in @code{$RANDFILE} or, if that is unset, in @file{$HOME/.rnd}.
|
||||
in @code{$RANDFILE} or, if that is unset, in @file{$HOME/.rnd}. If
|
||||
none of those are available, it is likely that SSL encryption will not
|
||||
be usable.
|
||||
|
||||
If you're getting the ``Could not seed OpenSSL PRNG; disabling SSL.''
|
||||
error, you should provide random data using some of the methods
|
||||
@@ -1752,7 +1774,6 @@ described above.
|
||||
|
||||
@cindex EGD
|
||||
@item --egd-file=@var{file}
|
||||
[OpenSSL only]
|
||||
Use @var{file} as the EGD socket. EGD stands for @dfn{Entropy
|
||||
Gathering Daemon}, a user-space program that collects data from
|
||||
various unpredictable system sources and makes it available to other
|
||||
@@ -1767,7 +1788,7 @@ read random data from EGD socket specified using this option.
|
||||
|
||||
If this option is not specified (and the equivalent startup command is
|
||||
not used), EGD is never contacted. EGD is not needed on modern Unix
|
||||
systems that support @file{/dev/urandom}.
|
||||
systems that support @file{/dev/random}.
|
||||
@end table
|
||||
|
||||
@cindex WARC
|
||||
@@ -1891,18 +1912,17 @@ Preserve remote file permissions instead of permissions set by umask.
|
||||
|
||||
@cindex symbolic links, retrieving
|
||||
@item --retr-symlinks
|
||||
By default, when retrieving @sc{ftp} directories recursively and a symbolic link
|
||||
is encountered, the symbolic link is traversed and the pointed-to files are
|
||||
retrieved. Currently, Wget does not traverse symbolic links to directories to
|
||||
download them recursively, though this feature may be added in the future.
|
||||
Usually, when retrieving @sc{ftp} directories recursively and a symbolic
|
||||
link is encountered, the linked-to file is not downloaded. Instead, a
|
||||
matching symbolic link is created on the local filesystem. The
|
||||
pointed-to file will not be downloaded unless this recursive retrieval
|
||||
would have encountered it separately and downloaded it anyway.
|
||||
|
||||
When @samp{--retr-symlinks=no} is specified, the linked-to file is not
|
||||
downloaded. Instead, a matching symbolic link is created on the local
|
||||
filesystem. The pointed-to file will not be retrieved unless this recursive
|
||||
retrieval would have encountered it separately and downloaded it anyway. This
|
||||
option poses a security risk where a malicious FTP Server may cause Wget to
|
||||
write to files outside of the intended directories through a specially crafted
|
||||
@sc{.listing} file.
|
||||
When @samp{--retr-symlinks} is specified, however, symbolic links are
|
||||
traversed and the pointed-to files are retrieved. At this time, this
|
||||
option does not cause Wget to traverse symlinks to directories and
|
||||
recurse through them, but in the future it should be enhanced to do
|
||||
this.
|
||||
|
||||
Note that when retrieving a file (not a directory) because it was
|
||||
specified on the command-line, rather than because it was recursed to,
|
||||
@@ -2901,10 +2921,10 @@ variable = value
|
||||
The @dfn{variable} will also be called @dfn{command}. Valid
|
||||
@dfn{values} are different for different commands.
|
||||
|
||||
The commands are case-, underscore- and minus-insensitive. Thus
|
||||
@samp{DIr__PrefiX}, @samp{DIr-PrefiX} and @samp{dirprefix} are the same.
|
||||
Empty lines, lines beginning with @samp{#} and lines containing white-space
|
||||
only are discarded.
|
||||
The commands are case-insensitive and underscore-insensitive. Thus
|
||||
@samp{DIr__PrefiX} is the same as @samp{dirprefix}. Empty lines, lines
|
||||
beginning with @samp{#} and lines containing white-space only are
|
||||
discarded.
|
||||
|
||||
Commands that expect a comma-separated list will clear the list on an
|
||||
empty command. So, if you wish to reset the rejection list specified in
|
||||
@@ -3134,9 +3154,6 @@ environment.
|
||||
Set @sc{http} user to @var{string}, equivalent to
|
||||
@samp{--http-user=@var{string}}.
|
||||
|
||||
@item https_only = on/off
|
||||
When in recursive mode, only HTTPS links are followed (defaults to off).
|
||||
|
||||
@item https_proxy = @var{string}
|
||||
Use @var{string} as @sc{https} proxy, instead of the one specified in
|
||||
environment.
|
||||
|
||||
2
gnulib
2
gnulib
Submodule gnulib updated: ecc5d3e148...98ca2c063c
61
msdos/ChangeLog
Normal file
61
msdos/ChangeLog
Normal file
@@ -0,0 +1,61 @@
|
||||
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.
|
||||
1
po/stamp-po
Normal file
1
po/stamp-po
Normal file
@@ -0,0 +1 @@
|
||||
timestamp
|
||||
15138
src/ChangeLog
Normal file
15138
src/ChangeLog
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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, 2014 Free Software
|
||||
# Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -28,35 +28,50 @@
|
||||
# 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
|
||||
METALINK_HEADER = metalink.h
|
||||
endif
|
||||
if THREADS_ARE_ENABLED
|
||||
THREAD_OBJ = multi.c
|
||||
MULTI_HEADER = multi.h
|
||||
endif
|
||||
|
||||
# The following line is losing on some versions of make!
|
||||
DEFS = @DEFS@ -DSYSTEM_WGETRC=\"$(sysconfdir)/wgetrc\" -DLOCALEDIR=\"$(localedir)\"
|
||||
LIBS = @LIBICONV@ @LIBINTL@ @LIBS@ $(LIB_CLOCK_GETTIME)
|
||||
DEFS += -DSYSTEM_WGETRC=\"$(sysconfdir)/wgetrc\" -DLOCALEDIR=\"$(localedir)\"
|
||||
LIBS += $(LIBICONV) $(LIBINTL) $(LIB_CLOCK_GETTIME)
|
||||
|
||||
EXTRA_DIST = css.l css.c css_.c build_info.c.in
|
||||
EXTRA_DIST = css.l css.c css_.c build_info.c.in iri.c multi.c multi.h metalink.c metalink.h
|
||||
|
||||
bin_PROGRAMS = wget
|
||||
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 \
|
||||
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) \
|
||||
css-url.h css-tokens.h connect.h convert.h cookies.h \
|
||||
ftp.h hash.h host.h html-parse.h html-url.h \
|
||||
http.h http-ntlm.h init.h log.h mswindows.h netrc.h \
|
||||
options.h progress.h ptimer.h recur.h res.h retr.h \
|
||||
spider.h ssl.h sysdep.h url.h warc.h utils.h wget.h iri.h \
|
||||
exits.h version.h
|
||||
|
||||
wget_SOURCES = cmpt.c 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 \
|
||||
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) \
|
||||
$(THREAD_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 \
|
||||
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 $(THREAD_HEADER) $(METALINK_HEADER)
|
||||
|
||||
am__wget_SOURCES_DIST = $(wget_SOURCES)
|
||||
am__libunittest_a_SOURCES_DIST = $(wget_SOURCES)
|
||||
|
||||
|
||||
nodist_wget_SOURCES = version.c
|
||||
EXTRA_wget_SOURCES = iri.c
|
||||
LDADD = $(LIBOBJS) ../lib/libgnu.a
|
||||
AM_LDFLAGS = $(THREAD_LIB)
|
||||
AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib
|
||||
|
||||
|
||||
@@ -74,8 +89,7 @@ version.c: $(wget_SOURCES) ../lib/libgnu.a
|
||||
echo '/* version.c */' > $@
|
||||
echo '/* Autogenerated by Makefile - DO NOT EDIT */' >> $@
|
||||
echo '' >> $@
|
||||
echo '#include "version.h"' >> $@
|
||||
echo 'const char *version_string = "@VERSION@";' >> $@
|
||||
echo 'const char *version_string = "$(VERSION)";' >> $@
|
||||
echo 'const char *compilation_string = "'$(COMPILE)'";' \
|
||||
| $(ESCAPEQUOTE) >> $@
|
||||
echo 'const char *link_string = "'$(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
@@ -83,7 +97,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"' > $@
|
||||
|
||||
@@ -2,11 +2,13 @@ digest defined ENABLE_DIGEST
|
||||
https defined HAVE_SSL
|
||||
ipv6 defined ENABLE_IPV6
|
||||
iri defined ENABLE_IRI
|
||||
large-file SIZEOF_OFF_T >= 8 || defined WINDOWS
|
||||
large-file SIZEOF_OFF_T >= 8
|
||||
|
||||
nls defined ENABLE_NLS
|
||||
ntlm defined ENABLE_NTLM
|
||||
opie defined ENABLE_OPIE
|
||||
threads defined ENABLE_THREADS
|
||||
metalink defined ENABLE_METALINK
|
||||
psl defined HAVE_LIBPSL
|
||||
|
||||
ssl choice:
|
||||
|
||||
1427
src/cmpt.c
Normal file
1427
src/cmpt.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -54,11 +54,6 @@ as that of the covered work. */
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef ENABLE_IRI
|
||||
#include <idn-free.h>
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
#include "host.h"
|
||||
#include "connect.h"
|
||||
@@ -173,7 +168,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.
|
||||
@@ -218,7 +213,7 @@ resolve_bind_address (struct sockaddr *sa)
|
||||
should_bind = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
struct cwt_context {
|
||||
int fd;
|
||||
const struct sockaddr *addr;
|
||||
@@ -255,7 +250,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
|
||||
@@ -283,13 +278,14 @@ 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';
|
||||
idn_free (name);
|
||||
xfree (name);
|
||||
}
|
||||
|
||||
logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "),
|
||||
str ? str : escnonprint_uri (print), txt_addr, port);
|
||||
|
||||
xfree (str);
|
||||
if (str)
|
||||
xfree (str);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -371,7 +367,7 @@ connect_to_ip (const ip_address *ip, int port, const char *print)
|
||||
if (sock >= 0)
|
||||
fd_close (sock);
|
||||
if (print)
|
||||
logprintf (LOG_NOTQUIET, _("failed: %s.\n"), strerror (errno));
|
||||
logprintf (LOG_VERBOSE, _("failed: %s.\n"), strerror (errno));
|
||||
errno = save_errno;
|
||||
return -1;
|
||||
}
|
||||
@@ -433,7 +429,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.
|
||||
@@ -750,7 +746,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
|
||||
@@ -798,7 +794,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
|
||||
@@ -849,7 +845,7 @@ void *
|
||||
fd_transport_context (int fd)
|
||||
{
|
||||
struct transport_info *info = hash_table_get (transport_map, (void *)(intptr_t) fd);
|
||||
return info ? info->ctx : NULL;
|
||||
return info->ctx;
|
||||
}
|
||||
|
||||
/* When fd_read/fd_write are called multiple times in a loop, they should
|
||||
|
||||
@@ -60,7 +60,11 @@ enum {
|
||||
WAIT_FOR_READ = 1,
|
||||
WAIT_FOR_WRITE = 2
|
||||
};
|
||||
#ifdef ENABLE_THREADS
|
||||
int select_fds (int *, int *, int, double, int);
|
||||
#else
|
||||
int select_fd (int, double, int);
|
||||
#endif
|
||||
bool test_socket_open (int);
|
||||
|
||||
struct transport_implementation {
|
||||
|
||||
@@ -36,6 +36,9 @@ as that of the covered work. */
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#ifdef ENABLE_THREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include "convert.h"
|
||||
#include "url.h"
|
||||
#include "recur.h"
|
||||
@@ -55,6 +58,49 @@ struct hash_table *dl_url_file_map;
|
||||
struct hash_table *downloaded_html_set;
|
||||
struct hash_table *downloaded_css_set;
|
||||
|
||||
#ifdef ENABLE_THREADS
|
||||
static pthread_mutex_t convert_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static void
|
||||
lock_convert_mutex()
|
||||
{
|
||||
static int convert_mutex_init_p = 0;
|
||||
if (! convert_mutex_init_p)
|
||||
{
|
||||
pthread_mutexattr_t mta;
|
||||
pthread_mutexattr_init (&mta);
|
||||
pthread_mutexattr_settype (&mta, PTHREAD_MUTEX_RECURSIVE);
|
||||
|
||||
pthread_mutex_init (&convert_mutex, &mta);
|
||||
convert_mutex_init_p = 1;
|
||||
}
|
||||
pthread_mutex_lock (&convert_mutex);
|
||||
}
|
||||
|
||||
|
||||
#define THREAD_SAFE(ret, fn, args, argv) \
|
||||
ret fn args \
|
||||
{ \
|
||||
ret r; \
|
||||
lock_convert_mutex(); \
|
||||
r = fn##_1 argv; \
|
||||
pthread_mutex_unlock (&convert_mutex); \
|
||||
return r; \
|
||||
}
|
||||
|
||||
#define THREAD_SAFE_VOID(fn, args, argv) \
|
||||
void fn args \
|
||||
{ \
|
||||
lock_convert_mutex(); \
|
||||
fn##_1 argv; \
|
||||
pthread_mutex_unlock (&convert_mutex); \
|
||||
}
|
||||
|
||||
#define FNNAME_WTHREADS(fn) fn##_1
|
||||
#else
|
||||
#define FNNAME_WTHREADS(fn) fn
|
||||
#endif
|
||||
|
||||
static void convert_links (const char *, struct urlpos *);
|
||||
|
||||
|
||||
@@ -182,7 +228,7 @@ convert_links_in_hashtable (struct hash_table *downloaded_set,
|
||||
extracted from these two lists. */
|
||||
|
||||
void
|
||||
convert_all_links (void)
|
||||
FNNAME_WTHREADS(convert_all_links) (void)
|
||||
{
|
||||
double secs;
|
||||
int file_count = 0;
|
||||
@@ -661,7 +707,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. */
|
||||
@@ -761,7 +807,7 @@ dissociate_urls_from_file (const char *file)
|
||||
URL has already been downloaded. */
|
||||
|
||||
void
|
||||
register_download (const char *url, const char *file)
|
||||
FNNAME_WTHREADS(register_download) (const char *url, const char *file)
|
||||
{
|
||||
char *old_file, *old_url;
|
||||
|
||||
@@ -841,7 +887,7 @@ register_download (const char *url, const char *file)
|
||||
register_download() above. */
|
||||
|
||||
void
|
||||
register_redirection (const char *from, const char *to)
|
||||
FNNAME_WTHREADS(register_redirection) (const char *from, const char *to)
|
||||
{
|
||||
char *file;
|
||||
|
||||
@@ -856,7 +902,7 @@ register_redirection (const char *from, const char *to)
|
||||
/* Register that the file has been deleted. */
|
||||
|
||||
void
|
||||
register_delete_file (const char *file)
|
||||
FNNAME_WTHREADS(register_delete_file) (const char *file)
|
||||
{
|
||||
char *old_url, *old_file;
|
||||
|
||||
@@ -874,7 +920,7 @@ register_delete_file (const char *file)
|
||||
/* Register that FILE is an HTML file that has been downloaded. */
|
||||
|
||||
void
|
||||
register_html (const char *file)
|
||||
FNNAME_WTHREADS(register_html) (const char *url, const char *file)
|
||||
{
|
||||
if (!downloaded_html_set)
|
||||
downloaded_html_set = make_string_hash_table (0);
|
||||
@@ -884,7 +930,7 @@ register_html (const char *file)
|
||||
/* Register that FILE is a CSS file that has been downloaded. */
|
||||
|
||||
void
|
||||
register_css (const char *file)
|
||||
FNNAME_WTHREADS(register_css) (const char *url, const char *file)
|
||||
{
|
||||
if (!downloaded_css_set)
|
||||
downloaded_css_set = make_string_hash_table (0);
|
||||
@@ -895,8 +941,8 @@ static void downloaded_files_free (void);
|
||||
|
||||
/* Cleanup the data structures associated with this file. */
|
||||
|
||||
void
|
||||
convert_cleanup (void)
|
||||
static void
|
||||
FNNAME_WTHREADS(convert_cleanup) (void)
|
||||
{
|
||||
if (dl_file_url_map)
|
||||
{
|
||||
@@ -916,7 +962,7 @@ convert_cleanup (void)
|
||||
if (converted_files)
|
||||
string_set_free (converted_files);
|
||||
}
|
||||
|
||||
|
||||
/* Book-keeping code for downloaded files that enables extension
|
||||
hacks. */
|
||||
|
||||
@@ -971,7 +1017,7 @@ downloaded_mode_to_ptr (downloaded_file_t mode)
|
||||
URLs. */
|
||||
|
||||
downloaded_file_t
|
||||
downloaded_file (downloaded_file_t mode, const char *file)
|
||||
FNNAME_WTHREADS(downloaded_file) (downloaded_file_t mode, const char *file)
|
||||
{
|
||||
downloaded_file_t *ptr;
|
||||
|
||||
@@ -1012,7 +1058,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:
|
||||
@@ -1085,6 +1131,17 @@ html_quote_string (const char *s)
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_THREADS
|
||||
THREAD_SAFE (downloaded_file_t, downloaded_file, (downloaded_file_t a, const char *b), (a, b));
|
||||
THREAD_SAFE_VOID (register_download, (const char *a, const char *b), (a, b));
|
||||
THREAD_SAFE_VOID (register_redirection, (const char *a, const char *b), (a, b));
|
||||
THREAD_SAFE_VOID (register_html, (const char *a, const char *b), (a, b));
|
||||
THREAD_SAFE_VOID (register_css, (const char *a, const char *b), (a, b));
|
||||
THREAD_SAFE_VOID (register_delete_file, (const char *a), (a));
|
||||
THREAD_SAFE_VOID (convert_cleanup, (void), ());
|
||||
THREAD_SAFE_VOID (convert_all_links, (void), ());
|
||||
#endif
|
||||
|
||||
/*
|
||||
* vim: et ts=2 sw=2
|
||||
*/
|
||||
|
||||
@@ -98,14 +98,12 @@ typedef enum
|
||||
} downloaded_file_t;
|
||||
|
||||
downloaded_file_t downloaded_file (downloaded_file_t, const char *);
|
||||
|
||||
void register_download (const char *, const char *);
|
||||
void register_redirection (const char *, const char *);
|
||||
void register_html (const char *);
|
||||
void register_css (const char *);
|
||||
void register_delete_file (const char *);
|
||||
void register_download (const char *a, const char *b);
|
||||
void convert_all_links (void);
|
||||
void convert_cleanup (void);
|
||||
void register_delete_file (const char *a);
|
||||
void register_redirection (const char *a, const char *b);
|
||||
void register_css (const char *a, const char *b);
|
||||
void register_html (const char *a, const char *b);
|
||||
|
||||
char *html_quote_string (const char *);
|
||||
|
||||
|
||||
@@ -58,9 +58,7 @@ 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
|
||||
@@ -153,13 +151,13 @@ cookie_expired_p (const struct cookie *c)
|
||||
static void
|
||||
delete_cookie (struct cookie *cookie)
|
||||
{
|
||||
xfree (cookie->domain);
|
||||
xfree (cookie->path);
|
||||
xfree (cookie->attr);
|
||||
xfree (cookie->value);
|
||||
xfree_null (cookie->domain);
|
||||
xfree_null (cookie->path);
|
||||
xfree_null (cookie->attr);
|
||||
xfree_null (cookie->value);
|
||||
xfree (cookie);
|
||||
}
|
||||
|
||||
|
||||
/* Functions for storing cookies.
|
||||
|
||||
All cookies can be reached beginning with jar->chains. The key in
|
||||
@@ -304,12 +302,7 @@ discard_matching_cookie (struct cookie_jar *jar, struct cookie *cookie)
|
||||
|
||||
res = hash_table_get_pair (jar->chains, victim->domain,
|
||||
&chain_key, NULL);
|
||||
|
||||
if (res == 0)
|
||||
{
|
||||
logprintf (LOG_VERBOSE, _("Unable to get cookie for %s\n"),
|
||||
victim->domain);
|
||||
}
|
||||
assert (res != 0);
|
||||
if (!victim->next)
|
||||
{
|
||||
/* VICTIM was the only cookie in the chain. Destroy the
|
||||
@@ -324,7 +317,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. */
|
||||
|
||||
@@ -376,7 +369,7 @@ parse_set_cookie (const char *set_cookie, bool silent)
|
||||
{
|
||||
if (!TOKEN_NON_EMPTY (value))
|
||||
goto error;
|
||||
xfree (cookie->domain);
|
||||
xfree_null (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
|
||||
@@ -389,7 +382,7 @@ parse_set_cookie (const char *set_cookie, bool silent)
|
||||
{
|
||||
if (!TOKEN_NON_EMPTY (value))
|
||||
goto error;
|
||||
xfree (cookie->path);
|
||||
xfree_null (cookie->path);
|
||||
cookie->path = strdupdelim (value.b, value.e);
|
||||
}
|
||||
else if (TOKEN_IS (name, "expires"))
|
||||
@@ -463,7 +456,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. */
|
||||
@@ -525,12 +518,12 @@ check_domain_match (const char *cookie_domain, const char *host)
|
||||
{
|
||||
|
||||
#ifdef HAVE_LIBPSL
|
||||
DEBUGP (("cdm: 1"));
|
||||
char *cookie_domain_lower = NULL;
|
||||
char *host_lower = NULL;
|
||||
const psl_ctx_t *psl;
|
||||
int is_acceptable;
|
||||
|
||||
DEBUGP (("cdm: 1"));
|
||||
if (!(psl = psl_builtin()))
|
||||
{
|
||||
DEBUGP (("\nlibpsl not built with a public suffix list. "
|
||||
@@ -699,7 +692,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. */
|
||||
@@ -783,7 +776,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'. */
|
||||
@@ -1114,7 +1107,7 @@ cookie_header (struct cookie_jar *jar, const char *host,
|
||||
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.
|
||||
@@ -1353,7 +1346,7 @@ cookie_jar_save (struct cookie_jar *jar, const char *file)
|
||||
|
||||
DEBUGP (("Done saving cookies.\n"));
|
||||
}
|
||||
|
||||
|
||||
/* Clean up cookie-related data. */
|
||||
|
||||
void
|
||||
@@ -1376,7 +1369,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. */
|
||||
@@ -1445,8 +1438,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;
|
||||
xfree (n);
|
||||
xfree (v);
|
||||
free (n);
|
||||
free (v);
|
||||
}
|
||||
if (expected[j])
|
||||
printf ("Too few parameters for '%s'\n", data);
|
||||
|
||||
@@ -52,7 +52,6 @@ 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;
|
||||
@@ -98,7 +97,7 @@ get_uri_string (const char *at, int *pos, int *length)
|
||||
*length -= 2;
|
||||
}
|
||||
|
||||
return xstrndup (at + *pos, *length);
|
||||
return xstrdup (at + *pos);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -56,7 +56,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 GATEWAYTIMEOUT:
|
||||
case PROXERR:
|
||||
return WGET_EXIT_SERVER_ERROR;
|
||||
case URLERROR: case QUOTEXC: case SSLINITFAILED: case UNKNOWNATTR:
|
||||
default:
|
||||
|
||||
@@ -43,9 +43,8 @@ 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
|
||||
@@ -191,7 +190,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 == c_strncasecmp (skey_head[i], respline, l))
|
||||
if (0 == strncasecmp (skey_head[i], respline, l))
|
||||
{
|
||||
seed = respline + l;
|
||||
break;
|
||||
@@ -785,8 +784,16 @@ ftp_epsv (int csock, ip_address *ip, int *port)
|
||||
}
|
||||
|
||||
/* Finally, get the port number */
|
||||
for (tport = 0, i = 0; i < 5 && c_isdigit (*s); i++, s++)
|
||||
tport = 0;
|
||||
for (i = 1; c_isdigit (*s); s++)
|
||||
{
|
||||
if (i > 5)
|
||||
{
|
||||
xfree (respline);
|
||||
return FTPINVPASV;
|
||||
}
|
||||
tport = (*s - '0') + 10 * tport;
|
||||
}
|
||||
|
||||
/* Make sure that the response terminates correcty */
|
||||
if (*s++ != delim)
|
||||
@@ -958,18 +965,16 @@ 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. */
|
||||
static const char *list_commands[] = {
|
||||
"LIST -a",
|
||||
"LIST"
|
||||
};
|
||||
|
||||
*list_a_used = false;
|
||||
const char *list_commands[] = { "LIST -a",
|
||||
"LIST" };
|
||||
|
||||
if (avoid_list_a)
|
||||
{
|
||||
@@ -1063,25 +1068,25 @@ ftp_syst (int csock, enum stype *server_type, enum ustype *unix_type)
|
||||
|
||||
if (request == NULL)
|
||||
*server_type = ST_OTHER;
|
||||
else if (!c_strcasecmp (request, "VMS"))
|
||||
else if (!strcasecmp (request, "VMS"))
|
||||
*server_type = ST_VMS;
|
||||
else if (!c_strcasecmp (request, "UNIX"))
|
||||
else if (!strcasecmp (request, "UNIX"))
|
||||
{
|
||||
*server_type = ST_UNIX;
|
||||
/* 2013-10-17 Andrea Urbani (matfanjol)
|
||||
I check more in depth the system type */
|
||||
if (!c_strncasecmp (ftp_last_respline, "215 UNIX Type: L8", 17))
|
||||
if (!strncasecmp (ftp_last_respline, "215 UNIX Type: L8", 17))
|
||||
*unix_type = UST_TYPE_L8;
|
||||
else if (!c_strncasecmp (ftp_last_respline,
|
||||
else if (!strncasecmp (ftp_last_respline,
|
||||
"215 UNIX MultiNet Unix Emulation V5.3(93)", 41))
|
||||
*unix_type = UST_MULTINET;
|
||||
}
|
||||
else if (!c_strcasecmp (request, "WINDOWS_NT")
|
||||
|| !c_strcasecmp (request, "WINDOWS2000"))
|
||||
else if (!strcasecmp (request, "WINDOWS_NT")
|
||||
|| !strcasecmp (request, "WINDOWS2000"))
|
||||
*server_type = ST_WINNT;
|
||||
else if (!c_strcasecmp (request, "MACOS"))
|
||||
else if (!strcasecmp (request, "MACOS"))
|
||||
*server_type = ST_MACOS;
|
||||
else if (!c_strcasecmp (request, "OS/400"))
|
||||
else if (!strcasecmp (request, "OS/400"))
|
||||
*server_type = ST_OS400;
|
||||
else
|
||||
*server_type = ST_OTHER;
|
||||
@@ -1130,7 +1135,7 @@ ftp_pwd (int csock, char **pwd)
|
||||
goto err;
|
||||
|
||||
/* Has the `pwd' been already allocated? Free! */
|
||||
xfree (*pwd);
|
||||
xfree_null (*pwd);
|
||||
|
||||
*pwd = xstrdup (request);
|
||||
|
||||
|
||||
17
src/ftp-ls.c
17
src/ftp-ls.c
@@ -42,7 +42,6 @@ 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
|
||||
@@ -122,7 +121,7 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
|
||||
{
|
||||
len = clean_line (line, len);
|
||||
/* Skip if total... */
|
||||
if (!c_strncasecmp (line, "total", 5))
|
||||
if (!strncasecmp (line, "total", 5))
|
||||
continue;
|
||||
/* Get the first token (permissions). */
|
||||
tok = strtok (line, " ");
|
||||
@@ -200,7 +199,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 (!c_strcasecmp (tok, months[i]))
|
||||
if (!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. */
|
||||
@@ -363,8 +362,8 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
|
||||
if (error || ignore)
|
||||
{
|
||||
DEBUGP (("Skipping.\n"));
|
||||
xfree (cur.name);
|
||||
xfree (cur.linkto);
|
||||
xfree_null (cur.name);
|
||||
xfree_null (cur.linkto);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -776,14 +775,14 @@ ftp_parse_vms_ls (const char *file)
|
||||
what will work in a CWD command.
|
||||
*/
|
||||
len = strlen (tok);
|
||||
if (!c_strncasecmp((tok + (len - 4)), ".DIR", 4))
|
||||
if (!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 (!c_strncasecmp ((tok + (len - 6)), ".DIR;1", 6))
|
||||
else if (!strncasecmp ((tok + (len - 6)), ".DIR;1", 6))
|
||||
{
|
||||
*(tok+ (len - 6)) = '\0'; /* Discard ".DIR;1". */
|
||||
cur.type = FT_DIRECTORY;
|
||||
@@ -1052,7 +1051,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
|
||||
@@ -1089,7 +1088,7 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
|
||||
else
|
||||
upwd = concat_strings (tmpu, "@", (char *) 0);
|
||||
xfree (tmpu);
|
||||
xfree (tmpp);
|
||||
xfree_null (tmpp);
|
||||
}
|
||||
else
|
||||
upwd = xstrdup ("");
|
||||
|
||||
218
src/ftp.c
218
src/ftp.c
@@ -50,7 +50,6 @@ as that of the covered work. */
|
||||
#include "convert.h" /* for downloaded_file */
|
||||
#include "recur.h" /* for INFINITE_RECURSION */
|
||||
#include "warc.h"
|
||||
#include "c-strcase.h"
|
||||
|
||||
#ifdef __VMS
|
||||
# include "vms.h"
|
||||
@@ -77,6 +76,7 @@ typedef struct
|
||||
struct url *proxy; /* FTWK-style proxy */
|
||||
} ccon;
|
||||
|
||||
extern int numurls;
|
||||
|
||||
/* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
|
||||
the string S, and return the number converted to wgint, if found, 0
|
||||
@@ -102,7 +102,7 @@ ftp_expected_bytes (const char *s)
|
||||
return 0;
|
||||
if (c_tolower (*s) != 'b')
|
||||
continue;
|
||||
if (c_strncasecmp (s, "byte", 4))
|
||||
if (strncasecmp (s, "byte", 4))
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
@@ -449,7 +449,7 @@ Error in server response, closing control connection.\n"));
|
||||
return err;
|
||||
case FTPSRVERR :
|
||||
/* PWD unsupported -- assume "/". */
|
||||
xfree (con->id);
|
||||
xfree_null (con->id);
|
||||
con->id = xstrdup ("/");
|
||||
break;
|
||||
case FTPOK:
|
||||
@@ -700,78 +700,74 @@ Error in server response, closing control connection.\n"));
|
||||
|
||||
for (cwd_count = cwd_start; cwd_count < cwd_end; cwd_count++)
|
||||
{
|
||||
switch (cwd_count)
|
||||
{
|
||||
case 0:
|
||||
/* Step one (optional): Go to the initial directory,
|
||||
exactly as reported by the server.
|
||||
*/
|
||||
targ = con->id;
|
||||
break;
|
||||
switch (cwd_count)
|
||||
{
|
||||
case 0:
|
||||
/* Step one (optional): Go to the initial directory,
|
||||
exactly as reported by the server.
|
||||
*/
|
||||
targ = con->id;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Step two: Go to the target directory. (Absolute or
|
||||
relative will work now.)
|
||||
*/
|
||||
targ = target;
|
||||
break;
|
||||
case 1:
|
||||
/* Step two: Go to the target directory. (Absolute or
|
||||
relative will work now.)
|
||||
*/
|
||||
targ = target;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Step three (optional): "CWD []" to restore server
|
||||
VMS-ness.
|
||||
*/
|
||||
targ = "[]";
|
||||
break;
|
||||
case 2:
|
||||
/* Step three (optional): "CWD []" to restore server
|
||||
VMS-ness.
|
||||
*/
|
||||
targ = "[]";
|
||||
break;
|
||||
|
||||
default:
|
||||
logprintf (LOG_ALWAYS, _("Logically impossible section reached in getftp()"));
|
||||
logprintf (LOG_ALWAYS, _("cwd_count: %d\ncwd_start: %d\ncwd_end: %d\n"),
|
||||
cwd_count, cwd_start, cwd_end);
|
||||
abort ();
|
||||
}
|
||||
default:
|
||||
/* Can't happen. */
|
||||
assert (1);
|
||||
}
|
||||
|
||||
if (!opt.server_response)
|
||||
logprintf (LOG_VERBOSE, "==> CWD (%d) %s ... ", cwd_count,
|
||||
quotearg_style (escape_quoting_style, target));
|
||||
|
||||
err = ftp_cwd (csock, targ);
|
||||
|
||||
/* FTPRERR, WRITEFAILED, FTPNSFOD */
|
||||
switch (err)
|
||||
{
|
||||
case FTPRERR:
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
logputs (LOG_NOTQUIET, _("\
|
||||
if (!opt.server_response)
|
||||
logprintf (LOG_VERBOSE, "==> CWD (%d) %s ... ", cwd_count,
|
||||
quotearg_style (escape_quoting_style, target));
|
||||
err = ftp_cwd (csock, targ);
|
||||
/* FTPRERR, WRITEFAILED, FTPNSFOD */
|
||||
switch (err)
|
||||
{
|
||||
case FTPRERR:
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
logputs (LOG_NOTQUIET, _("\
|
||||
Error in server response, closing control connection.\n"));
|
||||
fd_close (csock);
|
||||
con->csock = -1;
|
||||
return err;
|
||||
case WRITEFAILED:
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
logputs (LOG_NOTQUIET,
|
||||
_("Write failed, closing control connection.\n"));
|
||||
fd_close (csock);
|
||||
con->csock = -1;
|
||||
return err;
|
||||
case FTPNSFOD:
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
logprintf (LOG_NOTQUIET, _("No such directory %s.\n\n"),
|
||||
quote (u->dir));
|
||||
fd_close (csock);
|
||||
con->csock = -1;
|
||||
return err;
|
||||
case FTPOK:
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
fd_close (csock);
|
||||
con->csock = -1;
|
||||
return err;
|
||||
case WRITEFAILED:
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
logputs (LOG_NOTQUIET,
|
||||
_("Write failed, closing control connection.\n"));
|
||||
fd_close (csock);
|
||||
con->csock = -1;
|
||||
return err;
|
||||
case FTPNSFOD:
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
logprintf (LOG_NOTQUIET, _("No such directory %s.\n\n"),
|
||||
quote (u->dir));
|
||||
fd_close (csock);
|
||||
con->csock = -1;
|
||||
return err;
|
||||
case FTPOK:
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
if (!opt.server_response)
|
||||
logputs (LOG_VERBOSE, _("done.\n"));
|
||||
|
||||
if (!opt.server_response)
|
||||
logputs (LOG_VERBOSE, _("done.\n"));
|
||||
|
||||
} /* for */
|
||||
} /* for */
|
||||
|
||||
/* 2004-09-20 SMS. */
|
||||
/* End of deviant indenting. */
|
||||
|
||||
} /* else */
|
||||
}
|
||||
@@ -1310,6 +1306,11 @@ Error in server response, closing control connection.\n"));
|
||||
|
||||
/* Get the contents of the document. */
|
||||
flags = 0;
|
||||
#ifdef ENABLE_METALINK
|
||||
if (opt.metalink_file && expected_bytes)
|
||||
/* If content-length is present, read that much; otherwise, read until EOF. */
|
||||
flags |= rb_read_exactly;
|
||||
#endif
|
||||
if (restval && rest_failed)
|
||||
flags |= rb_skip_startpos;
|
||||
rd_size = 0;
|
||||
@@ -1350,6 +1351,7 @@ Error in server response, closing control connection.\n"));
|
||||
|
||||
/* Get the server to tell us if everything is retrieved. */
|
||||
err = ftp_response (csock, &respline);
|
||||
*last_expected_bytes = ftp_expected_bytes (respline);
|
||||
if (err != FTPOK)
|
||||
{
|
||||
/* The control connection is decidedly closed. Print the time
|
||||
@@ -1365,12 +1367,16 @@ Error in server response, closing control connection.\n"));
|
||||
con->csock = -1;
|
||||
return FTPRETRINT;
|
||||
} /* err != FTPOK */
|
||||
*last_expected_bytes = ftp_expected_bytes (respline);
|
||||
/* If retrieval failed for any reason, return FTPRETRINT, but do not
|
||||
close socket, since the control connection is still alive. If
|
||||
there is something wrong with the control connection, it will
|
||||
become apparent later. */
|
||||
if (*respline != '2')
|
||||
become apparent later.
|
||||
In case of a metalink file download, proabably due to taking only a chunk
|
||||
of the file, respline becomes '2', even though file download is successful.
|
||||
TODO: Make sure exempting metalink downloads from this check does not cause
|
||||
any troubles.
|
||||
*/
|
||||
if (*respline != '2' && !opt.metalink_file)
|
||||
{
|
||||
xfree (respline);
|
||||
if (res != -1)
|
||||
@@ -1540,7 +1546,7 @@ Error in server response, closing control connection.\n"));
|
||||
This loop either gets commands from con, or (if ON_YOUR_OWN is
|
||||
set), makes them up to retrieve the file given by the URL. */
|
||||
static uerr_t
|
||||
ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_file)
|
||||
ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_file, struct range *range)
|
||||
{
|
||||
int count, orig_lp;
|
||||
wgint restval, len = 0, qtyread = 0;
|
||||
@@ -1564,7 +1570,6 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
|
||||
else
|
||||
{
|
||||
/* URL-derived file. Consider "-O file" name. */
|
||||
xfree (con->target);
|
||||
con->target = url_file_name (u, NULL);
|
||||
if (!opt.output_document)
|
||||
locf = con->target;
|
||||
@@ -1656,6 +1661,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
|
||||
else
|
||||
restval = 0;
|
||||
|
||||
|
||||
/* Get the current time string. */
|
||||
tms = datetime_str (time (NULL));
|
||||
/* Print fetch message, if opt.verbose. */
|
||||
@@ -1679,11 +1685,24 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
|
||||
else
|
||||
len = 0;
|
||||
|
||||
/* If range is not NULL, then this is a segmented download. Get the relevant
|
||||
segment information from the specified range parameter. */
|
||||
if (range)
|
||||
{
|
||||
restval = range->first_byte;
|
||||
/* It is not the length in the usual sense, but this is the correct
|
||||
value for getftp to use. */
|
||||
len = range->last_byte + 1;
|
||||
}
|
||||
|
||||
/* If we are working on a WARC record, getftp should also write
|
||||
to the warc_tmp file. */
|
||||
err = getftp (u, len, &qtyread, restval, con, count, &last_expected_bytes,
|
||||
warc_tmp);
|
||||
|
||||
if (range)
|
||||
range->bytes_covered = qtyread;
|
||||
|
||||
if (con->csock == -1)
|
||||
con->st &= ~DONE_CWD;
|
||||
else
|
||||
@@ -1707,7 +1726,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
|
||||
if (err == FOPEN_EXCL_ERR)
|
||||
{
|
||||
/* Re-determine the file name. */
|
||||
xfree (con->target);
|
||||
xfree_null (con->target);
|
||||
con->target = url_file_name (u, NULL);
|
||||
locf = con->target;
|
||||
}
|
||||
@@ -1818,7 +1837,7 @@ Removing file due to --delete-after in ftp_loop_internal():\n"));
|
||||
else
|
||||
con->cmd &= ~LEAVE_PENDING;
|
||||
|
||||
if (local_file)
|
||||
if (local_file && !*local_file)
|
||||
*local_file = xstrdup (locf);
|
||||
|
||||
return RETROK;
|
||||
@@ -1856,7 +1875,7 @@ ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
|
||||
|
||||
con->target = xstrdup (lf);
|
||||
xfree (lf);
|
||||
err = ftp_loop_internal (u, NULL, con, NULL);
|
||||
err = ftp_loop_internal (u, NULL, con, NULL, NULL);
|
||||
lf = xstrdup (con->target);
|
||||
xfree (con->target);
|
||||
con->target = old_target;
|
||||
@@ -2051,7 +2070,7 @@ Already have correct symlink %s -> %s\n\n"),
|
||||
else /* opt.retr_symlinks */
|
||||
{
|
||||
if (dlthis)
|
||||
err = ftp_loop_internal (u, f, con, NULL);
|
||||
err = ftp_loop_internal (u, f, con, NULL, NULL);
|
||||
} /* opt.retr_symlinks */
|
||||
break;
|
||||
case FT_DIRECTORY:
|
||||
@@ -2062,7 +2081,7 @@ Already have correct symlink %s -> %s\n\n"),
|
||||
case FT_PLAINFILE:
|
||||
/* Call the retrieve loop. */
|
||||
if (dlthis)
|
||||
err = ftp_loop_internal (u, f, con, NULL);
|
||||
err = ftp_loop_internal (u, f, con, NULL, NULL);
|
||||
break;
|
||||
case FT_UNKNOWN:
|
||||
logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
|
||||
@@ -2216,29 +2235,6 @@ has_insecure_name_p (const char *s)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Test if the file node is invalid. This can occur due to malformed or
|
||||
* maliciously crafted listing files being returned by the server.
|
||||
*
|
||||
* Currently, this function only tests if there are multiple entries in the
|
||||
* listing file by the same name. However this function can be expanded as more
|
||||
* such illegal listing formats are discovered. */
|
||||
static bool
|
||||
is_invalid_entry (struct fileinfo *f)
|
||||
{
|
||||
struct fileinfo *cur = f;
|
||||
char *f_name = f->name;
|
||||
|
||||
/* If the node we're currently checking has a duplicate later, we eliminate
|
||||
* the current node and leave the next one intact. */
|
||||
while (cur->next)
|
||||
{
|
||||
cur = cur->next;
|
||||
if (strcmp(f_name, cur->name) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* A near-top-level function to retrieve the files in a directory.
|
||||
The function calls ftp_get_listing, to get a linked list of files.
|
||||
Then it weeds out the file names that do not match the pattern.
|
||||
@@ -2276,11 +2272,11 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
|
||||
f = f->next;
|
||||
}
|
||||
}
|
||||
/* Remove all files with possible harmful names or invalid entries. */
|
||||
/* Remove all files with possible harmful names */
|
||||
f = start;
|
||||
while (f)
|
||||
{
|
||||
if (has_insecure_name_p (f->name) || is_invalid_entry (f))
|
||||
if (has_insecure_name_p (f->name))
|
||||
{
|
||||
logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
|
||||
quote (f->name));
|
||||
@@ -2368,7 +2364,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
|
||||
{
|
||||
/* Let's try retrieving it anyway. */
|
||||
con->st |= ON_YOUR_OWN;
|
||||
res = ftp_loop_internal (u, NULL, con, NULL);
|
||||
res = ftp_loop_internal (u, NULL, con, NULL, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -2389,7 +2385,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
|
||||
encoded into a URL. */
|
||||
uerr_t
|
||||
ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
|
||||
bool recursive, bool glob)
|
||||
bool recursive, bool glob, struct range *range)
|
||||
{
|
||||
ccon con; /* FTP connection */
|
||||
uerr_t res;
|
||||
@@ -2403,6 +2399,10 @@ ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
|
||||
con.rs = ST_UNIX;
|
||||
con.id = NULL;
|
||||
con.proxy = proxy;
|
||||
/* To let ftp_loop_internal AND getftp know of the desired file name. Added
|
||||
while implementing metalink support to wget. */
|
||||
if(local_file && *local_file)
|
||||
con.target = xstrdup (*local_file);
|
||||
|
||||
/* If the file name is empty, the user probably wants a directory
|
||||
index. We'll provide one, properly HTML-ized. Unless
|
||||
@@ -2468,7 +2468,7 @@ ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
|
||||
ispattern ? GLOB_GLOBALL : GLOB_GETONE);
|
||||
}
|
||||
else
|
||||
res = ftp_loop_internal (u, NULL, &con, local_file);
|
||||
res = ftp_loop_internal (u, NULL, &con, local_file, range);
|
||||
}
|
||||
if (res == FTPOK)
|
||||
res = RETROK;
|
||||
@@ -2477,8 +2477,10 @@ ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
|
||||
/* If a connection was left, quench it. */
|
||||
if (con.csock != -1)
|
||||
fd_close (con.csock);
|
||||
xfree (con.id);
|
||||
xfree (con.target);
|
||||
xfree_null (con.id);
|
||||
con.id = NULL;
|
||||
xfree_null (con.target);
|
||||
con.target = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -2492,7 +2494,7 @@ delelement (struct fileinfo *f, struct fileinfo **start)
|
||||
struct fileinfo *next = f->next;
|
||||
|
||||
xfree (f->name);
|
||||
xfree (f->linkto);
|
||||
xfree_null (f->linkto);
|
||||
xfree (f);
|
||||
|
||||
if (next)
|
||||
|
||||
@@ -32,6 +32,8 @@ as that of the covered work. */
|
||||
#ifndef FTP_H
|
||||
#define FTP_H
|
||||
|
||||
#include "wget.h"
|
||||
|
||||
#include "host.h"
|
||||
|
||||
/* System types. */
|
||||
@@ -53,6 +55,8 @@ enum ustype
|
||||
UST_OTHER
|
||||
};
|
||||
|
||||
extern char ftp_last_respline[];
|
||||
|
||||
uerr_t ftp_response (int, char **);
|
||||
uerr_t ftp_login (int, const char *, const char *);
|
||||
uerr_t ftp_port (int, int *);
|
||||
@@ -150,7 +154,7 @@ enum wget_ftp_fstatus
|
||||
};
|
||||
|
||||
struct fileinfo *ftp_parse_ls (const char *, const enum stype);
|
||||
uerr_t ftp_loop (struct url *, char **, int *, struct url *, bool, bool);
|
||||
uerr_t ftp_loop (struct url *, char **, int *, struct url *, bool, bool, struct range *);
|
||||
|
||||
uerr_t ftp_index (const char *, struct url *, struct fileinfo *);
|
||||
|
||||
|
||||
272
src/gettext.h
Normal file
272
src/gettext.h
Normal file
@@ -0,0 +1,272 @@
|
||||
/* 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 */
|
||||
88
src/gnutls.c
88
src/gnutls.c
@@ -122,10 +122,9 @@ ssl_init (void)
|
||||
while ((dent = readdir (dir)) != NULL)
|
||||
{
|
||||
struct stat st;
|
||||
size_t ca_file_length = dirlen + strlen(dent->d_name) + 2;
|
||||
char *ca_file = alloca(ca_file_length);
|
||||
char ca_file[dirlen + strlen(dent->d_name) + 2];
|
||||
|
||||
snprintf (ca_file, ca_file_length, "%s/%s", ca_directory, dent->d_name);
|
||||
snprintf (ca_file, sizeof(ca_file), "%s/%s", ca_directory, dent->d_name);
|
||||
if (stat (ca_file, &st) != 0)
|
||||
continue;
|
||||
|
||||
@@ -139,7 +138,8 @@ 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)
|
||||
DEBUGP (("WARNING: Failed to open cert %s: (%d).\n", ca_file, rc));
|
||||
logprintf (LOG_NOTQUIET, _("ERROR: Failed to open cert %s: (%d).\n"),
|
||||
ca_file, rc);
|
||||
else
|
||||
ncerts += rc;
|
||||
}
|
||||
@@ -149,36 +149,6 @@ 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. */
|
||||
@@ -211,6 +181,10 @@ 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;
|
||||
@@ -229,6 +203,11 @@ 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)
|
||||
{
|
||||
@@ -427,10 +406,9 @@ ssl_connect_wget (int fd, const char *hostname)
|
||||
#endif
|
||||
struct wgnutls_transport_context *ctx;
|
||||
gnutls_session_t session;
|
||||
int err;
|
||||
const char *str;
|
||||
|
||||
int err,alert;
|
||||
gnutls_init (&session, GNUTLS_CLIENT);
|
||||
const char *str;
|
||||
|
||||
/* We set the server name but only if it's not an IP address. */
|
||||
if (! is_valid_ip_address (hostname))
|
||||
@@ -450,40 +428,26 @@ ssl_connect_wget (int fd, const char *hostname)
|
||||
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:
|
||||
err = gnutls_priority_set_direct (session, "NORMAL:%COMPAT:-VERS-SSL3.0", NULL);
|
||||
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);
|
||||
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:-VERS-SSL3.0", NULL);
|
||||
err = gnutls_priority_set_direct (session, "NORMAL:-RSA", NULL);
|
||||
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 ();
|
||||
}
|
||||
#else
|
||||
@@ -492,7 +456,6 @@ ssl_connect_wget (int fd, const char *hostname)
|
||||
{
|
||||
case secure_protocol_auto:
|
||||
break;
|
||||
|
||||
case secure_protocol_sslv2:
|
||||
case secure_protocol_sslv3:
|
||||
allowed_protocols[0] = GNUTLS_SSL3;
|
||||
@@ -506,20 +469,7 @@ ssl_connect_wget (int fd, const char *hostname)
|
||||
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
|
||||
@@ -583,7 +533,7 @@ ssl_connect_wget (int fd, const char *hostname)
|
||||
if (err == GNUTLS_E_WARNING_ALERT_RECEIVED ||
|
||||
err == GNUTLS_E_FATAL_ALERT_RECEIVED)
|
||||
{
|
||||
gnutls_alert_description_t alert = gnutls_alert_get (session);
|
||||
alert = gnutls_alert_get (session);
|
||||
str = gnutls_alert_get_name (alert);
|
||||
if (str == NULL)
|
||||
str = "(unknown)";
|
||||
|
||||
13
src/hash.c
13
src/hash.c
@@ -46,11 +46,10 @@ as that of the covered work. */
|
||||
# include "utils.h"
|
||||
#else
|
||||
/* Make do without them. */
|
||||
# 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)
|
||||
|
||||
# define xnew(x) xmalloc (sizeof (x))
|
||||
# define xnew_array(type, x) xmalloc (sizeof (type) * (x))
|
||||
# define xmalloc malloc
|
||||
# define xfree free
|
||||
# ifndef countof
|
||||
# define countof(x) (sizeof (x) / sizeof ((x)[0]))
|
||||
# endif
|
||||
@@ -586,7 +585,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. */
|
||||
@@ -741,7 +740,7 @@ cmp_pointer (const void *ptr1, const void *ptr2)
|
||||
{
|
||||
return ptr1 == ptr2;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
28
src/host.c
28
src/host.c
@@ -57,10 +57,6 @@ as that of the covered work. */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef ENABLE_IRI
|
||||
#include <idn-free.h>
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
#include "host.h"
|
||||
#include "url.h"
|
||||
@@ -155,13 +151,6 @@ 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)
|
||||
@@ -320,7 +309,7 @@ address_list_release (struct address_list *al)
|
||||
address_list_delete (al);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Versions of gethostbyname and getaddrinfo that support timeout. */
|
||||
|
||||
#ifndef ENABLE_IPV6
|
||||
@@ -419,7 +408,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. */
|
||||
@@ -581,7 +570,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 --
|
||||
@@ -603,7 +592,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, (void *) al));
|
||||
DEBUGP (("Found %s in host_name_addresses_map (%p)\n", host, al));
|
||||
++al->refcount;
|
||||
return al;
|
||||
}
|
||||
@@ -648,7 +637,7 @@ cache_remove (const char *host)
|
||||
hash_table_remove (host_name_addresses_map, host);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
@@ -745,13 +734,14 @@ lookup_host (const char *host, int flags)
|
||||
str = xmalloc (len);
|
||||
snprintf (str, len, "%s (%s)", name, host);
|
||||
str[len-1] = '\0';
|
||||
idn_free (name);
|
||||
xfree (name);
|
||||
}
|
||||
|
||||
logprintf (LOG_VERBOSE, _("Resolving %s... "),
|
||||
quotearg_style (escape_quoting_style, str ? str : host));
|
||||
|
||||
xfree (str);
|
||||
if (str)
|
||||
xfree (str);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
@@ -858,7 +848,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
|
||||
|
||||
@@ -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. "<foo" -> "<foo".
|
||||
However, "<foo" will work, as will "<!foo", "<", 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. */
|
||||
|
||||
@@ -881,7 +881,7 @@ map_html_tags (const char *text, int size,
|
||||
if (*p == '!')
|
||||
{
|
||||
if (!(flags & MHT_STRICT_COMMENTS)
|
||||
&& p + 3 < end && p[1] == '-' && p[2] == '-')
|
||||
&& p < end + 3 && 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 +1167,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)
|
||||
|
||||
@@ -45,7 +45,6 @@ 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 *);
|
||||
|
||||
@@ -256,7 +255,7 @@ find_attr (struct taginfo *tag, const char *name, int *attrind)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < tag->nattrs; i++)
|
||||
if (!c_strcasecmp (tag->attrs[i].name, name))
|
||||
if (!strcasecmp (tag->attrs[i].name, name))
|
||||
{
|
||||
if (attrind)
|
||||
*attrind = i;
|
||||
@@ -379,7 +378,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)
|
||||
{
|
||||
@@ -488,7 +487,8 @@ 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;
|
||||
|
||||
xfree (ctx->base);
|
||||
if (ctx->base)
|
||||
xfree (ctx->base);
|
||||
if (ctx->parent_base)
|
||||
ctx->base = uri_merge (ctx->parent_base, newbase);
|
||||
else
|
||||
@@ -536,12 +536,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 == c_strcasecmp (rel, "stylesheet"))
|
||||
if (0 == strcasecmp (rel, "stylesheet"))
|
||||
{
|
||||
up->link_inline_p = 1;
|
||||
up->link_expect_css = 1;
|
||||
}
|
||||
else if (0 == c_strcasecmp (rel, "shortcut icon"))
|
||||
else if (0 == strcasecmp (rel, "shortcut icon"))
|
||||
{
|
||||
up->link_inline_p = 1;
|
||||
}
|
||||
@@ -553,7 +553,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 || c_strcasecmp (type, "text/html") == 0)
|
||||
if (!type || strcasecmp (type, "text/html") == 0)
|
||||
up->link_expect_html = 1;
|
||||
}
|
||||
}
|
||||
@@ -570,7 +570,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 == c_strcasecmp (http_equiv, "refresh"))
|
||||
if (http_equiv && 0 == 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 +615,7 @@ tag_handle_meta (int tagid _GL_UNUSED, struct taginfo *tag, struct map_context *
|
||||
entry->link_expect_html = 1;
|
||||
}
|
||||
}
|
||||
else if (http_equiv && 0 == c_strcasecmp (http_equiv, "content-type"))
|
||||
else if (http_equiv && 0 == strcasecmp (http_equiv, "content-type"))
|
||||
{
|
||||
/* Handle stuff like:
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=CHARSET"> */
|
||||
@@ -629,17 +629,17 @@ tag_handle_meta (int tagid _GL_UNUSED, struct taginfo *tag, struct map_context *
|
||||
if (!mcharset)
|
||||
return;
|
||||
|
||||
xfree (meta_charset);
|
||||
xfree_null (meta_charset);
|
||||
meta_charset = mcharset;
|
||||
}
|
||||
else if (name && 0 == c_strcasecmp (name, "robots"))
|
||||
else if (name && 0 == strcasecmp (name, "robots"))
|
||||
{
|
||||
/* Handle stuff like:
|
||||
<meta name="robots" content="index,nofollow"> */
|
||||
char *content = find_attr (tag, "content", NULL);
|
||||
if (!content)
|
||||
return;
|
||||
if (!c_strcasecmp (content, "none"))
|
||||
if (!strcasecmp (content, "none"))
|
||||
ctx->nofollow = true;
|
||||
else
|
||||
{
|
||||
@@ -651,7 +651,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 (!c_strncasecmp (content, "nofollow", end - content))
|
||||
if (!strncasecmp (content, "nofollow", end - content))
|
||||
ctx->nofollow = true;
|
||||
/* Skip past the next comma, if any. */
|
||||
if (*end == ',')
|
||||
@@ -692,7 +692,7 @@ collect_tags_mapper (struct taginfo *tag, void *arg)
|
||||
|
||||
check_style_attr (tag, ctx);
|
||||
|
||||
if (tag->end_tag_p && (0 == c_strcasecmp (tag->name, "style"))
|
||||
if (tag->end_tag_p && (0 == strcasecmp (tag->name, "style"))
|
||||
&& tag->contents_begin && tag->contents_end
|
||||
&& tag->contents_begin <= tag->contents_end)
|
||||
{
|
||||
@@ -701,7 +701,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,16 +748,15 @@ 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);
|
||||
|
||||
/* 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)
|
||||
/* If meta charset isn't null, override content encoding */
|
||||
if (iri && meta_charset)
|
||||
set_content_encoding (iri, meta_charset);
|
||||
|
||||
DEBUGP (("no-follow in %s: %d\n", file, ctx.nofollow));
|
||||
if (meta_disallow_follow)
|
||||
*meta_disallow_follow = ctx.nofollow;
|
||||
|
||||
xfree (ctx.base);
|
||||
xfree_null (ctx.base);
|
||||
wget_read_file_free (fm);
|
||||
return ctx.head;
|
||||
}
|
||||
@@ -788,7 +787,6 @@ get_urls_file (const char *file)
|
||||
{
|
||||
int up_error_code;
|
||||
char *url_text;
|
||||
char *new_url;
|
||||
struct urlpos *entry;
|
||||
struct url *url;
|
||||
|
||||
@@ -823,7 +821,7 @@ get_urls_file (const char *file)
|
||||
url_text = merged;
|
||||
}
|
||||
|
||||
new_url = rewrite_shorthand_url (url_text);
|
||||
char *new_url = rewrite_shorthand_url (url_text);
|
||||
if (new_url)
|
||||
{
|
||||
xfree (url_text);
|
||||
|
||||
120
src/http-ntlm.c
120
src/http-ntlm.c
@@ -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:
|
||||
@@ -474,82 +474,82 @@ ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
|
||||
|
||||
/* Create the big type-3 message binary blob */
|
||||
|
||||
snprintf (ntlmbuf, sizeof (ntlmbuf),
|
||||
"NTLMSSP%c"
|
||||
"\x03%c%c%c" /* type-3, 32 bits */
|
||||
size = (size_t) 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;
|
||||
|
||||
684
src/http.c
684
src/http.c
File diff suppressed because it is too large
Load Diff
@@ -31,10 +31,12 @@ as that of the covered work. */
|
||||
#ifndef HTTP_H
|
||||
#define HTTP_H
|
||||
|
||||
#include "wget.h"
|
||||
|
||||
struct url;
|
||||
|
||||
uerr_t http_loop (struct url *, struct url *, char **, char **, const char *,
|
||||
int *, struct url *, struct iri *);
|
||||
int *, struct url *, struct iri *, struct range *);
|
||||
void save_cookies (void);
|
||||
void http_cleanup (void);
|
||||
time_t http_atotm (const char *);
|
||||
|
||||
195
src/init.c
195
src/init.c
@@ -69,8 +69,6 @@ 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"
|
||||
@@ -92,7 +90,6 @@ 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);
|
||||
@@ -104,7 +101,6 @@ 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);
|
||||
@@ -161,9 +157,6 @@ static const struct {
|
||||
{ "continue", &opt.always_rest, 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 },
|
||||
@@ -215,6 +208,9 @@ static const struct {
|
||||
#endif
|
||||
{ "input", &opt.input_filename, cmd_file },
|
||||
{ "iri", &opt.enable_iri, cmd_boolean },
|
||||
#ifdef ENABLE_THREADS
|
||||
{ "jobs", &opt.jobs, cmd_number },
|
||||
#endif
|
||||
{ "keepsessioncookies", &opt.keep_session_cookies, cmd_boolean },
|
||||
{ "limitrate", &opt.limit_rate, cmd_bytes },
|
||||
{ "loadcookies", &opt.cookies_input, cmd_file },
|
||||
@@ -222,6 +218,9 @@ static const struct {
|
||||
{ "logfile", &opt.lfilename, cmd_file },
|
||||
{ "login", &opt.ftp_user, cmd_string },/* deprecated*/
|
||||
{ "maxredirect", &opt.max_redirect, cmd_number },
|
||||
#ifdef ENABLE_METALINK
|
||||
{ "metalink", &opt.metalink_file, cmd_file },
|
||||
#endif
|
||||
{ "method", &opt.method, cmd_string_uppercase },
|
||||
{ "mirror", NULL, cmd_spec_mirror },
|
||||
{ "netrc", &opt.netrc, cmd_boolean },
|
||||
@@ -266,6 +265,9 @@ static const struct {
|
||||
{ "removelisting", &opt.remove_listing, cmd_boolean },
|
||||
{ "reportspeed", &opt.report_bps, cmd_spec_report_speed},
|
||||
{ "restrictfilenames", NULL, cmd_spec_restrict_file_names },
|
||||
#ifdef ENABLE_METALINK
|
||||
{ "retries", &opt.n_retries, cmd_number_inf },
|
||||
#endif
|
||||
{ "retrsymlinks", &opt.retr_symlinks, cmd_boolean },
|
||||
{ "retryconnrefused", &opt.retry_connrefused, cmd_boolean },
|
||||
{ "robots", &opt.use_robots, cmd_boolean },
|
||||
@@ -276,7 +278,7 @@ static const struct {
|
||||
#endif
|
||||
{ "serverresponse", &opt.server_response, cmd_boolean },
|
||||
{ "showalldnsentries", &opt.show_all_dns_entries, cmd_boolean },
|
||||
{ "showprogress", &opt.show_progress, cmd_spec_progressdisp },
|
||||
{ "showprogress", &opt.show_progress, cmd_boolean },
|
||||
{ "spanhosts", &opt.spanhost, cmd_boolean },
|
||||
{ "spider", &opt.spider, cmd_boolean },
|
||||
{ "startpos", &opt.start_pos, cmd_bytes },
|
||||
@@ -322,7 +324,7 @@ command_by_name (const char *cmdname)
|
||||
while (lo <= hi)
|
||||
{
|
||||
int mid = (lo + hi) >> 1;
|
||||
int cmp = c_strcasecmp (cmdname, commands[mid].name);
|
||||
int cmp = strcasecmp (cmdname, commands[mid].name);
|
||||
if (cmp < 0)
|
||||
hi = mid - 1;
|
||||
else if (cmp > 0)
|
||||
@@ -332,7 +334,7 @@ command_by_name (const char *cmdname)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Reset the variables to default values. */
|
||||
void
|
||||
defaults (void)
|
||||
@@ -349,6 +351,12 @@ defaults (void)
|
||||
opt.cookies = true;
|
||||
opt.verbose = -1;
|
||||
opt.ntry = 20;
|
||||
#ifdef ENABLE_THREADS
|
||||
opt.jobs = 1;
|
||||
#endif
|
||||
#ifdef ENABLE_METALINK
|
||||
opt.n_retries = 1;
|
||||
#endif
|
||||
opt.reclevel = 5;
|
||||
opt.add_hostdir = true;
|
||||
opt.netrc = true;
|
||||
@@ -373,22 +381,6 @@ 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;
|
||||
@@ -435,10 +427,10 @@ defaults (void)
|
||||
|
||||
/* Use a negative value to mark the absence of --start-pos option */
|
||||
opt.start_pos = -1;
|
||||
opt.show_progress = -1;
|
||||
opt.show_progress = false;
|
||||
opt.noscroll = false;
|
||||
}
|
||||
|
||||
|
||||
/* Return the user's home directory (strdup-ed), or NULL if none is
|
||||
found. */
|
||||
char *
|
||||
@@ -487,7 +479,7 @@ home_dir (void)
|
||||
}
|
||||
|
||||
ret = home ? xstrdup (home) : NULL;
|
||||
xfree (buf);
|
||||
free (buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -528,7 +520,7 @@ wgetrc_user_file_name (void)
|
||||
home = home_dir ();
|
||||
if (home)
|
||||
file = aprintf ("%s/.wgetrc", home);
|
||||
xfree (home);
|
||||
xfree_null (home);
|
||||
#endif /* def __VMS [else] */
|
||||
|
||||
if (!file)
|
||||
@@ -563,7 +555,8 @@ wgetrc_file_name (void)
|
||||
if (!file)
|
||||
{
|
||||
char *home = home_dir ();
|
||||
xfree (file);
|
||||
xfree_null (file);
|
||||
file = NULL;
|
||||
home = ws_mypath ();
|
||||
if (home)
|
||||
{
|
||||
@@ -571,6 +564,7 @@ wgetrc_file_name (void)
|
||||
if (!file_exists_p (file))
|
||||
{
|
||||
xfree (file);
|
||||
file = NULL;
|
||||
}
|
||||
xfree (home);
|
||||
}
|
||||
@@ -644,8 +638,8 @@ run_wgetrc (const char *file)
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
xfree (com);
|
||||
xfree (val);
|
||||
xfree_null (com);
|
||||
xfree_null (val);
|
||||
++ln;
|
||||
}
|
||||
xfree (line);
|
||||
@@ -898,7 +892,7 @@ run_command (const char *cmdopt)
|
||||
exit (WGET_EXIT_PARSE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Generic helper functions, for use with `commands'. */
|
||||
|
||||
/* Forward declarations: */
|
||||
@@ -966,7 +960,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 (!c_strcasecmp (val, "inf"))
|
||||
if (!strcasecmp (val, "inf"))
|
||||
{
|
||||
*(int *) place = 0;
|
||||
return true;
|
||||
@@ -981,7 +975,7 @@ cmd_string (const char *com _GL_UNUSED, const char *val, void *place)
|
||||
{
|
||||
char **pstring = (char **)place;
|
||||
|
||||
xfree (*pstring);
|
||||
xfree_null (*pstring);
|
||||
*pstring = xstrdup (val);
|
||||
return true;
|
||||
}
|
||||
@@ -992,7 +986,7 @@ cmd_string_uppercase (const char *com _GL_UNUSED, const char *val, void *place)
|
||||
{
|
||||
char *q, **pstring;
|
||||
pstring = (char **)place;
|
||||
xfree (*pstring);
|
||||
xfree_null (*pstring);
|
||||
|
||||
*pstring = xmalloc (strlen (val) + 1);
|
||||
|
||||
@@ -1012,7 +1006,7 @@ cmd_file (const char *com _GL_UNUSED, const char *val, void *place)
|
||||
{
|
||||
char **pstring = (char **)place;
|
||||
|
||||
xfree (*pstring);
|
||||
xfree_null (*pstring);
|
||||
|
||||
/* #### If VAL is empty, perhaps should set *PLACE to NULL. */
|
||||
|
||||
@@ -1030,20 +1024,6 @@ 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)
|
||||
@@ -1293,7 +1273,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. */
|
||||
|
||||
@@ -1417,7 +1397,7 @@ cmd_spec_progress (const char *com, const char *val, void *place_ignored _GL_UNU
|
||||
exec_name, com, quote (val));
|
||||
return false;
|
||||
}
|
||||
xfree (opt.progress_type);
|
||||
xfree_null (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. */
|
||||
@@ -1518,7 +1498,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 = c_strcasecmp (val, "bits") == 0;
|
||||
opt.report_bps = 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;
|
||||
@@ -1533,8 +1513,6 @@ 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);
|
||||
@@ -1568,27 +1546,11 @@ cmd_spec_useragent (const char *com, const char *val, void *place_ignored _GL_UN
|
||||
exec_name, com, quote (val));
|
||||
return false;
|
||||
}
|
||||
xfree (opt.useragent);
|
||||
xfree_null (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). */
|
||||
@@ -1600,12 +1562,11 @@ 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
|
||||
@@ -1740,7 +1701,7 @@ decode_string (const char *val, const struct decode_item *items, int itemcount,
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < itemcount; i++)
|
||||
if (0 == c_strcasecmp (val, items[i].name))
|
||||
if (0 == strcasecmp (val, items[i].name))
|
||||
{
|
||||
*place = items[i].code;
|
||||
return true;
|
||||
@@ -1783,57 +1744,55 @@ cleanup (void)
|
||||
spider_cleanup ();
|
||||
host_cleanup ();
|
||||
log_cleanup ();
|
||||
netrc_cleanup ();
|
||||
netrc_cleanup (netrc_list);
|
||||
|
||||
xfree (opt.choose_config);
|
||||
xfree (opt.lfilename);
|
||||
xfree (opt.dir_prefix);
|
||||
xfree (opt.input_filename);
|
||||
xfree (opt.output_document);
|
||||
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);
|
||||
free_vec (opt.accepts);
|
||||
free_vec (opt.rejects);
|
||||
free_vec ((char **)opt.excludes);
|
||||
free_vec ((char **)opt.includes);
|
||||
free_vec (opt.excludes);
|
||||
free_vec (opt.includes);
|
||||
free_vec (opt.domains);
|
||||
free_vec (opt.follow_tags);
|
||||
free_vec (opt.ignore_tags);
|
||||
xfree (opt.progress_type);
|
||||
xfree (opt.ftp_user);
|
||||
xfree (opt.ftp_passwd);
|
||||
xfree (opt.ftp_proxy);
|
||||
xfree (opt.https_proxy);
|
||||
xfree (opt.http_proxy);
|
||||
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);
|
||||
free_vec (opt.no_proxy);
|
||||
xfree (opt.useragent);
|
||||
xfree (opt.referer);
|
||||
xfree (opt.http_user);
|
||||
xfree (opt.http_passwd);
|
||||
xfree_null (opt.useragent);
|
||||
xfree_null (opt.referer);
|
||||
xfree_null (opt.http_user);
|
||||
xfree_null (opt.http_passwd);
|
||||
free_vec (opt.user_headers);
|
||||
free_vec (opt.warc_user_headers);
|
||||
# ifdef HAVE_SSL
|
||||
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);
|
||||
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);
|
||||
# endif
|
||||
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_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);
|
||||
|
||||
#endif /* DEBUG_MALLOC */
|
||||
}
|
||||
|
||||
|
||||
/* Unit testing routines. */
|
||||
|
||||
#ifdef TESTING
|
||||
@@ -1845,7 +1804,7 @@ test_commands_sorted(void)
|
||||
|
||||
for (i = 1; i < countof(commands); ++i)
|
||||
{
|
||||
if (c_strcasecmp (commands[i - 1].name, commands[i].name) > 0)
|
||||
if (strcasecmp (commands[i - 1].name, commands[i].name) > 0)
|
||||
{
|
||||
mu_assert ("FAILED", false);
|
||||
break;
|
||||
@@ -1861,7 +1820,7 @@ test_cmd_spec_restrict_file_names(void)
|
||||
static const struct {
|
||||
const char *val;
|
||||
int expected_restrict_files_os;
|
||||
bool expected_restrict_files_ctrl;
|
||||
int expected_restrict_files_ctrl;
|
||||
int expected_restrict_files_case;
|
||||
bool result;
|
||||
} test_array[] = {
|
||||
@@ -1886,9 +1845,9 @@ test_cmd_spec_restrict_file_names(void)
|
||||
*/
|
||||
mu_assert ("test_cmd_spec_restrict_file_names: wrong result",
|
||||
res == test_array[i].result
|
||||
&& (int) opt.restrict_files_os == test_array[i].expected_restrict_files_os
|
||||
&& opt.restrict_files_os == test_array[i].expected_restrict_files_os
|
||||
&& opt.restrict_files_ctrl == test_array[i].expected_restrict_files_ctrl
|
||||
&& (int) opt.restrict_files_case == test_array[i].expected_restrict_files_case);
|
||||
&& opt.restrict_files_case == test_array[i].expected_restrict_files_case);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
134
src/iri.c
134
src/iri.c
@@ -35,20 +35,18 @@ as that of the covered work. */
|
||||
#include <iconv.h>
|
||||
#include <stringprep.h>
|
||||
#include <idna.h>
|
||||
#include <idn-free.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "url.h"
|
||||
#include "c-strcase.h"
|
||||
#include "c-strcasestr.h"
|
||||
#include "xstrndup.h"
|
||||
|
||||
/* RFC3987 section 3.1 mandates STD3 ASCII RULES */
|
||||
#define IDNA_FLAGS IDNA_USE_STD3_ASCII_RULES
|
||||
|
||||
/* Note: locale encoding is kept in options struct (opt.locale) */
|
||||
|
||||
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 *
|
||||
@@ -59,7 +57,7 @@ parse_charset (char *str)
|
||||
if (!str || !*str)
|
||||
return NULL;
|
||||
|
||||
str = c_strcasestr (str, "charset=");
|
||||
str = strcasestr (str, "charset=");
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
@@ -112,35 +110,52 @@ 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 (const char *tocode, const char *fromcode, char *in, size_t inlen, char **out)
|
||||
do_conversion (iconv_t cd, char *in, size_t inlen, char **out)
|
||||
{
|
||||
iconv_t cd;
|
||||
/* sXXXav : hummm hard to guess... */
|
||||
size_t len, done, outlen;
|
||||
size_t len, done, outlen = inlen * 2;
|
||||
int invalid = 0, tooshort = 0;
|
||||
char *s, *in_org, *in_save;
|
||||
char *s;
|
||||
|
||||
cd = iconv_open (tocode, fromcode);
|
||||
if (cd == (iconv_t)(-1))
|
||||
{
|
||||
logprintf (LOG_VERBOSE, _("Conversion from %s to UTF-8 isn't supported\n"),
|
||||
quote (opt.locale));
|
||||
*out = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* iconv() has to work on an unescaped string */
|
||||
in_org = in;
|
||||
in_save = in = xstrndup(in, inlen);
|
||||
url_unescape(in);
|
||||
inlen = strlen(in);
|
||||
|
||||
len = outlen = inlen * 2;
|
||||
*out = s = xmalloc (outlen + 1);
|
||||
s = xmalloc (outlen + 1);
|
||||
*out = s;
|
||||
len = outlen;
|
||||
done = 0;
|
||||
|
||||
for (;;)
|
||||
@@ -149,9 +164,6 @@ do_conversion (const char *tocode, const char *fromcode, char *in, size_t inlen,
|
||||
{
|
||||
*out = s;
|
||||
*(s + len - outlen - done) = '\0';
|
||||
xfree(in_save);
|
||||
iconv_close(cd);
|
||||
DEBUGP (("converted '%s' (%s) -> '%s' (%s)\n", in_org, fromcode, *out, tocode));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -190,35 +202,9 @@ do_conversion (const char *tocode, const char *fromcode, char *in, size_t inlen,
|
||||
}
|
||||
}
|
||||
|
||||
xfree(in_save);
|
||||
iconv_close(cd);
|
||||
DEBUGP (("converted '%s' (%s) -> '%s' (%s)\n", in_org, fromcode, *out, tocode));
|
||||
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;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Try to "ASCII encode" UTF-8 host. Return the new domain on success or NULL
|
||||
on error. */
|
||||
char *
|
||||
@@ -272,6 +258,7 @@ idn_decode (char *host)
|
||||
bool
|
||||
remote_to_utf8 (struct iri *iri, const char *str, const char **new)
|
||||
{
|
||||
iconv_t cd;
|
||||
bool ret = false;
|
||||
|
||||
if (!iri->uri_encoding)
|
||||
@@ -280,11 +267,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 (!c_strcasecmp (iri->uri_encoding, "UTF-8"))
|
||||
if (!strcmp (iri->uri_encoding, "UTF-8"))
|
||||
{
|
||||
const unsigned char *p;
|
||||
for (p = (unsigned char *) str; *p; p++)
|
||||
if (*p > 127)
|
||||
const char *p = str;
|
||||
for (p = str; *p; p++)
|
||||
if (*p < 0)
|
||||
{
|
||||
*new = strdup (str);
|
||||
return true;
|
||||
@@ -292,13 +279,19 @@ remote_to_utf8 (struct iri *iri, const char *str, const char **new)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (do_conversion ("UTF-8", iri->uri_encoding, (char *) str, strlen (str), (char **) new))
|
||||
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))
|
||||
ret = true;
|
||||
|
||||
iconv_close (cd);
|
||||
|
||||
/* Test if something was converted */
|
||||
if (*new && !strcmp (str, *new))
|
||||
if (!strcmp (str, *new))
|
||||
{
|
||||
xfree (*new);
|
||||
xfree ((char *) *new);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -332,13 +325,10 @@ struct iri *iri_dup (const struct iri *src)
|
||||
void
|
||||
iri_free (struct iri *i)
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
xfree (i->uri_encoding);
|
||||
xfree (i->content_encoding);
|
||||
xfree (i->orig_url);
|
||||
xfree (i);
|
||||
}
|
||||
xfree_null (i->uri_encoding);
|
||||
xfree_null (i->content_encoding);
|
||||
xfree_null (i->orig_url);
|
||||
xfree (i);
|
||||
}
|
||||
|
||||
/* Set uri_encoding of struct iri i. If a remote encoding was specified, use
|
||||
@@ -351,7 +341,7 @@ set_uri_encoding (struct iri *i, char *charset, bool force)
|
||||
return;
|
||||
if (i->uri_encoding)
|
||||
{
|
||||
if (charset && !c_strcasecmp (i->uri_encoding, charset))
|
||||
if (charset && !strcasecmp (i->uri_encoding, charset))
|
||||
return;
|
||||
xfree (i->uri_encoding);
|
||||
}
|
||||
@@ -368,7 +358,7 @@ set_content_encoding (struct iri *i, char *charset)
|
||||
return;
|
||||
if (i->content_encoding)
|
||||
{
|
||||
if (charset && !c_strcasecmp (i->content_encoding, charset))
|
||||
if (charset && !strcasecmp (i->content_encoding, charset))
|
||||
return;
|
||||
xfree (i->content_encoding);
|
||||
}
|
||||
|
||||
@@ -39,9 +39,6 @@ struct iri {
|
||||
|
||||
#ifdef ENABLE_IRI
|
||||
|
||||
# include <idna.h>
|
||||
# include <idn-free.h>
|
||||
|
||||
char *parse_charset (char *str);
|
||||
char *find_locale (void);
|
||||
bool check_encoding_name (char *encoding);
|
||||
@@ -65,7 +62,6 @@ extern struct iri dummy_iri;
|
||||
#define locale_to_utf8(str) (str)
|
||||
#define idn_encode(a,b) NULL
|
||||
#define idn_decode(str) NULL
|
||||
#define idn_free(str) ((void)0)
|
||||
#define remote_to_utf8(a,b,c) false
|
||||
#define iri_new() (&dummy_iri)
|
||||
#define iri_dup(a) (&dummy_iri)
|
||||
|
||||
44
src/log.c
44
src/log.c
@@ -73,7 +73,7 @@ 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
|
||||
@@ -142,7 +142,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,7 +156,11 @@ static void
|
||||
free_log_line (int num)
|
||||
{
|
||||
struct log_ln *ln = log_lines + num;
|
||||
xfree (ln->malloced_line);
|
||||
if (ln->malloced_line)
|
||||
{
|
||||
xfree (ln->malloced_line);
|
||||
ln->malloced_line = NULL;
|
||||
}
|
||||
ln->content = NULL;
|
||||
}
|
||||
|
||||
@@ -261,7 +265,7 @@ saved_append (const char *s)
|
||||
s = end;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check X against opt.verbose and opt.quiet. The semantics is as
|
||||
follows:
|
||||
|
||||
@@ -310,14 +314,6 @@ 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
|
||||
@@ -342,7 +338,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. */
|
||||
|
||||
@@ -353,14 +349,8 @@ logputs (enum log_options o, const char *s)
|
||||
FILE *warcfp;
|
||||
|
||||
check_redirect_output ();
|
||||
if (o == LOG_PROGRESS)
|
||||
fp = get_progress_fp ();
|
||||
else
|
||||
fp = get_log_fp ();
|
||||
|
||||
if (fp == NULL)
|
||||
if ((fp = get_log_fp ()) == NULL)
|
||||
return;
|
||||
|
||||
warcfp = get_warc_log_fp ();
|
||||
CHECK_VERBOSE (o);
|
||||
|
||||
@@ -395,7 +385,7 @@ struct logvprintf_state {
|
||||
(An alternative approach would be to use va_copy, but that's not
|
||||
portable.) */
|
||||
|
||||
static bool GCC_FORMAT_ATTR (2, 0)
|
||||
static bool
|
||||
log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
|
||||
va_list args)
|
||||
{
|
||||
@@ -461,7 +451,8 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
|
||||
FPUTS (write_ptr, fp);
|
||||
if (warcfp != NULL)
|
||||
FPUTS (write_ptr, warcfp);
|
||||
xfree (state->bigmsg);
|
||||
if (state->bigmsg)
|
||||
xfree (state->bigmsg);
|
||||
|
||||
flush:
|
||||
if (flush_log_p)
|
||||
@@ -550,7 +541,6 @@ logprintf (enum log_options o, const char *fmt, ...)
|
||||
CHECK_VERBOSE (o);
|
||||
|
||||
xzero (lpstate);
|
||||
errno = 0;
|
||||
do
|
||||
{
|
||||
va_start (args, fmt);
|
||||
@@ -590,7 +580,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
|
||||
@@ -685,7 +675,7 @@ log_dump_context (void)
|
||||
fflush (fp);
|
||||
fflush (warcfp);
|
||||
}
|
||||
|
||||
|
||||
/* String escape functions. */
|
||||
|
||||
/* Return the number of non-printable characters in SOURCE.
|
||||
@@ -857,9 +847,9 @@ log_cleanup (void)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < countof (ring); i++)
|
||||
xfree (ring[i].buffer);
|
||||
xfree_null (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;
|
||||
|
||||
597
src/main.c
597
src/main.c
@@ -54,9 +54,6 @@ as that of the covered work. */
|
||||
#include "http.h" /* for save_cookies */
|
||||
#include "ptimer.h"
|
||||
#include "warc.h"
|
||||
#include "version.h"
|
||||
#include "c-strcase.h"
|
||||
#include "dirname.h"
|
||||
#include <getopt.h>
|
||||
#include <getpass.h>
|
||||
#include <quote.h>
|
||||
@@ -81,46 +78,30 @@ struct iri dummy_iri;
|
||||
struct options opt;
|
||||
|
||||
/* defined in version.c */
|
||||
extern char *version_string;
|
||||
extern char *compilation_string;
|
||||
extern char *system_getrc;
|
||||
extern char *link_string;
|
||||
/* defined in build_info.c */
|
||||
extern const char *compiled_features[];
|
||||
/* Used for --version output in print_version */
|
||||
#define MAX_CHARS_PER_LINE 72
|
||||
#define TABULATION 4
|
||||
|
||||
#if defined(SIGHUP) || defined(SIGUSR1)
|
||||
static void redirect_output_signal (int);
|
||||
#endif
|
||||
|
||||
const char *exec_name;
|
||||
|
||||
/* Number of successfully downloaded URLs */
|
||||
int numurls = 0;
|
||||
|
||||
|
||||
#ifndef TESTING
|
||||
/* Initialize I18N/L10N. That amounts to invoking setlocale, and
|
||||
setting up gettext's message catalog using bindtextdomain and
|
||||
textdomain. Does nothing if NLS is disabled or missing. */
|
||||
|
||||
#if defined(SIGHUP) || defined(SIGUSR1)
|
||||
/* Hangup signal handler. When wget receives SIGHUP or SIGUSR1, it
|
||||
will proceed operation as usual, trying to write into a log file.
|
||||
If that is impossible, the output will be turned off. */
|
||||
|
||||
static void
|
||||
redirect_output_signal (int sig)
|
||||
{
|
||||
const char *signal_name = "WTF?!";
|
||||
|
||||
#ifdef SIGHUP
|
||||
if (sig == SIGHUP)
|
||||
signal_name = "SIGHUP";
|
||||
#endif
|
||||
#ifdef SIGUSR1
|
||||
if (sig == SIGUSR1)
|
||||
signal_name = "SIGUSR1";
|
||||
#endif
|
||||
|
||||
log_request_redirect_output (signal_name);
|
||||
progress_schedule_redirect ();
|
||||
signal (sig, redirect_output_signal);
|
||||
}
|
||||
#endif /* defined(SIGHUP) || defined(SIGUSR1) */
|
||||
|
||||
static void
|
||||
i18n_initialize (void)
|
||||
{
|
||||
@@ -133,11 +114,11 @@ i18n_initialize (void)
|
||||
textdomain ("wget");
|
||||
#endif /* ENABLE_NLS */
|
||||
}
|
||||
|
||||
|
||||
/* Definition of command-line options. */
|
||||
|
||||
static void _Noreturn print_help (void);
|
||||
static void _Noreturn print_version (void);
|
||||
static void print_help (void);
|
||||
static void print_version (void);
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
# define IF_SSL(x) x
|
||||
@@ -194,7 +175,6 @@ static struct cmdline_option option_data[] =
|
||||
{ "content-disposition", 0, OPT_BOOLEAN, "contentdisposition", -1 },
|
||||
{ "content-on-error", 0, OPT_BOOLEAN, "contentonerror", -1 },
|
||||
{ "cookies", 0, OPT_BOOLEAN, "cookies", -1 },
|
||||
{ IF_SSL ("crl-file"), 0, OPT_VALUE, "crlfile", -1 },
|
||||
{ "cut-dirs", 0, OPT_VALUE, "cutdirs", -1 },
|
||||
{ "debug", 'd', OPT_BOOLEAN, "debug", -1 },
|
||||
{ "default-page", 0, OPT_VALUE, "defaultpage", -1 },
|
||||
@@ -240,12 +220,18 @@ static struct cmdline_option option_data[] =
|
||||
#endif
|
||||
{ "input-file", 'i', OPT_VALUE, "input", -1 },
|
||||
{ "iri", 0, OPT_BOOLEAN, "iri", -1 },
|
||||
#ifdef ENABLE_THREADS
|
||||
{ "jobs", 0, OPT_VALUE, "jobs", 1 },
|
||||
#endif
|
||||
{ "keep-session-cookies", 0, OPT_BOOLEAN, "keepsessioncookies", -1 },
|
||||
{ "level", 'l', OPT_VALUE, "reclevel", -1 },
|
||||
{ "limit-rate", 0, OPT_VALUE, "limitrate", -1 },
|
||||
{ "load-cookies", 0, OPT_VALUE, "loadcookies", -1 },
|
||||
{ "local-encoding", 0, OPT_VALUE, "localencoding", -1 },
|
||||
{ "max-redirect", 0, OPT_VALUE, "maxredirect", -1 },
|
||||
#ifdef ENABLE_METALINK
|
||||
{ "metalink-file", 0, OPT_VALUE, "metalink", -1 },
|
||||
#endif
|
||||
{ "method", 0, OPT_VALUE, "method", -1 },
|
||||
{ "mirror", 'm', OPT_BOOLEAN, "mirror", -1 },
|
||||
{ "no", 'n', OPT__NO, NULL, required_argument },
|
||||
@@ -288,6 +274,9 @@ static struct cmdline_option option_data[] =
|
||||
{ "report-speed", 0, OPT_BOOLEAN, "reportspeed", -1 },
|
||||
{ "restrict-file-names", 0, OPT_BOOLEAN, "restrictfilenames", -1 },
|
||||
{ "retr-symlinks", 0, OPT_BOOLEAN, "retrsymlinks", -1 },
|
||||
#ifdef ENABLE_METALINK
|
||||
{ "retries", 0, OPT_VALUE, "retries", -1 },
|
||||
#endif
|
||||
{ "retry-connrefused", 0, OPT_BOOLEAN, "retryconnrefused", -1 },
|
||||
{ "save-cookies", 0, OPT_VALUE, "savecookies", -1 },
|
||||
{ "save-headers", 0, OPT_BOOLEAN, "saveheaders", -1 },
|
||||
@@ -340,7 +329,8 @@ no_prefix (const char *s)
|
||||
|
||||
char *cp = p;
|
||||
int size = 3 + strlen (s) + 1; /* "no-STRING\0" */
|
||||
assert(p + size <= buffer + sizeof (buffer));
|
||||
if (p + size >= buffer + sizeof (buffer))
|
||||
abort ();
|
||||
|
||||
cp[0] = 'n', cp[1] = 'o', cp[2] = '-';
|
||||
strcpy (cp + 3, s);
|
||||
@@ -447,206 +437,219 @@ Mandatory arguments to long options are mandatory for short options too.\n\n"),
|
||||
N_("\
|
||||
Startup:\n"),
|
||||
N_("\
|
||||
-V, --version display the version of Wget and exit\n"),
|
||||
-V, --version display the version of Wget and exit.\n"),
|
||||
N_("\
|
||||
-h, --help print this help\n"),
|
||||
-h, --help print this help.\n"),
|
||||
N_("\
|
||||
-b, --background go to background after startup\n"),
|
||||
-b, --background go to background after startup.\n"),
|
||||
N_("\
|
||||
-e, --execute=COMMAND execute a `.wgetrc'-style command\n"),
|
||||
-e, --execute=COMMAND execute a `.wgetrc'-style command.\n"),
|
||||
"\n",
|
||||
|
||||
N_("\
|
||||
Logging and input file:\n"),
|
||||
N_("\
|
||||
-o, --output-file=FILE log messages to FILE\n"),
|
||||
-o, --output-file=FILE log messages to FILE.\n"),
|
||||
N_("\
|
||||
-a, --append-output=FILE append messages to FILE\n"),
|
||||
-a, --append-output=FILE append messages to FILE.\n"),
|
||||
#ifdef ENABLE_DEBUG
|
||||
N_("\
|
||||
-d, --debug print lots of debugging information\n"),
|
||||
-d, --debug print lots of debugging information.\n"),
|
||||
#endif
|
||||
#ifdef USE_WATT32
|
||||
N_("\
|
||||
--wdebug print Watt-32 debug output\n"),
|
||||
--wdebug print Watt-32 debug output.\n"),
|
||||
#endif
|
||||
N_("\
|
||||
-q, --quiet quiet (no output)\n"),
|
||||
-q, --quiet quiet (no output).\n"),
|
||||
N_("\
|
||||
-v, --verbose be verbose (this is the default)\n"),
|
||||
-v, --verbose be verbose (this is the default).\n"),
|
||||
N_("\
|
||||
-nv, --no-verbose turn off verboseness, without being quiet\n"),
|
||||
-nv, --no-verbose turn off verboseness, without being quiet.\n"),
|
||||
N_("\
|
||||
--report-speed=TYPE output bandwidth as TYPE. TYPE can be bits\n"),
|
||||
--report-speed=TYPE Output bandwidth as TYPE. TYPE can be bits.\n"),
|
||||
N_("\
|
||||
-i, --input-file=FILE download URLs found in local or external FILE\n"),
|
||||
-i, --input-file=FILE download URLs found in local or external FILE.\n"),
|
||||
N_("\
|
||||
-F, --force-html treat input file as HTML\n"),
|
||||
-F, --force-html treat input file as HTML.\n"),
|
||||
N_("\
|
||||
-B, --base=URL resolves HTML input-file links (-i -F)\n\
|
||||
relative to URL\n"),
|
||||
relative to URL.\n"),
|
||||
N_("\
|
||||
--config=FILE specify config file to use\n"),
|
||||
--config=FILE Specify config file to use.\n"),
|
||||
N_("\
|
||||
--no-config do not read any config file\n"),
|
||||
--no-config Do not read any config file.\n"),
|
||||
"\n",
|
||||
|
||||
#ifdef ENABLE_METALINK
|
||||
N_("\
|
||||
--metalink-file download URLs found in local or external metalink FILE.\n"),
|
||||
#endif
|
||||
|
||||
N_("\
|
||||
Download:\n"),
|
||||
#ifdef ENABLE_METALINK
|
||||
N_("\
|
||||
-t, --tries=NUMBER set number of retries to NUMBER (0 unlimits)\n"),
|
||||
N_("\
|
||||
--retry-connrefused retry even if connection is refused\n"),
|
||||
N_("\
|
||||
-O, --output-document=FILE write documents to FILE\n"),
|
||||
N_("\
|
||||
-nc, --no-clobber skip downloads that would download to\n\
|
||||
existing files (overwriting them)\n"),
|
||||
N_("\
|
||||
-c, --continue resume getting a partially-downloaded file\n"),
|
||||
N_("\
|
||||
--start-pos=OFFSET start downloading from zero-based position OFFSET\n"),
|
||||
N_("\
|
||||
--progress=TYPE select progress gauge type\n"),
|
||||
N_("\
|
||||
--show-progress display the progress bar in any verbosity mode\n"),
|
||||
N_("\
|
||||
-N, --timestamping don't re-retrieve files unless newer than\n\
|
||||
local\n"),
|
||||
N_("\
|
||||
--no-use-server-timestamps don't set the local file's timestamp by\n\
|
||||
the one on the server\n"),
|
||||
N_("\
|
||||
-S, --server-response print server response\n"),
|
||||
N_("\
|
||||
--spider don't download anything\n"),
|
||||
N_("\
|
||||
-T, --timeout=SECONDS set all timeout values to SECONDS\n"),
|
||||
N_("\
|
||||
--dns-timeout=SECS set the DNS lookup timeout to SECS\n"),
|
||||
N_("\
|
||||
--connect-timeout=SECS set the connect timeout to SECS\n"),
|
||||
N_("\
|
||||
--read-timeout=SECS set the read timeout to SECS\n"),
|
||||
N_("\
|
||||
-w, --wait=SECONDS wait SECONDS between retrievals\n"),
|
||||
N_("\
|
||||
--waitretry=SECONDS wait 1..SECONDS between retries of a retrieval\n"),
|
||||
N_("\
|
||||
--random-wait wait from 0.5*WAIT...1.5*WAIT secs between retrievals\n"),
|
||||
N_("\
|
||||
--no-proxy explicitly turn off proxy\n"),
|
||||
N_("\
|
||||
-Q, --quota=NUMBER set retrieval quota to NUMBER\n"),
|
||||
N_("\
|
||||
--bind-address=ADDRESS bind to ADDRESS (hostname or IP) on local host\n"),
|
||||
N_("\
|
||||
--limit-rate=RATE limit download rate to RATE\n"),
|
||||
N_("\
|
||||
--no-dns-cache disable caching DNS lookups\n"),
|
||||
N_("\
|
||||
--restrict-file-names=OS restrict chars in file names to ones OS allows\n"),
|
||||
N_("\
|
||||
--ignore-case ignore case when matching files/directories\n"),
|
||||
#ifdef ENABLE_IPV6
|
||||
N_("\
|
||||
-4, --inet4-only connect only to IPv4 addresses\n"),
|
||||
N_("\
|
||||
-6, --inet6-only connect only to IPv6 addresses\n"),
|
||||
N_("\
|
||||
--prefer-family=FAMILY connect first to addresses of specified family,\n\
|
||||
one of IPv6, IPv4, or none\n"),
|
||||
--retries specify the number of retries for a file.\n\
|
||||
(needs to be used with --metalink-file)\n"),
|
||||
#endif
|
||||
N_("\
|
||||
--user=USER set both ftp and http user to USER\n"),
|
||||
-t, --tries=NUMBER set number of retries to NUMBER (0 unlimits).\n"),
|
||||
N_("\
|
||||
--password=PASS set both ftp and http password to PASS\n"),
|
||||
--retry-connrefused retry even if connection is refused.\n"),
|
||||
N_("\
|
||||
--ask-password prompt for passwords\n"),
|
||||
-O, --output-document=FILE write documents to FILE.\n"),
|
||||
N_("\
|
||||
--no-iri turn off IRI support\n"),
|
||||
-nc, --no-clobber skip downloads that would download to\n\
|
||||
existing files (overwriting them).\n"),
|
||||
N_("\
|
||||
--local-encoding=ENC use ENC as the local encoding for IRIs\n"),
|
||||
-c, --continue resume getting a partially-downloaded file.\n"),
|
||||
N_("\
|
||||
--remote-encoding=ENC use ENC as the default remote encoding\n"),
|
||||
--start-pos=OFFSET start downloading from zero-based position OFFSET.\n"),
|
||||
N_("\
|
||||
--unlink remove file before clobber\n"),
|
||||
--progress=TYPE select progress gauge type.\n"),
|
||||
N_("\
|
||||
--show-progress display the progress bar in any verbosity mode.\n"),
|
||||
N_("\
|
||||
-N, --timestamping don't re-retrieve files unless newer than\n\
|
||||
local.\n"),
|
||||
N_("\
|
||||
--no-use-server-timestamps don't set the local file's timestamp by\n\
|
||||
the one on the server.\n"),
|
||||
N_("\
|
||||
-S, --server-response print server response.\n"),
|
||||
N_("\
|
||||
--spider don't download anything.\n"),
|
||||
N_("\
|
||||
-T, --timeout=SECONDS set all timeout values to SECONDS.\n"),
|
||||
N_("\
|
||||
--dns-timeout=SECS set the DNS lookup timeout to SECS.\n"),
|
||||
N_("\
|
||||
--connect-timeout=SECS set the connect timeout to SECS.\n"),
|
||||
N_("\
|
||||
--read-timeout=SECS set the read timeout to SECS.\n"),
|
||||
N_("\
|
||||
-w, --wait=SECONDS wait SECONDS between retrievals.\n"),
|
||||
N_("\
|
||||
--waitretry=SECONDS wait 1..SECONDS between retries of a retrieval.\n"),
|
||||
N_("\
|
||||
--random-wait wait from 0.5*WAIT...1.5*WAIT secs between retrievals.\n"),
|
||||
N_("\
|
||||
--no-proxy explicitly turn off proxy.\n"),
|
||||
N_("\
|
||||
-Q, --quota=NUMBER set retrieval quota to NUMBER.\n"),
|
||||
N_("\
|
||||
--bind-address=ADDRESS bind to ADDRESS (hostname or IP) on local host.\n"),
|
||||
N_("\
|
||||
--limit-rate=RATE limit download rate to RATE.\n"),
|
||||
N_("\
|
||||
--no-dns-cache disable caching DNS lookups.\n"),
|
||||
N_("\
|
||||
--restrict-file-names=OS restrict chars in file names to ones OS allows.\n"),
|
||||
N_("\
|
||||
--ignore-case ignore case when matching files/directories.\n"),
|
||||
#ifdef ENABLE_IPV6
|
||||
N_("\
|
||||
-4, --inet4-only connect only to IPv4 addresses.\n"),
|
||||
N_("\
|
||||
-6, --inet6-only connect only to IPv6 addresses.\n"),
|
||||
N_("\
|
||||
--prefer-family=FAMILY connect first to addresses of specified family,\n\
|
||||
one of IPv6, IPv4, or none.\n"),
|
||||
#endif
|
||||
N_("\
|
||||
--user=USER set both ftp and http user to USER.\n"),
|
||||
N_("\
|
||||
--password=PASS set both ftp and http password to PASS.\n"),
|
||||
N_("\
|
||||
--ask-password prompt for passwords.\n"),
|
||||
N_("\
|
||||
--no-iri turn off IRI support.\n"),
|
||||
N_("\
|
||||
--local-encoding=ENC use ENC as the local encoding for IRIs.\n"),
|
||||
N_("\
|
||||
--remote-encoding=ENC use ENC as the default remote encoding.\n"),
|
||||
N_("\
|
||||
--unlink remove file before clobber.\n"),
|
||||
#ifdef ENABLE_THREADS
|
||||
N_("\
|
||||
--jobs specify how many threads use.\n"),
|
||||
#endif
|
||||
"\n",
|
||||
|
||||
N_("\
|
||||
Directories:\n"),
|
||||
N_("\
|
||||
-nd, --no-directories don't create directories\n"),
|
||||
-nd, --no-directories don't create directories.\n"),
|
||||
N_("\
|
||||
-x, --force-directories force creation of directories\n"),
|
||||
-x, --force-directories force creation of directories.\n"),
|
||||
N_("\
|
||||
-nH, --no-host-directories don't create host directories\n"),
|
||||
-nH, --no-host-directories don't create host directories.\n"),
|
||||
N_("\
|
||||
--protocol-directories use protocol name in directories\n"),
|
||||
--protocol-directories use protocol name in directories.\n"),
|
||||
N_("\
|
||||
-P, --directory-prefix=PREFIX save files to PREFIX/..\n"),
|
||||
-P, --directory-prefix=PREFIX save files to PREFIX/...\n"),
|
||||
N_("\
|
||||
--cut-dirs=NUMBER ignore NUMBER remote directory components\n"),
|
||||
--cut-dirs=NUMBER ignore NUMBER remote directory components.\n"),
|
||||
"\n",
|
||||
|
||||
N_("\
|
||||
HTTP options:\n"),
|
||||
N_("\
|
||||
--http-user=USER set http user to USER\n"),
|
||||
--http-user=USER set http user to USER.\n"),
|
||||
N_("\
|
||||
--http-password=PASS set http password to PASS\n"),
|
||||
--http-password=PASS set http password to PASS.\n"),
|
||||
N_("\
|
||||
--no-cache disallow server-cached data\n"),
|
||||
--no-cache disallow server-cached data.\n"),
|
||||
N_ ("\
|
||||
--default-page=NAME change the default page name (normally\n\
|
||||
this is 'index.html'.)\n"),
|
||||
--default-page=NAME Change the default page name (normally\n\
|
||||
this is `index.html'.).\n"),
|
||||
N_("\
|
||||
-E, --adjust-extension save HTML/CSS documents with proper extensions\n"),
|
||||
-E, --adjust-extension save HTML/CSS documents with proper extensions.\n"),
|
||||
N_("\
|
||||
--ignore-length ignore 'Content-Length' header field\n"),
|
||||
--ignore-length ignore `Content-Length' header field.\n"),
|
||||
N_("\
|
||||
--header=STRING insert STRING among the headers\n"),
|
||||
--header=STRING insert STRING among the headers.\n"),
|
||||
N_("\
|
||||
--max-redirect maximum redirections allowed per page\n"),
|
||||
--max-redirect maximum redirections allowed per page.\n"),
|
||||
N_("\
|
||||
--proxy-user=USER set USER as proxy username\n"),
|
||||
--proxy-user=USER set USER as proxy username.\n"),
|
||||
N_("\
|
||||
--proxy-password=PASS set PASS as proxy password\n"),
|
||||
--proxy-password=PASS set PASS as proxy password.\n"),
|
||||
N_("\
|
||||
--referer=URL include 'Referer: URL' header in HTTP request\n"),
|
||||
--referer=URL include `Referer: URL' header in HTTP request.\n"),
|
||||
N_("\
|
||||
--save-headers save the HTTP headers to file\n"),
|
||||
--save-headers save the HTTP headers to file.\n"),
|
||||
N_("\
|
||||
-U, --user-agent=AGENT identify as AGENT instead of Wget/VERSION\n"),
|
||||
-U, --user-agent=AGENT identify as AGENT instead of Wget/VERSION.\n"),
|
||||
N_("\
|
||||
--no-http-keep-alive disable HTTP keep-alive (persistent connections)\n"),
|
||||
--no-http-keep-alive disable HTTP keep-alive (persistent connections).\n"),
|
||||
N_("\
|
||||
--no-cookies don't use cookies\n"),
|
||||
--no-cookies don't use cookies.\n"),
|
||||
N_("\
|
||||
--load-cookies=FILE load cookies from FILE before session\n"),
|
||||
--load-cookies=FILE load cookies from FILE before session.\n"),
|
||||
N_("\
|
||||
--save-cookies=FILE save cookies to FILE after session\n"),
|
||||
--save-cookies=FILE save cookies to FILE after session.\n"),
|
||||
N_("\
|
||||
--keep-session-cookies load and save session (non-permanent) cookies\n"),
|
||||
--keep-session-cookies load and save session (non-permanent) cookies.\n"),
|
||||
N_("\
|
||||
--post-data=STRING use the POST method; send STRING as the data\n"),
|
||||
--post-data=STRING use the POST method; send STRING as the data.\n"),
|
||||
N_("\
|
||||
--post-file=FILE use the POST method; send contents of FILE\n"),
|
||||
--post-file=FILE use the POST method; send contents of FILE.\n"),
|
||||
N_("\
|
||||
--method=HTTPMethod use method \"HTTPMethod\" in the request\n"),
|
||||
--method=HTTPMethod use method \"HTTPMethod\" in the request.\n"),
|
||||
N_("\
|
||||
--body-data=STRING send STRING as data. --method MUST be set\n"),
|
||||
--body-data=STRING Send STRING as data. --method MUST be set.\n"),
|
||||
N_("\
|
||||
--body-file=FILE send contents of FILE. --method MUST be set\n"),
|
||||
--body-file=FILE Send contents of FILE. --method MUST be set.\n"),
|
||||
N_("\
|
||||
--content-disposition honor the Content-Disposition header when\n\
|
||||
choosing local file names (EXPERIMENTAL)\n"),
|
||||
choosing local file names (EXPERIMENTAL).\n"),
|
||||
N_("\
|
||||
--content-on-error output the received content on server errors\n"),
|
||||
--content-on-error output the received content on server errors.\n"),
|
||||
N_("\
|
||||
--auth-no-challenge send Basic HTTP authentication information\n\
|
||||
without first waiting for the server's\n\
|
||||
challenge\n"),
|
||||
without first waiting for the server's\n\
|
||||
challenge.\n"),
|
||||
"\n",
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
@@ -654,33 +657,27 @@ HTTP options:\n"),
|
||||
HTTPS (SSL/TLS) options:\n"),
|
||||
N_("\
|
||||
--secure-protocol=PR choose secure protocol, one of auto, SSLv2,\n\
|
||||
SSLv3, TLSv1 and PFS\n"),
|
||||
SSLv3, TLSv1 and PFS.\n"),
|
||||
N_("\
|
||||
--https-only only follow secure HTTPS links\n"),
|
||||
N_("\
|
||||
--no-check-certificate don't validate the server's certificate\n"),
|
||||
--no-check-certificate don't validate the server's certificate.\n"),
|
||||
N_("\
|
||||
--certificate=FILE client certificate file\n"),
|
||||
--certificate=FILE client certificate file.\n"),
|
||||
N_("\
|
||||
--certificate-type=TYPE client certificate type, PEM or DER\n"),
|
||||
--certificate-type=TYPE client certificate type, PEM or DER.\n"),
|
||||
N_("\
|
||||
--private-key=FILE private key file\n"),
|
||||
--private-key=FILE private key file.\n"),
|
||||
N_("\
|
||||
--private-key-type=TYPE private key type, PEM or DER\n"),
|
||||
--private-key-type=TYPE private key type, PEM or DER.\n"),
|
||||
N_("\
|
||||
--ca-certificate=FILE file with the bundle of CAs\n"),
|
||||
--ca-certificate=FILE file with the bundle of CA's.\n"),
|
||||
N_("\
|
||||
--ca-directory=DIR directory where hash list of CAs is stored\n"),
|
||||
--ca-directory=DIR directory where hash list of CA's is stored.\n"),
|
||||
N_("\
|
||||
--crl-file=FILE file with bundle of CRLs\n"),
|
||||
#if defined(HAVE_LIBSSL) || defined(HAVE_LIBSSL32)
|
||||
--random-file=FILE file with random data for seeding the SSL PRNG.\n"),
|
||||
N_("\
|
||||
--random-file=FILE file with random data for seeding the SSL PRNG\n"),
|
||||
#endif
|
||||
#if (defined(HAVE_LIBSSL) || defined(HAVE_LIBSSL32)) && defined(HAVE_RAND_EGD)
|
||||
N_("\
|
||||
--egd-file=FILE file naming the EGD socket with random data\n"),
|
||||
#endif
|
||||
--egd-file=FILE file naming the EGD socket with random data.\n"),
|
||||
"\n",
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
@@ -688,120 +685,120 @@ HTTPS (SSL/TLS) options:\n"),
|
||||
FTP options:\n"),
|
||||
#ifdef __VMS
|
||||
N_("\
|
||||
--ftp-stmlf use Stream_LF format for all binary FTP files\n"),
|
||||
--ftp-stmlf Use Stream_LF format for all binary FTP files.\n"),
|
||||
#endif /* def __VMS */
|
||||
N_("\
|
||||
--ftp-user=USER set ftp user to USER\n"),
|
||||
--ftp-user=USER set ftp user to USER.\n"),
|
||||
N_("\
|
||||
--ftp-password=PASS set ftp password to PASS\n"),
|
||||
--ftp-password=PASS set ftp password to PASS.\n"),
|
||||
N_("\
|
||||
--no-remove-listing don't remove '.listing' files\n"),
|
||||
--no-remove-listing don't remove `.listing' files.\n"),
|
||||
N_("\
|
||||
--no-glob turn off FTP file name globbing\n"),
|
||||
--no-glob turn off FTP file name globbing.\n"),
|
||||
N_("\
|
||||
--no-passive-ftp disable the \"passive\" transfer mode\n"),
|
||||
--no-passive-ftp disable the \"passive\" transfer mode.\n"),
|
||||
N_("\
|
||||
--preserve-permissions preserve remote file permissions\n"),
|
||||
--preserve-permissions preserve remote file permissions.\n"),
|
||||
N_("\
|
||||
--retr-symlinks when recursing, get linked-to files (not dir)\n"),
|
||||
--retr-symlinks when recursing, get linked-to files (not dir).\n"),
|
||||
"\n",
|
||||
|
||||
N_("\
|
||||
WARC options:\n"),
|
||||
N_("\
|
||||
--warc-file=FILENAME save request/response data to a .warc.gz file\n"),
|
||||
--warc-file=FILENAME save request/response data to a .warc.gz file.\n"),
|
||||
N_("\
|
||||
--warc-header=STRING insert STRING into the warcinfo record\n"),
|
||||
--warc-header=STRING insert STRING into the warcinfo record.\n"),
|
||||
N_("\
|
||||
--warc-max-size=NUMBER set maximum size of WARC files to NUMBER\n"),
|
||||
--warc-max-size=NUMBER set maximum size of WARC files to NUMBER.\n"),
|
||||
N_("\
|
||||
--warc-cdx write CDX index files\n"),
|
||||
--warc-cdx write CDX index files.\n"),
|
||||
N_("\
|
||||
--warc-dedup=FILENAME do not store records listed in this CDX file\n"),
|
||||
--warc-dedup=FILENAME do not store records listed in this CDX file.\n"),
|
||||
#ifdef HAVE_LIBZ
|
||||
N_("\
|
||||
--no-warc-compression do not compress WARC files with GZIP\n"),
|
||||
--no-warc-compression do not compress WARC files with GZIP.\n"),
|
||||
#endif
|
||||
N_("\
|
||||
--no-warc-digests do not calculate SHA1 digests\n"),
|
||||
--no-warc-digests do not calculate SHA1 digests.\n"),
|
||||
N_("\
|
||||
--no-warc-keep-log do not store the log file in a WARC record\n"),
|
||||
--no-warc-keep-log do not store the log file in a WARC record.\n"),
|
||||
N_("\
|
||||
--warc-tempdir=DIRECTORY location for temporary files created by the\n\
|
||||
WARC writer\n"),
|
||||
WARC writer.\n"),
|
||||
"\n",
|
||||
|
||||
N_("\
|
||||
Recursive download:\n"),
|
||||
N_("\
|
||||
-r, --recursive specify recursive download\n"),
|
||||
-r, --recursive specify recursive download.\n"),
|
||||
N_("\
|
||||
-l, --level=NUMBER maximum recursion depth (inf or 0 for infinite)\n"),
|
||||
-l, --level=NUMBER maximum recursion depth (inf or 0 for infinite).\n"),
|
||||
N_("\
|
||||
--delete-after delete files locally after downloading them\n"),
|
||||
--delete-after delete files locally after downloading them.\n"),
|
||||
N_("\
|
||||
-k, --convert-links make links in downloaded HTML or CSS point to\n\
|
||||
local files\n"),
|
||||
local files.\n"),
|
||||
N_("\
|
||||
--backups=N before writing file X, rotate up to N backup files\n"),
|
||||
--backups=N before writing file X, rotate up to N backup files.\n"),
|
||||
|
||||
#ifdef __VMS
|
||||
N_("\
|
||||
-K, --backup-converted before converting file X, back up as X_orig\n"),
|
||||
-K, --backup-converted before converting file X, back up as X_orig.\n"),
|
||||
#else /* def __VMS */
|
||||
N_("\
|
||||
-K, --backup-converted before converting file X, back up as X.orig\n"),
|
||||
-K, --backup-converted before converting file X, back up as X.orig.\n"),
|
||||
#endif /* def __VMS [else] */
|
||||
N_("\
|
||||
-m, --mirror shortcut for -N -r -l inf --no-remove-listing\n"),
|
||||
-m, --mirror shortcut for -N -r -l inf --no-remove-listing.\n"),
|
||||
N_("\
|
||||
-p, --page-requisites get all images, etc. needed to display HTML page\n"),
|
||||
-p, --page-requisites get all images, etc. needed to display HTML page.\n"),
|
||||
N_("\
|
||||
--strict-comments turn on strict (SGML) handling of HTML comments\n"),
|
||||
--strict-comments turn on strict (SGML) handling of HTML comments.\n"),
|
||||
"\n",
|
||||
|
||||
N_("\
|
||||
Recursive accept/reject:\n"),
|
||||
N_("\
|
||||
-A, --accept=LIST comma-separated list of accepted extensions\n"),
|
||||
-A, --accept=LIST comma-separated list of accepted extensions.\n"),
|
||||
N_("\
|
||||
-R, --reject=LIST comma-separated list of rejected extensions\n"),
|
||||
-R, --reject=LIST comma-separated list of rejected extensions.\n"),
|
||||
N_("\
|
||||
--accept-regex=REGEX regex matching accepted URLs\n"),
|
||||
--accept-regex=REGEX regex matching accepted URLs.\n"),
|
||||
N_("\
|
||||
--reject-regex=REGEX regex matching rejected URLs\n"),
|
||||
--reject-regex=REGEX regex matching rejected URLs.\n"),
|
||||
#ifdef HAVE_LIBPCRE
|
||||
N_("\
|
||||
--regex-type=TYPE regex type (posix|pcre)\n"),
|
||||
--regex-type=TYPE regex type (posix|pcre).\n"),
|
||||
#else
|
||||
N_("\
|
||||
--regex-type=TYPE regex type (posix)\n"),
|
||||
--regex-type=TYPE regex type (posix).\n"),
|
||||
#endif
|
||||
N_("\
|
||||
-D, --domains=LIST comma-separated list of accepted domains\n"),
|
||||
-D, --domains=LIST comma-separated list of accepted domains.\n"),
|
||||
N_("\
|
||||
--exclude-domains=LIST comma-separated list of rejected domains\n"),
|
||||
--exclude-domains=LIST comma-separated list of rejected domains.\n"),
|
||||
N_("\
|
||||
--follow-ftp follow FTP links from HTML documents\n"),
|
||||
--follow-ftp follow FTP links from HTML documents.\n"),
|
||||
N_("\
|
||||
--follow-tags=LIST comma-separated list of followed HTML tags\n"),
|
||||
--follow-tags=LIST comma-separated list of followed HTML tags.\n"),
|
||||
N_("\
|
||||
--ignore-tags=LIST comma-separated list of ignored HTML tags\n"),
|
||||
--ignore-tags=LIST comma-separated list of ignored HTML tags.\n"),
|
||||
N_("\
|
||||
-H, --span-hosts go to foreign hosts when recursive\n"),
|
||||
-H, --span-hosts go to foreign hosts when recursive.\n"),
|
||||
N_("\
|
||||
-L, --relative follow relative links only\n"),
|
||||
-L, --relative follow relative links only.\n"),
|
||||
N_("\
|
||||
-I, --include-directories=LIST list of allowed directories\n"),
|
||||
-I, --include-directories=LIST list of allowed directories.\n"),
|
||||
N_("\
|
||||
--trust-server-names use the name specified by the redirection\n\
|
||||
URL's last component\n"),
|
||||
url last component.\n"),
|
||||
N_("\
|
||||
-X, --exclude-directories=LIST list of excluded directories\n"),
|
||||
-X, --exclude-directories=LIST list of excluded directories.\n"),
|
||||
N_("\
|
||||
-np, --no-parent don't ascend to the parent directory\n"),
|
||||
-np, --no-parent don't ascend to the parent directory.\n"),
|
||||
"\n",
|
||||
N_("Mail bug reports and suggestions to <bug-wget@gnu.org>\n")
|
||||
N_("Mail bug reports and suggestions to <bug-wget@gnu.org>.\n")
|
||||
};
|
||||
|
||||
size_t i;
|
||||
@@ -892,10 +889,7 @@ format_and_print_line (const char *prefix, const char *line,
|
||||
remaining_chars = line_length - TABULATION;
|
||||
}
|
||||
if (printf ("%s ", token) < 0)
|
||||
{
|
||||
xfree (line_dup);
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
remaining_chars -= strlen (token) + 1; /* account for " " */
|
||||
token = strtok (NULL, " ");
|
||||
}
|
||||
@@ -1005,27 +999,24 @@ There is NO WARRANTY, to the extent permitted by law.\n"), stdout) < 0)
|
||||
exit (WGET_EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
const char *program_name; /* Needed by lib/error.c. */
|
||||
const char *program_argstring; /* Needed by wget_warc.c. */
|
||||
char *program_name; /* Needed by lib/error.c. */
|
||||
char *program_argstring; /* Needed by wget_warc.c. */
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char **url, **t, *p;
|
||||
char **url, **t;
|
||||
int i, ret, longindex;
|
||||
int nurl;
|
||||
int retconf;
|
||||
int argstring_length;
|
||||
bool use_userconfig = false;
|
||||
bool noconfig = false;
|
||||
bool append_to_log = false;
|
||||
|
||||
total_downloaded_bytes = 0;
|
||||
|
||||
program_name = argv[0];
|
||||
|
||||
struct ptimer *timer = ptimer_new ();
|
||||
double start_time = ptimer_measure (timer);
|
||||
|
||||
total_downloaded_bytes = 0;
|
||||
program_name = argv[0];
|
||||
|
||||
i18n_initialize ();
|
||||
|
||||
/* Construct the name of the executable, without the directory part. */
|
||||
@@ -1033,7 +1024,11 @@ main (int argc, char **argv)
|
||||
/* On VMS, lose the "dev:[dir]" prefix and the ".EXE;nnn" suffix. */
|
||||
exec_name = vms_basename (argv[0]);
|
||||
#else /* def __VMS */
|
||||
exec_name = base_name (argv[0]);
|
||||
exec_name = strrchr (argv[0], PATH_SEPARATOR);
|
||||
if (!exec_name)
|
||||
exec_name = argv[0];
|
||||
else
|
||||
++exec_name;
|
||||
#endif /* def __VMS [else] */
|
||||
|
||||
#ifdef WINDOWS
|
||||
@@ -1042,9 +1037,10 @@ main (int argc, char **argv)
|
||||
#endif
|
||||
|
||||
/* Construct the arguments string. */
|
||||
for (argstring_length = 1, i = 1; i < argc; i++)
|
||||
argstring_length += strlen (argv[i]) + 3 + 1;
|
||||
program_argstring = p = malloc (argstring_length);
|
||||
int argstring_length = 1;
|
||||
for (i = 1; i < argc; i++)
|
||||
argstring_length += strlen (argv[i]) + 2 + 1;
|
||||
char *p = program_argstring = malloc (argstring_length * sizeof (char));
|
||||
if (p == NULL)
|
||||
{
|
||||
fprintf (stderr, _("Memory allocation problem\n"));
|
||||
@@ -1052,10 +1048,8 @@ main (int argc, char **argv)
|
||||
}
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
int arglen;
|
||||
|
||||
*p++ = '"';
|
||||
arglen = strlen (argv[i]);
|
||||
int arglen = strlen (argv[i]);
|
||||
memcpy (p, argv[i], arglen);
|
||||
p += arglen;
|
||||
*p++ = '"';
|
||||
@@ -1071,6 +1065,9 @@ main (int argc, char **argv)
|
||||
/* This separate getopt_long is needed to find the user config file
|
||||
option ("--config") and parse it before the other user options. */
|
||||
longindex = -1;
|
||||
int retconf;
|
||||
bool use_userconfig = false;
|
||||
bool noconfig = false;
|
||||
|
||||
while ((retconf = getopt_long (argc, argv,
|
||||
short_options, long_options, &longindex)) != -1)
|
||||
@@ -1271,11 +1268,8 @@ main (int argc, char **argv)
|
||||
if (opt.verbose == -1)
|
||||
opt.verbose = !opt.quiet;
|
||||
|
||||
if (!opt.verbose && opt.show_progress == -1)
|
||||
opt.show_progress = false;
|
||||
|
||||
if (opt.quiet && opt.show_progress == -1)
|
||||
opt.show_progress = false;
|
||||
if (opt.verbose == 1)
|
||||
opt.show_progress = true;
|
||||
|
||||
/* Sanity checks. */
|
||||
if (opt.verbose && opt.quiet)
|
||||
@@ -1393,7 +1387,11 @@ for details.\n\n"));
|
||||
opt.always_rest = false;
|
||||
}
|
||||
|
||||
if (!nurl && !opt.input_filename)
|
||||
if (!nurl && !opt.input_filename
|
||||
#ifdef ENABLE_METALINK
|
||||
&& !opt.metalink_file
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/* No URL specified. */
|
||||
fprintf (stderr, _("%s: missing URL\n"), exec_name);
|
||||
@@ -1466,7 +1464,7 @@ for details.\n\n"));
|
||||
|
||||
/* When user specifies HEAD as the method, we do not wish to download any
|
||||
files. Hence, set wget to run in spider mode. */
|
||||
if (opt.method && c_strcasecmp (opt.method, "HEAD") == 0)
|
||||
if (opt.method && strcasecmp (opt.method, "HEAD") == 0)
|
||||
setoptval ("spider", "1", "spider");
|
||||
|
||||
/* Convert post_data to body-data and post_file_name to body-file options.
|
||||
@@ -1483,12 +1481,12 @@ for details.\n\n"));
|
||||
if (opt.post_data)
|
||||
{
|
||||
setoptval ("bodydata", opt.post_data, "body-data");
|
||||
xfree(opt.post_data);
|
||||
opt.post_data = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
setoptval ("bodyfile", opt.post_file_name, "body-file");
|
||||
xfree(opt.post_file_name);
|
||||
opt.post_file_name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1616,6 +1614,53 @@ outputting to a regular file.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_METALINK
|
||||
if(opt.metalink_file)
|
||||
{
|
||||
/* --protocol-directories is the longest option among the ones checked below. */
|
||||
char *temp_option = malloc(sizeof "--protocol-directories");
|
||||
|
||||
if(opt.user || opt.passwd || opt.http_user || opt.http_passwd ||
|
||||
opt.ftp_user || opt.ftp_passwd || opt.ask_passwd)
|
||||
{
|
||||
fprintf (stderr, _("Username and password information not needed to \
|
||||
be specified when downloading from a metalink.\n"));
|
||||
exit (WGET_EXIT_GENERIC_ERROR);
|
||||
}
|
||||
temp_option[0] = '\0';
|
||||
if(opt.input_filename)
|
||||
sprintf(temp_option, "-i");
|
||||
else if(opt.output_document)
|
||||
sprintf(temp_option, "-O");
|
||||
else if(opt.base_href)
|
||||
sprintf(temp_option, "--base");
|
||||
else if(opt.force_html)
|
||||
sprintf(temp_option, "--force-html");
|
||||
else if(opt.always_rest)
|
||||
sprintf(temp_option, "-c");
|
||||
else if(opt.spider)
|
||||
sprintf(temp_option, "-spider");
|
||||
else if(opt.cut_dirs)
|
||||
sprintf(temp_option, "--cut-dirs");
|
||||
else if(opt.wait)
|
||||
sprintf(temp_option, "-w");
|
||||
else if(opt.waitretry != 10)
|
||||
sprintf(temp_option, "--waitretry");
|
||||
else if(opt.timestamping)
|
||||
sprintf(temp_option, "--timestamping");
|
||||
else if(opt.protocol_directories)
|
||||
sprintf(temp_option, "--protocol-directories");
|
||||
else if(opt.dirstruct)
|
||||
sprintf(temp_option, "--force-directories");
|
||||
if(temp_option[0])
|
||||
{
|
||||
fprintf (stderr, _("%s can't be used with --metalink.\n"), temp_option);
|
||||
free(temp_option);
|
||||
exit (WGET_EXIT_GENERIC_ERROR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __VMS
|
||||
/* Set global ODS5 flag according to the specified destination (if
|
||||
any), otherwise according to the current default device.
|
||||
@@ -1689,7 +1734,7 @@ outputting to a regular file.\n"));
|
||||
else
|
||||
{
|
||||
retrieve_url (url_parsed, *t, &filename, &redirected_URL, NULL,
|
||||
&dt, opt.recursive, iri, true);
|
||||
&dt, opt.recursive, iri, true, NULL);
|
||||
}
|
||||
|
||||
if (opt.delete_after && filename != NULL && file_exists_p (filename))
|
||||
@@ -1699,8 +1744,8 @@ outputting to a regular file.\n"));
|
||||
if (unlink (filename))
|
||||
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
|
||||
}
|
||||
xfree (redirected_URL);
|
||||
xfree (filename);
|
||||
xfree_null (redirected_URL);
|
||||
xfree_null (filename);
|
||||
url_free (url_parsed);
|
||||
}
|
||||
iri_free (iri);
|
||||
@@ -1711,6 +1756,7 @@ outputting to a regular file.\n"));
|
||||
{
|
||||
int count;
|
||||
int status;
|
||||
|
||||
status = retrieve_from_file (opt.input_filename, opt.force_html, &count);
|
||||
inform_exit_status (status);
|
||||
if (!count)
|
||||
@@ -1718,6 +1764,21 @@ outputting to a regular file.\n"));
|
||||
opt.input_filename);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_METALINK
|
||||
/* And then from the metalink file, if any. */
|
||||
if (opt.metalink_file)
|
||||
{
|
||||
int count;
|
||||
int status;
|
||||
|
||||
status = retrieve_from_file (opt.metalink_file, opt.force_html, &count);
|
||||
inform_exit_status (status);
|
||||
if (!count)
|
||||
logprintf (LOG_NOTQUIET, _("No URLs found in %s.\n"),
|
||||
opt.input_filename);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Print broken links. */
|
||||
if (opt.recursive && opt.spider)
|
||||
print_broken_links ();
|
||||
@@ -1725,16 +1786,19 @@ outputting to a regular file.\n"));
|
||||
/* Print the downloaded sum. */
|
||||
if ((opt.recursive || opt.page_requisites
|
||||
|| nurl > 1
|
||||
|| (opt.input_filename && total_downloaded_bytes != 0))
|
||||
|| (opt.input_filename && total_downloaded_bytes != 0)
|
||||
#ifdef ENABLE_METALINK
|
||||
|| (opt.metalink_file && total_downloaded_bytes != 0)
|
||||
#endif
|
||||
)
|
||||
&&
|
||||
total_downloaded_bytes != 0)
|
||||
{
|
||||
double end_time = ptimer_measure (timer);
|
||||
char *wall_time = xstrdup (secs_to_human_time (end_time - start_time));
|
||||
char *download_time = xstrdup (secs_to_human_time (total_download_time));
|
||||
|
||||
ptimer_destroy (timer);
|
||||
|
||||
char *wall_time = xstrdup (secs_to_human_time (end_time - start_time));
|
||||
char *download_time = xstrdup (secs_to_human_time (total_download_time));
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("FINISHED --%s--\nTotal wall clock time: %s\n"
|
||||
"Downloaded: %d files, %s in %s (%s)\n"),
|
||||
@@ -1764,8 +1828,33 @@ outputting to a regular file.\n"));
|
||||
|
||||
exit (get_exit_status ());
|
||||
}
|
||||
|
||||
#endif /* TESTING */
|
||||
|
||||
#if defined(SIGHUP) || defined(SIGUSR1)
|
||||
|
||||
/* So the signal_name check doesn't blow when only one is available. */
|
||||
#ifndef SIGHUP
|
||||
# define SIGHUP -1
|
||||
#endif
|
||||
#ifndef SIGUSR1
|
||||
# define SIGUSR1 -1
|
||||
#endif
|
||||
|
||||
/* Hangup signal handler. When wget receives SIGHUP or SIGUSR1, it
|
||||
will proceed operation as usual, trying to write into a log file.
|
||||
If that is impossible, the output will be turned off. */
|
||||
|
||||
static void
|
||||
redirect_output_signal (int sig)
|
||||
{
|
||||
const char *signal_name = (sig == SIGHUP ? "SIGHUP" :
|
||||
(sig == SIGUSR1 ? "SIGUSR1" :
|
||||
"WTF?!"));
|
||||
log_request_redirect_output (signal_name);
|
||||
progress_schedule_redirect ();
|
||||
signal (sig, redirect_output_signal);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* vim: et ts=2 sw=2
|
||||
|
||||
470
src/metalink.c
Normal file
470
src/metalink.c
Normal file
@@ -0,0 +1,470 @@
|
||||
/* Declarations for HTTP.
|
||||
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2014 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"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <metalink/metalink_parser.h>
|
||||
#include <metalink/metalink_types.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "md5.h"
|
||||
#include "sha1.h"
|
||||
#include "sha256.h"
|
||||
#include "metalink.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#define HASH_TYPES 3
|
||||
/* Between MD5, SHA1 and SHA256, SHA256 has the greatest hash length, which is
|
||||
32. In the line below, 64 is written to have a more readable code. */
|
||||
#define MAX_DIGEST_LENGTH 32
|
||||
|
||||
static char supported_hashes[HASH_TYPES][7] = {"sha256", "sha1", "md5"};
|
||||
static int digest_sizes[HASH_TYPES] = {SHA256_DIGEST_SIZE, SHA1_DIGEST_SIZE, MD5_DIGEST_SIZE};
|
||||
static int (*hash_function[HASH_TYPES]) (FILE *, void *) = {sha256_stream, sha1_stream, md5_stream};
|
||||
|
||||
/* First, parse the metalink using libmetalink functions and structures. Then
|
||||
pass the information to an internal set of structures. */
|
||||
mlink *
|
||||
parse_metalink(char *input_file)
|
||||
{
|
||||
int err;
|
||||
metalink_t *metalink;
|
||||
metalink_file_t **files;
|
||||
metalink_resource_t **resources;
|
||||
metalink_checksum_t **checksums;
|
||||
metalink_chunk_checksum_t *chunk_checksum;
|
||||
metalink_piece_hash_t **piece_hashes;
|
||||
mlink *m_link;
|
||||
err = metalink_parse_file (input_file, &metalink);
|
||||
if(err != 0 || !metalink)
|
||||
{
|
||||
logprintf (LOG_VERBOSE, "Libmetalink could not parse the metalink file.\n");
|
||||
return NULL;
|
||||
}
|
||||
else if(metalink->files == NULL) {
|
||||
logprintf (LOG_VERBOSE, "PARSE METALINK: Metalink doesn't have any file data.\n");
|
||||
metalink_delete(metalink);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m_link = malloc (sizeof *m_link);
|
||||
m_link->identity = (metalink->identity ? xstrdup (metalink->identity) : NULL);
|
||||
m_link->tags = (metalink->tags ? xstrdup (metalink->tags) : NULL);
|
||||
m_link->files = NULL;
|
||||
m_link->num_of_files = 0;
|
||||
|
||||
for (files = metalink->files; *files; ++files)
|
||||
{
|
||||
mlink_file *file;
|
||||
|
||||
if (!(*files)->name)
|
||||
{
|
||||
/* File name is missing */
|
||||
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping file"
|
||||
" due to missing name/path.\n");
|
||||
continue;
|
||||
}
|
||||
else if (!(*files)->resources)
|
||||
{
|
||||
/* URL is missing */
|
||||
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping file(%s)"
|
||||
" due to missing resources.\n", (*files)->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
file = malloc(sizeof(mlink_file));
|
||||
++(m_link->num_of_files);
|
||||
file -> next = (m_link->files);
|
||||
(m_link->files) = file;
|
||||
|
||||
file->name = xstrdup ((*files)->name);
|
||||
file->size = (*files)->size;
|
||||
file->maxconnections = (*files)->maxconnections;
|
||||
file->version = ((*files)->version ? xstrdup ((*files)->version) : NULL);
|
||||
file->language = ((*files)->language ? xstrdup ((*files)->language) : NULL);
|
||||
file->os = ((*files)->os ? xstrdup ((*files)->os) : NULL);
|
||||
file->resources = NULL;
|
||||
file->checksums = NULL;
|
||||
file->chunk_checksum = NULL;
|
||||
file->num_of_res = file->num_of_checksums = 0;
|
||||
|
||||
for (resources = (*files)->resources; *resources; ++resources)
|
||||
{
|
||||
mlink_resource *resource;
|
||||
|
||||
if (!(*resources)->url)
|
||||
{
|
||||
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping resource"
|
||||
" due to missing URL.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
resource = malloc (sizeof(mlink_resource));
|
||||
++(file->num_of_res);
|
||||
|
||||
resource->url = xstrdup ((*resources)->url);
|
||||
resource->type = ((*resources)->type ? xstrdup ((*resources)->type) : NULL);
|
||||
resource->location = ((*resources)->location ? xstrdup ((*resources)->location) : NULL);
|
||||
resource->preference = (*resources)->preference;
|
||||
resource->maxconnections = (*resources)->maxconnections;
|
||||
|
||||
resource->next = (file->resources);
|
||||
(file->resources) = resource;
|
||||
}
|
||||
|
||||
for (checksums = (*files)->checksums; *checksums; ++checksums)
|
||||
{
|
||||
mlink_checksum *checksum = malloc (sizeof(mlink_checksum));
|
||||
|
||||
if (!(*checksums)->type)
|
||||
{
|
||||
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping checksum"
|
||||
" due to missing hash type.\n");
|
||||
continue;
|
||||
}
|
||||
else if (!(*checksums)->hash)
|
||||
{
|
||||
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping resource"
|
||||
" due to missing hash value.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
checksum->type = ((*checksums)->type ? xstrdup ((*checksums)->type) : NULL);
|
||||
checksum->hash = ((*checksums)->hash ? xstrdup ((*checksums)->hash) : NULL);
|
||||
|
||||
checksum->next = (file->checksums);
|
||||
(file->checksums) = checksum;
|
||||
}
|
||||
|
||||
if((chunk_checksum = (*files)->chunk_checksum))
|
||||
{
|
||||
mlink_chunk_checksum *chunk_sum;
|
||||
|
||||
if(!chunk_checksum->type)
|
||||
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping chunk checksum"
|
||||
" due to missing type information.\n");
|
||||
else
|
||||
{
|
||||
chunk_sum = malloc (sizeof(mlink_chunk_checksum));
|
||||
chunk_sum->length = chunk_checksum->length;
|
||||
chunk_sum->type = (chunk_checksum->type ? xstrdup (chunk_checksum->type) : NULL);
|
||||
for (piece_hashes = chunk_checksum->piece_hashes; *piece_hashes; ++piece_hashes)
|
||||
{
|
||||
mlink_piece_hash piece_hash;
|
||||
if(!chunk_checksum->type)
|
||||
{
|
||||
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping chunk checksum"
|
||||
" due to missing hash value for piece(%d).\n",
|
||||
(*piece_hashes)->piece);
|
||||
free (chunk_sum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
metalink_delete(metalink);
|
||||
return m_link;
|
||||
}
|
||||
|
||||
/* Elect resouces so that only the URLs with type HTTP and FTP (i.e. the
|
||||
protocols supported by Metalink&GNU Wget) remain on the list of resources. */
|
||||
void
|
||||
elect_resources (mlink *mlink)
|
||||
{
|
||||
mlink_file *file;
|
||||
mlink_resource *res, *res_next;
|
||||
|
||||
for (file = mlink->files; file; file = file->next)
|
||||
{
|
||||
res = file->resources;
|
||||
if (!res)
|
||||
continue;
|
||||
|
||||
while (res_next = res->next)
|
||||
{
|
||||
if (strcmp(res_next->type, "ftp") && strcmp(res_next->type, "http"))
|
||||
{
|
||||
res->next = res_next->next;
|
||||
free(res_next);
|
||||
}
|
||||
else
|
||||
res = res_next;
|
||||
}
|
||||
res = file->resources;
|
||||
if (strcmp(res->type, "ftp") && strcmp(res->type, "http"))
|
||||
{
|
||||
file->resources = res->next;
|
||||
free(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Elect checksums so that only the hashes with types MD5, SHA-1 or SHA-256
|
||||
(i.e. the hashes supported by Metalink) remain on the list of checksums. */
|
||||
void
|
||||
elect_checksums (mlink *mlink)
|
||||
{
|
||||
int i;
|
||||
mlink_file *file = mlink -> files;
|
||||
mlink_checksum *csum, *csum_next;
|
||||
|
||||
for (; file; file = file->next)
|
||||
{
|
||||
csum = file->checksums;
|
||||
if (!csum)
|
||||
continue;
|
||||
|
||||
while (csum_next = csum->next)
|
||||
{
|
||||
/* Traverse supported hash types & break if csum->type is the same. */
|
||||
for (i = 0; i < HASH_TYPES; ++i)
|
||||
if (!strcmp(csum_next->type, supported_hashes[i]))
|
||||
break;
|
||||
|
||||
if(i == HASH_TYPES)
|
||||
{
|
||||
csum->next = csum_next->next;
|
||||
free(csum_next);
|
||||
}
|
||||
else
|
||||
csum=csum_next;
|
||||
}
|
||||
csum = file->checksums;
|
||||
for (i = 0; i < HASH_TYPES; ++i)
|
||||
if (!strcmp(csum->type, supported_hashes[i]))
|
||||
break;
|
||||
if(i == HASH_TYPES)
|
||||
{
|
||||
file->checksums = csum->next;
|
||||
free(csum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the space allocated for the whole mlink structure. */
|
||||
void
|
||||
delete_mlink(mlink *metalink)
|
||||
{
|
||||
mlink_file *file, *file_temp;
|
||||
mlink_resource *res, *res_temp;
|
||||
mlink_checksum *csum, *csum_temp;
|
||||
mlink_piece_hash *phash, *phash_temp;
|
||||
|
||||
if(!metalink)
|
||||
return;
|
||||
|
||||
xfree_null (metalink->tags);
|
||||
xfree_null (metalink->identity);
|
||||
|
||||
file = metalink->files;
|
||||
while (file)
|
||||
{
|
||||
xfree_null(file->os);
|
||||
xfree_null(file->language);
|
||||
xfree_null(file->version);
|
||||
xfree_null(file->name);
|
||||
|
||||
res = file->resources;
|
||||
while (res)
|
||||
{
|
||||
xfree_null (res->url);
|
||||
xfree_null (res->type);
|
||||
xfree_null (res->location);
|
||||
|
||||
res_temp = res;
|
||||
res = res->next;
|
||||
free (res_temp);
|
||||
}
|
||||
|
||||
csum = file->checksums;
|
||||
while (csum)
|
||||
{
|
||||
xfree_null (csum->type);
|
||||
xfree_null (csum->hash);
|
||||
|
||||
csum_temp = csum;
|
||||
csum = csum->next;
|
||||
free (csum_temp);
|
||||
}
|
||||
|
||||
if(file->chunk_checksum)
|
||||
{
|
||||
free (file->chunk_checksum->type);
|
||||
phash = file->chunk_checksum->piece_hashes;
|
||||
while (phash)
|
||||
{
|
||||
xfree_null (phash->hash);
|
||||
|
||||
phash_temp = phash;
|
||||
phash = phash->next;
|
||||
free (phash_temp);
|
||||
}
|
||||
}
|
||||
|
||||
file_temp = file;
|
||||
file = file->next;
|
||||
free (file_temp);
|
||||
}
|
||||
free (metalink);
|
||||
}
|
||||
|
||||
/* Parses metalink into type metalink_t and returns a pointer to it.
|
||||
Returns NULL if the parsing is failed. */
|
||||
metalink_t*
|
||||
metalink_context (const char *url)
|
||||
{
|
||||
metalink_error_t err;
|
||||
metalink_t* metalink;
|
||||
|
||||
err = metalink_parse_file (url, &metalink);
|
||||
|
||||
if(err != 0)
|
||||
metalink = NULL;
|
||||
return metalink;
|
||||
}
|
||||
|
||||
/* It should be taken into account that file hashes in metalink files may
|
||||
include uppercase letter. This function turns the case of the first length
|
||||
letters in the space pointed by hash into lowercase. */
|
||||
static void
|
||||
lower_hex_case (unsigned char *hash, int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* 32 is the difference between the ascii codes of 'a' and 'A'. */
|
||||
for(i = 0; i < length; ++i)
|
||||
if('A' <= hash[i] && hash[i] <= 'Z')
|
||||
hash[i] += 32;
|
||||
}
|
||||
|
||||
/* Verifies file hash by comparing the file hashes found by gnulib functions
|
||||
and hashes provided by metalink file. Works by comparing strongest supported
|
||||
hash type available in the metalink file.
|
||||
|
||||
Returns;
|
||||
-1 if hashes that were compared turned out to be different.
|
||||
0 if all pairs of hashes compared turned out to be the same.
|
||||
1 if due to some error, comparisons could not be made. */
|
||||
int
|
||||
verify_file_hash (const char *filename, mlink_checksum *checksums)
|
||||
{
|
||||
int i, j, req_type, res = 0;
|
||||
|
||||
unsigned char hash_raw[MAX_DIGEST_LENGTH];
|
||||
/* Points to a hash of supported type from the metalink file. The index dedicated
|
||||
to a type is inversely proportional to its strength. (check supported_types
|
||||
to see the supported hash types listed in decreasing order of strength)*/
|
||||
unsigned char *metalink_hashes[HASH_TYPES];
|
||||
unsigned char file_hash[2 * MAX_DIGEST_LENGTH + 1];
|
||||
FILE *file;
|
||||
mlink_checksum *checksum;
|
||||
|
||||
if (!checksums)
|
||||
{
|
||||
/* Metalink file has no hashes for this file. */
|
||||
logprintf (LOG_VERBOSE, "Validating(%s) failed: digest missing in metalink file.\n",
|
||||
filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < HASH_TYPES; ++i)
|
||||
metalink_hashes[i] = NULL;
|
||||
|
||||
/* Fill metalink_hashes to contain an instance of supported types of hashes. */
|
||||
for (checksum = checksums; checksum; checksum = checksum->next)
|
||||
for (j = 0; j < HASH_TYPES; ++j)
|
||||
if (!strcmp(checksum->type, supported_hashes[j]))
|
||||
{
|
||||
if(metalink_hashes[j])
|
||||
{
|
||||
/* As of libmetalin-0.03, it is not checked during parsing the
|
||||
information in the metalink file whether there are multiple
|
||||
hashes of same type for one file. That case should be checked,
|
||||
as none of those hashes can be trusted above the other. */
|
||||
logprintf (LOG_VERBOSE, "Validating(%s) failed: metalink file contains different hashes of same type.\n",
|
||||
filename);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
metalink_hashes[j] = checksum->hash;
|
||||
}
|
||||
|
||||
for (i = 0; !metalink_hashes[i]; ++i);
|
||||
|
||||
if (i == HASH_TYPES)
|
||||
{
|
||||
/* no hash of supported types could be found. */
|
||||
logprintf (LOG_VERBOSE, "Validating(%s) failed: No hash of supported types could be found in metalink file.\n",
|
||||
filename);
|
||||
return 1;
|
||||
}
|
||||
req_type = i;
|
||||
|
||||
if (!(file = fopen(filename, "rb")))
|
||||
{
|
||||
/* File could not be opened. */
|
||||
logprintf (LOG_VERBOSE, "Validating(%s) failed: file could not be opened.\n",
|
||||
filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
res = (*hash_function[req_type]) (file, hash_raw);
|
||||
fclose(file);
|
||||
|
||||
/* Find file hash accordingly. */
|
||||
if (res)
|
||||
{
|
||||
logprintf (LOG_VERBOSE, "Validating(%s) failed: File hash could not be found.\n",
|
||||
filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Turn byte-form hash to hex form. */
|
||||
for(j = 0 ; j < digest_sizes[req_type]; ++j)
|
||||
sprintf(file_hash + 2 * j, "%02x", hash_raw[j]);
|
||||
|
||||
lower_hex_case(metalink_hashes[req_type], 2 * digest_sizes[req_type]);
|
||||
if (strcmp(metalink_hashes[req_type], file_hash))
|
||||
{
|
||||
logprintf (LOG_VERBOSE, "Verifying(%s) failed: %s hashes are different.\n",
|
||||
filename, supported_hashes[i]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
logprintf (LOG_VERBOSE, "Verifying(%s): %s hashes are the same.\n",
|
||||
filename, supported_hashes[i]);
|
||||
return 0;
|
||||
}
|
||||
106
src/metalink.h
Normal file
106
src/metalink.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/* Declarations for metalink.c.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
2005, 2006, 2007, 2008, 2009, 2010, 2011 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. */
|
||||
|
||||
#ifndef MLINK_H
|
||||
#define MLINK_H
|
||||
|
||||
typedef struct metalink_piece_hash
|
||||
{
|
||||
struct metalink_piece_hash *next;
|
||||
|
||||
int piece;
|
||||
char *hash;
|
||||
} mlink_piece_hash;
|
||||
|
||||
typedef struct metalink_checksum
|
||||
{
|
||||
struct metalink_checksum *next;
|
||||
|
||||
char *type;
|
||||
char *hash;
|
||||
} mlink_checksum;
|
||||
|
||||
typedef struct metalink_resource
|
||||
{
|
||||
struct metalink_resource *next;
|
||||
|
||||
char *url;
|
||||
char *type;
|
||||
char *location;
|
||||
int preference;
|
||||
int maxconnections;
|
||||
} mlink_resource;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *type;
|
||||
int length;
|
||||
mlink_piece_hash *piece_hashes;
|
||||
} mlink_chunk_checksum;
|
||||
|
||||
typedef struct metalink_file
|
||||
{
|
||||
struct metalink_file *next;
|
||||
|
||||
char *name;
|
||||
long long int size;
|
||||
char *version;
|
||||
char *language;
|
||||
char *os;
|
||||
int maxconnections;
|
||||
mlink_resource *resources;
|
||||
int num_of_res;
|
||||
mlink_checksum *checksums;
|
||||
int num_of_checksums;
|
||||
mlink_chunk_checksum *chunk_checksum;
|
||||
} mlink_file;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *identity;
|
||||
char *tags;
|
||||
mlink_file *files;
|
||||
int num_of_files;
|
||||
} mlink;
|
||||
|
||||
mlink *parse_metalink (char *);
|
||||
|
||||
void elect_resources (mlink *);
|
||||
|
||||
void elect_checksums (mlink *);
|
||||
|
||||
void delete_mlink (mlink *);
|
||||
|
||||
metalink_t *metalink_context (const char *);
|
||||
|
||||
int verify_file_hash (const char *, mlink_checksum *);
|
||||
|
||||
#endif /* MLINK_H */
|
||||
@@ -85,11 +85,11 @@ windows_main (char **exec_name)
|
||||
if (p)
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ws_cleanup (void)
|
||||
{
|
||||
xfree (exec_name);
|
||||
xfree ((char*)exec_name);
|
||||
WSACleanup ();
|
||||
}
|
||||
|
||||
@@ -367,8 +367,8 @@ static int old_percentage = -1;
|
||||
void
|
||||
ws_changetitle (const char *url)
|
||||
{
|
||||
xfree (title_buf);
|
||||
xfree (curr_url);
|
||||
xfree_null (title_buf);
|
||||
xfree_null (curr_url);
|
||||
title_buf = xmalloc (strlen (url) + 20);
|
||||
curr_url = xstrdup (url);
|
||||
old_percentage = -1;
|
||||
@@ -477,7 +477,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).
|
||||
|
||||
239
src/multi.c
Normal file
239
src/multi.c
Normal file
@@ -0,0 +1,239 @@
|
||||
/* Declarations for HTTP.
|
||||
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2014 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"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "multi.h"
|
||||
#include "url.h"
|
||||
#include "exits.h"
|
||||
|
||||
static struct range *ranges;
|
||||
char **files;
|
||||
|
||||
/* Allocate space for temporary file names. */
|
||||
void
|
||||
init_temp_files()
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!(files = malloc (opt.jobs * (sizeof *files))))
|
||||
{
|
||||
logprintf (LOG_VERBOSE, "Space for temporary file data could not be allocated.\n");
|
||||
exit (WGET_EXIT_GENERIC_ERROR);
|
||||
}
|
||||
for (i = 0; i < opt.jobs; ++i)
|
||||
if(!(files[i] = malloc (L_tmpnam * sizeof(char))))
|
||||
{
|
||||
logprintf (LOG_VERBOSE, "Space for temporary file names could not be allocated.\n");
|
||||
exit (WGET_EXIT_GENERIC_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign names to temporary files to be used. */
|
||||
void
|
||||
name_temp_files()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < opt.jobs; ++i)
|
||||
if(!tmpnam(files[i]))
|
||||
{
|
||||
logprintf (LOG_VERBOSE, "Temporary file name could not be assigned.\n");
|
||||
exit (WGET_EXIT_GENERIC_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Merge the temporary files in which the chunks are stored to form the
|
||||
resulting file(output). */
|
||||
void
|
||||
merge_temp_files(char *output)
|
||||
{
|
||||
FILE *out, *in;
|
||||
int j, ret;
|
||||
void *buf = malloc (MIN_CHUNK_SIZE);
|
||||
|
||||
out = fopen (output, "wb");
|
||||
for(j = 0; j < opt.jobs; ++j)
|
||||
{
|
||||
in = fopen(files[j],"rb");
|
||||
ret = MIN_CHUNK_SIZE;
|
||||
while(ret == MIN_CHUNK_SIZE)
|
||||
{
|
||||
ret = fread(buf, 1, MIN_CHUNK_SIZE, in);
|
||||
fwrite(buf, 1, ret, out);
|
||||
}
|
||||
fclose(in);
|
||||
}
|
||||
fclose(out);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/* Delete the temporary files used. */
|
||||
void
|
||||
delete_temp_files()
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
while(j < opt.jobs)
|
||||
unlink(files[j++]);
|
||||
}
|
||||
|
||||
/* Clean the space allocated for temporary files data. */
|
||||
void
|
||||
clean_temp_files()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < opt.jobs; ++i)
|
||||
free (files[i]);
|
||||
free(files);
|
||||
}
|
||||
|
||||
/* Allocate ranges array to store the ranges data. */
|
||||
void
|
||||
init_ranges()
|
||||
{
|
||||
if(!(ranges = malloc (opt.jobs * (sizeof *ranges))))
|
||||
{
|
||||
logprintf (LOG_VERBOSE, "Space for ranges data could not be allocated.\n");
|
||||
exit (WGET_EXIT_GENERIC_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign values to the ranges.
|
||||
Also allocates the resources array each struct range must have.
|
||||
|
||||
Returns the number of ranges to which values are assigned. */
|
||||
int
|
||||
fill_ranges_data(int num_of_resources, long long int file_size,
|
||||
long int chunk_size)
|
||||
{
|
||||
int i, r;
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
ranges[i].first_byte = i * chunk_size;
|
||||
ranges[i].last_byte = (i+1) * chunk_size - 1;
|
||||
ranges[i].bytes_covered = ranges[i].is_assigned = 0;
|
||||
ranges[i].resources = malloc(num_of_resources * sizeof(bool));
|
||||
ranges[i].status_least_severe = RETROK;
|
||||
for (r = 0; r < num_of_resources; ++r)
|
||||
ranges[i].resources[r] = false;
|
||||
++i;
|
||||
} while (ranges[i-1].last_byte < (file_size - 1));
|
||||
ranges[i-1].last_byte = file_size -1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Free the resources array of each range allocated by fill_ranges_data(). */
|
||||
void
|
||||
clean_range_res_data()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < opt.jobs; ++i)
|
||||
free (ranges[i].resources);
|
||||
}
|
||||
|
||||
/* Free the ranges array that is used for storing ranges' data. */
|
||||
void
|
||||
clean_ranges()
|
||||
{
|
||||
free (ranges);
|
||||
ranges = NULL;
|
||||
}
|
||||
|
||||
/* Assign 'last minute' data to struct s_thread_ctx instances regarding their
|
||||
usage and range information. Then create a thread using that instance. */
|
||||
int
|
||||
spawn_thread (struct s_thread_ctx *thread_ctx, int index, int resource)
|
||||
{
|
||||
static pthread_t thread;
|
||||
|
||||
thread_ctx[index].url_parsed = url_parse (thread_ctx[index].url,
|
||||
&(thread_ctx[index].url_err), thread_ctx[index].i, true);
|
||||
if(!thread_ctx[index].url_parsed)
|
||||
return 1;
|
||||
|
||||
thread_ctx[index].file = files[index];
|
||||
thread_ctx[index].range = ranges + index;
|
||||
(thread_ctx[index].range)->is_assigned = 1;
|
||||
(thread_ctx[index].range)->resources[resource] = true;
|
||||
|
||||
thread_ctx[index].used = 1;
|
||||
thread_ctx[index].terminated = 0;
|
||||
|
||||
return pthread_create (&thread, NULL, segmented_retrieve_url, &thread_ctx[index]);
|
||||
}
|
||||
|
||||
/* Collects the first thread to terminate and updates struct s_thread_ctx
|
||||
instance's data regarding its 'business' (i.e. being used by a thread).
|
||||
|
||||
Returns the index of the struct s_thread_ctx instance that was used in the
|
||||
terminating thread. */
|
||||
int
|
||||
collect_thread (sem_t *retr_sem, struct s_thread_ctx *thread_ctx)
|
||||
{
|
||||
int k, ret;
|
||||
do
|
||||
ret = sem_wait (retr_sem);
|
||||
while (ret < 0 && errno == EINTR);
|
||||
|
||||
for (k = 0; k < opt.jobs; k++)
|
||||
if (thread_ctx[k].used && thread_ctx[k].terminated)
|
||||
{
|
||||
url_free (thread_ctx[k].url_parsed);
|
||||
thread_ctx[k].used = 0;
|
||||
(thread_ctx[k].range)->is_assigned = 0;
|
||||
return k;
|
||||
}
|
||||
}
|
||||
|
||||
/* The function which is being called by pthread_create in spawn_thread(). It
|
||||
is used to call retrieve_url(), which requires many arguments. */
|
||||
static void *
|
||||
segmented_retrieve_url (void *arg)
|
||||
{
|
||||
struct s_thread_ctx *ctx = (struct s_thread_ctx *) arg;
|
||||
|
||||
ctx->status = retrieve_url (ctx->url_parsed, ctx->url,
|
||||
&ctx->file, &ctx->redirected,
|
||||
ctx->referer, &ctx->dt,
|
||||
false, ctx->i, true, ctx->range);
|
||||
ctx->terminated = 1;
|
||||
sem_post (ctx->retr_sem);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Extern declarations for printing version information
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
/* Declarations for HTTP.
|
||||
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is part of GNU Wget.
|
||||
|
||||
@@ -27,10 +28,62 @@ 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. */
|
||||
|
||||
/* Extern declarations for strings in version.c */
|
||||
extern const char *version_string;
|
||||
extern const char *compilation_string;
|
||||
extern const char *link_string;
|
||||
#ifndef MULTI_H
|
||||
#define MULTI_H
|
||||
|
||||
/* Extern declaration for string in build_info.c */
|
||||
extern const char *compiled_features[];
|
||||
#include <semaphore.h>
|
||||
|
||||
#include "wget.h"
|
||||
|
||||
#include "iri.h"
|
||||
#include "url.h"
|
||||
|
||||
#define MIN_CHUNK_SIZE 2048
|
||||
|
||||
struct s_thread_ctx
|
||||
{
|
||||
pthread_t thread;
|
||||
int used;
|
||||
int terminated;
|
||||
int dt, url_err;
|
||||
char *redirected;
|
||||
char *referer;
|
||||
struct url *url_parsed;
|
||||
struct iri *i;
|
||||
struct range *range;
|
||||
char *file;
|
||||
char *url;
|
||||
#ifdef ENABLE_THREADS
|
||||
sem_t *retr_sem;
|
||||
#else
|
||||
/* Not used. */
|
||||
void *retr_sem;
|
||||
#endif
|
||||
uerr_t status;
|
||||
};
|
||||
|
||||
void init_temp_files();
|
||||
|
||||
void name_temp_files();
|
||||
|
||||
void merge_temp_files(char *);
|
||||
|
||||
void delete_temp_files();
|
||||
|
||||
void clean_temp_files();
|
||||
|
||||
void init_ranges();
|
||||
|
||||
int fill_ranges_data(int, long long int, long int);
|
||||
|
||||
void clean_range_res_data();
|
||||
|
||||
void clean_ranges();
|
||||
|
||||
int spawn_thread (struct s_thread_ctx*, int, int);
|
||||
|
||||
int collect_thread (sem_t *, struct s_thread_ctx *);
|
||||
|
||||
static void * segmented_retrieve_url (void *);
|
||||
|
||||
#endif /* MULTI_H */
|
||||
14
src/netrc.c
14
src/netrc.c
@@ -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(p) do { free ((void *) (p)); p = NULL; } while (0)
|
||||
# define xfree free
|
||||
# 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 (a->host);
|
||||
xfree (a->acc);
|
||||
xfree (a->passwd);
|
||||
xfree_null (a->host);
|
||||
xfree_null (a->acc);
|
||||
xfree_null (a->passwd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -424,9 +424,9 @@ free_netrc(acc_t *l)
|
||||
while (l)
|
||||
{
|
||||
t = l->next;
|
||||
xfree (l->acc);
|
||||
xfree (l->passwd);
|
||||
xfree (l->host);
|
||||
xfree_null (l->acc);
|
||||
xfree_null (l->passwd);
|
||||
xfree_null (l->host);
|
||||
xfree (l);
|
||||
l = t;
|
||||
}
|
||||
|
||||
106
src/openssl.c
106
src/openssl.c
@@ -40,11 +40,6 @@ as that of the covered work. */
|
||||
#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"
|
||||
@@ -91,11 +86,9 @@ 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;
|
||||
@@ -171,9 +164,6 @@ 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)
|
||||
{
|
||||
@@ -182,6 +172,8 @@ ssl_init (void)
|
||||
}
|
||||
#endif
|
||||
|
||||
SSL_METHOD const *meth;
|
||||
|
||||
if (ssl_ctx)
|
||||
/* The SSL has already been initialized. */
|
||||
return true;
|
||||
@@ -195,12 +187,6 @@ 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 ();
|
||||
SSLeay_add_all_algorithms ();
|
||||
@@ -208,48 +194,22 @@ ssl_init (void)
|
||||
|
||||
switch (opt.secure_protocol)
|
||||
{
|
||||
case secure_protocol_auto:
|
||||
meth = SSLv23_client_method ();
|
||||
break;
|
||||
#ifndef OPENSSL_NO_SSL2
|
||||
case secure_protocol_sslv2:
|
||||
meth = SSLv2_client_method ();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SSL3
|
||||
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 ();
|
||||
}
|
||||
|
||||
@@ -259,9 +219,6 @@ 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)
|
||||
*/
|
||||
@@ -271,18 +228,6 @@ 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
|
||||
@@ -425,7 +370,7 @@ openssl_errstr (int fd _GL_UNUSED, void *arg)
|
||||
return NULL;
|
||||
|
||||
/* Get rid of previous contents of ctx->last_error, if any. */
|
||||
xfree (ctx->last_error);
|
||||
xfree_null (ctx->last_error);
|
||||
|
||||
/* Iterate over OpenSSL's error stack and accumulate errors in the
|
||||
last_error buffer, separated by "; ". This is better than using
|
||||
@@ -469,7 +414,7 @@ openssl_close (int fd, void *arg)
|
||||
|
||||
SSL_shutdown (conn);
|
||||
SSL_free (conn);
|
||||
xfree (ctx->last_error);
|
||||
xfree_null (ctx->last_error);
|
||||
xfree (ctx);
|
||||
|
||||
close (fd);
|
||||
@@ -545,7 +490,7 @@ ssl_connect_wget (int fd, const char *hostname)
|
||||
DEBUGP (("SSL handshake timed out.\n"));
|
||||
goto timeout;
|
||||
}
|
||||
if (scwt_ctx.result <= 0 || SSL_state(conn) != SSL_ST_OK)
|
||||
if (scwt_ctx.result <= 0 || conn->state != SSL_ST_OK)
|
||||
goto error;
|
||||
|
||||
ctx = xnew0 (struct openssl_transport_context);
|
||||
@@ -610,27 +555,6 @@ 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("");
|
||||
}
|
||||
|
||||
/* 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
|
||||
@@ -674,25 +598,23 @@ ssl_check_certificate (int fd, const char *host)
|
||||
|
||||
IF_DEBUG
|
||||
{
|
||||
char *subject = _get_rfc2253_formatted (X509_get_subject_name (cert));
|
||||
char *issuer = _get_rfc2253_formatted (X509_get_issuer_name (cert));
|
||||
char *subject = X509_NAME_oneline (X509_get_subject_name (cert), 0, 0);
|
||||
char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
|
||||
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)));
|
||||
xfree (subject);
|
||||
xfree (issuer);
|
||||
OPENSSL_free (subject);
|
||||
OPENSSL_free (issuer);
|
||||
}
|
||||
|
||||
vresult = SSL_get_verify_result (conn);
|
||||
if (vresult != X509_V_OK)
|
||||
{
|
||||
char *issuer = _get_rfc2253_formatted (X509_get_issuer_name (cert));
|
||||
char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
|
||||
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)
|
||||
@@ -788,7 +710,7 @@ ssl_check_certificate (int fd, const char *host)
|
||||
}
|
||||
}
|
||||
}
|
||||
sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
|
||||
sk_GENERAL_NAME_free (subjectAltNames);
|
||||
if (host_in_octet_string)
|
||||
ASN1_OCTET_STRING_free(host_in_octet_string);
|
||||
|
||||
|
||||
@@ -35,6 +35,11 @@ struct options
|
||||
hence not boolean.) */
|
||||
bool quiet; /* Are we quiet? */
|
||||
int ntry; /* Number of tries per URL */
|
||||
#ifdef ENABLE_METALINK
|
||||
int n_retries; /* Number of tries per file */
|
||||
#endif
|
||||
char *metalink_file; /* Metalink filename */
|
||||
|
||||
bool retry_connrefused; /* Treat CONNREFUSED as non-fatal. */
|
||||
bool background; /* Whether we should work in background. */
|
||||
bool ignore_length; /* Do we heed content-length at all? */
|
||||
@@ -133,7 +138,7 @@ struct options
|
||||
char **no_proxy;
|
||||
char *base_href;
|
||||
char *progress_type; /* progress indicator type. */
|
||||
int show_progress; /* Show only the progress bar */
|
||||
bool show_progress; /* Show only the progress bar */
|
||||
bool noscroll; /* Don't scroll the filename in the progressbar */
|
||||
char *proxy_user; /*oli*/
|
||||
char *proxy_passwd;
|
||||
@@ -202,8 +207,6 @@ 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 */
|
||||
@@ -218,7 +221,6 @@ struct options
|
||||
|
||||
char *ca_directory; /* CA directory (hash files) */
|
||||
char *ca_cert; /* CA certificate file to use */
|
||||
char *crl_file; /* file with CRLs */
|
||||
|
||||
char *random_file; /* file with random data to seed the PRNG */
|
||||
char *egd_file; /* file name of the egd daemon socket */
|
||||
@@ -288,6 +290,8 @@ struct options
|
||||
bool show_all_dns_entries; /* Show all the DNS entries when resolving a
|
||||
name. */
|
||||
bool report_bps; /*Output bandwidth in bits format*/
|
||||
|
||||
int jobs; /* How many threads use at the same time. */
|
||||
};
|
||||
|
||||
extern struct options opt;
|
||||
|
||||
357
src/progress.c
357
src/progress.c
@@ -36,20 +36,24 @@ as that of the covered work. */
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
#include <mbiter.h>
|
||||
|
||||
#ifdef ENABLE_THREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "progress.h"
|
||||
#include "utils.h"
|
||||
#include "retr.h"
|
||||
#include "c-strcase.h"
|
||||
#include "ptimer.h"
|
||||
|
||||
struct progress_implementation {
|
||||
const char *name;
|
||||
bool interactive;
|
||||
void *(*create) (const char *, wgint, wgint);
|
||||
void (*update) (void *, wgint, double);
|
||||
void (*draw) (void *);
|
||||
void (*draw) (void *, bool);
|
||||
void (*finish) (void *, double);
|
||||
void (*set_params) (char *);
|
||||
};
|
||||
@@ -59,15 +63,33 @@ struct progress_implementation {
|
||||
static void *dot_create (const char *, wgint, wgint);
|
||||
static void dot_update (void *, wgint, double);
|
||||
static void dot_finish (void *, double);
|
||||
static void dot_draw (void *);
|
||||
static void dot_draw (void *, bool);
|
||||
static void dot_set_params (char *);
|
||||
|
||||
static void *bar_create (const char *, wgint, wgint);
|
||||
static void bar_update (void *, wgint, double);
|
||||
static void bar_draw (void *);
|
||||
static void bar_draw (void *, bool);
|
||||
static void bar_finish (void *, double);
|
||||
static void bar_set_params (char *);
|
||||
|
||||
struct progress_header
|
||||
{
|
||||
struct progress_header *next;
|
||||
};
|
||||
|
||||
static struct progress_header *progress_list = NULL;
|
||||
static struct progress_header *current_progress = NULL;
|
||||
|
||||
#ifdef ENABLE_THREADS
|
||||
static pthread_mutex_t progress_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
# define LOCK_PROGRESS() pthread_mutex_lock (&progress_mutex);
|
||||
# define UNLOCK_PROGRESS() pthread_mutex_unlock (&progress_mutex);
|
||||
#else
|
||||
# define LOCK_PROGRESS()
|
||||
# define UNLOCK_PROGRESS()
|
||||
#endif
|
||||
|
||||
|
||||
static struct progress_implementation implementations[] = {
|
||||
{ "dot", 0, dot_create, dot_update, dot_draw, dot_finish, dot_set_params },
|
||||
{ "bar", 1, bar_create, bar_update, bar_draw, bar_finish, bar_set_params }
|
||||
@@ -88,6 +110,37 @@ static int current_impl_locked;
|
||||
|
||||
#define FALLBACK_PROGRESS_IMPLEMENTATION "dot"
|
||||
|
||||
|
||||
/* Time between screen refreshes will not be shorter than this, so
|
||||
that Wget doesn't swamp the TTY with output. */
|
||||
#define REFRESH_INTERVAL 0.2
|
||||
|
||||
/* Time between screen refreshes the file to show when there are multiple
|
||||
downloads at the same time. */
|
||||
#define REFRESH_SWITCH_FILE 1.5
|
||||
|
||||
/* Assumed screen width if we can't find the real value. */
|
||||
#define DEFAULT_SCREEN_WIDTH 80
|
||||
|
||||
/* Minimum screen width we'll try to work with. If this is too small,
|
||||
create_image will overflow the buffer. */
|
||||
#define MINIMUM_SCREEN_WIDTH 45
|
||||
|
||||
/* The last known screen width. This can be updated by the code that
|
||||
detects that SIGWINCH was received (but it's never updated from the
|
||||
signal handler). */
|
||||
static int screen_width;
|
||||
|
||||
/* A flag that, when set, means SIGWINCH was received. */
|
||||
static volatile sig_atomic_t received_sigwinch;
|
||||
|
||||
static int bp_width; /* screen width we're using at the
|
||||
time the progress gauge was
|
||||
created. this is different from
|
||||
the screen_width global variable in
|
||||
that the latter can be changed by a
|
||||
signal. */
|
||||
|
||||
/* Return true if NAME names a valid progress bar implementation. The
|
||||
characters after the first : will be ignored. */
|
||||
|
||||
@@ -157,6 +210,7 @@ void *
|
||||
progress_create (const char *f_download, wgint initial, wgint total)
|
||||
{
|
||||
/* Check if the log status has changed under our feet. */
|
||||
struct progress_header *ret;
|
||||
if (output_redirected)
|
||||
{
|
||||
if (!current_impl_locked)
|
||||
@@ -164,7 +218,17 @@ progress_create (const char *f_download, wgint initial, wgint total)
|
||||
output_redirected = 0;
|
||||
}
|
||||
|
||||
return current_impl->create (f_download, initial, total);
|
||||
ret = current_impl->create (f_download, initial, total);
|
||||
if (ret)
|
||||
{
|
||||
LOCK_PROGRESS ();
|
||||
|
||||
ret->next = progress_list;
|
||||
progress_list = ret;
|
||||
|
||||
UNLOCK_PROGRESS ();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Return true if the progress gauge is "interactive", i.e. if it can
|
||||
@@ -184,8 +248,50 @@ progress_interactive_p (void *progress _GL_UNUSED)
|
||||
void
|
||||
progress_update (void *progress, wgint howmuch, double dltime)
|
||||
{
|
||||
static struct ptimer *last_draw = NULL;
|
||||
static struct ptimer *last_switch = NULL;
|
||||
bool force_screen_update = false;
|
||||
|
||||
current_impl->update (progress, howmuch, dltime);
|
||||
current_impl->draw (progress);
|
||||
LOCK_PROGRESS ();
|
||||
|
||||
if (last_draw == NULL)
|
||||
last_draw = ptimer_new ();
|
||||
if (last_switch == NULL)
|
||||
last_switch = ptimer_new ();
|
||||
|
||||
/* If SIGWINCH (the window size change signal) been received,
|
||||
determine the new screen size and update the screen. */
|
||||
if (received_sigwinch)
|
||||
{
|
||||
int old_width = screen_width;
|
||||
screen_width = determine_screen_width ();
|
||||
if (!screen_width)
|
||||
screen_width = DEFAULT_SCREEN_WIDTH;
|
||||
else if (screen_width < MINIMUM_SCREEN_WIDTH)
|
||||
screen_width = MINIMUM_SCREEN_WIDTH;
|
||||
if (screen_width != old_width)
|
||||
force_screen_update = true;
|
||||
received_sigwinch = 0;
|
||||
}
|
||||
|
||||
if (ptimer_measure (last_draw) >= REFRESH_INTERVAL || force_screen_update)
|
||||
{
|
||||
if (current_progress == NULL)
|
||||
current_progress = progress_list;
|
||||
|
||||
bp_width = screen_width - 1;
|
||||
current_impl->draw (current_progress, force_screen_update);
|
||||
ptimer_reset (last_draw);
|
||||
|
||||
if (ptimer_measure (last_switch) >= REFRESH_SWITCH_FILE)
|
||||
{
|
||||
ptimer_reset (last_switch);
|
||||
current_progress = current_progress->next;
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK_PROGRESS ();
|
||||
}
|
||||
|
||||
/* Tell the progress gauge to clean up. Calling this will free the
|
||||
@@ -194,12 +300,38 @@ progress_update (void *progress, wgint howmuch, double dltime)
|
||||
void
|
||||
progress_finish (void *progress, double dltime)
|
||||
{
|
||||
struct progress_header *header = progress;
|
||||
{
|
||||
struct progress_header *it, *prev = NULL;
|
||||
|
||||
LOCK_PROGRESS ();
|
||||
|
||||
for (it = progress_list; it; it = it->next)
|
||||
{
|
||||
if (it == progress)
|
||||
{
|
||||
if (current_progress == progress)
|
||||
current_progress = it->next;
|
||||
|
||||
if (it == progress_list)
|
||||
progress_list = progress_list->next;
|
||||
else
|
||||
prev->next = it->next;
|
||||
break;
|
||||
}
|
||||
prev = it;
|
||||
}
|
||||
|
||||
UNLOCK_PROGRESS ();
|
||||
}
|
||||
current_impl->finish (progress, dltime);
|
||||
}
|
||||
|
||||
|
||||
/* Dot-printing. */
|
||||
|
||||
struct dot_progress {
|
||||
struct progress_header header;
|
||||
|
||||
wgint initial_length; /* how many bytes have been downloaded
|
||||
previously. */
|
||||
wgint total_length; /* expected total byte count when the
|
||||
@@ -354,12 +486,16 @@ dot_update (void *progress, wgint howmuch, double dltime)
|
||||
}
|
||||
|
||||
static void
|
||||
dot_draw (void *progress)
|
||||
dot_draw (void *progress, bool force)
|
||||
{
|
||||
struct dot_progress *dp = progress;
|
||||
int dot_bytes = opt.dot_bytes;
|
||||
wgint ROW_BYTES = opt.dot_bytes * opt.dots_in_line;
|
||||
|
||||
/* FIXME: support threads. */
|
||||
if (opt.jobs > 1)
|
||||
return;
|
||||
|
||||
log_set_flush (false);
|
||||
|
||||
for (; dp->accumulated >= dot_bytes; dp->accumulated -= dot_bytes)
|
||||
@@ -428,7 +564,7 @@ dot_set_params (char *params)
|
||||
return;
|
||||
|
||||
/* We use this to set the retrieval style. */
|
||||
if (!c_strcasecmp (params, "default"))
|
||||
if (!strcasecmp (params, "default"))
|
||||
{
|
||||
/* Default style: 1K dots, 10 dots in a cluster, 50 dots in a
|
||||
line. */
|
||||
@@ -436,7 +572,7 @@ dot_set_params (char *params)
|
||||
opt.dot_spacing = 10;
|
||||
opt.dots_in_line = 50;
|
||||
}
|
||||
else if (!c_strcasecmp (params, "binary"))
|
||||
else if (!strcasecmp (params, "binary"))
|
||||
{
|
||||
/* "Binary" retrieval: 8K dots, 16 dots in a cluster, 48 dots
|
||||
(384K) in a line. */
|
||||
@@ -444,7 +580,7 @@ dot_set_params (char *params)
|
||||
opt.dot_spacing = 16;
|
||||
opt.dots_in_line = 48;
|
||||
}
|
||||
else if (!c_strcasecmp (params, "mega"))
|
||||
else if (!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. */
|
||||
@@ -452,7 +588,7 @@ dot_set_params (char *params)
|
||||
opt.dot_spacing = 8;
|
||||
opt.dots_in_line = 48;
|
||||
}
|
||||
else if (!c_strcasecmp (params, "giga"))
|
||||
else if (!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
|
||||
@@ -466,24 +602,9 @@ 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. */
|
||||
#define DEFAULT_SCREEN_WIDTH 80
|
||||
|
||||
/* Minimum screen width we'll try to work with. If this is too small,
|
||||
create_image will overflow the buffer. */
|
||||
#define MINIMUM_SCREEN_WIDTH 45
|
||||
|
||||
/* The last known screen width. This can be updated by the code that
|
||||
detects that SIGWINCH was received (but it's never updated from the
|
||||
signal handler). */
|
||||
static int screen_width;
|
||||
|
||||
/* A flag that, when set, means SIGWINCH was received. */
|
||||
static volatile sig_atomic_t received_sigwinch;
|
||||
|
||||
/* Size of the download speed history ring. */
|
||||
#define DLSPEED_HISTORY_SIZE 20
|
||||
|
||||
@@ -498,15 +619,12 @@ static volatile sig_atomic_t received_sigwinch;
|
||||
download speeds are scratched. */
|
||||
#define STALL_START_TIME 5
|
||||
|
||||
/* Time between screen refreshes will not be shorter than this, so
|
||||
that Wget doesn't swamp the TTY with output. */
|
||||
#define REFRESH_INTERVAL 0.2
|
||||
|
||||
/* Don't refresh the ETA too often to avoid jerkiness in predictions.
|
||||
This allows ETA to change approximately once per second. */
|
||||
#define ETA_REFRESH_INTERVAL 0.99
|
||||
|
||||
struct bar_progress {
|
||||
struct progress_header header;
|
||||
const char *f_download; /* Filename of the downloaded file */
|
||||
wgint initial_length; /* how many bytes have been downloaded
|
||||
previously. */
|
||||
@@ -514,19 +632,8 @@ struct bar_progress {
|
||||
download finishes */
|
||||
wgint count; /* bytes downloaded so far */
|
||||
|
||||
double last_screen_update; /* time of the last screen update,
|
||||
measured since the beginning of
|
||||
download. */
|
||||
|
||||
double dltime; /* download time so far */
|
||||
int width; /* screen width we're using at the
|
||||
time the progress gauge was
|
||||
created. this is different from
|
||||
the screen_width global variable in
|
||||
that the latter can be changed by a
|
||||
signal. */
|
||||
char *buffer; /* buffer where the bar "image" is
|
||||
stored. */
|
||||
|
||||
int tick; /* counter used for drawing the
|
||||
progress bar where the total size
|
||||
is not known. */
|
||||
@@ -561,7 +668,7 @@ struct bar_progress {
|
||||
int last_eta_value;
|
||||
};
|
||||
|
||||
static void create_image (struct bar_progress *, double, bool);
|
||||
static void create_image (struct bar_progress *, char *buffer, double, bool);
|
||||
static void display_image (char *);
|
||||
|
||||
static void *
|
||||
@@ -591,15 +698,11 @@ bar_create (const char *f_download, wgint initial, wgint total)
|
||||
}
|
||||
|
||||
/* - 1 because we don't want to use the last screen column. */
|
||||
bp->width = screen_width - 1;
|
||||
/* + enough space for the terminating zero, and hopefully enough room
|
||||
* for multibyte characters. */
|
||||
bp->buffer = xmalloc (bp->width + 100);
|
||||
bp_width = screen_width - 1;
|
||||
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
|
||||
create_image (bp, 0, false);
|
||||
display_image (bp->buffer);
|
||||
bar_draw (bp, false);
|
||||
|
||||
return bp;
|
||||
}
|
||||
@@ -626,37 +729,20 @@ bar_update (void *progress, wgint howmuch, double dltime)
|
||||
}
|
||||
|
||||
static void
|
||||
bar_draw (void *progress)
|
||||
bar_draw (void *progress, bool force)
|
||||
{
|
||||
bool force_screen_update = false;
|
||||
struct bar_progress *bp = progress;
|
||||
static char *buffer = NULL;
|
||||
|
||||
/* If SIGWINCH (the window size change signal) been received,
|
||||
determine the new screen size and update the screen. */
|
||||
if (received_sigwinch)
|
||||
if (buffer == NULL)
|
||||
buffer = xmalloc (bp_width + 100);
|
||||
|
||||
if (force)
|
||||
{
|
||||
int old_width = screen_width;
|
||||
screen_width = determine_screen_width ();
|
||||
if (!screen_width)
|
||||
screen_width = DEFAULT_SCREEN_WIDTH;
|
||||
else if (screen_width < MINIMUM_SCREEN_WIDTH)
|
||||
screen_width = MINIMUM_SCREEN_WIDTH;
|
||||
if (screen_width != old_width)
|
||||
{
|
||||
bp->width = screen_width - 1;
|
||||
bp->buffer = xrealloc (bp->buffer, bp->width + 100);
|
||||
force_screen_update = true;
|
||||
}
|
||||
received_sigwinch = 0;
|
||||
buffer = xrealloc (buffer, bp_width + 100);
|
||||
}
|
||||
|
||||
if (bp->dltime - bp->last_screen_update < REFRESH_INTERVAL && !force_screen_update)
|
||||
/* Don't update more often than five times per second. */
|
||||
return;
|
||||
|
||||
create_image (bp, bp->dltime, false);
|
||||
display_image (bp->buffer);
|
||||
bp->last_screen_update = bp->dltime;
|
||||
create_image (bp, buffer, bp->dltime, false);
|
||||
display_image (buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -669,13 +755,11 @@ bar_finish (void *progress, double dltime)
|
||||
/* See bar_update() for explanation. */
|
||||
bp->total_length = bp->initial_length + bp->count;
|
||||
|
||||
create_image (bp, dltime, true);
|
||||
display_image (bp->buffer);
|
||||
bar_draw (bp, false);
|
||||
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
logputs (LOG_PROGRESS, "\n");
|
||||
|
||||
xfree (bp->buffer);
|
||||
xfree (bp);
|
||||
}
|
||||
|
||||
@@ -814,39 +898,8 @@ 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
|
||||
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;
|
||||
}
|
||||
# define count_cols(mbs) ((int)(strlen(mbs)))
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
@@ -896,17 +949,28 @@ get_eta (int *bcd)
|
||||
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)
|
||||
create_image (struct bar_progress *bp, char *buffer, double dl_total_time, bool done)
|
||||
{
|
||||
const int MAX_FILENAME_COLS = bp->width / 4;
|
||||
char *p = bp->buffer;
|
||||
const int MAX_FILENAME_LEN = bp_width / 4;
|
||||
char *p = 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_cols = count_cols (bp->f_download);
|
||||
int orig_filename_len = strlen (bp->f_download);
|
||||
|
||||
/* The progress bar should look like this:
|
||||
file xx% [=======> ] nnn.nnK 12.34KB/s eta 36m 51s
|
||||
@@ -918,8 +982,9 @@ 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_COLS chars + 1
|
||||
"file " - Downloaded filename - MAX_FILENAME_LEN chars + 1
|
||||
"xx% " or "100%" - percentage - 4 chars
|
||||
" url " - string - MAX MAX_URL_LEN chars + 2
|
||||
"[]" - progress bar decorations - 2 chars
|
||||
" nnn.nnK" - downloaded bytes - 7 chars + 1
|
||||
" 12.5KB/s" - download rate - 8 chars + 1
|
||||
@@ -928,57 +993,42 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
||||
"=====>..." - progress bar - the rest
|
||||
*/
|
||||
|
||||
#define PROGRESS_FILENAME_LEN MAX_FILENAME_COLS + 1
|
||||
#define PROGRESS_FILENAME_LEN MAX_FILENAME_LEN + 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
|
||||
|
||||
int progress_size = bp->width - (PROGRESS_FILENAME_LEN + PROGRESS_PERCENT_LEN +
|
||||
int progress_size = bp_width - (PROGRESS_FILENAME_LEN + PROGRESS_PERCENT_LEN +
|
||||
PROGRESS_DECORAT_LEN + PROGRESS_FILESIZE_LEN +
|
||||
PROGRESS_DWNLOAD_RATE + PROGRESS_ETA_LEN);
|
||||
|
||||
/* 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;
|
||||
|
||||
if (progress_size < 5)
|
||||
progress_size = 0;
|
||||
|
||||
if (orig_filename_cols <= MAX_FILENAME_COLS)
|
||||
if (orig_filename_len <= MAX_FILENAME_LEN)
|
||||
{
|
||||
int padding = MAX_FILENAME_COLS - orig_filename_cols;
|
||||
int padding = MAX_FILENAME_LEN - orig_filename_len;
|
||||
sprintf (p, "%s ", bp->f_download);
|
||||
p += orig_filename_cols + 1;
|
||||
p += orig_filename_len + 1;
|
||||
for (;padding;padding--)
|
||||
*p++ = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset_cols;
|
||||
int bytes_in_filename, offset_bytes, col;
|
||||
int *cols_ret = &col;
|
||||
int padding;
|
||||
int offset;
|
||||
|
||||
#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 + 1);
|
||||
if (((orig_filename_len > MAX_FILENAME_LEN) && !opt.noscroll) && !done)
|
||||
offset = ((int) bp->tick) % (orig_filename_len - MAX_FILENAME_LEN);
|
||||
else
|
||||
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,
|
||||
cols_ret);
|
||||
memcpy (p, bp->f_download + offset_bytes, bytes_in_filename);
|
||||
p += bytes_in_filename;
|
||||
padding = MAX_FILENAME_COLS - *cols_ret;
|
||||
for (;padding;padding--)
|
||||
*p++ = ' ';
|
||||
offset = 0;
|
||||
memcpy (p, bp->f_download + offset, MAX_FILENAME_LEN);
|
||||
p += MAX_FILENAME_LEN;
|
||||
*p++ = ' ';
|
||||
}
|
||||
|
||||
@@ -1055,12 +1105,12 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
||||
}
|
||||
*p++ = ']';
|
||||
|
||||
++bp->tick;
|
||||
}
|
||||
++bp->tick;
|
||||
|
||||
/* " 234.56M" */
|
||||
down_size = human_readable (size, 1000, 2);
|
||||
cols_diff = 7 - count_cols (down_size);
|
||||
const char * down_size = human_readable (size, 1000, 2);
|
||||
int cols_diff = 7 - count_cols (down_size);
|
||||
while (cols_diff > 0)
|
||||
{
|
||||
*p++=' ';
|
||||
@@ -1159,18 +1209,9 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
||||
move_to_end (p);
|
||||
}
|
||||
|
||||
while (p - bp->buffer - bytes_cols_diff < bp->width)
|
||||
while (p - buffer - bytes_cols_diff - size_grouped_diff < bp_width)
|
||||
*p++ = ' ';
|
||||
*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.
|
||||
*/
|
||||
assert (count_cols (bp->buffer) <= bp->width + 1);
|
||||
}
|
||||
|
||||
/* Print the contents of the buffer as a one-line ASCII "image" so
|
||||
@@ -1202,7 +1243,7 @@ bar_set_params (char *params)
|
||||
} while ((param = strtok (NULL, ":")) != NULL);
|
||||
}
|
||||
|
||||
if (((opt.lfilename && opt.show_progress != 1)
|
||||
if ((opt.lfilename
|
||||
#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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
255
src/recur.c
255
src/recur.c
@@ -37,6 +37,12 @@ as that of the covered work. */
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#ifdef ENABLE_THREADS
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
|
||||
#include "multi.h"
|
||||
|
||||
#include "url.h"
|
||||
#include "recur.h"
|
||||
@@ -50,7 +56,7 @@ as that of the covered work. */
|
||||
#include "html-url.h"
|
||||
#include "css-url.h"
|
||||
#include "spider.h"
|
||||
|
||||
|
||||
/* Functions for maintaining the URL queue. */
|
||||
|
||||
struct queue_element {
|
||||
@@ -159,33 +165,33 @@ url_dequeue (struct url_queue *queue, struct iri **i,
|
||||
xfree (qel);
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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 *);
|
||||
|
||||
#if !ENABLE_THREADS
|
||||
# define THREAD_JOIN(...) (0)
|
||||
# define SEM_INIT(...) (0)
|
||||
# define SEM_WAIT(...) (0)
|
||||
#else
|
||||
# define THREAD_JOIN pthread_join
|
||||
# define SEM_INIT sem_init
|
||||
# define SEM_WAIT sem_wait
|
||||
static void *
|
||||
start_retrieve_url (void *arg)
|
||||
{
|
||||
struct s_thread_ctx *ctx = (struct s_thread_ctx *) arg;
|
||||
|
||||
ctx->status = retrieve_url (ctx->url_parsed, ctx->url,
|
||||
&ctx->file, &ctx->redirected,
|
||||
ctx->referer, &ctx->dt,
|
||||
false, ctx->i, true, NULL);
|
||||
ctx->terminated = 1;
|
||||
sem_post (ctx->retr_sem);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Retrieve a part of the web beginning with START_URL. This used to
|
||||
be called "recursive retrieval", because the old function was
|
||||
@@ -212,6 +218,21 @@ uerr_t
|
||||
retrieve_tree (struct url *start_url_parsed, struct iri *pi)
|
||||
{
|
||||
uerr_t status = RETROK;
|
||||
struct s_thread_ctx *thread_ctx;
|
||||
char *next_url = NULL, *next_referer;
|
||||
int next_depth;
|
||||
bool next_html_allowed, next_css_allowed;
|
||||
struct iri *next_i = NULL;
|
||||
|
||||
#ifdef ENABLE_THREADS
|
||||
const int N_THREADS = opt.jobs > 0 ? opt.jobs : 1;
|
||||
sem_t retr_sem;
|
||||
#else
|
||||
const int N_THREADS = 1;
|
||||
void *retr_sem;
|
||||
#endif
|
||||
|
||||
int free_threads = N_THREADS;
|
||||
|
||||
/* The queue of URLs we need to load. */
|
||||
struct url_queue *queue;
|
||||
@@ -234,6 +255,11 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
|
||||
set_uri_encoding (i, opt.locale, true);
|
||||
#undef COPYSTR
|
||||
|
||||
thread_ctx = calloc (N_THREADS, sizeof *thread_ctx);
|
||||
|
||||
/* FIXME: CHECK FOR ERRORS. */
|
||||
SEM_INIT (&retr_sem, 0, 0);
|
||||
|
||||
queue = url_queue_new ();
|
||||
blacklist = make_string_hash_table (0);
|
||||
|
||||
@@ -241,16 +267,19 @@ 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);
|
||||
blacklist_add (blacklist, start_url_parsed->url);
|
||||
string_set_add (blacklist, start_url_parsed->url);
|
||||
|
||||
while (1)
|
||||
{
|
||||
bool descend = false;
|
||||
char *url, *referer, *file = NULL;
|
||||
int depth;
|
||||
bool html_allowed, css_allowed;
|
||||
char *file = NULL;
|
||||
bool is_css = false;
|
||||
bool dash_p_leaf_HTML = false;
|
||||
char *url = NULL, *referer;
|
||||
int depth;
|
||||
bool html_allowed, css_allowed;
|
||||
bool dequed = false;
|
||||
int index = 0;
|
||||
|
||||
if (opt.quota && total_downloaded_bytes > opt.quota)
|
||||
break;
|
||||
@@ -259,10 +288,20 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
|
||||
|
||||
/* Get the next URL from the queue... */
|
||||
|
||||
if (!url_dequeue (queue, (struct iri **) &i,
|
||||
(const char **)&url, (const char **)&referer,
|
||||
&depth, &html_allowed, &css_allowed))
|
||||
break;
|
||||
if (next_url == NULL)
|
||||
{
|
||||
if (url_dequeue (queue, (struct iri **) &next_i,
|
||||
(const char **)&next_url, (const char **)&next_referer,
|
||||
&next_depth, &next_html_allowed, &next_css_allowed))
|
||||
dequed = true;
|
||||
}
|
||||
|
||||
i = next_i;
|
||||
url = next_url;
|
||||
referer = next_referer;
|
||||
depth = next_depth;
|
||||
html_allowed = next_html_allowed;
|
||||
css_allowed = next_css_allowed;
|
||||
|
||||
/* ...and download it. Note that this download is in most cases
|
||||
unconditional, as download_child_p already makes sure a file
|
||||
@@ -272,7 +311,7 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
|
||||
and again under URL2, but at a different (possibly smaller)
|
||||
depth, we want the URL's children to be taken into account
|
||||
the second time. */
|
||||
if (dl_url_file_map && hash_table_contains (dl_url_file_map, url))
|
||||
if (dequed && url && dl_url_file_map && hash_table_contains (dl_url_file_map, url))
|
||||
{
|
||||
bool is_css_bool;
|
||||
|
||||
@@ -294,15 +333,110 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
|
||||
}
|
||||
else
|
||||
{
|
||||
int dt = 0, url_err;
|
||||
char *redirected = NULL;
|
||||
struct url *url_parsed = url_parse (url, &url_err, i, true);
|
||||
int j;
|
||||
retry:
|
||||
if (! url)
|
||||
{
|
||||
int used = 0;
|
||||
for (j = 0; j < N_THREADS; j++)
|
||||
{
|
||||
if (thread_ctx[j].used)
|
||||
{
|
||||
used = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
status = retrieve_url (url_parsed, url, &file, &redirected, referer,
|
||||
&dt, false, i, true);
|
||||
if (! used)
|
||||
break;
|
||||
}
|
||||
|
||||
if (url && free_threads)
|
||||
{
|
||||
int err;
|
||||
for (j = 0; j < N_THREADS; j++)
|
||||
if (! thread_ctx[j].used)
|
||||
{
|
||||
index = j;
|
||||
free_threads--;
|
||||
thread_ctx[j].used = 1;
|
||||
thread_ctx[j].terminated = 0;
|
||||
break;
|
||||
}
|
||||
assert (j < N_THREADS);
|
||||
|
||||
thread_ctx[index].file = file;
|
||||
thread_ctx[index].referer = referer;
|
||||
thread_ctx[index].dt = 0;
|
||||
thread_ctx[index].i = i;
|
||||
thread_ctx[index].redirected = NULL;
|
||||
thread_ctx[index].range = NULL;
|
||||
thread_ctx[index].url = url;
|
||||
thread_ctx[index].retr_sem = &retr_sem;
|
||||
thread_ctx[index].url_parsed = url_parse (thread_ctx[index].url,
|
||||
&thread_ctx[index].url_err,
|
||||
i, true);
|
||||
|
||||
#ifdef ENABLE_THREADS
|
||||
err = pthread_create (&thread_ctx[index].thread, NULL,
|
||||
start_retrieve_url, &thread_ctx[index]);
|
||||
#else
|
||||
thread_ctx[index].status = retrieve_url (thread_ctx[index].url_parsed,
|
||||
thread_ctx[index].url,
|
||||
&thread_ctx[index].file,
|
||||
&thread_ctx[index].redirected,
|
||||
thread_ctx[index].referer,
|
||||
&thread_ctx[index].dt,
|
||||
false, i, true,
|
||||
NULL);
|
||||
thread_ctx[index].used = 1;
|
||||
thread_ctx[index].terminated = 1;
|
||||
err = 0;
|
||||
#endif
|
||||
|
||||
if (err == 0)
|
||||
next_url = NULL;
|
||||
else
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, "pthread_create: %s\n", strerror (errno));
|
||||
url_free (thread_ctx[index].url_parsed);
|
||||
thread_ctx[index].used = 0;
|
||||
free_threads++;
|
||||
return THREADS_ERR;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
index = -1;
|
||||
for (j = 0; j < N_THREADS; j++)
|
||||
if (thread_ctx[j].used && thread_ctx[j].terminated)
|
||||
{
|
||||
index = j;
|
||||
thread_ctx[j].used = 0;
|
||||
THREAD_JOIN (thread_ctx[j].thread, NULL);
|
||||
free_threads++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
int ret;
|
||||
do
|
||||
ret = SEM_WAIT (&retr_sem);
|
||||
while (ret < 0 && errno == EINTR);
|
||||
if (ret < 0)
|
||||
return SEM_ERR;
|
||||
|
||||
goto retry;
|
||||
}
|
||||
|
||||
file = thread_ctx[index].file;
|
||||
referer = thread_ctx[index].referer;
|
||||
i = thread_ctx[index].i;
|
||||
url = thread_ctx[index].url;
|
||||
|
||||
if (html_allowed && file && status == RETROK
|
||||
&& (dt & RETROKF) && (dt & TEXTHTML))
|
||||
&& (thread_ctx[index].dt & RETROKF) && (thread_ctx[index].dt & TEXTHTML))
|
||||
{
|
||||
descend = true;
|
||||
is_css = false;
|
||||
@@ -312,38 +446,40 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
|
||||
lots of web servers serve css with an incorrect content type
|
||||
*/
|
||||
if (file && status == RETROK
|
||||
&& (dt & RETROKF) &&
|
||||
((dt & TEXTCSS) || css_allowed))
|
||||
&& (thread_ctx[index].dt & RETROKF) &&
|
||||
((thread_ctx[index].dt & TEXTCSS) || css_allowed)
|
||||
)
|
||||
{
|
||||
descend = true;
|
||||
is_css = true;
|
||||
}
|
||||
|
||||
if (redirected)
|
||||
if (thread_ctx[index].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,
|
||||
if (!descend_redirect_p (thread_ctx[index].redirected,
|
||||
thread_ctx[index].url_parsed, depth,
|
||||
start_url_parsed, blacklist, i))
|
||||
descend = false;
|
||||
else
|
||||
/* Make sure that the old pre-redirect form gets
|
||||
blacklisted. */
|
||||
blacklist_add (blacklist, url);
|
||||
string_set_add (blacklist, url);
|
||||
}
|
||||
|
||||
xfree (url);
|
||||
url = redirected;
|
||||
xfree (thread_ctx[index].url);
|
||||
url = thread_ctx[index].redirected;
|
||||
}
|
||||
else
|
||||
{
|
||||
xfree (url);
|
||||
url = xstrdup (url_parsed->url);
|
||||
xfree (thread_ctx[index].url);
|
||||
url = xstrdup (thread_ctx[index].url_parsed->url);
|
||||
}
|
||||
url_free (url_parsed);
|
||||
url_free(thread_ctx[index].url_parsed);
|
||||
}
|
||||
|
||||
if (opt.spider)
|
||||
@@ -425,7 +561,7 @@ 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. */
|
||||
blacklist_add (blacklist, child->url->url);
|
||||
string_set_add (blacklist, child->url->url);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,11 +595,12 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
register_delete_file (file);
|
||||
}
|
||||
|
||||
#ifndef ENABLE_THREADS
|
||||
xfree (url);
|
||||
xfree (referer);
|
||||
xfree (file);
|
||||
xfree_null (referer);
|
||||
xfree_null (file);
|
||||
iri_free (i);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If anything is left of the queue due to a premature exit, free it
|
||||
@@ -478,7 +615,7 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
|
||||
{
|
||||
iri_free (d6);
|
||||
xfree (d1);
|
||||
xfree (d2);
|
||||
xfree_null (d2);
|
||||
}
|
||||
}
|
||||
url_queue_delete (queue);
|
||||
@@ -512,7 +649,7 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
|
||||
|
||||
DEBUGP (("Deciding whether to enqueue \"%s\".\n", url));
|
||||
|
||||
if (blacklist_contains (blacklist, url))
|
||||
if (string_set_contains (blacklist, url))
|
||||
{
|
||||
if (opt.spider)
|
||||
{
|
||||
@@ -691,7 +828,7 @@ 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));
|
||||
blacklist_add (blacklist, url);
|
||||
string_set_add (blacklist, url);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -733,14 +870,12 @@ descend_redirect_p (const char *redirected, struct url *orig_parsed, int depth,
|
||||
success = download_child_p (upos, orig_parsed, depth,
|
||||
start_url_parsed, blacklist, iri);
|
||||
|
||||
if (success)
|
||||
blacklist_add (blacklist, upos->url->url);
|
||||
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 success;
|
||||
}
|
||||
|
||||
|
||||
20
src/res.c
20
src/res.c
@@ -81,7 +81,6 @@ as that of the covered work. */
|
||||
#include "url.h"
|
||||
#include "retr.h"
|
||||
#include "res.h"
|
||||
#include "c-strcase.h"
|
||||
|
||||
#ifdef TESTING
|
||||
#include "test.h"
|
||||
@@ -98,7 +97,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
|
||||
@@ -404,10 +403,10 @@ free_specs (struct robot_specs *specs)
|
||||
int i;
|
||||
for (i = 0; i < specs->count; i++)
|
||||
xfree (specs->paths[i].path);
|
||||
xfree (specs->paths);
|
||||
xfree_null (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
|
||||
@@ -472,7 +471,7 @@ res_match_path (const struct robot_specs *specs, const char *path)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Registering the specs. */
|
||||
|
||||
static struct hash_table *registered_specs;
|
||||
@@ -522,7 +521,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"
|
||||
@@ -564,7 +563,7 @@ res_retrieve_file (const char *url, char **file, struct iri *iri)
|
||||
else
|
||||
{
|
||||
err = retrieve_url (url_parsed, robots_url, file, NULL, NULL, NULL,
|
||||
false, i, false);
|
||||
false, i, false, NULL);
|
||||
url_free(url_parsed);
|
||||
}
|
||||
|
||||
@@ -579,10 +578,11 @@ 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 *
|
||||
|
||||
422
src/retr.c
422
src/retr.c
@@ -37,10 +37,22 @@ as that of the covered work. */
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#ifdef ENABLE_THREADS
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
#ifdef ENABLE_METALINK
|
||||
#include <metalink/metalink_parser.h>
|
||||
#include <metalink/metalink_types.h>
|
||||
#ifdef VMS
|
||||
# include <unixio.h> /* For delete(). */
|
||||
#endif
|
||||
|
||||
#include "metalink.h"
|
||||
#endif
|
||||
#ifdef ENABLE_THREADS
|
||||
#include "multi.h"
|
||||
#endif
|
||||
#include "exits.h"
|
||||
#include "utils.h"
|
||||
#include "retr.h"
|
||||
@@ -57,6 +69,17 @@ as that of the covered work. */
|
||||
#include "html-url.h"
|
||||
#include "iri.h"
|
||||
|
||||
#ifdef ENABLE_METALINK
|
||||
static pthread_mutex_t pconn_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
#define IS_IO_ERROR(status) status == FOPENERR || status == WRITEFAILED || \
|
||||
status == UNLINKERR || status == FWRITEERR || status == FOPEN_EXCL_ERR
|
||||
|
||||
#define PCONN_LOCK() pthread_mutex_lock (&pconn_mutex)
|
||||
|
||||
#define PCONN_UNLOCK() pthread_mutex_unlock (&pconn_mutex)
|
||||
#endif
|
||||
|
||||
/* Total size of downloaded files. Used to enforce quota. */
|
||||
SUM_SIZE_INT total_downloaded_bytes;
|
||||
|
||||
@@ -70,7 +93,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,6 +159,10 @@ 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.
|
||||
@@ -223,7 +250,6 @@ write_data (FILE *out, FILE *out2, const char *buf, int bufsize,
|
||||
|
||||
int
|
||||
fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread, wgint startpos,
|
||||
|
||||
wgint *qtyread, wgint *qtywritten, double *elapsed, int flags,
|
||||
FILE *out2)
|
||||
{
|
||||
@@ -261,16 +287,11 @@ 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;
|
||||
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 = progress_create (downloaded_filename, start, start + toread);
|
||||
progress_interactive = progress_interactive_p (progress);
|
||||
}
|
||||
|
||||
@@ -379,10 +400,8 @@ fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread,
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
int write_res;
|
||||
|
||||
sum_read += ret;
|
||||
write_res = write_data (out, out2, dlbuf, ret, &skip, &sum_written);
|
||||
int write_res = write_data (out, out2, dlbuf, ret, &skip, &sum_written);
|
||||
if (write_res < 0)
|
||||
{
|
||||
ret = (write_res == -3) ? -3 : -2;
|
||||
@@ -437,11 +456,11 @@ fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread,
|
||||
if (qtywritten)
|
||||
*qtywritten += sum_written;
|
||||
|
||||
xfree (dlbuf);
|
||||
free (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
|
||||
@@ -546,7 +565,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 (hunk);
|
||||
xfree_null (hunk);
|
||||
return NULL;
|
||||
}
|
||||
tail += rdlen;
|
||||
@@ -618,7 +637,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. */
|
||||
|
||||
@@ -682,7 +701,7 @@ calc_rate (wgint bytes, double secs, int *units)
|
||||
|
||||
return dlrate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define SUSPEND_METHOD do { \
|
||||
method_suspended = true; \
|
||||
@@ -715,7 +734,7 @@ static char *getproxy (struct url *);
|
||||
uerr_t
|
||||
retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
|
||||
char **newloc, const char *refurl, int *dt, bool recursive,
|
||||
struct iri *iri, bool register_status)
|
||||
struct iri *iri, bool register_status, struct range *segment_range)
|
||||
{
|
||||
uerr_t result;
|
||||
char *url;
|
||||
@@ -742,8 +761,13 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
|
||||
url = xstrdup (origurl);
|
||||
if (newloc)
|
||||
*newloc = NULL;
|
||||
|
||||
#ifndef ENABLE_METALINK
|
||||
/* Note that, each and every call to retrieve_url(), except the ones made by
|
||||
functions relevant to metalink support, the value of *file is NULL. */
|
||||
if (file)
|
||||
*file = NULL;
|
||||
#endif
|
||||
|
||||
if (!refurl)
|
||||
refurl = opt.referer;
|
||||
@@ -753,7 +777,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
|
||||
|
||||
result = NOCONERROR;
|
||||
mynewloc = NULL;
|
||||
local_file = NULL;
|
||||
local_file = *file;
|
||||
proxy_url = NULL;
|
||||
|
||||
proxy = getproxy (u);
|
||||
@@ -764,7 +788,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, pi, true);
|
||||
proxy_url = url_parse (proxy, &up_error_code, NULL, true);
|
||||
if (!proxy_url)
|
||||
{
|
||||
char *error = url_error (proxy, up_error_code);
|
||||
@@ -785,8 +809,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
|
||||
result = PROXERR;
|
||||
goto bail;
|
||||
}
|
||||
iri_free(pi);
|
||||
xfree (proxy);
|
||||
free (proxy);
|
||||
}
|
||||
|
||||
if (u->scheme == SCHEME_HTTP
|
||||
@@ -796,7 +819,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
|
||||
|| (proxy_url && proxy_url->scheme == SCHEME_HTTP))
|
||||
{
|
||||
result = http_loop (u, orig_parsed, &mynewloc, &local_file, refurl, dt,
|
||||
proxy_url, iri);
|
||||
proxy_url, iri, segment_range);
|
||||
}
|
||||
else if (u->scheme == SCHEME_FTP)
|
||||
{
|
||||
@@ -807,7 +830,7 @@ 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, &local_file, dt, proxy_url, recursive, glob, segment_range);
|
||||
recursive = oldrec;
|
||||
|
||||
/* There is a possibility of having HTTP being redirected to
|
||||
@@ -835,7 +858,8 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
|
||||
|
||||
assert (mynewloc != NULL);
|
||||
|
||||
xfree (local_file);
|
||||
if (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
|
||||
@@ -849,7 +873,8 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
|
||||
the content encoding. */
|
||||
iri->utf8_encode = opt.enable_iri;
|
||||
set_content_encoding (iri, NULL);
|
||||
xfree (iri->orig_url);
|
||||
xfree_null (iri->orig_url);
|
||||
iri->orig_url = NULL;
|
||||
|
||||
/* Now, see if this new location makes sense. */
|
||||
newloc_parsed = url_parse (mynewloc, &up_error_code, iri, true);
|
||||
@@ -915,10 +940,6 @@ 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)
|
||||
@@ -932,7 +953,6 @@ 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;
|
||||
@@ -949,16 +969,16 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
|
||||
register_redirection (origurl, u->url);
|
||||
|
||||
if (*dt & TEXTHTML)
|
||||
register_html (local_file);
|
||||
register_html ("",local_file);
|
||||
|
||||
if (*dt & TEXTCSS)
|
||||
register_css (local_file);
|
||||
register_css ("",local_file);
|
||||
}
|
||||
|
||||
if (file)
|
||||
*file = local_file ? local_file : NULL;
|
||||
else
|
||||
xfree (local_file);
|
||||
xfree_null (local_file);
|
||||
|
||||
if (orig_parsed != u)
|
||||
{
|
||||
@@ -1026,7 +1046,7 @@ retrieve_from_file (const char *file, bool html, int *count)
|
||||
opt.base_href = xstrdup (url);
|
||||
|
||||
status = retrieve_url (url_parsed, url, &url_file, NULL, NULL, &dt,
|
||||
false, iri, true);
|
||||
false, iri, true, NULL);
|
||||
url_free (url_parsed);
|
||||
|
||||
if (!url_file || (status != RETROK))
|
||||
@@ -1042,78 +1062,310 @@ retrieve_from_file (const char *file, bool html, int *count)
|
||||
|
||||
/* Reset UTF-8 encode status */
|
||||
iri->utf8_encode = opt.enable_iri;
|
||||
xfree (iri->orig_url);
|
||||
xfree_null (iri->orig_url);
|
||||
iri->orig_url = NULL;
|
||||
|
||||
input_file = url_file;
|
||||
}
|
||||
else
|
||||
input_file = (char *) file;
|
||||
|
||||
url_list = (html ? get_urls_html (input_file, NULL, NULL, iri)
|
||||
: get_urls_file (input_file));
|
||||
#ifdef ENABLE_METALINK
|
||||
mlink *mlink = parse_metalink(input_file);
|
||||
|
||||
xfree (url_file);
|
||||
|
||||
for (cur_url = url_list; cur_url; cur_url = cur_url->next, ++*count)
|
||||
if(opt.metalink_file && mlink)
|
||||
{
|
||||
char *filename = NULL, *new_file = NULL, *proxy;
|
||||
int dt = 0;
|
||||
struct iri *tmpiri = iri_dup (iri);
|
||||
struct url *parsed_url = NULL;
|
||||
int i, j, r, ranges_covered, chunk_size, url_err, retries, ret, dt=0;
|
||||
pthread_t thread;
|
||||
sem_t retr_sem;
|
||||
uerr_t status;
|
||||
mlink_file* file;
|
||||
mlink_resource *resource;
|
||||
struct s_thread_ctx *thread_ctx;
|
||||
|
||||
if (cur_url->ignore_when_downloading)
|
||||
continue;
|
||||
/* Wget supports HTTP&FTP, and Metalink supports MD5, SHA1 & SHA-256. */
|
||||
elect_resources (mlink);
|
||||
elect_checksums (mlink);
|
||||
|
||||
if (opt.quota && total_downloaded_bytes > opt.quota)
|
||||
init_temp_files();
|
||||
init_ranges ();
|
||||
thread_ctx = malloc (opt.jobs * (sizeof *thread_ctx));
|
||||
|
||||
retries = 0;
|
||||
file = mlink->files;
|
||||
while (file)
|
||||
{
|
||||
status = QUOTEXC;
|
||||
break;
|
||||
memset (thread_ctx, '\0', opt.jobs * (sizeof *thread_ctx));
|
||||
|
||||
/* If chunk_size is too small, set it equal to MIN_CHUNK_SIZE. */
|
||||
chunk_size = (file->size) / opt.jobs;
|
||||
if(chunk_size < MIN_CHUNK_SIZE)
|
||||
chunk_size = MIN_CHUNK_SIZE;
|
||||
|
||||
j = fill_ranges_data (file->num_of_res, file->size, chunk_size);
|
||||
|
||||
/* If chunk_size was set to MIN_CHUNK_SIZE, opt.jobs should be corrected. */
|
||||
if (j < opt.jobs)
|
||||
opt.jobs = j;
|
||||
|
||||
name_temp_files ();
|
||||
|
||||
sem_init (&retr_sem, 0, 0);
|
||||
j = ranges_covered = 0;
|
||||
resource = file->resources;
|
||||
|
||||
/* Assign values to thread_ctx[] elements and spawn threads that will
|
||||
conduct the download. */
|
||||
for (r = 0; r < opt.jobs; ++r)
|
||||
{
|
||||
if (!resource)
|
||||
{
|
||||
j = 0;
|
||||
resource = file->resources;
|
||||
}
|
||||
|
||||
thread_ctx[r].referer = NULL;
|
||||
thread_ctx[r].redirected = NULL;
|
||||
thread_ctx[r].dt = dt;
|
||||
thread_ctx[r].i = iri;
|
||||
thread_ctx[r].url = resource->url;
|
||||
thread_ctx[r].retr_sem = &retr_sem;
|
||||
|
||||
ret = spawn_thread (thread_ctx, r, j);
|
||||
if (ret)
|
||||
{
|
||||
/* If thread creation is unsuccessful */
|
||||
char *error = url_error (thread_ctx[r].url, thread_ctx[r].url_err);
|
||||
logprintf (LOG_NOTQUIET, "%s: %s.\n", thread_ctx[r].url, error);
|
||||
xfree (error);
|
||||
free (thread_ctx);
|
||||
clean_range_res_data ();
|
||||
clean_ranges ();
|
||||
clean_temp_files ();
|
||||
return URLERROR;
|
||||
}
|
||||
++j;
|
||||
resource = resource->next;
|
||||
}
|
||||
|
||||
/* Until all the ranges are covered, collect threads. */
|
||||
while (ranges_covered < opt.jobs)
|
||||
{
|
||||
r = collect_thread (&retr_sem, thread_ctx);
|
||||
++ranges_covered;
|
||||
|
||||
status = thread_ctx[r].status;
|
||||
|
||||
/* Check return status of thread for errors. */
|
||||
if (IS_IO_ERROR (status))
|
||||
{
|
||||
/* The error is of type WGET_EXIT_IO_FAIL given in exits.c.
|
||||
No fallbacking is needed for this type of error. */
|
||||
inform_exit_status (status);
|
||||
break;
|
||||
}
|
||||
else if(status != RETROK)
|
||||
{
|
||||
int error_severity;
|
||||
PCONN_LOCK ();
|
||||
|
||||
/* Pick the least severe error.*/
|
||||
error_severity = get_exit_status();
|
||||
inform_exit_status ((thread_ctx[r].range)->status_least_severe);
|
||||
if(get_exit_status() != error_severity)
|
||||
(thread_ctx[r].range)->status_least_severe = status;
|
||||
|
||||
PCONN_UNLOCK ();
|
||||
|
||||
/* Look for resource from which downloading this range is not
|
||||
tried. */
|
||||
j = 0;
|
||||
resource = file->resources;
|
||||
while (j < file->num_of_res)
|
||||
{
|
||||
if (!((thread_ctx[r].range)->resources)[j])
|
||||
break;
|
||||
++j;
|
||||
resource = resource -> next;
|
||||
}
|
||||
/* If there is such a resource, then update the range values
|
||||
to try that not-tried resource and spawn thread.
|
||||
If all the resources are exhausted, stop collecting the
|
||||
threads, as the download failed. */
|
||||
if (j < file->num_of_res)
|
||||
{
|
||||
if ((thread_ctx[r].range)->bytes_covered)
|
||||
{
|
||||
thread_ctx[r].url = resource->url;
|
||||
(thread_ctx[r].range)->first_byte =
|
||||
(thread_ctx[r].range)->bytes_covered;
|
||||
(thread_ctx[r].range)->bytes_covered = 0;
|
||||
}
|
||||
--ranges_covered;
|
||||
ret = spawn_thread (thread_ctx, r, j);
|
||||
if (ret)
|
||||
{
|
||||
/* If thread creation is unsuccessful */
|
||||
char *error = url_error (thread_ctx[r].url, thread_ctx[r].url_err);
|
||||
logprintf (LOG_NOTQUIET, "%s: %s.\n", thread_ctx[r].url, error);
|
||||
xfree (error);
|
||||
free (thread_ctx);
|
||||
clean_range_res_data ();
|
||||
clean_ranges ();
|
||||
clean_temp_files ();
|
||||
return URLERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sem_destroy(&retr_sem);
|
||||
|
||||
/* Check the download status. If conditions are suitable, retry. */
|
||||
if (status != RETROK)
|
||||
{
|
||||
logprintf (LOG_VERBOSE, _("Downloading %s failed. Chunk %d could "
|
||||
"not be downloaded from any of the "
|
||||
"URLs listed in metalink file.\n"),
|
||||
file->name, r);
|
||||
|
||||
/* Failed downloads should only be retried if the error causing
|
||||
the failure is not an IO error. */
|
||||
if (!(IS_IO_ERROR((thread_ctx[r].range)->status_least_severe)))
|
||||
{
|
||||
if(retries < opt.n_retries)
|
||||
{
|
||||
logprintf (LOG_VERBOSE,
|
||||
_("Retrying to download(%s). (TRY #%d)\n"),
|
||||
file->name, ++retries + 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *file_path;
|
||||
int res;
|
||||
/* Form the actual file to be downloaded and verify hash. */
|
||||
file_path = malloc((opt.dir_prefix ? strlen(opt.dir_prefix) : 0)
|
||||
+ strlen(file->name) + (sizeof "/"));
|
||||
if(opt.dir_prefix)
|
||||
sprintf(file_path, "%s/%s", opt.dir_prefix, file->name);
|
||||
else
|
||||
sprintf(file_path, "%s", file->name);
|
||||
mkalldirs(file_path);
|
||||
merge_temp_files(file_path);
|
||||
res = verify_file_hash(file_path, file->checksums);
|
||||
free(file_path);
|
||||
if(!res)
|
||||
{
|
||||
++*count;
|
||||
logprintf (LOG_VERBOSE, _("Verifying(%s) succeeded.\n"),
|
||||
file->name);
|
||||
}
|
||||
else if(res < 0)
|
||||
{
|
||||
logprintf (LOG_VERBOSE, _("Verifying(%s) failed.\n"),
|
||||
file->name);
|
||||
if(retries < opt.n_retries)
|
||||
{
|
||||
logprintf (LOG_VERBOSE,
|
||||
_("Retrying to download(%s). (TRY #%d)\n"),
|
||||
file->name, ++retries + 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete_temp_files();
|
||||
|
||||
clean_range_res_data();
|
||||
if (opt.quota && total_downloaded_bytes > opt.quota)
|
||||
{
|
||||
status = QUOTEXC;
|
||||
break;
|
||||
}
|
||||
file = file->next;
|
||||
}
|
||||
|
||||
parsed_url = url_parse (cur_url->url->url, NULL, tmpiri, true);
|
||||
free(thread_ctx);
|
||||
clean_ranges ();
|
||||
clean_temp_files ();
|
||||
delete_mlink(mlink);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
url_list = (html ? get_urls_html (input_file, NULL, NULL, iri)
|
||||
: get_urls_file (input_file));
|
||||
|
||||
proxy = getproxy (cur_url->url);
|
||||
if ((opt.recursive || opt.page_requisites)
|
||||
&& (cur_url->url->scheme != SCHEME_FTP || proxy))
|
||||
xfree_null (url_file);
|
||||
|
||||
for (cur_url = url_list; cur_url; cur_url = cur_url->next, ++*count)
|
||||
{
|
||||
int old_follow_ftp = opt.follow_ftp;
|
||||
char *filename = NULL, *new_file = NULL;
|
||||
int dt;
|
||||
struct iri *tmpiri = iri_dup (iri);
|
||||
struct url *parsed_url = NULL;
|
||||
|
||||
/* Turn opt.follow_ftp on in case of recursive FTP retrieval */
|
||||
if (cur_url->url->scheme == SCHEME_FTP)
|
||||
opt.follow_ftp = 1;
|
||||
if (cur_url->ignore_when_downloading)
|
||||
continue;
|
||||
|
||||
status = retrieve_tree (parsed_url ? parsed_url : cur_url->url,
|
||||
if (opt.quota && total_downloaded_bytes > opt.quota)
|
||||
{
|
||||
status = QUOTEXC;
|
||||
break;
|
||||
}
|
||||
|
||||
parsed_url = url_parse (cur_url->url->url, NULL, tmpiri, true);
|
||||
|
||||
char *proxy = getproxy (cur_url->url);
|
||||
if ((opt.recursive || opt.page_requisites)
|
||||
&& (cur_url->url->scheme != SCHEME_FTP || 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)
|
||||
opt.follow_ftp = 1;
|
||||
|
||||
status = retrieve_tree (parsed_url ? parsed_url : cur_url->url,
|
||||
tmpiri);
|
||||
|
||||
opt.follow_ftp = old_follow_ftp;
|
||||
}
|
||||
else
|
||||
status = retrieve_url (parsed_url ? parsed_url : cur_url->url,
|
||||
cur_url->url->url, &filename,
|
||||
&new_file, NULL, &dt, opt.recursive, tmpiri,
|
||||
true);
|
||||
xfree (proxy);
|
||||
opt.follow_ftp = old_follow_ftp;
|
||||
}
|
||||
else
|
||||
status = retrieve_url (parsed_url ? parsed_url : cur_url->url,
|
||||
cur_url->url->url, &filename,
|
||||
&new_file, NULL, &dt, opt.recursive, tmpiri,
|
||||
true, NULL);
|
||||
free(proxy);
|
||||
|
||||
if (parsed_url)
|
||||
url_free (parsed_url);
|
||||
if (parsed_url)
|
||||
url_free (parsed_url);
|
||||
|
||||
if (filename && opt.delete_after && file_exists_p (filename))
|
||||
{
|
||||
DEBUGP (("\
|
||||
if (filename && opt.delete_after && file_exists_p (filename))
|
||||
{
|
||||
DEBUGP (("\
|
||||
Removing file due to --delete-after in retrieve_from_file():\n"));
|
||||
logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
|
||||
if (unlink (filename))
|
||||
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
|
||||
dt &= ~RETROKF;
|
||||
logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
|
||||
if (unlink (filename))
|
||||
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
|
||||
dt &= ~RETROKF;
|
||||
}
|
||||
|
||||
xfree_null (new_file);
|
||||
xfree_null (filename);
|
||||
iri_free (tmpiri);
|
||||
}
|
||||
|
||||
xfree (new_file);
|
||||
xfree (filename);
|
||||
iri_free (tmpiri);
|
||||
/* Free the linked list of URL-s. */
|
||||
free_urlpos (url_list);
|
||||
#ifdef ENABLE_METALINK
|
||||
}
|
||||
|
||||
/* Free the linked list of URL-s. */
|
||||
free_urlpos (url_list);
|
||||
#endif
|
||||
|
||||
iri_free (iri);
|
||||
|
||||
@@ -1184,7 +1436,7 @@ free_urlpos (struct urlpos *l)
|
||||
struct urlpos *next = l->next;
|
||||
if (l->url)
|
||||
url_free (l->url);
|
||||
xfree (l->local_name);
|
||||
xfree_null (l->local_name);
|
||||
xfree (l);
|
||||
l = next;
|
||||
}
|
||||
@@ -1285,13 +1537,11 @@ bool
|
||||
url_uses_proxy (struct url * u)
|
||||
{
|
||||
bool ret;
|
||||
char *proxy;
|
||||
|
||||
if (!u)
|
||||
return false;
|
||||
proxy = getproxy (u);
|
||||
char *proxy = getproxy (u);
|
||||
ret = proxy != NULL;
|
||||
xfree (proxy);
|
||||
free(proxy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@ 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;
|
||||
@@ -60,7 +58,7 @@ char *fd_read_hunk (int, hunk_terminator_t, long, long);
|
||||
char *fd_read_line (int);
|
||||
|
||||
uerr_t retrieve_url (struct url *, const char *, char **, char **,
|
||||
const char *, int *, bool, struct iri *, bool);
|
||||
const char *, int *, bool, struct iri *, bool, struct range *);
|
||||
uerr_t retrieve_from_file (const char *, bool, int *);
|
||||
|
||||
const char *retr_rate (wgint, double);
|
||||
|
||||
@@ -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)
|
||||
|
||||
24
src/test.c
24
src/test.c
@@ -41,22 +41,22 @@ as that of the covered work. */
|
||||
#error "TESTING not set!!!"
|
||||
#endif
|
||||
|
||||
const char *test_parse_content_disposition(void);
|
||||
const char *test_subdir_p(void);
|
||||
const char *test_dir_matches_p(void);
|
||||
const char *test_commands_sorted(void);
|
||||
const char *test_cmd_spec_restrict_file_names(void);
|
||||
const char *test_path_simplify (void);
|
||||
const char *test_append_uri_pathel(void);
|
||||
const char *test_are_urls_equal(void);
|
||||
const char *test_is_robots_txt_url(void);
|
||||
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 const char *
|
||||
all_tests(void)
|
||||
all_tests()
|
||||
{
|
||||
mu_run_test (test_parse_content_disposition);
|
||||
mu_run_test (test_subdir_p);
|
||||
@@ -71,10 +71,10 @@ all_tests(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *program_name; /* Needed by lib/error.c. */
|
||||
char *program_name; /* Needed by lib/error.c. */
|
||||
|
||||
int
|
||||
main (int argc _GL_UNUSED, const char *argv[])
|
||||
main (int argc _GL_UNUSED, char *argv[])
|
||||
{
|
||||
const char *result;
|
||||
|
||||
|
||||
101
src/url.c
101
src/url.c
@@ -41,7 +41,6 @@ as that of the covered work. */
|
||||
#include "utils.h"
|
||||
#include "url.h"
|
||||
#include "host.h" /* for is_valid_ipv6_address */
|
||||
#include "c-strcase.h"
|
||||
|
||||
#ifdef __VMS
|
||||
#include "vms.h"
|
||||
@@ -86,7 +85,7 @@ static struct scheme_data supported_schemes[] =
|
||||
/* Forward declarations: */
|
||||
|
||||
static bool path_simplify (enum url_scheme, char *);
|
||||
|
||||
|
||||
/* Support for escaping and unescaping of URL strings. */
|
||||
|
||||
/* Table of "reserved" and "unsafe" characters. Those terms are
|
||||
@@ -273,7 +272,7 @@ url_escape_allow_passthrough (const char *s)
|
||||
{
|
||||
return url_escape_1 (s, urlchr_unsafe, true);
|
||||
}
|
||||
|
||||
|
||||
/* Decide whether the char at position P needs to be encoded. (It is
|
||||
not enough to pass a single char *P because the function may need
|
||||
to inspect the surrounding context.)
|
||||
@@ -419,7 +418,7 @@ reencode_escapes (const char *s)
|
||||
assert (p2 - newstr == newlen);
|
||||
return newstr;
|
||||
}
|
||||
|
||||
|
||||
/* Returns the scheme type if the scheme is supported, or
|
||||
SCHEME_INVALID if not. */
|
||||
|
||||
@@ -575,8 +574,8 @@ rewrite_shorthand_url (const char *url)
|
||||
goto http;
|
||||
|
||||
/* Turn "foo.bar.com:path" to "ftp://foo.bar.com/path". */
|
||||
if ((ret = aprintf ("ftp://%s", url)) != NULL)
|
||||
ret[6 + (p - url)] = '/';
|
||||
ret = aprintf ("ftp://%s", url);
|
||||
ret[6 + (p - url)] = '/';
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -586,7 +585,7 @@ rewrite_shorthand_url (const char *url)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void split_path (const char *, char **, char **);
|
||||
|
||||
/* Like strpbrk, with the exception that it returns the pointer to the
|
||||
@@ -619,12 +618,12 @@ lowercase_str (char *str)
|
||||
}
|
||||
|
||||
static const char *
|
||||
init_seps (enum url_scheme scheme)
|
||||
init_seps (enum url_scheme scheme, char *seps)
|
||||
{
|
||||
static char seps[8] = ":/";
|
||||
char *p = seps + 2;
|
||||
int flags = supported_schemes[scheme].flags;
|
||||
|
||||
strcpy (seps, ":/");
|
||||
if (flags & scm_has_params)
|
||||
*p++ = ';';
|
||||
if (flags & scm_has_query)
|
||||
@@ -677,11 +676,13 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
|
||||
const char *params_b, *params_e;
|
||||
const char *query_b, *query_e;
|
||||
const char *fragment_b, *fragment_e;
|
||||
char seps_b[8];
|
||||
|
||||
int port;
|
||||
char *user = NULL, *passwd = NULL;
|
||||
|
||||
const char *url_encoded = NULL;
|
||||
char *new_url = NULL;
|
||||
|
||||
int error_code;
|
||||
|
||||
@@ -695,30 +696,29 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
|
||||
goto error;
|
||||
}
|
||||
|
||||
url_encoded = url;
|
||||
|
||||
if (iri && iri->utf8_encode)
|
||||
{
|
||||
char *new_url = NULL;
|
||||
|
||||
iri->utf8_encode = remote_to_utf8 (iri, iri->orig_url ? iri->orig_url : url, (const char **) &new_url);
|
||||
if (!iri->utf8_encode)
|
||||
new_url = NULL;
|
||||
else
|
||||
{
|
||||
xfree (iri->orig_url);
|
||||
iri->orig_url = xstrdup (url);
|
||||
url_encoded = reencode_escapes (new_url);
|
||||
if (url_encoded != new_url)
|
||||
xfree (new_url);
|
||||
percent_encode = false;
|
||||
percent_encode = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX XXX Could that change introduce (security) bugs ??? XXX XXX*/
|
||||
if (percent_encode)
|
||||
url_encoded = reencode_escapes (url);
|
||||
url_encoded = reencode_escapes (new_url ? new_url : url);
|
||||
else
|
||||
url_encoded = new_url ? new_url : url;
|
||||
|
||||
p = url_encoded;
|
||||
|
||||
if (new_url && url_encoded != new_url)
|
||||
xfree (new_url);
|
||||
|
||||
p += strlen (supported_schemes[scheme].leading_string);
|
||||
uname_b = p;
|
||||
p = url_skip_credentials (p);
|
||||
@@ -740,7 +740,7 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
|
||||
/* Initialize separators for optional parts of URL, depending on the
|
||||
scheme. For example, FTP has params, and HTTP and HTTPS have
|
||||
query string and fragment. */
|
||||
seps = init_seps (scheme);
|
||||
seps = init_seps (scheme, seps_b);
|
||||
|
||||
host_b = p;
|
||||
|
||||
@@ -897,7 +897,6 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
|
||||
{
|
||||
xfree (u->host);
|
||||
u->host = new;
|
||||
u->idn_allocated = true;
|
||||
host_modified = true;
|
||||
}
|
||||
}
|
||||
@@ -918,7 +917,7 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
|
||||
u->url = url_string (u, URL_AUTH_SHOW);
|
||||
|
||||
if (url_encoded != url)
|
||||
xfree (url_encoded);
|
||||
xfree ((char *) url_encoded);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -933,7 +932,7 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
|
||||
error:
|
||||
/* Cleanup in case of error: */
|
||||
if (url_encoded && url_encoded != url)
|
||||
xfree (url_encoded);
|
||||
xfree ((char *) url_encoded);
|
||||
|
||||
/* Transmit the error code to the caller, if the caller wants to
|
||||
know. */
|
||||
@@ -958,7 +957,7 @@ url_error (const char *url, int error_code)
|
||||
|
||||
if ((p = strchr (scheme, ':')))
|
||||
*p = '\0';
|
||||
if (!c_strcasecmp (scheme, "https"))
|
||||
if (!strcasecmp (scheme, "https"))
|
||||
error = aprintf (_("HTTPS support not compiled in"));
|
||||
else
|
||||
error = aprintf (_(parse_errors[error_code]), quote (scheme));
|
||||
@@ -1174,31 +1173,22 @@ url_set_file (struct url *url, const char *newfile)
|
||||
void
|
||||
url_free (struct url *url)
|
||||
{
|
||||
if (url)
|
||||
{
|
||||
if (url->idn_allocated) {
|
||||
idn_free (url->host); /* A dummy if !defined(ENABLE_IRI) */
|
||||
url->host = NULL;
|
||||
}
|
||||
else
|
||||
xfree (url->host);
|
||||
xfree (url->host);
|
||||
xfree (url->path);
|
||||
xfree (url->url);
|
||||
|
||||
xfree (url->path);
|
||||
xfree (url->url);
|
||||
xfree_null (url->params);
|
||||
xfree_null (url->query);
|
||||
xfree_null (url->fragment);
|
||||
xfree_null (url->user);
|
||||
xfree_null (url->passwd);
|
||||
|
||||
xfree (url->params);
|
||||
xfree (url->query);
|
||||
xfree (url->fragment);
|
||||
xfree (url->user);
|
||||
xfree (url->passwd);
|
||||
xfree (url->dir);
|
||||
xfree (url->file);
|
||||
|
||||
xfree (url->dir);
|
||||
xfree (url->file);
|
||||
|
||||
xfree (url);
|
||||
}
|
||||
xfree (url);
|
||||
}
|
||||
|
||||
|
||||
/* Create all the necessary directories for PATH (a file). Calls
|
||||
make_directory internally. */
|
||||
int
|
||||
@@ -1250,7 +1240,7 @@ mkalldirs (const char *path)
|
||||
xfree (t);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* Functions for constructing the file name out of URL components. */
|
||||
|
||||
/* A growable string structure, used by url_file_name and friends.
|
||||
@@ -1653,7 +1643,7 @@ url_file_name (const struct url *u, char *replaced_filename)
|
||||
logprintf (LOG_NOTQUIET, "New name is %s.\n", temp_fnres.base);
|
||||
}
|
||||
|
||||
xfree (fname_len_check);
|
||||
free (fname_len_check);
|
||||
|
||||
/* The filename has already been 'cleaned' by append_uri_pathel() above. So,
|
||||
* just append it. */
|
||||
@@ -1666,7 +1656,7 @@ url_file_name (const struct url *u, char *replaced_filename)
|
||||
/* Make a final check that the path length is acceptable? */
|
||||
/* TODO: check fnres.base for path length problem */
|
||||
|
||||
xfree (temp_fnres.base);
|
||||
free (temp_fnres.base);
|
||||
|
||||
/* Check the cases in which the unique extensions are not used:
|
||||
1) Clobbering is turned off (-nc).
|
||||
@@ -1706,7 +1696,7 @@ url_file_name (const struct url *u, char *replaced_filename)
|
||||
|
||||
return unique;
|
||||
}
|
||||
|
||||
|
||||
/* Resolve "." and ".." elements of PATH by destructively modifying
|
||||
PATH and return true if PATH has been modified, false otherwise.
|
||||
|
||||
@@ -1792,7 +1782,7 @@ path_simplify (enum url_scheme scheme, char *path)
|
||||
|
||||
return t != h;
|
||||
}
|
||||
|
||||
|
||||
/* Return the length of URL's path. Path is considered to be
|
||||
terminated by one or more of the ?query or ;params or #fragment,
|
||||
depending on the scheme. */
|
||||
@@ -1802,10 +1792,11 @@ path_end (const char *url)
|
||||
{
|
||||
enum url_scheme scheme = url_scheme (url);
|
||||
const char *seps;
|
||||
char seps_b[8];
|
||||
if (scheme == SCHEME_INVALID)
|
||||
scheme = SCHEME_HTTP; /* use http semantics for rel links */
|
||||
/* +2 to ignore the first two separators ':' and '/' */
|
||||
seps = init_seps (scheme) + 2;
|
||||
seps = init_seps (scheme, seps_b) + 2;
|
||||
return strpbrk_or_eos (url, seps);
|
||||
}
|
||||
|
||||
@@ -2003,7 +1994,7 @@ uri_merge (const char *base, const char *link)
|
||||
|
||||
return merge;
|
||||
}
|
||||
|
||||
|
||||
#define APPEND(p, s) do { \
|
||||
int len = strlen (s); \
|
||||
memcpy (p, s, len); \
|
||||
@@ -2120,7 +2111,7 @@ url_string (const struct url *url, enum url_auth_mode auth_mode)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if scheme a is similar to scheme b.
|
||||
|
||||
Schemes are similar if they are equal. If SSL is supported, schemes
|
||||
@@ -2138,7 +2129,7 @@ schemes_are_similar_p (enum url_scheme a, enum url_scheme b)
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
getchar_from_escaped_string (const char *str, char *c)
|
||||
{
|
||||
@@ -2199,7 +2190,7 @@ are_urls_equal (const char *u1, const char *u2)
|
||||
|
||||
return (*p == 0 && *q == 0 ? true : false);
|
||||
}
|
||||
|
||||
|
||||
#ifdef TESTING
|
||||
/* Debugging and testing support for path_simplify. */
|
||||
|
||||
|
||||
@@ -95,10 +95,6 @@ struct url
|
||||
/* Username and password (unquoted). */
|
||||
char *user;
|
||||
char *passwd;
|
||||
|
||||
/* 'host' is allocated by idna_to_ascii_8z() via idn_encode().
|
||||
* Call 'idn_free()' to free this memory. */
|
||||
bool idn_allocated;
|
||||
};
|
||||
|
||||
/* Function declarations */
|
||||
|
||||
144
src/utils.c
144
src/utils.c
@@ -64,10 +64,8 @@ as that of the covered work. */
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* For TIOCGWINSZ and friends: */
|
||||
#ifndef WINDOWS
|
||||
# include <sys/ioctl.h>
|
||||
# include <termios.h>
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
|
||||
/* Needed for Unix version of run_with_timeout. */
|
||||
#include <signal.h>
|
||||
@@ -101,7 +99,6 @@ as that of the covered work. */
|
||||
#endif
|
||||
|
||||
#include "exits.h"
|
||||
#include "c-strcase.h"
|
||||
|
||||
static void _Noreturn
|
||||
memfatal (const char *context, long attempted_size)
|
||||
@@ -270,7 +267,7 @@ sepstring (const char *s)
|
||||
res[i + 1] = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* Like sprintf, but prints into a string of sufficient size freshly
|
||||
allocated with malloc, which is returned. If unable to print due
|
||||
to invalid format, returns NULL. Inability to allocate needed
|
||||
@@ -352,32 +349,6 @@ aprintf (const char *fmt, ...)
|
||||
#endif /* not HAVE_VASPRINTF */
|
||||
}
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/* strlcpy() is a BSD function that sometimes is really handy.
|
||||
* It is the same as snprintf(dst,dstsize,"%s",src), but much faster. */
|
||||
|
||||
size_t
|
||||
strlcpy (char *dst, const char *src, size_t size)
|
||||
{
|
||||
const char *old = src;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (size)
|
||||
{
|
||||
while (--size)
|
||||
{
|
||||
if (!(*dst++ = *src++))
|
||||
return src - old - 1;
|
||||
}
|
||||
|
||||
*dst = 0;
|
||||
}
|
||||
|
||||
while (*src++);
|
||||
return src - old - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Concatenate the NULL-terminated list of string arguments into
|
||||
freshly allocated space. */
|
||||
|
||||
@@ -385,30 +356,47 @@ char *
|
||||
concat_strings (const char *str0, ...)
|
||||
{
|
||||
va_list args;
|
||||
const char *arg;
|
||||
size_t length = 0, pos = 0;
|
||||
char *s;
|
||||
int saved_lengths[5]; /* inspired by Apache's apr_pstrcat */
|
||||
char *ret, *p;
|
||||
|
||||
if (!str0)
|
||||
return NULL;
|
||||
const char *next_str;
|
||||
int total_length = 0;
|
||||
size_t argcount;
|
||||
|
||||
/* calculate the length of the resulting string */
|
||||
/* Calculate the length of and allocate the resulting string. */
|
||||
|
||||
argcount = 0;
|
||||
va_start (args, str0);
|
||||
for (arg = str0; arg; arg = va_arg (args, const char *))
|
||||
length += strlen(arg);
|
||||
for (next_str = str0; next_str != NULL; next_str = va_arg (args, char *))
|
||||
{
|
||||
int len = strlen (next_str);
|
||||
if (argcount < countof (saved_lengths))
|
||||
saved_lengths[argcount++] = len;
|
||||
total_length += len;
|
||||
}
|
||||
va_end (args);
|
||||
p = ret = xmalloc (total_length + 1);
|
||||
|
||||
s = xmalloc (length + 1);
|
||||
/* Copy the strings into the allocated space. */
|
||||
|
||||
/* concatenate strings */
|
||||
argcount = 0;
|
||||
va_start (args, str0);
|
||||
for (arg = str0; arg; arg = va_arg (args, const char *))
|
||||
pos += strlcpy(s + pos, arg, length - pos + 1);
|
||||
for (next_str = str0; next_str != NULL; next_str = va_arg (args, char *))
|
||||
{
|
||||
int len;
|
||||
if (argcount < countof (saved_lengths))
|
||||
len = saved_lengths[argcount++];
|
||||
else
|
||||
len = strlen (next_str);
|
||||
memcpy (p, next_str, len);
|
||||
p += len;
|
||||
}
|
||||
va_end (args);
|
||||
*p = '\0';
|
||||
|
||||
return s;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Format the provided time according to the specified format. The
|
||||
format is a string with format elements supported by strftime. */
|
||||
|
||||
@@ -442,7 +430,7 @@ datetime_str (time_t t)
|
||||
{
|
||||
return fmttime(t, "%Y-%m-%d %H:%M:%S");
|
||||
}
|
||||
|
||||
|
||||
/* The Windows versions of the following two functions are defined in
|
||||
mswindows.c. On MSDOS this function should never be called. */
|
||||
|
||||
@@ -507,7 +495,7 @@ fork_to_background (void)
|
||||
|
||||
#endif /* def __VMS [else] */
|
||||
|
||||
|
||||
|
||||
/* "Touch" FILE, i.e. make its mtime ("modified time") equal the time
|
||||
specified with TM. The atime ("access time") is set to the current
|
||||
time. */
|
||||
@@ -817,7 +805,7 @@ fopen_excl (const char *fname, int binary)
|
||||
return fopen (fname, binary ? "wb" : "w");
|
||||
#endif /* not O_EXCL */
|
||||
}
|
||||
|
||||
|
||||
/* Create DIRECTORY. If some of the pathname components of DIRECTORY
|
||||
are missing, create them first. In case any mkdir() call fails,
|
||||
return its error status. Returns 0 on successful completion.
|
||||
@@ -883,7 +871,7 @@ file_merge (const char *base, const char *file)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Like fnmatch, but performs a case-insensitive match. */
|
||||
|
||||
int
|
||||
@@ -1124,11 +1112,11 @@ has_html_suffix_p (const char *fname)
|
||||
|
||||
if ((suf = suffix (fname)) == NULL)
|
||||
return false;
|
||||
if (!c_strcasecmp (suf, "html"))
|
||||
if (!strcasecmp (suf, "html"))
|
||||
return true;
|
||||
if (!c_strcasecmp (suf, "htm"))
|
||||
if (!strcasecmp (suf, "htm"))
|
||||
return true;
|
||||
if (suf[0] && !c_strcasecmp (suf + 1, "html"))
|
||||
if (suf[0] && !strcasecmp (suf + 1, "html"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -1274,7 +1262,7 @@ wget_read_file_free (struct file_memory *fm)
|
||||
}
|
||||
xfree (fm);
|
||||
}
|
||||
|
||||
|
||||
/* Free the pointers in a NULL-terminated vector of pointers, then
|
||||
free the pointer itself. */
|
||||
void
|
||||
@@ -1343,7 +1331,7 @@ vec_append (char **vec, const char *str)
|
||||
vec[cnt] = NULL;
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
/* Sometimes it's useful to create "sets" of strings, i.e. special
|
||||
hash tables where you want to store strings as keys and merely
|
||||
query for their existence. Here is a set of utility routines that
|
||||
@@ -1408,7 +1396,7 @@ free_keys_and_values (struct hash_table *ht)
|
||||
xfree (iter.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get digit grouping data for thousand separors by calling
|
||||
localeconv(). The data includes separator string and grouping info
|
||||
and is cached after the first call to the function.
|
||||
@@ -1799,7 +1787,7 @@ convert_to_bits (wgint num)
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Determine the width of the terminal we're running on. If that's
|
||||
not possible, return 0. */
|
||||
|
||||
@@ -1812,7 +1800,7 @@ determine_screen_width (void)
|
||||
int fd;
|
||||
struct winsize wsz;
|
||||
|
||||
if (opt.lfilename != NULL && opt.show_progress != 1)
|
||||
if (opt.lfilename != NULL)
|
||||
return 0;
|
||||
|
||||
fd = fileno (stderr);
|
||||
@@ -1829,7 +1817,7 @@ determine_screen_width (void)
|
||||
return 0;
|
||||
#endif /* neither TIOCGWINSZ nor WINDOWS */
|
||||
}
|
||||
|
||||
|
||||
/* Whether the rnd system (either rand or [dl]rand48) has been
|
||||
seeded. */
|
||||
static int rnd_seeded;
|
||||
@@ -1849,14 +1837,7 @@ static int rnd_seeded;
|
||||
int
|
||||
random_number (int max)
|
||||
{
|
||||
#ifdef HAVE_RANDOM
|
||||
if (!rnd_seeded)
|
||||
{
|
||||
srandom ((long) time (NULL) ^ (long) getpid ());
|
||||
rnd_seeded = 1;
|
||||
}
|
||||
return random () % max;
|
||||
#elif defined HAVE_DRAND48
|
||||
#ifdef HAVE_DRAND48
|
||||
if (!rnd_seeded)
|
||||
{
|
||||
srand48 ((long) time (NULL) ^ (long) getpid ());
|
||||
@@ -1891,9 +1872,7 @@ random_number (int max)
|
||||
double
|
||||
random_float (void)
|
||||
{
|
||||
#ifdef HAVE_RANDOM
|
||||
return ((double) random_number (RAND_MAX)) / RAND_MAX;
|
||||
#elif defined HAVE_DRAND48
|
||||
#ifdef HAVE_DRAND48
|
||||
if (!rnd_seeded)
|
||||
{
|
||||
srand48 ((long) time (NULL) ^ (long) getpid ());
|
||||
@@ -1907,7 +1886,7 @@ random_float (void)
|
||||
+ random_number (10000) / (10000.0 * 10000.0 * 10000.0 * 10000.0));
|
||||
#endif /* not HAVE_DRAND48 */
|
||||
}
|
||||
|
||||
|
||||
/* Implementation of run_with_timeout, a generic timeout-forcing
|
||||
routine for systems with Unix-like signal handling. */
|
||||
|
||||
@@ -1918,7 +1897,7 @@ random_float (void)
|
||||
static sigjmp_buf run_with_timeout_env;
|
||||
|
||||
static void _Noreturn
|
||||
abort_run_with_timeout (int sig _GL_UNUSED)
|
||||
abort_run_with_timeout (int sig)
|
||||
{
|
||||
assert (sig == SIGALRM);
|
||||
siglongjmp (run_with_timeout_env, -1);
|
||||
@@ -1928,8 +1907,8 @@ abort_run_with_timeout (int sig _GL_UNUSED)
|
||||
|
||||
static jmp_buf run_with_timeout_env;
|
||||
|
||||
static void _Noreturn
|
||||
abort_run_with_timeout (int sig _GL_UNUSED)
|
||||
static void
|
||||
abort_run_with_timeout (int sig)
|
||||
{
|
||||
assert (sig == SIGALRM);
|
||||
/* We don't have siglongjmp to preserve the set of blocked signals;
|
||||
@@ -2032,6 +2011,16 @@ run_with_timeout (double timeout, void (*fun) (void *), void *arg)
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_THREADS
|
||||
if (opt.jobs > 1)
|
||||
{
|
||||
/* XXX: FIXME. Support this functionality when there are
|
||||
multiple threads. Do not translate the string. */
|
||||
logputs (LOG_NOTQUIET, "\ntimeouts not (yet) supported with threads.\n");
|
||||
abort ();
|
||||
}
|
||||
#endif
|
||||
|
||||
signal (SIGALRM, abort_run_with_timeout);
|
||||
if (SETJMP (run_with_timeout_env) != 0)
|
||||
{
|
||||
@@ -2066,7 +2055,7 @@ run_with_timeout (double timeout, void (*fun) (void *), void *arg)
|
||||
}
|
||||
#endif /* not WINDOWS */
|
||||
#endif /* not USE_SIGNAL_TIMEOUT */
|
||||
|
||||
|
||||
#ifndef WINDOWS
|
||||
|
||||
/* Sleep the specified amount of seconds. On machines without
|
||||
@@ -2313,7 +2302,6 @@ compile_posix_regex (const char *str)
|
||||
fprintf (stderr, _("Invalid regular expression %s, %s\n"),
|
||||
quote (str), errbuf);
|
||||
xfree (errbuf);
|
||||
xfree (regex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2367,7 +2355,7 @@ match_posix_regex (const void *regex, const char *str)
|
||||
|
||||
#undef IS_ASCII
|
||||
#undef NEXT_CHAR
|
||||
|
||||
|
||||
/* Simple merge sort for use by stable_sort. Implementation courtesy
|
||||
Zeljko Vrba with additional debugging by Nenad Barbutov. */
|
||||
|
||||
@@ -2413,7 +2401,7 @@ stable_sort (void *base, size_t nmemb, size_t size,
|
||||
mergesort_internal (base, temp, size, 0, nmemb - 1, cmpfun);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Print a decimal number. If it is equal to or larger than ten, the
|
||||
number is rounded. Otherwise it is printed with one significant
|
||||
digit without trailing zeros and with no more than three fractional
|
||||
|
||||
11
src/utils.h
11
src/utils.h
@@ -47,7 +47,12 @@ as that of the covered work. */
|
||||
|
||||
#define alloca_array(type, size) ((type *) alloca ((size) * sizeof (type)))
|
||||
|
||||
#define xfree(p) do { free ((void *) (p)); p = NULL; } while (0)
|
||||
#define xfree free
|
||||
/* Free P if it is non-NULL. C requires free() to behaves this way by
|
||||
default, but Wget's code is historically careful not to pass NULL
|
||||
to free. This allows us to assert p!=NULL in xfree to check
|
||||
additional errors. (But we currently don't do that!) */
|
||||
#define xfree_null(p) if (!(p)) ; else xfree (p)
|
||||
|
||||
struct hash_table;
|
||||
|
||||
@@ -151,10 +156,6 @@ const char *print_decimal (double);
|
||||
|
||||
long get_max_length (const char *path, int length, int name);
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy (char *dst, const char *src, size_t size);
|
||||
#endif
|
||||
|
||||
extern unsigned char char_prop[];
|
||||
|
||||
#endif /* UTILS_H */
|
||||
|
||||
321
src/warc.c
321
src/warc.c
@@ -27,15 +27,11 @@ 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. */
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "wget.h"
|
||||
#include "hash.h"
|
||||
#include "utils.h"
|
||||
#include "version.h"
|
||||
#include "dirname.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -55,21 +51,23 @@ as that of the covered work. */
|
||||
#include <uuid.h>
|
||||
#endif
|
||||
|
||||
#ifndef WINDOWS
|
||||
#include <libgen.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "warc.h"
|
||||
#include "exits.h"
|
||||
|
||||
#ifdef WINDOWS
|
||||
/* we need this on Windows to have O_TEMPORARY defined */
|
||||
# include <fcntl.h>
|
||||
# include <rpc.h>
|
||||
#endif
|
||||
|
||||
#ifndef O_TEMPORARY
|
||||
#define O_TEMPORARY 0
|
||||
#endif
|
||||
|
||||
#include "warc.h"
|
||||
#include "exits.h"
|
||||
extern char *version_string;
|
||||
|
||||
/* Set by main in main.c */
|
||||
extern char *program_argstring;
|
||||
|
||||
|
||||
/* The log file (a temporary file that contains a copy
|
||||
@@ -165,12 +163,10 @@ warc_write_buffer (const char *buffer, size_t size)
|
||||
static bool
|
||||
warc_write_string (const char *str)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
if (!warc_write_ok)
|
||||
return false;
|
||||
|
||||
n = strlen (str);
|
||||
size_t n = strlen (str);
|
||||
if (n != warc_write_buffer (str, n))
|
||||
warc_write_ok = false;
|
||||
|
||||
@@ -259,9 +255,6 @@ warc_write_block_from_file (FILE *data_in)
|
||||
{
|
||||
/* Add the Content-Length header. */
|
||||
char content_length[MAX_INT_TO_STRING_LEN(off_t)];
|
||||
char buffer[BUFSIZ];
|
||||
size_t s;
|
||||
|
||||
fseeko (data_in, 0L, SEEK_END);
|
||||
number_to_string (content_length, ftello (data_in));
|
||||
warc_write_header ("Content-Length", content_length);
|
||||
@@ -273,6 +266,8 @@ warc_write_block_from_file (FILE *data_in)
|
||||
warc_write_ok = false;
|
||||
|
||||
/* Copy the data in the file to the WARC record. */
|
||||
char buffer[BUFSIZ];
|
||||
size_t s;
|
||||
while (warc_write_ok && (s = fread (buffer, 1, BUFSIZ, data_in)) > 0)
|
||||
{
|
||||
if (warc_write_buffer (buffer, s) < s)
|
||||
@@ -297,11 +292,6 @@ warc_write_end_record (void)
|
||||
/* We start a new gzip stream for each record. */
|
||||
if (warc_write_ok && warc_current_gzfile)
|
||||
{
|
||||
char extra_header[EXTRA_GZIP_HEADER_SIZE];
|
||||
char static_header[GZIP_STATIC_HEADER_SIZE];
|
||||
off_t current_offset, uncompressed_size, compressed_size;
|
||||
size_t result;
|
||||
|
||||
if (gzclose (warc_current_gzfile) != Z_OK)
|
||||
{
|
||||
warc_write_ok = false;
|
||||
@@ -327,16 +317,17 @@ warc_write_end_record (void)
|
||||
*/
|
||||
|
||||
/* Calculate the uncompressed and compressed sizes. */
|
||||
current_offset = ftello (warc_current_file);
|
||||
uncompressed_size = current_offset - warc_current_gzfile_offset;
|
||||
compressed_size = warc_current_gzfile_uncompressed_size;
|
||||
off_t current_offset = ftello (warc_current_file);
|
||||
off_t uncompressed_size = current_offset - warc_current_gzfile_offset;
|
||||
off_t compressed_size = warc_current_gzfile_uncompressed_size;
|
||||
|
||||
/* Go back to the static GZIP header. */
|
||||
fseeko (warc_current_file, warc_current_gzfile_offset
|
||||
+ EXTRA_GZIP_HEADER_SIZE, SEEK_SET);
|
||||
|
||||
/* Read the header. */
|
||||
result = fread (static_header, 1, GZIP_STATIC_HEADER_SIZE,
|
||||
char static_header[GZIP_STATIC_HEADER_SIZE];
|
||||
size_t result = fread (static_header, 1, GZIP_STATIC_HEADER_SIZE,
|
||||
warc_current_file);
|
||||
if (result != GZIP_STATIC_HEADER_SIZE)
|
||||
{
|
||||
@@ -353,6 +344,7 @@ warc_write_end_record (void)
|
||||
fwrite (static_header, 1, GZIP_STATIC_HEADER_SIZE, warc_current_file);
|
||||
|
||||
/* Prepare the extra GZIP header. */
|
||||
char extra_header[EXTRA_GZIP_HEADER_SIZE];
|
||||
/* XLEN, the length of the extra header fields. */
|
||||
extra_header[0] = ((EXTRA_GZIP_HEADER_SIZE - 2) & 255);
|
||||
extra_header[1] = ((EXTRA_GZIP_HEADER_SIZE - 2) >> 8) & 255;
|
||||
@@ -395,9 +387,12 @@ static bool
|
||||
warc_write_date_header (const char *timestamp)
|
||||
{
|
||||
char current_timestamp[21];
|
||||
|
||||
return warc_write_header ("WARC-Date", timestamp ? timestamp :
|
||||
warc_timestamp (current_timestamp, sizeof(current_timestamp)));
|
||||
if (timestamp == NULL)
|
||||
{
|
||||
warc_timestamp (current_timestamp);
|
||||
timestamp = current_timestamp;
|
||||
}
|
||||
return warc_write_header ("WARC-Date", timestamp);
|
||||
}
|
||||
|
||||
/* Writes the WARC-IP-Address header for the given IP to
|
||||
@@ -473,7 +468,7 @@ warc_sha1_stream_with_payload (FILE *stream, void *res_block, void *res_payload,
|
||||
or EWOULDBLOCK. */
|
||||
if (ferror (stream))
|
||||
{
|
||||
xfree (buffer);
|
||||
free (buffer);
|
||||
return 1;
|
||||
}
|
||||
goto process_partial_block;
|
||||
@@ -533,7 +528,7 @@ warc_sha1_stream_with_payload (FILE *stream, void *res_block, void *res_payload,
|
||||
sha1_finish_ctx (&ctx_block, res_block);
|
||||
if (payload_offset >= 0)
|
||||
sha1_finish_ctx (&ctx_payload, res_payload);
|
||||
xfree (buffer);
|
||||
free (buffer);
|
||||
return 0;
|
||||
|
||||
#undef BLOCKSIZE
|
||||
@@ -575,13 +570,13 @@ warc_write_digest_headers (FILE *file, long payload_offset)
|
||||
|
||||
digest = warc_base32_sha1_digest (sha1_res_block);
|
||||
warc_write_header ("WARC-Block-Digest", digest);
|
||||
xfree (digest);
|
||||
free (digest);
|
||||
|
||||
if (payload_offset >= 0)
|
||||
{
|
||||
digest = warc_base32_sha1_digest (sha1_res_payload);
|
||||
warc_write_header ("WARC-Payload-Digest", digest);
|
||||
xfree (digest);
|
||||
free (digest);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -592,102 +587,37 @@ warc_write_digest_headers (FILE *file, long payload_offset)
|
||||
The UTC time is formatted following ISO 8601, as required
|
||||
for use in the WARC-Date header.
|
||||
The timestamp will be 21 characters long. */
|
||||
char *
|
||||
warc_timestamp (char *timestamp, size_t timestamp_size)
|
||||
void
|
||||
warc_timestamp (char *timestamp)
|
||||
{
|
||||
time_t rawtime = time (NULL);
|
||||
struct tm * timeinfo = gmtime (&rawtime);
|
||||
|
||||
if (strftime (timestamp, timestamp_size, "%Y-%m-%dT%H:%M:%SZ", timeinfo) == 0 && timestamp_size > 0)
|
||||
*timestamp = 0;
|
||||
|
||||
return timestamp;
|
||||
time_t rawtime;
|
||||
struct tm * timeinfo;
|
||||
time ( &rawtime );
|
||||
timeinfo = gmtime (&rawtime);
|
||||
strftime (timestamp, 21, "%Y-%m-%dT%H:%M:%SZ", timeinfo);
|
||||
}
|
||||
|
||||
#if HAVE_LIBUUID || HAVE_UUID_CREATE
|
||||
/* Fills urn_str with a UUID in the format required
|
||||
for the WARC-Record-Id header.
|
||||
The string will be 47 characters long. */
|
||||
#if HAVE_LIBUUID
|
||||
void
|
||||
warc_uuid_str (char *urn_str)
|
||||
{
|
||||
char uuid_str[37];
|
||||
|
||||
uuid_t record_id;
|
||||
|
||||
uuid_generate (record_id);
|
||||
uuid_unparse (record_id, uuid_str);
|
||||
|
||||
sprintf (urn_str, "<urn:uuid:%s>", uuid_str);
|
||||
}
|
||||
#elif HAVE_UUID_CREATE
|
||||
void
|
||||
warc_uuid_str (char *urn_str)
|
||||
{
|
||||
char *uuid_str;
|
||||
uuid_t record_id;
|
||||
|
||||
#if HAVE_UUID_CREATE
|
||||
uuid_create (&record_id, NULL);
|
||||
uuid_to_string (&record_id, &uuid_str, NULL);
|
||||
#else
|
||||
uuid_generate (record_id);
|
||||
uuid_unparse (record_id, uuid_str);
|
||||
#endif
|
||||
|
||||
sprintf (urn_str, "<urn:uuid:%s>", uuid_str);
|
||||
xfree (uuid_str);
|
||||
}
|
||||
#else
|
||||
# ifdef WINDOWS
|
||||
|
||||
typedef RPC_STATUS (RPC_ENTRY * UuidCreate_proc) (UUID *);
|
||||
typedef RPC_STATUS (RPC_ENTRY * UuidToString_proc) (UUID *, unsigned char **);
|
||||
typedef RPC_STATUS (RPC_ENTRY * RpcStringFree_proc) (unsigned char **);
|
||||
|
||||
static int
|
||||
windows_uuid_str (char *urn_str)
|
||||
{
|
||||
static UuidCreate_proc pfn_UuidCreate = NULL;
|
||||
static UuidToString_proc pfn_UuidToString = NULL;
|
||||
static RpcStringFree_proc pfn_RpcStringFree = NULL;
|
||||
static int rpc_uuid_avail = -1;
|
||||
|
||||
/* Rpcrt4.dll is not available on older versions of Windows, so we
|
||||
need to test its availability at run time. */
|
||||
if (rpc_uuid_avail == -1)
|
||||
{
|
||||
HMODULE hm_rpcrt4 = LoadLibrary ("Rpcrt4.dll");
|
||||
|
||||
if (hm_rpcrt4)
|
||||
{
|
||||
pfn_UuidCreate =
|
||||
(UuidCreate_proc) GetProcAddress (hm_rpcrt4, "UuidCreate");
|
||||
pfn_UuidToString =
|
||||
(UuidToString_proc) GetProcAddress (hm_rpcrt4, "UuidToStringA");
|
||||
pfn_RpcStringFree =
|
||||
(RpcStringFree_proc) GetProcAddress (hm_rpcrt4, "RpcStringFreeA");
|
||||
if (pfn_UuidCreate && pfn_UuidToString && pfn_RpcStringFree)
|
||||
rpc_uuid_avail = 1;
|
||||
else
|
||||
rpc_uuid_avail = 0;
|
||||
}
|
||||
else
|
||||
rpc_uuid_avail = 0;
|
||||
}
|
||||
|
||||
if (rpc_uuid_avail)
|
||||
{
|
||||
BYTE *uuid_str;
|
||||
UUID uuid;
|
||||
|
||||
if (pfn_UuidCreate (&uuid) == RPC_S_OK)
|
||||
{
|
||||
if (pfn_UuidToString (&uuid, &uuid_str) == RPC_S_OK)
|
||||
{
|
||||
sprintf (urn_str, "<urn:uuid:%s>", uuid_str);
|
||||
pfn_RpcStringFree (&uuid_str);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/* Fills urn_str with a UUID based on random numbers in the format
|
||||
required for the WARC-Record-Id header.
|
||||
(See RFC 4122, UUID version 4.)
|
||||
@@ -699,27 +629,19 @@ windows_uuid_str (char *urn_str)
|
||||
void
|
||||
warc_uuid_str (char *urn_str)
|
||||
{
|
||||
/* RFC 4122, a version 4 UUID with only random numbers */
|
||||
// RFC 4122, a version 4 UUID with only random numbers
|
||||
|
||||
unsigned char uuid_data[16];
|
||||
int i;
|
||||
|
||||
#ifdef WINDOWS
|
||||
/* If the native method fails (expected on older Windows versions),
|
||||
use the fallback below. */
|
||||
if (windows_uuid_str (urn_str))
|
||||
return;
|
||||
#endif
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
uuid_data[i] = random_number (255);
|
||||
|
||||
/* Set the four most significant bits (bits 12 through 15) of the
|
||||
* time_hi_and_version field to the 4-bit version number */
|
||||
// Set the four most significant bits (bits 12 through 15) of the
|
||||
// time_hi_and_version field to the 4-bit version number
|
||||
uuid_data[6] = (uuid_data[6] & 0x0F) | 0x40;
|
||||
|
||||
/* Set the two most significant bits (bits 6 and 7) of the
|
||||
* clock_seq_hi_and_reserved to zero and one, respectively. */
|
||||
// Set the two most significant bits (bits 6 and 7) of the
|
||||
// clock_seq_hi_and_reserved to zero and one, respectively.
|
||||
uuid_data[8] = (uuid_data[8] & 0xBF) | 0x80;
|
||||
|
||||
sprintf (urn_str,
|
||||
@@ -736,19 +658,18 @@ warc_uuid_str (char *urn_str)
|
||||
static bool
|
||||
warc_write_warcinfo_record (char *filename)
|
||||
{
|
||||
FILE *warc_tmp;
|
||||
char timestamp[22];
|
||||
char *filename_basename;
|
||||
|
||||
/* Write warc-info record as the first record of the file. */
|
||||
/* We add the record id of this info record to the other records in the
|
||||
file. */
|
||||
warc_current_warcinfo_uuid_str = (char *) malloc (48);
|
||||
warc_uuid_str (warc_current_warcinfo_uuid_str);
|
||||
|
||||
warc_timestamp (timestamp, sizeof(timestamp));
|
||||
char timestamp[22];
|
||||
warc_timestamp (timestamp);
|
||||
|
||||
filename_basename = base_name (filename);
|
||||
char *filename_copy, *filename_basename;
|
||||
filename_copy = strdup (filename);
|
||||
filename_basename = strdup (basename (filename_copy));
|
||||
|
||||
warc_write_start_record ();
|
||||
warc_write_header ("WARC-Type", "warcinfo");
|
||||
@@ -757,12 +678,12 @@ warc_write_warcinfo_record (char *filename)
|
||||
warc_write_header ("WARC-Record-ID", warc_current_warcinfo_uuid_str);
|
||||
warc_write_header ("WARC-Filename", filename_basename);
|
||||
|
||||
xfree (filename_basename);
|
||||
|
||||
/* Create content. */
|
||||
warc_tmp = warc_tempfile ();
|
||||
FILE *warc_tmp = warc_tempfile ();
|
||||
if (warc_tmp == NULL)
|
||||
{
|
||||
free (filename_copy);
|
||||
free (filename_basename);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -788,6 +709,8 @@ warc_write_warcinfo_record (char *filename)
|
||||
if (! warc_write_ok)
|
||||
logprintf (LOG_NOTQUIET, _("Error writing warcinfo record to WARC file.\n"));
|
||||
|
||||
free (filename_copy);
|
||||
free (filename_basename);
|
||||
fclose (warc_tmp);
|
||||
return warc_write_ok;
|
||||
}
|
||||
@@ -806,6 +729,22 @@ warc_write_warcinfo_record (char *filename)
|
||||
static bool
|
||||
warc_start_new_file (bool meta)
|
||||
{
|
||||
if (opt.warc_filename == NULL)
|
||||
return false;
|
||||
|
||||
if (warc_current_file != NULL)
|
||||
fclose (warc_current_file);
|
||||
|
||||
free (warc_current_warcinfo_uuid_str);
|
||||
free (warc_current_filename);
|
||||
|
||||
warc_current_file_number++;
|
||||
|
||||
int base_filename_length = strlen (opt.warc_filename);
|
||||
/* filename format: base + "-" + 5 digit serial number + ".warc.gz" */
|
||||
char *new_filename = malloc (base_filename_length + 1 + 5 + 8 + 1);
|
||||
warc_current_filename = new_filename;
|
||||
|
||||
#ifdef __VMS
|
||||
# define WARC_GZ "warc-gz"
|
||||
#else /* def __VMS */
|
||||
@@ -818,25 +757,6 @@ warc_start_new_file (bool meta)
|
||||
const char *extension = "warc";
|
||||
#endif
|
||||
|
||||
int base_filename_length;
|
||||
char *new_filename;
|
||||
|
||||
if (opt.warc_filename == NULL)
|
||||
return false;
|
||||
|
||||
if (warc_current_file != NULL)
|
||||
fclose (warc_current_file);
|
||||
|
||||
xfree (warc_current_warcinfo_uuid_str);
|
||||
xfree (warc_current_filename);
|
||||
|
||||
warc_current_file_number++;
|
||||
|
||||
base_filename_length = strlen (opt.warc_filename);
|
||||
/* filename format: base + "-" + 5 digit serial number + ".warc.gz" */
|
||||
new_filename = malloc (base_filename_length + 1 + 5 + 8 + 1);
|
||||
warc_current_filename = new_filename;
|
||||
|
||||
/* If max size is enabled, we add a serial number to the file names. */
|
||||
if (meta)
|
||||
sprintf (new_filename, "%s-meta.%s", opt.warc_filename, extension);
|
||||
@@ -908,13 +828,12 @@ static bool
|
||||
warc_parse_cdx_header (char *lineptr, int *field_num_original_url,
|
||||
int *field_num_checksum, int *field_num_record_id)
|
||||
{
|
||||
char *token;
|
||||
char *save_ptr;
|
||||
|
||||
*field_num_original_url = -1;
|
||||
*field_num_checksum = -1;
|
||||
*field_num_record_id = -1;
|
||||
|
||||
char *token;
|
||||
char *save_ptr;
|
||||
token = strtok_r (lineptr, CDX_FIELDSEP, &save_ptr);
|
||||
|
||||
if (token != NULL && strcmp (token, "CDX") == 0)
|
||||
@@ -955,12 +874,13 @@ warc_process_cdx_line (char *lineptr, int field_num_original_url,
|
||||
char *original_url = NULL;
|
||||
char *checksum = NULL;
|
||||
char *record_id = NULL;
|
||||
|
||||
char *token;
|
||||
char *save_ptr;
|
||||
int field_num = 0;
|
||||
token = strtok_r (lineptr, CDX_FIELDSEP, &save_ptr);
|
||||
|
||||
/* Read this line to get the fields we need. */
|
||||
token = strtok_r (lineptr, CDX_FIELDSEP, &save_ptr);
|
||||
int field_num = 0;
|
||||
while (token != NULL)
|
||||
{
|
||||
char **val;
|
||||
@@ -989,7 +909,7 @@ warc_process_cdx_line (char *lineptr, int field_num_original_url,
|
||||
char * checksum_v;
|
||||
base32_decode_alloc (checksum, strlen (checksum), &checksum_v,
|
||||
&checksum_l);
|
||||
xfree (checksum);
|
||||
free (checksum);
|
||||
|
||||
if (checksum_v != NULL && checksum_l == SHA1_DIGEST_SIZE)
|
||||
{
|
||||
@@ -1000,20 +920,20 @@ warc_process_cdx_line (char *lineptr, int field_num_original_url,
|
||||
rec->uuid = record_id;
|
||||
memcpy (rec->digest, checksum_v, SHA1_DIGEST_SIZE);
|
||||
hash_table_put (warc_cdx_dedup_table, rec->digest, rec);
|
||||
xfree (checksum_v);
|
||||
free (checksum_v);
|
||||
}
|
||||
else
|
||||
{
|
||||
xfree (original_url);
|
||||
xfree (checksum_v);
|
||||
xfree (record_id);
|
||||
free (original_url);
|
||||
free (checksum_v);
|
||||
free (record_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xfree(checksum);
|
||||
xfree(original_url);
|
||||
xfree(record_id);
|
||||
xfree_null(checksum);
|
||||
xfree_null(original_url);
|
||||
xfree_null(record_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1022,17 +942,17 @@ warc_process_cdx_line (char *lineptr, int field_num_original_url,
|
||||
static bool
|
||||
warc_load_cdx_dedup_file (void)
|
||||
{
|
||||
FILE *f;
|
||||
char *lineptr = NULL;
|
||||
size_t n = 0;
|
||||
ssize_t line_length;
|
||||
FILE *f = fopen (opt.warc_cdx_dedup_filename, "r");
|
||||
if (f == NULL)
|
||||
return false;
|
||||
|
||||
int field_num_original_url = -1;
|
||||
int field_num_checksum = -1;
|
||||
int field_num_record_id = -1;
|
||||
|
||||
f = fopen (opt.warc_cdx_dedup_filename, "r");
|
||||
if (f == NULL)
|
||||
return false;
|
||||
char *lineptr = NULL;
|
||||
size_t n = 0;
|
||||
ssize_t line_length;
|
||||
|
||||
/* The first line should contain the CDX header.
|
||||
Format: " CDX x x x x x"
|
||||
@@ -1061,8 +981,6 @@ _("CDX file does not list record ids. (Missing column 'u'.)\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
int nrecords;
|
||||
|
||||
/* Initialize the table. */
|
||||
warc_cdx_dedup_table = hash_table_new (1000, warc_hash_sha1_digest,
|
||||
warc_cmp_sha1_digest);
|
||||
@@ -1080,14 +998,14 @@ _("CDX file does not list record ids. (Missing column 'u'.)\n"));
|
||||
while (line_length != -1);
|
||||
|
||||
/* Print results. */
|
||||
nrecords = hash_table_count (warc_cdx_dedup_table);
|
||||
int nrecords = hash_table_count (warc_cdx_dedup_table);
|
||||
logprintf (LOG_VERBOSE, ngettext ("Loaded %d record from CDX.\n\n",
|
||||
"Loaded %d records from CDX.\n\n",
|
||||
nrecords),
|
||||
nrecords);
|
||||
}
|
||||
|
||||
xfree (lineptr);
|
||||
free (lineptr);
|
||||
fclose (f);
|
||||
|
||||
return true;
|
||||
@@ -1100,12 +1018,11 @@ _("CDX file does not list record ids. (Missing column 'u'.)\n"));
|
||||
static struct warc_cdx_record *
|
||||
warc_find_duplicate_cdx_record (char *url, char *sha1_digest_payload)
|
||||
{
|
||||
struct warc_cdx_record *rec_existing;
|
||||
|
||||
if (warc_cdx_dedup_table == NULL)
|
||||
return NULL;
|
||||
|
||||
rec_existing = hash_table_get (warc_cdx_dedup_table, sha1_digest_payload);
|
||||
struct warc_cdx_record *rec_existing
|
||||
= hash_table_get (warc_cdx_dedup_table, sha1_digest_payload);
|
||||
|
||||
if (rec_existing && strcmp (rec_existing->url, url) == 0)
|
||||
return rec_existing;
|
||||
@@ -1176,13 +1093,11 @@ warc_init (void)
|
||||
static void
|
||||
warc_write_metadata (void)
|
||||
{
|
||||
char manifest_uuid[48];
|
||||
FILE *warc_tmp_fp;
|
||||
|
||||
/* If there are multiple WARC files, the metadata should be written to a separate file. */
|
||||
if (opt.warc_maxsize > 0)
|
||||
warc_start_new_file (true);
|
||||
|
||||
char manifest_uuid [48];
|
||||
warc_uuid_str (manifest_uuid);
|
||||
|
||||
fflush (warc_manifest_fp);
|
||||
@@ -1192,7 +1107,7 @@ warc_write_metadata (void)
|
||||
warc_manifest_fp, -1);
|
||||
/* warc_write_resource_record has closed warc_manifest_fp. */
|
||||
|
||||
warc_tmp_fp = warc_tempfile ();
|
||||
FILE * warc_tmp_fp = warc_tempfile ();
|
||||
if (warc_tmp_fp == NULL)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("Could not open temporary WARC file.\n"));
|
||||
@@ -1228,7 +1143,7 @@ warc_close (void)
|
||||
if (warc_current_file != NULL)
|
||||
{
|
||||
warc_write_metadata ();
|
||||
xfree (warc_current_warcinfo_uuid_str);
|
||||
free (warc_current_warcinfo_uuid_str);
|
||||
fclose (warc_current_file);
|
||||
}
|
||||
if (warc_current_cdx_file != NULL)
|
||||
@@ -1247,8 +1162,6 @@ FILE *
|
||||
warc_tempfile (void)
|
||||
{
|
||||
char filename[100];
|
||||
int fd;
|
||||
|
||||
if (path_search (filename, 100, opt.warc_tempdir, "wget", true) == -1)
|
||||
return NULL;
|
||||
|
||||
@@ -1267,16 +1180,13 @@ warc_tempfile (void)
|
||||
return fopen (tfn, "w+", "fop=tmd"); /* Create auto-delete temp file. */
|
||||
}
|
||||
#else /* def __VMS */
|
||||
fd = mkostemp (filename, O_TEMPORARY);
|
||||
int fd = mkostemp (filename, O_TEMPORARY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
#if !O_TEMPORARY
|
||||
if (unlink (filename) < 0)
|
||||
{
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
return fdopen (fd, "wb+");
|
||||
@@ -1333,10 +1243,7 @@ warc_write_cdx_record (const char *url, const char *timestamp_str,
|
||||
const char *response_uuid)
|
||||
{
|
||||
/* Transform the timestamp. */
|
||||
char timestamp_str_cdx[15];
|
||||
char offset_string[MAX_INT_TO_STRING_LEN(off_t)];
|
||||
const char *checksum;
|
||||
|
||||
char timestamp_str_cdx [15];
|
||||
memcpy (timestamp_str_cdx , timestamp_str , 4); /* "YYYY" "-" */
|
||||
memcpy (timestamp_str_cdx + 4, timestamp_str + 5, 2); /* "mm" "-" */
|
||||
memcpy (timestamp_str_cdx + 6, timestamp_str + 8, 2); /* "dd" "T" */
|
||||
@@ -1346,6 +1253,7 @@ warc_write_cdx_record (const char *url, const char *timestamp_str,
|
||||
timestamp_str_cdx[14] = '\0';
|
||||
|
||||
/* Rewrite the checksum. */
|
||||
const char *checksum;
|
||||
if (payload_digest != NULL)
|
||||
checksum = payload_digest + 5; /* Skip the "sha1:" */
|
||||
else
|
||||
@@ -1356,6 +1264,7 @@ warc_write_cdx_record (const char *url, const char *timestamp_str,
|
||||
if (redirect_location == NULL || strlen(redirect_location) == 0)
|
||||
redirect_location = "-";
|
||||
|
||||
char offset_string[MAX_INT_TO_STRING_LEN(off_t)];
|
||||
number_to_string (offset_string, offset);
|
||||
|
||||
/* Print the CDX line. */
|
||||
@@ -1387,11 +1296,10 @@ warc_write_revisit_record (char *url, char *timestamp_str,
|
||||
char *refers_to, ip_address *ip, FILE *body)
|
||||
{
|
||||
char revisit_uuid [48];
|
||||
char *block_digest = NULL;
|
||||
char sha1_res_block[SHA1_DIGEST_SIZE];
|
||||
|
||||
warc_uuid_str (revisit_uuid);
|
||||
|
||||
char *block_digest = NULL;
|
||||
char sha1_res_block[SHA1_DIGEST_SIZE];
|
||||
sha1_stream (body, sha1_res_block);
|
||||
block_digest = warc_base32_sha1_digest (sha1_res_block);
|
||||
|
||||
@@ -1413,7 +1321,7 @@ warc_write_revisit_record (char *url, char *timestamp_str,
|
||||
warc_write_end_record ();
|
||||
|
||||
fclose (body);
|
||||
xfree (block_digest);
|
||||
free (block_digest);
|
||||
|
||||
return warc_write_ok;
|
||||
}
|
||||
@@ -1441,8 +1349,6 @@ warc_write_response_record (char *url, char *timestamp_str,
|
||||
char *payload_digest = NULL;
|
||||
char sha1_res_block[SHA1_DIGEST_SIZE];
|
||||
char sha1_res_payload[SHA1_DIGEST_SIZE];
|
||||
char response_uuid [48];
|
||||
off_t offset;
|
||||
|
||||
if (opt.warc_digests_enabled)
|
||||
{
|
||||
@@ -1475,7 +1381,7 @@ warc_write_response_record (char *url, char *timestamp_str,
|
||||
result = warc_write_revisit_record (url, timestamp_str,
|
||||
concurrent_to_uuid, payload_digest, rec_existing->uuid,
|
||||
ip, body);
|
||||
xfree (payload_digest);
|
||||
free (payload_digest);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1487,10 +1393,11 @@ warc_write_response_record (char *url, char *timestamp_str,
|
||||
|
||||
/* Not a revisit, just store the record. */
|
||||
|
||||
char response_uuid [48];
|
||||
warc_uuid_str (response_uuid);
|
||||
|
||||
fseeko (warc_current_file, 0L, SEEK_END);
|
||||
offset = ftello (warc_current_file);
|
||||
off_t offset = ftello (warc_current_file);
|
||||
|
||||
warc_write_start_record ();
|
||||
warc_write_header ("WARC-Type", "response");
|
||||
@@ -1516,8 +1423,8 @@ warc_write_response_record (char *url, char *timestamp_str,
|
||||
response_uuid);
|
||||
}
|
||||
|
||||
xfree (block_digest);
|
||||
xfree (payload_digest);
|
||||
free (block_digest);
|
||||
free (payload_digest);
|
||||
|
||||
return warc_write_ok;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
|
||||
void warc_init (void);
|
||||
void warc_close (void);
|
||||
void warc_timestamp (char *timestamp);
|
||||
void warc_uuid_str (char *id_str);
|
||||
|
||||
char * warc_timestamp (char *timestamp, size_t timestamp_size);
|
||||
|
||||
FILE * warc_tempfile (void);
|
||||
|
||||
bool warc_write_request_record (char *url, char *timestamp_str,
|
||||
|
||||
26
src/wget.h
26
src/wget.h
@@ -59,7 +59,7 @@ as that of the covered work. */
|
||||
/* `gettext (FOO)' is long to write, so we use `_(FOO)'. If NLS is
|
||||
unavailable, _(STRING) simply returns STRING. */
|
||||
#include "gettext.h"
|
||||
#define _(STRING) gettext(STRING)
|
||||
#define _(string) gettext (string)
|
||||
|
||||
/* A pseudo function call that serves as a marker for the automated
|
||||
extraction of messages, but does not call gettext(). The run-time
|
||||
@@ -266,7 +266,7 @@ typedef double SUM_SIZE_INT;
|
||||
/* The same as above, except the comparison is case-insensitive. */
|
||||
#define BOUNDED_EQUAL_NO_CASE(beg, end, string_literal) \
|
||||
((end) - (beg) == sizeof (string_literal) - 1 \
|
||||
&& !c_strncasecmp (beg, string_literal, sizeof (string_literal) - 1))
|
||||
&& !strncasecmp (beg, string_literal, sizeof (string_literal) - 1))
|
||||
|
||||
/* Like ptr=strdup(str), but allocates the space for PTR on the stack.
|
||||
This cannot be an expression because this is not portable:
|
||||
@@ -312,15 +312,8 @@ typedef double SUM_SIZE_INT;
|
||||
in base 10. 24082 / 10000 = 8*log_{10}(2). */
|
||||
#define MAX_INT_TO_STRING_LEN(x) ((sizeof(x) * 24082 / 10000) + 2)
|
||||
|
||||
/* Find the minimum or maximum of two provided values */
|
||||
# define MIN(i, j) ((i) <= (j) ? (i) : (j))
|
||||
# define MAX(i, j) ((i) >= (j) ? (i) : (j))
|
||||
|
||||
|
||||
extern const char *exec_name;
|
||||
extern const char *program_name;
|
||||
extern const char *program_argstring;
|
||||
|
||||
|
||||
/* Document type ("dt") flags */
|
||||
enum
|
||||
{
|
||||
@@ -344,16 +337,25 @@ typedef enum
|
||||
FTPOK, FTPLOGINC, FTPLOGREFUSED, FTPPORTERR, FTPSYSERR,
|
||||
FTPNSFOD, FTPUNKNOWNTYPE, FTPRERR,
|
||||
FTPSRVERR, FTPRETRINT, FTPRESTFAIL, URLERROR, FOPENERR,
|
||||
FOPEN_EXCL_ERR, FWRITEERR, HEOF, GATEWAYTIMEOUT,
|
||||
FOPEN_EXCL_ERR, FWRITEERR, HEOF,
|
||||
HERR, RETROK, RECLEVELEXC, WRONGCODE,
|
||||
FTPINVPASV, FTPNOPASV, CONTNOTSUPPORTED, RETRUNNEEDED, RETRFINISHED,
|
||||
READERR, TRYLIMEXC, FILEBADFILE, RANGEERR,
|
||||
RETRBADPATTERN, PROXERR,
|
||||
AUTHFAILED, QUOTEXC, WRITEFAILED, SSLINITFAILED, VERIFCERTERR,
|
||||
UNLINKERR, NEWLOCATION_KEEP_POST, CLOSEFAILED, ATTRMISSING, UNKNOWNATTR,
|
||||
WARC_ERR, WARC_TMP_FOPENERR, WARC_TMP_FWRITEERR
|
||||
WARC_ERR, WARC_TMP_FOPENERR, WARC_TMP_FWRITEERR, THREADS_ERR, SEM_ERR
|
||||
} uerr_t;
|
||||
|
||||
struct range {
|
||||
wgint first_byte;
|
||||
wgint last_byte;
|
||||
wgint bytes_covered;
|
||||
wgint is_assigned;
|
||||
bool *resources;
|
||||
uerr_t status_least_severe;
|
||||
};
|
||||
|
||||
/* 2005-02-19 SMS.
|
||||
Select an appropriate "orig" suffix and a separator character for
|
||||
adding a unique suffix to a file name.
|
||||
|
||||
958
testenv/ChangeLog
Normal file
958
testenv/ChangeLog
Normal file
@@ -0,0 +1,958 @@
|
||||
2014-07-23 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* test/base_test.py (BaseTest.gen_cmd_line): Add support for running all
|
||||
tests through valgrind if the relevant environment variable is set
|
||||
* conf/expected_ret_code (ExpectedRetCode.__call__): Valgrind returns error
|
||||
code 45 when it detects a memory leak.
|
||||
* Readme: Update with details about valgrind tests
|
||||
|
||||
2014-07-22 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* (README): Remove old TODO and document SERVER_WAIT variable
|
||||
|
||||
2014-06-22 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* (conf.files_crawled): diff is a set object and needs explicit str
|
||||
conversion.
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* base_test.py:
|
||||
(CommonMethods): Rename to BaseTest.
|
||||
(BaseTest): Implement __init__ method where the class-wide variables are
|
||||
initialized. Also variable names like `xxx_list` is renamed to its plural
|
||||
form, e.g. `server_list` => `servers`.
|
||||
(BaseTest.init_test_env): Remove name argument due to its unnecessarity.
|
||||
(BaseTest.get_test_dir): Because the path of the test directory is needed
|
||||
in multiple methods, this method is implemented.
|
||||
(BaseTest.get_domain_addr): Rewrite the return statement utilizing str
|
||||
formatting (which is more Pythonic).
|
||||
(BaseTest.get_cmd_line): Rename to gen_cmd_line. Change the variables with
|
||||
capitcal characters to lower ones. Also, the nested for loop is rewritten
|
||||
to a plain loop using the zip function.
|
||||
(BaseTest.__gen_local_filesys): Rename to gen_local_fs_snapshot. Move to
|
||||
ExpectedFiles in conf/expected_files.py and is marked as a static
|
||||
method. Refactor to a less verbose implementation.
|
||||
(BaseTest._check_downloaded_files): Rename to __call__ to agree with the
|
||||
invocation in test case classes. Move to ExpectedFiles in
|
||||
conf/expected_files.py.
|
||||
(BaseTest.get_server_rules): Refactor to a more Pythonic form utilizing
|
||||
dict.items() and is marked static.
|
||||
(BaseTest.stop_server): (new method) an abstract method which should stop
|
||||
the currently using servers.
|
||||
(BaseTest.instantiate_server_by): (new method) an abstract method which
|
||||
should instantiate a server instance according to the given argument.
|
||||
(BaseTest.__enter__): (new method) method which initialize the context
|
||||
manager
|
||||
(BaseTest.__exit__): (new method) method that finilize the context manager
|
||||
and deal with the exceptions during the execution of the with statement,
|
||||
subclasses can override this method for extensibility
|
||||
* http_test.py:
|
||||
(HTTPTest.__init__): Add call to super.__init__. Default values of
|
||||
pre_hook, test_params, post_hook are set to None to avoid a subtle bug of
|
||||
Python. Argument servers is renamed to protocols.
|
||||
(HTTPTest.Server_setup): Move to BaseTest and rename to server_setup.
|
||||
Calls to pre_hook_call, call_test, post_hook_call are removed.
|
||||
(HTTPTest.hook_call, pre_hook_call, call_test, post_hook_call): Move to
|
||||
BaseTest for that both HTTP test cases and FTP test cases may use these
|
||||
methods.
|
||||
(HTTPTest.init_HTTP_Server, init_HTTPS_Server): Merge and rename to
|
||||
instantiate_server_by to implement the abstract method in BaseTest.
|
||||
(HTTPTest.stop_HTTP_Server): Rename to stop_server to implement the
|
||||
abstract method in BaseTest. Also, pull out the part where remaining
|
||||
requests are gathered into a new method request_remaining.
|
||||
(BaseTest.act_retcode): Rename to ret_code because ExpectedRetCode is
|
||||
moved out from BaseTest, so the name act_retcode is actually a bit
|
||||
verbose.
|
||||
* conf/expected_ret_code.py:
|
||||
(ExpectedRetCode.__call__): Rewrite the str into a more readable form.
|
||||
* conf/files_crawled.py:
|
||||
(FilesCrawled.__call__): Refactor this method into a more Pythonic form
|
||||
utilizing the zip function.
|
||||
* conf/local_files.py:
|
||||
(LocalFiles__call__): Rewrite this method with the recommended with
|
||||
statement.
|
||||
* conf/server_conf.py:
|
||||
(ServerConf.__call__): Rewrite this method due to BaseTest.server_list is
|
||||
renamed to BaseTest.servers.
|
||||
* conf/server_files.py:
|
||||
(ServerFiles.__call__): Refactor the nested for loop into a plain one
|
||||
utilizing the zip function.
|
||||
* conf/urls.py:
|
||||
(URLs): Rename url_list to urls.
|
||||
* conf/wget_commands.py:
|
||||
(WgetCommands): Rename command_list to commands, rename test_obj.options
|
||||
to test_obj.wget_options.
|
||||
* Test--https.py, Test-Proto.py, Test-Parallel-Proto.py: Argument servers
|
||||
is changed to protocols due to change in the signature of
|
||||
HTTPTest.__init__.
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* test: (new package) package for test case classes
|
||||
* WgetTest.py: Split into test/base_test.py and test/http_test.py.
|
||||
* Test-*.py: Optimize the imports according to changes of WgetTest.py
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* server: (new package) package for the server classes
|
||||
* server.http: (new package) package for HTTP server
|
||||
* server.ftp: (new package) package for FTP server
|
||||
* HTTPServer.py: Move to server/http/http_server.py. Also change the
|
||||
CERTFILE to '../certs/wget-cert.pem'.
|
||||
* FTPServer.py: Move to server/ftp/ftp_server.py.
|
||||
* WgetTest.py: Optimize import respect to the server classes.
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* conf: (new package) package for rule classes and hook methods
|
||||
* WgetTest.py:
|
||||
(CommonMethods.Authentication): Move to conf/authentication.py.
|
||||
(CommonMethods.ExpectHeader): Move to conf/expect_header.py.
|
||||
(CommonMethods.RejectHeader): Move to conf/reject_header.py.
|
||||
(CommonMethods.Response): Move to conf/response.py.
|
||||
(CommonMethods.SendHeader): Move to conf/send_header.py.
|
||||
(CommonMethods.ServerFiles): Move to conf/server_files.py.
|
||||
(CommonMethods.LocalFiles): Move to conf/local_files.py.
|
||||
(CommonMethods.ServerConf): Move to conf/server_conf.py.
|
||||
(CommonMethods.WgetCommands): Move to conf/wget_commands.py.
|
||||
(CommonMethods.Urls): Move to conf/urls.py.
|
||||
(CommonMethods.ExpectedRetcode): Move to conf/expected_retcode.py.
|
||||
(CommonMethods.ExpectedFiles): Move to conf/expected_files.py.
|
||||
(CommonMethods.FilesCrawled): Move to conf/files_crawled.py.
|
||||
(CommonMethods.__check_downloaded_files): Rename to
|
||||
_check_downloaded_files, so that the method is callable from outside the
|
||||
class.
|
||||
(CommomMethods.get_server_rules): Modify so that it utilizes the conf
|
||||
package.
|
||||
(HTTPTest): Add a method hook_call(configs, name) to reduce duplications
|
||||
in pre_hook_call, call_test and post_hook_call utilizing the conf package.
|
||||
* conf/hook_sample.py: (new file) sample for hooks
|
||||
* conf/rule_sample.py: (new file) sample for rules
|
||||
* REAMDE: Update sections about customizing rules and hooks.
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* exc: (new package) package for miscellaneous exceptions
|
||||
* WgetTest.py: Move TestFailed to exc/test_failed.py.
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* Test-Proto.py: Fix a typo (line 71: server to servers).
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* WgetTest.py: Move WgetFile to package misc.
|
||||
* README: Modify documentation respect to WgetFile.
|
||||
* Test-*.py: Optimize imports about WgetFile.
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* misc: (new package) package for miscellaneous modules
|
||||
* ColourTerm.py: Move to package misc and rename to colour_terminal.py,
|
||||
add print_color functions to reduce the use of string literals like
|
||||
"BLUE", "RED" etc.
|
||||
* WgetTest.py:
|
||||
(CommonMethods.Server_setup): Change invocation to printer to print_blue.
|
||||
(CommonMethods.FilesCrawled): Change invocation to printer to print_red.
|
||||
(HTTPTest.__init__): Change invocations to printer to print_red and
|
||||
print_green respectively.
|
||||
|
||||
2014-01-02 Darshit Shah <darnir@gmail.com>
|
||||
* Makefile.am: Add new Test--https.py to list of tests and EXTRA_DIST.
|
||||
Also replace all tabs with spaces in file for conformity.
|
||||
* Test--https.py: New test to check if Wget works correctly with HTTPS
|
||||
servers
|
||||
* HTTPServer.py: Import new modules for use in HTTPS Servers
|
||||
(HTTPSServer): New class that generates a SSL-wrapped socket for use in a
|
||||
HTTPS Server.
|
||||
(HTTPSd): HTTPS daemon class. Analogous to the HTTPd class
|
||||
* WgetTest.py: Define global variables HTTP and HTTPS to reflect Server
|
||||
types
|
||||
(CommonMethods.exec_wget): Add the protocol information to the URL before
|
||||
passing it to wget
|
||||
(HTTPTest.__init__): Edit syntax. The servers variable now accepts a list of
|
||||
servers defined by their type. E.g. HTTP, HTTPS.
|
||||
(HTTPTest.Server_setup): Reflect change in type of variable servers.
|
||||
However, we maintin the value of self.servers to allow most of the code to
|
||||
remain unchanged.
|
||||
(HTTPTest.init_HTTPS_Server): Initialize a HTTPS Server
|
||||
* Test-Parallel-Proto.py: Edit to reflect slight change in Test Fiel Syntax.
|
||||
* Test-Proto.py: Same
|
||||
|
||||
2014-01-02 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (CommonMentods.exec_wget): Wait for n seconds before calling
|
||||
the Wget executable.
|
||||
|
||||
2013-12-27 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py: Add modeline
|
||||
(CommonMethods.ServerConf): New pre-test hook that sets
|
||||
BaseHTTPRequestHandler class variables in all available servers
|
||||
* HTTPServer.py (HTTPd.ServerConf): Call the respective method in the Server
|
||||
to set the class variables
|
||||
(StoppableHTTPServer.server_sett): Set the handler class variables
|
||||
|
||||
2013-12-26 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (HTTPTest.call_test): Correct the call to stop_HTTP_Server.
|
||||
|
||||
2013-12-25 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (CommonMehtods.exec_wget): Catch and handle exception if the
|
||||
Wget executable is not found at src/wget
|
||||
(HTTPTest.call_test): In case of error during execution, remove all existing
|
||||
servers before quitting
|
||||
|
||||
2013-12-15 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (HTTPTest.HTTP_setup): Rename to Server_setup so it can be
|
||||
easily reused for other non-HTTP servers.
|
||||
(HTTPTest.__init__): Call Server_setup instead of HTTP_setup
|
||||
(HTTPTest.Server_setup): Split into three more functions, that handle
|
||||
pre-hooks, test execution and post-hooks respectively.
|
||||
(HTTPTest.pre_hook_call): Set up and execute the pre-test hooks. Code split
|
||||
from HTTPTest.Server_setup
|
||||
(HTTPTest.call_test): Execute wget and log exit code. Code split from
|
||||
HTTPTest.Server_setup
|
||||
(HTTPTest.post_hook_call): Set up and execute post-test hooks. Code split
|
||||
from HTTPTest.Server_setup
|
||||
|
||||
2013-12-04 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* Makefile.am [RACE_CHECKING_IS_ENABLED]: Define `RACE_FAIL' and
|
||||
RACE_TESTS'.
|
||||
|
||||
2013-10-14 Giuseppe Scrivano <gscrivan@redhat.com>
|
||||
|
||||
* Makefile.am (XFAIL_TESTS): Remove Test--spider-r.py.
|
||||
|
||||
2013-10-06 Giuseppe Scrivano <gscrivan@redhat.com>
|
||||
|
||||
* Makefile.am (EXTRA_DIST): Distribute test files.
|
||||
|
||||
2013-09-16 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* README: Update documentation
|
||||
|
||||
2013-09-14 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* HTTPServer.py (StoppableHTTPServer): Define object variable
|
||||
request_headers which stores a list of requests received by the server
|
||||
(StoppableHTTPServer.get_req_headers): Return the list of Request
|
||||
Headers stored by the server
|
||||
(_Handler.do_HEAD): Send the Request MEthod string for identification
|
||||
(_Handler.do_GET): Same
|
||||
(_Handler.__log_request): Log the request in Request_Headers list
|
||||
(_Handler.send_head): Make a call to __log_request
|
||||
* Test--spider-r.py: Add new list, Request_List, which contains all
|
||||
the requests that Wget is expected to send. This will allow for
|
||||
fine-grained tests on recursive downloading.
|
||||
* WgetTest.py (CommonMethods.FilesCrawled): New Post-Test Hook, that
|
||||
ensures that all the expected Files on the server were accessed as
|
||||
expected.
|
||||
(HTTPTest.stop_HTTP_server): On stopping server, asks it to respond
|
||||
with list of all requests it received.
|
||||
|
||||
2013-09-13 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* Test--spider-r.py: Test retrieval in recursive spider mode.
|
||||
* Makefile.am: add new file
|
||||
|
||||
2013-09-13 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* HTTPServer.py (_Handler.do_HEAD): If requested path is /, respond
|
||||
with /index.html
|
||||
(_Handler.do_HEAD): Smartly guess value of Content-Type Header from
|
||||
file extension
|
||||
(_Handler.guess_type): Use a preset list of extensions and
|
||||
Content-Type strings. If the extension matches one in the list, use
|
||||
that string, else default to "text/plain"
|
||||
|
||||
2013-09-13 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (CommonMethods._replace_substring): New method that will
|
||||
replace a substring delimited by {{ }} characters by the value of
|
||||
self.<substring> variable
|
||||
(CommonMethods.WgetCommands): Use the _replace_substring () call to
|
||||
replace the substrings in the the command line.
|
||||
(CommonMethods.ServerFiles): Run the _replace_substring () method on
|
||||
the File contents too.
|
||||
|
||||
2013-09-11 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (CommonMethods.exec_wget): Expect domain_list instead of
|
||||
domain.
|
||||
(CommonMethods.get_cmd_line): Same. Generate command line by
|
||||
prepending to each file it's respective domain string
|
||||
(CommonMethods.ServerFiles): Generate file_list and server_rules for
|
||||
each Server and set the config details
|
||||
(HTTPTest): New named parameter, servers which signifies number of
|
||||
servers to spawn
|
||||
(HTTPTest.HTTP_setup): This method now takes servers as a new
|
||||
parameter. Instead of storing server and domain, we now store
|
||||
server_list and domain_list. Each server must be initialized through a
|
||||
loop.
|
||||
(HTTPTest.stop_HTTP_server): Stop all servers in a loop.
|
||||
* Test-Parallel-Proto.py: Prototype test file for multiple servers.
|
||||
|
||||
2013-09-10 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (HTTPTest.stop_HTTP_server): With the threaded servers,
|
||||
we can simply use the socketserver.shutdown() method to close the
|
||||
server instead of sending a QUIT command
|
||||
* HTTPServer.py (StoppabelHTTPServer.serve_forever): Delete method. No
|
||||
need to override this method anymore.
|
||||
(WgetHTTPRequestHandler.do_QUIT): No longer required
|
||||
(HTTPd): Rename self.server to self.server_inst to reduce ambiguity
|
||||
when referenced from WgetTest
|
||||
|
||||
2013-09-08 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* README (File Structure): Add explanation about various variables
|
||||
used consistently across all tests.
|
||||
|
||||
2013-09-07 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* HTTPServer.py: Remove bunch of old code artefacts
|
||||
* WgetTest.py: Same
|
||||
|
||||
2013-09-07 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* HTTPServer.py (StoppableHTTPServer.server_conf): Change global
|
||||
variable fileSys to an object variable. This is good programming
|
||||
practice and required for parallel-wget support.
|
||||
(StoppableHTTPServer.server_forever): Edit overridden method to remove
|
||||
the global queue variable. No longer required under the new working
|
||||
(WgetHTTPRequestHandler.do_QUIT): Don't push fileSys through the queue
|
||||
(_Handler): Rename class __Handler to _Handler to match Python's
|
||||
encapsulation rules
|
||||
(_Handler.do_POST): fileSys is now an object variable of the server
|
||||
(_Handler.do_PUT): Same
|
||||
(_Handler.send_put): Same
|
||||
(_Handler.send_head): Same
|
||||
(HTTPd): New class that wraps around the server for Threading
|
||||
(create_server): Make new object of HTTPd.
|
||||
(spawn_server): Start the thread created through create_server
|
||||
(ret_fileSys): Removed method. No longer required.
|
||||
* WgetTest.py (HTTPTest.__init__): Don't explicitly set
|
||||
self.act_retcode. Instead toggle tests_passed boolean to set the
|
||||
correct return code.
|
||||
(HTTPTest.HTTP_setup): We no longer call HTTPServer.spawn_server to
|
||||
start a new instance of the server.
|
||||
(HTTPTest.init_HTTP_server): We no longer call the old
|
||||
create_server(), spawn_server() methods. Instead use the new HTTPd
|
||||
class interface to create new instances of the server
|
||||
(HTTPTest.stop_HTTP_server): Don't ask server to return fileSys.
|
||||
|
||||
2013-09-07 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* Test-Post.py: Test basic functionality for sending HTTP POST
|
||||
requests using the --method command
|
||||
* Makefile.am: Add new test
|
||||
|
||||
2013-09-06 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (CommonMethods.__check_downloaded_files): Print a
|
||||
unified diff in case there is a mismatch in the file contents
|
||||
|
||||
2013-09-06 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* HTTPServer.py (WgetHTTPRequestHandler.test_cookies): Comment out the
|
||||
old test_cookies code. This is no longer used and was causing problems
|
||||
with expected cookies. The code will soon be removed anyways
|
||||
* Test-cookie.py: Add new test for basic cookie functionality
|
||||
* Test-cookie-401.py: Ensure cookies are saved during a 401 response
|
||||
* Test-cookie-expires.py: Ensure that the Expires field is correctly
|
||||
handled
|
||||
* Test-cookies-domain-mismatch.py: Ensure that mismatched domains are
|
||||
handled by Wget
|
||||
* Makefile.am: Add the new tests
|
||||
|
||||
2013-09-06 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* README: New section on pending work. Will keep updating this to keep
|
||||
track of work that remains to be done on this implementation
|
||||
|
||||
2013-09-05 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* Test-auth-with-content-disposition.py: Add test that ensures Content
|
||||
Disposition works alongwith authentication
|
||||
* Makefile.am: Add new test
|
||||
|
||||
2013-09-04 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* Test-c-full.py: Test Continue options
|
||||
* Makefile.am: Add Test-c-full.py and Test-O
|
||||
|
||||
2013-09-02 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* Makefile.am: Add new Test
|
||||
* Test-Head.py: New Test to ensure HEAD requests are handled correctly
|
||||
|
||||
2013-08-31 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* README: Explain that TEST_NAME needs to be unique
|
||||
* Test-auth-no-challenge.py: Edit non-unique TEST_NAME
|
||||
|
||||
2013-08-31 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* HTTPTest.py (ServerError): Define new Exception for handling
|
||||
internal control flow.
|
||||
(StoppableHTTPServer.SendHeader): Simply pass. Do nothing. Adding
|
||||
functionality here seems to crash for no apparent reason.
|
||||
(stoppableHTTPServer.send_cust_headers): Minor optimization. No need
|
||||
for extra variable.
|
||||
(__Handler.Response): Handle explicit Response Code Rules
|
||||
(__Handler.Authentication): Handle Authentication rules
|
||||
(__Handler.handle_auth): Actual worker method for authentication
|
||||
(__Handler.ExpectHeader): Ensure Expected Headers are received
|
||||
(__Handler.RejectHeader): Ensure Blacklisted Headers are NOT received
|
||||
(__Handler.send_HEAD): Dynamically call server rule functions based on
|
||||
the self.rules list. This feature will later be added to POST/PUT, etc
|
||||
|
||||
2013-08-31 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py: Remove import module defaultdict.
|
||||
(CommonMethods.get_server_rules): server_rules should be a dict, not a
|
||||
defaultdict (list).
|
||||
* HTTPServer.py (WgetHTTPRequestHandler.get_rule_list): If rule does
|
||||
not exist, return None. Not an emppty list.
|
||||
(WgetHTTPRequestHandler.test_cookies): Rule variable is not a list
|
||||
(__Handler.send_cust_headers): Same
|
||||
(__Handler.custom_response): Same
|
||||
(__Handler.is_authorized): Same
|
||||
(__Handler.expect_headers): Same
|
||||
(__Handler.reject_headers): Same
|
||||
|
||||
2013-08-31 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* README: (newfile) Simple help / instructions about using the Test
|
||||
Environment.
|
||||
* Makefile.am: (newfile) Makefile for the Test Environment. Uses the
|
||||
Automake Parallel Test Harness
|
||||
* WgetTest.py: (newfile) Base module that executes the Test.
|
||||
* HTTPServer.py: (newfile) Contains the custom HTTP Server for the
|
||||
Test Environment. Creates an instance of http.server in Python3.
|
||||
* FTPServer.py: (newfile) Overrides methods from pyftpdlib for use in
|
||||
the Test Environment. ** Work under progress **.
|
||||
* ColourTerm.py: (newfile) A custom module to output coloured text to
|
||||
the terminal. Known to work on POSIX shells.
|
||||
* Test-Proto.py: (newfile) A prototype Test File. This should be
|
||||
copied when writing a new Test Case.
|
||||
* Test-Content-disposition-2.py: Test Content Disposition clobbering
|
||||
* Test-Content-disposition.py: Test Content Disposition Headers
|
||||
* Test-O.py: Test Output filename command
|
||||
* Test-auth-basic-fail.py: Test returncode on auth failure
|
||||
* Test-auth-basic.py: Test Basic Auth negotiation
|
||||
* Test-auth-both.py: Test handling of Multiple auth providers. This
|
||||
test currently fails.
|
||||
* Test-auth-digest.py: Test Digest Auth Negotiation
|
||||
* Test-auth-no-challenge-url.py: Ensure --auth-no-challenge is handled
|
||||
when auth details are in-URL.
|
||||
* Test-auth-no-challenge.py: Ensure --auth-no-challenge is honoured
|
||||
* Test-auth-retcode.py: Ensure correct return code after 403 Forbidden
|
||||
response.
|
||||
2014-08-08 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* conf/__init__.py: Add extra newline according to PEP8
|
||||
* conf/{authentication,expect_header,expected_files,expected_ret_code,
|
||||
files_crawled,hook_sample,local_files,reject_header,response,send_header,
|
||||
server_files,urls,wget_commands}.py: Add docstrings explaining the conf file
|
||||
and how it should be used
|
||||
* server/http/http_server (InvalidRangeHeader): Clear TODO and eliminate
|
||||
this exception. Use ServerError for all such purposes.
|
||||
(_Handler): Remove reference to InvalidRangeHeader
|
||||
(_handler.parse_range_header): User ServerError instead of InvalidRangeHeader
|
||||
(_Handler.do_GET): Add docstring
|
||||
(_Handler.do_POST): Add docstring. Also create an empty dict for rules if
|
||||
no rules are supplied. Send the Location header as suggested in RFC 7231
|
||||
(_Handler.do_PUT): Don't pop the server file already. Push it to later in ..
|
||||
(_Handler.send_put): .. Here. If the file exists respond with a 204 No
|
||||
Content message and pop the file for replacement. Do not send the
|
||||
Content-Length, Content-Type headers since PUT requests should not respond
|
||||
with data.
|
||||
(_Handler.parse_auth_header): Fit line within 80 chars
|
||||
(_Handler.check_response): Better visual indent
|
||||
(_Handler.authorize_digest): Better visual indent.
|
||||
(_Handler.expect_headers): Remove unused function
|
||||
(_Handler.guess_type): Fix indentation
|
||||
(HTTPd): Add newline according to PEP8 guidelines
|
||||
(HTTPSd): Fix indentation
|
||||
(StoppableHTTPServer): Add docstring
|
||||
(HTTPSServer): Fix indentation
|
||||
(WgetHTTPRequestHandler): Merge class into _handler.
|
||||
(_Handler): Add docstring
|
||||
(_Handler.parse_range_header): Fix indentation
|
||||
(ServerError): Split exception into separate file ...
|
||||
* exc/server_error.py: ... Here
|
||||
* misc/colour_terminal.py: Add docstring, fix indentation
|
||||
* test/base_test.py: Fix visual indent
|
||||
* test/http_test.py: Fit within 80 char lines
|
||||
|
||||
2014-08-04 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* conf/server_conf.py: Delete file. Server configuration is now done via the
|
||||
server_conf() method.
|
||||
* server/http/http_server.py (StppableHTTPServer.server_sett): Delete
|
||||
method required by the above hook
|
||||
(HTTPd.server_sett): Same
|
||||
|
||||
2014-07-26 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* Test-*.py: Remove the '-d' switch from WGET_OPTIONS.
|
||||
* test/base_test (BaseTest.gen_cmd_line): Add --debug and --no-config to the
|
||||
list of switches passed to wget unconditionally.
|
||||
|
||||
2014-07-23 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* test/base_test.py (BaseTest.gen_cmd_line): Add support for running all
|
||||
tests through valgrind if the relevant environment variable is set
|
||||
* conf/expected_ret_code (ExpectedRetCode.__call__): Valgrind returns error
|
||||
code 45 when it detects a memory leak.
|
||||
* Readme: Update with details about valgrind tests
|
||||
|
||||
2014-07-22 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* (README): Remove old TODO and document SERVER_WAIT variable
|
||||
|
||||
2014-06-22 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* (conf.files_crawled): diff is a set object and needs explicit str
|
||||
conversion.
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* base_test.py:
|
||||
(CommonMethods): Rename to BaseTest.
|
||||
(BaseTest): Implement __init__ method where the class-wide variables are
|
||||
initialized. Also variable names like `xxx_list` is renamed to its plural
|
||||
form, e.g. `server_list` => `servers`.
|
||||
(BaseTest.init_test_env): Remove name argument due to its unnecessarity.
|
||||
(BaseTest.get_test_dir): Because the path of the test directory is needed
|
||||
in multiple methods, this method is implemented.
|
||||
(BaseTest.get_domain_addr): Rewrite the return statement utilizing str
|
||||
formatting (which is more Pythonic).
|
||||
(BaseTest.get_cmd_line): Rename to gen_cmd_line. Change the variables with
|
||||
capitcal characters to lower ones. Also, the nested for loop is rewritten
|
||||
to a plain loop using the zip function.
|
||||
(BaseTest.__gen_local_filesys): Rename to gen_local_fs_snapshot. Move to
|
||||
ExpectedFiles in conf/expected_files.py and is marked as a static
|
||||
method. Refactor to a less verbose implementation.
|
||||
(BaseTest._check_downloaded_files): Rename to __call__ to agree with the
|
||||
invocation in test case classes. Move to ExpectedFiles in
|
||||
conf/expected_files.py.
|
||||
(BaseTest.get_server_rules): Refactor to a more Pythonic form utilizing
|
||||
dict.items() and is marked static.
|
||||
(BaseTest.stop_server): (new method) an abstract method which should stop
|
||||
the currently using servers.
|
||||
(BaseTest.instantiate_server_by): (new method) an abstract method which
|
||||
should instantiate a server instance according to the given argument.
|
||||
(BaseTest.__enter__): (new method) method which initialize the context
|
||||
manager
|
||||
(BaseTest.__exit__): (new method) method that finilize the context manager
|
||||
and deal with the exceptions during the execution of the with statement,
|
||||
subclasses can override this method for extensibility
|
||||
* http_test.py:
|
||||
(HTTPTest.__init__): Add call to super.__init__. Default values of
|
||||
pre_hook, test_params, post_hook are set to None to avoid a subtle bug of
|
||||
Python. Argument servers is renamed to protocols.
|
||||
(HTTPTest.Server_setup): Move to BaseTest and rename to server_setup.
|
||||
Calls to pre_hook_call, call_test, post_hook_call are removed.
|
||||
(HTTPTest.hook_call, pre_hook_call, call_test, post_hook_call): Move to
|
||||
BaseTest for that both HTTP test cases and FTP test cases may use these
|
||||
methods.
|
||||
(HTTPTest.init_HTTP_Server, init_HTTPS_Server): Merge and rename to
|
||||
instantiate_server_by to implement the abstract method in BaseTest.
|
||||
(HTTPTest.stop_HTTP_Server): Rename to stop_server to implement the
|
||||
abstract method in BaseTest. Also, pull out the part where remaining
|
||||
requests are gathered into a new method request_remaining.
|
||||
(BaseTest.act_retcode): Rename to ret_code because ExpectedRetCode is
|
||||
moved out from BaseTest, so the name act_retcode is actually a bit
|
||||
verbose.
|
||||
* conf/expected_ret_code.py:
|
||||
(ExpectedRetCode.__call__): Rewrite the str into a more readable form.
|
||||
* conf/files_crawled.py:
|
||||
(FilesCrawled.__call__): Refactor this method into a more Pythonic form
|
||||
utilizing the zip function.
|
||||
* conf/local_files.py:
|
||||
(LocalFiles__call__): Rewrite this method with the recommended with
|
||||
statement.
|
||||
* conf/server_conf.py:
|
||||
(ServerConf.__call__): Rewrite this method due to BaseTest.server_list is
|
||||
renamed to BaseTest.servers.
|
||||
* conf/server_files.py:
|
||||
(ServerFiles.__call__): Refactor the nested for loop into a plain one
|
||||
utilizing the zip function.
|
||||
* conf/urls.py:
|
||||
(URLs): Rename url_list to urls.
|
||||
* conf/wget_commands.py:
|
||||
(WgetCommands): Rename command_list to commands, rename test_obj.options
|
||||
to test_obj.wget_options.
|
||||
* Test--https.py, Test-Proto.py, Test-Parallel-Proto.py: Argument servers
|
||||
is changed to protocols due to change in the signature of
|
||||
HTTPTest.__init__.
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* test: (new package) package for test case classes
|
||||
* WgetTest.py: Split into test/base_test.py and test/http_test.py.
|
||||
* Test-*.py: Optimize the imports according to changes of WgetTest.py
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* server: (new package) package for the server classes
|
||||
* server.http: (new package) package for HTTP server
|
||||
* server.ftp: (new package) package for FTP server
|
||||
* HTTPServer.py: Move to server/http/http_server.py. Also change the
|
||||
CERTFILE to '../certs/wget-cert.pem'.
|
||||
* FTPServer.py: Move to server/ftp/ftp_server.py.
|
||||
* WgetTest.py: Optimize import respect to the server classes.
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* conf: (new package) package for rule classes and hook methods
|
||||
* WgetTest.py:
|
||||
(CommonMethods.Authentication): Move to conf/authentication.py.
|
||||
(CommonMethods.ExpectHeader): Move to conf/expect_header.py.
|
||||
(CommonMethods.RejectHeader): Move to conf/reject_header.py.
|
||||
(CommonMethods.Response): Move to conf/response.py.
|
||||
(CommonMethods.SendHeader): Move to conf/send_header.py.
|
||||
(CommonMethods.ServerFiles): Move to conf/server_files.py.
|
||||
(CommonMethods.LocalFiles): Move to conf/local_files.py.
|
||||
(CommonMethods.ServerConf): Move to conf/server_conf.py.
|
||||
(CommonMethods.WgetCommands): Move to conf/wget_commands.py.
|
||||
(CommonMethods.Urls): Move to conf/urls.py.
|
||||
(CommonMethods.ExpectedRetcode): Move to conf/expected_retcode.py.
|
||||
(CommonMethods.ExpectedFiles): Move to conf/expected_files.py.
|
||||
(CommonMethods.FilesCrawled): Move to conf/files_crawled.py.
|
||||
(CommonMethods.__check_downloaded_files): Rename to
|
||||
_check_downloaded_files, so that the method is callable from outside the
|
||||
class.
|
||||
(CommomMethods.get_server_rules): Modify so that it utilizes the conf
|
||||
package.
|
||||
(HTTPTest): Add a method hook_call(configs, name) to reduce duplications
|
||||
in pre_hook_call, call_test and post_hook_call utilizing the conf package.
|
||||
* conf/hook_sample.py: (new file) sample for hooks
|
||||
* conf/rule_sample.py: (new file) sample for rules
|
||||
* REAMDE: Update sections about customizing rules and hooks.
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* exc: (new package) package for miscellaneous exceptions
|
||||
* WgetTest.py: Move TestFailed to exc/test_failed.py.
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* Test-Proto.py: Fix a typo (line 71: server to servers).
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* WgetTest.py: Move WgetFile to package misc.
|
||||
* README: Modify documentation respect to WgetFile.
|
||||
* Test-*.py: Optimize imports about WgetFile.
|
||||
|
||||
2014-03-13 Zihang Chen <chsc4698@gmail.com>
|
||||
|
||||
* misc: (new package) package for miscellaneous modules
|
||||
* ColourTerm.py: Move to package misc and rename to colour_terminal.py,
|
||||
add print_color functions to reduce the use of string literals like
|
||||
"BLUE", "RED" etc.
|
||||
* WgetTest.py:
|
||||
(CommonMethods.Server_setup): Change invocation to printer to print_blue.
|
||||
(CommonMethods.FilesCrawled): Change invocation to printer to print_red.
|
||||
(HTTPTest.__init__): Change invocations to printer to print_red and
|
||||
print_green respectively.
|
||||
|
||||
2014-01-02 Darshit Shah <darnir@gmail.com>
|
||||
* Makefile.am: Add new Test--https.py to list of tests and EXTRA_DIST.
|
||||
Also replace all tabs with spaces in file for conformity.
|
||||
* Test--https.py: New test to check if Wget works correctly with HTTPS
|
||||
servers
|
||||
* HTTPServer.py: Import new modules for use in HTTPS Servers
|
||||
(HTTPSServer): New class that generates a SSL-wrapped socket for use in a
|
||||
HTTPS Server.
|
||||
(HTTPSd): HTTPS daemon class. Analogous to the HTTPd class
|
||||
* WgetTest.py: Define global variables HTTP and HTTPS to reflect Server
|
||||
types
|
||||
(CommonMethods.exec_wget): Add the protocol information to the URL before
|
||||
passing it to wget
|
||||
(HTTPTest.__init__): Edit syntax. The servers variable now accepts a list of
|
||||
servers defined by their type. E.g. HTTP, HTTPS.
|
||||
(HTTPTest.Server_setup): Reflect change in type of variable servers.
|
||||
However, we maintin the value of self.servers to allow most of the code to
|
||||
remain unchanged.
|
||||
(HTTPTest.init_HTTPS_Server): Initialize a HTTPS Server
|
||||
* Test-Parallel-Proto.py: Edit to reflect slight change in Test Fiel Syntax.
|
||||
* Test-Proto.py: Same
|
||||
|
||||
2014-01-02 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (CommonMentods.exec_wget): Wait for n seconds before calling
|
||||
the Wget executable.
|
||||
|
||||
2013-12-27 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py: Add modeline
|
||||
(CommonMethods.ServerConf): New pre-test hook that sets
|
||||
BaseHTTPRequestHandler class variables in all available servers
|
||||
* HTTPServer.py (HTTPd.ServerConf): Call the respective method in the Server
|
||||
to set the class variables
|
||||
(StoppableHTTPServer.server_sett): Set the handler class variables
|
||||
|
||||
2013-12-26 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (HTTPTest.call_test): Correct the call to stop_HTTP_Server.
|
||||
|
||||
2013-12-25 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (CommonMehtods.exec_wget): Catch and handle exception if the
|
||||
Wget executable is not found at src/wget
|
||||
(HTTPTest.call_test): In case of error during execution, remove all existing
|
||||
servers before quitting
|
||||
|
||||
2013-12-15 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (HTTPTest.HTTP_setup): Rename to Server_setup so it can be
|
||||
easily reused for other non-HTTP servers.
|
||||
(HTTPTest.__init__): Call Server_setup instead of HTTP_setup
|
||||
(HTTPTest.Server_setup): Split into three more functions, that handle
|
||||
pre-hooks, test execution and post-hooks respectively.
|
||||
(HTTPTest.pre_hook_call): Set up and execute the pre-test hooks. Code split
|
||||
from HTTPTest.Server_setup
|
||||
(HTTPTest.call_test): Execute wget and log exit code. Code split from
|
||||
HTTPTest.Server_setup
|
||||
(HTTPTest.post_hook_call): Set up and execute post-test hooks. Code split
|
||||
from HTTPTest.Server_setup
|
||||
|
||||
2013-10-14 Giuseppe Scrivano <gscrivan@redhat.com>
|
||||
|
||||
* Makefile.am (XFAIL_TESTS): Remove Test--spider-r.py.
|
||||
|
||||
2013-10-06 Giuseppe Scrivano <gscrivan@redhat.com>
|
||||
|
||||
* Makefile.am (EXTRA_DIST): Distribute test files.
|
||||
|
||||
2013-09-16 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* README: Update documentation
|
||||
|
||||
2013-09-14 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* HTTPServer.py (StoppableHTTPServer): Define object variable
|
||||
request_headers which stores a list of requests received by the server
|
||||
(StoppableHTTPServer.get_req_headers): Return the list of Request
|
||||
Headers stored by the server
|
||||
(_Handler.do_HEAD): Send the Request MEthod string for identification
|
||||
(_Handler.do_GET): Same
|
||||
(_Handler.__log_request): Log the request in Request_Headers list
|
||||
(_Handler.send_head): Make a call to __log_request
|
||||
* Test--spider-r.py: Add new list, Request_List, which contains all
|
||||
the requests that Wget is expected to send. This will allow for
|
||||
fine-grained tests on recursive downloading.
|
||||
* WgetTest.py (CommonMethods.FilesCrawled): New Post-Test Hook, that
|
||||
ensures that all the expected Files on the server were accessed as
|
||||
expected.
|
||||
(HTTPTest.stop_HTTP_server): On stopping server, asks it to respond
|
||||
with list of all requests it received.
|
||||
|
||||
2013-09-13 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* Test--spider-r.py: Test retrieval in recursive spider mode.
|
||||
* Makefile.am: add new file
|
||||
|
||||
2013-09-13 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* HTTPServer.py (_Handler.do_HEAD): If requested path is /, respond
|
||||
with /index.html
|
||||
(_Handler.do_HEAD): Smartly guess value of Content-Type Header from
|
||||
file extension
|
||||
(_Handler.guess_type): Use a preset list of extensions and
|
||||
Content-Type strings. If the extension matches one in the list, use
|
||||
that string, else default to "text/plain"
|
||||
|
||||
2013-09-13 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (CommonMethods._replace_substring): New method that will
|
||||
replace a substring delimited by {{ }} characters by the value of
|
||||
self.<substring> variable
|
||||
(CommonMethods.WgetCommands): Use the _replace_substring () call to
|
||||
replace the substrings in the the command line.
|
||||
(CommonMethods.ServerFiles): Run the _replace_substring () method on
|
||||
the File contents too.
|
||||
|
||||
2013-09-11 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (CommonMethods.exec_wget): Expect domain_list instead of
|
||||
domain.
|
||||
(CommonMethods.get_cmd_line): Same. Generate command line by
|
||||
prepending to each file it's respective domain string
|
||||
(CommonMethods.ServerFiles): Generate file_list and server_rules for
|
||||
each Server and set the config details
|
||||
(HTTPTest): New named parameter, servers which signifies number of
|
||||
servers to spawn
|
||||
(HTTPTest.HTTP_setup): This method now takes servers as a new
|
||||
parameter. Instead of storing server and domain, we now store
|
||||
server_list and domain_list. Each server must be initialized through a
|
||||
loop.
|
||||
(HTTPTest.stop_HTTP_server): Stop all servers in a loop.
|
||||
* Test-Parallel-Proto.py: Prototype test file for multiple servers.
|
||||
|
||||
2013-09-10 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (HTTPTest.stop_HTTP_server): With the threaded servers,
|
||||
we can simply use the socketserver.shutdown() method to close the
|
||||
server instead of sending a QUIT command
|
||||
* HTTPServer.py (StoppabelHTTPServer.serve_forever): Delete method. No
|
||||
need to override this method anymore.
|
||||
(WgetHTTPRequestHandler.do_QUIT): No longer required
|
||||
(HTTPd): Rename self.server to self.server_inst to reduce ambiguity
|
||||
when referenced from WgetTest
|
||||
|
||||
2013-09-08 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* README (File Structure): Add explanation about various variables
|
||||
used consistently across all tests.
|
||||
|
||||
2013-09-07 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* HTTPServer.py: Remove bunch of old code artefacts
|
||||
* WgetTest.py: Same
|
||||
|
||||
2013-09-07 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* HTTPServer.py (StoppableHTTPServer.server_conf): Change global
|
||||
variable fileSys to an object variable. This is good programming
|
||||
practice and required for parallel-wget support.
|
||||
(StoppableHTTPServer.server_forever): Edit overridden method to remove
|
||||
the global queue variable. No longer required under the new working
|
||||
(WgetHTTPRequestHandler.do_QUIT): Don't push fileSys through the queue
|
||||
(_Handler): Rename class __Handler to _Handler to match Python's
|
||||
encapsulation rules
|
||||
(_Handler.do_POST): fileSys is now an object variable of the server
|
||||
(_Handler.do_PUT): Same
|
||||
(_Handler.send_put): Same
|
||||
(_Handler.send_head): Same
|
||||
(HTTPd): New class that wraps around the server for Threading
|
||||
(create_server): Make new object of HTTPd.
|
||||
(spawn_server): Start the thread created through create_server
|
||||
(ret_fileSys): Removed method. No longer required.
|
||||
* WgetTest.py (HTTPTest.__init__): Don't explicitly set
|
||||
self.act_retcode. Instead toggle tests_passed boolean to set the
|
||||
correct return code.
|
||||
(HTTPTest.HTTP_setup): We no longer call HTTPServer.spawn_server to
|
||||
start a new instance of the server.
|
||||
(HTTPTest.init_HTTP_server): We no longer call the old
|
||||
create_server(), spawn_server() methods. Instead use the new HTTPd
|
||||
class interface to create new instances of the server
|
||||
(HTTPTest.stop_HTTP_server): Don't ask server to return fileSys.
|
||||
|
||||
2013-09-07 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* Test-Post.py: Test basic functionality for sending HTTP POST
|
||||
requests using the --method command
|
||||
* Makefile.am: Add new test
|
||||
|
||||
2013-09-06 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py (CommonMethods.__check_downloaded_files): Print a
|
||||
unified diff in case there is a mismatch in the file contents
|
||||
|
||||
2013-09-06 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* HTTPServer.py (WgetHTTPRequestHandler.test_cookies): Comment out the
|
||||
old test_cookies code. This is no longer used and was causing problems
|
||||
with expected cookies. The code will soon be removed anyways
|
||||
* Test-cookie.py: Add new test for basic cookie functionality
|
||||
* Test-cookie-401.py: Ensure cookies are saved during a 401 response
|
||||
* Test-cookie-expires.py: Ensure that the Expires field is correctly
|
||||
handled
|
||||
* Test-cookies-domain-mismatch.py: Ensure that mismatched domains are
|
||||
handled by Wget
|
||||
* Makefile.am: Add the new tests
|
||||
|
||||
2013-09-06 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* README: New section on pending work. Will keep updating this to keep
|
||||
track of work that remains to be done on this implementation
|
||||
|
||||
2013-09-05 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* Test-auth-with-content-disposition.py: Add test that ensures Content
|
||||
Disposition works alongwith authentication
|
||||
* Makefile.am: Add new test
|
||||
|
||||
2013-09-04 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* Test-c-full.py: Test Continue options
|
||||
* Makefile.am: Add Test-c-full.py and Test-O
|
||||
|
||||
2013-09-02 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* Makefile.am: Add new Test
|
||||
* Test-Head.py: New Test to ensure HEAD requests are handled correctly
|
||||
|
||||
2013-08-31 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* README: Explain that TEST_NAME needs to be unique
|
||||
* Test-auth-no-challenge.py: Edit non-unique TEST_NAME
|
||||
|
||||
2013-08-31 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* HTTPTest.py (ServerError): Define new Exception for handling
|
||||
internal control flow.
|
||||
(StoppableHTTPServer.SendHeader): Simply pass. Do nothing. Adding
|
||||
functionality here seems to crash for no apparent reason.
|
||||
(stoppableHTTPServer.send_cust_headers): Minor optimization. No need
|
||||
for extra variable.
|
||||
(__Handler.Response): Handle explicit Response Code Rules
|
||||
(__Handler.Authentication): Handle Authentication rules
|
||||
(__Handler.handle_auth): Actual worker method for authentication
|
||||
(__Handler.ExpectHeader): Ensure Expected Headers are received
|
||||
(__Handler.RejectHeader): Ensure Blacklisted Headers are NOT received
|
||||
(__Handler.send_HEAD): Dynamically call server rule functions based on
|
||||
the self.rules list. This feature will later be added to POST/PUT, etc
|
||||
|
||||
2013-08-31 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* WgetTest.py: Remove import module defaultdict.
|
||||
(CommonMethods.get_server_rules): server_rules should be a dict, not a
|
||||
defaultdict (list).
|
||||
* HTTPServer.py (WgetHTTPRequestHandler.get_rule_list): If rule does
|
||||
not exist, return None. Not an emppty list.
|
||||
(WgetHTTPRequestHandler.test_cookies): Rule variable is not a list
|
||||
(__Handler.send_cust_headers): Same
|
||||
(__Handler.custom_response): Same
|
||||
(__Handler.is_authorized): Same
|
||||
(__Handler.expect_headers): Same
|
||||
(__Handler.reject_headers): Same
|
||||
|
||||
2013-08-31 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* README: (newfile) Simple help / instructions about using the Test
|
||||
Environment.
|
||||
* Makefile.am: (newfile) Makefile for the Test Environment. Uses the
|
||||
Automake Parallel Test Harness
|
||||
* WgetTest.py: (newfile) Base module that executes the Test.
|
||||
* HTTPServer.py: (newfile) Contains the custom HTTP Server for the
|
||||
Test Environment. Creates an instance of http.server in Python3.
|
||||
* FTPServer.py: (newfile) Overrides methods from pyftpdlib for use in
|
||||
the Test Environment. ** Work under progress **.
|
||||
* ColourTerm.py: (newfile) A custom module to output coloured text to
|
||||
the terminal. Known to work on POSIX shells.
|
||||
* Test-Proto.py: (newfile) A prototype Test File. This should be
|
||||
copied when writing a new Test Case.
|
||||
* Test-Content-disposition-2.py: Test Content Disposition clobbering
|
||||
* Test-Content-disposition.py: Test Content Disposition Headers
|
||||
* Test-O.py: Test Output filename command
|
||||
* Test-auth-basic-fail.py: Test returncode on auth failure
|
||||
* Test-auth-basic.py: Test Basic Auth negotiation
|
||||
* Test-auth-both.py: Test handling of Multiple auth providers. This
|
||||
test currently fails.
|
||||
* Test-auth-digest.py: Test Digest Auth Negotiation
|
||||
* Test-auth-no-challenge-url.py: Ensure --auth-no-challenge is handled
|
||||
when auth details are in-URL.
|
||||
* Test-auth-no-challenge.py: Ensure --auth-no-challenge is honoured
|
||||
* Test-auth-retcode.py: Ensure correct return code after 403 Forbidden
|
||||
response.
|
||||
@@ -27,10 +27,14 @@
|
||||
|
||||
|
||||
AUTOMAKE_OPTIONS = parallel-tests
|
||||
AM_TESTS_ENVIRONMENT = export WGETRC=/dev/null; MAKE_CHECK=True; export MAKE_CHECK;\
|
||||
export PYTHONPATH=$$PYTHONPATH:$(srcdir); export VALGRIND_TESTS="@VALGRIND_TESTS@";
|
||||
if HAVE_PYTHON3
|
||||
TESTS = Test-auth-basic-fail.py \
|
||||
AM_TESTS_ENVIRONMENT = MAKE_CHECK=True; export MAKE_CHECK;
|
||||
|
||||
if RACE_CHECKING_IS_ENABLED
|
||||
RACE_FAIL = Test--spider-r.py
|
||||
RACE_TESTS =
|
||||
endif
|
||||
|
||||
TESTS = Test-auth-basic-fail.py \
|
||||
Test-auth-basic.py \
|
||||
Test-auth-both.py \
|
||||
Test-auth-digest.py \
|
||||
@@ -45,21 +49,42 @@ if HAVE_PYTHON3
|
||||
Test-cookie-domain-mismatch.py \
|
||||
Test-cookie-expires.py \
|
||||
Test-cookie.py \
|
||||
$(RACE_TESTS) \
|
||||
Test-Head.py \
|
||||
Test--https.py \
|
||||
Test--https-crl.py \
|
||||
Test--https.py \
|
||||
Test-O.py \
|
||||
Test-Post.py \
|
||||
Test-504.py \
|
||||
Test--spider-r.py \
|
||||
Test-redirect-crash.py
|
||||
Test--spider-r.py
|
||||
|
||||
# added test cases expected to fail here and under TESTS
|
||||
XFAIL_TESTS =
|
||||
endif
|
||||
XFAIL_TESTS = Test-auth-both.py \
|
||||
$(RACE_FAIL)
|
||||
|
||||
EXTRA_DIST = certs conf exc misc server test README $(TESTS) $(XFAIL_TESTS)
|
||||
LOG_COMPILER = python3
|
||||
|
||||
TEST_EXTENSIONS = .py
|
||||
PY_LOG_COMPILER = python3
|
||||
AM_PY_LOG_FLAGS = -O
|
||||
EXTRA_DIST = ColourTerm.py \
|
||||
FTPServer.py \
|
||||
HTTPServer.py \
|
||||
README \
|
||||
Test--spider-r.py \
|
||||
Test--https.py \
|
||||
Test-Content-disposition-2.py \
|
||||
Test-Content-disposition.py \
|
||||
Test-Head.py \
|
||||
Test-O.py \
|
||||
Test-Parallel-Proto.py \
|
||||
Test-Post.py \
|
||||
Test-Proto.py \
|
||||
Test-auth-basic-fail.py \
|
||||
Test-auth-basic.py \
|
||||
Test-auth-both.py \
|
||||
Test-auth-digest.py \
|
||||
Test-auth-no-challenge-url.py \
|
||||
Test-auth-no-challenge.py \
|
||||
Test-auth-retcode.py \
|
||||
Test-auth-with-content-disposition.py \
|
||||
Test-c-full.py \
|
||||
Test-cookie-401.py \
|
||||
Test-cookie-domain-mismatch.py \
|
||||
Test-cookie-expires.py \
|
||||
Test-cookie.py \
|
||||
WgetTest.py
|
||||
|
||||
@@ -93,10 +93,8 @@ Environment Variables:
|
||||
valgrind.
|
||||
* NO_CLEANUP: Do not remove the temporary files created by the test.
|
||||
This will prevent the ${testname}-test directory from being deleted
|
||||
* VALGRIND_TESTS: If this variable is set and contains the valgrind command line,
|
||||
the test suite will execute all the tests via this command.
|
||||
If it is set to "1", valgrind memcheck is enabled with hard coded options.
|
||||
This variable is set by ./configure --enable-valgrind-tests.
|
||||
* VALGRIND_TESTS: If this variable is set, the test suite will execute all the
|
||||
tests through valgrind's memcheck tool.
|
||||
|
||||
|
||||
File Structure:
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
from sys import exit
|
||||
from test.http_test import HTTPTest
|
||||
from test.base_test import HTTP, HTTPS
|
||||
from misc.wget_file import WgetFile
|
||||
import os
|
||||
|
||||
"""
|
||||
This test ensures that Wget can download files from HTTPS Servers
|
||||
"""
|
||||
TEST_NAME = "HTTPS CRL"
|
||||
############# File Definitions ###############################################
|
||||
File1 = "Would you like some Tea?"
|
||||
File2 = "With lemon or cream?"
|
||||
|
||||
A_File = WgetFile ("File1", File1)
|
||||
B_File = WgetFile ("File2", File2)
|
||||
|
||||
CAFILE = os.path.abspath(os.path.join(os.getenv('srcdir', '.'), 'certs', 'ca-cert.pem'))
|
||||
CRLFILE = os.path.abspath(os.path.join(os.getenv('srcdir', '.'), 'certs', 'server-crl.pem'))
|
||||
WGET_OPTIONS = "--crl-file " + CRLFILE + " --ca-certificate=" + CAFILE
|
||||
WGET_URLS = [["File1", "File2"]]
|
||||
|
||||
Files = [[A_File, B_File]]
|
||||
|
||||
Servers = [HTTPS]
|
||||
|
||||
ExpectedReturnCode = 5
|
||||
|
||||
################ Pre and Post Test Hooks #####################################
|
||||
pre_test = {
|
||||
"ServerFiles" : Files
|
||||
}
|
||||
test_options = {
|
||||
"WgetCommands" : WGET_OPTIONS,
|
||||
"Urls" : WGET_URLS
|
||||
}
|
||||
post_test = {
|
||||
"ExpectedRetcode" : ExpectedReturnCode
|
||||
}
|
||||
|
||||
err = HTTPTest (
|
||||
name=TEST_NAME,
|
||||
pre_hook=pre_test,
|
||||
test_params=test_options,
|
||||
post_hook=post_test,
|
||||
protocols=Servers
|
||||
).begin ()
|
||||
|
||||
exit (err)
|
||||
@@ -3,7 +3,6 @@ from sys import exit
|
||||
from test.http_test import HTTPTest
|
||||
from test.base_test import HTTP, HTTPS
|
||||
from misc.wget_file import WgetFile
|
||||
import os
|
||||
|
||||
"""
|
||||
This test ensures that Wget can download files from HTTPS Servers
|
||||
@@ -18,8 +17,7 @@ A_File = WgetFile ("File1", File1)
|
||||
B_File = WgetFile ("File2", File2)
|
||||
C_File = WgetFile ("File3", File3)
|
||||
|
||||
CAFILE = os.path.abspath(os.path.join(os.getenv('srcdir', '.'), 'certs', 'ca-cert.pem'))
|
||||
WGET_OPTIONS = "--ca-certificate=" + CAFILE
|
||||
WGET_OPTIONS = "--no-check-certificate"
|
||||
WGET_URLS = [["File1", "File2"]]
|
||||
|
||||
Files = [[A_File, B_File]]
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
from sys import exit
|
||||
from test.http_test import HTTPTest
|
||||
from misc.wget_file import WgetFile
|
||||
|
||||
"""
|
||||
This test ensures that Wget handles a 504 Gateway Timeout response
|
||||
correctly.
|
||||
Since, we do not have a direct mechanism for conditionally sending responses
|
||||
via the HTTP Server, I've used a workaround.
|
||||
The server will always respond to a request for File1 with a 504 Gateway
|
||||
Timeout. Using the --tries=2 option, we ensure that Wget attempts the file
|
||||
only twice and then move on to the next file. Finally, check the exact
|
||||
requests that the Server received and compare them, in order, to the
|
||||
expected sequence of requests.
|
||||
|
||||
In this case, we expect Wget to attempt File1 twice and File2 once. If Wget
|
||||
considered 504 as a general Server Error, it would be a fatal failure and
|
||||
Wget would request File1 only once.
|
||||
"""
|
||||
TEST_NAME = "504 Gateway Timeouts"
|
||||
############# File Definitions ###############################################
|
||||
File1 = """All happy families are alike;
|
||||
Each unhappy family is unhappy in its own way"""
|
||||
File2 = "Anyone for chocochip cookies?"
|
||||
|
||||
File1_rules = {
|
||||
"Response" : 504
|
||||
}
|
||||
|
||||
A_File = WgetFile ("File1", File1, rules=File1_rules)
|
||||
B_File = WgetFile ("File2", File2)
|
||||
|
||||
Request_List = [
|
||||
[
|
||||
"GET /File1",
|
||||
"GET /File1",
|
||||
"GET /File2",
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
WGET_OPTIONS = "--tries=2"
|
||||
WGET_URLS = [["File1", "File2"]]
|
||||
|
||||
Files = [[A_File, B_File]]
|
||||
|
||||
ExpectedReturnCode = 4
|
||||
ExpectedDownloadedFiles = [B_File]
|
||||
|
||||
################ Pre and Post Test Hooks #####################################
|
||||
pre_test = {
|
||||
"ServerFiles" : Files
|
||||
}
|
||||
test_options = {
|
||||
"WgetCommands" : WGET_OPTIONS,
|
||||
"Urls" : WGET_URLS
|
||||
}
|
||||
post_test = {
|
||||
"ExpectedFiles" : ExpectedDownloadedFiles,
|
||||
"ExpectedRetcode" : ExpectedReturnCode,
|
||||
"FilesCrawled" : Request_List
|
||||
}
|
||||
|
||||
err = HTTPTest (
|
||||
name=TEST_NAME,
|
||||
pre_hook=pre_test,
|
||||
test_params=test_options,
|
||||
post_hook=post_test
|
||||
).begin ()
|
||||
|
||||
exit (err)
|
||||
@@ -12,10 +12,9 @@ TEST_NAME = "Content Disposition Clobber"
|
||||
File1 = "Teapot"
|
||||
File2 = "The Teapot Protocol"
|
||||
|
||||
# use upper case 'I' to provoke Wget failure with turkish locale
|
||||
File2_rules = {
|
||||
"SendHeader" : {
|
||||
"Content-DIsposition" : "Attachment; FILENAME=HTTP.Teapot"
|
||||
"Content-Disposition" : "Attachment; filename=HTTP.Teapot"
|
||||
}
|
||||
}
|
||||
A_File = WgetFile ("HTTP.Teapot", File1)
|
||||
|
||||
@@ -14,8 +14,7 @@ File2 = "Anyone for chocochip cookies?"
|
||||
|
||||
File1_rules = {
|
||||
"SendHeader" : {
|
||||
# use upper case 'I' to provoke Wget failure with turkish locale
|
||||
"Set-Cookie" : "sess-id=0213; path=/; DoMAIn=.example.com"
|
||||
"Set-Cookie" : "sess-id=0213; path=/; domain=.example.com"
|
||||
}
|
||||
}
|
||||
File2_rules = {
|
||||
|
||||
@@ -30,8 +30,7 @@ File2_rules = {
|
||||
}
|
||||
File3_rules = {
|
||||
"SendHeader" : {
|
||||
# use upper case 'I' to provoke Wget failure with turkish locale
|
||||
"Set-Cookie" : "sess-id=0213; path=/; ExPIRes=Sun, 06 Nov 2001 12:32:43 GMT"
|
||||
"Set-Cookie" : "sess-id=0213; path=/; Expires=Sun, 06 Nov 2001 12:32:43 GMT"
|
||||
},
|
||||
"ExpectHeader" : {
|
||||
"Cookie" : "new-sess=N; sess-id=0213"
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
from sys import exit
|
||||
from test.http_test import HTTPTest
|
||||
from misc.wget_file import WgetFile
|
||||
import os
|
||||
|
||||
# This test caused wget up to 1.16 to crash
|
||||
#os.environ["LC_ALL"] = "en_US.UTF-8"
|
||||
|
||||
urls = [
|
||||
"File%20formats/Images/SVG,%20Scalable%20Vector%20Graphics/html,%20W3C%20v1.2%20rec%20(tiny)/directory",
|
||||
"File formats/Images/SVG, Scalable Vector Graphics/html, W3C v1.2 rec (tiny)/directory/",
|
||||
"File%20formats/Images/SVG,%20Scalable%20Vector%20Graphics/html,%20W3C%20v1.2%20rec%20(tiny)/directory/somefile.rng",
|
||||
"File%20formats/Images/SVG%2C%20Scalable%20Vector%20Graphics/html%2c%20W3C%20v1.2%20rec%20%28tiny%29/directory/somefile.rng",
|
||||
"File%20formats/Images/SVG%2C%20Scalable%20Vector%20Graphics/html%2c%20W3C%20v1.2%20rec%20%28tiny%29/directory/",
|
||||
"File%20formats/Images/SVG%2C%20Scalable%20Vector%20Graphics/html%2C%20W3C%20v1.2%20rec%20%28tiny%29/directory"]
|
||||
|
||||
|
||||
redirected = [
|
||||
"File%20formats/Images/SVG,%20Scalable%20Vector%20Graphics/html,%20W3C%20v1.2%20rec%20(tiny)/directory/"
|
||||
]
|
||||
|
||||
TEST_NAME = "Redirection crash"
|
||||
############# File Definitions ###############################################
|
||||
Index = ""
|
||||
for i in urls:
|
||||
Index = Index + "<a href='/%s'></a>" % i
|
||||
|
||||
File1 = ""
|
||||
|
||||
def get_redirect(url):
|
||||
data = {
|
||||
"File%20formats/Images/SVG,%20Scalable%20Vector%20Graphics/html,%20W3C%20v1.2%20rec%20(tiny)/directory" :
|
||||
"File%20formats/Images/SVG,%20Scalable%20Vector%20Graphics/html,%20W3C%20v1.2%20rec%20(tiny)/directory/",
|
||||
"File%20formats/Images/SVG%2C%20Scalable%20Vector%20Graphics/html%2C%20W3C%20v1.2%20rec%20%28tiny%29/directory" :
|
||||
"File%20formats/Images/SVG,%20Scalable%20Vector%20Graphics/html,%20W3C%20v1.2%20rec%20(tiny)/directory/"
|
||||
}
|
||||
dest = data.get(url)
|
||||
if dest:
|
||||
return {"Response" : 301,
|
||||
"SendHeader" : {"Location" : "/%s" % dest}}
|
||||
return None
|
||||
|
||||
|
||||
index_url = "File%20formats/Images/SVG,%20Scalable%20Vector%20Graphics/html,%20W3C%20v1.2%20rec%20(tiny)/index.html"
|
||||
Index_File = WgetFile (index_url, Index)
|
||||
Files = ([Index_File] + [WgetFile(i, File1, rules=get_redirect(i)) for i in (redirected + urls)])
|
||||
|
||||
WGET_OPTIONS = "--recursive -e robots=off"
|
||||
|
||||
WGET_URLS = [[index_url]]
|
||||
|
||||
ExpectedReturnCode = 0
|
||||
|
||||
################ Pre and Post Test Hooks #####################################
|
||||
pre_test = {
|
||||
"ServerFiles" : [Files]
|
||||
}
|
||||
test_options = {
|
||||
"WgetCommands" : WGET_OPTIONS,
|
||||
"Urls" : WGET_URLS
|
||||
}
|
||||
post_test = {
|
||||
"ExpectedRetcode" : ExpectedReturnCode,
|
||||
}
|
||||
|
||||
err = HTTPTest (
|
||||
name=TEST_NAME,
|
||||
pre_hook=pre_test,
|
||||
test_params=test_options,
|
||||
post_hook=post_test
|
||||
).begin ()
|
||||
|
||||
exit (err)
|
||||
@@ -1,77 +0,0 @@
|
||||
To create the server RSA private key:
|
||||
$ certtool --generate-privkey --outfile server-key.pem --rsa
|
||||
|
||||
|
||||
To create a self signed CA certificate:
|
||||
$ certtool --generate-privkey --outfile ca-key.pem
|
||||
$ certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca-cert.pem
|
||||
Common name: GNU Wget
|
||||
UID:
|
||||
Organizational unit name: Wget
|
||||
Organization name: GNU
|
||||
Locality name:
|
||||
State or province name:
|
||||
Country name (2 chars):
|
||||
Enter the subject's domain component (DC):
|
||||
This field should not be used in new certificates.
|
||||
E-mail:
|
||||
Enter the certificate's serial number in decimal (default: 6080487640893163573):
|
||||
|
||||
Activation/Expiration time.
|
||||
The certificate will expire in (days): -1
|
||||
|
||||
Extensions.
|
||||
Does the certificate belong to an authority? (y/N): y
|
||||
Path length constraint (decimal, -1 for no constraint):
|
||||
Is this a TLS web client certificate? (y/N):
|
||||
Will the certificate be used for IPsec IKE operations? (y/N):
|
||||
Is this a TLS web server certificate? (y/N):
|
||||
Enter a dnsName of the subject of the certificate:
|
||||
Enter a URI of the subject of the certificate:
|
||||
Enter the IP address of the subject of the certificate:
|
||||
Enter the e-mail of the subject of the certificate:
|
||||
Will the certificate be used to sign other certificates? (y/N): y
|
||||
Will the certificate be used to sign CRLs? (y/N): y
|
||||
Will the certificate be used to sign code? (y/N):
|
||||
Will the certificate be used to sign OCSP requests? (y/N): y
|
||||
Will the certificate be used for time stamping? (y/N):
|
||||
Enter the URI of the CRL distribution point:
|
||||
|
||||
|
||||
To generate a server certificate using the private key only:
|
||||
$ certtool --generate-certificate --load-privkey server-key.pem --outfile server-cert.pem --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem
|
||||
Common name: 127.0.0.1
|
||||
UID:
|
||||
Organizational unit name: Wget
|
||||
Organization name: GNU
|
||||
Locality name:
|
||||
State or province name:
|
||||
Country name (2 chars):
|
||||
Enter the subject's domain component (DC):
|
||||
This field should not be used in new certificates.
|
||||
E-mail:
|
||||
Enter the certificate's serial number in decimal (default: 6080488276853553635):
|
||||
|
||||
Activation/Expiration time.
|
||||
The certificate will expire in (days): -1
|
||||
|
||||
Extensions.
|
||||
Does the certificate belong to an authority? (y/N):
|
||||
Is this a TLS web client certificate? (y/N):
|
||||
Will the certificate be used for IPsec IKE operations? (y/N):
|
||||
Is this a TLS web server certificate? (y/N): y
|
||||
Enter a dnsName of the subject of the certificate: 127.0.0.1
|
||||
Enter a dnsName of the subject of the certificate: localhost
|
||||
Enter a dnsName of the subject of the certificate:
|
||||
Enter a URI of the subject of the certificate:
|
||||
Enter the IP address of the subject of the certificate:
|
||||
Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (Y/n):
|
||||
Will the certificate be used for encryption (RSA ciphersuites)? (Y/n):
|
||||
|
||||
|
||||
To create a CRL for the server certificate:
|
||||
$ certtool --generate-crl --load-ca-privkey ca-key.pem --load-ca-certificate ca-cert.pem --load-certificate server-cert.pem --outfile server-crl.pem
|
||||
Generating a signed CRL...
|
||||
Update times.
|
||||
The certificate will expire in (days): -1
|
||||
CRL Number (default: 6080006793650397145):
|
||||
@@ -1,20 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDPjCCAiagAwIBAgIIVGI7SyiXCDUwDQYJKoZIhvcNAQELBQAwMDERMA8GA1UE
|
||||
AxMIR05VIFdnZXQxDTALBgNVBAsTBFdnZXQxDDAKBgNVBAoTA0dOVTAiGA8yMDE0
|
||||
MTExMTE2MzczM1oYDzk5OTkxMjMxMjM1OTU5WjAwMREwDwYDVQQDEwhHTlUgV2dl
|
||||
dDENMAsGA1UECxMEV2dldDEMMAoGA1UEChMDR05VMIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAv2IR1/gsaJsn+egtVFbMMMbivK+eVzPY8wEXb2flpe9a
|
||||
Kkwz824nSSrWfRigQmf/ODkNlK2x91kppfPmWkClUREQB3I4d/sHFnzqCkFKmNwt
|
||||
VT4DsL47VumgZF6ZjSqTYQD3MDH3VhFj1iKrRMM/aCZXwntD+67sKw6UPXfFbfUO
|
||||
Recpb7fCZPZFVFYStxgcF7cyH+DADLX5QCEjiLYH1es6FXrdw+ypgwBl+HuLkQ/4
|
||||
gE0JLQK5PAKSYeLy0JEBUPovkMXT+r9aPkQBF/9WD6uUPia0ERHbMIT0My84hBrG
|
||||
9d5u5gXPnH1ZxKIr8iJOYCydVjYndn21zs2IExwL6wIDAQABo1gwVjAPBgNVHRMB
|
||||
Af8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMJMA8GA1UdDwEB/wQFAwMHBgAw
|
||||
HQYDVR0OBBYEFPM+TjiESqm+wW/HYaNQ2m4pi+tUMA0GCSqGSIb3DQEBCwUAA4IB
|
||||
AQCWKV1Txo3xytRSO1PwWK9ce5FhvQW9mubuuWmbEnQt9JaOhO1Og6ZmdPDlAQeo
|
||||
m0CJZZ0VNeodoBXPGopy3VyzF4ZzUR9leGk3sb1qTSoDCvJd/zLrfukHKugtwuK0
|
||||
b1fPnEjBjQ6gQI21coc1tmyX8Qsm7of5n+Ji601WG+FiVmmdEsCjmA/eAvwSbu1E
|
||||
cAVH476KUt4CrpVPQQVqzFPDz8i4iw/P+Jo+iNmL5S72OG2GfkSJq3XkUYa509W6
|
||||
N+8c3p4y0q/PcQ92s1OIHyEPZFRFhm4xw0sHkhD2KVoHseHZjCoYn4/lIzMPnJ6v
|
||||
EfZUJQXndeJnffbthaUp8Ea2
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,144 +0,0 @@
|
||||
Public Key Info:
|
||||
Public Key Algorithm: RSA
|
||||
Key Security Level: Medium (2048 bits)
|
||||
|
||||
modulus:
|
||||
00:bf:62:11:d7:f8:2c:68:9b:27:f9:e8:2d:54:56:
|
||||
cc:30:c6:e2:bc:af:9e:57:33:d8:f3:01:17:6f:67:
|
||||
e5:a5:ef:5a:2a:4c:33:f3:6e:27:49:2a:d6:7d:18:
|
||||
a0:42:67:ff:38:39:0d:94:ad:b1:f7:59:29:a5:f3:
|
||||
e6:5a:40:a5:51:11:10:07:72:38:77:fb:07:16:7c:
|
||||
ea:0a:41:4a:98:dc:2d:55:3e:03:b0:be:3b:56:e9:
|
||||
a0:64:5e:99:8d:2a:93:61:00:f7:30:31:f7:56:11:
|
||||
63:d6:22:ab:44:c3:3f:68:26:57:c2:7b:43:fb:ae:
|
||||
ec:2b:0e:94:3d:77:c5:6d:f5:0e:45:e7:29:6f:b7:
|
||||
c2:64:f6:45:54:56:12:b7:18:1c:17:b7:32:1f:e0:
|
||||
c0:0c:b5:f9:40:21:23:88:b6:07:d5:eb:3a:15:7a:
|
||||
dd:c3:ec:a9:83:00:65:f8:7b:8b:91:0f:f8:80:4d:
|
||||
09:2d:02:b9:3c:02:92:61:e2:f2:d0:91:01:50:fa:
|
||||
2f:90:c5:d3:fa:bf:5a:3e:44:01:17:ff:56:0f:ab:
|
||||
94:3e:26:b4:11:11:db:30:84:f4:33:2f:38:84:1a:
|
||||
c6:f5:de:6e:e6:05:cf:9c:7d:59:c4:a2:2b:f2:22:
|
||||
4e:60:2c:9d:56:36:27:76:7d:b5:ce:cd:88:13:1c:
|
||||
0b:eb:
|
||||
|
||||
public exponent:
|
||||
01:00:01:
|
||||
|
||||
private exponent:
|
||||
45:0c:7f:fd:98:a7:85:12:3d:a9:17:90:8b:36:49:
|
||||
b3:6b:7e:50:af:58:04:84:4b:48:d9:62:f8:29:d7:
|
||||
1c:38:30:22:c4:9d:95:bd:6f:65:21:94:83:4b:c8:
|
||||
3e:4d:41:32:aa:ba:f0:a2:7e:6c:0c:7a:4f:4a:a1:
|
||||
18:7c:ec:68:44:2c:b1:53:0f:76:92:56:2b:51:e4:
|
||||
2a:d1:05:b6:02:f2:44:27:fc:b2:de:df:8f:ea:f8:
|
||||
98:5d:dd:2e:a6:66:c7:ff:ce:2f:50:47:b9:80:ca:
|
||||
b1:6e:8e:b6:5f:6f:58:07:45:70:80:82:b5:a2:95:
|
||||
c8:af:18:e2:d8:7c:9d:bf:c5:a9:da:4f:af:08:37:
|
||||
92:27:94:12:c0:94:70:90:ff:e4:05:8b:ed:18:a9:
|
||||
19:3c:47:3a:7c:fe:4f:9c:15:ab:f6:7e:48:2a:58:
|
||||
d7:14:67:96:bd:e6:fa:9f:3a:51:0c:63:49:14:d5:
|
||||
9d:e9:a8:24:19:2a:83:e4:fe:e2:ec:db:f9:13:33:
|
||||
a6:d3:62:d2:6b:7e:a9:5b:93:73:f5:c9:d0:ad:58:
|
||||
11:cb:77:d3:13:3c:bf:37:f9:64:95:c7:4c:69:f2:
|
||||
6e:b8:36:69:57:93:4a:03:06:58:8a:51:3d:d6:97:
|
||||
61:2f:7c:76:33:14:88:51:45:68:4e:29:fe:12:43:
|
||||
69:
|
||||
|
||||
prime1:
|
||||
00:e0:e6:81:38:18:3e:c8:98:51:71:2d:5f:22:8c:
|
||||
93:95:37:17:47:00:4f:6a:87:98:73:8d:f3:c3:02:
|
||||
f7:e1:9d:a0:5c:a5:10:a6:0d:88:5d:e0:72:10:93:
|
||||
24:af:6e:a4:0e:55:5c:03:37:5f:1d:90:41:c2:d6:
|
||||
e3:a6:ba:20:08:0b:01:31:eb:fc:7e:97:66:3c:fe:
|
||||
b5:ab:4c:0b:2f:18:16:f3:28:47:70:41:dc:cf:04:
|
||||
9c:7e:28:78:3b:3f:31:cf:b1:77:2c:6d:c9:bf:ad:
|
||||
19:ff:03:1f:c6:98:9a:60:47:a5:1d:c4:52:c5:9e:
|
||||
77:5a:cc:a4:e3:96:81:d4:4d:
|
||||
|
||||
prime2:
|
||||
00:d9:d9:0c:6e:81:bb:0e:5d:c6:92:cc:48:70:b8:
|
||||
da:60:e8:56:e7:2a:20:da:29:0f:c9:f0:9f:b8:9f:
|
||||
df:d9:a1:68:7e:ce:3e:7c:f2:00:66:68:79:c4:01:
|
||||
fa:b9:71:3e:73:06:3f:85:5c:83:33:ee:58:77:50:
|
||||
89:aa:90:33:d0:6c:aa:6f:34:b2:30:8b:e9:a9:82:
|
||||
df:e2:7f:04:09:9f:14:9a:db:c7:cb:e5:85:46:b2:
|
||||
42:d0:a7:fe:7a:e3:ff:1e:84:9c:36:50:e3:de:fb:
|
||||
11:1c:34:09:fe:46:db:45:c3:50:19:f1:25:c0:e3:
|
||||
5c:d5:0d:88:13:e1:9a:5d:17:
|
||||
|
||||
coefficient:
|
||||
00:ca:79:cb:79:87:91:9f:9a:99:0b:5d:c5:78:21:
|
||||
a7:60:c6:8a:2d:a5:b5:87:a2:d6:df:b0:17:5f:bf:
|
||||
e1:ce:f0:ca:89:18:0e:e0:4a:7f:00:e5:41:2d:04:
|
||||
5b:05:51:e5:08:89:dd:80:82:c7:94:94:1c:f4:0f:
|
||||
1b:9a:d0:72:83:bb:e9:ca:d5:09:0d:4b:c0:b7:6a:
|
||||
a7:b4:c3:df:4e:f1:7f:0f:57:ad:25:ff:e4:d3:ef:
|
||||
05:95:31:ca:00:54:97:4b:2d:56:aa:1a:89:d8:a0:
|
||||
d6:dc:64:88:88:36:26:92:39:57:8b:da:18:23:77:
|
||||
c3:e3:39:0e:95:f7:3c:77:fe:
|
||||
|
||||
exp1:
|
||||
00:99:f2:8f:4f:93:a1:1e:74:cd:82:f8:78:df:d0:
|
||||
74:91:b6:a5:53:6f:cd:ec:f1:26:95:2a:fd:4a:67:
|
||||
34:c1:16:c2:17:c8:d1:ed:a8:e3:c8:c7:03:ad:7e:
|
||||
db:a4:ce:ca:b4:19:10:24:0f:7a:27:65:80:ee:5b:
|
||||
64:77:d3:7e:6b:a3:04:cd:64:69:71:4a:37:ac:d6:
|
||||
fa:0a:68:c2:5b:19:55:54:5b:25:13:9d:b2:05:6f:
|
||||
75:a4:12:15:c3:10:8e:0b:4a:c2:76:02:2d:10:ec:
|
||||
f0:17:94:ce:e2:85:c1:5e:d8:8c:19:25:33:37:9d:
|
||||
32:bc:4f:cb:2b:12:f2:8a:1d:
|
||||
|
||||
exp2:
|
||||
3e:53:68:c9:1c:f8:a5:6d:92:e8:60:e5:c0:ca:42:
|
||||
40:43:78:c9:7e:36:13:f4:77:7d:f1:07:e1:4c:6c:
|
||||
40:d9:7b:09:fc:7b:c8:47:7c:71:d0:26:36:3b:d2:
|
||||
bd:c7:76:74:76:2f:2a:3a:83:97:11:f3:e1:7e:fb:
|
||||
43:ff:29:b3:d1:c3:19:39:dc:59:23:4e:60:9e:fe:
|
||||
ea:d0:28:19:90:97:d6:8e:56:a5:31:2f:66:40:8d:
|
||||
f9:20:77:20:35:a6:c1:d6:72:d2:df:65:b2:5f:e6:
|
||||
4f:49:5c:2a:91:9f:1e:60:78:c4:53:47:d7:dd:b4:
|
||||
ab:87:c9:8c:d6:98:d1:55:
|
||||
|
||||
|
||||
Public Key ID: F3:3E:4E:38:84:4A:A9:BE:C1:6F:C7:61:A3:50:DA:6E:29:8B:EB:54
|
||||
Public key's random art:
|
||||
+--[ RSA 2048]----+
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| .. . |
|
||||
| Eo . S |
|
||||
| .+o..+. + |
|
||||
| .+o.= oo o |
|
||||
|.o.o* o +. |
|
||||
|+o+*.. .o. |
|
||||
+-----------------+
|
||||
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAv2IR1/gsaJsn+egtVFbMMMbivK+eVzPY8wEXb2flpe9aKkwz
|
||||
824nSSrWfRigQmf/ODkNlK2x91kppfPmWkClUREQB3I4d/sHFnzqCkFKmNwtVT4D
|
||||
sL47VumgZF6ZjSqTYQD3MDH3VhFj1iKrRMM/aCZXwntD+67sKw6UPXfFbfUORecp
|
||||
b7fCZPZFVFYStxgcF7cyH+DADLX5QCEjiLYH1es6FXrdw+ypgwBl+HuLkQ/4gE0J
|
||||
LQK5PAKSYeLy0JEBUPovkMXT+r9aPkQBF/9WD6uUPia0ERHbMIT0My84hBrG9d5u
|
||||
5gXPnH1ZxKIr8iJOYCydVjYndn21zs2IExwL6wIDAQABAoIBAEUMf/2Yp4USPakX
|
||||
kIs2SbNrflCvWASES0jZYvgp1xw4MCLEnZW9b2UhlINLyD5NQTKquvCifmwMek9K
|
||||
oRh87GhELLFTD3aSVitR5CrRBbYC8kQn/LLe34/q+Jhd3S6mZsf/zi9QR7mAyrFu
|
||||
jrZfb1gHRXCAgrWilcivGOLYfJ2/xanaT68IN5InlBLAlHCQ/+QFi+0YqRk8Rzp8
|
||||
/k+cFav2fkgqWNcUZ5a95vqfOlEMY0kU1Z3pqCQZKoPk/uLs2/kTM6bTYtJrfqlb
|
||||
k3P1ydCtWBHLd9MTPL83+WSVx0xp8m64NmlXk0oDBliKUT3Wl2EvfHYzFIhRRWhO
|
||||
Kf4SQ2kCgYEA4OaBOBg+yJhRcS1fIoyTlTcXRwBPaoeYc43zwwL34Z2gXKUQpg2I
|
||||
XeByEJMkr26kDlVcAzdfHZBBwtbjprogCAsBMev8fpdmPP61q0wLLxgW8yhHcEHc
|
||||
zwScfih4Oz8xz7F3LG3Jv60Z/wMfxpiaYEelHcRSxZ53Wsyk45aB1E0CgYEA2dkM
|
||||
boG7Dl3GksxIcLjaYOhW5yog2ikPyfCfuJ/f2aFofs4+fPIAZmh5xAH6uXE+cwY/
|
||||
hVyDM+5Yd1CJqpAz0GyqbzSyMIvpqYLf4n8ECZ8UmtvHy+WFRrJC0Kf+euP/HoSc
|
||||
NlDj3vsRHDQJ/kbbRcNQGfElwONc1Q2IE+GaXRcCgYEAmfKPT5OhHnTNgvh439B0
|
||||
kbalU2/N7PEmlSr9Smc0wRbCF8jR7ajjyMcDrX7bpM7KtBkQJA96J2WA7ltkd9N+
|
||||
a6MEzWRpcUo3rNb6CmjCWxlVVFslE52yBW91pBIVwxCOC0rCdgItEOzwF5TO4oXB
|
||||
XtiMGSUzN50yvE/LKxLyih0CgYA+U2jJHPilbZLoYOXAykJAQ3jJfjYT9Hd98Qfh
|
||||
TGxA2XsJ/HvIR3xx0CY2O9K9x3Z0di8qOoOXEfPhfvtD/ymz0cMZOdxZI05gnv7q
|
||||
0CgZkJfWjlalMS9mQI35IHcgNabB1nLS32WyX+ZPSVwqkZ8eYHjEU0fX3bSrh8mM
|
||||
1pjRVQKBgQDKect5h5GfmpkLXcV4IadgxootpbWHotbfsBdfv+HO8MqJGA7gSn8A
|
||||
5UEtBFsFUeUIid2AgseUlBz0Dxua0HKDu+nK1QkNS8C3aqe0w99O8X8PV60l/+TT
|
||||
7wWVMcoAVJdLLVaqGonYoNbcZIiINiaSOVeL2hgjd8PjOQ6V9zx3/g==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -1,21 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDgDCCAmigAwIBAgIIVGI73zrIeeMwDQYJKoZIhvcNAQELBQAwMDERMA8GA1UE
|
||||
AxMIR05VIFdnZXQxDTALBgNVBAsTBFdnZXQxDDAKBgNVBAoTA0dOVTAiGA8yMDE0
|
||||
MTExMTE2NDAwMFoYDzk5OTkxMjMxMjM1OTU5WjAxMRIwEAYDVQQDEwkxMjcuMC4w
|
||||
LjExDTALBgNVBAsTBFdnZXQxDDAKBgNVBAoTA0dOVTCCASIwDQYJKoZIhvcNAQEB
|
||||
BQADggEPADCCAQoCggEBAMjC3Gt55EfStl6mE371+pD3/cpR5MLxkdbBss5MlIP2
|
||||
TDhiPOItLXml8oxs4BjUm3wfn3GV9iJLmbzbIWL+0kbRkQ2LCPKUf+Cln3z2ZE+r
|
||||
XwdWlT8gVfv51Opfkp2lLDVUqLfNKRGQgivjSCmLqY2LqeB0SaVNvuaD3EpqZyIH
|
||||
0E5SZgjqBHgRRtvGkcy0rOmp5SI2NASLugUioXa9OLWjpYDwodsd3ERlL0DJ1aJW
|
||||
8TC8Tqix4i0osWzar+LXBIin0Qvar9/uRHN0p1kq3p0XgNHKqWpiTT54+WYx7Pem
|
||||
v4qRXz11swiJzUL+Pw1DurQ9smbzDgAsz7V2FJnUeCcCAwEAAaOBmDCBlTAMBgNV
|
||||
HRMBAf8EAjAAMB8GA1UdEQQYMBaCCTEyNy4wLjAuMYIJbG9jYWxob3N0MBMGA1Ud
|
||||
JQQMMAoGCCsGAQUFBwMBMA8GA1UdDwEB/wQFAwMHoAAwHQYDVR0OBBYEFJfm323L
|
||||
JbKTM/tMKSt0qlUqewbnMB8GA1UdIwQYMBaAFPM+TjiESqm+wW/HYaNQ2m4pi+tU
|
||||
MA0GCSqGSIb3DQEBCwUAA4IBAQCDmuSD4IGmn0UQ5jhGQquh92Iu59j64Rrg7EIM
|
||||
zoppciyYR8gDUutOI9CEisxJz6umvAdOo5L981gcFaBv6hHWaE/krAZccR+ZXZP6
|
||||
fI9btO8My8O63fYcd2KkLEFqvKDF43i01S2LrqXdPo3uELbFZwxCmUKsexFGsoW1
|
||||
CbXbRjnS7w/f72myRmvBeDiNMuGfe1lb4IflybH3DMlKC7i0AN1JKglp+IKn5XAE
|
||||
neWR03i3UaYJsibIxj0DkTS+hVPu5MXQ9RlF5CkRdFKjGinLE/u70XyAyx0/IeAN
|
||||
e7c2MJvpdfRmTXm2ew4sNyK9RXo7Bv0Yqkl65iMscF8LNnxL
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,12 +0,0 @@
|
||||
-----BEGIN X509 CRL-----
|
||||
MIIB1DCBvQIBATANBgkqhkiG9w0BAQsFADAwMREwDwYDVQQDEwhHTlUgV2dldDEN
|
||||
MAsGA1UECxMEV2dldDEMMAoGA1UEChMDR05VGA8yMDE0MTExMTE2NDU1NFoYDzk5
|
||||
OTkxMjMxMjM1OTU5WjAdMBsCCFRiO986yHnjGA8yMDE0MTExMTE2NDU1NFqgNjA0
|
||||
MB8GA1UdIwQYMBaAFPM+TjiESqm+wW/HYaNQ2m4pi+tUMBEGA1UdFAQKAghUYj1E
|
||||
KHs9ijANBgkqhkiG9w0BAQsFAAOCAQEAZgwqs1VOFG39dFHHMXvBr4eJfhwiG4bC
|
||||
cL6IvLhvl9ikcyQMHrpOBtNjkCtgclSbJjjTDdera1+zuCWE0WBOJ4mojYdAIOhR
|
||||
QvSwp4NwAtibu2F/fjeXoo+LEpcRKtLvAotB30eCZ1OPrijsa/HxFILOLlayjns8
|
||||
wM4RmQC4o43y1G/1jqM8hGDg4Wz0j1URVuyP+pU55JpubV5LlExy3gIRwevD2lam
|
||||
q3hiighenJYFO3HGZkYT2SIoSpXZnQqKPJ4HwRBSg/cjOpc1y1lIIvKhmk+Cut6M
|
||||
+S5HL4pIk8vGYg57nTfOOkj1goqFkfU0DBqvVAZj02ay/VIDu61T1g==
|
||||
-----END X509 CRL-----
|
||||
@@ -1,144 +0,0 @@
|
||||
Public Key Info:
|
||||
Public Key Algorithm: RSA
|
||||
Key Security Level: Medium (2048 bits)
|
||||
|
||||
modulus:
|
||||
00:c8:c2:dc:6b:79:e4:47:d2:b6:5e:a6:13:7e:f5:
|
||||
fa:90:f7:fd:ca:51:e4:c2:f1:91:d6:c1:b2:ce:4c:
|
||||
94:83:f6:4c:38:62:3c:e2:2d:2d:79:a5:f2:8c:6c:
|
||||
e0:18:d4:9b:7c:1f:9f:71:95:f6:22:4b:99:bc:db:
|
||||
21:62:fe:d2:46:d1:91:0d:8b:08:f2:94:7f:e0:a5:
|
||||
9f:7c:f6:64:4f:ab:5f:07:56:95:3f:20:55:fb:f9:
|
||||
d4:ea:5f:92:9d:a5:2c:35:54:a8:b7:cd:29:11:90:
|
||||
82:2b:e3:48:29:8b:a9:8d:8b:a9:e0:74:49:a5:4d:
|
||||
be:e6:83:dc:4a:6a:67:22:07:d0:4e:52:66:08:ea:
|
||||
04:78:11:46:db:c6:91:cc:b4:ac:e9:a9:e5:22:36:
|
||||
34:04:8b:ba:05:22:a1:76:bd:38:b5:a3:a5:80:f0:
|
||||
a1:db:1d:dc:44:65:2f:40:c9:d5:a2:56:f1:30:bc:
|
||||
4e:a8:b1:e2:2d:28:b1:6c:da:af:e2:d7:04:88:a7:
|
||||
d1:0b:da:af:df:ee:44:73:74:a7:59:2a:de:9d:17:
|
||||
80:d1:ca:a9:6a:62:4d:3e:78:f9:66:31:ec:f7:a6:
|
||||
bf:8a:91:5f:3d:75:b3:08:89:cd:42:fe:3f:0d:43:
|
||||
ba:b4:3d:b2:66:f3:0e:00:2c:cf:b5:76:14:99:d4:
|
||||
78:27:
|
||||
|
||||
public exponent:
|
||||
01:00:01:
|
||||
|
||||
private exponent:
|
||||
00:92:80:1f:f9:0d:e9:d7:bf:9b:f5:55:9b:c4:7a:
|
||||
1b:6e:ce:89:14:aa:ce:14:b3:d3:88:b3:b0:97:7a:
|
||||
aa:a5:e1:85:9d:5f:92:ae:39:e9:85:6b:e3:a3:35:
|
||||
90:12:8e:93:27:f0:ab:99:67:a5:45:41:85:de:9a:
|
||||
c9:b2:43:e1:8e:6c:3f:3d:72:c8:04:bc:f8:d4:26:
|
||||
08:4c:58:40:bb:22:83:26:07:b8:c1:68:07:56:e8:
|
||||
e8:c6:5f:17:ce:92:49:c0:61:16:fd:89:68:fe:b8:
|
||||
45:45:61:85:b7:4b:83:5f:17:1b:cf:ff:0b:fe:e4:
|
||||
cc:f9:ca:1f:66:ee:5e:74:25:94:7a:27:0e:0f:43:
|
||||
50:14:48:ad:c6:8a:e1:ac:ff:8e:10:ed:e6:92:48:
|
||||
c8:94:c1:3a:2c:db:86:71:66:8e:19:93:13:ed:f9:
|
||||
47:06:5e:8b:e2:2e:cb:3a:c2:b3:5e:8d:31:e4:c5:
|
||||
a7:cd:3f:09:70:e4:02:5d:34:2a:4d:b7:f5:06:e2:
|
||||
f5:3b:8f:b6:ad:4a:22:b8:fe:43:a7:4d:67:ef:c3:
|
||||
e1:ed:83:e2:d5:f2:d0:37:0f:56:ab:5b:47:69:0a:
|
||||
14:03:2c:43:a3:73:e9:05:72:5e:df:68:9c:67:4b:
|
||||
08:64:2d:c2:67:23:aa:e5:35:88:56:99:95:17:60:
|
||||
20:01:
|
||||
|
||||
prime1:
|
||||
00:ea:ca:12:86:c0:25:b8:ab:fd:44:2c:1a:3f:1b:
|
||||
19:68:d4:26:6e:9c:ad:6d:35:12:29:9f:40:c2:4c:
|
||||
96:ef:8b:08:61:39:08:b7:8a:1f:81:97:71:ff:af:
|
||||
5a:5b:db:9a:2f:2f:29:ab:92:bb:c5:51:a2:84:c5:
|
||||
f4:88:79:ac:a2:b8:17:1e:4a:66:62:be:e5:ab:fd:
|
||||
01:42:6b:16:f9:73:7b:cd:3e:f7:5c:5c:95:dd:79:
|
||||
73:c4:60:a8:cf:95:80:ba:7d:02:14:9c:7e:58:4f:
|
||||
8c:08:2c:b8:46:31:23:b2:1a:c3:38:78:5c:ea:50:
|
||||
9d:42:23:31:30:9a:0f:3f:27:
|
||||
|
||||
prime2:
|
||||
00:da:e5:d3:66:0f:34:53:8c:e8:bf:5f:1e:46:93:
|
||||
47:df:30:57:be:1f:30:6a:7e:e9:f0:6b:3f:61:89:
|
||||
51:e2:0b:da:51:09:65:f6:23:3a:61:86:02:46:0a:
|
||||
cf:11:73:7c:2d:65:bd:64:b8:0e:24:d2:b7:51:8f:
|
||||
39:b4:a2:1b:e4:9a:bc:66:31:e2:00:eb:3e:20:06:
|
||||
97:0a:a0:bb:82:da:bf:d5:e9:20:77:a7:55:86:69:
|
||||
ce:eb:38:d3:f4:ad:82:9e:ce:02:05:c5:11:aa:c0:
|
||||
b9:66:6f:e7:f4:26:57:72:fa:50:0b:ad:76:44:86:
|
||||
e0:3e:f7:c0:3e:f3:94:9f:01:
|
||||
|
||||
coefficient:
|
||||
00:94:f2:42:a9:1a:62:1c:7a:bf:34:1b:a7:87:ae:
|
||||
bd:3a:d9:f1:8c:4e:f6:f5:27:5a:ae:f1:1e:15:06:
|
||||
a6:d0:e4:e0:ec:3a:40:02:13:b9:31:9a:cd:3a:c6:
|
||||
34:7d:c6:9d:9e:60:5b:ca:03:88:87:56:f0:e1:ea:
|
||||
37:96:2b:53:40:b2:78:4e:80:e2:e0:24:8c:83:0e:
|
||||
f8:77:a4:64:d5:cc:09:6c:d6:52:49:f9:55:61:16:
|
||||
72:b5:d2:ea:e1:61:fb:31:24:f0:30:8c:fe:5c:29:
|
||||
71:06:09:11:4d:ef:51:a6:33:62:54:d2:c7:de:ba:
|
||||
78:17:b1:27:50:f4:ef:c4:3a:
|
||||
|
||||
exp1:
|
||||
1f:36:0d:90:6c:2a:97:8a:05:78:f2:83:ea:af:a7:
|
||||
89:0f:ea:ab:f9:97:f4:54:81:bd:96:b5:fd:1e:41:
|
||||
52:46:a1:2e:8b:6e:65:37:af:48:82:e1:5c:a3:ea:
|
||||
d7:1b:32:3b:e3:81:1e:95:ba:f0:58:11:ca:a4:a6:
|
||||
05:1e:67:9c:99:ec:38:d2:9b:19:b5:56:c2:ae:37:
|
||||
64:a4:e7:c0:f1:61:1b:bf:ab:12:54:1c:77:fc:95:
|
||||
2f:1d:ca:53:0e:04:b6:c5:b7:69:16:04:95:a8:bd:
|
||||
6c:b8:c5:26:4f:91:f7:33:27:90:72:2f:a7:d6:5f:
|
||||
91:53:2c:4e:d1:ac:05:31:
|
||||
|
||||
exp2:
|
||||
00:83:a4:55:a6:fa:1b:d8:e7:54:0d:ca:f1:55:36:
|
||||
3b:b1:f0:cb:c3:cd:d3:fb:27:ca:1e:c9:10:bb:e2:
|
||||
ae:78:c7:f2:0a:6c:21:82:8e:1b:0d:0d:5f:8e:a9:
|
||||
ef:6f:aa:49:12:b0:2d:df:45:85:54:05:d9:33:56:
|
||||
74:38:ba:89:15:c9:2c:e6:34:b7:9b:1f:de:23:ba:
|
||||
72:d9:74:62:70:46:87:b9:e8:52:9b:42:e9:ff:44:
|
||||
e0:a8:bb:6b:54:a9:88:75:62:a4:fa:bd:52:6b:a3:
|
||||
2d:9c:7a:4e:3f:99:53:5c:15:47:50:4e:88:62:9b:
|
||||
ce:7e:6f:d6:90:c5:42:2b:01:
|
||||
|
||||
|
||||
Public Key ID: 97:E6:DF:6D:CB:25:B2:93:33:FB:4C:29:2B:74:AA:55:2A:7B:06:E7
|
||||
Public key's random art:
|
||||
+--[ RSA 2048]----+
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| . |
|
||||
| S + . |
|
||||
| .+oo. . |
|
||||
| .=+oo.+ .|
|
||||
| +E.=O.oo|
|
||||
| o+ .=*++o|
|
||||
+-----------------+
|
||||
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAyMLca3nkR9K2XqYTfvX6kPf9ylHkwvGR1sGyzkyUg/ZMOGI8
|
||||
4i0teaXyjGzgGNSbfB+fcZX2IkuZvNshYv7SRtGRDYsI8pR/4KWffPZkT6tfB1aV
|
||||
PyBV+/nU6l+SnaUsNVSot80pEZCCK+NIKYupjYup4HRJpU2+5oPcSmpnIgfQTlJm
|
||||
COoEeBFG28aRzLSs6anlIjY0BIu6BSKhdr04taOlgPCh2x3cRGUvQMnVolbxMLxO
|
||||
qLHiLSixbNqv4tcEiKfRC9qv3+5Ec3SnWSrenReA0cqpamJNPnj5ZjHs96a/ipFf
|
||||
PXWzCInNQv4/DUO6tD2yZvMOACzPtXYUmdR4JwIDAQABAoIBAQCSgB/5DenXv5v1
|
||||
VZvEehtuzokUqs4Us9OIs7CXeqql4YWdX5KuOemFa+OjNZASjpMn8KuZZ6VFQYXe
|
||||
msmyQ+GObD89csgEvPjUJghMWEC7IoMmB7jBaAdW6OjGXxfOkknAYRb9iWj+uEVF
|
||||
YYW3S4NfFxvP/wv+5Mz5yh9m7l50JZR6Jw4PQ1AUSK3GiuGs/44Q7eaSSMiUwTos
|
||||
24ZxZo4ZkxPt+UcGXoviLss6wrNejTHkxafNPwlw5AJdNCpNt/UG4vU7j7atSiK4
|
||||
/kOnTWfvw+Htg+LV8tA3D1arW0dpChQDLEOjc+kFcl7faJxnSwhkLcJnI6rlNYhW
|
||||
mZUXYCABAoGBAOrKEobAJbir/UQsGj8bGWjUJm6crW01EimfQMJMlu+LCGE5CLeK
|
||||
H4GXcf+vWlvbmi8vKauSu8VRooTF9Ih5rKK4Fx5KZmK+5av9AUJrFvlze80+91xc
|
||||
ld15c8RgqM+VgLp9AhScflhPjAgsuEYxI7Iawzh4XOpQnUIjMTCaDz8nAoGBANrl
|
||||
02YPNFOM6L9fHkaTR98wV74fMGp+6fBrP2GJUeIL2lEJZfYjOmGGAkYKzxFzfC1l
|
||||
vWS4DiTSt1GPObSiG+SavGYx4gDrPiAGlwqgu4Lav9XpIHenVYZpzus40/Stgp7O
|
||||
AgXFEarAuWZv5/QmV3L6UAutdkSG4D73wD7zlJ8BAoGAHzYNkGwql4oFePKD6q+n
|
||||
iQ/qq/mX9FSBvZa1/R5BUkahLotuZTevSILhXKPq1xsyO+OBHpW68FgRyqSmBR5n
|
||||
nJnsONKbGbVWwq43ZKTnwPFhG7+rElQcd/yVLx3KUw4EtsW3aRYElai9bLjFJk+R
|
||||
9zMnkHIvp9ZfkVMsTtGsBTECgYEAg6RVpvob2OdUDcrxVTY7sfDLw83T+yfKHskQ
|
||||
u+KueMfyCmwhgo4bDQ1fjqnvb6pJErAt30WFVAXZM1Z0OLqJFcks5jS3mx/eI7py
|
||||
2XRicEaHuehSm0Lp/0TgqLtrVKmIdWKk+r1Sa6MtnHpOP5lTXBVHUE6IYpvOfm/W
|
||||
kMVCKwECgYEAlPJCqRpiHHq/NBunh669OtnxjE729SdarvEeFQam0OTg7DpAAhO5
|
||||
MZrNOsY0fcadnmBbygOIh1bw4eo3litTQLJ4ToDi4CSMgw74d6Rk1cwJbNZSSflV
|
||||
YRZytdLq4WH7MSTwMIz+XClxBgkRTe9RpjNiVNLH3rp4F7EnUPTvxDo=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
30
testenv/certs/wget-cert.pem
Normal file
30
testenv/certs/wget-cert.pem
Normal file
@@ -0,0 +1,30 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMV8qEpuSVUdWaAY
|
||||
F2N1ljGEJ/907Og5B0aZLeDskmLAOohKMWTiiSx+lseXVD/Zf/LaFfy/+q0Rk5+o
|
||||
pFEPEEjadvdxogb9HPwjfj48ng74yV1c5ZGRx/aIeIJN9cacfs4J5NlT3ZPiV8/2
|
||||
mpBurBYvta5tneUl+lx4NHTEBmjTAgMBAAECgYBHlFlDMRovWYYEuvavPA2GQQpm
|
||||
UzETMqhqdFbmsZiVZmtQvuOMV3e0wuVPzo/g3Kq9kUJq7AKl/DrvoaZ9IuKZgkDD
|
||||
0QEBYo/lcxEA9qcfgVs5XLp9ED1mXzJSZ3bmpCDqa2NjG7yFdWzPxc1DXmT05MrF
|
||||
bZbb0Wao0tvMwoeJYQJBAOql5uOyjDHvLLuS0IFKbYz4LQwAp7Gjs0ZS9qLNhQQn
|
||||
m5Vr8xS9QwFID693K6aDl3tqSCIwSnyInacj8M8v18sCQQDXdReE2i4LKOVLcQsP
|
||||
XabN96fFLlnoIh9MqFza4skjhXJWqjBLgJuFqyT5CTbU9TmaoIPXdo4454P1CCgR
|
||||
KEIZAkAZE7nlQ8Ov4nvJYBtgde/XTP6jdb52QaR7M4qgQ46frwv1oB/Oa5upm2Xx
|
||||
vq6vkQiza9xhqv+K557RqgmmWtqZAkASoXJmL4OZvXCOZHkDXCLHXqnoOAjYNNMm
|
||||
Csz0tHWWF7z6V38TmExac6Ef07clFQtlHoooAH1t2D8l2g205hlJAkBfeghbZDdY
|
||||
16NtVnvtzjjhKqZFqwTSANFV8NSzgb/QiNnX0hsMPt9bbc5VCo77Ly2oP5SvixfZ
|
||||
kjrIQqDV8MLu
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICODCCAaGgAwIBAgIJAOiSkPuPcAwqMA0GCSqGSIb3DQEBBQUAMDUxCzAJBgNV
|
||||
BAYTAklOMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhHTlUgV2dldDAe
|
||||
Fw0xMzEyMDcwNTA3NTRaFw0xNDEyMDcwNTA3NTRaMDUxCzAJBgNVBAYTAklOMRMw
|
||||
EQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhHTlUgV2dldDCBnzANBgkqhkiG
|
||||
9w0BAQEFAAOBjQAwgYkCgYEAxXyoSm5JVR1ZoBgXY3WWMYQn/3Ts6DkHRpkt4OyS
|
||||
YsA6iEoxZOKJLH6Wx5dUP9l/8toV/L/6rRGTn6ikUQ8QSNp293GiBv0c/CN+Pjye
|
||||
DvjJXVzlkZHH9oh4gk31xpx+zgnk2VPdk+JXz/aakG6sFi+1rm2d5SX6XHg0dMQG
|
||||
aNMCAwEAAaNQME4wHQYDVR0OBBYEFLhtTG9a6v3ihL5DeWKfq6doYI42MB8GA1Ud
|
||||
IwQYMBaAFLhtTG9a6v3ihL5DeWKfq6doYI42MAwGA1UdEwQFMAMBAf8wDQYJKoZI
|
||||
hvcNAQEFBQADgYEApTEZX3cgmgdXDJsu7wtkejtq3vuyi6NXBUlHzoYzWaS5wn8P
|
||||
uDG4G9zd1cwmwrbYA8lS+ANWvkcqjM68gMs1ARMZRS0IrYMCN8bokQw+16sqImZO
|
||||
THX50Sb5U+9e1IotDWyRBNO10znsoh569BxhJ5WZdIaoKHOJdXEYV+3Y/hg=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -3,6 +3,7 @@ import os
|
||||
# this file implements the mechanism of conf class auto-registration,
|
||||
# don't modify this file if you have no idea what you're doing
|
||||
|
||||
|
||||
def gen_hook():
|
||||
hook_table = {}
|
||||
|
||||
@@ -23,9 +24,9 @@ def gen_hook():
|
||||
return cls
|
||||
|
||||
def find_hook(name):
|
||||
try:
|
||||
if name in hook_table:
|
||||
return hook_table[name]
|
||||
except:
|
||||
else:
|
||||
raise AttributeError
|
||||
|
||||
return Wrapper, find_hook
|
||||
|
||||
11
testenv/conf/server_conf.py
Normal file
11
testenv/conf/server_conf.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from conf import hook
|
||||
|
||||
|
||||
@hook()
|
||||
class ServerConf:
|
||||
def __init__(self, server_settings):
|
||||
self.server_settings = server_settings
|
||||
|
||||
def __call__(self, test_obj):
|
||||
for server in test_obj.servers:
|
||||
server.server_sett(self.server_settings)
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
@@ -25,12 +25,14 @@ T_COLORS = {
|
||||
'ENDC' : '\033[0m'
|
||||
}
|
||||
|
||||
system = True if platform.system() == 'Linux' else False
|
||||
check = False if getenv("MAKE_CHECK") == 'True' else True
|
||||
|
||||
def printer (color, string):
|
||||
if system and check:
|
||||
print (T_COLORS.get (color) + string + T_COLORS.get ('ENDC'))
|
||||
if platform.system () == 'Linux':
|
||||
if getenv ("MAKE_CHECK", "False") == "True":
|
||||
print (string)
|
||||
else:
|
||||
print (T_COLORS.get (color) + string + T_COLORS.get ('ENDC'))
|
||||
|
||||
else:
|
||||
print (string)
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ from random import random
|
||||
from hashlib import md5
|
||||
import threading
|
||||
import socket
|
||||
import re
|
||||
import ssl
|
||||
import os
|
||||
|
||||
|
||||
@@ -35,18 +37,16 @@ class HTTPSServer (StoppableHTTPServer):
|
||||
additional support for secure connections through SSL. """
|
||||
|
||||
def __init__ (self, address, handler):
|
||||
import ssl
|
||||
BaseServer.__init__ (self, address, handler)
|
||||
# step one up because test suite change directory away from $srcdir (don't do that !!!)
|
||||
CERTFILE = os.path.abspath(os.path.join('..', os.getenv('srcdir', '.'), 'certs', 'server-cert.pem'))
|
||||
KEYFILE = os.path.abspath(os.path.join('..', os.getenv('srcdir', '.'), 'certs', 'server-key.pem'))
|
||||
print (os.getcwd())
|
||||
CERTFILE = os.path.abspath(os.path.join('..', 'certs', 'wget-cert.pem'))
|
||||
print (CERTFILE)
|
||||
fop = open (CERTFILE)
|
||||
print (fop.readline())
|
||||
self.socket = ssl.wrap_socket (
|
||||
sock = socket.socket (self.address_family, self.socket_type),
|
||||
ssl_version = ssl.PROTOCOL_TLSv1,
|
||||
certfile = CERTFILE,
|
||||
keyfile = KEYFILE,
|
||||
server_side = True
|
||||
)
|
||||
self.server_bind()
|
||||
@@ -62,7 +62,8 @@ class _Handler (BaseHTTPRequestHandler):
|
||||
requests. """
|
||||
|
||||
def get_rule_list (self, name):
|
||||
return self.rules.get(name)
|
||||
r_list = self.rules.get (name) if name in self.rules else None
|
||||
return r_list
|
||||
|
||||
# The defailt protocol version of the server we run is HTTP/1.1 not
|
||||
# HTTP/1.0 which is the default with the http.server module.
|
||||
@@ -135,7 +136,6 @@ class _Handler (BaseHTTPRequestHandler):
|
||||
""" Helper functions for the Handlers. """
|
||||
|
||||
def parse_range_header (self, header_line, length):
|
||||
import re
|
||||
if header_line is None:
|
||||
return None
|
||||
if not header_line.startswith ("bytes="):
|
||||
@@ -205,37 +205,34 @@ class _Handler (BaseHTTPRequestHandler):
|
||||
return string.decode ('utf-8')
|
||||
|
||||
def send_challenge (self, auth_type):
|
||||
auth_type = auth_type.lower()
|
||||
if auth_type == "both":
|
||||
self.send_challenge ("basic")
|
||||
self.send_challenge ("digest")
|
||||
if auth_type == "Both":
|
||||
self.send_challenge ("Digest")
|
||||
self.send_challenge ("Basic")
|
||||
return
|
||||
if auth_type == "basic":
|
||||
challenge_str = 'BasIc realm="Wget-Test"'
|
||||
elif auth_type == "digest" or auth_type == "both_inline":
|
||||
if auth_type == "Basic":
|
||||
challenge_str = 'Basic realm="Wget-Test"'
|
||||
elif auth_type == "Digest" or auth_type == "Both_inline":
|
||||
self.nonce = md5 (str (random ()).encode ('utf-8')).hexdigest()
|
||||
self.opaque = md5 (str (random ()).encode ('utf-8')).hexdigest()
|
||||
# 'DIgest' to provoke a Wget failure with turkish locales
|
||||
challenge_str = 'DIgest realm="Test", nonce="%s", opaque="%s"' % (
|
||||
challenge_str = 'Digest realm="Test", nonce="%s", opaque="%s"' % (
|
||||
self.nonce,
|
||||
self.opaque)
|
||||
challenge_str += ', qop="auth"'
|
||||
if auth_type == "both_inline":
|
||||
# 'BasIc' to provoke a Wget failure with turkish locales
|
||||
challenge_str = 'BasIc realm="Wget-Test", ' + challenge_str
|
||||
if auth_type == "Both_inline":
|
||||
challenge_str = 'Basic realm="Wget-Test", ' + challenge_str
|
||||
self.send_header ("WWW-Authenticate", challenge_str)
|
||||
|
||||
def authorize_basic (self, auth_header, auth_rule):
|
||||
if auth_header is None or auth_header.split(' ')[0].lower() != 'basic':
|
||||
def authorize_Basic (self, auth_header, auth_rule):
|
||||
if auth_header is None or auth_header.split(' ')[0] != 'Basic':
|
||||
return False
|
||||
else:
|
||||
self.user = auth_rule.auth_user
|
||||
self.passw = auth_rule.auth_pass
|
||||
auth_str = "basic " + self.base64 (self.user + ":" + self.passw)
|
||||
return True if auth_str.lower() == auth_header.lower() else False
|
||||
auth_str = "Basic " + self.base64 (self.user + ":" + self.passw)
|
||||
return True if auth_str == auth_header else False
|
||||
|
||||
def parse_auth_header (self, auth_header):
|
||||
n = len("digest ")
|
||||
n = len("Digest ")
|
||||
auth_header = auth_header[n:].strip()
|
||||
items = auth_header.split(", ")
|
||||
keyvals = [i.split("=", 1) for i in items]
|
||||
@@ -267,8 +264,8 @@ class _Handler (BaseHTTPRequestHandler):
|
||||
|
||||
return True if resp == params['response'] else False
|
||||
|
||||
def authorize_digest (self, auth_header, auth_rule):
|
||||
if auth_header is None or auth_header.split(' ')[0].lower() != 'digest':
|
||||
def authorize_Digest (self, auth_header, auth_rule):
|
||||
if auth_header is None or auth_header.split(' ')[0] != 'Digest':
|
||||
return False
|
||||
else:
|
||||
self.user = auth_rule.auth_user
|
||||
@@ -287,10 +284,10 @@ class _Handler (BaseHTTPRequestHandler):
|
||||
pass_auth = False
|
||||
return pass_auth
|
||||
|
||||
def authorize_both (self, auth_header, auth_rule):
|
||||
def authorize_Both (self, auth_header, auth_rule):
|
||||
return False
|
||||
|
||||
def authorize_both_inline (self, auth_header, auth_rule):
|
||||
def authorize_Both_inline (self, auth_header, auth_rule):
|
||||
return False
|
||||
|
||||
def Authentication (self, auth_rule):
|
||||
@@ -305,21 +302,38 @@ class _Handler (BaseHTTPRequestHandler):
|
||||
def handle_auth (self, auth_rule):
|
||||
is_auth = True
|
||||
auth_header = self.headers.get ("Authorization")
|
||||
required_auth = auth_rule.auth_type.lower()
|
||||
if required_auth == "both" or required_auth == "both_inline":
|
||||
auth_type = auth_header.split(' ')[0].lower() if auth_header else required_auth
|
||||
required_auth = auth_rule.auth_type
|
||||
if required_auth == "Both" or required_auth == "Both_inline":
|
||||
auth_type = auth_header.split(' ')[0] if auth_header else required_auth
|
||||
else:
|
||||
auth_type = required_auth
|
||||
try:
|
||||
assert hasattr (self, "authorize_" + auth_type)
|
||||
is_auth = getattr (self, "authorize_" + auth_type) (auth_header, auth_rule)
|
||||
except AssertionError:
|
||||
raise ServerError ("Authentication Mechanism " + auth_type + " not supported")
|
||||
raise ServerError ("Authentication Mechanism " + auth_rule + " not supported")
|
||||
except AttributeError as ae:
|
||||
raise ServerError (ae.__str__())
|
||||
if is_auth is False:
|
||||
raise ServerError ("Unable to Authenticate")
|
||||
|
||||
def is_authorized (self):
|
||||
is_auth = True
|
||||
auth_rule = self.get_rule_list ('Authentication')
|
||||
if auth_rule:
|
||||
auth_header = self.headers.get ("Authorization")
|
||||
req_auth = auth_rule.auth_type
|
||||
if req_auth == "Both" or req_auth == "Both_inline":
|
||||
auth_type = auth_header.split(' ')[0] if auth_header else req_auth
|
||||
else:
|
||||
auth_type = req_auth
|
||||
assert hasattr (self, "authorize_" + auth_type)
|
||||
is_auth = getattr (self, "authorize_" + auth_type) (auth_header, auth_rule)
|
||||
if is_auth is False:
|
||||
self.send_response (401)
|
||||
self.send_challenge (auth_type)
|
||||
self.finish_headers ()
|
||||
return is_auth
|
||||
|
||||
def ExpectHeader (self, header_obj):
|
||||
exp_headers = header_obj.headers
|
||||
@@ -330,16 +344,27 @@ class _Handler (BaseHTTPRequestHandler):
|
||||
self.finish_headers ()
|
||||
raise ServerError ("Header " + header_line + " not found")
|
||||
|
||||
|
||||
def RejectHeader (self, header_obj):
|
||||
rej_headers = header_obj.headers
|
||||
for header_line in rej_headers:
|
||||
header_recd = self.headers.get (header_line)
|
||||
if header_recd is not None and header_recd == rej_headers[header_line]:
|
||||
self.send_error (400, 'Blacklisted Header ' + header_line + ' received')
|
||||
self.send_error (400, 'Blackisted Header ' + header_line + ' received')
|
||||
self.finish_headers ()
|
||||
raise ServerError ("Header " + header_line + ' received')
|
||||
|
||||
def reject_headers (self):
|
||||
rej_headers = self.get_rule_list ("RejectHeader")
|
||||
if rej_headers:
|
||||
rej_headers = rej_headers.headers
|
||||
for header_line in rej_headers:
|
||||
header_re = self.headers.get (header_line)
|
||||
if header_re is not None and header_re == rej_headers[header_line]:
|
||||
self.send_error (400, 'Blacklisted Header was Sent')
|
||||
self.end_headers ()
|
||||
return False
|
||||
return True
|
||||
|
||||
def __log_request (self, method):
|
||||
req = method + " " + self.path
|
||||
self.server.request_headers.append (req)
|
||||
@@ -415,7 +440,11 @@ class _Handler (BaseHTTPRequestHandler):
|
||||
".css" : "text/css",
|
||||
".html" : "text/html"
|
||||
}
|
||||
return extension_map.get(ext, "text/plain")
|
||||
if ext in extension_map:
|
||||
return extension_map[ext]
|
||||
else:
|
||||
return "text/plain"
|
||||
|
||||
|
||||
class HTTPd (threading.Thread):
|
||||
server_class = StoppableHTTPServer
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user