160 Commits

Author SHA1 Message Date
Darshit Shah
af702340a1 Merge remote-tracking branch 'origin/master' into parallel-wget
Conflicts:
	src/http.c
	testenv/Makefile.am
	testenv/Test--https.py
	testenv/Test--spider-r.py
	testenv/Test-Content-disposition-2.py
	testenv/Test-Content-disposition.py
	testenv/Test-Head.py
	testenv/Test-O.py
	testenv/Test-Parallel-Proto.py
	testenv/Test-Post.py
	testenv/Test-Proto.py
	testenv/Test-auth-basic-fail.py
	testenv/Test-auth-basic.py
	testenv/Test-auth-both.py
	testenv/Test-auth-digest.py
	testenv/Test-auth-no-challenge-url.py
	testenv/Test-auth-no-challenge.py
	testenv/Test-auth-retcode.py
	testenv/Test-auth-with-content-disposition.py
	testenv/Test-c-full.py
	testenv/Test-cookie-401.py
	testenv/Test-cookie-domain-mismatch.py
	testenv/Test-cookie-expires.py
	testenv/Test-cookie.py
	testenv/conf/__init__.py
	testenv/conf/authentication.py
	testenv/conf/expect_header.py
	testenv/conf/expected_files.py
	testenv/conf/expected_ret_code.py
	testenv/conf/files_crawled.py
	testenv/conf/hook_sample.py
	testenv/conf/local_files.py
	testenv/conf/reject_header.py
	testenv/conf/response.py
	testenv/conf/send_header.py
	testenv/conf/server_files.py
	testenv/conf/urls.py
	testenv/conf/wget_commands.py
	testenv/misc/colour_terminal.py
	testenv/server/http/http_server.py
	testenv/test/base_test.py
	testenv/test/http_test.py
2014-09-14 16:57:15 +05:30
Darshit Shah
6140b1b6e3 Support running tests through valgrind 2014-07-23 18:42:43 +05:30
Darshit Shah
c22b806ee0 Document SERVER_WAIT 2014-07-22 12:49:46 +05:30
Giuseppe Scrivano
ca69294c8a syntax-check: fix tab-space indentation 2014-07-21 17:15:31 +02:00
Giuseppe Scrivano
87a5922141 Merge remote-tracking branch 'origin/master' into parallel-wget
Conflicts:
	src/Makefile.am
	src/wget.h
2014-07-17 11:07:35 +02:00
Giuseppe Scrivano
99ccc492f4 Merge remote-tracking branch 'origin/master' into parallel-wget
Conflicts:
	src/progress.c
	src/retr.c
2014-06-22 20:17:50 +02:00
Darshit Shah
825716399c Fix crash in test suite 2014-06-22 01:06:08 +05:30
Darshit Shah
21908a4b13 Merge remote-tracking branch 'origin/master' into parallel-wget
Conflicts:
	README.checkout
	configure.ac
	src/build_info.c.in
	src/ftp.c
	src/http.c
	src/main.c
	src/options.h
	src/progress.c
	src/retr.c
	src/retr.h
2014-06-09 00:58:01 +05:30
Zihang Chen
ecd69778bf Refactor mainly the test cases classes
Files that were refactored are WgetTest.py, some conf
scripts and some test case file. The purpose of the
refactoring of the test cases classes is to provide
a better interface for the incoming FTP test
counterpart.
2014-06-07 16:34:39 +02:00
Zihang Chen
d26c8ebb16 Create package test for test case classes
delete mode 100644 testenv/WgetTest.py
 create mode 100644 testenv/test/__init__.py
 create mode 100644 testenv/test/base_test.py
 create mode 100644 testenv/test/http_test.py
2014-06-07 16:34:39 +02:00
Zihang Chen
507383df07 Move server classes to package server.protocol
delete mode 100644 testenv/FTPServer.py
 delete mode 100644 testenv/HTTPServer.py
 create mode 100644 testenv/server/__init__.py
 create mode 100644 testenv/server/ftp/__init__.py
 create mode 100644 testenv/server/ftp/ftp_server.py
 create mode 100644 testenv/server/http/__init__.py
 create mode 100644 testenv/server/http/http_server.py
2014-06-07 16:34:39 +02:00
Zihang Chen
195393bf41 Create package conf where rules and hooks are put
create mode 100644 testenv/conf/__init__.py
 create mode 100644 testenv/conf/authentication.py
 create mode 100644 testenv/conf/expect_header.py
 create mode 100644 testenv/conf/expected_files.py
 create mode 100644 testenv/conf/expected_ret_code.py
 create mode 100644 testenv/conf/files_crawled.py
 create mode 100644 testenv/conf/hook_sample.py
 create mode 100644 testenv/conf/local_files.py
 create mode 100644 testenv/conf/reject_header.py
 create mode 100644 testenv/conf/response.py
 create mode 100644 testenv/conf/rule_sample.py
 create mode 100644 testenv/conf/send_header.py
 create mode 100644 testenv/conf/server_conf.py
 create mode 100644 testenv/conf/server_files.py
 create mode 100644 testenv/conf/urls.py
 create mode 100644 testenv/conf/wget_commands.py
2014-06-07 16:34:39 +02:00
Zihang Chen
42e482ad99 Create package exc and move TestFailed to exc
create mode 100644 testenv/exc/__init__.py
 create mode 100644 testenv/exc/test_failed.py
2014-06-07 16:34:39 +02:00
Zihang Chen
82f44f303a Fix a typo in Test-Proto.py 2014-06-07 16:34:39 +02:00
Zihang Chen
31e5f33b5e From WgetTest.py move WgetFile to misc
create mode 100644 testenv/misc/wget_file.py
2014-06-07 16:34:39 +02:00
Zihang Chen
422171da81 Create package misc, move ColourTerm.py to misc
delete mode 100644 testenv/ColourTerm.py
 create mode 100644 testenv/misc/__init__.py
 create mode 100644 testenv/misc/colour_terminal.py
2014-06-07 16:34:38 +02:00
Giuseppe Scrivano
df96c81cf3 Merge remote-tracking branch 'origin' into parallel-wget 2014-03-31 20:55:31 +02:00
Giuseppe Scrivano
60a95d8393 Merge remote-tracking branch 'origin/master' into parallel-wget
Conflicts:
	src/http.c
	src/main.c
2014-03-21 13:12:57 +01:00
Giuseppe Scrivano
35ab8cdd7a Merge remote-tracking branch 'origin/master' into parallel-wget 2014-03-05 11:22:39 +01:00
Giuseppe Scrivano
9020b71c18 Merge branch 'master' into parallel-wget
Conflicts:
	src/main.c
2014-01-22 22:12:22 +01:00
Darshit Shah
b31e6e4674 Add support for HTTPS Servers 2014-01-03 20:32:06 +01:00
Darshit Shah
b828a6e4a7 Sleep for n seconds before calling Wget Executable
This commit adds support for a new Environment Variable, SERVER_WAIT
which if set will cause the script to sleep for SERVER_WAIT seconds
before calling the wget executable. During this period, the custom
HTTP/HTTPS/FTP servers are all set up and running and can be used
for any other purposes. This feature is often used when a separate
executable must be used for testing apart from the one at src/wget
2014-01-03 20:32:06 +01:00
Darshit Shah
7effa90359 Support programatically setting Handler class variables 2014-01-03 20:32:06 +01:00
Darshit Shah
7e1f4c1abc Correct the call to stop_HTTP_Server 2014-01-03 20:32:06 +01:00
Darshit Shah
f616192dfd Improve error handling when wget executable isn't available 2014-01-03 20:32:06 +01:00
Darshit Shah
31868fed6c Split large function to improve readability and extensibility 2014-01-03 20:32:06 +01:00
Darshit Shah
59a03f15dd Add new configure option, --enable-race-checking
This commit adds a new configure option, --enable-race-checking
which is to be used exclusively for debugging. Also, conditionally
add tests to XFAIL_TESTS when Race Checking is enabled.
2013-12-04 20:45:44 +01:00
Darshit Shah
fa670282ee configure: fix redundant --enable-threads and add metalink info.
Remove redundant --enable-threads option and add Metalink to configure
summary.
2013-12-04 20:22:25 +01:00
Giuseppe Scrivano
0d58672dc6 Always define options.jobs 2013-11-10 14:33:04 +01:00
Giuseppe Scrivano
93597efe7b progress bar: fix a possible segfault 2013-11-10 14:24:17 +01:00
Giuseppe Scrivano
3010d9c281 Merge branch 'origin' into parallel-wget 2013-11-04 11:14:18 +01:00
Giuseppe Scrivano
ebfae2c353 progress: show the URL near the progress bar 2013-11-03 00:32:46 +01:00
Giuseppe Scrivano
15d167e264 progress: progress bar supports threads. 2013-11-03 00:32:32 +01:00
Giuseppe Scrivano
b87cee3763 progress: Split update into update and draw 2013-11-03 00:30:19 +01:00
Giuseppe Scrivano
1a48da4cdc http: don't register multiple times the same fd 2013-11-03 00:29:59 +01:00
Giuseppe Scrivano
349cbd0dd5 threads: correctly initialize number of threads. 2013-10-30 22:30:26 +01:00
Giuseppe Scrivano
d9f1cd05c1 testenv: Remove Test--spider-r.py from XFAIL_TESTS 2013-10-14 00:23:41 +02:00
Giuseppe Scrivano
921a23d60c recur: Refactor to use the same code when threads are disabled. 2013-10-13 23:24:32 +02:00
Giuseppe Scrivano
7d18fd1025 metalink: internationalize some messages to the user. 2013-10-13 18:35:43 +02:00
Giuseppe Scrivano
43ca403306 retr: minor aesthetic changes. 2013-10-13 18:17:17 +02:00
Giuseppe Scrivano
93ad38686a Merge remote-tracking branch 'origin' into parallel-wget 2013-10-13 17:53:35 +02:00
Giuseppe Scrivano
89024dda4f testenv: fix make dist 2013-10-06 19:33:19 +02:00
Giuseppe Scrivano
00c93a0625 Merge remote-tracking branch 'pytests' into parallel-wget 2013-10-06 16:26:49 +02:00
Giuseppe Scrivano
44c821227c Merge remote-tracking branch 'origin' into parallel-wget 2013-10-06 14:58:20 +02:00
Giuseppe Scrivano
cb5c287f02 Unregister a connection while it is used 2013-10-06 14:58:17 +02:00
Darshit Shah
3dfba0bec8 use wgint instead of int 2013-09-18 10:00:03 +02:00
Darshit Shah
fd80f6e878 Change commandline option to --metalink-file 2013-09-18 09:59:07 +02:00
Darshit Shah
db4262d6dd Merge branch 'master' into Working 2013-09-17 03:22:23 +05:30
Darshit Shah
7743384820 Update documentation to reflect changes in code 2013-09-17 03:15:01 +05:30
Darshit Shah
b703633715 Add feature that allows to ensure that Wget correctly crawls the website in recursive mode 2013-09-16 21:06:20 +05:30
Darshit Shah
0758f47954 Add new test for recursive spider mode 2013-09-16 21:06:20 +05:30
Darshit Shah
43bb61b4e3 Smartly guess content type header 2013-09-16 21:06:20 +05:30
Darshit Shah
d4d0e6378c Support substring replace in File Contents too 2013-09-16 21:06:20 +05:30
Darshit Shah
f5785003b1 Compatibility fix with multiple servers
We will not maintian two different interfaces as earlier decided.
Instead, a common, single interface will be maintained. Hence, the tests
must adhere to the same format expected of the Parallel Tests.
2013-09-16 21:06:20 +05:30
Darshit Shah
8b1a9b6de7 Extend Functionality to support spawning multiple servers 2013-09-16 21:06:20 +05:30
Darshit Shah
e84192a8d3 Use the provided calls to shutdown server instead of rewriting it 2013-09-10 12:27:00 +05:30
Darshit Shah
99659f3295 Improve Documentation 2013-09-10 12:26:34 +05:30
Darshit Shah
cb94e52d0f Slight code cleanup. Remove unused code 2013-09-07 17:33:54 +05:30
Darshit Shah
886ac1a89b Shift to new Threading Model from Multiprocessing model
This eliminated the use of Global Variables from the HTTPServer module
and uses the more correct threading.Threads module to spawn a new
server. However, on multi-core systems, the performance may deteriorate
when too many servers are launched due to CPython implementation of GIL.

Many artefacts from the old model still remain, sometimes as commenst,
else as executable code. These will be cleaned up soon
2013-09-07 17:33:54 +05:30
Darshit Shah
e74c2ec25e Add new test for POST Requests 2013-09-07 17:33:54 +05:30
Darshit Shah
48644f174e Print diff when file contents don't match 2013-09-07 17:33:53 +05:30
Darshit Shah
b6f9efe7b5 Add tests for Cookie support 2013-09-07 17:33:53 +05:30
Darshit Shah
4c9e6b4f71 Document pending work 2013-09-07 17:33:53 +05:30
Darshit Shah
e13bc90211 Add new test to ensure Content Disposition and Auth work together 2013-09-07 17:33:53 +05:30
Darshit Shah
60d1f4d1ad Add new Test for Continue command 2013-09-07 17:33:53 +05:30
Darshit Shah
738b299419 Add test, Test-Head 2013-09-07 17:33:53 +05:30
Darshit Shah
9b9d16b2f3 Edit non-unique TEST_NAME variable 2013-09-07 17:33:53 +05:30
Darshit Shah
ae958db622 Minor optimizations to the way Server Rules are executed 2013-09-07 17:33:53 +05:30
Darshit Shah
50b4f0c72b The rules need not be a defaultdict. 2013-09-07 17:33:53 +05:30
Darshit Shah
dccc154a0e Introducing Python based Test Environment 2013-09-07 17:33:53 +05:30
Giuseppe Scrivano
4445d48471 Merge remote-tracking branch 'origin' into parallel-wget 2013-07-30 01:02:28 +02:00
Giuseppe Scrivano
f29fded6f4 Disable timeouts when there are threads 2013-07-12 00:53:27 +02:00
Giuseppe Scrivano
a528894d13 Merge remote-tracking branch 'origin/master' into parallel-wget 2013-07-12 00:16:23 +02:00
Giuseppe Scrivano
7bb672a487 doc: fix error with texinfo 5. 2013-07-04 10:25:23 +02:00
Darshit Shah
747023c476 Mention libmetalink in list of required utilities 2013-07-02 19:33:55 +02:00
Giuseppe Scrivano
29cf6bb9d1 Merge remote-tracking branch 'origin/master' into parallel-wget 2013-07-02 11:14:29 +02:00
Giuseppe Scrivano
3595b9de52 configure: by default disable threads and metalink 2013-06-23 21:53:41 +02:00
Giuseppe Scrivano
2d1196b116 Define PCONN_LOCK when threads are not used. 2013-06-23 21:46:25 +02:00
Giuseppe Scrivano
74d5c8bfb7 Fix possible race condition 2013-06-23 21:16:13 +02:00
Giuseppe Scrivano
fec5bb9e93 Merge remote-tracking branch 'origin/master' into parallel-wget 2013-06-23 18:33:06 +02:00
Jochen Hein
5f48ec1500 Remove double empty space from string. 2013-06-03 21:31:20 +02:00
Bykov Aleksey
8560182d57 Changed fopen mode 2013-05-22 19:20:17 +02:00
Ray Satiro
8e5038747b MinGW compatibility fixes 2013-05-22 00:16:58 +02:00
Giuseppe Scrivano
82126ccb67 dist: add some missing files. 2013-05-19 23:34:38 +02:00
Giuseppe Scrivano
ced4c1de82 Merge remote-tracking branch 'origin/master' into parallel-wget 2013-05-19 16:50:07 +02:00
Giuseppe Scrivano
04fcd759fd Ensure that each thread uses a different socket 2013-04-21 23:12:56 +02:00
Giuseppe Scrivano
e9058befae Merge branch 'master' into parallel-wget
Conflicts:
	src/init.c
	src/main.c
2013-04-21 21:11:53 +02:00
Ilim Ugur
c1a44a16ef Fix bug due to ambiguous variable name. 2013-02-07 22:25:56 +01:00
Giuseppe Scrivano
5a0f05423a Fix a tight-loop when a recursion level is used. 2012-12-09 22:04:58 +01:00
Giuseppe Scrivano
3217905144 Fix a build error with new gnulib versions. 2012-12-09 22:00:37 +01:00
Giuseppe Scrivano
e23e8101db Fix build issue with last gnulib version. 2012-12-04 23:47:20 +01:00
Domenico Chierico
2dd255596a Fix tests build fixes 2012-12-04 23:46:43 +01:00
Giuseppe Scrivano
979a485a9a Fix iri support with threads 2012-12-02 21:55:29 +01:00
Giuseppe Scrivano
617bb37d6e Fix segfault 2012-12-02 00:52:42 +01:00
Giuseppe Scrivano
0717a886c2 Fix a deadlock. 2012-12-01 21:04:20 +01:00
Domenico Chierico
2f2483214c fix build issues 2012-11-30 00:23:58 +01:00
Giuseppe Scrivano
e6d8e165c5 Fix a deadlock 2012-11-29 23:40:33 +01:00
Giuseppe Scrivano
7c8735a6ee Fix thread resources leak. 2012-10-30 22:45:07 +01:00
Ilim Ugur
c24dce1d07 Correct faulty logic in elect_resources and elect_checksums. 2012-09-18 23:39:45 +03:00
Ilim Ugur
e7e869f951 Update ChangeLogs. Add missing prototypes to metalink.c. Remove static variable temp from multi.c.(NOT WORKING) 2012-09-18 01:16:56 +03:00
Ilim Ugur
bfe30ea754 Update ChangeLogs to reflect changes before August 16. 2012-09-14 01:06:40 +03:00
Ilim Ugur
dcc6abee90 Correct allocation size in interoption availability checks for --metalink. 2012-08-22 12:26:07 +03:00
Ilim Ugur
4cd6292b31 Parse metalink info to an internal set of structures. 2012-08-20 16:02:27 +03:00
Ilim Ugur
6b59fab021 Correct shallow copying in ftp.c. Correct malloc statement in retr.c. Support multi-thread FTP downloads. 2012-08-18 15:54:38 +03:00
Ilim Ugur
1d18db4bac Interpret name attribute of file tags in metalink as relative paths. Support -P with metalink downloads. 2012-08-18 02:46:53 +03:00
Ilim Ugur
ed8335aa76 Change --metalink-file to --metalink. Support --quota w/ --metalink. Correct clean_range_res_data(). Add interoption availability checks for --metalink. 2012-08-17 22:53:47 +03:00
Ilim Ugur
87a2b8dcb6 Add header comment to new files. Comment the GSoC code. 2012-08-16 19:14:31 +03:00
Ilim Ugur
a41525e5c2 Transfer handling temp files portion of the code to multi.c. 2012-08-16 16:22:53 +03:00
Ilim Ugur
76790a386a Add a default value for opt.jobs. Remove a (now) redundant variable. 2012-08-16 15:39:24 +03:00
Ilim Ugur
c25d01feb7 Transfer struct range array to multi.c. Delete to redundant variables in retr.c. 2012-08-16 14:22:08 +03:00
Ilim Ugur
f51826d9d8 Correct a source of memory leak when --jobs is not explicitly specified. 2012-08-15 02:24:12 +03:00
Ilim Ugur
721697aef6 Correct segmentation fault when specifying a non-existing metalink file path/URL. 2012-08-15 01:48:48 +03:00
Ilim Ugur
270460da98 Update man page and --help documentation. Update default value for --retries. 2012-08-15 00:43:52 +03:00
Ilim Ugur
fa9aaf2ce6 Correct two merging mistakes in src/convert.h and src/http.c. Replace bootstrap. 2012-08-14 20:24:18 +03:00
Ilim Ugur
eb01e9d442 Resolve conflicts to complete merging with master branch. 2012-08-14 19:47:52 +03:00
Ilim Ugur
2807c5c56d Generate random temp file names. 2012-08-13 01:56:02 +03:00
Ilim Ugur
e37ea16957 Update the logic of delete_temp_files() in multi.c. 2012-08-13 01:11:49 +03:00
Ilim Ugur
5abb1dc188 Update initial URL check and final download printing in main.c. Update the logic of merge_temp_files() in multi.c. 2012-08-12 23:57:59 +03:00
Ilim Ugur
54e5b5d373 Add option --metalink-file. Add a few interoption availability checks for --metalink-file. 2012-08-12 23:21:02 +03:00
Ilim Ugur
768202bf88 Assign values to a few uninitialized variables in retrieve_from_file() 2012-08-12 18:30:03 +03:00
Ilim Ugur
5e2c6fefe4 Delete existing temp_ files before starting to download. Retry on failed download or invalid hash using new option --retries. 2012-08-12 03:20:47 +03:00
Ilim Ugur
0ea58b0c31 Remove option --verify. Compare strongest supported hash type to verify files. 2012-08-11 04:47:31 +03:00
Ilim Ugur
3d19087207 Go back to using <hash_type>_stream functions in gnulib. (Reduces a lot of code) 2012-08-11 02:51:09 +03:00
Ilim Ugur
dc7e47d4d1 Correct faulty lengths in verification and faulty logic in case --verify=all. 2012-08-11 01:45:39 +03:00
Ilim Ugur
b1bc6efc8a Initial working attempt at verifying hashes. 2012-08-10 23:04:58 +03:00
Ilim Ugur
d65343a57b Correct fread error in metalink.c. - Still computes hash wrong. 2012-08-10 20:39:56 +03:00
Ilim Ugur
68dbb9ead7 Add sha256. Rewrite hash verification code. - not working 2012-08-08 14:20:08 +03:00
Ilim Ugur
98db799759 Initial attempt at verifying hashes. - not working 2012-08-03 20:47:31 +03:00
Ilim Ugur
8cfac52713 Remove cat and rm commands. Few corrections with ifdef macros. 2012-08-01 20:35:25 +03:00
Ilim Ugur
11d09dd001 Add FTP support to metalink code. (for single-threaded downloads only) 2012-08-01 00:37:40 +03:00
Ilim Ugur
159c371492 Update fallbacking for metalink: next source goes on from where the previous one failed. 2012-07-31 17:25:21 +03:00
Ilim Ugur
38b1df95f9 Make thread support optional. - No check for semaphore in configure.ac. 2012-07-29 23:43:03 +03:00
Ilim Ugur
f07e0a67b4 Have wget --version list metalink as supported. 2012-07-28 03:15:42 +03:00
Ilim Ugur
47bd180ab0 Transfer struct range to wget.h. Make metalink code optional. 2012-07-27 17:08:26 +03:00
Ilim Ugur
198acf4844 Do not fallback to next resource if there is an IO error. Delete a few redundant variables. 2012-07-26 21:29:48 +03:00
Ilim Ugur
5090e0c433 Set a minimum chunk size. 2012-07-25 17:41:53 +03:00
Ilim Ugur
bb28bda88f Accept metalink files specified as URLs. Better counting of the files downloaded in retrieve_from_file. 2012-07-25 01:05:04 +03:00
Ilim Ugur
9fd1e97e40 Correct minor mistakes in syntax. Prevent a leak in http_loop. 2012-07-24 23:59:47 +03:00
Ilim Ugur
40493a76fe Redesign the code block in retrieve_from_file. 2012-07-24 19:03:51 +03:00
Ilim Ugur
6f102902ad Make metalink check in configure.ac automatic. 2012-07-24 00:52:17 +03:00
Micah Cowan
26ca40970a Use latest bootstrap from gnulib, and fix bootstrap.conf. 2012-07-23 12:55:45 -07:00
Ilim Ugur
2f6ef8922b Use pkg-config of libmetalink in configure.ac 2012-07-22 12:44:33 +03:00
Ilim Ugur
39aaaf57f8 Try using pkg-config of libmetalink in configure.ac - error during make 2012-07-22 00:33:20 +03:00
Ilim Ugur
5f4debb6f8 Update configure.ac and src/Makefile.am 2012-07-21 00:40:23 +03:00
Ilim Ugur
2b8e2f8879 Initial attempt at fallbacking in threaded downloads. 2012-07-15 23:59:54 +03:00
Ilim Ugur
b5a8d663f7 Fix No URLs found in <file> message printed after download. 2012-07-15 23:31:47 +03:00
Ilim Ugur
44f75a1955 Separate segmented download and fallbacking. 2012-07-15 00:48:28 +03:00
Ilim Ugur
f4c42b94d8 Remove obsolete retry tag in retr.c 2012-07-11 01:51:34 +03:00
Ilim Ugur
1e1054db8a Initial attempt at incorporating sems logically. 2012-07-11 01:07:44 +03:00
Ilim Ugur
5c608df4e1 Update if statement involving hs->restval http.c:2859 2012-07-10 21:51:41 +03:00
Ilim Ugur
8bc3dbf2d4 Corrected the dual usage mistake of loop variable in retr.c. 2012-07-10 12:26:57 +03:00
Ilim Ugur
7ccf4210f6 Corrected faulty logic on thread creation. Segments recorded separately then merged. 2012-07-10 11:32:57 +03:00
Ilim Ugur
8c66c94989 Initial attempt at achieving segmented downloading from multiple resources. 2012-07-09 23:46:11 +03:00
Micah Cowan
15bfd733f9 Fix some very broken pconn-freeing logic (suspect more like this...). 2012-07-05 18:22:28 -07:00
Ilim Ugur
f63e2230d7 Implemented resource fallbacking during metalink download. No -c behavior. 2012-07-06 02:53:03 +03:00
Ilim Ugur
693b791082 A rough initial attempt at achieving Goal #2. 2012-07-05 17:36:51 +03:00
Ilim Ugur
02d225b5ca Merge http://addictivecode.org/git/parallel-wget into parallel-wget 2012-07-03 15:59:16 +03:00
Micah Cowan
671d681304 Fix bad persistence check. 2012-07-02 16:06:37 -07:00
Ilim Ugur
6ceea0d064 retrieve_from_file in retr.c now checks for metalink files. 2012-07-03 00:51:53 +03:00
Micah Cowan
fc220632fb Merge Giuseppe's parallel-wget patch. 2012-06-30 16:46:29 -07:00
196 changed files with 28801 additions and 26211 deletions

4
.gitignore vendored
View File

@@ -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

View File

@@ -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.

3222
ChangeLog

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

16
ChangeLog.README Normal file
View 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).

View File

@@ -27,7 +27,7 @@
# as that of the covered work.
#
# Version: @VERSION@
# Version: $(VERSION)
#
@@ -43,8 +43,8 @@ ACLOCAL_AMFLAGS = -I m4
# subdirectories in the distribution
SUBDIRS = lib src doc po tests util testenv
EXTRA_DIST = 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
View File

@@ -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:

View File

@@ -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
View File

@@ -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.

View File

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

View File

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

5
cfg.mk
View File

@@ -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)/.*)$$

View File

@@ -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
])

View File

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

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

View File

@@ -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

Submodule gnulib updated: ecc5d3e148...98ca2c063c

61
msdos/ChangeLog Normal file
View 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
View File

@@ -0,0 +1 @@
timestamp

15138
src/ChangeLog Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
# Makefile for `wget' utility
# Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
# 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 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"' > $@

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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 {

View File

@@ -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
*/

View File

@@ -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 *);

View File

@@ -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);

View File

@@ -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

View File

@@ -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:

View File

@@ -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);

View File

@@ -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
View File

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

View File

@@ -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
View 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 */

View File

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

View File

@@ -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>

View File

@@ -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

View File

@@ -253,7 +253,7 @@ struct pool {
(sizevar) = ga_newsize; \
} \
} while (0)
/* Test whether n+1-sized entity name fits in P. We don't support
IE-style non-terminated entities, e.g. "&ltfoo" -> "<foo".
However, "&lt;foo" will work, as will "&lt!foo", "&lt", etc. In
@@ -517,7 +517,7 @@ convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags
*p = c_tolower (*p);
}
}
/* Originally we used to adhere to rfc 1866 here, and allowed only
letters, digits, periods, and hyphens as names (of tags or
attributes). However, this broke too many pages which used
@@ -770,7 +770,7 @@ find_comment_end (const char *beg, const char *end)
}
return NULL;
}
/* Return true if the string containing of characters inside [b, e) is
present in hash table HT. */
@@ -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)

View File

@@ -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);

View File

@@ -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;

File diff suppressed because it is too large Load Diff

View File

@@ -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 *);

View File

@@ -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
View File

@@ -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);
}

View File

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

View File

@@ -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;

View File

@@ -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
View 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
View 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 */

View File

@@ -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
View 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);
}

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -291,7 +291,7 @@ windows_resolution (void)
return 10; /* according to MSDN */
}
#endif /* PTIMER_WINDOWS */
/* The code below this point is independent of timer implementation. */
struct ptimer {

View File

@@ -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;
}

View File

@@ -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 *

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -51,7 +51,7 @@ spider_cleanup (void)
if (nonexisting_urls_set)
string_set_free (nonexisting_urls_set);
}
/* Remembers broken links. */
void
nonexisting_url (const char *url)

View File

@@ -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
View File

@@ -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. */

View File

@@ -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 */

View File

@@ -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

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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
View 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.

View File

@@ -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

View File

@@ -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:

View File

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

View File

@@ -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]]

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

View File

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

View File

@@ -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 = {

View File

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

View File

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

View File

@@ -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):

View File

@@ -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-----

View File

@@ -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-----

View File

@@ -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-----

View File

@@ -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-----

View File

@@ -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-----

View 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-----

View File

@@ -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

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

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

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

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -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