Compare commits
436 Commits
curl-7_15_
...
curl-7_16_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ef442d5803 | ||
![]() |
8680e010c2 | ||
![]() |
4d8dcf7b77 | ||
![]() |
abdbd3100f | ||
![]() |
ddace02efe | ||
![]() |
1f4c8c4f09 | ||
![]() |
8162b32bad | ||
![]() |
daf527b276 | ||
![]() |
ee51c07be6 | ||
![]() |
856ba4c6c6 | ||
![]() |
b3e23373bd | ||
![]() |
e5adab39b1 | ||
![]() |
d31153584e | ||
![]() |
823d296e12 | ||
![]() |
e09450103b | ||
![]() |
fbc4407583 | ||
![]() |
a79e5d7925 | ||
![]() |
82491d5c06 | ||
![]() |
b6f889085d | ||
![]() |
cdbbb7d900 | ||
![]() |
2bf4d9a22c | ||
![]() |
f1918aa343 | ||
![]() |
56580fc6f8 | ||
![]() |
2e6600425e | ||
![]() |
cc021fc200 | ||
![]() |
e6aed92742 | ||
![]() |
02fb4d96d1 | ||
![]() |
43e3c5e5fa | ||
![]() |
4f496f2f70 | ||
![]() |
d681bc7520 | ||
![]() |
f21a2b3270 | ||
![]() |
5f5a28d20e | ||
![]() |
89f9cb4041 | ||
![]() |
2b280bcc69 | ||
![]() |
1c0224be42 | ||
![]() |
dbdb7fa55a | ||
![]() |
83a43bea8a | ||
![]() |
abb4cdafe9 | ||
![]() |
2b7bcf2505 | ||
![]() |
5aefdd93cb | ||
![]() |
4b27fae069 | ||
![]() |
10a13eba72 | ||
![]() |
44ac2776ae | ||
![]() |
36e3e6ed16 | ||
![]() |
5f9cbc4209 | ||
![]() |
3239f059b8 | ||
![]() |
45bac25d90 | ||
![]() |
354c8dcd82 | ||
![]() |
b1e4cc370d | ||
![]() |
2293474b90 | ||
![]() |
9e1aef7183 | ||
![]() |
f68323da7d | ||
![]() |
a61aafa325 | ||
![]() |
33bea767eb | ||
![]() |
9ab7cda010 | ||
![]() |
6da70628c6 | ||
![]() |
3bae748256 | ||
![]() |
521c4b303d | ||
![]() |
a2effd123a | ||
![]() |
7b704e173c | ||
![]() |
6045d051d7 | ||
![]() |
cfe00ed4ad | ||
![]() |
0b4bdcf18f | ||
![]() |
8cade952bf | ||
![]() |
385e612fa5 | ||
![]() |
1886388791 | ||
![]() |
32fe5b14ec | ||
![]() |
bbdc483671 | ||
![]() |
f11d3c329c | ||
![]() |
b0d13fa4cb | ||
![]() |
0fb5a65a58 | ||
![]() |
c8afb02b4c | ||
![]() |
869d65337e | ||
![]() |
277df1c6b1 | ||
![]() |
5ec5b95f54 | ||
![]() |
9e61c904ac | ||
![]() |
7efb955fd0 | ||
![]() |
75899741b9 | ||
![]() |
d465199411 | ||
![]() |
55123424c8 | ||
![]() |
f5e4a78b59 | ||
![]() |
7515a75206 | ||
![]() |
4750e6f3c5 | ||
![]() |
b7aaa4d907 | ||
![]() |
e61e09f658 | ||
![]() |
058e993acb | ||
![]() |
359d500908 | ||
![]() |
cb42855445 | ||
![]() |
d8ff0336a5 | ||
![]() |
0682d25da5 | ||
![]() |
d86d14074d | ||
![]() |
8500397cf1 | ||
![]() |
bd600fbebe | ||
![]() |
064bbb999f | ||
![]() |
bedc61ac45 | ||
![]() |
61a6992559 | ||
![]() |
ebee2e323d | ||
![]() |
b2f8de571f | ||
![]() |
cb4a5f5a2b | ||
![]() |
1beb7de7e0 | ||
![]() |
89ab5f4380 | ||
![]() |
439b84c782 | ||
![]() |
0e899d7728 | ||
![]() |
1a85fb2bd0 | ||
![]() |
8d11767048 | ||
![]() |
fcccf9aa0d | ||
![]() |
72bd027537 | ||
![]() |
1d44c9ccc1 | ||
![]() |
33831759b5 | ||
![]() |
6fe932b255 | ||
![]() |
8da02df8e0 | ||
![]() |
587c99351d | ||
![]() |
88c8d72a21 | ||
![]() |
cf99fed17a | ||
![]() |
ca48b6bf35 | ||
![]() |
4dcd606b47 | ||
![]() |
393ddd6e1f | ||
![]() |
840e796aa9 | ||
![]() |
5fd096da8d | ||
![]() |
eb29c5c285 | ||
![]() |
1eb286e43e | ||
![]() |
ae76ebe2d1 | ||
![]() |
e4505aefd9 | ||
![]() |
d6b0612882 | ||
![]() |
4c65eb0af8 | ||
![]() |
318a8258fd | ||
![]() |
17ae28e0fe | ||
![]() |
3c4f622479 | ||
![]() |
3ce43764be | ||
![]() |
b555c60e49 | ||
![]() |
2336d010ef | ||
![]() |
b9af0d89d5 | ||
![]() |
6f2afe0c30 | ||
![]() |
d8c61d459e | ||
![]() |
7ae5ebbeb2 | ||
![]() |
7335b71dfb | ||
![]() |
9583b03074 | ||
![]() |
3c81d5f125 | ||
![]() |
688699a046 | ||
![]() |
090f5a9a45 | ||
![]() |
da58d03ff7 | ||
![]() |
9ea3831c08 | ||
![]() |
a46f55b9de | ||
![]() |
a634f64400 | ||
![]() |
bcd8a3b240 | ||
![]() |
04d5d1895c | ||
![]() |
abd2775a70 | ||
![]() |
73226415fc | ||
![]() |
ab160ef445 | ||
![]() |
268fe09322 | ||
![]() |
7a557e984a | ||
![]() |
f1a55cbe6d | ||
![]() |
1e35d95df8 | ||
![]() |
d8387b418d | ||
![]() |
adea16a294 | ||
![]() |
7f2d5cab2d | ||
![]() |
c6ff612f6e | ||
![]() |
8db353e1d7 | ||
![]() |
e6978117a7 | ||
![]() |
5dcb055077 | ||
![]() |
0b5e1a9b2f | ||
![]() |
2e17a97474 | ||
![]() |
74ddbd8a3b | ||
![]() |
b8039a821b | ||
![]() |
438312f00e | ||
![]() |
381ccaa391 | ||
![]() |
3204494883 | ||
![]() |
e264f699d4 | ||
![]() |
68d4b77d44 | ||
![]() |
e1ac99af1f | ||
![]() |
be0d17e812 | ||
![]() |
4eb35406f4 | ||
![]() |
624745ab20 | ||
![]() |
9354822e09 | ||
![]() |
17d4f9513e | ||
![]() |
f830d77307 | ||
![]() |
a03c76b228 | ||
![]() |
35ad61429d | ||
![]() |
b5b3d9e5c7 | ||
![]() |
6e682c2b01 | ||
![]() |
7e2ea2ece0 | ||
![]() |
01926d66d7 | ||
![]() |
69f7d0a0ce | ||
![]() |
d1c84705ec | ||
![]() |
3274908551 | ||
![]() |
c730934498 | ||
![]() |
471a8b223b | ||
![]() |
47ee9202c3 | ||
![]() |
1bcbe89802 | ||
![]() |
bf57e9bb12 | ||
![]() |
318a7584f3 | ||
![]() |
961ec228d4 | ||
![]() |
a777eb3d81 | ||
![]() |
7f79b52dae | ||
![]() |
db680edc26 | ||
![]() |
e6ce80458f | ||
![]() |
cdcb123aa8 | ||
![]() |
78081a1652 | ||
![]() |
7408976b15 | ||
![]() |
763bb73cc3 | ||
![]() |
1dee2cd55e | ||
![]() |
426ecfd136 | ||
![]() |
4913baed16 | ||
![]() |
675f6a8901 | ||
![]() |
2147284cad | ||
![]() |
7f1870da5f | ||
![]() |
2149a095f7 | ||
![]() |
e8d21adbaa | ||
![]() |
fa28531322 | ||
![]() |
deef85ca9a | ||
![]() |
4f4427ff41 | ||
![]() |
0ed285e84d | ||
![]() |
905ca77c9e | ||
![]() |
61043c7e74 | ||
![]() |
4545c9f22f | ||
![]() |
ad772d7b48 | ||
![]() |
a56ef92729 | ||
![]() |
561d01c450 | ||
![]() |
c6c8a30da1 | ||
![]() |
914dbeb12c | ||
![]() |
56dc90eaab | ||
![]() |
f51c567de3 | ||
![]() |
9b2acca63e | ||
![]() |
afcd9f1b1c | ||
![]() |
755ccbc468 | ||
![]() |
0af7aec211 | ||
![]() |
ee085ad6bd | ||
![]() |
719bec2606 | ||
![]() |
b1db9dbb16 | ||
![]() |
609044aea2 | ||
![]() |
ba481718a4 | ||
![]() |
1be60dde7f | ||
![]() |
e92e811a61 | ||
![]() |
5aa0db8681 | ||
![]() |
d5691211dd | ||
![]() |
a93695a70e | ||
![]() |
ce935a2697 | ||
![]() |
812ce0d93f | ||
![]() |
bbae5b49f9 | ||
![]() |
772a985dc3 | ||
![]() |
8a7514de8a | ||
![]() |
32ad212ac9 | ||
![]() |
8a8d5c784c | ||
![]() |
125830ab4b | ||
![]() |
5b75b423e6 | ||
![]() |
012d7e2878 | ||
![]() |
cd3029f36f | ||
![]() |
6adaac7e18 | ||
![]() |
cde5e35d9b | ||
![]() |
ee17fba72e | ||
![]() |
6296b89319 | ||
![]() |
5450db9151 | ||
![]() |
b4700f026b | ||
![]() |
d771fa7c48 | ||
![]() |
b2c378267b | ||
![]() |
384c8f3560 | ||
![]() |
f44ef427a2 | ||
![]() |
c54a4301ee | ||
![]() |
36a3514225 | ||
![]() |
e1edd41e1b | ||
![]() |
13e60c55a1 | ||
![]() |
9b8b1a68f0 | ||
![]() |
4ec9316155 | ||
![]() |
ef769500d4 | ||
![]() |
23692574a2 | ||
![]() |
5f6fd682a5 | ||
![]() |
db24518a30 | ||
![]() |
90933ac660 | ||
![]() |
087579a6f4 | ||
![]() |
de59cde155 | ||
![]() |
3cd95eacdf | ||
![]() |
deb81b2ad4 | ||
![]() |
4e717cdb30 | ||
![]() |
33acd6f041 | ||
![]() |
7575e6afc4 | ||
![]() |
316a9f6480 | ||
![]() |
c6de584cad | ||
![]() |
d997ff6aa8 | ||
![]() |
b9ccecf86e | ||
![]() |
bd5d21aaf2 | ||
![]() |
19e07771d1 | ||
![]() |
ef267ab449 | ||
![]() |
4f6ed683e8 | ||
![]() |
c818e7064f | ||
![]() |
ead6ab2ef7 | ||
![]() |
5c3dc49f44 | ||
![]() |
83884180ac | ||
![]() |
4cac96c33a | ||
![]() |
5df4be1165 | ||
![]() |
96445f1b7d | ||
![]() |
4bdd7596d3 | ||
![]() |
18aae32015 | ||
![]() |
a8996b9e52 | ||
![]() |
94095c61d8 | ||
![]() |
1cddd744ad | ||
![]() |
786738dd00 | ||
![]() |
5b8d5fdf2f | ||
![]() |
694f31ca37 | ||
![]() |
9c1ad0f9f7 | ||
![]() |
71c6335293 | ||
![]() |
8c38ea4ebc | ||
![]() |
44d84ac164 | ||
![]() |
930f9bd534 | ||
![]() |
b61fbbde46 | ||
![]() |
ec956b0334 | ||
![]() |
44ffe0dc79 | ||
![]() |
e3a61fba52 | ||
![]() |
65794f60ec | ||
![]() |
7a710b4970 | ||
![]() |
0bb20cc611 | ||
![]() |
433c0c895e | ||
![]() |
67e8d22958 | ||
![]() |
10d1fc0e73 | ||
![]() |
2260c8aa11 | ||
![]() |
97eb62aff8 | ||
![]() |
1855fc35f2 | ||
![]() |
dc3ed35313 | ||
![]() |
6b868df554 | ||
![]() |
5ccbbe40c2 | ||
![]() |
86f93a53d6 | ||
![]() |
f53347631e | ||
![]() |
efe3cb6e1a | ||
![]() |
32ac4edeed | ||
![]() |
4c04c09138 | ||
![]() |
47ea80baee | ||
![]() |
95c3fa836b | ||
![]() |
ab60a12465 | ||
![]() |
2d38e51867 | ||
![]() |
a5dda669e3 | ||
![]() |
3c4f3a680a | ||
![]() |
b61c06384a | ||
![]() |
e7742bfb7c | ||
![]() |
22307ae0ee | ||
![]() |
e150150d9f | ||
![]() |
943f0733bb | ||
![]() |
8274447dd9 | ||
![]() |
083a84e5d0 | ||
![]() |
d5eb386d00 | ||
![]() |
1ce7b48057 | ||
![]() |
cbcdd337aa | ||
![]() |
c144adf77c | ||
![]() |
d390039873 | ||
![]() |
7d0c58a285 | ||
![]() |
9263001b21 | ||
![]() |
66ee6d07f8 | ||
![]() |
a40dcca794 | ||
![]() |
15e3dfe1d3 | ||
![]() |
a1de9367ec | ||
![]() |
eceb37bde2 | ||
![]() |
56fcf85ab6 | ||
![]() |
77db81d661 | ||
![]() |
2ad7fcbc2f | ||
![]() |
2c62dfd124 | ||
![]() |
ef66497a0d | ||
![]() |
1128029599 | ||
![]() |
befc30bc55 | ||
![]() |
ca5846cde9 | ||
![]() |
8547ab1663 | ||
![]() |
9c0e6ac365 | ||
![]() |
552b963e6d | ||
![]() |
e2b48366d3 | ||
![]() |
5e0d9aea32 | ||
![]() |
ae13c93b7d | ||
![]() |
b9f8a4a477 | ||
![]() |
68e9f75708 | ||
![]() |
d569693f24 | ||
![]() |
15d8bb2105 | ||
![]() |
b2ca777a08 | ||
![]() |
ba01198e6c | ||
![]() |
6ebd5e1761 | ||
![]() |
2723eda1e4 | ||
![]() |
1fa3a5cce9 | ||
![]() |
fe8aee6b08 | ||
![]() |
0639e2a6e2 | ||
![]() |
f1d707705e | ||
![]() |
296a7db960 | ||
![]() |
4c0936e72f | ||
![]() |
0992e391ba | ||
![]() |
b22aaeef6a | ||
![]() |
8090ee0e5d | ||
![]() |
f7d31bb3e3 | ||
![]() |
9cd928674f | ||
![]() |
3ea8a4d220 | ||
![]() |
b0d3ba76a0 | ||
![]() |
ab798fe5ba | ||
![]() |
e7d90e08b9 | ||
![]() |
c2404f77e9 | ||
![]() |
ec4a16f2e0 | ||
![]() |
ca5de26f50 | ||
![]() |
71920d61e6 | ||
![]() |
5de75eee56 | ||
![]() |
2d5fc39d35 | ||
![]() |
c001ed53fa | ||
![]() |
39e01e9349 | ||
![]() |
9e54d4c7d2 | ||
![]() |
56bf97ffc9 | ||
![]() |
7d3e719a2c | ||
![]() |
e55d4fd5c1 | ||
![]() |
5ee231415f | ||
![]() |
c866771cd2 | ||
![]() |
4a24219a1a | ||
![]() |
733a184ce0 | ||
![]() |
eee09e79e8 | ||
![]() |
6df85adf3e | ||
![]() |
3ee6036551 | ||
![]() |
fb65080548 | ||
![]() |
3a5f21b0d1 | ||
![]() |
13a5598dc3 | ||
![]() |
5a6c89661a | ||
![]() |
7c5745720a | ||
![]() |
00ae13f966 | ||
![]() |
29dc39fce1 | ||
![]() |
5c184cfc0d | ||
![]() |
055022a55f | ||
![]() |
c30e908034 | ||
![]() |
8d24c0212e | ||
![]() |
8240cea628 | ||
![]() |
f2a33eb372 | ||
![]() |
e134a40208 | ||
![]() |
690888cfc1 | ||
![]() |
fb8d9b6645 | ||
![]() |
f7ddb39ee1 | ||
![]() |
145084b699 | ||
![]() |
f1ba12607a | ||
![]() |
bb87b65f08 | ||
![]() |
b0f6e7cee4 | ||
![]() |
ed72d4e104 | ||
![]() |
8ec1bfe897 | ||
![]() |
1dec17562f | ||
![]() |
9cc3795f1a | ||
![]() |
be1306a6c2 | ||
![]() |
e9160a31e0 | ||
![]() |
0a670c578f | ||
![]() |
e3c15fc4b9 | ||
![]() |
dc7c915553 | ||
![]() |
b7eeb6e67f |
493
CHANGES
493
CHANGES
@@ -6,7 +6,500 @@
|
||||
|
||||
Changelog
|
||||
|
||||
Version 7.16.1 (29 January 2007)
|
||||
|
||||
Daniel (29 January 2007)
|
||||
- Michael Wallner reported that when doing a CONNECT with a custom User-Agent
|
||||
header, you got _two_ User-Agent headers in the CONNECT request...! Added
|
||||
test case 287 to verify the fix.
|
||||
|
||||
Daniel (28 January 2007)
|
||||
- curl_easy_reset() now resets the CA bundle path correctly.
|
||||
|
||||
- David McCreedy fixed the Curl command line tool for HTTP on non-ASCII
|
||||
platforms.
|
||||
|
||||
Daniel (25 January 2007)
|
||||
- Added the --libcurl [file] option to curl. Append this option to any
|
||||
ordinary curl command line, and you will get a libcurl-using source code
|
||||
written to the file that does the equivalent operation of what your command
|
||||
line operation does!
|
||||
|
||||
Dan F (24 January 2007)
|
||||
- Fixed a dangling pointer problem that prevented the http_proxy environment
|
||||
variable from being properly used in many cases (and caused test case 63
|
||||
to fail).
|
||||
|
||||
Daniel (23 January 2007)
|
||||
- David McCreedy did NTLM changes mainly for non-ASCII platforms:
|
||||
|
||||
#1
|
||||
There's a compilation error in http_ntlm.c if USE_NTLM2SESSION is NOT
|
||||
defined. I noticed this while testing various configurations. Line 867 of
|
||||
the current http_ntlm.c is a closing bracket for an if/else pair that only
|
||||
gets compiled in if USE_NTLM2SESSION is defined. But this closing bracket
|
||||
wasn't in an #ifdef so the code fails to compile unless USE_NTLM2SESSION was
|
||||
defined. Lines 198 and 140 of my patch wraps that closing bracket in an
|
||||
#ifdef USE_NTLM2SESSION.
|
||||
|
||||
#2
|
||||
I noticed several picky compiler warnings when DEBUG_ME is defined. I've
|
||||
fixed them with casting. By the way, DEBUG_ME was a huge help in
|
||||
understanding this code.
|
||||
|
||||
#3
|
||||
Hopefully the last non-ASCII conversion patch for libcurl in a while. I
|
||||
changed the "NTLMSSP" literal to hex since this signature must always be in
|
||||
ASCII.
|
||||
|
||||
Conversion code was strategically added where necessary. And the
|
||||
Curl_base64_encode calls were changed so the binary "blobs" http_ntlm.c
|
||||
creates are NOT translated on non-ASCII platforms.
|
||||
|
||||
Dan F (22 January 2007)
|
||||
- Converted (most of) the test data files into genuine XML. A handful still
|
||||
are not, due mainly to the lack of support for XML character entities
|
||||
(e.g. & => & ). This will make it easier to validate test files using
|
||||
tools like xmllint, as well as to edit and view them using XML tools.
|
||||
|
||||
Daniel (16 January 2007)
|
||||
- Armel Asselin improved libcurl to behave a lot better when an easy handle
|
||||
doing an FTP transfer is removed from a multi handle before completion. The
|
||||
fix also fixed the "alive counter" to be correct on "premature removal" for
|
||||
all protocols.
|
||||
|
||||
Dan F (16 January 2007)
|
||||
- Fixed a small memory leak in tftp uploads discovered by curl's memory leak
|
||||
detector. Also changed tftp downloads to URL-unescape the downloaded
|
||||
file name.
|
||||
|
||||
Daniel (14 January 2007)
|
||||
- David McCreedy provided libcurl changes for doing HTTP communication on
|
||||
non-ASCII platforms. It does add some complexity, most notably with more
|
||||
#ifdefs, but I want to see this supported added and I can't see how we can
|
||||
add it without the extra stuff added.
|
||||
|
||||
- Setting CURLOPT_COOKIELIST to "ALL" when no cookies at all was present,
|
||||
libcurl would crash when trying to read a NULL pointer.
|
||||
|
||||
Daniel (12 January 2007)
|
||||
- Toby Peterson found a nasty bug that prevented (lib)curl from properly
|
||||
downloading (most) things that were larger than 4GB on 32 bit systems. Matt
|
||||
Witherspoon helped as narrow down the problem.
|
||||
|
||||
Daniel (5 January 2007)
|
||||
- Linus Nielsen Feltzing introduced the --ftp-ssl-ccc command line option to
|
||||
curl that uses the new CURLOPT_FTP_SSL_CCC option in libcurl. If enabled, it
|
||||
will make libcurl shutdown SSL/TLS after the authentication is done on a
|
||||
FTP-SSL operation.
|
||||
|
||||
Daniel (4 January 2007)
|
||||
- David McCreedy made changes to allow base64 encoding/decoding to work on
|
||||
non-ASCII platforms.
|
||||
|
||||
Daniel (3 January 2007)
|
||||
- Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
|
||||
downloaded data in two buffers, just to be able to deal with a special HTTP
|
||||
pipelining case. That is now only activated for pipelined transfers. In
|
||||
Matt's case, it showed as a considerable performance difference,
|
||||
|
||||
Daniel (2 January 2007)
|
||||
- Victor Snezhko helped us fix bug report #1603712
|
||||
(http://curl.haxx.se/bug/view.cgi?id=1603712) (known bug #36) --limit-rate
|
||||
(CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE) are broken
|
||||
on Windows (since 7.16.0, but that's when they were introduced as previous
|
||||
to that the limiting logic was made in the application only and not in the
|
||||
library). It was actually also broken on select()-based systems (as apposed
|
||||
to poll()) but we haven't had any such reports. We now use select(), Sleep()
|
||||
or delay() properly to sleep a while without waiting for anything input or
|
||||
output when the rate limiting is activated with the easy interface.
|
||||
|
||||
- Modified libcurl.pc.in to use Libs.private for the libs libcurl itself needs
|
||||
to get built static. It has been mentioned before and was again brought to
|
||||
our attention by Nathanael Nerode who filed debian bug report #405226
|
||||
(http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=405226).
|
||||
|
||||
Daniel (29 December 2006)
|
||||
- Make curl_easy_duphandle() set the magic number in the new handle.
|
||||
|
||||
Daniel (22 December 2006)
|
||||
- Robert Foreman provided a prime example snippet showing how libcurl would
|
||||
get confused and not acknowledge the 'no_proxy' variable properly once it
|
||||
had used the proxy and you re-used the same easy handle. I made sure the
|
||||
proxy name is properly stored in the connect struct rather than the
|
||||
sessionhandle/easy struct.
|
||||
|
||||
- David McCreedy fixed a bad call to getsockname() that wrongly used a size_t
|
||||
variable to point to when it should be a socklen_t.
|
||||
|
||||
- When setting a proxy with environment variables and (for example) running
|
||||
'curl [URL]' with a URL without a protocol prefix, curl would not send a
|
||||
correct request as it failed to add the protocol prefix.
|
||||
|
||||
Daniel (21 December 2006)
|
||||
- Robson Braga Araujo reported bug #1618359
|
||||
(http://curl.haxx.se/bug/view.cgi?id=1618359) and subsequently provided a
|
||||
patch for it: when downloading 2 zero byte files in a row, curl 7.16.0
|
||||
enters an infinite loop, while curl 7.16.1-20061218 does one additional
|
||||
unnecessary request.
|
||||
|
||||
Fix: During the "Major overhaul introducing http pipelining support and
|
||||
shared connection cache within the multi handle." change, headerbytecount
|
||||
was moved to live in the Curl_transfer_keeper structure. But that structure
|
||||
is reset in the Transfer method, losing the information that we had about
|
||||
the header size. This patch moves it back to the connectdata struct.
|
||||
|
||||
Daniel (16 December 2006)
|
||||
- Brendan Jurd provided a fix that now prevents libcurl from getting a SIGPIPE
|
||||
during certain conditions when GnuTLS is used.
|
||||
|
||||
Daniel (11 December 2006)
|
||||
- Alexey Simak found out that when doing FTP with the multi interface and
|
||||
something went wrong like it got a bad response code back from the server,
|
||||
libcurl would leak memory. Added test case 538 to verify the fix.
|
||||
|
||||
I also noted that the connection would get cached in that case, which
|
||||
doesn't make sense since it cannot be re-use when the authentication has
|
||||
failed. I fixed that issue too at the same time, and also that the path
|
||||
would be "remembered" in vain for cases where the connection was about to
|
||||
get closed.
|
||||
|
||||
Daniel (6 December 2006)
|
||||
- Sebastien Willemijns reported bug #1603712
|
||||
(http://curl.haxx.se/bug/view.cgi?id=1603712) which is about connections
|
||||
getting cut off prematurely when --limit-rate is used. While I found no such
|
||||
problems in my tests nor in my reading of the code, I found that the
|
||||
--limit-rate code was severly flawed (since it was moved into the lib, since
|
||||
7.15.5) when used with the easy interface and it didn't work as documented
|
||||
so I reworked it somewhat and now it works for my tests.
|
||||
|
||||
Daniel (5 December 2006)
|
||||
- Stefan Krause pointed out a compiler warning with a picky MSCV compiler when
|
||||
passing a curl_off_t argument to the Curl_read_rewind() function which takes
|
||||
an size_t argument. Curl_read_rewind() also had debug code left in it and it
|
||||
was put in a different source file with no good reason when only used from
|
||||
one single spot.
|
||||
|
||||
- Sh Diao reported that CURLOPT_CLOSEPOLICY doesn't work, and indeed, there is
|
||||
no code present in the library that receives the option. Since it was not
|
||||
possible to use, we know that no current users exist and thus we simply
|
||||
removed it from the docs and made the code always use the default path of
|
||||
the code.
|
||||
|
||||
- Jared Lundell filed bug report #1604956
|
||||
(http://curl.haxx.se/bug/view.cgi?id=1604956) which identified setting
|
||||
CURLOPT_MAXCONNECTS to zero caused libcurl to SIGSEGV. Starting now, libcurl
|
||||
will always internally use no less than 1 entry in the connection cache.
|
||||
|
||||
- Sh Diao reported that CURLOPT_FORBID_REUSE no works, and indeed it broke in
|
||||
the 7.16.0 release.
|
||||
|
||||
- Martin Skinner brought back bug report #1230118 to haunt us once again.
|
||||
(http://curl.haxx.se/bug/view.cgi?id=1230118) curl_getdate() did not work
|
||||
properly for all input dates on Windows. It was mostly seen on some TZ time
|
||||
zones using DST. Luckily, Martin also provided a fix.
|
||||
|
||||
- Alexey Simak filed bug report #1600447
|
||||
(http://curl.haxx.se/bug/view.cgi?id=1600447) in which he noted that active
|
||||
FTP connections don't work with the multi interface. The problem is here
|
||||
that the multi interface state machine has a state during which it can wait
|
||||
for the data connection to connect, but the active connection is not done in
|
||||
the same step in the sequence as the passive one is so it doesn't quite work
|
||||
for active. The active FTP code still use a blocking function to allow the
|
||||
remote server to connect.
|
||||
|
||||
The fix (work-around is a better word) for this problem is to set the
|
||||
boolean prematurely that the data connection is completed, so that the "wait
|
||||
for connect" phase ends at once.
|
||||
|
||||
The proper fix, left for the future, is of course to make the active FTP
|
||||
case to act in a non-blocking way too.
|
||||
|
||||
- Matt Witherspoon fixed a problem case when the CPU load went to 100% when a
|
||||
HTTP upload was disconnected:
|
||||
|
||||
"What appears to be happening is that my system (Linux 2.6.17 and 2.6.13) is
|
||||
setting *only* POLLHUP on poll() when the conditions in my previous mail
|
||||
occur. As you can see, select.c:Curl_select() does not check for POLLHUP. So
|
||||
basically what was happening, is poll() was returning immediately (with
|
||||
POLLHUP set), but when Curl_select() looked at the bits, neither POLLERR or
|
||||
POLLOUT was set. This still caused Curl_readwrite() to be called, which
|
||||
quickly returned. Then the transfer() loop kept continuing at full speed
|
||||
forever."
|
||||
|
||||
Daniel (1 December 2006)
|
||||
- Toon Verwaest reported that there are servers that send the Content-Range:
|
||||
header in a third, not suppported by libcurl, format and we agreed that we
|
||||
could make the parser more forgiving to accept all the three found
|
||||
variations.
|
||||
|
||||
Daniel (25 November 2006)
|
||||
- Venkat Akella found out that libcurl did not like HTTP responses that simply
|
||||
responded with a single status line and no headers nor body. Starting now, a
|
||||
HTTP response on a persistent connection (i.e not set to be closed after the
|
||||
response has been taken care of) must have Content-Length or chunked
|
||||
encoding set, or libcurl will simply assume that there is no body.
|
||||
|
||||
To my horror I learned that we had no less than 57(!) test cases that did bad
|
||||
HTTP responses like this, and even the test http server (sws) responded badly
|
||||
when queried by the test system if it is the test system. So although the
|
||||
actual fix for the problem was tiny, going through all the newly failing test
|
||||
cases got really painful and boring.
|
||||
|
||||
Daniel (24 November 2006)
|
||||
- James Housley did lots of work and introduced SFTP downloads.
|
||||
|
||||
Daniel (13 November 2006)
|
||||
- Ron in bug #1595348 (http://curl.haxx.se/bug/view.cgi?id=1595348) pointed
|
||||
out a stack overwrite (and the corresponding fix) on 64bit Windows when
|
||||
dealing with HTTP chunked encoding.
|
||||
|
||||
Daniel (9 November 2006)
|
||||
- Nir Soffer updated libcurl.framework.make:
|
||||
o fix symlinks, should link to Versions, not to ./Versions
|
||||
o indentation improvments
|
||||
|
||||
- Dmitriy Sergeyev found a SIGSEGV with his test04.c example posted on 7 Nov
|
||||
2006. It turned out we wrongly assumed that the connection cache was present
|
||||
when tearing down a connection.
|
||||
|
||||
- Ciprian Badescu found a SIGSEGV when doing multiple TFTP transfers using the
|
||||
multi interface, but I could also repeat it doing multiple sequential ones
|
||||
with the easy interface. Using Ciprian's test case, I could fix it.
|
||||
|
||||
Daniel (8 November 2006)
|
||||
- Bradford Bruce reported that when setting CURLOPT_DEBUGFUNCTION without
|
||||
CURLOPT_VERBOSE set to non-zero, you still got a few debug messages from the
|
||||
SSL handshake. This is now stopped.
|
||||
|
||||
Daniel (7 November 2006)
|
||||
- Olaf fixed a leftover problem with the CONNECT fix of his that would leave a
|
||||
wrong error message in the error message buffer.
|
||||
|
||||
Daniel (3 November 2006)
|
||||
- Olaf Stueben provided a patch that I edited slightly. It fixes the notorious
|
||||
KNOWN_BUGS #25, which happens when a proxy closes the connection when
|
||||
libcurl has sent CONNECT, as part of an authentication negotiation. Starting
|
||||
now, libcurl will re-connect accordingly and continue the authentication as
|
||||
it should.
|
||||
|
||||
Daniel (2 November 2006)
|
||||
- James Housley brought support for SCP transfers, based on the libssh2 library
|
||||
for the actual network protocol stuff.
|
||||
|
||||
Added these new curl_easy_setopt() options:
|
||||
|
||||
CURLOPT_SSH_AUTH_TYPES
|
||||
CURLOPT_SSH_PUBLIC_KEYFILE
|
||||
CURLOPT_SSH_PRIVATE_KEYFILE
|
||||
|
||||
Version 7.16.0 (30 October 2006)
|
||||
|
||||
Daniel (25 October 2006)
|
||||
- Fixed CURLOPT_FAILONERROR to return CURLE_HTTP_RETURNED_ERROR even for the
|
||||
case when 401 or 407 are returned, *IF* no auth credentials have been given.
|
||||
The CURLOPT_FAILONERROR option is not possible to make fool-proof for 401
|
||||
and 407 cases when auth credentials is given, but we've now covered this
|
||||
somewhat more.
|
||||
|
||||
You might get some amounts of headers transferred before this situation is
|
||||
detected, like for when a "100-continue" is received as a response to a
|
||||
POST/PUT and a 401 or 407 is received immediately afterwards.
|
||||
|
||||
Added test 281 to verify this change.
|
||||
|
||||
Daniel (23 October 2006)
|
||||
- Ravi Pratap provided a major update with pipelining fixes. We also no longer
|
||||
re-use connections (for pipelining) before the name resolving is done.
|
||||
|
||||
Daniel (21 October 2006)
|
||||
- Nir Soffer made the tests/libtest/Makefile.am use a proper variable for all
|
||||
the single test applications' link and dependences, so that you easier can
|
||||
override those from the command line when using make.
|
||||
|
||||
- Armel Asselin separated CA cert verification problems from problems with
|
||||
reading the (local) CA cert file to let users easier pinpoint the actual
|
||||
problem. CURLE_SSL_CACERT_BADFILE (77) is the new libcurl error code.
|
||||
|
||||
Daniel (18 October 2006)
|
||||
- Removed the "protocol-guessing" for URLs with host names starting with FTPS
|
||||
or TELNET since they are practically non-existant. This leaves us with only
|
||||
three different prefixes that would assume the protocol is anything but
|
||||
HTTP, and they are host names starting with "ftp.", "dict." or "ldap.".
|
||||
|
||||
Daniel (17 October 2006)
|
||||
- Bug report #1579171 pointed out code flaws detected with "prefast", and they
|
||||
were 1 - a too small memory clear with memset() in the threaded resolver and
|
||||
2 - a range of potentially bad uses of the ctype family of is*() functions
|
||||
such as isdigit(), isalnum(), isprint() and more. The latter made me switch
|
||||
to using our own set of these functions/macros using uppercase letters, and
|
||||
with some extra set of crazy typecasts to avoid mistakingly passing in
|
||||
negative numbers to the underlying is*() functions.
|
||||
|
||||
- With Jeff Pohlmeyer's help, I fixed the expire timer when using
|
||||
curl_multi_socket() during name resolves with c-ares and the LOW_SPEED
|
||||
options now work fine with curl_multi_socket() as well.
|
||||
|
||||
Daniel (16 October 2006)
|
||||
- Added a check in configure that simply tries to run a program (not when
|
||||
cross-compiling) in order to detect problems with run-time libraries that
|
||||
otherwise would occur when the sizeof tests for curl_off_t would run and
|
||||
thus be much more confusing to users. The check of course should run after
|
||||
all lib-checks are done and before any other test is used that would run an
|
||||
executable built for testing-purposes.
|
||||
|
||||
Dan F (13 October 2006)
|
||||
- The tagging of application/x-www-form-urlencoded POST body data sent
|
||||
to the CURLOPT_DEBUGFUNCTION callback has been fixed (it was erroneously
|
||||
included as part of the header). A message was also added to the
|
||||
command line tool to show when data is being sent, enabled when
|
||||
--verbose is used.
|
||||
|
||||
Daniel (12 October 2006)
|
||||
- Starting now, adding an easy handle to a multi stack that was already added
|
||||
to a multi stack will cause CURLM_BAD_EASY_HANDLE to get returned.
|
||||
|
||||
- Jeff Pohlmeyer has been working with the hiperfifo.c example source code,
|
||||
and while doing so it became apparent that the current timeout system for
|
||||
the socket API really was a bit awkward since it become quite some work to
|
||||
be sure we have the correct timeout set.
|
||||
|
||||
Jeff then provided the new CURLMOPT_TIMERFUNCTION that is yet another
|
||||
callback the app can set to get to know when the general timeout time
|
||||
changes and thus for an application like hiperfifo.c it makes everything a
|
||||
lot easier and nicer. There's a CURLMOPT_TIMERDATA option too of course in
|
||||
good old libcurl tradition.
|
||||
|
||||
Jeff has also updated the hiperfifo.c example code to use this news.
|
||||
|
||||
Daniel (9 October 2006)
|
||||
- Bogdan Nicula's second test case (posted Sun, 08 Oct 2006) converted to test
|
||||
case 535 and it now runs fine. Again a problem with the pipelining code not
|
||||
taking all possible (error) conditions into account.
|
||||
|
||||
Daniel (6 October 2006)
|
||||
- Bogdan Nicula's hanging test case (posted Wed, 04 Oct 2006) was converted to
|
||||
test case 533 and the test now runs fine.
|
||||
|
||||
Daniel (4 October 2006)
|
||||
- Dmitriy Sergeyev provided an example source code that crashed CVS libcurl
|
||||
but that worked nicely in 7.15.5. I converted it into test case 532 and
|
||||
fixed the problem.
|
||||
|
||||
Daniel (29 September 2006)
|
||||
- Removed a few other no-longer present options from the header file.
|
||||
|
||||
- Support for FTP third party transfers was removed. Here's why:
|
||||
|
||||
o The recent multi interface changes broke it and the design of the 3rd party
|
||||
transfers made it very hard to fix the problems
|
||||
o It was still blocking and thus nasty for the multi interface
|
||||
o It was a lot of extra code for a very rarely used feature
|
||||
o It didn't use the same code as for "plain" FTP transfers, so it didn't work
|
||||
fine for IPv6 and it didn't properly re-use connections and more
|
||||
o There's nobody around who's willing to work on and improve the existing
|
||||
code
|
||||
|
||||
This does not mean that third party transfers are banned forever, only that
|
||||
they need to be done better if they are to be re-added in the future.
|
||||
|
||||
The CURLOPT_SOURCE_* options are removed from the lib and so are the --3p*
|
||||
options from the command line tool. For this reason, I also bumped the
|
||||
version info for the lib.
|
||||
|
||||
Daniel (28 September 2006)
|
||||
- Reported in #1561470 (http://curl.haxx.se/bug/view.cgi?id=1561470), libcurl
|
||||
would crash if a bad function sequence was used when shutting down after
|
||||
using the multi interface (i.e using easy_cleanup after multi_cleanup) so
|
||||
precautions have been added to make sure it doesn't any more - test case 529
|
||||
was added to verify.
|
||||
|
||||
Daniel (27 September 2006)
|
||||
- The URL in the cookie jar file is now changed since it was giving a 404.
|
||||
Reported by Timothy Stone. The new URL will take the visitor to a curl web
|
||||
site mirror with the document.
|
||||
|
||||
Daniel (24 September 2006)
|
||||
- Bernard Leak fixed configure --with-gssapi-libs.
|
||||
|
||||
- Cory Nelson made libcurl use the WSAPoll() function if built for Windows
|
||||
Vista (_WIN32_WINNT >= 0x0600)
|
||||
|
||||
Daniel (23 September 2006)
|
||||
- Mike Protts added --ftp-ssl-control to make curl use FTP-SSL, but only
|
||||
encrypt the control connection and use the data connection "plain".
|
||||
|
||||
- Dmitriy Sergeyev provided a patch that made the SOCKS[45] code work better
|
||||
as it now will read the full data sent from servers. The SOCKS-related code
|
||||
was also moved to the new lib/socks.c source file.
|
||||
|
||||
Daniel (21 September 2006)
|
||||
- Added test case 531 in an attempt to repeat bug report #1561470
|
||||
(http://curl.haxx.se/bug/view.cgi?id=1561470) that is said to crash when an
|
||||
FTP upload fails with the multi interface. It did not, but I made a failed
|
||||
upload still assume the control connection to be fine.
|
||||
|
||||
Daniel (20 September 2006)
|
||||
- Armel Asselin fixed problems when you gave a proxy URL with user name and
|
||||
empty password or no password at all. Test case 278 and 279 were added to
|
||||
verify.
|
||||
|
||||
Daniel (12 September 2006)
|
||||
- Added docs/examples/10-at-a-time.c by Michael Wallner
|
||||
|
||||
- Added docs/examples/hiperfifo.c by Jeff Pohlmeyer
|
||||
|
||||
Daniel (11 September 2006)
|
||||
- Fixed my breakage from earlier today so that doing curl_easy_cleanup() on a
|
||||
handle that is part of a multi handle first removes the handle from the
|
||||
stack.
|
||||
|
||||
- Added CURLOPT_SSL_SESSIONID_CACHE and --no-sessionid to disable SSL
|
||||
session-ID re-use on demand since there obviously are broken servers out
|
||||
there that misbehave with session-IDs used.
|
||||
|
||||
- Jeff Pohlmeyer presented a *multi_socket()-using program that exposed a
|
||||
problem with it (SIGSEGV-style). It clearly showed that the existing
|
||||
socket-state and state-difference function wasn't good enough so I rewrote
|
||||
it and could then re-run Jeff's program without any crash. The previous
|
||||
version clearly could miss to tell the application when a handle changed
|
||||
from using one socket to using another.
|
||||
|
||||
While I was at it (as I could use this as a means to track this problem
|
||||
down), I've now added a 'magic' number to the easy handle struct that is
|
||||
inited at curl_easy_init() time and cleared at curl_easy_cleanup() time that
|
||||
we can use internally to detect that an easy handle seems to be fine, or at
|
||||
least not closed or freed (freeing in debug builds fill the area with 0x13
|
||||
bytes but in normal builds we can of course not assume any particular data
|
||||
in the freed areas).
|
||||
|
||||
Daniel (9 September 2006)
|
||||
- Michele Bini fixed how the hostname is put in NTLM packages. As servers
|
||||
don't expect fully qualified names we need to cut them off at the first dot.
|
||||
|
||||
- Peter Sylvester cleaned up and fixed the getsockname() uses in ftp.c. Some
|
||||
of them can be completetly removed though...
|
||||
|
||||
Daniel (6 September 2006)
|
||||
- Ravi Pratap and I have implemented HTTP Pipelining support. Enable it for a
|
||||
multi handle using CURLMOPT_PIPELINING and all HTTP connections done on that
|
||||
handle will be attempted to get pipelined instead of done in parallell as
|
||||
they are performed otherwise.
|
||||
|
||||
As a side-effect from this work, connections are now shared between all easy
|
||||
handles within a multi handle, so if you use N easy handles for transfers,
|
||||
each of them can pick up and re-use a connection that was previously used by
|
||||
any of the handles, be it the same or one of the others.
|
||||
|
||||
This separation of the tight relationship between connections and easy
|
||||
handles is most noticable when you close easy handles that have been used in
|
||||
a multi handle and check amount of used memory or watch the debug output, as
|
||||
there are times when libcurl will keep the easy handle around for a while
|
||||
longer to be able to close it properly. Like for sending QUIT to close down
|
||||
an FTP connection.
|
||||
|
||||
This is a major change.
|
||||
|
||||
Daniel (4 September 2006)
|
||||
- Dmitry Rechkin (http://curl.haxx.se/bug/view.cgi?id=1551412) provided a
|
||||
patch that while not fixing things very nicely, it does make the SOCKS5
|
||||
|
2
COPYING
2
COPYING
@@ -1,6 +1,6 @@
|
||||
COPYRIGHT AND PERMISSION NOTICE
|
||||
|
||||
Copyright (c) 1996 - 2006, Daniel Stenberg, <daniel@haxx.se>.
|
||||
Copyright (c) 1996 - 2007, Daniel Stenberg, <daniel@haxx.se>.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
@@ -73,6 +73,14 @@ mingw32-ssl:
|
||||
$(MAKE) -C lib -f Makefile.m32 SSL=1 ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.m32 SSL=1 ZLIB=1
|
||||
|
||||
mingw32-ssh2-ssl:
|
||||
$(MAKE) -C lib -f Makefile.m32 SSH2=1 SSL=1 ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.m32 SSH2=1 SSL=1 ZLIB=1
|
||||
|
||||
mingw32-ssh2-ssl-sspi:
|
||||
$(MAKE) -C lib -f Makefile.m32 SSH2=1 SSL=1 SSPI=1 ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.m32 SSH2=1 SSL=1 SSPI=1 ZLIB=1
|
||||
|
||||
mingw32-clean:
|
||||
$(MAKE) -C lib -f Makefile.m32 clean
|
||||
$(MAKE) -C src -f Makefile.m32 clean
|
||||
@@ -212,6 +220,10 @@ netware-ssl-zlib:
|
||||
$(MAKE) -C lib -f Makefile.netware WITH_SSL=1 WITH_ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.netware WITH_SSL=1 WITH_ZLIB=1
|
||||
|
||||
netware-ssh2-ssl-zlib:
|
||||
$(MAKE) -C lib -f Makefile.netware WITH_SSH2=1 WITH_SSL=1 WITH_ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.netware WITH_SSH2=1 WITH_SSL=1 WITH_ZLIB=1
|
||||
|
||||
netware-zlib:
|
||||
$(MAKE) -C lib -f Makefile.netware WITH_ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.netware WITH_ZLIB=1
|
||||
|
@@ -1,48 +1,86 @@
|
||||
Curl and libcurl 7.15.6
|
||||
Curl and libcurl 7.16.1
|
||||
|
||||
Public curl release number: 96
|
||||
Releases counted from the very beginning: 123
|
||||
Available command line options: 114
|
||||
Available curl_easy_setopt() options: 135
|
||||
Public curl release number: 97
|
||||
Releases counted from the very beginning: 124
|
||||
Available command line options: 115
|
||||
Available curl_easy_setopt() options: 137
|
||||
Number of public functions in libcurl: 54
|
||||
Amount of public web site mirrors: 33
|
||||
Number of known libcurl bindings: 32
|
||||
Number of contributors: 515
|
||||
Amount of public web site mirrors: 39
|
||||
Number of known libcurl bindings: 35
|
||||
Number of contributors: 539
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o Added support for other MS-DOS compilers (besides djgpp)
|
||||
o CURLOPT_SOCKOPTFUNCTION and CURLOPT_SOCKOPTDATA were added
|
||||
o (FTP) libcurl avoids sending TYPE if the desired type was already set
|
||||
o (FTP) CURLOPT_PREQUOTE works even when CURLOPT_NOBODY is set true
|
||||
|
||||
o Support for SCP and SFTP were added (powered by libssh2)
|
||||
o CURLOPT_CLOSEPOLICY is now deprecated
|
||||
o --ftp-ssl-ccc and CURLOPT_FTP_SSL_CCC were added
|
||||
o HTTP support for non-ASCII platforms
|
||||
o --libcurl was added
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o SOCKS5 proxy connects can now time-out
|
||||
o SOCKS5 connects that require auth no longer segfaults when auth not given
|
||||
o multi interface using asynch resolves could get stuck in wrong state
|
||||
o the 'running_handles' counter wasn't always updated properly when
|
||||
curl_multi_remove_handle() was used
|
||||
o (FTP) EPRT transfers with IPv6 didn't work properly
|
||||
o (FTP) SINGLECWD mode and using files in the root dir
|
||||
o (HTTP) Expect: header disabling work better
|
||||
o (HTTP) "Expect: 100-continue" disable on second POST on re-used connection
|
||||
o src/config.h.in is fixed
|
||||
o proxy close during CONNECT authentication is now dealt with nicely
|
||||
o the CURLOPT_DEBUGFUNCTION was sometimes called even when CURLOPT_VERBOSE
|
||||
was not enabled
|
||||
o multiple TFTP transfers on the same (easy or multi) handle could cause a
|
||||
crash
|
||||
o SIGSEGV when disconnecting on a transfer on a re-used handle when the
|
||||
host name didn't resolve
|
||||
o stack overwrite on 64bit Windows in the chunked decoding department
|
||||
o HTTP responses on persistent connections without Content-Length nor chunked
|
||||
encoding are now considered to be without response body
|
||||
o Content-Range: header parsing improved
|
||||
o CPU 100% load when HTTP upload connection broke
|
||||
o active FTP didn't work with multi interface
|
||||
o curl_getdate() could be off one hour for TZ time zones with DST, on windows
|
||||
o CURLOPT_FORBID_REUSE works again
|
||||
o CURLOPT_MAXCONNECTS set to zero caused libcurl to SIGSEGV
|
||||
o rate limiting works better
|
||||
o getting FTP response code errors when using the multi-interface caused
|
||||
libcurl to leak memory
|
||||
o no more SIGPIPE when GnuTLS is used
|
||||
o FTP downloading 2 zero byte files in a row
|
||||
o using proxy and URLs without protocol prefixes
|
||||
o first using a proxy and then accessing a site that 'no_proxy' matched,
|
||||
would still make libcurl use the proxy...
|
||||
o curl_easy_duphandle() now makes a handle that is valid for the multi
|
||||
interface since the magic number is set fine
|
||||
o libcurl.pc now uses Libs.private for "private" libs
|
||||
o --limit-rate (CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE)
|
||||
now work on windows again
|
||||
o improved download performance by avoiding the unconditional "double copying"
|
||||
o base64 encoding/decoding works on non-ASCII platforms
|
||||
o large file downloads
|
||||
o CURLOPT_COOKIELIST set to "ALL" crash
|
||||
o easy handle removal from multi handle before completion
|
||||
o TFTP upload memory leak
|
||||
o curl_easy_reset() now resets the CA bundle path correctly
|
||||
o two User-Agent headers in CONNECT requests with custom User-Agent
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
o see docs/KNOWN_BUGS (http://curl.haxx.se/docs/knownbugs.html)
|
||||
|
||||
Other curl-related news:
|
||||
|
||||
o pycurl-7.15.5 was released: http://pycurl.sf.net
|
||||
o TclCurl 7.16.0 was released:
|
||||
http://personal1.iddeo.es/andresgarci/tclcurl/english/
|
||||
o Curb - Libcurl bindings for Ruby: http://curb.rubyforge.org/
|
||||
|
||||
New curl mirrors:
|
||||
|
||||
o http://curl.geosdreams.info/ is a new Polish mirror
|
||||
o http://curl.gfiles.org/ is a new Russian mirror
|
||||
o curl.miroir-francais.fr is a new French web mirror
|
||||
o curl.dsmirror.nl is a new Dutch web mirror
|
||||
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Domenico Andreoli, Armel Asselin, Gisle Vanem, Yang Tse, Andrew Biggs,
|
||||
Peter Sylvester, David McCreedy, Dmitriy Sergeyev, Dmitry Rechkin,
|
||||
Jari Sundell
|
||||
James Housley, Olaf Stueben, Yang Tse, Gisle Vanem, Bradford Bruce,
|
||||
Ciprian Badescu, Dmitriy Sergeyev, Nir Soffer, Venkat Akella, Toon Verwaest,
|
||||
Matt Witherspoon, Alexey Simak, Martin Skinner, Sh Diao, Jared Lundell,
|
||||
Stefan Krause, Sebastien Willemijns, Alexey Simak, Brendan Jurd,
|
||||
Robson Braga Araujo, David McCreedy, Robert Foreman, Nathanael Nerode,
|
||||
Victor Snezhko, Linus Nielsen Feltzing, Toby Peterson, Dan Fandrich,
|
||||
Armel Asselin, Michael Wallner, Guenter Knauf
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
@@ -1,5 +1,4 @@
|
||||
To get fixed in 7.15.5 (planned release: August 2006)
|
||||
To get fixed in 7.16.1 (planned release: January 2007)
|
||||
======================
|
||||
|
||||
66 -
|
||||
|
||||
82 -
|
||||
|
135
acinclude.m4
135
acinclude.m4
@@ -976,6 +976,107 @@ AC_DEFUN([CURL_CHECK_MSG_NOSIGNAL], [
|
||||
]) # AC_DEFUN
|
||||
|
||||
|
||||
dnl CURL_CHECK_STRUCT_TIMEVAL
|
||||
dnl -------------------------------------------------
|
||||
dnl Check for timeval struct
|
||||
|
||||
AC_DEFUN([CURL_CHECK_STRUCT_TIMEVAL], [
|
||||
AC_REQUIRE([AC_HEADER_TIME])dnl
|
||||
AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl
|
||||
AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl
|
||||
AC_CHECK_HEADERS(sys/types.h sys/time.h time.h)
|
||||
AC_CACHE_CHECK([for struct timeval], [ac_cv_struct_timeval], [
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([
|
||||
#undef inline
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
#include <time.h>
|
||||
#endif
|
||||
#else
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
],[
|
||||
struct timeval ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_usec = 0;
|
||||
])
|
||||
],[
|
||||
ac_cv_struct_timeval="yes"
|
||||
],[
|
||||
ac_cv_struct_timeval="no"
|
||||
])
|
||||
])
|
||||
case "$ac_cv_struct_timeval" in
|
||||
yes)
|
||||
AC_DEFINE_UNQUOTED(HAVE_STRUCT_TIMEVAL, 1,
|
||||
[Define to 1 if you have the timeval struct.])
|
||||
;;
|
||||
esac
|
||||
]) # AC_DEFUN
|
||||
|
||||
|
||||
dnl TYPE_SIG_ATOMIC_T
|
||||
dnl -------------------------------------------------
|
||||
dnl Check if the sig_atomic_t type is available, and
|
||||
dnl verify if it is already defined as volatile.
|
||||
|
||||
AC_DEFUN([TYPE_SIG_ATOMIC_T], [
|
||||
AC_CHECK_HEADERS(signal.h)
|
||||
AC_CHECK_TYPE([sig_atomic_t],[
|
||||
AC_DEFINE(HAVE_SIG_ATOMIC_T, 1,
|
||||
[Define to 1 if sig_atomic_t is an available typedef.])
|
||||
], ,[
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
])
|
||||
case "$ac_cv_type_sig_atomic_t" in
|
||||
yes)
|
||||
#
|
||||
AC_MSG_CHECKING([if sig_atomic_t is already defined as volatile])
|
||||
AC_TRY_LINK([
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
],[
|
||||
static volatile sig_atomic_t dummy = 0;
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
ac_cv_sig_atomic_t_volatile="no"
|
||||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
ac_cv_sig_atomic_t_volatile="yes"
|
||||
])
|
||||
#
|
||||
if test "$ac_cv_sig_atomic_t_volatile" = "yes"; then
|
||||
AC_DEFINE(HAVE_SIG_ATOMIC_T_VOLATILE, 1,
|
||||
[Define to 1 if sig_atomic_t is already defined as volatile.])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
]) # AC_DEFUN
|
||||
|
||||
|
||||
dnl CURL_CHECK_NONBLOCKING_SOCKET
|
||||
dnl -------------------------------------------------
|
||||
dnl Check for how to set a socket to non-blocking state. There seems to exist
|
||||
@@ -1814,3 +1915,37 @@ else
|
||||
AC_MSG_WARN([`missing' script is too old or missing])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl CURL_VERIFY_RUNTIMELIBS
|
||||
dnl -------------------------------------------------
|
||||
dnl Verify that the shared libs found so far can be used when running
|
||||
dnl programs, since otherwise the situation will create odd configure errors
|
||||
dnl that are misleading people.
|
||||
dnl
|
||||
dnl Make sure this test is run BEFORE the first test in the script that
|
||||
dnl runs anything, which at the time of this writing is the AC_CHECK_SIZEOF
|
||||
dnl macro. It must also run AFTER all lib-checking macros are complete.
|
||||
|
||||
AC_DEFUN([CURL_VERIFY_RUNTIMELIBS], [
|
||||
|
||||
dnl this test is of course not sensible if we are cross-compiling!
|
||||
if test "x$cross_compiling" != xyes; then
|
||||
|
||||
dnl just run a program to verify that the libs checked for previous to this
|
||||
dnl point also is available run-time!
|
||||
AC_MSG_CHECKING([run-time libs availability])
|
||||
AC_TRY_RUN([
|
||||
main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
],
|
||||
AC_MSG_RESULT([fine]),
|
||||
AC_MSG_RESULT([failed])
|
||||
AC_MSG_ERROR([one or more libs available at link-time are not available run-time. Libs used at link-time: $LIBS])
|
||||
)
|
||||
|
||||
dnl if this test fails, configure has already stopped
|
||||
fi
|
||||
])
|
||||
|
@@ -14,3 +14,9 @@ Henrik Stoerner
|
||||
Yang Tse
|
||||
Nick Mathewson
|
||||
Alexander Lazic
|
||||
Andreas Rieke
|
||||
Guilherme Balena Versiani
|
||||
Brad Spencer
|
||||
Ravi Pratap
|
||||
William Ahern
|
||||
Bram Matthys
|
||||
|
32
ares/CHANGES
32
ares/CHANGES
@@ -1,5 +1,37 @@
|
||||
Changelog for the c-ares project
|
||||
|
||||
* November 22
|
||||
|
||||
- Install ares_dns.h too
|
||||
|
||||
- Michael Wallner fixed this problem: When I set domains in the options
|
||||
struct, and there are domain/search entries in /etc/resolv.conf, the domains
|
||||
of the options struct will be overridden.
|
||||
|
||||
* November 6
|
||||
|
||||
- Yang Tse removed a couple of potential zero size memory allocations.
|
||||
|
||||
- Andreas Rieke fixed the line endings in the areslib.dsp file that I (Daniel)
|
||||
broke in the 1.3.2 release. We should switch to a system where that file is
|
||||
auto-generated. We could rip some code for that from curl...
|
||||
|
||||
Version 1.3.2 (November 3, 2006)
|
||||
|
||||
* October 12 2006
|
||||
|
||||
- Prevent ares_getsock() to overflow if more than 16 sockets are used.
|
||||
|
||||
* September 11 2006
|
||||
|
||||
- Guilherme Balena Versiani: I noted a strange BUG in Win32 port
|
||||
(ares_init.c/get_iphlpapi_dns_info() function): when I disable the network
|
||||
by hand or disconnect the network cable in Windows 2000 or Windows XP, my
|
||||
application gets 127.0.0.1 as the only name server. The problem comes from
|
||||
'GetNetworkParams' function, that returns the empty string "" as the only
|
||||
name server in that case. Moreover, the Windows implementation of
|
||||
inet_addr() returns INADDR_LOOPBACK instead of INADDR_NONE.
|
||||
|
||||
* August 29 2006
|
||||
|
||||
- Brad Spencer did
|
||||
|
@@ -59,7 +59,7 @@ libcares_la_SOURCES = $(CSOURCES) $(HHEADERS)
|
||||
# where to install the c-ares headers
|
||||
libcares_ladir = $(includedir)
|
||||
# what headers to install on 'make install':
|
||||
libcares_la_HEADERS = ares.h ares_version.h
|
||||
libcares_la_HEADERS = ares.h ares_version.h ares_dns.h
|
||||
|
||||
# Make files named *.dist replace the file without .dist extension
|
||||
dist-hook:
|
||||
|
184
ares/Makefile.dj
184
ares/Makefile.dj
@@ -2,32 +2,50 @@
|
||||
# c-ares Makefile for djgpp/gcc/Watt-32.
|
||||
# By Gisle Vanem <giva@bgnett.no> 2004.
|
||||
#
|
||||
.SUFFIXES: .exe
|
||||
# $Id$
|
||||
|
||||
include ../packages/DOS/common.dj
|
||||
|
||||
include Makefile.inc
|
||||
|
||||
WATT32_ROOT = $(subst \,/,$(WATT_ROOT))
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -O2 -Wall -DWATT32 -Dselect=select_s -DHAVE_AF_INET6 \
|
||||
-DHAVE_PF_INET6 -DHAVE_IOCTLSOCKET -DHAVE_STRUCT_IN6_ADDR \
|
||||
-DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \
|
||||
-DHAVE_ARPA_NAMESER_H -DNS_INADDRSZ=4 \
|
||||
-DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID -I$(WATT32_ROOT)/inc
|
||||
CFLAGS += -DWATT32 -DHAVE_AF_INET6 -DHAVE_PF_INET6 -DHAVE_FIONBIO \
|
||||
-DHAVE_STRUCT_IN6_ADDR -DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID \
|
||||
-DHAVE_SYS_TIME_H -DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \
|
||||
-DHAVE_SIGNAL_H -DHAVE_SIG_ATOMIC_T -DRETSIGTYPE='void' \
|
||||
-DHAVE_ARPA_NAMESER_H -DNS_INADDRSZ=4 -DHAVE_RECV -DHAVE_SEND \
|
||||
-DSEND_TYPE_ARG1='int' -DSEND_QUAL_ARG2='const' \
|
||||
-DSEND_TYPE_ARG2='void*' -DSEND_TYPE_ARG3='int' \
|
||||
-DSEND_TYPE_ARG4='int' -DSEND_TYPE_RETV='int' \
|
||||
-DRECV_TYPE_ARG1='int' -DRECV_TYPE_ARG2='void*' \
|
||||
-DRECV_TYPE_ARG3='int' -DRECV_TYPE_ARG4='int' \
|
||||
-DRECV_TYPE_RETV='int' -UHAVE_CONFIG_H -Dselect=select_s
|
||||
|
||||
LDFLAGS = -s
|
||||
EX_LIBS = $(WATT32_ROOT)/lib/libwatt.a
|
||||
|
||||
OBJ_DIR = djgpp
|
||||
ifeq ($(USE_DEBUG),1)
|
||||
EX_LIBS = ../lib/libcurl.a
|
||||
endif
|
||||
|
||||
ifeq ($(USE_SSL),1)
|
||||
EX_LIBS += $(OPENSSL_ROOT)/lib/libssl.a $(OPENSSL_ROOT)/lib/libcrypt.a
|
||||
endif
|
||||
|
||||
ifeq ($(USE_ZLIB),1)
|
||||
EX_LIBS += $(ZLIB_ROOT)/libz.a
|
||||
CFLAGS += -DUSE_MANUAL
|
||||
endif
|
||||
|
||||
ifeq ($(USE_IDNA),1)
|
||||
EX_LIBS += $(LIBIDN_ROOT)/lib/dj_obj/libidn.a -liconv
|
||||
endif
|
||||
|
||||
EX_LIBS += $(WATT32_ROOT)/lib/libwatt.a
|
||||
|
||||
OBJECTS = $(addprefix $(OBJ_DIR)/, $(CSOURCES:.c=.o))
|
||||
|
||||
all: $(OBJ_DIR) libcares.a ahost.exe adig.exe
|
||||
@echo Welcome to c-ares.
|
||||
|
||||
$(OBJ_DIR):
|
||||
- mkdir $(OBJ_DIR)
|
||||
|
||||
libcares.a: $(OBJECTS)
|
||||
ar rs $@ $?
|
||||
|
||||
@@ -44,12 +62,132 @@ vclean realclean: clean
|
||||
rm -f ahost.exe adig.exe depend.dj
|
||||
- rmdir $(OBJ_DIR)
|
||||
|
||||
$(OBJ_DIR)/%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
@echo
|
||||
|
||||
depend:
|
||||
$(CC) -MM $(CFLAGS) $(CSOURCES) | \
|
||||
sed -e 's/^\([a-zA-Z0-9_-]*\.o:\)/$$(OBJ_DIR)\/\1/' > depend.dj
|
||||
|
||||
-include depend.dj
|
||||
# DO NOT DELETE THIS LINE
|
||||
$(OBJ_DIR)/ares_fds.o: ares_fds.c setup.h setup_once.h ares.h ares_private.h \
|
||||
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_getsock.o: ares_getsock.c setup.h setup_once.h ares.h ares_private.h \
|
||||
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_process.o: ares_process.c setup.h setup_once.h ares.h ares_dns.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_free_hostent.o: ares_free_hostent.c setup.h setup_once.h ares.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_query.o: ares_query.c setup.h setup_once.h ares.h ares_dns.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares__close_sockets.o: ares__close_sockets.c setup.h setup_once.h ares.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_free_string.o: ares_free_string.c setup.h setup_once.h ares.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_search.o: ares_search.c setup.h setup_once.h ares.h ares_private.h \
|
||||
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares__get_hostent.o: ares__get_hostent.c setup.h setup_once.h ares.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h inet_net_pton.h
|
||||
$(OBJ_DIR)/ares_gethostbyaddr.o: ares_gethostbyaddr.c setup.h setup_once.h ares.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h inet_net_pton.h
|
||||
$(OBJ_DIR)/ares_send.o: ares_send.c setup.h setup_once.h ares.h ares_dns.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares__read_line.o: ares__read_line.c setup.h setup_once.h ares.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_gethostbyname.o: ares_gethostbyname.c setup.h setup_once.h ares.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h inet_net_pton.h \
|
||||
bitncmp.h
|
||||
$(OBJ_DIR)/ares_strerror.o: ares_strerror.c setup.h setup_once.h ares.h
|
||||
$(OBJ_DIR)/ares_cancel.o: ares_cancel.c setup.h setup_once.h ares.h ares_private.h \
|
||||
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_init.o: ares_init.c setup.h setup_once.h ares.h ares_private.h \
|
||||
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h inet_net_pton.h
|
||||
$(OBJ_DIR)/ares_timeout.o: ares_timeout.c setup.h setup_once.h ares.h ares_private.h \
|
||||
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_destroy.o: ares_destroy.c setup.h setup_once.h ares.h ares_private.h \
|
||||
ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_mkquery.o: ares_mkquery.c setup.h setup_once.h ares.h ares_dns.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_version.o: ares_version.c setup.h setup_once.h ares_version.h
|
||||
$(OBJ_DIR)/ares_expand_name.o: ares_expand_name.c setup.h setup_once.h ares.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_parse_a_reply.o: ares_parse_a_reply.c setup.h setup_once.h ares.h \
|
||||
ares_dns.h ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/windows_port.o: windows_port.c setup.h setup_once.h
|
||||
$(OBJ_DIR)/ares_expand_string.o: ares_expand_string.c setup.h setup_once.h ares.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_parse_ptr_reply.o: ares_parse_ptr_reply.c setup.h setup_once.h \
|
||||
ares.h ares_dns.h ares_private.h ares_ipv6.h ../lib/memdebug.h \
|
||||
../lib/setup.h ../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_parse_aaaa_reply.o: ares_parse_aaaa_reply.c setup.h setup_once.h \
|
||||
ares.h ares_dns.h inet_net_pton.h ares_private.h ares_ipv6.h \
|
||||
../lib/memdebug.h ../lib/setup.h ../include/curl/stdcheaders.h \
|
||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h
|
||||
$(OBJ_DIR)/ares_getnameinfo.o: ares_getnameinfo.c setup.h setup_once.h ares.h \
|
||||
ares_private.h ares_ipv6.h ../lib/memdebug.h ../lib/setup.h \
|
||||
../include/curl/stdcheaders.h ../include/curl/curl.h \
|
||||
../include/curl/curlver.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/curl.h inet_ntop.h
|
||||
$(OBJ_DIR)/inet_net_pton.o: inet_net_pton.c setup.h setup_once.h ares_ipv6.h \
|
||||
inet_net_pton.h
|
||||
$(OBJ_DIR)/bitncmp.o: bitncmp.c bitncmp.h
|
||||
$(OBJ_DIR)/inet_ntop.o: inet_ntop.c setup.h setup_once.h ares_ipv6.h inet_ntop.h
|
||||
|
@@ -20,7 +20,7 @@ endif
|
||||
TARGETS = adig.nlm ahost.nlm
|
||||
LTARGET = libcares.lib
|
||||
VERSION = $(LIBCARES_VERSION)
|
||||
COPYR = Copyright (C) 1996 - 2006, Daniel Stenberg, <daniel@haxx.se>
|
||||
COPYR = Copyright (C) 1996 - 2007, Daniel Stenberg, <daniel@haxx.se>
|
||||
DESCR = cURL $(subst .def,,$(notdir $@)) $(LIBCARES_VERSION_STR) - http://curl.haxx.se
|
||||
MTSAFE = YES
|
||||
STACK = 64000
|
||||
@@ -281,6 +281,8 @@ config.h: Makefile.netware
|
||||
@echo $(DL)#define HAVE_SEND 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIGNAL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIGNAL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIG_ATOMIC_T 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SOCKET 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STDINT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STDLIB_H 1$(DL) >> $@
|
||||
@@ -316,9 +318,10 @@ config.h: Makefile.netware
|
||||
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_TIMEVAL 1$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@
|
||||
ifdef NW_WINSOCK
|
||||
|
@@ -121,8 +121,8 @@ $(DEF_FILE): $(OBJECTS) Makefile.VC6
|
||||
@echo ares_gettimeofday >> $@
|
||||
@echo ares_parse_aaaa_reply >> $@
|
||||
|
||||
ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj cares_imp.lib
|
||||
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\ahost.obj cares_imp.lib $(EX_LIBS)
|
||||
ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\getopt.obj cares_imp.lib
|
||||
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\getopt.obj cares_imp.lib $(EX_LIBS)
|
||||
|
||||
adig.exe: $(OBJ_DIR) $(OBJ_DIR)\adig.obj $(OBJ_DIR)\getopt.obj cares_imp.lib
|
||||
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\adig.obj $(OBJ_DIR)\getopt.obj cares_imp.lib $(EX_LIBS)
|
||||
|
@@ -954,6 +954,107 @@ AC_DEFUN([CURL_CHECK_MSG_NOSIGNAL], [
|
||||
]) # AC_DEFUN
|
||||
|
||||
|
||||
dnl CURL_CHECK_STRUCT_TIMEVAL
|
||||
dnl -------------------------------------------------
|
||||
dnl Check for timeval struct
|
||||
|
||||
AC_DEFUN([CURL_CHECK_STRUCT_TIMEVAL], [
|
||||
AC_REQUIRE([AC_HEADER_TIME])dnl
|
||||
AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl
|
||||
AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl
|
||||
AC_CHECK_HEADERS(sys/types.h sys/time.h time.h)
|
||||
AC_CACHE_CHECK([for struct timeval], [ac_cv_struct_timeval], [
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([
|
||||
#undef inline
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
#include <time.h>
|
||||
#endif
|
||||
#else
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
],[
|
||||
struct timeval ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_usec = 0;
|
||||
])
|
||||
],[
|
||||
ac_cv_struct_timeval="yes"
|
||||
],[
|
||||
ac_cv_struct_timeval="no"
|
||||
])
|
||||
])
|
||||
case "$ac_cv_struct_timeval" in
|
||||
yes)
|
||||
AC_DEFINE_UNQUOTED(HAVE_STRUCT_TIMEVAL, 1,
|
||||
[Define to 1 if you have the timeval struct.])
|
||||
;;
|
||||
esac
|
||||
]) # AC_DEFUN
|
||||
|
||||
|
||||
dnl TYPE_SIG_ATOMIC_T
|
||||
dnl -------------------------------------------------
|
||||
dnl Check if the sig_atomic_t type is available, and
|
||||
dnl verify if it is already defined as volatile.
|
||||
|
||||
AC_DEFUN([TYPE_SIG_ATOMIC_T], [
|
||||
AC_CHECK_HEADERS(signal.h)
|
||||
AC_CHECK_TYPE([sig_atomic_t],[
|
||||
AC_DEFINE(HAVE_SIG_ATOMIC_T, 1,
|
||||
[Define to 1 if sig_atomic_t is an available typedef.])
|
||||
], ,[
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
])
|
||||
case "$ac_cv_type_sig_atomic_t" in
|
||||
yes)
|
||||
#
|
||||
AC_MSG_CHECKING([if sig_atomic_t is already defined as volatile])
|
||||
AC_TRY_LINK([
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
],[
|
||||
static volatile sig_atomic_t dummy = 0;
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
ac_cv_sig_atomic_t_volatile="no"
|
||||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
ac_cv_sig_atomic_t_volatile="yes"
|
||||
])
|
||||
#
|
||||
if test "$ac_cv_sig_atomic_t_volatile" = "yes"; then
|
||||
AC_DEFINE(HAVE_SIG_ATOMIC_T_VOLATILE, 1,
|
||||
[Define to 1 if sig_atomic_t is already defined as volatile.])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
]) # AC_DEFUN
|
||||
|
||||
|
||||
dnl CURL_CHECK_NONBLOCKING_SOCKET
|
||||
dnl -------------------------------------------------
|
||||
dnl Check for how to set a socket to non-blocking state. There seems to exist
|
||||
|
20
ares/adig.c
20
ares/adig.c
@@ -1,4 +1,6 @@
|
||||
/* Copyright 1998 by the Massachusetts Institute of Technology.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
@@ -16,7 +18,7 @@
|
||||
#include "setup.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#if defined(WIN32) && !defined(WATT32)
|
||||
#include "nameser.h"
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
@@ -153,8 +155,8 @@ int main(int argc, char **argv)
|
||||
fd_set read_fds, write_fds;
|
||||
struct timeval *tvp, tv;
|
||||
|
||||
#ifdef WIN32
|
||||
WORD wVersionRequested = MAKEWORD(1,1);
|
||||
#ifdef USE_WINSOCK
|
||||
WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
|
||||
WSADATA wsaData;
|
||||
WSAStartup(wVersionRequested, &wsaData);
|
||||
#endif
|
||||
@@ -162,10 +164,16 @@ int main(int argc, char **argv)
|
||||
options.flags = ARES_FLAG_NOCHECKRESP;
|
||||
options.servers = NULL;
|
||||
options.nservers = 0;
|
||||
while ((c = getopt(argc, argv, "f:s:c:t:T:U:")) != -1)
|
||||
while ((c = getopt(argc, argv, "df:s:c:t:T:U:")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'd':
|
||||
#ifdef WATT32
|
||||
dbug_init();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
/* Add a flag. */
|
||||
for (i = 0; i < nflags; i++)
|
||||
@@ -225,7 +233,7 @@ int main(int argc, char **argv)
|
||||
|
||||
case 'T':
|
||||
/* Set the TCP port number. */
|
||||
if (!isdigit((unsigned char)*optarg))
|
||||
if (!ISDIGIT(*optarg))
|
||||
usage();
|
||||
options.tcp_port = (unsigned short)strtol(optarg, NULL, 0);
|
||||
optmask |= ARES_OPT_TCP_PORT;
|
||||
@@ -233,7 +241,7 @@ int main(int argc, char **argv)
|
||||
|
||||
case 'U':
|
||||
/* Set the UDP port number. */
|
||||
if (!isdigit((unsigned char)*optarg))
|
||||
if (!ISDIGIT(*optarg))
|
||||
usage();
|
||||
options.udp_port = (unsigned short)strtol(optarg, NULL, 0);
|
||||
optmask |= ARES_OPT_UDP_PORT;
|
||||
|
@@ -18,8 +18,7 @@
|
||||
#include "setup.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#else
|
||||
#if !defined(WIN32) || defined(WATT32)
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
@@ -64,8 +63,8 @@ int main(int argc, char **argv)
|
||||
struct in_addr addr4;
|
||||
struct in6_addr addr6;
|
||||
|
||||
#ifdef WIN32
|
||||
WORD wVersionRequested = MAKEWORD(1,1);
|
||||
#ifdef USE_WINSOCK
|
||||
WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
|
||||
WSADATA wsaData;
|
||||
WSAStartup(wVersionRequested, &wsaData);
|
||||
#endif
|
||||
|
@@ -31,7 +31,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tcp.h>
|
||||
#elif defined(WIN32) && !defined(__CYGWIN__)
|
||||
#elif defined(WIN32)
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
|
@@ -54,7 +54,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
|
||||
|
||||
/* Get the address part. */
|
||||
p = line;
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
while (*p && !ISSPACE(*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
@@ -76,12 +76,12 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
|
||||
|
||||
/* Get the canonical hostname. */
|
||||
p++;
|
||||
while (isspace((unsigned char)*p))
|
||||
while (ISSPACE(*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
q = p;
|
||||
while (*q && !isspace((unsigned char)*q))
|
||||
while (*q && !ISSPACE(*q))
|
||||
q++;
|
||||
end_at_hostname = (*q == 0);
|
||||
*q = 0;
|
||||
@@ -92,13 +92,13 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
|
||||
{
|
||||
/* Count the aliases. */
|
||||
p = q + 1;
|
||||
while (isspace((unsigned char)*p))
|
||||
while (ISSPACE(*p))
|
||||
p++;
|
||||
while (*p)
|
||||
{
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
while (*p && !ISSPACE(*p))
|
||||
p++;
|
||||
while (isspace((unsigned char)*p))
|
||||
while (ISSPACE(*p))
|
||||
p++;
|
||||
naliases++;
|
||||
}
|
||||
@@ -128,12 +128,12 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
|
||||
if (!end_at_hostname)
|
||||
{
|
||||
p = canonical + strlen(canonical) + 1;
|
||||
while (isspace((unsigned char)*p))
|
||||
while (ISSPACE(*p))
|
||||
p++;
|
||||
while (*p)
|
||||
{
|
||||
q = p;
|
||||
while (*q && !isspace((unsigned char)*q))
|
||||
while (*q && !ISSPACE(*q))
|
||||
q++;
|
||||
hostent->h_aliases[naliases] = malloc(q - p + 1);
|
||||
if (hostent->h_aliases[naliases] == NULL)
|
||||
@@ -141,7 +141,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
|
||||
memcpy(hostent->h_aliases[naliases], p, q - p);
|
||||
hostent->h_aliases[naliases][q - p] = 0;
|
||||
p = q;
|
||||
while (isspace((unsigned char)*p))
|
||||
while (ISSPACE(*p))
|
||||
p++;
|
||||
naliases++;
|
||||
}
|
||||
|
@@ -39,7 +39,10 @@ void ares_cancel(ares_channel channel)
|
||||
channel->queries = NULL;
|
||||
if (!(channel->flags & ARES_FLAG_STAYOPEN))
|
||||
{
|
||||
for (i = 0; i < channel->nservers; i++)
|
||||
ares__close_sockets(channel, &channel->servers[i]);
|
||||
if (channel->servers)
|
||||
{
|
||||
for (i = 0; i < channel->nservers; i++)
|
||||
ares__close_sockets(channel, &channel->servers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,23 +25,37 @@ void ares_destroy(ares_channel channel)
|
||||
int i;
|
||||
struct query *query;
|
||||
|
||||
for (i = 0; i < channel->nservers; i++)
|
||||
ares__close_sockets(channel, &channel->servers[i]);
|
||||
free(channel->servers);
|
||||
for (i = 0; i < channel->ndomains; i++)
|
||||
free(channel->domains[i]);
|
||||
free(channel->domains);
|
||||
if (!channel)
|
||||
return;
|
||||
|
||||
if (channel->servers) {
|
||||
for (i = 0; i < channel->nservers; i++)
|
||||
ares__close_sockets(channel, &channel->servers[i]);
|
||||
free(channel->servers);
|
||||
}
|
||||
|
||||
if (channel->domains) {
|
||||
for (i = 0; i < channel->ndomains; i++)
|
||||
free(channel->domains[i]);
|
||||
free(channel->domains);
|
||||
}
|
||||
|
||||
if(channel->sortlist)
|
||||
free(channel->sortlist);
|
||||
free(channel->lookups);
|
||||
while (channel->queries)
|
||||
{
|
||||
query = channel->queries;
|
||||
channel->queries = query->next;
|
||||
query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
|
||||
|
||||
if (channel->lookups)
|
||||
free(channel->lookups);
|
||||
|
||||
while (channel->queries) {
|
||||
query = channel->queries;
|
||||
channel->queries = query->next;
|
||||
query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
|
||||
if (query->tcpbuf)
|
||||
free(query->tcpbuf);
|
||||
if (query->skip_server)
|
||||
free(query->skip_server);
|
||||
free(query);
|
||||
}
|
||||
free(query);
|
||||
}
|
||||
|
||||
free(channel);
|
||||
}
|
||||
|
@@ -81,8 +81,8 @@ static char *ares_striendstr(const char *s1, const char *s2);
|
||||
void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t salen,
|
||||
int flags, ares_nameinfo_callback callback, void *arg)
|
||||
{
|
||||
struct sockaddr_in *addr;
|
||||
struct sockaddr_in6 *addr6;
|
||||
struct sockaddr_in *addr = NULL;
|
||||
struct sockaddr_in6 *addr6 = NULL;
|
||||
struct nameinfo_query *niquery;
|
||||
|
||||
/* Verify the buffer size */
|
||||
@@ -264,11 +264,11 @@ static char *lookup_service(unsigned short port, int flags,
|
||||
char tmpbuf[4096];
|
||||
|
||||
if (port)
|
||||
{
|
||||
{
|
||||
if (flags & ARES_NI_NUMERICSERV)
|
||||
sep = NULL;
|
||||
else
|
||||
{
|
||||
{
|
||||
if (flags & ARES_NI_UDP)
|
||||
proto = "udp";
|
||||
else if (flags & ARES_NI_SCTP)
|
||||
@@ -288,15 +288,15 @@ static char *lookup_service(unsigned short port, int flags,
|
||||
#elif GETSERVBYPORT_R_ARGS == 4
|
||||
if (getservbyport_r(port, proto, &se, (void *)tmpbuf) != 0)
|
||||
sep = NULL;
|
||||
#else
|
||||
#else
|
||||
/* Lets just hope the OS uses TLS! */
|
||||
sep = getservbyport(port, proto);
|
||||
#endif
|
||||
#else
|
||||
#endif
|
||||
#else
|
||||
/* Lets just hope the OS uses TLS! */
|
||||
sep = getservbyport(port, proto);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (sep && sep->s_name)
|
||||
/* get service name */
|
||||
strcpy(tmpbuf, sep->s_name);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* $Id$ */
|
||||
|
||||
/* Copyright 2005 by Daniel Stenberg.
|
||||
/* Copyright (C) 2005 - 2006, Daniel Stenberg
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted, provided
|
||||
@@ -39,7 +39,9 @@ int ares_getsock(ares_channel channel,
|
||||
if (!channel->queries)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < channel->nservers; i++)
|
||||
for (i = 0;
|
||||
(i < channel->nservers) && (sockindex < ARES_GETSOCK_MAXNUM);
|
||||
i++)
|
||||
{
|
||||
server = &channel->servers[i];
|
||||
if (server->udp_socket != ARES_SOCKET_BAD)
|
||||
@@ -56,13 +58,12 @@ int ares_getsock(ares_channel channel,
|
||||
break;
|
||||
socks[sockindex] = server->tcp_socket;
|
||||
bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
|
||||
sockindex++;
|
||||
|
||||
if (server->qhead) {
|
||||
if (server->qhead)
|
||||
/* then the tcp socket is also writable! */
|
||||
bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex-1);
|
||||
}
|
||||
bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex);
|
||||
|
||||
sockindex++;
|
||||
}
|
||||
}
|
||||
return bitmap;
|
||||
|
@@ -125,7 +125,9 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||
channel->queries = NULL;
|
||||
channel->domains = NULL;
|
||||
channel->sortlist = NULL;
|
||||
channel->servers = NULL;
|
||||
channel->sock_state_cb = NULL;
|
||||
channel->sock_state_cb_data = NULL;
|
||||
|
||||
/* Initialize configuration by each of the four sources, from highest
|
||||
* precedence to lowest.
|
||||
@@ -140,7 +142,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||
if (status != ARES_SUCCESS)
|
||||
{
|
||||
/* Something failed; clean up memory we may have allocated. */
|
||||
if (channel->nservers != -1)
|
||||
if (channel->servers)
|
||||
free(channel->servers);
|
||||
if (channel->domains)
|
||||
{
|
||||
@@ -214,12 +216,16 @@ static int init_by_options(ares_channel channel, struct ares_options *options,
|
||||
/* Copy the servers, if given. */
|
||||
if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
|
||||
{
|
||||
channel->servers =
|
||||
malloc(options->nservers * sizeof(struct server_state));
|
||||
if (!channel->servers && options->nservers != 0)
|
||||
return ARES_ENOMEM;
|
||||
for (i = 0; i < options->nservers; i++)
|
||||
channel->servers[i].addr = options->servers[i];
|
||||
/* Avoid zero size allocations at any cost */
|
||||
if (options->nservers > 0)
|
||||
{
|
||||
channel->servers =
|
||||
malloc(options->nservers * sizeof(struct server_state));
|
||||
if (!channel->servers)
|
||||
return ARES_ENOMEM;
|
||||
for (i = 0; i < options->nservers; i++)
|
||||
channel->servers[i].addr = options->servers[i];
|
||||
}
|
||||
channel->nservers = options->nservers;
|
||||
}
|
||||
|
||||
@@ -228,16 +234,20 @@ static int init_by_options(ares_channel channel, struct ares_options *options,
|
||||
*/
|
||||
if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
|
||||
{
|
||||
channel->domains = malloc(options->ndomains * sizeof(char *));
|
||||
if (!channel->domains && options->ndomains != 0)
|
||||
return ARES_ENOMEM;
|
||||
for (i = 0; i < options->ndomains; i++)
|
||||
{
|
||||
channel->ndomains = i;
|
||||
channel->domains[i] = strdup(options->domains[i]);
|
||||
if (!channel->domains[i])
|
||||
return ARES_ENOMEM;
|
||||
}
|
||||
/* Avoid zero size allocations at any cost */
|
||||
if (options->ndomains > 0)
|
||||
{
|
||||
channel->domains = malloc(options->ndomains * sizeof(char *));
|
||||
if (!channel->domains)
|
||||
return ARES_ENOMEM;
|
||||
for (i = 0; i < options->ndomains; i++)
|
||||
{
|
||||
channel->ndomains = i;
|
||||
channel->domains[i] = strdup(options->domains[i]);
|
||||
if (!channel->domains[i])
|
||||
return ARES_ENOMEM;
|
||||
}
|
||||
}
|
||||
channel->ndomains = options->ndomains;
|
||||
}
|
||||
|
||||
@@ -373,7 +383,8 @@ static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
|
||||
printf ("DNS Servers:\n"
|
||||
" %s (primary)\n", fi->DnsServerList.IpAddress.String);
|
||||
}
|
||||
if (inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
|
||||
if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
|
||||
inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
|
||||
left > ip_size)
|
||||
{
|
||||
ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
|
||||
@@ -581,11 +592,11 @@ DhcpNameServer
|
||||
return (errno == ENOENT) ? ARES_SUCCESS : ARES_EFILE;
|
||||
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
|
||||
{
|
||||
if ((p = try_config(line, "domain")))
|
||||
if ((p = try_config(line, "domain")) && channel->ndomains == -1)
|
||||
status = config_domain(channel, p);
|
||||
else if ((p = try_config(line, "lookup")) && !channel->lookups)
|
||||
status = config_lookup(channel, p, "bind", "file");
|
||||
else if ((p = try_config(line, "search")))
|
||||
else if ((p = try_config(line, "search")) && channel->ndomains == -1)
|
||||
status = set_search(channel, p);
|
||||
else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
|
||||
status = config_nameserver(&servers, &nservers, p);
|
||||
@@ -710,7 +721,6 @@ static int init_by_defaults(ares_channel channel)
|
||||
if (gethostname(hostname, sizeof(hostname)) == -1
|
||||
|| !strchr(hostname, '.'))
|
||||
{
|
||||
channel->domains = malloc(0);
|
||||
channel->ndomains = 0;
|
||||
}
|
||||
else
|
||||
@@ -749,7 +759,7 @@ static int config_domain(ares_channel channel, char *str)
|
||||
|
||||
/* Set a single search domain. */
|
||||
q = str;
|
||||
while (*q && !isspace((unsigned char)*q))
|
||||
while (*q && !ISSPACE(*q))
|
||||
q++;
|
||||
*q = 0;
|
||||
return set_search(channel, str);
|
||||
@@ -773,9 +783,9 @@ static int config_lookup(ares_channel channel, const char *str,
|
||||
if (*p == *bindch) *l++ = 'b';
|
||||
else *l++ = 'f';
|
||||
}
|
||||
while (*p && !isspace((unsigned char)*p) && (*p != ','))
|
||||
while (*p && !ISSPACE(*p) && (*p != ','))
|
||||
p++;
|
||||
while (*p && (isspace((unsigned char)*p) || (*p == ',')))
|
||||
while (*p && (ISSPACE(*p) || (*p == ',')))
|
||||
p++;
|
||||
}
|
||||
*l = 0;
|
||||
@@ -800,7 +810,7 @@ static int config_nameserver(struct server_state **servers, int *nservers,
|
||||
while (more)
|
||||
{
|
||||
more = 0;
|
||||
while (*p && !isspace(*p) && *p != ',')
|
||||
while (*p && !ISSPACE(*p) && *p != ',')
|
||||
p++;
|
||||
|
||||
if (*p)
|
||||
@@ -860,7 +870,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||
char ipbuf[16], ipbufpfx[32];
|
||||
/* Find just the IP */
|
||||
q = str;
|
||||
while (*q && *q != '/' && *q != ';' && !isspace((unsigned char)*q))
|
||||
while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
|
||||
q++;
|
||||
memcpy(ipbuf, str, (int)(q-str));
|
||||
ipbuf[(int)(q-str)] = 0;
|
||||
@@ -868,7 +878,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||
if (*q == '/')
|
||||
{
|
||||
const char *str2 = q+1;
|
||||
while (*q && *q != ';' && !isspace((unsigned char)*q))
|
||||
while (*q && *q != ';' && !ISSPACE(*q))
|
||||
q++;
|
||||
memcpy(ipbufpfx, str, (int)(q-str));
|
||||
ipbufpfx[(int)(q-str)] = 0;
|
||||
@@ -917,11 +927,11 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*q && *q != ';' && !isspace((unsigned char)*q))
|
||||
while (*q && *q != ';' && !ISSPACE(*q))
|
||||
q++;
|
||||
}
|
||||
str = q;
|
||||
while (isspace((unsigned char)*str))
|
||||
while (ISSPACE(*str))
|
||||
str++;
|
||||
}
|
||||
|
||||
@@ -939,6 +949,7 @@ static int set_search(ares_channel channel, const char *str)
|
||||
for(n=0; n < channel->ndomains; n++)
|
||||
free(channel->domains[n]);
|
||||
free(channel->domains);
|
||||
channel->domains = NULL;
|
||||
channel->ndomains = -1;
|
||||
}
|
||||
|
||||
@@ -947,15 +958,21 @@ static int set_search(ares_channel channel, const char *str)
|
||||
p = str;
|
||||
while (*p)
|
||||
{
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
while (*p && !ISSPACE(*p))
|
||||
p++;
|
||||
while (isspace((unsigned char)*p))
|
||||
while (ISSPACE(*p))
|
||||
p++;
|
||||
n++;
|
||||
}
|
||||
|
||||
if (!n)
|
||||
{
|
||||
channel->ndomains = 0;
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
||||
channel->domains = malloc(n * sizeof(char *));
|
||||
if (!channel->domains && n)
|
||||
if (!channel->domains)
|
||||
return ARES_ENOMEM;
|
||||
|
||||
/* Now copy the domains. */
|
||||
@@ -965,7 +982,7 @@ static int set_search(ares_channel channel, const char *str)
|
||||
{
|
||||
channel->ndomains = n;
|
||||
q = p;
|
||||
while (*q && !isspace((unsigned char)*q))
|
||||
while (*q && !ISSPACE(*q))
|
||||
q++;
|
||||
channel->domains[n] = malloc(q - p + 1);
|
||||
if (!channel->domains[n])
|
||||
@@ -973,7 +990,7 @@ static int set_search(ares_channel channel, const char *str)
|
||||
memcpy(channel->domains[n], p, q - p);
|
||||
channel->domains[n][q - p] = 0;
|
||||
p = q;
|
||||
while (isspace((unsigned char)*p))
|
||||
while (ISSPACE(*p))
|
||||
p++;
|
||||
n++;
|
||||
}
|
||||
@@ -990,7 +1007,7 @@ static int set_options(ares_channel channel, const char *str)
|
||||
while (*p)
|
||||
{
|
||||
q = p;
|
||||
while (*q && !isspace((unsigned char)*q))
|
||||
while (*q && !ISSPACE(*q))
|
||||
q++;
|
||||
val = try_option(p, q, "ndots:");
|
||||
if (val && channel->ndots == -1)
|
||||
@@ -1002,7 +1019,7 @@ static int set_options(ares_channel channel, const char *str)
|
||||
if (val && channel->tries == -1)
|
||||
channel->tries = atoi(val);
|
||||
p = q;
|
||||
while (isspace((unsigned char)*p))
|
||||
while (ISSPACE(*p))
|
||||
p++;
|
||||
}
|
||||
|
||||
@@ -1015,10 +1032,10 @@ static char *try_config(char *s, const char *opt)
|
||||
size_t len;
|
||||
|
||||
len = strlen(opt);
|
||||
if (strncmp(s, opt, len) != 0 || !isspace((unsigned char)s[len]))
|
||||
if (strncmp(s, opt, len) != 0 || !ISSPACE(s[len]))
|
||||
return NULL;
|
||||
s += len;
|
||||
while (isspace((unsigned char)*s))
|
||||
while (ISSPACE(*s))
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
|
@@ -59,7 +59,7 @@
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#if (defined(WIN32) || defined(WATT32)) && !defined(MSDOS)
|
||||
#ifdef USE_WINSOCK
|
||||
#define GET_ERRNO() WSAGetLastError()
|
||||
#else
|
||||
#define GET_ERRNO() errno
|
||||
@@ -160,7 +160,7 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now)
|
||||
vec[n].iov_len = sendreq->len;
|
||||
n++;
|
||||
}
|
||||
wcount = (ssize_t)writev(server->tcp_socket, vec, n);
|
||||
wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n);
|
||||
free(vec);
|
||||
if (wcount < 0)
|
||||
{
|
||||
|
@@ -239,15 +239,15 @@ static int single_domain(ares_channel channel, const char *name, char **s)
|
||||
== ARES_SUCCESS)
|
||||
{
|
||||
if (strncasecmp(line, name, len) != 0 ||
|
||||
!isspace((unsigned char)line[len]))
|
||||
!ISSPACE(line[len]))
|
||||
continue;
|
||||
p = line + len;
|
||||
while (isspace((unsigned char)*p))
|
||||
while (ISSPACE(*p))
|
||||
p++;
|
||||
if (*p)
|
||||
{
|
||||
q = p + 1;
|
||||
while (*q && !isspace((unsigned char)*q))
|
||||
while (*q && !ISSPACE(*q))
|
||||
q++;
|
||||
*s = malloc(q - p + 1);
|
||||
if (*s)
|
||||
|
@@ -5,11 +5,11 @@
|
||||
|
||||
#define ARES_VERSION_MAJOR 1
|
||||
#define ARES_VERSION_MINOR 3
|
||||
#define ARES_VERSION_PATCH 1
|
||||
#define ARES_VERSION_PATCH 3
|
||||
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
|
||||
(ARES_VERSION_MINOR<<8)|\
|
||||
(ARES_VERSION_PATCH))
|
||||
#define ARES_VERSION_STR "1.3.1"
|
||||
#define ARES_VERSION_STR "1.3.3-CVS"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* Copyright (C) 2004 - 2005 by Daniel Stenberg et al
|
||||
/* Copyright (C) 2004 - 2006 by Daniel Stenberg et al
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted, provided
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
/* ================================================================ */
|
||||
/* ares/config-win32.h - Hand crafted config file for windows */
|
||||
/* ares/config-win32.h - Hand crafted config file for Windows */
|
||||
/* ================================================================ */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
@@ -29,6 +29,15 @@
|
||||
#define HAVE_GETOPT_H 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define if you have the <sys/time.h> header file */
|
||||
/* #define HAVE_SYS_TIME_H 1 */
|
||||
|
||||
/* Define if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \
|
||||
defined(__POCC__)
|
||||
@@ -47,6 +56,19 @@
|
||||
/* Define if you have the <ws2tcpip.h> header file. */
|
||||
#define HAVE_WS2TCPIP_H 1
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* OTHER HEADER INFO */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if sig_atomic_t is an available typedef. */
|
||||
#define HAVE_SIG_ATOMIC_T 1
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define if you can safely include both <sys/time.h> and <time.h>. */
|
||||
/* #define TIME_WITH_SYS_TIME 1 */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* FUNCTIONS */
|
||||
/* ---------------------------------------------------------------- */
|
||||
@@ -54,24 +76,6 @@
|
||||
/* Define if you have the ioctlsocket function. */
|
||||
#define HAVE_IOCTLSOCKET 1
|
||||
|
||||
/* Define if you have the getnameinfo function. */
|
||||
#define HAVE_GETNAMEINFO 1
|
||||
|
||||
/* Define to the type qualifier of arg 1 for getnameinfo. */
|
||||
#define GETNAMEINFO_QUAL_ARG1 const
|
||||
|
||||
/* Define to the type of arg 1 for getnameinfo. */
|
||||
#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
|
||||
|
||||
/* Define to the type of arg 2 for getnameinfo. */
|
||||
#define GETNAMEINFO_TYPE_ARG2 socklen_t
|
||||
|
||||
/* Define to the type of args 4 and 6 for getnameinfo. */
|
||||
#define GETNAMEINFO_TYPE_ARG46 DWORD
|
||||
|
||||
/* Define to the type of arg 7 for getnameinfo. */
|
||||
#define GETNAMEINFO_TYPE_ARG7 int
|
||||
|
||||
/* Define if you have the recv function. */
|
||||
#define HAVE_RECV 1
|
||||
|
||||
@@ -111,6 +115,39 @@
|
||||
/* Define to the function return type for send. */
|
||||
#define SEND_TYPE_RETV int
|
||||
|
||||
/* Specifics for the Watt-32 tcp/ip stack */
|
||||
#ifdef WATT32
|
||||
#define SOCKET int
|
||||
#define NS_INADDRSZ 4
|
||||
#define HAVE_ARPA_NAMESER_H 1
|
||||
#undef HAVE_WINSOCK_H
|
||||
#undef HAVE_WINSOCK2_H
|
||||
#undef HAVE_WS2TCPIP_H
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* TYPEDEF REPLACEMENTS */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define this if in_addr_t is not an available 'typedefed' type */
|
||||
#define in_addr_t unsigned long
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define ssize_t if it is not an available 'typedefed' type */
|
||||
#if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || defined(__POCC__)
|
||||
#elif defined(_WIN64)
|
||||
#define ssize_t __int64
|
||||
#else
|
||||
#define ssize_t int
|
||||
#endif
|
||||
|
||||
/* Define to 'int' if socklen_t is not an available 'typedefed' type */
|
||||
#ifndef HAVE_WS2TCPIP_H
|
||||
#define socklen_t int
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* STRUCT RELATED */
|
||||
/* ---------------------------------------------------------------- */
|
||||
@@ -121,6 +158,9 @@
|
||||
/* Define this if you have struct sockaddr_storage */
|
||||
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
|
||||
/* Define this if you have struct timeval */
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* IPV6 COMPATIBILITY */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
@@ -265,6 +265,7 @@ dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_TYPE_SIZE_T
|
||||
AC_HEADER_TIME
|
||||
CURL_CHECK_STRUCT_TIMEVAL
|
||||
|
||||
AC_CHECK_SIZEOF(size_t)
|
||||
AC_CHECK_SIZEOF(long)
|
||||
@@ -296,6 +297,10 @@ TYPE_IN_ADDR_T
|
||||
|
||||
TYPE_SOCKADDR_STORAGE
|
||||
|
||||
TYPE_SIG_ATOMIC_T
|
||||
|
||||
AC_TYPE_SIGNAL
|
||||
|
||||
CURL_CHECK_FUNC_RECV
|
||||
|
||||
CURL_CHECK_FUNC_SEND
|
||||
|
@@ -79,14 +79,13 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
|
||||
|
||||
ch = *src++;
|
||||
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
|
||||
&& isascii((unsigned char)(src[1]))
|
||||
&& isxdigit((unsigned char)(src[1]))) {
|
||||
&& ISXDIGIT(src[1])) {
|
||||
/* Hexadecimal: Eat nybble string. */
|
||||
if (size <= 0U)
|
||||
goto emsgsize;
|
||||
dirty = 0;
|
||||
src++; /* skip x or X. */
|
||||
while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) {
|
||||
while ((ch = *src++) != '\0' && ISXDIGIT(ch)) {
|
||||
if (isupper(ch))
|
||||
ch = tolower(ch);
|
||||
n = (int)(strchr(xdigits, ch) - xdigits);
|
||||
@@ -106,7 +105,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
|
||||
goto emsgsize;
|
||||
*dst++ = (unsigned char) (tmp << 4);
|
||||
}
|
||||
} else if (isascii(ch) && isdigit(ch)) {
|
||||
} else if (ISDIGIT(ch)) {
|
||||
/* Decimal: eat dotted digit string. */
|
||||
for (;;) {
|
||||
tmp = 0;
|
||||
@@ -117,7 +116,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
|
||||
if (tmp > 255)
|
||||
goto enoent;
|
||||
} while ((ch = *src++) != '\0' &&
|
||||
isascii(ch) && isdigit(ch));
|
||||
ISDIGIT(ch));
|
||||
if (size-- <= 0U)
|
||||
goto emsgsize;
|
||||
*dst++ = (unsigned char) tmp;
|
||||
@@ -126,15 +125,15 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
|
||||
if (ch != '.')
|
||||
goto enoent;
|
||||
ch = *src++;
|
||||
if (!isascii(ch) || !isdigit(ch))
|
||||
if (!ISDIGIT(ch))
|
||||
goto enoent;
|
||||
}
|
||||
} else
|
||||
goto enoent;
|
||||
|
||||
bits = -1;
|
||||
if (ch == '/' && isascii((unsigned char)(src[0])) &&
|
||||
isdigit((unsigned char)(src[0])) && dst > odst) {
|
||||
if (ch == '/' &&
|
||||
ISDIGIT(src[0]) && dst > odst) {
|
||||
/* CIDR width specifier. Nothing can follow it. */
|
||||
ch = *src++; /* Skip over the /. */
|
||||
bits = 0;
|
||||
@@ -142,7 +141,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
|
||||
n = (int)(strchr(digits, ch) - digits);
|
||||
bits *= 10;
|
||||
bits += n;
|
||||
} while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
|
||||
} while ((ch = *src++) != '\0' && ISDIGIT(ch));
|
||||
if (ch != '\0')
|
||||
goto enoent;
|
||||
if (bits > 32)
|
||||
|
18
ares/setup.h
18
ares/setup.h
@@ -69,6 +69,22 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
|
||||
* define USE_WINSOCK to 1 if we have and use WINSOCK API, else
|
||||
* undefine USE_WINSOCK.
|
||||
*/
|
||||
|
||||
#undef USE_WINSOCK
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
# define USE_WINSOCK 2
|
||||
#else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# define USE_WINSOCK 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Work-arounds for systems without configure support
|
||||
*/
|
||||
@@ -105,7 +121,7 @@
|
||||
* Typedef our socket type
|
||||
*/
|
||||
|
||||
#if defined(WIN32) && !defined(WATT32)
|
||||
#ifdef USE_WINSOCK
|
||||
typedef SOCKET ares_socket_t;
|
||||
#define ARES_SOCKET_BAD INVALID_SOCKET
|
||||
#else
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* Copyright (C) 2004 - 2006 by Daniel Stenberg et al
|
||||
/* Copyright (C) 2004 - 2007 by Daniel Stenberg et al
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted, provided
|
||||
@@ -17,9 +17,19 @@
|
||||
*/
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* NOTICE *
|
||||
* ======== *
|
||||
* *
|
||||
* Content of header files lib/setup_once.h and ares/setup_once.h *
|
||||
* must be kept in sync. Modify the other one if you change this. *
|
||||
* *
|
||||
********************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* If we have the MSG_NOSIGNAL define, make sure we use
|
||||
* it as the fourth argument of send() and recv()
|
||||
* it as the fourth argument of function send()
|
||||
*/
|
||||
|
||||
#ifdef HAVE_MSG_NOSIGNAL
|
||||
@@ -64,12 +74,9 @@
|
||||
#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
|
||||
(RECV_TYPE_ARG2)(y), \
|
||||
(RECV_TYPE_ARG3)(z), \
|
||||
(RECV_TYPE_ARG4)(SEND_4TH_ARG))
|
||||
(RECV_TYPE_ARG4)(0))
|
||||
#endif
|
||||
#else /* HAVE_RECV */
|
||||
#ifdef DJGPP
|
||||
#define sread(x,y,z) (ssize_t)read_s((int)(x), (char *)(y), (int)(z))
|
||||
#endif
|
||||
#ifndef sread
|
||||
/* */
|
||||
Error Missing_definition_of_macro_sread
|
||||
@@ -94,9 +101,6 @@
|
||||
(SEND_TYPE_ARG4)(SEND_4TH_ARG))
|
||||
#endif
|
||||
#else /* HAVE_SEND */
|
||||
#ifdef DJGPP
|
||||
#define swrite(x,y,z) (ssize_t)write_s((int)(x), (char *)(y), (int)(z))
|
||||
#endif
|
||||
#ifndef swrite
|
||||
/* */
|
||||
Error Missing_definition_of_macro_swrite
|
||||
@@ -105,5 +109,38 @@
|
||||
#endif /* HAVE_SEND */
|
||||
|
||||
|
||||
/*
|
||||
* Uppercase macro versions of ANSI/ISO is*() functions/macros which
|
||||
* avoid negative number inputs with argument byte codes > 127.
|
||||
*/
|
||||
|
||||
#define ISSPACE(x) (isspace((int) ((unsigned char)x)))
|
||||
#define ISDIGIT(x) (isdigit((int) ((unsigned char)x)))
|
||||
#define ISALNUM(x) (isalnum((int) ((unsigned char)x)))
|
||||
#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
|
||||
#define ISGRAPH(x) (isgraph((int) ((unsigned char)x)))
|
||||
#define ISALPHA(x) (isalpha((int) ((unsigned char)x)))
|
||||
#define ISPRINT(x) (isprint((int) ((unsigned char)x)))
|
||||
|
||||
|
||||
/*
|
||||
* Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_SIG_ATOMIC_T
|
||||
typedef int sig_atomic_t;
|
||||
#define HAVE_SIG_ATOMIC_T
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Default return type for signal handlers.
|
||||
*/
|
||||
|
||||
#ifndef RETSIGTYPE
|
||||
#define RETSIGTYPE void
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __SETUP_ONCE_H */
|
||||
|
||||
|
@@ -129,6 +129,10 @@ SOURCE=..\..\ares_gethostbyname.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\ares_getsock.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\ares_init.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@@ -6,7 +6,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
|
@@ -5,7 +5,6 @@ REM $Date$
|
||||
|
||||
REM create ca-bundle.h
|
||||
echo /* This file is generated automatically */ >lib\ca-bundle.h
|
||||
echo #define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE") >>lib\ca-bundle.h
|
||||
|
||||
REM create hugehelp.c
|
||||
copy src\hugehelp.c.cvs src\hugehelp.c
|
||||
|
82
configure.ac
82
configure.ac
@@ -28,7 +28,7 @@ dnl We don't know the version number "staticly" so we use a dash here
|
||||
AC_INIT(curl, [-], [a suitable curl mailing list => http://curl.haxx.se/mail/])
|
||||
|
||||
dnl configure script copyright
|
||||
AC_COPYRIGHT([Copyright (c) 1998 - 2005 Daniel Stenberg, <daniel@haxx.se>
|
||||
AC_COPYRIGHT([Copyright (c) 1998 - 2006 Daniel Stenberg, <daniel@haxx.se>
|
||||
This configure script may be copied, distributed and modified under the
|
||||
terms of the curl license; see COPYING for more details])
|
||||
|
||||
@@ -78,6 +78,7 @@ AC_SUBST(PKGADD_VENDOR)
|
||||
dnl
|
||||
dnl initialize all the info variables
|
||||
curl_ssl_msg="no (--with-ssl / --with-gnutls)"
|
||||
curl_ssh_msg="no (--with-libssh2)"
|
||||
curl_zlib_msg="no (--with-zlib)"
|
||||
curl_krb4_msg="no (--with-krb4*)"
|
||||
curl_gss_msg="no (--with-gssapi)"
|
||||
@@ -747,7 +748,7 @@ AC_ARG_WITH(gssapi-includes,
|
||||
AC_ARG_WITH(gssapi-libs,
|
||||
AC_HELP_STRING([--with-gssapi-libs=DIR],
|
||||
[Specify location of GSSAPI libs]),
|
||||
[ GSSAPI_LIBS="-L$withval"
|
||||
[ GSSAPI_LIB_DIR="-L$withval"
|
||||
want_gss="yes" ]
|
||||
)
|
||||
|
||||
@@ -1043,6 +1044,74 @@ if test X"$OPT_SSL" != Xno; then
|
||||
|
||||
fi
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for the presence of LIBSSH2 libraries and headers
|
||||
dnl **********************************************************************
|
||||
|
||||
dnl Default to compiler & linker defaults for LIBSSH2 files & libraries.
|
||||
OPT_LIBSSH2=off
|
||||
AC_ARG_WITH(libssh2,dnl
|
||||
AC_HELP_STRING([--with-libssh2=PATH],[Where to look for libssh2, PATH points to the LIBSSH2 installation (default: /usr/local/lib); when possible, set the PKG_CONFIG_PATH environment variable instead of using this option])
|
||||
AC_HELP_STRING([--without-libssh2], [disable LIBSSH2]),
|
||||
OPT_LIBSSH2=$withval)
|
||||
|
||||
if test X"$OPT_LIBSSH2" != Xno; then
|
||||
dnl backup the pre-libssh2 variables
|
||||
CLEANLDFLAGS="$LDFLAGS"
|
||||
CLEANCPPFLAGS="$CPPFLAGS"
|
||||
CLEANLIBS="$LIBS"
|
||||
|
||||
case "$OPT_LIBSSH2" in
|
||||
yes)
|
||||
dnl --with-libssh2 (without path) used
|
||||
PREFIX_LIBSSH2=/usr/local/lib
|
||||
LIB_LIBSSH2="$PREFIX_LIBSSH2/lib$libsuff"
|
||||
;;
|
||||
off)
|
||||
dnl no --with-libssh2 option given, just check default places
|
||||
PREFIX_LIBSSH2=
|
||||
;;
|
||||
*)
|
||||
dnl use the given --with-libssh2 spot
|
||||
PREFIX_LIBSSH2=$OPT_LIBSSH2
|
||||
LIB_LIBSSH2="$PREFIX_LIBSSH2/lib$libsuff"
|
||||
LDFLAGS="$LDFLAGS -L$LIB_LIBSSH2"
|
||||
CPPFLAGS="$CPPFLAGS -I$PREFIX_LIBSSH2/include"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test X"$HAVECRYPTO" = X"yes"; then
|
||||
dnl This is only reasonable to do if crypto actually is there: check for
|
||||
dnl LIBSSH2 libs NOTE: it is important to do this AFTER the crypto lib
|
||||
|
||||
AC_CHECK_LIB(ssh2, libssh2_channel_open_ex)
|
||||
|
||||
AC_CHECK_HEADERS(libssh2.h,
|
||||
curl_ssh_msg="enabled (libSSH2)"
|
||||
LIBSSH2_ENABLED=1
|
||||
AC_DEFINE(USE_LIBSSH2, 1, [if libSSH2 is in use]))
|
||||
|
||||
if test X"$OPT_LIBSSH2" != Xoff &&
|
||||
test "$LIBSSH2_ENABLED" != "1"; then
|
||||
AC_MSG_ERROR([libSSH2 libs and/or directories were not found where specified!])
|
||||
fi
|
||||
else
|
||||
AC_MSG_WARN([without the use of OpenSSL libs, libssh2 cannot work])
|
||||
fi
|
||||
|
||||
if test "$LIBSSH2_ENABLED" = "1"; then
|
||||
if test -n "$LIB_LIBSSH2"; then
|
||||
dnl when the libssh2 shared libs were found in a path that the run-time
|
||||
dnl linker doesn't search through, we need to add it to LD_LIBRARY_PATH
|
||||
dnl to prevent further configure tests to fail due to this
|
||||
|
||||
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$LIB_LIBSSH2"
|
||||
export LD_LIBRARY_PATH
|
||||
AC_MSG_NOTICE([Added $LIB_LIBSSH2 to LD_LIBRARY_PATH])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for the random seed preferences
|
||||
dnl **********************************************************************
|
||||
@@ -1527,6 +1596,8 @@ dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_TYPE_SIZE_T
|
||||
AC_HEADER_TIME
|
||||
CURL_CHECK_STRUCT_TIMEVAL
|
||||
CURL_VERIFY_RUNTIMELIBS
|
||||
|
||||
AC_CHECK_SIZEOF(curl_off_t, ,[
|
||||
#include <stdio.h>
|
||||
@@ -1562,6 +1633,10 @@ TYPE_IN_ADDR_T
|
||||
|
||||
TYPE_SOCKADDR_STORAGE
|
||||
|
||||
TYPE_SIG_ATOMIC_T
|
||||
|
||||
AC_TYPE_SIGNAL
|
||||
|
||||
AC_FUNC_SELECT_ARGTYPES
|
||||
|
||||
CURL_CHECK_FUNC_RECV
|
||||
@@ -1572,7 +1647,7 @@ CURL_CHECK_MSG_NOSIGNAL
|
||||
|
||||
dnl Checks for library functions.
|
||||
dnl AC_PROG_GCC_TRADITIONAL
|
||||
AC_TYPE_SIGNAL
|
||||
|
||||
dnl AC_FUNC_VPRINTF
|
||||
case $host in
|
||||
*msdosdjgpp)
|
||||
@@ -2074,6 +2149,7 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
|
||||
Install prefix: ${prefix}
|
||||
Compiler: ${CC}
|
||||
SSL support: ${curl_ssl_msg}
|
||||
SSH support: ${curl_ssh_msg}
|
||||
zlib support: ${curl_zlib_msg}
|
||||
krb4 support: ${curl_krb4_msg}
|
||||
GSSAPI support: ${curl_gss_msg}
|
||||
|
@@ -142,8 +142,8 @@ Rexx
|
||||
|
||||
Ruby
|
||||
|
||||
Written by Hirotaka Matsuyuki
|
||||
http://www.d1.dion.ne.jp/~matuyuki/ruby.html
|
||||
Written by Ross Bamford
|
||||
http://curb.rubyforge.org/
|
||||
|
||||
Scheme
|
||||
|
||||
@@ -155,6 +155,11 @@ S-Lang
|
||||
S-Lang binding written by John E Davis
|
||||
http://www.jedsoft.org/slang/modules/curl.html
|
||||
|
||||
Smalltalk
|
||||
|
||||
Smalltalk binding written by Danil Osipchuk
|
||||
http://www.squeaksource.com/CurlPlugin/
|
||||
|
||||
SPL
|
||||
|
||||
SPL binding written by Clifford Wolf
|
||||
|
@@ -87,7 +87,6 @@ FTP
|
||||
- via http-proxy
|
||||
- all operations can be tunneled through a http-proxy
|
||||
- customizable to retrieve file modification date
|
||||
- third party transfers
|
||||
- no dir depth limit
|
||||
|
||||
FTPS (*1)
|
||||
|
25
docs/INSTALL
25
docs/INSTALL
@@ -51,12 +51,12 @@ UNIX
|
||||
path for your compiler/linker, you don't need to do anything special. If
|
||||
you have OpenSSL installed in /usr/local/ssl, you can run configure like:
|
||||
|
||||
./configure --with-ssl
|
||||
./configure --with-ssl
|
||||
|
||||
If you have OpenSSL installed somewhere else (for example, /opt/OpenSSL,)
|
||||
you can run configure like this:
|
||||
|
||||
./configure --with-ssl=/opt/OpenSSL
|
||||
./configure --with-ssl=/opt/OpenSSL
|
||||
|
||||
If you insist on forcing a build without SSL support, even though you may
|
||||
have OpenSSL installed in your system, you can run configure like this:
|
||||
@@ -148,12 +148,21 @@ Win32
|
||||
-------
|
||||
|
||||
Run the 'mingw32.bat' file to get the proper environment variables set,
|
||||
then run 'make mingw32' in the root dir. Use 'make mingw32-ssl' to build
|
||||
then run 'make mingw32' in the root dir. Use 'make mingw32-ssl' to build
|
||||
curl SSL enabled.
|
||||
|
||||
If you have any problems linking libraries or finding header files, be sure
|
||||
to verify that the provided "Makefile.m32" files use the proper paths, and
|
||||
adjust as necessary.
|
||||
adjust as necessary. It is also possible to override these paths with
|
||||
environment variables, for example:
|
||||
|
||||
set ZLIB_PATH=c:\zlib-1.2.3
|
||||
set OPENSSL_PATH=c:\openssl-0.9.8d
|
||||
set LIBSSH2_PATH=c:\libssh2-0.15
|
||||
|
||||
ATTENTION: if you want to build with libssh2 support you have to use latest
|
||||
sources fetched from CVS - the current 0.14 release will NOT work!
|
||||
Use 'make mingw32-ssh2-ssl' to build curl with SSH2 and SSL enabled.
|
||||
|
||||
Cygwin
|
||||
------
|
||||
@@ -184,7 +193,7 @@ Win32
|
||||
documentation on how to compile zlib. Define the ZLIB_PATH environment
|
||||
variable to the location of zlib.h and zlib.lib, for example:
|
||||
|
||||
set ZLIB_PATH=c:\zlib-1.2.1
|
||||
set ZLIB_PATH=c:\zlib-1.2.3
|
||||
|
||||
Then run 'nmake vc-zlib' in curl's root directory.
|
||||
|
||||
@@ -198,7 +207,7 @@ Win32
|
||||
Before running nmake define the OPENSSL_PATH environment variable with
|
||||
the root/base directory of OpenSSL, for example:
|
||||
|
||||
set OPENSSL_PATH=c:\openssl-0.9.7d
|
||||
set OPENSSL_PATH=c:\openssl-0.9.8d
|
||||
|
||||
Then run 'nmake vc-ssl' or 'nmake vc-ssl-dll' in curl's root
|
||||
directory. 'nmake vc-ssl' will create a libcurl static and dynamic
|
||||
@@ -676,6 +685,7 @@ PORTS
|
||||
- PowerPC Linux
|
||||
- PowerPC Mac OS 9
|
||||
- PowerPC Mac OS X
|
||||
- SuperH4 Linux 2.6.X
|
||||
- SINIX-Z v5
|
||||
- Sparc Linux
|
||||
- Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8, 9, 10
|
||||
@@ -717,3 +727,6 @@ OpenSSL http://www.openssl.org
|
||||
MingW http://www.mingw.org
|
||||
OpenLDAP http://www.openldap.org
|
||||
Zlib http://www.gzip.org/zlib/
|
||||
libssh2 http://www.libssh2.org
|
||||
|
||||
|
||||
|
@@ -3,11 +3,31 @@ join in and help us correct one or more of these! Also be sure to check the
|
||||
changelog of the current development status, as one or more of these problems
|
||||
may have been fixed since this was written!
|
||||
|
||||
41. Jeff Pohlmeyer's curl_multi_socket crashing case. Recipe and instructions
|
||||
here: http://curl.haxx.se/mail/lib-2007-01/0022.html
|
||||
|
||||
40. HTTP Pipelining, NULL content
|
||||
http://curl.haxx.se/bug/view.cgi?id=1631566
|
||||
|
||||
39. Steffen Rumler's Race Condition in Curl_proxyCONNECT:
|
||||
http://curl.haxx.se/mail/lib-2007-01/0045.html
|
||||
|
||||
38. Kumar Swamy Bhatt's problem in ftp/ssl "LIST" operation:
|
||||
http://curl.haxx.se/mail/lib-2007-01/0103.html
|
||||
|
||||
37. Having more than one connection to the same host when doing NTLM
|
||||
authentication (with performs multiple "passes" and authenticates a
|
||||
connection rather than a HTTP request), and particularly when using the
|
||||
multi interface, there's a risk that libcurl will re-use a wrong connection
|
||||
when doing the different passes in the NTLM negotiation and thus fail to
|
||||
negotiate (in seemingly mysterious ways).
|
||||
|
||||
35. Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very
|
||||
bad when used with the multi interface.
|
||||
|
||||
34. The SOCKS4 connection codes don't properly acknowledge (connect) timeouts.
|
||||
Also see #12.
|
||||
Also see #12. According to bug #1556528, even the SOCKS5 connect code does
|
||||
not do it right: http://curl.haxx.se/bug/view.cgi?id=1556528,
|
||||
|
||||
33. Doing multi-pass HTTP authentication on a non-default port does not work.
|
||||
This happens because the multi-pass code abuses the redirect following code
|
||||
@@ -43,12 +63,6 @@ may have been fixed since this was written!
|
||||
"system context" will make it use wrong(?) user name - at least when compared
|
||||
to what winhttp does. See http://curl.haxx.se/bug/view.cgi?id=1281867
|
||||
|
||||
25. When doing a CONNECT request with curl it doesn't properly handle if the
|
||||
proxy closes the connection within the authentication "negotiation phase".
|
||||
Like if you do HTTPS or similar over a proxy and you use perhaps
|
||||
--proxy-anyauth. There's work in progress on this problem, and a recent
|
||||
patch was posted here: http://curl.haxx.se/mail/lib-2005-08/0074.html
|
||||
|
||||
23. We don't support SOCKS for IPv6. We don't support FTPS over a SOCKS proxy.
|
||||
We don't have any test cases for SOCKS proxy. We probably have even more
|
||||
bugs and lack of features when a SOCKS proxy is used. And there seem to be a
|
||||
@@ -72,9 +86,6 @@ may have been fixed since this was written!
|
||||
|
||||
Since 7.15.4 at least line endings are converted.
|
||||
|
||||
19. FTP 3rd party transfers with the multi interface doesn't work. Test:
|
||||
define CURL_MULTIEASY, rebuild curl, run test case 230 - 232.
|
||||
|
||||
16. FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>,
|
||||
<password>, and <fpath> components, encoded as "%00". The problem is that
|
||||
curl_unescape does not detect this, but instead returns a shortened C
|
||||
|
24
docs/THANKS
24
docs/THANKS
@@ -17,6 +17,7 @@ Alexander Kourakos
|
||||
Alexander Krasnostavsky
|
||||
Alexander Lazic
|
||||
Alexander Zhuravlev
|
||||
Alexey Simak
|
||||
Alexis Carvalho
|
||||
Amol Pattekar
|
||||
Andi Jahja
|
||||
@@ -26,6 +27,7 @@ Andreas Olsson
|
||||
Andreas Rieke
|
||||
Andres Garcia
|
||||
Andrew Benham
|
||||
Andrew Biggs
|
||||
Andrew Bushnell
|
||||
Andrew Francis
|
||||
Andrew Fuller
|
||||
@@ -36,6 +38,7 @@ Angus Mackay
|
||||
Antoine Calando
|
||||
Anton Kalmykov
|
||||
Arkadiusz Miskiewicz
|
||||
Armel Asselin
|
||||
Arve Knudsen
|
||||
Ates Goral
|
||||
Augustus Saunders
|
||||
@@ -43,12 +46,15 @@ Avery Fay
|
||||
Ben Greear
|
||||
Ben Madsen
|
||||
Benjamin Gerard
|
||||
Bernard Leak
|
||||
Bertrand Demiddelaer
|
||||
Bjorn Reese
|
||||
Bj<EFBFBD>rn Stenberg
|
||||
Bob Schader
|
||||
Bogdan Nicula
|
||||
Brad Burdick
|
||||
Bradford Bruce
|
||||
Brendan Jurd
|
||||
Brent Beardsley
|
||||
Brian Akins
|
||||
Brian Dessent
|
||||
@@ -68,6 +74,7 @@ Christian Robottom Reis
|
||||
Christophe Demory
|
||||
Christophe Legry
|
||||
Christopher R. Palmer
|
||||
Ciprian Badescu
|
||||
Clarence Gardner
|
||||
Clifford Wolf
|
||||
Cody Jones
|
||||
@@ -116,7 +123,9 @@ Dimitris Sarris
|
||||
Dinar
|
||||
Dirk Eddelbuettel
|
||||
Dirk Manske
|
||||
Dmitriy Sergeyev
|
||||
Dmitry Bartsevich
|
||||
Dmitry Rechkin
|
||||
Dolbneff A.V
|
||||
Domenico Andreoli
|
||||
Dominick Meglio
|
||||
@@ -206,11 +215,13 @@ James Clancy
|
||||
James Cone
|
||||
James Gallagher
|
||||
James Griffiths
|
||||
James Housley
|
||||
James MacMillan
|
||||
Jamie Lokier
|
||||
Jamie Newton
|
||||
Jamie Wilkinson
|
||||
Jan Kunder
|
||||
Jared Lundell
|
||||
Jari Sundell
|
||||
Jason S. Priebe
|
||||
Jaz Fresh
|
||||
@@ -313,12 +324,14 @@ Markus Oberhumer
|
||||
Martijn Koster
|
||||
Martin C. Martin
|
||||
Martin Hedenfalk
|
||||
Martin Skinner
|
||||
Marty Kuhrt
|
||||
Maruko
|
||||
Massimiliano Ziccardi
|
||||
Mathias Axelsson
|
||||
Mats Lidell
|
||||
Matt Veenstra
|
||||
Matt Witherspoon
|
||||
Matthew Blain
|
||||
Matthew Clarke
|
||||
Maurice Barnum
|
||||
@@ -337,12 +350,14 @@ Mihai Ionescu
|
||||
Mikael Sennerholm
|
||||
Mike Bytnar
|
||||
Mike Dobbs
|
||||
Mike Protts
|
||||
Miklos Nemeth
|
||||
Mitz Wark
|
||||
Mohamed Lrhazi
|
||||
Mohun Biswas
|
||||
Moonesamy
|
||||
Nathan O'Sullivan
|
||||
Nathanael Nerode
|
||||
Naveen Noel
|
||||
Neil Dunbar
|
||||
Neil Spring
|
||||
@@ -355,10 +370,12 @@ Nicolas Croiset
|
||||
Nicolas Fran<61>ois
|
||||
Niels van Tongeren
|
||||
Nikita Schmidt
|
||||
Nir Soffer
|
||||
Nis Jorgensen
|
||||
Nodak Sodak
|
||||
Norbert Novotny
|
||||
Ofer
|
||||
Olaf Stueben
|
||||
Olaf St<53>ben
|
||||
Oren Tirosh
|
||||
P R Schaffner
|
||||
@@ -398,6 +415,7 @@ Ralph Beckmann
|
||||
Ralph Mitchell
|
||||
Ramana Mokkapati
|
||||
Randy McMurchy
|
||||
Ravi Pratap
|
||||
Reinout van Schouwen
|
||||
Renaud Chaillat
|
||||
Renaud Duhaut
|
||||
@@ -416,6 +434,7 @@ Rick Jones
|
||||
Rick Richardson
|
||||
Rob Stanzel
|
||||
Robert D. Young
|
||||
Robert Foreman
|
||||
Robert Olson
|
||||
Robert Weaver
|
||||
Robin Kay
|
||||
@@ -442,6 +461,7 @@ Scott Davis
|
||||
Sebastien Willemijns
|
||||
Sergio Ballestrero
|
||||
Seshubabu Pasam
|
||||
Sh Diao
|
||||
Shard
|
||||
Shawn Poulson
|
||||
Shmulik Regev
|
||||
@@ -452,6 +472,7 @@ Simon Liu
|
||||
Spiridonoff A.V
|
||||
Stadler Stephan
|
||||
Stefan Esser
|
||||
Stefan Krause
|
||||
Stefan Ulrich
|
||||
Stephan Bergmann
|
||||
Stephen Kick
|
||||
@@ -489,6 +510,7 @@ Tomas Szepe
|
||||
Tomasz Lacki
|
||||
Tommy Tam
|
||||
Ton Voon
|
||||
Toon Verwaest
|
||||
Tor Arntsen
|
||||
Torsten Foertsch
|
||||
Toshiyuki Maezawa
|
||||
@@ -498,6 +520,8 @@ Troy Engel
|
||||
Tupone Alfredo
|
||||
Ulf H<>rnhammar
|
||||
Ulrich Zadow
|
||||
Venkat Akella
|
||||
Victor Snezhko
|
||||
Vilmos Nebehaj
|
||||
Vincent Bronner
|
||||
Vincent Penquerc'h
|
||||
|
20
docs/TODO
20
docs/TODO
@@ -43,10 +43,6 @@ TODO
|
||||
powered libcurl the default build (which of course would require that we'd
|
||||
bundle the c-ares source code in the libcurl source code releases).
|
||||
|
||||
* Support CONNECT 407 responses that kill the connection and expect the
|
||||
client to reconnect to complete the authentication. Currently libcurl
|
||||
assumes that a proxy connection will be kept alive.
|
||||
|
||||
* Make the curl/*.h headers include the proper system includes based on what
|
||||
was present at the time when configure was run. Currently, the sys/select.h
|
||||
header is for example included by curl/multi.h only on specific platforms
|
||||
@@ -115,10 +111,6 @@ TODO
|
||||
|
||||
HTTP
|
||||
|
||||
* Pipelining. Sending multiple requests before the previous one(s) are done.
|
||||
This could possibly be implemented using the multi interface to queue
|
||||
requests and the response data.
|
||||
|
||||
* When doing CONNECT to a HTTP proxy, libcurl always uses HTTP/1.0. This has
|
||||
never been reported as causing trouble to anyone, but should be considered
|
||||
to use the HTTP version the user has chosen.
|
||||
@@ -192,8 +184,8 @@ TODO
|
||||
|
||||
* Fix the connection phase to be non-blocking when multi interface is used
|
||||
|
||||
* Add a way to check if the connection seems to be alive, to corrspond to the
|
||||
SSL_peak() way we use with OpenSSL.
|
||||
* Add a way to check if the connection seems to be alive, to correspond to
|
||||
the SSL_peak() way we use with OpenSSL.
|
||||
|
||||
LDAP
|
||||
|
||||
@@ -205,10 +197,6 @@ TODO
|
||||
|
||||
* RTSP - RFC2326 (protocol - very HTTP-like, also contains URL description)
|
||||
|
||||
* SFTP/SCP/SSH (no RFCs for protocol nor URI/URL format). An implementation
|
||||
should most probably use an existing ssh library, such as OpenSSH. or
|
||||
libssh2.org
|
||||
|
||||
* RSYNC (no RFCs for protocol nor URI/URL format). An implementation should
|
||||
most probably use an existing rsync library, such as librsync.
|
||||
|
||||
@@ -277,6 +265,10 @@ TODO
|
||||
|
||||
TEST SUITE
|
||||
|
||||
* Make our own version of stunnel for simple port forwarding to enable HTTPS
|
||||
and FTP-SSL tests without the stunnel dependency, and it could allow us to
|
||||
provide test tools built with either OpenSSL or GnuTLS
|
||||
|
||||
* Make the test servers able to serve multiple running test suites. Like if
|
||||
two users run 'make test' at once.
|
||||
|
||||
|
118
docs/curl.1
118
docs/curl.1
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -21,7 +21,7 @@
|
||||
.\" * $Id$
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl 1 "21 Mar 2006" "Curl 7.15.4" "Curl Manual"
|
||||
.TH curl 1 "3 Nov 2006" "Curl 7.16.1" "Curl Manual"
|
||||
.SH NAME
|
||||
curl \- transfer a URL
|
||||
.SH SYNOPSIS
|
||||
@@ -30,13 +30,13 @@ curl \- transfer a URL
|
||||
.SH DESCRIPTION
|
||||
.B curl
|
||||
is a tool to transfer data from or to a server, using one of the supported
|
||||
protocols (HTTP, HTTPS, FTP, FTPS, TFTP, DICT, TELNET, LDAP or FILE).
|
||||
The command is designed to work without user interaction.
|
||||
protocols (HTTP, HTTPS, FTP, FTPS, SCP, SFTP, TFTP, DICT, TELNET, LDAP or
|
||||
FILE). The command is designed to work without user interaction.
|
||||
|
||||
curl offers a busload of useful tricks like proxy support, user
|
||||
authentication, ftp upload, HTTP post, SSL (https:) connections, cookies, file
|
||||
transfer resume and more. As you will see below, the amount of features will
|
||||
make your head spin!
|
||||
authentication, ftp upload, HTTP post, SSL connections, cookies, file transfer
|
||||
resume and more. As you will see below, the amount of features will make your
|
||||
head spin!
|
||||
|
||||
curl is powered by libcurl for all transfer-related features. See
|
||||
.BR libcurl (3)
|
||||
@@ -312,25 +312,25 @@ run curl.
|
||||
|
||||
If this option is used several times, each occurrence will toggle this on/off.
|
||||
.IP "--egd-file <file>"
|
||||
(HTTPS) Specify the path name to the Entropy Gathering Daemon socket. The
|
||||
socket is used to seed the random engine for SSL connections. See also the
|
||||
(SSL) Specify the path name to the Entropy Gathering Daemon socket. The socket
|
||||
is used to seed the random engine for SSL connections. See also the
|
||||
\fI--random-file\fP option.
|
||||
.IP "-E/--cert <certificate[:password]>"
|
||||
(HTTPS)
|
||||
Tells curl to use the specified certificate file when getting a file
|
||||
with HTTPS. The certificate must be in PEM format.
|
||||
If the optional password isn't specified, it will be queried for on
|
||||
the terminal. Note that this certificate is the private key and the private
|
||||
certificate concatenated!
|
||||
(SSL) Tells curl to use the specified certificate file when getting a file
|
||||
with HTTPS or FTPS. The certificate must be in PEM format. If the optional
|
||||
password isn't specified, it will be queried for on the terminal. Note that
|
||||
this option assumes a \&"certificate" file that is the private key and the
|
||||
private certificate concatenated! See \fI--cert\fP and \fI--key\fP to specify
|
||||
them independently.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--cert-type <type>"
|
||||
(SSL) Tells curl what certificate type the provided certificate is in. PEM,
|
||||
DER and ENG are recognized types.
|
||||
DER and ENG are recognized types. If not specified, PEM is assumed.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--cacert <CA certificate>"
|
||||
(HTTPS) Tells curl to use the specified certificate file to verify the
|
||||
(SSL) Tells curl to use the specified certificate file to verify the
|
||||
peer. The file may contain multiple CA certificates. The certificate(s) must
|
||||
be in PEM format.
|
||||
|
||||
@@ -344,10 +344,10 @@ Current Working Directory, or in any folder along your PATH.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--capath <CA certificate directory>"
|
||||
(HTTPS) Tells curl to use the specified certificate directory to verify the
|
||||
(SSL) Tells curl to use the specified certificate directory to verify the
|
||||
peer. The certificates must be in PEM format, and the directory must have been
|
||||
processed using the c_rehash utility supplied with openssl. Using
|
||||
\fI--capath\fP can allow curl to make https connections much more efficiently
|
||||
\fI--capath\fP can allow curl to make SSL-connections much more efficiently
|
||||
than using \fI--cacert\fP if the \fI--cacert\fP file contains many CA
|
||||
certificates.
|
||||
|
||||
@@ -359,6 +359,10 @@ normal cases when a HTTP server fails to deliver a document, it returns an
|
||||
HTML document stating so (which often also describes why and more). This flag
|
||||
will prevent curl from outputting that and return error 22.
|
||||
|
||||
This method is not fail-safe and there are occasions where non-succesful
|
||||
response codes will slip through, especially when authentication is involved
|
||||
(response codes 401 and 407).
|
||||
|
||||
If this option is used twice, the second will again disable silent failure.
|
||||
.IP "--ftp-account [data]"
|
||||
(FTP) When an FTP server asks for "account data" after user name and password
|
||||
@@ -395,7 +399,6 @@ in 7.11.0)
|
||||
|
||||
If this option is used several times, the following occurrences make no
|
||||
difference.
|
||||
|
||||
.IP "--ftp-alternative-to-user <command>"
|
||||
(FTP) If authenticating with the USER and PASS commands fails, send this
|
||||
command. When connecting to Tumbleweed's Secure Transport server over FTPS
|
||||
@@ -412,9 +415,16 @@ This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
|
||||
If this option is used twice, the second will again use the server's suggested
|
||||
address.
|
||||
.IP "--ftp-ssl"
|
||||
(FTP) Try to use SSL/TLS for the FTP connection.
|
||||
Reverts to a non-secure connection if the server doesn't support SSL/TLS.
|
||||
(Added in 7.11.0)
|
||||
(FTP) Try to use SSL/TLS for the FTP connection. Reverts to a non-secure
|
||||
connection if the server doesn't support SSL/TLS. See also
|
||||
\fI--ftp-ssl-control\fP and \fI--ftp-ssl-reqd\fP for different levels of
|
||||
encryption required. (Added in 7.11.0)
|
||||
|
||||
If this option is used twice, the second will again disable this.
|
||||
.IP "--ftp-ssl-control"
|
||||
(FTP) Require SSL/TLS for the ftp login, clear for transfer. Allows secure
|
||||
authentication, but non-encrypted data transfers for efficiency. Fails the
|
||||
transfer if the server doesn't support SSL/TLS. (Added in 7.16.0)
|
||||
|
||||
If this option is used twice, the second will again disable this.
|
||||
.IP "--ftp-ssl-reqd"
|
||||
@@ -422,6 +432,14 @@ If this option is used twice, the second will again disable this.
|
||||
Terminates the connection if the server doesn't support SSL/TLS.
|
||||
(Added in 7.15.5)
|
||||
|
||||
If this option is used twice, the second will again disable this.
|
||||
.IP "--ftp-ssl-ccc"
|
||||
(FTP) Use CCC (Clear Command Channel)
|
||||
Shuts down the SSL/TLS layer after authenticating. The rest of the
|
||||
control channel communication will be unencrypted. This allows
|
||||
NAT routers to follow the FTP transaction.
|
||||
(Added in 7.16.1)
|
||||
|
||||
If this option is used twice, the second will again disable this.
|
||||
.IP "-F/--form <name=content>"
|
||||
(HTTP) This lets curl emulate a filled in form in which a user has pressed the
|
||||
@@ -489,9 +507,9 @@ of extra headers. Note that if you should add a custom header that has the
|
||||
same name as one of the internal ones curl would use, your externally set
|
||||
header will be used instead of the internal one. This allows you to make even
|
||||
trickier stuff than curl would normally do. You should not replace internally
|
||||
set headers without knowing perfectly well what you're doing. Replacing an
|
||||
internal header with one without content on the right side of the colon will
|
||||
prevent that header from appearing.
|
||||
set headers without knowing perfectly well what you're doing. Remove an
|
||||
internal header by giving a replacement without content on the right side of
|
||||
the colon, as in: -H \&"Host:".
|
||||
|
||||
curl will make sure that each header you add/replace get sent with the proper
|
||||
end of line marker, you should thus \fBnot\fP add that as a part of the header
|
||||
@@ -540,6 +558,9 @@ and transfers. All SSL connections are attempted to be made secure by using
|
||||
the CA certificate bundle installed by default. This makes all connections
|
||||
considered "insecure" to fail unless \fI-k/--insecure\fP is used.
|
||||
|
||||
See this online resource for further details:
|
||||
\fBhttp://curl.haxx.se/docs/sslcerts.html\fP
|
||||
|
||||
If this option is used twice, the second time will again disable it.
|
||||
.IP "--key <key>"
|
||||
(SSL) Private key file name. Allows you to provide your private key in this
|
||||
@@ -548,7 +569,8 @@ separate file.
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--key-type <type>"
|
||||
(SSL) Private key file type. Specify which type your \fI--key\fP provided
|
||||
private key is. DER, PEM and ENG are supported.
|
||||
private key is. DER, PEM and ENG are supported. If not specified, PEM is
|
||||
assumed.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--krb4 <level>"
|
||||
@@ -577,7 +599,7 @@ line. So, it could look similar to this:
|
||||
|
||||
url = "http://curl.haxx.se/docs/"
|
||||
|
||||
This option can be used multiple times.
|
||||
This option can be used multiple times to load multiple config files.
|
||||
|
||||
When curl is invoked, it always (unless \fI-q\fP is used) checks for a default
|
||||
config file and uses it if found. The default config file is checked for in
|
||||
@@ -592,6 +614,12 @@ resort the '%USERPROFILE%\Application Data'.
|
||||
2) On windows, if there is no _curlrc file in the home dir, it checks for one
|
||||
in the same dir the executable curl is placed. On unix-like systems, it will
|
||||
simply try to load .curlrc from the determined home dir.
|
||||
.IP "--libcurl <file>"
|
||||
Append this option to any ordinary curl command line, and you will get a
|
||||
libcurl-using source code written to the file that does the equivalent
|
||||
operation of what your command line operation does!
|
||||
|
||||
If this option is used several times, the last given file name will be used.
|
||||
.IP "--limit-rate <speed>"
|
||||
Specify the maximum transfer rate you want curl to use. This feature is useful
|
||||
if you have a limited pipe and you'd like your transfer not use your entire
|
||||
@@ -601,6 +629,10 @@ The given speed is measured in bytes/second, unless a suffix is appended.
|
||||
Appending 'k' or 'K' will count the number as kilobytes, 'm' or M' makes it
|
||||
megabytes while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G.
|
||||
|
||||
The given rate is the average speed, counted during the entire transfer. It
|
||||
means that curl might use higher transfer speeds in short bursts, but over
|
||||
time it uses no more than the given rate.
|
||||
|
||||
If you are also using the \fI-Y/--speed-limit\fP option, that option will take
|
||||
precedence and might cripple the rate-limiting slightly, to help keeping the
|
||||
speed-limit logic working.
|
||||
@@ -705,6 +737,15 @@ will output the data in chunks, not necessarily exactly when the data arrives.
|
||||
Using this option will disable that buffering.
|
||||
|
||||
If this option is used twice, the second will again switch on buffering.
|
||||
.IP "--no-sessionid"
|
||||
(SSL) Disable curl's use of SSL session-ID caching. By default all transfers
|
||||
are done using the cache. Note that while nothing ever should get hurt by
|
||||
attempting to reuse SSL session-IDs, there seem to be broken SSL
|
||||
implementations in the wild that may require you to disable this in order for
|
||||
you to succeed. (Added in 7.16.0)
|
||||
|
||||
If this option is used twice, the second will again switch on use of the
|
||||
session cache.
|
||||
.IP "--ntlm"
|
||||
(HTTP) Enables NTLM authentication. The NTLM authentication method was
|
||||
designed by Microsoft and is used by IIS web servers. It is a proprietary
|
||||
@@ -818,7 +859,7 @@ must send syntactically correct FTP commands as RFC959 defines.
|
||||
|
||||
This option can be used multiple times.
|
||||
.IP "--random-file <file>"
|
||||
(HTTPS) Specify the path name to file containing what will be considered as
|
||||
(SSL) Specify the path name to file containing what will be considered as
|
||||
random data. The data is used to seed the random engine for SSL connections.
|
||||
See also the \fI--egd-file\fP option.
|
||||
.IP "-r/--range <range>"
|
||||
@@ -1196,7 +1237,7 @@ not set.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-z/--time-cond <date expression>"
|
||||
(HTTP) Request a file that has been modified later than the given time and
|
||||
(HTTP/FTP) Request a file that has been modified later than the given time and
|
||||
date, or one that has been modified before that time. The date expression can
|
||||
be all sorts of date strings or if it doesn't match any internal ones, it
|
||||
tries to get the time from a given file name instead! See the
|
||||
@@ -1218,25 +1259,14 @@ If this option is used several times, the last one will be used.
|
||||
(HTTP) Forces curl to issue its requests using HTTP 1.0 instead of using its
|
||||
internally preferred: HTTP 1.1.
|
||||
.IP "-1/--tlsv1"
|
||||
(HTTPS)
|
||||
(SSL)
|
||||
Forces curl to use TSL version 1 when negotiating with a remote TLS server.
|
||||
.IP "-2/--sslv2"
|
||||
(HTTPS)
|
||||
(SSL)
|
||||
Forces curl to use SSL version 2 when negotiating with a remote SSL server.
|
||||
.IP "-3/--sslv3"
|
||||
(HTTPS)
|
||||
(SSL)
|
||||
Forces curl to use SSL version 3 when negotiating with a remote SSL server.
|
||||
.IP "--3p-quote"
|
||||
(FTP) Specify arbitrary commands to send to the source server. See the
|
||||
\fI-Q/--quote\fP option for details. (Added in 7.13.0)
|
||||
.IP "--3p-url"
|
||||
(FTP) Activates a FTP 3rd party transfer. Specifies the source URL to get a
|
||||
file from, while the "normal" URL will be used as target URL, the file that
|
||||
will be written/created.
|
||||
|
||||
Note that not all FTP server allow 3rd party transfers. (Added in 7.13.0)
|
||||
.IP "--3p-user"
|
||||
(FTP) Specify user:password for the source URL transfer. (Added in 7.13.0)
|
||||
.IP "-4/--ipv4"
|
||||
If libcurl is capable of resolving an address to multiple IP versions (which
|
||||
it is if it is ipv6-capable), this option tells libcurl to resolve names to
|
||||
|
166
docs/examples/10-at-a-time.c
Normal file
166
docs/examples/10-at-a-time.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Example application source code using the multi interface to download many
|
||||
* files, but with a capped maximum amount of simultaneous transfers.
|
||||
*
|
||||
* Written by Michael Wallner
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <curl/multi.h>
|
||||
|
||||
static const char *urls[] = {
|
||||
"http://www.microsoft.com",
|
||||
"http://www.opensource.org",
|
||||
"http://www.google.com",
|
||||
"http://www.yahoo.com",
|
||||
"http://www.ibm.com",
|
||||
"http://www.mysql.com",
|
||||
"http://www.oracle.com",
|
||||
"http://www.ripe.net",
|
||||
"http://www.iana.org",
|
||||
"http://www.amazon.com",
|
||||
"http://www.netcraft.com",
|
||||
"http://www.heise.de",
|
||||
"http://www.chip.de",
|
||||
"http://www.ca.com",
|
||||
"http://www.cnet.com",
|
||||
"http://www.news.com",
|
||||
"http://www.cnn.com",
|
||||
"http://www.wikipedia.org",
|
||||
"http://www.dell.com",
|
||||
"http://www.hp.com",
|
||||
"http://www.cert.org",
|
||||
"http://www.mit.edu",
|
||||
"http://www.nist.gov",
|
||||
"http://www.ebay.com",
|
||||
"http://www.playstation.com",
|
||||
"http://www.uefa.com",
|
||||
"http://www.ieee.org",
|
||||
"http://www.apple.com",
|
||||
"http://www.sony.com",
|
||||
"http://www.symantec.com",
|
||||
"http://www.zdnet.com",
|
||||
"http://www.fujitsu.com",
|
||||
"http://www.supermicro.com",
|
||||
"http://www.hotmail.com",
|
||||
"http://www.ecma.com",
|
||||
"http://www.bbc.co.uk",
|
||||
"http://news.google.com",
|
||||
"http://www.foxnews.com",
|
||||
"http://www.msn.com",
|
||||
"http://www.wired.com",
|
||||
"http://www.sky.com",
|
||||
"http://www.usatoday.com",
|
||||
"http://www.cbs.com",
|
||||
"http://www.nbc.com",
|
||||
"http://slashdot.org",
|
||||
"http://www.bloglines.com",
|
||||
"http://www.techweb.com",
|
||||
"http://www.newslink.org",
|
||||
"http://www.un.org",
|
||||
};
|
||||
|
||||
#define MAX 10 /* number of simultaneous transfers */
|
||||
#define CNT sizeof(urls)/sizeof(char*) /* total number of transfers to do */
|
||||
|
||||
static int cb(char *d, size_t n, size_t l, void *p)
|
||||
{
|
||||
/* take care of the data here, ignored in this example */
|
||||
(void)d;
|
||||
(void)p;
|
||||
return n*l;
|
||||
}
|
||||
|
||||
static void init(CURLM *cm, int i)
|
||||
{
|
||||
CURL *eh = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, cb);
|
||||
curl_easy_setopt(eh, CURLOPT_HEADER, 0);
|
||||
curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
|
||||
curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
|
||||
curl_easy_setopt(eh, CURLOPT_VERBOSE, 0);
|
||||
|
||||
curl_multi_add_handle(cm, eh);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURLM *cm;
|
||||
CURLMsg *msg;
|
||||
long L;
|
||||
unsigned int C=0;
|
||||
int M, Q, U = -1;
|
||||
fd_set R, W, E;
|
||||
struct timeval T;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
cm = curl_multi_init();
|
||||
|
||||
for (C = 0; C < MAX; ++C) {
|
||||
init(cm, C);
|
||||
}
|
||||
|
||||
while (U) {
|
||||
while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(cm, &U));
|
||||
|
||||
if (U) {
|
||||
FD_ZERO(&R);
|
||||
FD_ZERO(&W);
|
||||
FD_ZERO(&E);
|
||||
|
||||
if (curl_multi_fdset(cm, &R, &W, &E, &M)) {
|
||||
fprintf(stderr, "E: curl_multi_fdset\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* In a real-world program you OF COURSE check the return that maxfd is
|
||||
bigger than -1 so that the call to select() below makes sense! */
|
||||
|
||||
if (curl_multi_timeout(cm, &L)) {
|
||||
fprintf(stderr, "E: curl_multi_timeout\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
T.tv_sec = L/1000;
|
||||
T.tv_usec = (L%1000)*1000;
|
||||
|
||||
if (0 > select(M+1, &R, &W, &E, &T)) {
|
||||
fprintf(stderr, "E: select\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
while ((msg = curl_multi_info_read(cm, &Q))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
char *url;
|
||||
CURL *e = msg->easy_handle;
|
||||
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
|
||||
fprintf(stderr, "R: %d - %s <%s>\n",
|
||||
msg->data.result, curl_easy_strerror(msg->data.result), url);
|
||||
curl_multi_remove_handle(cm, e);
|
||||
curl_easy_cleanup(e);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
|
||||
}
|
||||
if (C < CNT) {
|
||||
init(cm, C++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(cm);
|
||||
curl_global_cleanup();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@@ -11,7 +11,8 @@ EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \
|
||||
multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \
|
||||
multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c debug.c \
|
||||
anyauthput.c htmltitle.cc htmltidy.c opensslthreadlock.c \
|
||||
cookie_interface.c cacertinmem.c synctime.c sampleconv.c ftpuploadresume.c
|
||||
cookie_interface.c cacertinmem.c synctime.c sampleconv.c ftpuploadresume.c \
|
||||
10-at-a-time.c hiperfifo.c ghiper.c
|
||||
|
||||
all:
|
||||
@echo "done"
|
||||
|
@@ -26,9 +26,9 @@ want you do reorganize them like:
|
||||
$ `curl-config --cc` -o example example.c `curl-config --cflags --libs`
|
||||
|
||||
*PLEASE* do not use the curl.haxx.se site as a test target for your libcurl
|
||||
applications/experiments. Even if the examples in this directory use that site
|
||||
as an example URL at some places, it doesn't mean that the URLs work or that
|
||||
we expect you to actually torture our web site with your tests! Thanks.
|
||||
applications/experiments. Even if some of the examples use that site as a URL
|
||||
at some places, it doesn't mean that the URLs work or that we expect you to
|
||||
actually torture our web site with your tests! Thanks.
|
||||
|
||||
EXAMPLES
|
||||
|
||||
@@ -43,9 +43,13 @@ fopen.c - fopen() layer that supports opening URLs and files
|
||||
ftp3rdparty.c - FTP 3rd party transfer
|
||||
ftpget.c - simple getting a file from FTP
|
||||
ftpgetresp.c - get the response strings from the FTP server
|
||||
ftpupload.c - upload a file to a FTP server
|
||||
ftpupload.c - upload a file to an FTP server
|
||||
ftpuploadresume.c - resume an upload to an FTP server
|
||||
getinfo.c - get the Content-Type from the recent transfer
|
||||
getinmemory.c - download a file to memory only
|
||||
ghiper.c - curl_multi_socket() using code with glib-2
|
||||
hiperfifo.c - downloads all URLs written to the fifo, using
|
||||
curl_multi_socket() and libevent
|
||||
htmltitle.cc - download a HTML file and extract the <title> tag from a HTML
|
||||
page using libxml
|
||||
http-post.c - HTTP POST
|
||||
@@ -61,8 +65,12 @@ opensslthreadlock.c - show how to do locking when using OpenSSL multi-threaded
|
||||
persistant.c - request two URLs with a persistant connection
|
||||
post-callback.c - send a HTTP POST using a callback
|
||||
postit2.c - send a HTTP multipart formpost
|
||||
sampleconv.c - showing how a program on a non-ASCII platform would invoke
|
||||
callbacks to do its own codeset conversions instead of using
|
||||
the built-in iconv functions in libcurl
|
||||
sepheaders.c - download headers to a separate file
|
||||
simple.c - the most simple download a URL source
|
||||
simplepost.c - HTTP POST
|
||||
simplessl.c - HTTPS example with certificates many options set
|
||||
synctime.c - Sync local time by extracing date from remote HTTP servers
|
||||
10-at-a-time.c - Download many files simultaneously, 10 at a time.
|
||||
|
@@ -114,6 +114,13 @@ static char *curlx_usage[]={
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* We use this ZERO_NULL to avoid picky compiler warnings,
|
||||
* when assigning a NULL pointer to a function pointer var.
|
||||
*/
|
||||
|
||||
#define ZERO_NULL 0
|
||||
|
||||
/* This is a context that we pass to all callbacks */
|
||||
|
||||
typedef struct sslctxparm_st {
|
||||
@@ -236,7 +243,7 @@ static CURLcode sslctxfun(CURL * curl, void * sslctx, void * parm) {
|
||||
|
||||
SSL_CTX_set_verify_depth(ctx,2);
|
||||
|
||||
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);
|
||||
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,ZERO_NULL);
|
||||
|
||||
SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback, parm);
|
||||
|
||||
|
@@ -84,6 +84,9 @@ int my_trace(CURL *handle, curl_infotype type,
|
||||
case CURLINFO_DATA_OUT:
|
||||
text = "=> Send data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_OUT:
|
||||
text = "=> Send SSL data";
|
||||
break;
|
||||
case CURLINFO_HEADER_IN:
|
||||
text = "<= Recv header";
|
||||
break;
|
||||
@@ -93,9 +96,6 @@ int my_trace(CURL *handle, curl_infotype type,
|
||||
case CURLINFO_SSL_DATA_IN:
|
||||
text = "<= Recv SSL data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_OUT:
|
||||
text = "<= Send SSL data";
|
||||
break;
|
||||
}
|
||||
|
||||
dump(text, stderr, data, size, config->trace_ascii);
|
||||
|
@@ -153,6 +153,10 @@ fill_buffer(URL_FILE *file,int want,int waittime)
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls, *and* you make sure that maxfd is bigger than -1
|
||||
so that the call to select() below makes sense! */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
|
461
docs/examples/ghiper.c
Normal file
461
docs/examples/ghiper.c
Normal file
@@ -0,0 +1,461 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Example application source code using the multi socket interface to
|
||||
* download many files at once.
|
||||
*
|
||||
* Written by Jeff Pohlmeyer
|
||||
|
||||
Requires glib-2.x and a (POSIX?) system that has mkfifo().
|
||||
|
||||
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
|
||||
sample programs, adapted to use glib's g_io_channel in place of libevent.
|
||||
|
||||
When running, the program creates the named pipe "hiper.fifo"
|
||||
|
||||
Whenever there is input into the fifo, the program reads the input as a list
|
||||
of URL's and creates some new easy handles to fetch each URL via the
|
||||
curl_multi "hiper" API.
|
||||
|
||||
|
||||
Thus, you can try a single URL:
|
||||
% echo http://www.yahoo.com > hiper.fifo
|
||||
|
||||
Or a whole bunch of them:
|
||||
% cat my-url-list > hiper.fifo
|
||||
|
||||
The fifo buffer is handled almost instantly, so you can even add more URL's
|
||||
while the previous requests are still being downloaded.
|
||||
|
||||
This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
callback.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <glib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
#define MSG_OUT g_print /* Change to "g_error" to write to stderr */
|
||||
#define SHOW_VERBOSE 0 /* Set to non-zero for libcurl messages */
|
||||
#define SHOW_PROGRESS 0 /* Set to non-zero to enable progress callback */
|
||||
|
||||
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo {
|
||||
CURLM *multi;
|
||||
guint timer_event;
|
||||
int prev_running;
|
||||
int still_running;
|
||||
int requested; /* count: curl_easy_init() */
|
||||
int completed; /* count: curl_easy_cleanup() */
|
||||
} GlobalInfo;
|
||||
|
||||
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo {
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific socket */
|
||||
typedef struct _SockInfo {
|
||||
curl_socket_t sockfd;
|
||||
CURL *easy;
|
||||
int action;
|
||||
long timeout;
|
||||
GIOChannel *ch;
|
||||
guint ev;
|
||||
GlobalInfo *global;
|
||||
} SockInfo;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(char *where, CURLMcode code) {
|
||||
if ( CURLM_OK != code ) {
|
||||
char *s;
|
||||
switch (code) {
|
||||
case CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break;
|
||||
case CURLM_OK: s="CURLM_OK"; break;
|
||||
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
|
||||
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
|
||||
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
|
||||
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
|
||||
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET"; break;
|
||||
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
|
||||
case CURLM_LAST: s="CURLM_LAST"; break;
|
||||
default: s="CURLM_unknown";
|
||||
}
|
||||
MSG_OUT("ERROR: %s returns %s\n", where, s);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_run_count(GlobalInfo *g)
|
||||
{
|
||||
if (g->prev_running > g->still_running) {
|
||||
char *eff_url=NULL;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn=NULL;
|
||||
CURL*easy;
|
||||
CURLcode res;
|
||||
|
||||
MSG_OUT("REMAINING: %d\n", g->still_running);
|
||||
/*
|
||||
I am still uncertain whether it is safe to remove an easy handle
|
||||
from inside the curl_multi_info_read loop, so here I will search
|
||||
for completed transfers in the inner "while" loop, and then remove
|
||||
them in the outer "do-while" loop...
|
||||
*/
|
||||
do {
|
||||
easy=NULL;
|
||||
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
easy=msg->easy_handle;
|
||||
res=msg->data.result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (easy) {
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
MSG_OUT("DONE: %s => (%d) %s\n", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
g_free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
g_free(conn);
|
||||
g->completed++;
|
||||
}
|
||||
} while ( easy );
|
||||
MSG_OUT("Requested: %d Completed:%d\n", g->requested, g->completed);
|
||||
}
|
||||
g->prev_running = g->still_running;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Called by glib when our timeout expires */
|
||||
static gboolean timer_cb(gpointer data)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo *)data;
|
||||
CURLMcode rc;
|
||||
|
||||
do {
|
||||
rc = curl_multi_socket(g->multi, CURL_SOCKET_TIMEOUT, &g->still_running);
|
||||
} while (rc == CURLM_CALL_MULTI_PERFORM);
|
||||
mcode_or_die("timer_cb: curl_multi_socket", rc);
|
||||
check_run_count(g);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp)
|
||||
{
|
||||
struct timeval timeout;
|
||||
GlobalInfo *g=(GlobalInfo *)userp;
|
||||
timeout.tv_sec = timeout_ms/1000;
|
||||
timeout.tv_usec = (timeout_ms%1000)*1000;
|
||||
|
||||
MSG_OUT("*** update_timeout_cb %ld => %ld:%ld ***\n",
|
||||
timeout_ms, timeout.tv_sec, timeout.tv_usec);
|
||||
|
||||
g->timer_event = g_timeout_add(timeout_ms, timer_cb, g);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Called by glib when we get action on a multi socket */
|
||||
static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) data;
|
||||
CURLMcode rc;
|
||||
int fd=g_io_channel_unix_get_fd(ch);
|
||||
do {
|
||||
rc = curl_multi_socket(g->multi, fd, &g->still_running);
|
||||
} while (rc == CURLM_CALL_MULTI_PERFORM);
|
||||
mcode_or_die("event_cb: curl_multi_socket", rc);
|
||||
check_run_count(g);
|
||||
if(g->still_running) {
|
||||
return TRUE;
|
||||
} else {
|
||||
MSG_OUT("last transfer done, kill timeout\n");
|
||||
if (g->timer_event) { g_source_remove(g->timer_event); }
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(SockInfo *f)
|
||||
{
|
||||
if (!f) { return; }
|
||||
if (f->ev) { g_source_remove(f->ev); }
|
||||
g_free(f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Assign information to a SockInfo structure */
|
||||
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
|
||||
{
|
||||
GIOCondition kind =
|
||||
(act&CURL_POLL_IN?G_IO_IN:0)|(act&CURL_POLL_OUT?G_IO_OUT:0);
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
f->easy = e;
|
||||
if (f->ev) { g_source_remove(f->ev); }
|
||||
f->ev=g_io_add_watch(f->ch, kind, event_cb,g);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize a new SockInfo structure */
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
|
||||
{
|
||||
SockInfo *fdp = g_malloc0(sizeof(SockInfo));
|
||||
|
||||
fdp->global = g;
|
||||
fdp->ch=g_io_channel_unix_new(s);
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
SockInfo *fdp = (SockInfo*) sockp;
|
||||
char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
|
||||
|
||||
MSG_OUT("socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
if (what == CURL_POLL_REMOVE) {
|
||||
MSG_OUT("\n");
|
||||
remsock(fdp);
|
||||
} else {
|
||||
if (!fdp) {
|
||||
MSG_OUT("Adding data: %s%s\n",
|
||||
what&CURL_POLL_IN?"READ":"",
|
||||
what&CURL_POLL_OUT?"WRITE":"" );
|
||||
addsock(s, e, what, g);
|
||||
}
|
||||
else {
|
||||
MSG_OUT(
|
||||
"Changing action from %d to %d\n", fdp->action, what);
|
||||
setsock(fdp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
ConnInfo *conn = (ConnInfo*) data;
|
||||
(void)ptr;
|
||||
(void)conn;
|
||||
return realsize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
static int prog_cb (void *p, double dltotal, double dlnow, double ult, double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
MSG_OUT("Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
static void new_conn(char *url, GlobalInfo *g )
|
||||
{
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = g_malloc0(sizeof(ConnInfo));
|
||||
|
||||
conn->error[0]='\0';
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
if (!conn->easy) {
|
||||
MSG_OUT("curl_easy_init() failed, exiting!\n");
|
||||
exit(2);
|
||||
}
|
||||
conn->global = g;
|
||||
conn->url = g_strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, SHOW_VERBOSE);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, SHOW_PROGRESS?0:1);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_CONNECTTIMEOUT, 30);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 1);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30);
|
||||
|
||||
MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc =curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
g->requested++;
|
||||
do {
|
||||
rc = curl_multi_socket_all(g->multi, &g->still_running);
|
||||
} while (CURLM_CALL_MULTI_PERFORM == rc);
|
||||
mcode_or_die("new_conn: curl_multi_socket_all", rc);
|
||||
check_run_count(g);
|
||||
}
|
||||
|
||||
|
||||
/* This gets called by glib whenever data is received from the fifo */
|
||||
static gboolean fifo_cb (GIOChannel *ch, GIOCondition condition, gpointer data)
|
||||
{
|
||||
#define BUF_SIZE 1024
|
||||
gsize len, tp;
|
||||
gchar *buf, *tmp, *all=NULL;
|
||||
GIOStatus rv;
|
||||
|
||||
do {
|
||||
GError *err=NULL;
|
||||
rv = g_io_channel_read_line (ch,&buf,&len,&tp,&err);
|
||||
if ( buf ) {
|
||||
if (tp) { buf[tp]='\0'; }
|
||||
new_conn(buf,(GlobalInfo*)data);
|
||||
g_free(buf);
|
||||
} else {
|
||||
buf = g_malloc(BUF_SIZE+1);
|
||||
while (TRUE) {
|
||||
buf[BUF_SIZE]='\0';
|
||||
g_io_channel_read_chars(ch,buf,BUF_SIZE,&len,&err);
|
||||
if (len) {
|
||||
buf[len]='\0';
|
||||
if (all) {
|
||||
tmp=all;
|
||||
all=g_strdup_printf("%s%s", tmp, buf);
|
||||
g_free(tmp);
|
||||
} else {
|
||||
all = g_strdup(buf);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (all) {
|
||||
new_conn(all,(GlobalInfo*)data);
|
||||
g_free(all);
|
||||
}
|
||||
g_free(buf);
|
||||
}
|
||||
if ( err ) {
|
||||
g_error("fifo_cb: %s", err->message);
|
||||
g_free(err);
|
||||
break;
|
||||
}
|
||||
} while ( (len) && (rv == G_IO_STATUS_NORMAL) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int init_fifo(void)
|
||||
{
|
||||
struct stat st;
|
||||
char *fifo = "hiper.fifo";
|
||||
int socket;
|
||||
|
||||
if (lstat (fifo, &st) == 0) {
|
||||
if ((st.st_mode & S_IFMT) == S_IFREG) {
|
||||
errno = EEXIST;
|
||||
perror("lstat");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
unlink (fifo);
|
||||
if (mkfifo (fifo, 0600) == -1) {
|
||||
perror("mkfifo");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
socket = open (fifo, O_RDWR | O_NONBLOCK, 0);
|
||||
|
||||
if (socket == -1) {
|
||||
perror("open");
|
||||
exit (1);
|
||||
}
|
||||
MSG_OUT("Now, pipe some URL's into > %s\n", fifo);
|
||||
|
||||
return socket;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo *g;
|
||||
CURLMcode rc;
|
||||
GMainLoop*gmain;
|
||||
int fd;
|
||||
GIOChannel* ch;
|
||||
g=g_malloc0(sizeof(GlobalInfo));
|
||||
|
||||
fd=init_fifo();
|
||||
ch=g_io_channel_unix_new(fd);
|
||||
g_io_add_watch(ch,G_IO_IN,fifo_cb,g);
|
||||
gmain=g_main_loop_new(NULL,FALSE);
|
||||
g->multi = curl_multi_init();
|
||||
curl_multi_setopt(g->multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g->multi, CURLMOPT_SOCKETDATA, g);
|
||||
curl_multi_setopt(g->multi, CURLMOPT_TIMERFUNCTION, update_timeout_cb);
|
||||
curl_multi_setopt(g->multi, CURLMOPT_TIMERDATA, g);
|
||||
do {
|
||||
rc = curl_multi_socket_all(g->multi, &g->still_running);
|
||||
} while (CURLM_CALL_MULTI_PERFORM == rc);
|
||||
g_main_loop_run(gmain);
|
||||
curl_multi_cleanup(g->multi);
|
||||
return 0;
|
||||
}
|
416
docs/examples/hiperfifo.c
Normal file
416
docs/examples/hiperfifo.c
Normal file
@@ -0,0 +1,416 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Example application source code using the multi socket interface to
|
||||
* download many files at once.
|
||||
*
|
||||
* Written by Jeff Pohlmeyer
|
||||
|
||||
Requires libevent and a (POSIX?) system that has mkfifo().
|
||||
|
||||
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
|
||||
sample programs.
|
||||
|
||||
When running, the program creates the named pipe "hiper.fifo"
|
||||
|
||||
Whenever there is input into the fifo, the program reads the input as a list
|
||||
of URL's and creates some new easy handles to fetch each URL via the
|
||||
curl_multi "hiper" API.
|
||||
|
||||
|
||||
Thus, you can try a single URL:
|
||||
% echo http://www.yahoo.com > hiper.fifo
|
||||
|
||||
Or a whole bunch of them:
|
||||
% cat my-url-list > hiper.fifo
|
||||
|
||||
The fifo buffer is handled almost instantly, so you can even add more URL's
|
||||
while the previous requests are still being downloaded.
|
||||
|
||||
Note:
|
||||
For the sake of simplicity, URL length is limited to 1023 char's !
|
||||
|
||||
This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
callback.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/poll.h>
|
||||
#include <curl/curl.h>
|
||||
#include <event.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
|
||||
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo {
|
||||
struct event fifo_event;
|
||||
struct event timer_event;
|
||||
CURLM *multi;
|
||||
int prev_running;
|
||||
int still_running;
|
||||
FILE* input;
|
||||
} GlobalInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo {
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific socket */
|
||||
typedef struct _SockInfo {
|
||||
curl_socket_t sockfd;
|
||||
CURL *easy;
|
||||
int action;
|
||||
long timeout;
|
||||
struct event ev;
|
||||
int evset;
|
||||
GlobalInfo *global;
|
||||
} SockInfo;
|
||||
|
||||
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static void update_timeout(GlobalInfo *g)
|
||||
{
|
||||
long timeout_ms;
|
||||
struct timeval timeout;
|
||||
|
||||
curl_multi_timeout(g->multi, &timeout_ms);
|
||||
if(timeout_ms < 0)
|
||||
return;
|
||||
|
||||
timeout.tv_sec = timeout_ms/1000;
|
||||
timeout.tv_usec = (timeout_ms%1000)*1000;
|
||||
evtimer_add(&g->timer_event, &timeout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
void mcode_or_die(char *where, CURLMcode code) {
|
||||
if ( CURLM_OK != code ) {
|
||||
char *s;
|
||||
switch (code) {
|
||||
case CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break;
|
||||
case CURLM_OK: s="CURLM_OK"; break;
|
||||
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
|
||||
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
|
||||
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
|
||||
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
|
||||
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET"; break;
|
||||
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
|
||||
case CURLM_LAST: s="CURLM_LAST"; break;
|
||||
default: s="CURLM_unknown";
|
||||
}
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_run_count(GlobalInfo *g)
|
||||
{
|
||||
if (g->prev_running > g->still_running) {
|
||||
char *eff_url=NULL;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn=NULL;
|
||||
CURL*easy;
|
||||
CURLcode res;
|
||||
|
||||
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
|
||||
/*
|
||||
I am still uncertain whether it is safe to remove an easy handle
|
||||
from inside the curl_multi_info_read loop, so here I will search
|
||||
for completed transfers in the inner "while" loop, and then remove
|
||||
them in the outer "do-while" loop...
|
||||
*/
|
||||
do {
|
||||
easy=NULL;
|
||||
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
easy=msg->easy_handle;
|
||||
res=msg->data.result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (easy) {
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
free(conn);
|
||||
}
|
||||
} while ( easy );
|
||||
}
|
||||
g->prev_running = g->still_running;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by libevent when we get action on a multi socket */
|
||||
static void event_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) userp;
|
||||
CURLMcode rc;
|
||||
|
||||
do {
|
||||
rc = curl_multi_socket(g->multi, fd, &g->still_running);
|
||||
} while (rc == CURLM_CALL_MULTI_PERFORM);
|
||||
mcode_or_die("event_cb: curl_multi_socket", rc);
|
||||
check_run_count(g);
|
||||
if(g->still_running) {
|
||||
update_timeout(g);
|
||||
} else {
|
||||
fprintf(MSG_OUT, "last transfer done, kill timeout\n");
|
||||
if (evtimer_pending(&g->timer_event, NULL)) {
|
||||
evtimer_del(&g->timer_event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by libevent when our timeout expires */
|
||||
static void timer_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
(void)fd;
|
||||
(void)kind;
|
||||
GlobalInfo *g = (GlobalInfo *)userp;
|
||||
CURLMcode rc;
|
||||
|
||||
do {
|
||||
rc = curl_multi_socket(g->multi, CURL_SOCKET_TIMEOUT, &g->still_running);
|
||||
} while (rc == CURLM_CALL_MULTI_PERFORM);
|
||||
mcode_or_die("timer_cb: curl_multi_socket", rc);
|
||||
check_run_count(g);
|
||||
if ( g->still_running ) { update_timeout(g); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(SockInfo *f)
|
||||
{
|
||||
if (!f) { return; }
|
||||
if (f->evset) { event_del(&f->ev); }
|
||||
free(f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Assign information to a SockInfo structure */
|
||||
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
|
||||
{
|
||||
int kind =
|
||||
(act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0)|EV_PERSIST;
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
f->easy = e;
|
||||
if (f->evset) { event_del(&f->ev); }
|
||||
event_set( &f->ev, f->sockfd, kind, event_cb, g);
|
||||
f->evset=1;
|
||||
event_add(&f->ev, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize a new SockInfo structure */
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) {
|
||||
SockInfo *fdp = calloc(sizeof(SockInfo), 1);
|
||||
|
||||
fdp->global = g;
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
SockInfo *fdp = (SockInfo*) sockp;
|
||||
char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
if (what == CURL_POLL_REMOVE) {
|
||||
fprintf(MSG_OUT, "\n");
|
||||
remsock(fdp);
|
||||
} else {
|
||||
if (!fdp) {
|
||||
fprintf(MSG_OUT, "Adding data: %s%s\n",
|
||||
what&CURL_POLL_IN?"READ":"",
|
||||
what&CURL_POLL_OUT?"WRITE":"" );
|
||||
addsock(s, e, what, g);
|
||||
}
|
||||
else {
|
||||
fprintf(MSG_OUT,
|
||||
"Changing action from %d to %d\n", fdp->action, what);
|
||||
setsock(fdp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
ConnInfo *conn = (ConnInfo*) data;
|
||||
(void)ptr;
|
||||
(void)conn;
|
||||
return realsize;
|
||||
}
|
||||
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
int prog_cb (void *p, double dltotal, double dlnow, double ult, double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
void new_conn(char *url, GlobalInfo *g ) {
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = calloc(1, sizeof(ConnInfo));
|
||||
memset(conn, 0, sizeof(ConnInfo));
|
||||
conn->error[0]='\0';
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
if (!conn->easy) {
|
||||
fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
|
||||
exit(2);
|
||||
}
|
||||
conn->global = g;
|
||||
conn->url = strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 0);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
fprintf(MSG_OUT,
|
||||
"Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc =curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
do {
|
||||
rc = curl_multi_socket_all(g->multi, &g->still_running);
|
||||
} while (CURLM_CALL_MULTI_PERFORM == rc);
|
||||
mcode_or_die("new_conn: curl_multi_socket_all", rc);
|
||||
check_run_count(g);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This gets called whenever data is received from the fifo */
|
||||
void fifo_cb(int fd, short event, void *arg) {
|
||||
char s[1024];
|
||||
long int rv=0;
|
||||
int n=0;
|
||||
GlobalInfo *g = (GlobalInfo *)arg;
|
||||
|
||||
do {
|
||||
s[0]='\0';
|
||||
rv=fscanf(g->input, "%1023s%n", s, &n);
|
||||
s[n]='\0';
|
||||
if ( n && s[0] ) {
|
||||
new_conn(s,arg); /* if we read a URL, go get it! */
|
||||
} else break;
|
||||
} while ( rv != EOF);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Create a named pipe and tell libevent to monitor it */
|
||||
int init_fifo (GlobalInfo *g) {
|
||||
struct stat st;
|
||||
char *fifo = "hiper.fifo";
|
||||
int socket;
|
||||
|
||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||
if (lstat (fifo, &st) == 0) {
|
||||
if ((st.st_mode & S_IFMT) == S_IFREG) {
|
||||
errno = EEXIST;
|
||||
perror("lstat");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
unlink(fifo);
|
||||
if (mkfifo (fifo, 0600) == -1) {
|
||||
perror("mkfifo");
|
||||
exit (1);
|
||||
}
|
||||
socket = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||
if (socket == -1) {
|
||||
perror("open");
|
||||
exit (1);
|
||||
}
|
||||
g->input = fdopen(socket, "r");
|
||||
|
||||
fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo);
|
||||
event_set(&g->fifo_event, socket, EV_READ | EV_PERSIST, fifo_cb, g);
|
||||
event_add(&g->fifo_event, NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo g;
|
||||
CURLMcode rc;
|
||||
|
||||
memset(&g, 0, sizeof(GlobalInfo));
|
||||
event_init();
|
||||
init_fifo(&g);
|
||||
g.multi = curl_multi_init();
|
||||
evtimer_set(&g.timer_event, timer_cb, &g);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
|
||||
do {
|
||||
rc = curl_multi_socket_all(g.multi, &g.still_running);
|
||||
} while (CURLM_CALL_MULTI_PERFORM == rc);
|
||||
update_timeout(&g);
|
||||
event_dispatch();
|
||||
curl_multi_cleanup(g.multi);
|
||||
return 0;
|
||||
}
|
@@ -15,13 +15,13 @@ endif
|
||||
|
||||
LIBS += $(WATT32_ROOT)/lib/libwatt.a $(ZLIB_ROOT)/libz.a
|
||||
|
||||
PROGRAMS = fopen.exe ftpget.exe ftpgetresp.exe ftpupload.exe \
|
||||
getinmemory.exe http-post.exe httpput.exe multi-app.exe \
|
||||
multi-double.exe multi-post.exe multi-single.exe \
|
||||
persistant.exe post-callback.exe postit2.exe \
|
||||
sepheaders.exe simple.exe simplessl.exe https.exe \
|
||||
ftp3rdparty.exe getinfo.exe anyauthput.exe \
|
||||
cookie_interface.exe
|
||||
CSOURCES = fopen.c ftpget.c ftpgetresp.c ftpupload.c getinmemory.c \
|
||||
http-post.c httpput.c multi-app.c multi-double.c multi-post.c \
|
||||
multi-single.c persistant.c post-callback.c postit2.c \
|
||||
sepheaders.c simple.c simplessl.c https.c ftp3rdparty.c \
|
||||
getinfo.c anyauthput.c cookie_interface.c 10-at-a-time.c
|
||||
|
||||
PROGRAMS = $(CSOURCES:.c=.exe)
|
||||
|
||||
all: $(PROGRAMS)
|
||||
|
||||
@@ -32,3 +32,5 @@ all: $(PROGRAMS)
|
||||
clean:
|
||||
rm -f $(PROGRAMS)
|
||||
|
||||
# DO NOT DELETE THIS LINE
|
||||
|
||||
|
@@ -80,6 +80,10 @@ int main(int argc, char **argv)
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls, *and* you make sure that maxfd is bigger than -1 so
|
||||
that the call to select() below makes sense! */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
|
@@ -153,6 +153,10 @@ int main(int argc, char **argv)
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls, *and* you make sure that maxfd is bigger than -1
|
||||
so that the call to select() below makes sense! */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
|
@@ -71,6 +71,10 @@ int main(int argc, char **argv)
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls, *and* you make sure that maxfd is bigger than -1 so
|
||||
that the call to select() below makes sense! */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
|
@@ -93,6 +93,10 @@ int main(int argc, char *argv[])
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls, *and* you make sure that maxfd is bigger than -1
|
||||
so that the call to select() below makes sense! */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
|
@@ -65,6 +65,10 @@ int main(int argc, char **argv)
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
/* In a real-world program you OF COURSE check the return code of the
|
||||
function calls, *and* you make sure that maxfd is bigger than -1 so
|
||||
that the call to select() below makes sense! */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
@@ -41,9 +41,6 @@ int main(int argc, char **argv)
|
||||
/* no progress meter please */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
|
||||
|
||||
/* shut up completely */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_MUTE, 1);
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
|
||||
|
||||
|
@@ -9,6 +9,18 @@
|
||||
*
|
||||
* This example code only builds as-is on Windows.
|
||||
*
|
||||
* While Unix/Linux user, you do not need this software.
|
||||
* You can achieve the same result as synctime using curl, awk and date.
|
||||
* Set proxy as according to your network, but beware of proxy Cache-Control.
|
||||
*
|
||||
* To set your system clock, root access is required.
|
||||
* # date -s "`curl -sI http://nist.time.gov/timezone.cgi?UTC/s/0 \
|
||||
* | awk -F': ' '/Date: / {print $2}'`"
|
||||
*
|
||||
* To view remote webserver date and time.
|
||||
* $ curl -sI http://nist.time.gov/timezone.cgi?UTC/s/0 \
|
||||
* | awk -F': ' '/Date: / {print $2}'
|
||||
*
|
||||
* Synchronising your computer clock via Internet time server usually relies
|
||||
* on DAYTIME, TIME, or NTP protocols. These protocols provide good accurate
|
||||
* time synchronisation but it does not work very well through a
|
||||
@@ -300,10 +312,11 @@ int main(int argc, char *argv[])
|
||||
MthStr[LOCALTime.wMonth-1], LOCALTime.wYear,
|
||||
LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond,
|
||||
LOCALTime.wMilliseconds);
|
||||
fprintf(stderr, "\nBefore HTTP. Date: %s%s\n\n", timeBuf, tzoneBuf);
|
||||
|
||||
fprintf(stderr, "Fetch: %s\n\n", conf->timeserver);
|
||||
fprintf(stderr, "Before HTTP. Date: %s%s\n\n", timeBuf, tzoneBuf);
|
||||
|
||||
/* HTTP HEAD command to the Webserver */
|
||||
fprintf(stderr, "Fetch: %s\n", conf->timeserver);
|
||||
SyncTime_CURL_Fetch(curl, conf->timeserver, "index.htm",
|
||||
HTTP_COMMAND_HEAD);
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_easy_cleanup 3 "13 Nov 2002" "libcurl 7.7" "libcurl Manual"
|
||||
.TH curl_easy_cleanup 3 "12 Oct 2006" "libcurl 7.7" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_cleanup - End a libcurl easy session
|
||||
.SH SYNOPSIS
|
||||
@@ -21,6 +21,9 @@ more files.
|
||||
|
||||
When you've called this, you can safely remove all the strings you've
|
||||
previously told libcurl to use, as it won't use them anymore now.
|
||||
|
||||
Any uses of the \fBhandle\fP after this function has been called are
|
||||
illegal. This kills the handle and all memory associated with it!
|
||||
.SH RETURN VALUE
|
||||
None
|
||||
.SH "SEE ALSO"
|
||||
|
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -21,7 +21,7 @@
|
||||
.\" * $Id$
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl_easy_setopt 3 "19 Apr 2006" "libcurl 7.15.4" "libcurl Manual"
|
||||
.TH curl_easy_setopt 3 "2 Nov 2006" "libcurl 7.16.1" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_setopt \- set options for a curl easy handle
|
||||
.SH SYNOPSIS
|
||||
@@ -344,6 +344,14 @@ when showing the progress meter and displaying \fICURLOPT_VERBOSE\fP data.
|
||||
A non-zero parameter tells the library to fail silently if the HTTP code
|
||||
returned is equal to or larger than 400. The default action would be to return
|
||||
the page normally, ignoring that code.
|
||||
|
||||
This method is not fail-safe and there are occasions where non-succesful
|
||||
response codes will slip through, especially when authentication is involved
|
||||
(response codes 401 and 407).
|
||||
|
||||
You might get some amounts of headers transferred before this situation is
|
||||
detected, like for when a "100-continue" is received as a response to a
|
||||
POST/PUT and a 401 or 407 is received immediately afterwards.
|
||||
.SH NETWORK OPTIONS
|
||||
.IP CURLOPT_URL
|
||||
The actual URL to deal with. The parameter should be a char * to a zero
|
||||
@@ -917,18 +925,12 @@ Try "AUTH SSL" first, and only if that fails try "AUTH TLS"
|
||||
.IP CURLFTPAUTH_TLS
|
||||
Try "AUTH TLS" first, and only if that fails try "AUTH SSL"
|
||||
.RE
|
||||
.IP CURLOPT_SOURCE_URL
|
||||
When set, it enables a FTP third party transfer, using the set URL as source,
|
||||
while \fICURLOPT_URL\fP is the target.
|
||||
.IP CURLOPT_SOURCE_USERPWD
|
||||
Set "username:password" to use for the source connection when doing FTP third
|
||||
party transfers.
|
||||
.IP CURLOPT_SOURCE_QUOTE
|
||||
Exactly like \fICURLOPT_QUOTE\fP, but for the source host.
|
||||
.IP CURLOPT_SOURCE_PREQUOTE
|
||||
Exactly like \fICURLOPT_PREQUOTE\fP, but for the source host.
|
||||
.IP CURLOPT_SOURCE_POSTQUOTE
|
||||
Exactly like \fICURLOPT_POSTQUOTE\fP, but for the source host.
|
||||
.IP CURLOPT_FTP_SSL_CCC
|
||||
Pass a long that is set to 0 to disable and 1 to enable. If enabled, this
|
||||
option makes libcurl use CCC (Clear Command Channel). It shuts down the
|
||||
SSL/TLS layer after authenticating. The rest of the control channel
|
||||
communication will be unencrypted. This allows NAT routers to follow the FTP
|
||||
transaction. (Added in 7.16.1)
|
||||
.IP CURLOPT_FTP_ACCOUNT
|
||||
Pass a pointer to a zero-terminated string (or NULL to disable). When an FTP
|
||||
server asks for "account data" after user name and password has been provided,
|
||||
@@ -973,7 +975,9 @@ techniques). Pass a NULL to this option to disable the use of ranges.
|
||||
.IP CURLOPT_RESUME_FROM
|
||||
Pass a long as parameter. It contains the offset in number of bytes that you
|
||||
want the transfer to start from. Set this option to 0 to make the transfer
|
||||
start from the beginning (effectively disabling resume).
|
||||
start from the beginning (effectively disabling resume). For FTP, set this
|
||||
option to -1 to make the transfer start from the end of the target file
|
||||
(useful to continue an interrupted upload).
|
||||
.IP CURLOPT_RESUME_FROM_LARGE
|
||||
Pass a curl_off_t as parameter. It contains the offset in number of bytes that
|
||||
you want the transfer to start from. (Added in 7.11.0)
|
||||
@@ -1010,10 +1014,16 @@ to POST with \fICURLOPT_POST\fP etc.
|
||||
When uploading a file to a remote site, this option should be used to tell
|
||||
libcurl what the expected size of the infile is. This value should be passed
|
||||
as a long. See also \fICURLOPT_INFILESIZE_LARGE\fP.
|
||||
|
||||
Note that this option does not limit how much data libcurl will actually send,
|
||||
as that is controlled entirely by what the read callback returns.
|
||||
.IP CURLOPT_INFILESIZE_LARGE
|
||||
When uploading a file to a remote site, this option should be used to tell
|
||||
libcurl what the expected size of the infile is. This value should be passed
|
||||
as a curl_off_t. (Added in 7.11.0)
|
||||
|
||||
Note that this option does not limit how much data libcurl will actually send,
|
||||
as that is controlled entirely by what the read callback returns.
|
||||
.IP CURLOPT_UPLOAD
|
||||
A non-zero parameter tells the library to prepare for an upload. The
|
||||
\fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP or
|
||||
@@ -1077,13 +1087,15 @@ Pass a long as parameter. It contains the time in seconds that the transfer
|
||||
should be below the \fICURLOPT_LOW_SPEED_LIMIT\fP for the library to consider
|
||||
it too slow and abort.
|
||||
.IP CURLOPT_MAX_SEND_SPEED_LARGE
|
||||
Pass a curl_off_t as parameter. If an upload exceeds this speed on cumulative
|
||||
average during the transfer, the transfer will pause to keep the average rate
|
||||
less than or equal to the parameter value. (default: 0, unlimited)
|
||||
Pass a curl_off_t as parameter. If an upload exceeds this speed on cumulative
|
||||
average during the transfer, the transfer will pause to keep the average rate
|
||||
less than or equal to the parameter value. Defaults to unlimited
|
||||
speed. (Added in 7.15.5)
|
||||
.IP CURLOPT_MAX_RECV_SPEED_LARGE
|
||||
Pass a curl_off_t as parameter. If an upload exceeds this speed on cumulative
|
||||
average during the transfer, the transfer will pause to keep the average rate
|
||||
less than or equal to the parameter value. (default: 0, unlimited)
|
||||
Pass a curl_off_t as parameter. If an upload exceeds this speed on cumulative
|
||||
average during the transfer, the transfer will pause to keep the average rate
|
||||
less than or equal to the parameter value. Defaults to unlimited speed. (Added
|
||||
in 7.15.5)
|
||||
.IP CURLOPT_MAXCONNECTS
|
||||
Pass a long. The set number will be the persistent connection cache size. The
|
||||
set amount will be the maximum amount of simultaneously open connections that
|
||||
@@ -1092,23 +1104,14 @@ value unless you are perfectly aware of how this work and changes libcurl's
|
||||
behaviour. This concerns connection using any of the protocols that support
|
||||
persistent connections.
|
||||
|
||||
When reaching the maximum limit, curl uses the \fICURLOPT_CLOSEPOLICY\fP to
|
||||
figure out which of the existing connections to close to prevent the number of
|
||||
open connections to increase.
|
||||
When reaching the maximum limit, curl closes the oldest one in the cache to
|
||||
prevent the number of open connections to increase.
|
||||
|
||||
If you already have performed transfers with this curl handle, setting a
|
||||
smaller MAXCONNECTS than before may cause open connections to get closed
|
||||
unnecessarily.
|
||||
.IP CURLOPT_CLOSEPOLICY
|
||||
Pass a long. This option sets what policy libcurl should use when the
|
||||
connection cache is filled and one of the open connections has to be closed to
|
||||
make room for a new connection. This must be one of the CURLCLOSEPOLICY_*
|
||||
defines. Use \fICURLCLOSEPOLICY_LEAST_RECENTLY_USED\fP to make libcurl close
|
||||
the connection that was least recently used, that connection is also least
|
||||
likely to be capable of re-use. Use \fICURLCLOSEPOLICY_OLDEST\fP to make
|
||||
libcurl close the oldest connection, the one that was created first among the
|
||||
ones in the connection cache. The other close policies are not support
|
||||
yet.
|
||||
(Obsolete) This option does nothing.
|
||||
.IP CURLOPT_FRESH_CONNECT
|
||||
Pass a long. Set to non-zero to make the next transfer use a new (fresh)
|
||||
connection by force. If the connection cache is full before this connection,
|
||||
@@ -1246,14 +1249,14 @@ even indicate an accessible file.
|
||||
Note that option is by default set to the system path where libcurl's cacert
|
||||
bundle is assumed to be stored, as established at build time.
|
||||
.IP CURLOPT_CAPATH
|
||||
Pass a char * to a zero terminated string naming a directory holding
|
||||
multiple CA certificates to verify the peer with. The certificate
|
||||
directory must be prepared using the openssl c_rehash utility. This
|
||||
makes sense only when used in combination with the
|
||||
\fICURLOPT_SSL_VERIFYPEER\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP
|
||||
is zero, \fICURLOPT_CAPATH\fP need not even indicate an accessible
|
||||
path. The \fICURLOPT_CAPATH\fP function apparently does not work in
|
||||
Windows due to some limitation in openssl. (Added in 7.9.8)
|
||||
Pass a char * to a zero terminated string naming a directory holding multiple
|
||||
CA certificates to verify the peer with. The certificate directory must be
|
||||
prepared using the openssl c_rehash utility. This makes sense only when used
|
||||
in combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If
|
||||
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAPATH\fP need not even
|
||||
indicate an accessible path. The \fICURLOPT_CAPATH\fP function apparently
|
||||
does not work in Windows due to some limitation in openssl. This option is
|
||||
OpenSSL-specific and does nothing if libcurl is built to use GnuTLS.
|
||||
.IP CURLOPT_RANDOM_FILE
|
||||
Pass a char * to a zero terminated file name. The file will be used to read
|
||||
from to seed the random engine for SSL. The more random the specified file is,
|
||||
@@ -1300,12 +1303,29 @@ compile OpenSSL.
|
||||
|
||||
You'll find more details about cipher lists on this URL:
|
||||
\fIhttp://www.openssl.org/docs/apps/ciphers.html\fP
|
||||
.IP CURLOPT_SSL_SESSIONID_CACHE
|
||||
Pass a long set to 0 to disable libcurl's use of SSL session-ID caching. Set
|
||||
this to 1 to enable it. By default all transfers are done using the
|
||||
cache. Note that while nothing ever should get hurt by attempting to reuse SSL
|
||||
session-IDs, there seem to be broken SSL implementations in the wild that may
|
||||
require you to disable this in order for you to succeed. (Added in 7.16.0)
|
||||
.IP CURLOPT_KRB4LEVEL
|
||||
Pass a char * as parameter. Set the krb4 security level, this also enables
|
||||
krb4 awareness. This is a string, 'clear', 'safe', 'confidential' or
|
||||
\&'private'. If the string is set but doesn't match one of these, 'private'
|
||||
will be used. Set the string to NULL to disable kerberos4. The kerberos
|
||||
support only works for FTP.
|
||||
.SH SSH OPTIONS
|
||||
.IP CURLOPT_SSH_AUTH_TYPES
|
||||
Pass a long set to a bitmask consisting of one or more of
|
||||
CURLSSH_AUTH_PUBLICKEY, CURLSSH_AUTH_PASSWORD, CURLSSH_AUTH_HOST,
|
||||
CURLSSH_AUTH_KEYBOARD. Set CURLSSH_AUTH_ANY to let libcurl pick one.
|
||||
.IP CURLOPT_SSH_PUBLIC_KEYFILE
|
||||
Pass a char * pointing to a file name for your public key. If not used,
|
||||
libcurl defaults to using \fB~/.ssh/id_dsa.pub\fP.
|
||||
.IP CURLOPT_SSH_PRIVATE_KEYFILE
|
||||
Pass a char * pointing to a file name for your private key. If not used,
|
||||
libcurl defaults to using \fB~/.ssh/id_dsa\fP.
|
||||
.SH OTHER OPTIONS
|
||||
.IP CURLOPT_PRIVATE
|
||||
Pass a char * as parameter, pointing to data that should be associated with
|
||||
|
@@ -20,8 +20,14 @@ NULL is returned as a signal that there is no more to get at this point. The
|
||||
integer pointed to with \fImsgs_in_queue\fP will contain the number of
|
||||
remaining messages after this function was called.
|
||||
|
||||
When you fetch a message using this function, it is removed from the internal
|
||||
queue so calling this function again will not return the same message
|
||||
again. It will instead return new messages at each new invoke until the queue
|
||||
is emptied.
|
||||
|
||||
The data the returned pointer points to will not survive calling
|
||||
\fIcurl_multi_cleanup(3)\fP or \fIcurl_multi_remove_handle(3)\fP.
|
||||
\fIcurl_multi_cleanup(3)\fP, \fIcurl_multi_remove_handle(3)\fP or
|
||||
\fIcurl_easy_cleanup(3)\fP.
|
||||
|
||||
The 'CURLMsg' struct is very simple and only contain very basic information.
|
||||
If more involved information is wanted, the particular "easy handle" in
|
||||
@@ -37,6 +43,12 @@ present in that struct and can thus be used in subsequent regular
|
||||
CURLcode result; /* return code for transfer */
|
||||
} data;
|
||||
};
|
||||
|
||||
When \fBmsg\fP is \fICURLMSG_DONE\fP, the message identifies a transfer that
|
||||
is done, and then \fBresult\fP contains the return code for the easy handle
|
||||
that just completed.
|
||||
|
||||
At this point, there is no other \fBmsg\fP types defined.
|
||||
.SH "RETURN VALUE"
|
||||
A pointer to a filled-in struct, or NULL if it failed or ran out of
|
||||
structs. It also writes the number of messages left in the queue (after this
|
||||
|
@@ -30,11 +30,15 @@ If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this basically means that you
|
||||
should call \fIcurl_multi_perform\fP again, before you select() on more
|
||||
actions. You don't have to do it immediately, but the return code means that
|
||||
libcurl may have more data available to return or that there may be more data
|
||||
to send off before it is "satisfied".
|
||||
to send off before it is "satisfied". Do note that \fIcurl_multi_perform(3)\fP
|
||||
will return \fICURLM_CALL_MULTI_PERFORM\fP only when it wants to be called
|
||||
again \fBimmediately\fP. When things are fine and there are nothing immediate
|
||||
it wants done, it'll return \fICURLM_OK\fP and you need to wait for \&"action"
|
||||
and then call this function again.
|
||||
|
||||
NOTE that this only returns errors etc regarding the whole multi stack. There
|
||||
might still have occurred problems on individual transfers even when this
|
||||
function returns OK.
|
||||
function returns \fICURLM_OK\fP.
|
||||
.SH "TYPICAL USAGE"
|
||||
Most applications will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's
|
||||
file descriptors, then it'll wait for action on them using \fBselect(3)\fP and
|
||||
@@ -42,4 +46,5 @@ as soon as one or more of them are ready, \fIcurl_multi_perform(3)\fP gets
|
||||
called.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
|
||||
.BR curl_multi_fdset "(3), " curl_multi_info_read "(3)"
|
||||
.BR curl_multi_fdset "(3), " curl_multi_info_read "(3), "
|
||||
.BR libcurl-errors "(3)"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_multi_setopt 3 "8 Jan 2006" "libcurl 7.16.0" "libcurl Manual"
|
||||
.TH curl_multi_setopt 3 "10 Oct 2006" "libcurl 7.16.0" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_multi_setopt \- set options for a curl multi handle
|
||||
.SH SYNOPSIS
|
||||
@@ -9,7 +9,7 @@ curl_multi_setopt \- set options for a curl multi handle
|
||||
CURLMcode curl_multi_setopt(CURLM * multi_handle, CURLMoption option, param);
|
||||
.SH DESCRIPTION
|
||||
curl_multi_setopt() is used to tell a libcurl multi handle how to behave. By
|
||||
using the appropriate options to \fIcurl_multi_setopt\fP, you can change
|
||||
using the appropriate options to \fIcurl_multi_setopt(3)\fP, you can change
|
||||
libcurl's behaviour when using that multi handle. All options are set with
|
||||
the \fIoption\fP followed by the parameter \fIparam\fP. That parameter can be
|
||||
a \fBlong\fP, a \fBfunction pointer\fP, an \fBobject pointer\fP or a
|
||||
@@ -19,19 +19,43 @@ You can only set one option in each function call.
|
||||
|
||||
.SH OPTIONS
|
||||
.IP CURLMOPT_SOCKETFUNCTION
|
||||
Pass a pointer to a function matching the curl_socket_callback prototype. The
|
||||
\fIcurl_multi_socket(3)\fP functions inform the application about updates in
|
||||
the socket (file descriptor) status by doing none, one or multiple calls to
|
||||
the curl_socket_callback given in the \fBparam\fP argument. They update the
|
||||
status with changes since the previous time a \fIcurl_multi_socket(3)\fP
|
||||
function was called. If the given callback pointer is NULL, no callback will
|
||||
be called. Set the callback's \fBuserp\fP argument with
|
||||
\fICURLMOPT_SOCKETDATA\fP. See \fIcurl_multi_socket(3)\fP for more callback
|
||||
details.
|
||||
Pass a pointer to a function matching the \fBcurl_socket_callback\fP
|
||||
prototype. The \fIcurl_multi_socket(3)\fP functions inform the application
|
||||
about updates in the socket (file descriptor) status by doing none, one or
|
||||
multiple calls to the curl_socket_callback given in the \fBparam\fP
|
||||
argument. They update the status with changes since the previous time a
|
||||
\fIcurl_multi_socket(3)\fP function was called. If the given callback pointer
|
||||
is NULL, no callback will be called. Set the callback's \fBuserp\fP argument
|
||||
with \fICURLMOPT_SOCKETDATA\fP. See \fIcurl_multi_socket(3)\fP for more
|
||||
callback details.
|
||||
.IP CURLMOPT_SOCKETDATA
|
||||
Pass a pointer to whatever you want passed to the curl_socket_callback's forth
|
||||
argument, the userp pointer. This is not used by libcurl but only passed-thru
|
||||
as-is. Set the callback pointer with \fICURLMOPT_SOCKETFUNCTION\fP.
|
||||
Pass a pointer to whatever you want passed to the \fBcurl_socket_callback\fP's
|
||||
forth argument, the userp pointer. This is not used by libcurl but only
|
||||
passed-thru as-is. Set the callback pointer with
|
||||
\fICURLMOPT_SOCKETFUNCTION\fP.
|
||||
.IP CURLMOPT_PIPELINING
|
||||
Pass a long set to 1 to enable or 0 to disable. Enabling pipelining on a multi
|
||||
handle will make it attempt to perform HTTP Pipelining as far as possible for
|
||||
transfers using this handle. This means that if you add a second request that
|
||||
can use an already existing connection, the second request will be \&"piped"
|
||||
on the same connection rather than being executed in parallell. (Added in
|
||||
7.16.0)
|
||||
.IP CURLMOPT_TIMERFUNCTION
|
||||
Pass a pointer to a function matching the \fBcurl_multi_timer_callback\fP
|
||||
prototype. This function will then be called when the timeout value
|
||||
changes. The timeout value is at what latest time the application should call
|
||||
one of the \&"performing" functions of the multi interface
|
||||
(\fIcurl_multi_socket(3)\fP, \fIcurl_multi_socket_all(3)\fP and
|
||||
\fIcurl_multi_perform(3)\fP) - to allow libcurl to keep timeouts and retries
|
||||
etc to work. Libcurl attempts to limit calling this only when the fixed future
|
||||
timeout time actually change. See also \fICURLMOPT_TIMERDATA\fP. This callback
|
||||
can be used instead of, or in addition to, \fIcurl_multi_timeout(3)\fP. (Added
|
||||
in 7.16.0)
|
||||
.IP CURLMOPT_TIMERDATA
|
||||
Pass a pointer to whatever you want passed to the
|
||||
\fBcurl_multi_timer_callback\fP's third argument, the userp pointer. This is
|
||||
not used by libcurl but only passed-thru as-is. Set the callback pointer with
|
||||
\fICURLMOPT_TIMERFUNCTION\fP. (Added in 7.16.0)
|
||||
.SH RETURNS
|
||||
The standard CURLMcode for multi interface error codes. Note that it returns a
|
||||
CURLM_UNKNOWN_OPTION if you try setting an option that this version of libcurl
|
||||
|
@@ -24,8 +24,9 @@ The list should be freed again (after usage) with
|
||||
A null pointer is returned if anything went wrong, otherwise the new list
|
||||
pointer is returned.
|
||||
.SH EXAMPLE
|
||||
.nf
|
||||
CURL handle;
|
||||
curl_slist *slist=NULL;
|
||||
struct curl_slist *slist=NULL;
|
||||
|
||||
slist = curl_slist_append(slist, "pragma:");
|
||||
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, slist);
|
||||
@@ -33,5 +34,6 @@ pointer is returned.
|
||||
curl_easy_perform(handle);
|
||||
|
||||
curl_slist_free_all(slist); /* free the list again */
|
||||
.fi
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_slist_free_all "(3), "
|
||||
|
@@ -21,7 +21,7 @@
|
||||
.\" * $Id$
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl_version_info 3 "19 Apr 2006" "libcurl 7.15.4" "libcurl Manual"
|
||||
.TH curl_version_info 3 "2 Nov 2006" "libcurl 7.16.1" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_version_info - returns run-time libcurl version info
|
||||
.SH SYNOPSIS
|
||||
@@ -66,6 +66,11 @@ typedef struct {
|
||||
/* when 'age' is 2 or higher, the member below also exists: */
|
||||
const char *libidn; /* human readable string */
|
||||
|
||||
/* when 'age' is 3 or higher, the members below also exist: */
|
||||
int iconv_ver_num; /* '_libiconv_version' if iconv support enabled */
|
||||
|
||||
const char *libssh_version; /* human readable string */
|
||||
|
||||
} curl_version_info_data;
|
||||
.fi
|
||||
|
||||
|
@@ -174,7 +174,7 @@ problem with the local client certificate
|
||||
.IP "CURLE_SSL_CIPHER (59)"
|
||||
couldn't use specified cipher
|
||||
.IP "CURLE_SSL_CACERT (60)"
|
||||
problem with the CA cert (path? access rights?)
|
||||
peer certificate cannot be authenticated with known CA certificates
|
||||
.IP "CURLE_BAD_CONTENT_ENCODING (61)"
|
||||
Unrecognized transfer encoding
|
||||
.IP "CURLE_LDAP_INVALID_URL (62)"
|
||||
@@ -208,6 +208,8 @@ No such TFTP user
|
||||
Character conversion failed
|
||||
.IP "CURLE_CONV_REQD (76)"
|
||||
Caller must register conversion callbacks
|
||||
.IP "CURLE_SSL_CACERT_BADFILE (77)"
|
||||
Problem with reading the SSL CA cert (path? access rights?)
|
||||
.SH "CURLMcode"
|
||||
This is the generic return code used by functions in the libcurl multi
|
||||
interface. Also consider \fIcurl_multi_strerror(3)\fP.
|
||||
@@ -219,7 +221,9 @@ Things are fine.
|
||||
.IP "CURLM_BAD_HANDLE (1)"
|
||||
The passed-in handle is not a valid CURLM handle.
|
||||
.IP "CURLM_BAD_EASY_HANDLE (2)"
|
||||
An easy handle was not good/valid.
|
||||
An easy handle was not good/valid. It could mean that it isn't an easy handle
|
||||
at all, or possibly that the handle already is in used by this or another
|
||||
multi handle.
|
||||
.IP "CURLM_OUT_OF_MEMORY (3)"
|
||||
You are doomed.
|
||||
.IP "CURLM_INTERNAL_ERROR (4)"
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -390,6 +390,15 @@ typedef enum {
|
||||
CURLOPT_CONV_FROM_NETWORK_FUNCTION,
|
||||
CURLOPT_CONV_TO_NETWORK_FUNCTION, and
|
||||
CURLOPT_CONV_FROM_UTF8_FUNCTION */
|
||||
CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
|
||||
or wrong format */
|
||||
CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */
|
||||
CURLE_SSH, /* 79 - error from the SSH layer, somewhat
|
||||
generic so the error message will be of
|
||||
interest when this has happened */
|
||||
|
||||
CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
|
||||
connection */
|
||||
CURL_LAST /* never use! */
|
||||
} CURLcode;
|
||||
|
||||
@@ -425,6 +434,14 @@ typedef enum {
|
||||
#define CURLAUTH_ANY ~0 /* all types set */
|
||||
#define CURLAUTH_ANYSAFE (~CURLAUTH_BASIC)
|
||||
|
||||
#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */
|
||||
#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */
|
||||
#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
|
||||
#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */
|
||||
#define CURLSSH_AUTH_HOST (1<<2) /* host key files */
|
||||
#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */
|
||||
#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
|
||||
|
||||
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
|
||||
the obsolete stuff removed! */
|
||||
/* this was the error code 50 in 7.7.3 and a few earlier versions, this
|
||||
@@ -941,22 +958,12 @@ typedef enum {
|
||||
CINIT(TCP_NODELAY, LONG, 121),
|
||||
|
||||
/* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
|
||||
|
||||
/* When doing 3rd party transfer, set the source user and password with
|
||||
this */
|
||||
CINIT(SOURCE_USERPWD, OBJECTPOINT, 123),
|
||||
|
||||
/* 123 OBSOLETE. Gone in 7.16.0 */
|
||||
/* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
|
||||
/* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
|
||||
/* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
|
||||
|
||||
/* When doing 3rd party transfer, set the source pre-quote linked list
|
||||
of commands with this */
|
||||
CINIT(SOURCE_PREQUOTE, OBJECTPOINT, 127),
|
||||
|
||||
/* When doing 3rd party transfer, set the source post-quote linked list
|
||||
of commands with this */
|
||||
CINIT(SOURCE_POSTQUOTE, OBJECTPOINT, 128),
|
||||
/* 127 OBSOLETE. Gone in 7.16.0 */
|
||||
/* 128 OBSOLETE. Gone in 7.16.0 */
|
||||
|
||||
/* When FTP over SSL/TLS is selected (with CURLOPT_FTP_SSL), this option
|
||||
can be used to change libcurl's default action which is to first try
|
||||
@@ -973,12 +980,8 @@ typedef enum {
|
||||
CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
|
||||
CINIT(IOCTLDATA, OBJECTPOINT, 131),
|
||||
|
||||
/* To make a 3rd party transfer, set the source URL with this */
|
||||
CINIT(SOURCE_URL, OBJECTPOINT, 132),
|
||||
|
||||
/* When doing 3rd party transfer, set the source quote linked list of
|
||||
commands with this */
|
||||
CINIT(SOURCE_QUOTE, OBJECTPOINT, 133),
|
||||
/* 132 OBSOLETE. Gone in 7.16.0 */
|
||||
/* 133 OBSOLETE. Gone in 7.16.0 */
|
||||
|
||||
/* zero terminated string for pass on to the FTP server when asked for
|
||||
"account" info */
|
||||
@@ -1037,6 +1040,20 @@ typedef enum {
|
||||
CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
|
||||
CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
|
||||
|
||||
/* set to 0 to disable session ID re-use for this transfer, default is
|
||||
enabled (== 1) */
|
||||
CINIT(SSL_SESSIONID_CACHE, LONG, 150),
|
||||
|
||||
/* allowed SSH authentication methods */
|
||||
CINIT(SSH_AUTH_TYPES, LONG, 151),
|
||||
|
||||
/* Used by scp/sftp to do public/private key authentication */
|
||||
CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152),
|
||||
CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153),
|
||||
|
||||
/* Send CCC (Clear Command Channel) after authentication */
|
||||
CINIT(FTP_SSL_CCC, LONG, 154),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -1055,18 +1072,6 @@ typedef enum {
|
||||
|
||||
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
|
||||
the obsolete stuff removed! */
|
||||
#define CURLOPT_HTTPREQUEST -1
|
||||
#define CURLOPT_FTPASCII CURLOPT_TRANSFERTEXT
|
||||
#define CURLOPT_MUTE -2
|
||||
#define CURLOPT_PASSWDFUNCTION -3
|
||||
#define CURLOPT_PASSWDDATA -4
|
||||
#define CURLOPT_CLOSEFUNCTION -5
|
||||
|
||||
#define CURLOPT_SOURCE_HOST -6
|
||||
#define CURLOPT_SOURCE_PATH -7
|
||||
#define CURLOPT_SOURCE_PORT -8
|
||||
#define CURLOPT_PASV_HOST -9
|
||||
|
||||
#else
|
||||
/* This is set if CURL_NO_OLDIES is defined at compile-time */
|
||||
#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
|
||||
@@ -1526,6 +1531,7 @@ typedef enum {
|
||||
CURLVERSION_FIRST,
|
||||
CURLVERSION_SECOND,
|
||||
CURLVERSION_THIRD,
|
||||
CURLVERSION_FOURTH,
|
||||
CURLVERSION_LAST /* never actually use this */
|
||||
} CURLversion;
|
||||
|
||||
@@ -1534,7 +1540,7 @@ typedef enum {
|
||||
meant to be a built-in version number for what kind of struct the caller
|
||||
expects. If the struct ever changes, we redefine the NOW to another enum
|
||||
from above. */
|
||||
#define CURLVERSION_NOW CURLVERSION_THIRD
|
||||
#define CURLVERSION_NOW CURLVERSION_FOURTH
|
||||
|
||||
typedef struct {
|
||||
CURLversion age; /* age of the returned struct */
|
||||
@@ -1555,8 +1561,13 @@ typedef struct {
|
||||
/* This field was added in CURLVERSION_THIRD */
|
||||
const char *libidn;
|
||||
|
||||
/* These field were added in CURLVERSION_FOURTH */
|
||||
|
||||
/* Same as '_libiconv_version' if built with HAVE_ICONV */
|
||||
int iconv_ver_num;
|
||||
|
||||
const char *libssh_version; /* human readable string */
|
||||
|
||||
} curl_version_info_data;
|
||||
|
||||
#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */
|
||||
|
@@ -28,13 +28,13 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.15.6-CVS"
|
||||
#define LIBCURL_VERSION "7.16.1-CVS"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 15
|
||||
#define LIBCURL_VERSION_PATCH 6
|
||||
#define LIBCURL_VERSION_MINOR 16
|
||||
#define LIBCURL_VERSION_PATCH 1
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -51,6 +51,6 @@
|
||||
and it is always a greater number in a more recent release. It makes
|
||||
comparisons with greater than and less than work.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x070f06
|
||||
#define LIBCURL_VERSION_NUM 0x071001
|
||||
|
||||
#endif /* __CURL_CURLVER_H */
|
||||
|
@@ -28,6 +28,10 @@
|
||||
|
||||
#include "curl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CURL_EXTERN int curl_mprintf(const char *format, ...);
|
||||
CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
|
||||
CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
|
||||
@@ -59,4 +63,8 @@ CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
|
||||
# define vaprintf curl_mvaprintf
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CURL_MPRINTF_H */
|
||||
|
@@ -231,6 +231,20 @@ typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
|
||||
pointer */
|
||||
void *socketp); /* private socket
|
||||
pointer */
|
||||
/*
|
||||
* Name: curl_multi_timer_callback
|
||||
*
|
||||
* Desc: Called by libcurl whenever the library detects a change in the
|
||||
* maximum number of milliseconds the app is allowed to wait before
|
||||
* curl_multi_socket() or curl_multi_perform() must be called
|
||||
* (to allow libcurl's timed events to take place).
|
||||
*
|
||||
* Returns: The callback should return zero.
|
||||
*/
|
||||
typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
|
||||
long timeout_ms, /* see above */
|
||||
void *userp); /* private callback
|
||||
pointer */
|
||||
|
||||
CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
|
||||
int *running_handles);
|
||||
@@ -270,6 +284,15 @@ typedef enum {
|
||||
/* This is the argument passed to the socket callback */
|
||||
CINIT(SOCKETDATA, OBJECTPOINT, 2),
|
||||
|
||||
/* set to 1 to enable pipelining for this multi handle */
|
||||
CINIT(PIPELINING, LONG, 3),
|
||||
|
||||
/* This is the timer callback function pointer */
|
||||
CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
|
||||
|
||||
/* This is the argument passed to the timer callback */
|
||||
CINIT(TIMERDATA, OBJECTPOINT, 5),
|
||||
|
||||
CURLMOPT_LASTENTRY /* the last unused */
|
||||
} CURLMoption;
|
||||
|
||||
|
@@ -46,7 +46,7 @@ OBJS = $(OBJ_DIR)\transfer.obj $(OBJ_DIR)\file.obj &
|
||||
$(OBJ_DIR)\hostsyn.obj $(OBJ_DIR)\parsedate.obj &
|
||||
$(OBJ_DIR)\select.obj $(OBJ_DIR)\sslgen.obj &
|
||||
$(OBJ_DIR)\gtls.obj $(OBJ_DIR)\tftp.obj &
|
||||
$(OBJ_DIR)\splay.obj
|
||||
$(OBJ_DIR)\splay.obj $(OBJ_DIR)\socks.obj
|
||||
|
||||
RESOURCE = $(OBJ_DIR)\libcurl.res
|
||||
|
||||
|
@@ -48,7 +48,7 @@ INCLUDES = -I$(top_srcdir)/include \
|
||||
-I$(top_builddir)/lib \
|
||||
-I$(top_srcdir)/lib
|
||||
|
||||
VERSION=-version-info 3:0:0
|
||||
VERSION=-version-info 4:0:0
|
||||
|
||||
# This flag accepts an argument of the form current[:revision[:age]]. So,
|
||||
# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
|
||||
|
@@ -8,7 +8,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
content_encoding.c share.c http_digest.c md5.c http_negotiate.c \
|
||||
http_ntlm.c inet_pton.c strtoofft.c strerror.c hostares.c hostasyn.c \
|
||||
hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c \
|
||||
select.c gtls.c sslgen.c tftp.c splay.c strdup.c
|
||||
select.c gtls.c sslgen.c tftp.c splay.c strdup.c socks.c ssh.c
|
||||
|
||||
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
||||
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
||||
@@ -18,6 +18,6 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
||||
share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \
|
||||
inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h \
|
||||
setup.h transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h \
|
||||
gtls.h tftp.h sockaddr.h splay.h strdup.h setup_once.h
|
||||
gtls.h tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h
|
||||
|
||||
|
||||
|
@@ -2,18 +2,21 @@
|
||||
# $Id$
|
||||
#
|
||||
## Makefile for building libcurl.a with MingW32 (GCC-3.2) and
|
||||
## optionally OpenSSL (0.9.7)
|
||||
## optionally OpenSSL (0.9.8)
|
||||
##
|
||||
## Use: make -f Makefile.m32
|
||||
## Use: make -f Makefile.m32 [SSL=1] [SSH2=1] [DYN=1]
|
||||
##
|
||||
## Comments to: Troy Engel <tengel@sonic.net> or
|
||||
## Joern Hartroth <hartroth@acm.org>
|
||||
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.7d
|
||||
OPENSSL_PATH = ../../openssl-0.9.8d
|
||||
endif
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-0.14
|
||||
endif
|
||||
ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.1
|
||||
ZLIB_PATH = ../../zlib-1.2.3
|
||||
endif
|
||||
|
||||
CC = gcc
|
||||
@@ -26,19 +29,27 @@ STRIP = strip -g
|
||||
## Nothing more to do below this line!
|
||||
|
||||
INCLUDES = -I. -I../include
|
||||
CFLAGS = -g -O2 -DMINGW32 -DBUILDING_LIBCURL -DHAVE_LONGLONG
|
||||
CFLAGS = -g -O2 -DBUILDING_LIBCURL -DHAVE_LONGLONG
|
||||
ifdef SSH2
|
||||
INCLUDES += -I"$(LIBSSH2_PATH)/include" -I"$(LIBSSH2_PATH)/win32"
|
||||
CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H
|
||||
DLL_LIBS += -L$(LIBSSH2_PATH)/win32 -lssh2
|
||||
endif
|
||||
ifdef SSL
|
||||
INCLUDES += -I"$(OPENSSL_PATH)/outinc" -I"$(OPENSSL_PATH)/outinc/openssl"
|
||||
CFLAGS += -DUSE_SSLEAY -DUSE_OPENSSL -DHAVE_OPENSSL_ENGINE_H -DHAVE_OPENSSL_PKCS12_H \
|
||||
-DHAVE_ENGINE_LOAD_BUILTIN_ENGINES -DOPENSSL_NO_KRB5 \
|
||||
-DCURL_CA_BUNDLE='getenv("CURL_CA_BUNDLE")'
|
||||
DLL_LIBS = -L$(OPENSSL_PATH)/out -leay32 -lssl32
|
||||
-DCURL_WANTS_CA_BUNDLE_ENV
|
||||
DLL_LIBS += -L$(OPENSSL_PATH)/out -leay32 -lssl32
|
||||
endif
|
||||
ifdef ZLIB
|
||||
INCLUDES += -I"$(ZLIB_PATH)"
|
||||
CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
|
||||
DLL_LIBS += -L$(ZLIB_PATH) -lz
|
||||
endif
|
||||
ifdef SSPI
|
||||
CFLAGS += -DUSE_WINDOWS_SSPI
|
||||
endif
|
||||
COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
|
@@ -19,7 +19,12 @@ endif
|
||||
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.8b
|
||||
OPENSSL_PATH = ../../openssl-0.9.8d
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-0.14
|
||||
endif
|
||||
|
||||
ifndef INSTDIR
|
||||
@@ -29,7 +34,7 @@ endif
|
||||
# Edit the vars below to change NLM target settings.
|
||||
TARGET = libcurl
|
||||
VERSION = $(LIBCURL_VERSION)
|
||||
COPYR = Copyright (C) 1996 - 2006, Daniel Stenberg, <daniel@haxx.se>
|
||||
COPYR = Copyright (C) 1996 - 2007, Daniel Stenberg, <daniel@haxx.se>
|
||||
DESCR = cURL libcurl $(LIBCURL_VERSION_STR) - http://curl.haxx.se
|
||||
MTSAFE = YES
|
||||
STACK = 64000
|
||||
@@ -63,6 +68,7 @@ ifdef METROWERKS
|
||||
else
|
||||
CC = gcc
|
||||
endif
|
||||
AWK = awk
|
||||
YACC = bison -y
|
||||
CP = cp -afv
|
||||
# RM = rm -f
|
||||
@@ -121,6 +127,15 @@ ifdef WITH_SSL
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_libc/crypto.lib $(OPENSSL_PATH)/out_nw_libc/ssl.lib
|
||||
IMPORTS += GetProcessSwitchCount RunningProcess
|
||||
endif
|
||||
ifdef WITH_SSH2
|
||||
INCLUDES += -I$(LIBSSH2_PATH)/include
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(LIBSSH2_PATH)/nw/libssh2.lib
|
||||
else
|
||||
IMPORTS += @$(LIBSSH2_PATH)/nw/libssh2.imp
|
||||
MODULES += libssh2.nlm
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_ZLIB
|
||||
INCLUDES += -I$(ZLIB_PATH)
|
||||
ifdef LINK_STATIC
|
||||
@@ -184,7 +199,7 @@ $(OBJDIR)/%.o: %.c
|
||||
|
||||
$(OBJDIR)/version.inc: ../include/curl/curlver.h $(OBJDIR)
|
||||
@echo Creating $@
|
||||
@awk -f ../packages/NetWare/get_ver.awk $< > $@
|
||||
@$(AWK) -f ../packages/NetWare/get_ver.awk $< > $@
|
||||
|
||||
dist: all
|
||||
-$(RM) $(OBJDIR)/*.o $(OBJDIR)/$(TARGET).map $(OBJDIR)/$(TARGET).ncv
|
||||
@@ -205,6 +220,9 @@ clean:
|
||||
-$(RM) config.h ca-bundle.h
|
||||
-$(RM) -r $(OBJDIR)
|
||||
|
||||
distclean: clean
|
||||
-$(RM) -r $(TARGET).lib $(TARGET).nlm
|
||||
|
||||
$(INSTDIR):
|
||||
@mkdir $(INSTDIR)
|
||||
|
||||
@@ -324,6 +342,8 @@ config.h: Makefile.netware
|
||||
@echo $(DL)#define HAVE_SEND 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIGNAL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIGNAL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIG_ATOMIC_T 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SOCKET 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STDINT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STDLIB_H 1$(DL) >> $@
|
||||
@@ -359,9 +379,10 @@ config.h: Makefile.netware
|
||||
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_TIMEVAL 1$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@
|
||||
ifdef DISABLE_LDAP
|
||||
@@ -401,28 +422,44 @@ ifdef WITH_SSL
|
||||
@echo $(DL)#define HAVE_LIBCRYPTO 1$(DL) >> $@
|
||||
@echo $(DL)#define OPENSSL_NO_KRB5 1$(DL) >> $@
|
||||
endif
|
||||
ifdef WITH_SSH2
|
||||
@echo $(DL)#define USE_LIBSSH2 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBSSH2_H 1$(DL) >> $@
|
||||
endif
|
||||
ifdef OLD_NOVELLSDK
|
||||
@echo $(DL)#define socklen_t int$(DL) >> $@
|
||||
endif
|
||||
|
||||
ca-bundle.h: Makefile.netware
|
||||
FORCE: ;
|
||||
|
||||
ca-bundle.h: FORCE Makefile.netware
|
||||
@echo Creating $@
|
||||
@echo $(DL)/* Do not edit this file - it is created by make!$(DL) > $@
|
||||
@echo $(DL)** All your changes will be lost!!$(DL) >> $@
|
||||
@echo $(DL)*/$(DL) >> $@
|
||||
ifdef CABUNDLE
|
||||
@echo $(DL)#define CURL_CA_BUNDLE "$(CABUNDLE)"$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")$(DL) >> $@
|
||||
|
||||
url.c: ca-bundle.h
|
||||
endif
|
||||
|
||||
info: $(OBJDIR)/version.inc
|
||||
@echo Configured to build $(TARGET) with these options:
|
||||
@echo curl version: $(LIBCURL_VERSION_STR)
|
||||
@echo compiler/linker: $(CC) / $(LD)
|
||||
ifdef CABUNDLE
|
||||
@echo ca-bundle path: $(CABUNDLE)
|
||||
endif
|
||||
ifdef WITH_SSL
|
||||
@echo SSL support: enabled (OpenSSL)
|
||||
else
|
||||
@echo SSL support: no
|
||||
endif
|
||||
ifdef WITH_SSH2
|
||||
@echo SSH2 support: enabled (libssh2)
|
||||
else
|
||||
@echo SSH2 support: no
|
||||
endif
|
||||
ifdef WITH_ZLIB
|
||||
@echo zlib support: enabled
|
||||
else
|
||||
|
@@ -132,8 +132,8 @@ CFGSET = TRUE
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIB_NAME).dll
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(RTLIB) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib
|
||||
CC = $(CCNODBG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
@@ -481,6 +481,7 @@ X_OBJS= \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(DIROBJ)\splay.obj \
|
||||
$(DIROBJ)\socks.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
all : $(TARGET)
|
||||
|
@@ -12,11 +12,11 @@ c-ares:
|
||||
http://daniel.haxx.se/projects/c-ares/
|
||||
|
||||
NOTE
|
||||
libcurl 7.11.1 builds with c-ares 1.1.0, but 7.11.2 and later require c-ares
|
||||
1.2.0 or alter.
|
||||
The latest libcurl version requires c-ares 1.3.2 or later to work
|
||||
flawlessly.
|
||||
|
||||
Once upon the time libcurl built fine with the "original" ares. That is no
|
||||
longer true. You need to use c-ares. c-ares is based on ares but improved.
|
||||
longer true. You need to use c-ares.
|
||||
|
||||
Build c-ares
|
||||
============
|
||||
|
@@ -29,7 +29,7 @@ Modify Your Application
|
||||
|
||||
Add a line in your application code:
|
||||
|
||||
curl_memdebug("filename");
|
||||
curl_memdebug("dump");
|
||||
|
||||
This will make the malloc debug system output a full trace of all resource
|
||||
using functions to the given file name. Make sure you rebuild your program
|
||||
@@ -45,9 +45,9 @@ Run Your Application
|
||||
|
||||
Analyze the Flow
|
||||
|
||||
Use the tests/memanalyze.pl perl script to analyze the memdump file:
|
||||
Use the tests/memanalyze.pl perl script to analyze the dump file:
|
||||
|
||||
tests/memanalyze.pl < memdump
|
||||
tests/memanalyze.pl dump
|
||||
|
||||
This now outputs a report on what resources that were allocated but never
|
||||
freed etc. This report is very fine for posting to the list!
|
||||
|
@@ -1,8 +1,6 @@
|
||||
Implementation of the curl_multi_socket API
|
||||
|
||||
Most of the design decisions and debates about this new API have already
|
||||
been held on the curl-library mailing list a long time ago so I had a basic
|
||||
idea on what approach to use. The main ideas of the new API are simply:
|
||||
The main ideas of the new API are simply:
|
||||
|
||||
1 - The application can use whatever event system it likes as it gets info
|
||||
from libcurl about what file descriptors libcurl waits for what action
|
||||
@@ -38,62 +36,33 @@ Implementation of the curl_multi_socket API
|
||||
is that we get a curl_multi_timeout() that should also work with old-style
|
||||
applications that use curl_multi_perform().
|
||||
|
||||
The easy handle argument was removed fom the curl_multi_socket() function
|
||||
because having it there would require the application to do a socket to easy
|
||||
handle conversion on its own. I find it very unlikely that applications
|
||||
would want to do that and since libcurl would need such a lookup on its own
|
||||
anyway since we didn't want to force applications to do that translation
|
||||
code (it would be optional), it seemed like an unnecessary option.
|
||||
We also added a timer callback that makes libcurl call the application when
|
||||
the timeout value changes, and you set that with curl_multi_setopt().
|
||||
|
||||
Instead I created an internal "socket to easy handles" hash table that given
|
||||
We created an internal "socket to easy handles" hash table that given
|
||||
a socket (file descriptor) return the easy handle that waits for action on
|
||||
that socket. This hash is made using the already existing hash code
|
||||
(previously only used for the DNS cache).
|
||||
|
||||
To make libcurl be able to report plain sockets in the socket callback, I
|
||||
had to re-organize the internals of the curl_multi_fdset() etc so that the
|
||||
To make libcurl able to report plain sockets in the socket callback, we had
|
||||
to re-organize the internals of the curl_multi_fdset() etc so that the
|
||||
conversion from sockets to fd_sets for that function is only done in the
|
||||
last step before the data is returned. I also had to extend c-ares to get a
|
||||
function that can return plain sockets, as that library too returned only
|
||||
fd_sets and that is no longer good enough. The changes done to c-ares have
|
||||
been committed and are available in the c-ares CVS repository destined to be
|
||||
included in the upcoming c-ares 1.3.1 release.
|
||||
included in the c-ares 1.3.1 release.
|
||||
|
||||
The 'shiper' tool is the test application I wrote that uses the new
|
||||
curl_multi_socket() in its current state. It seems to be working and it uses
|
||||
the API as it is documented and supposed to work. It is still using
|
||||
select(), because I needed that during development (like until I had the
|
||||
socket hash implemented etc) and because I haven't yet learned how to use
|
||||
libevent or similar.
|
||||
|
||||
The hiper/shiper tools are very simple and initiates lots of connections and
|
||||
have them running for the test period and then kills them all.
|
||||
|
||||
Since I wasn't done with the implementation until early January I haven't
|
||||
had time to run very many measurements and checks, but I have done a few
|
||||
runs with up to a few hundred connections (with a single active one). The
|
||||
curl_multi_socket() invoke then takes 3-6 microseconds in average (using the
|
||||
read-only-1-byte-at-a-time hack). If this number does increase a lot when we
|
||||
add connections, it certainly matches my in my opinion very ambitious goal.
|
||||
We are now below the 60 microseconds "per socket action" goal. It is
|
||||
destined to be somewhat higher the more connections we have since the hash
|
||||
table gets more populated and the splay tree will grow etc.
|
||||
|
||||
Some tests at 7000 and 9000 connections showed that the socket hash lookup
|
||||
is somewhat of a bottle neck. Its current implementation may be a bit too
|
||||
limiting. It simply has a fixed-size array, and on each entry in the array
|
||||
it has a linked list with entries. So the hash only checks which list to
|
||||
scan through. The code I had used so for used a list with merely 7 slots (as
|
||||
that is what the DNS hash uses) but with 7000 connections that would make an
|
||||
average of 1000 nodes in each list to run through. I upped that to 97 slots
|
||||
(I believe a prime is suitable) and noticed a significant speed increase. I
|
||||
need to reconsider the hash implementation or use a rather large default
|
||||
value like this. At 9000 connections I was still below 10us per call.
|
||||
We have done a test runs with up to 9000 connections (with a single active
|
||||
one). The curl_multi_socket() invoke then takes less than 10 microseconds in
|
||||
average (using the read-only-1-byte-at-a-time hack). We are now below the
|
||||
60 microseconds "per socket action" goal (the extra 50 is the time libevent
|
||||
needs).
|
||||
|
||||
Status Right Now
|
||||
|
||||
The curl_multi_socket() API is implemented according to how it is
|
||||
documented.
|
||||
documented. We deem it ready to use.
|
||||
|
||||
http://curl.haxx.se/libcurl/c/curl_multi_socket.html
|
||||
http://curl.haxx.se/libcurl/c/curl_multi_timeout.html
|
||||
@@ -101,12 +70,4 @@ Status Right Now
|
||||
|
||||
What is Left for the curl_multi_socket API
|
||||
|
||||
1 - More measuring with more extreme number of connections
|
||||
|
||||
2 - More testing with actual URLs and complete from start to end transfers.
|
||||
|
||||
I'm quite sure we don't set expire times all over in the code properly, so
|
||||
there is bound to be some timeout bugs left.
|
||||
|
||||
What it really takes is for me to commit the code and to make an official
|
||||
release with it so that we get people "out there" to help out testing it.
|
||||
Real world usage!
|
||||
|
@@ -1,34 +1,27 @@
|
||||
Doing HTTP Pipelining with libcurl
|
||||
==================================
|
||||
HTTP Pipelining with libcurl
|
||||
============================
|
||||
|
||||
Background
|
||||
|
||||
Since pipelining implies that one or more requests are sent to a server before
|
||||
the previous response(s) have been received, it cannot be implemented easily
|
||||
into libcurl's easy interface due to its synchronous nature. We therefore only
|
||||
aim on adding it for multi interface use.
|
||||
the previous response(s) have been received, we only support it for multi
|
||||
interface use.
|
||||
|
||||
Considerations
|
||||
|
||||
When using the multi interface, you create one easy handle for each transfer.
|
||||
Bascially any number of handles can be created, added and used with the multi
|
||||
interface - simultaneously. It is an interface designed to allow many
|
||||
simultaneous transfers while still using a single thread.
|
||||
|
||||
Pipelining however, will force us to allow apps to somehow "connect" two (or
|
||||
more) easy handles that are added to a multi handle. The first one sends a
|
||||
request and receives a response, just as normal, while the second (and
|
||||
subsequent) ones need to be attached to the first handle so that it can send
|
||||
its request on the same connection and then sit and wait until its response
|
||||
comes.
|
||||
simultaneous transfers while still using a single thread. Pipelining does not
|
||||
change any of these details.
|
||||
|
||||
API
|
||||
|
||||
We add a new option to curl_multi_setopt() called CURLMOPT_PIPELINING that
|
||||
enables "attempted pipelining" and then all easy handles used on that handle
|
||||
will attempt to use an existing pipeline.
|
||||
We've added a new option to curl_multi_setopt() called CURLMOPT_PIPELINING
|
||||
that enables "attempted pipelining" and then all easy handles used on that
|
||||
handle will attempt to use an existing pipeline.
|
||||
|
||||
Decisions Already Made
|
||||
Details
|
||||
|
||||
- A pipeline is only created if a previous connection exists to the same IP
|
||||
address that the new request is being made to use.
|
||||
@@ -50,22 +43,9 @@ Decisions Already Made
|
||||
be considered for pipelining. Also, asking for explicit pipelining on handle
|
||||
X may be tricky when handle X get a closed connection.
|
||||
|
||||
To Ponder About
|
||||
|
||||
- We need options to control max pipeline length, and probably how to behave
|
||||
if we reach that limit. As was discussed on the list, it can probably be
|
||||
made very complicated, so perhaps we can think of a way to pass all
|
||||
variables involved to a callback and let the application decide how to act
|
||||
in specific situations. Either way, these fancy options are only interesting
|
||||
to work on when everything is working and we have working apps to test with.
|
||||
|
||||
- Currently (before pipelining) we do not have any code or concept that lets
|
||||
multiple handles share the same physical connection. We need to carefully
|
||||
make sure that each easy handle knows exactly what they can do and when, on
|
||||
the shared connection.
|
||||
|
||||
- We need to keep a linked list of each handle that is part of a single pipe
|
||||
so that if it breaks, we know which handles that need to resend their
|
||||
requests. The pipe linked-lists could very well be "held" in the multi
|
||||
handle struct so that they won't "belong" to a particular easy handle that
|
||||
happens to be part of the pipeline during a certain period.
|
||||
|
98
lib/base64.c
98
lib/base64.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -40,28 +40,27 @@
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "urldata.h" /* for the SessionHandle definition */
|
||||
#include "easyif.h" /* for Curl_convert_... prototypes */
|
||||
#include "base64.h"
|
||||
#include "memory.h"
|
||||
|
||||
/* include memdebug.h last */
|
||||
#include "memdebug.h"
|
||||
|
||||
/* ---- Base64 Encoding/Decoding Table --- */
|
||||
static const char table64[]=
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
static void decodeQuantum(unsigned char *dest, const char *src)
|
||||
{
|
||||
unsigned int x = 0;
|
||||
int i;
|
||||
char *found;
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
if(src[i] >= 'A' && src[i] <= 'Z')
|
||||
x = (x << 6) + (unsigned int)(src[i] - 'A' + 0);
|
||||
else if(src[i] >= 'a' && src[i] <= 'z')
|
||||
x = (x << 6) + (unsigned int)(src[i] - 'a' + 26);
|
||||
else if(src[i] >= '0' && src[i] <= '9')
|
||||
x = (x << 6) + (unsigned int)(src[i] - '0' + 52);
|
||||
else if(src[i] == '+')
|
||||
x = (x << 6) + 62;
|
||||
else if(src[i] == '/')
|
||||
x = (x << 6) + 63;
|
||||
if((found = strchr(table64, src[i])))
|
||||
x = (x << 6) + (unsigned int)(found - table64);
|
||||
else if(src[i] == '=')
|
||||
x = (x << 6);
|
||||
}
|
||||
@@ -133,10 +132,6 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
||||
return rawlen;
|
||||
}
|
||||
|
||||
/* ---- Base64 Encoding --- */
|
||||
static const char table64[]=
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/*
|
||||
* Curl_base64_encode()
|
||||
*
|
||||
@@ -145,7 +140,8 @@ static const char table64[]=
|
||||
* went wrong, -1 is returned.
|
||||
*
|
||||
*/
|
||||
size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
|
||||
size_t Curl_base64_encode(struct SessionHandle *data,
|
||||
const char *inp, size_t insize, char **outptr)
|
||||
{
|
||||
unsigned char ibuf[3];
|
||||
unsigned char obuf[4];
|
||||
@@ -153,6 +149,9 @@ size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
|
||||
int inputparts;
|
||||
char *output;
|
||||
char *base64data;
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
char *convbuf;
|
||||
#endif
|
||||
|
||||
char *indata = (char *)inp;
|
||||
|
||||
@@ -165,6 +164,28 @@ size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
|
||||
if(NULL == output)
|
||||
return 0;
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/*
|
||||
* The base64 data needs to be created using the network encoding
|
||||
* not the host encoding. And we can't change the actual input
|
||||
* so we copy it to a buffer, translate it, and use that instead.
|
||||
*/
|
||||
if(data) {
|
||||
convbuf = (char*)malloc(insize);
|
||||
if(!convbuf) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(convbuf, indata, insize);
|
||||
if(CURLE_OK != Curl_convert_to_network(data, convbuf, insize)) {
|
||||
free(convbuf);
|
||||
return 0;
|
||||
}
|
||||
indata = convbuf; /* switch to the converted buffer */
|
||||
}
|
||||
#else
|
||||
(void)data;
|
||||
#endif
|
||||
|
||||
while(insize > 0) {
|
||||
for (i = inputparts = 0; i < 3; i++) {
|
||||
if(insize > 0) {
|
||||
@@ -209,6 +230,10 @@ size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
|
||||
*output=0;
|
||||
*outptr = base64data; /* make it return the actual data memory */
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
if(data)
|
||||
free(convbuf);
|
||||
#endif
|
||||
return strlen(base64data); /* return the length of the new data */
|
||||
}
|
||||
/* ---- End of Base64 Encoding ---- */
|
||||
@@ -231,14 +256,26 @@ int main(int argc, char **argv, char **envp)
|
||||
size_t base64Len;
|
||||
unsigned char *data;
|
||||
int dataLen;
|
||||
struct SessionHandle *handle = NULL;
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* get a Curl handle so Curl_base64_encode can translate properly */
|
||||
handle = curl_easy_init();
|
||||
if(handle == NULL) {
|
||||
fprintf(stderr, "Error: curl_easy_init failed\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
data = (unsigned char *)suck(&dataLen);
|
||||
base64Len = Curl_base64_encode(data, dataLen, &base64);
|
||||
base64Len = Curl_base64_encode(handle, data, dataLen, &base64);
|
||||
|
||||
fprintf(stderr, "%d\n", base64Len);
|
||||
fprintf(stdout, "%s", base64);
|
||||
fprintf(stdout, "%s\n", base64);
|
||||
|
||||
free(base64); free(data);
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
curl_easy_cleanup(handle);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -261,10 +298,17 @@ int main(int argc, char **argv, char **envp)
|
||||
unsigned char *data;
|
||||
int dataLen;
|
||||
int i, j;
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* get a Curl handle so main can translate properly */
|
||||
struct SessionHandle *handle = curl_easy_init();
|
||||
if(handle == NULL) {
|
||||
fprintf(stderr, "Error: curl_easy_init failed\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
base64 = (char *)suck(&base64Len);
|
||||
data = (unsigned char *)malloc(base64Len * 3/4 + 8);
|
||||
dataLen = Curl_base64_decode(base64, data);
|
||||
dataLen = Curl_base64_decode(base64, &data);
|
||||
|
||||
fprintf(stderr, "%d\n", dataLen);
|
||||
|
||||
@@ -279,13 +323,21 @@ int main(int argc, char **argv, char **envp)
|
||||
printf(" | ");
|
||||
|
||||
for(j=0; j < 0x10; j++)
|
||||
if((j+i) < dataLen)
|
||||
printf("%c", isgraph(data[i+j])?data[i+j]:'.');
|
||||
else
|
||||
if((j+i) < dataLen) {
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
if(CURLE_OK !=
|
||||
Curl_convert_from_network(handle, &data[i+j], (size_t)1))
|
||||
data[i+j] = '.';
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
printf("%c", ISGRAPH(data[i+j])?data[i+j]:'.');
|
||||
} else
|
||||
break;
|
||||
puts("");
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
curl_easy_cleanup(handle);
|
||||
#endif
|
||||
free(base64); free(data);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -22,6 +22,7 @@
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
size_t Curl_base64_encode(const char *input, size_t size, char **str);
|
||||
size_t Curl_base64_encode(struct SessionHandle *data,
|
||||
const char *input, size_t size, char **str);
|
||||
size_t Curl_base64_decode(const char *source, unsigned char **outptr);
|
||||
#endif
|
||||
|
@@ -31,6 +31,8 @@
|
||||
#define HAVE_SETJMP_H 1
|
||||
#define HAVE_SGTTY_H 1
|
||||
#define HAVE_SIGNAL 1
|
||||
#define HAVE_SIGNAL_H 1
|
||||
#define HAVE_SIG_ATOMIC_T 1
|
||||
#define HAVE_SOCKET 1
|
||||
#define HAVE_STRCASECMP 1
|
||||
#define HAVE_STRDUP 1
|
||||
@@ -39,6 +41,7 @@
|
||||
#define HAVE_STRINGS_H 1
|
||||
#define HAVE_STRING_H 1
|
||||
#define HAVE_STRSTR 1
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_SYS_SOCKIO_H 1
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#define HAVE_TIME_H 1
|
||||
#define HAVE_STDLIB_H 1
|
||||
#define HAVE_UTIME_H 1
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
@@ -27,9 +28,12 @@
|
||||
#define HAVE_MEMCPY 1
|
||||
#define HAVE_SELECT 1
|
||||
#define HAVE_SOCKET 1
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
|
||||
//#define HAVE_STRICMP 1
|
||||
#define HAVE_SIGACTION 1
|
||||
#define HAVE_SIGNAL_H 1
|
||||
#define HAVE_SIG_ATOMIC_T 1
|
||||
|
||||
#ifdef MACOS_SSL_SUPPORT
|
||||
# define USE_SSLEAY 1
|
||||
@@ -43,6 +47,8 @@
|
||||
|
||||
#define HAVE_FIONBIO 1
|
||||
|
||||
#define RETSIGTYPE void
|
||||
|
||||
#define HAVE_GETNAMEINFO 1
|
||||
#define GETNAMEINFO_QUAL_ARG1 const
|
||||
#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
|
||||
|
@@ -119,6 +119,9 @@
|
||||
/* Define if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define if you have the `timeval' struct. */
|
||||
#define HAVE_STRUCT_TIMEVAL
|
||||
|
||||
/* Define if you have the `inet_addr' function. */
|
||||
#undef HAVE_INET_ADDR
|
||||
|
||||
@@ -242,6 +245,15 @@
|
||||
/* Define if you have the `signal' function. */
|
||||
#define HAVE_SIGNAL
|
||||
|
||||
/* Define if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H
|
||||
|
||||
/* Define if sig_atomic_t is an available typedef. */
|
||||
#define HAVE_SIG_ATOMIC_T
|
||||
|
||||
/* Define if sig_atomic_t is already defined as volatile. */
|
||||
#undef HAVE_SIG_ATOMIC_T_VOLATILE
|
||||
|
||||
/* Define if you have the `socket' function. */
|
||||
#define HAVE_SOCKET
|
||||
|
||||
|
@@ -413,6 +413,15 @@
|
||||
/* Define to 1 if you have the `signal' function. */
|
||||
#define HAVE_SIGNAL 1
|
||||
|
||||
/* Define to 1 if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define to 1 if sig_atomic_t is an available typedef. */
|
||||
#define HAVE_SIG_ATOMIC_T 1
|
||||
|
||||
/* Define to 1 if sig_atomic_t is already defined as volatile. */
|
||||
/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
|
||||
|
||||
/* If you have sigsetjmp */
|
||||
/* #undef HAVE_SIGSETJMP */
|
||||
|
||||
@@ -475,6 +484,9 @@
|
||||
/* if struct sockaddr_storage is defined */
|
||||
/* #undef HAVE_STRUCT_SOCKADDR_STORAGE */
|
||||
|
||||
/* Define this if you have struct timeval */
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
|
||||
/* Define to 1 if you have the <sys/filio.h> header file. */
|
||||
#define HAVE_SYS_FILIO_H 1
|
||||
|
||||
|
@@ -57,6 +57,9 @@
|
||||
#define HAVE_PROCESS_H 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define if you have the <sgtty.h> header file. */
|
||||
/* #define HAVE_SGTTY_H 1 */
|
||||
|
||||
@@ -81,6 +84,9 @@
|
||||
/* Define if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define if you have the <sys/time.h> header file */
|
||||
/* #define HAVE_SYS_TIME_H 1 */
|
||||
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
@@ -122,6 +128,9 @@
|
||||
/* OTHER HEADER INFO */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if sig_atomic_t is an available typedef. */
|
||||
#define HAVE_SIG_ATOMIC_T 1
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
@@ -285,13 +294,11 @@
|
||||
#define in_addr_t unsigned long
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
/* #define RETSIGTYPE void */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to `unsigned' if size_t is not an available 'typedefed' type */
|
||||
/* #define size_t unsigned */
|
||||
|
||||
/* Define to 'int' if ssize_t is not an available 'typedefed' type */
|
||||
#if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || defined(__POCC__)
|
||||
#elif defined(_WIN64)
|
||||
#define ssize_t __int64
|
||||
#else
|
||||
#define ssize_t int
|
||||
#endif
|
||||
@@ -335,6 +342,9 @@
|
||||
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
#endif
|
||||
|
||||
/* Define this if you have struct timeval */
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* COMPILER SPECIFIC */
|
||||
/* ---------------------------------------------------------------- */
|
||||
@@ -342,6 +352,11 @@
|
||||
/* Undef keyword 'const' if it does not work. */
|
||||
/* #undef const */
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER > 1310)
|
||||
/* MSVC 2003 has gmtime_r */
|
||||
#define HAVE_GMTIME_R
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* LDAP LIBRARY FILES */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
@@ -48,6 +48,9 @@
|
||||
/* Define if you have the <netinet/in.h> header file. */
|
||||
/* #define HAVE_NETINET_IN_H 1 */
|
||||
|
||||
/* Define if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define if you have the <sgtty.h> header file. */
|
||||
/* #define HAVE_SGTTY_H 1 */
|
||||
|
||||
@@ -75,6 +78,9 @@
|
||||
/* Define if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define if you have the <sys/time.h> header file */
|
||||
/* #define HAVE_SYS_TIME_H 1 */
|
||||
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
/* #define HAVE_SYS_TYPES_H 1 */
|
||||
|
||||
@@ -111,6 +117,9 @@
|
||||
/* OTHER HEADER INFO */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if sig_atomic_t is an available typedef. */
|
||||
#define HAVE_SIG_ATOMIC_T 1
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
@@ -269,13 +278,15 @@
|
||||
#define in_addr_t unsigned long
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
/* #define RETSIGTYPE void */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to `unsigned' if size_t is not an available 'typedefed' type */
|
||||
/* #define size_t unsigned */
|
||||
|
||||
/* Define to 'int' if ssize_t is not an available 'typedefed' type */
|
||||
/* Define ssize_t if it is not an available 'typedefed' type */
|
||||
#if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || defined(__POCC__)
|
||||
#elif defined(_WIN64)
|
||||
#define ssize_t __int64
|
||||
#else
|
||||
#define ssize_t int
|
||||
#endif
|
||||
|
||||
/* Define to 'int' if socklen_t is not an available 'typedefed' type */
|
||||
#ifndef HAVE_WS2TCPIP_H
|
||||
@@ -307,6 +318,9 @@
|
||||
/* Define this if you have struct sockaddr_storage */
|
||||
/* #define HAVE_STRUCT_SOCKADDR_STORAGE 1 */
|
||||
|
||||
/* Define this if you have struct timeval */
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* COMPILER SPECIFIC */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
@@ -44,11 +44,15 @@
|
||||
#define HAVE_NET_IF_H 1
|
||||
#define HAVE_PROCESS_H 1
|
||||
#define HAVE_PERROR 1
|
||||
#define HAVE_RECV 1
|
||||
#define HAVE_SELECT 1
|
||||
#define HAVE_SEND 1
|
||||
#define HAVE_SETJMP_H 1
|
||||
#define HAVE_SETLOCALE 1
|
||||
#define HAVE_SETVBUF 1
|
||||
#define HAVE_SIGNAL 1
|
||||
#define HAVE_SIGNAL_H 1
|
||||
#define HAVE_SIG_ATOMIC_T 1
|
||||
#define HAVE_SOCKET 1
|
||||
#define HAVE_SPNEGO 1
|
||||
#define HAVE_STRDUP 1
|
||||
@@ -56,6 +60,7 @@
|
||||
#define HAVE_STRICMP 1
|
||||
#define HAVE_STRSTR 1
|
||||
#define HAVE_STRTOLL 1
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
@@ -74,6 +79,22 @@
|
||||
#define STDC_HEADERS 1
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Qualifiers for send() and recv().
|
||||
*/
|
||||
#define SEND_TYPE_ARG1 int
|
||||
#define SEND_QUAL_ARG2 const
|
||||
#define SEND_TYPE_ARG2 void *
|
||||
#define SEND_TYPE_ARG3 int
|
||||
#define SEND_TYPE_ARG4 int
|
||||
#define SEND_TYPE_RETV int
|
||||
|
||||
#define RECV_TYPE_ARG1 int
|
||||
#define RECV_TYPE_ARG2 void *
|
||||
#define RECV_TYPE_ARG3 int
|
||||
#define RECV_TYPE_ARG4 int
|
||||
#define RECV_TYPE_RETV int
|
||||
|
||||
|
||||
#define BSD
|
||||
|
||||
/* #define MALLOCDEBUG */
|
||||
@@ -108,10 +129,11 @@
|
||||
#define ssize_t int
|
||||
#endif
|
||||
|
||||
#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")
|
||||
|
||||
/* Target HAVE_x section
|
||||
*/
|
||||
#if defined(DJGPP)
|
||||
#define CURL_CA_BUNDLE "/dev/env/CURL_CA_BUNDLE"
|
||||
#define HAVE_BASENAME 1
|
||||
#define HAVE_STRCASECMP 1
|
||||
#define HAVE_SIGACTION 1
|
||||
@@ -126,15 +148,11 @@
|
||||
#if (DJGPP_MINOR < 4)
|
||||
#define _MPRINTF_REPLACE
|
||||
#endif
|
||||
#else
|
||||
#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__)
|
||||
#elif defined(__WATCOMC__)
|
||||
#define HAVE_STRCASECMP 1
|
||||
#endif
|
||||
|
||||
#if defined(__HIGHC__)
|
||||
#elif defined(__HIGHC__)
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
#endif
|
||||
|
||||
|
@@ -84,7 +84,7 @@
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef USE_WINSOCK
|
||||
#define EINPROGRESS WSAEINPROGRESS
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#define EISCONN WSAEISCONN
|
||||
@@ -121,7 +121,7 @@ singleipconnect(struct connectdata *conn,
|
||||
*/
|
||||
int Curl_sockerrno(void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef USE_WINSOCK
|
||||
return (int)WSAGetLastError();
|
||||
#else
|
||||
return errno;
|
||||
@@ -384,11 +384,10 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
if( bind(sockfd, sock, socksize) >= 0) {
|
||||
/* we succeeded to bind */
|
||||
struct Curl_sockaddr_storage add;
|
||||
size_t size;
|
||||
socklen_t size;
|
||||
|
||||
size = sizeof(add);
|
||||
if(getsockname(sockfd, (struct sockaddr *) &add,
|
||||
(socklen_t *)&size)<0) {
|
||||
if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
|
||||
failf(data, "getsockname() failed");
|
||||
return CURLE_HTTP_PORT_FAILED;
|
||||
}
|
||||
|
12
lib/cookie.c
12
lib/cookie.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -806,9 +806,11 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
****************************************************************************/
|
||||
void Curl_cookie_clearall(struct CookieInfo *cookies)
|
||||
{
|
||||
Curl_cookie_freelist(cookies->cookies);
|
||||
cookies->cookies = NULL;
|
||||
cookies->numcookies = 0;
|
||||
if(cookies) {
|
||||
Curl_cookie_freelist(cookies->cookies);
|
||||
cookies->cookies = NULL;
|
||||
cookies->numcookies = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@@ -958,7 +960,7 @@ int Curl_cookie_output(struct CookieInfo *c, char *dumphere)
|
||||
char *format_ptr;
|
||||
|
||||
fputs("# Netscape HTTP Cookie File\n"
|
||||
"# http://www.netscape.com/newsref/std/cookie_spec.html\n"
|
||||
"# http://curlm.haxx.se/rfc/cookie_spec.html\n"
|
||||
"# This file was generated by libcurl! Edit at your own risk.\n\n",
|
||||
out);
|
||||
co = c->cookies;
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
18
lib/dict.c
18
lib/dict.c
@@ -38,7 +38,7 @@
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
#ifdef WIN32
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
@@ -134,8 +134,8 @@ CURLcode Curl_dict(struct connectdata *conn, bool *done)
|
||||
struct SessionHandle *data=conn->data;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
|
||||
char *path = conn->path;
|
||||
curl_off_t *bytecount = &conn->bytecount;
|
||||
char *path = data->reqdata.path;
|
||||
curl_off_t *bytecount = &data->reqdata.keep.bytecount;
|
||||
|
||||
*done = TRUE; /* unconditionally */
|
||||
|
||||
@@ -196,8 +196,8 @@ CURLcode Curl_dict(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
failf(data, "Failed sending DICT request");
|
||||
else
|
||||
result = Curl_Transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
|
||||
-1, NULL); /* no upload */
|
||||
result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
|
||||
-1, NULL); /* no upload */
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@@ -243,8 +243,8 @@ CURLcode Curl_dict(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
failf(data, "Failed sending DICT request");
|
||||
else
|
||||
result = Curl_Transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
|
||||
-1, NULL); /* no upload */
|
||||
result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
|
||||
-1, NULL); /* no upload */
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
@@ -268,8 +268,8 @@ CURLcode Curl_dict(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
failf(data, "Failed sending DICT request");
|
||||
else
|
||||
result = Curl_Transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
|
||||
-1, NULL);
|
||||
result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
|
||||
-1, NULL);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
82
lib/easy.c
82
lib/easy.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
#include "strequal.h"
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
#ifdef WIN32
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
@@ -87,6 +87,7 @@
|
||||
#include "progress.h"
|
||||
#include "easyif.h"
|
||||
#include "sendf.h" /* for failf function prototype */
|
||||
#include <ca-bundle.h>
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -106,7 +107,7 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#ifdef USE_WINSOCK
|
||||
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
|
||||
of win32_init() */
|
||||
static void win32_cleanup(void)
|
||||
@@ -122,12 +123,12 @@ static CURLcode win32_init(void)
|
||||
WSADATA wsaData;
|
||||
int err;
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
wVersionRequested = MAKEWORD(2, 0);
|
||||
#else
|
||||
wVersionRequested = MAKEWORD(1, 1);
|
||||
#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
|
||||
Error IPV6_requires_winsock2
|
||||
#endif
|
||||
|
||||
wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
|
||||
|
||||
err = WSAStartup(wVersionRequested, &wsaData);
|
||||
|
||||
if (err != 0)
|
||||
@@ -469,6 +470,13 @@ CURLcode curl_easy_perform(CURL *curl)
|
||||
|
||||
}
|
||||
|
||||
if(!data->state.connc) {
|
||||
/* oops, no connection cache, make one up */
|
||||
data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1);
|
||||
if(!data->state.connc)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return Curl_perform(data);
|
||||
}
|
||||
#endif
|
||||
@@ -496,6 +504,13 @@ void Curl_easy_addmulti(struct SessionHandle *data,
|
||||
data->multi = multi;
|
||||
}
|
||||
|
||||
void Curl_easy_initHandleData(struct SessionHandle *data)
|
||||
{
|
||||
memset(&data->reqdata, 0, sizeof(struct HandleData));
|
||||
|
||||
data->reqdata.maxdownload = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_easy_getinfo() is an external interface that allows an app to retrieve
|
||||
* information from a performed transfer and similar.
|
||||
@@ -543,16 +558,14 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
|
||||
/* copy all userdefined values */
|
||||
outcurl->set = data->set;
|
||||
outcurl->state.numconnects = data->state.numconnects;
|
||||
outcurl->state.connects = (struct connectdata **)
|
||||
malloc(sizeof(struct connectdata *) * outcurl->state.numconnects);
|
||||
|
||||
if(!outcurl->state.connects) {
|
||||
if(data->state.used_interface == Curl_if_multi)
|
||||
outcurl->state.connc = data->state.connc;
|
||||
else
|
||||
outcurl->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1);
|
||||
|
||||
if(!outcurl->state.connc)
|
||||
break;
|
||||
}
|
||||
|
||||
memset(outcurl->state.connects, 0,
|
||||
sizeof(struct connectdata *)*outcurl->state.numconnects);
|
||||
|
||||
outcurl->state.lastconnect = -1;
|
||||
|
||||
@@ -574,18 +587,14 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
|
||||
/* duplicate all values in 'change' */
|
||||
|
||||
if(data->change.url) {
|
||||
outcurl->change.url = strdup(data->change.url);
|
||||
if(!outcurl->change.url)
|
||||
break;
|
||||
outcurl->change.url_alloc = TRUE;
|
||||
}
|
||||
if(data->change.proxy) {
|
||||
outcurl->change.proxy = strdup(data->change.proxy);
|
||||
if(!outcurl->change.proxy)
|
||||
break;
|
||||
outcurl->change.proxy_alloc = TRUE;
|
||||
}
|
||||
|
||||
if(data->change.referer) {
|
||||
outcurl->change.referer = strdup(data->change.referer);
|
||||
if(!outcurl->change.referer)
|
||||
@@ -599,18 +608,29 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
|
||||
outcurl->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_OF_NETWORK);
|
||||
outcurl->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
|
||||
CURL_ICONV_CODESET_OF_HOST);
|
||||
outcurl->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||
CURL_ICONV_CODESET_FOR_UTF8);
|
||||
#endif
|
||||
|
||||
Curl_easy_initHandleData(outcurl);
|
||||
|
||||
outcurl->magic = CURLEASY_MAGIC_NUMBER;
|
||||
|
||||
fail = FALSE; /* we reach this point and thus we are OK */
|
||||
|
||||
} while(0);
|
||||
|
||||
if(fail) {
|
||||
if(outcurl) {
|
||||
if(outcurl->state.connects)
|
||||
free(outcurl->state.connects);
|
||||
if(outcurl->state.connc->type == CONNCACHE_PRIVATE)
|
||||
Curl_rm_connc(outcurl->state.connc);
|
||||
if(outcurl->state.headerbuff)
|
||||
free(outcurl->state.headerbuff);
|
||||
if(outcurl->change.proxy)
|
||||
free(outcurl->change.proxy);
|
||||
if(outcurl->change.url)
|
||||
free(outcurl->change.url);
|
||||
if(outcurl->change.referer)
|
||||
@@ -631,12 +651,21 @@ void curl_easy_reset(CURL *curl)
|
||||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
Curl_safefree(data->reqdata.pathbuffer);
|
||||
data->reqdata.pathbuffer=NULL;
|
||||
|
||||
Curl_safefree(data->reqdata.proto.generic);
|
||||
data->reqdata.proto.generic=NULL;
|
||||
|
||||
/* zero out UserDefined data: */
|
||||
memset(&data->set, 0, sizeof(struct UserDefined));
|
||||
|
||||
/* zero out Progress data: */
|
||||
memset(&data->progress, 0, sizeof(struct Progress));
|
||||
|
||||
/* init Handle data */
|
||||
Curl_easy_initHandleData(data);
|
||||
|
||||
/* The remainder of these calls have been taken from Curl_open() */
|
||||
|
||||
data->set.out = stdout; /* default output to stdout */
|
||||
@@ -682,6 +711,9 @@ void curl_easy_reset(CURL *curl)
|
||||
/* This is our prefered CA cert bundle since install time */
|
||||
data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
|
||||
#endif
|
||||
|
||||
data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
|
||||
type */
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -28,6 +28,8 @@
|
||||
*/
|
||||
void Curl_easy_addmulti(struct SessionHandle *data, void *multi);
|
||||
|
||||
void Curl_easy_initHandleData(struct SessionHandle *data);
|
||||
|
||||
CURLcode Curl_convert_to_network(struct SessionHandle *data,
|
||||
char *buffer, size_t length);
|
||||
CURLcode Curl_convert_from_network(struct SessionHandle *data,
|
||||
|
@@ -116,10 +116,6 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
||||
return ns;
|
||||
}
|
||||
|
||||
#define ishex(in) ((in >= 'a' && in <= 'f') || \
|
||||
(in >= 'A' && in <= 'F') || \
|
||||
(in >= '0' && in <= '9'))
|
||||
|
||||
char *curl_easy_unescape(CURL *handle, const char *string, int length,
|
||||
int *olen)
|
||||
{
|
||||
@@ -138,7 +134,7 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length,
|
||||
|
||||
while(--alloc > 0) {
|
||||
in = *string;
|
||||
if(('%' == in) && ishex(string[1]) && ishex(string[2])) {
|
||||
if(('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
|
||||
/* this is two hexadecimal digits following a '%' */
|
||||
char hexstr[3];
|
||||
char *ptr;
|
||||
|
38
lib/file.c
38
lib/file.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
#ifdef WIN32
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
@@ -102,7 +102,7 @@
|
||||
*/
|
||||
CURLcode Curl_file_connect(struct connectdata *conn)
|
||||
{
|
||||
char *real_path = curl_easy_unescape(conn->data, conn->path, 0, NULL);
|
||||
char *real_path = curl_easy_unescape(conn->data, conn->data->reqdata.path, 0, NULL);
|
||||
struct FILEPROTO *file;
|
||||
int fd;
|
||||
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
|
||||
@@ -119,7 +119,11 @@ CURLcode Curl_file_connect(struct connectdata *conn)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
conn->proto.file = file;
|
||||
if (conn->data->reqdata.proto.file) {
|
||||
free(conn->data->reqdata.proto.file);
|
||||
}
|
||||
|
||||
conn->data->reqdata.proto.file = file;
|
||||
|
||||
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
|
||||
/* If the first character is a slash, and there's
|
||||
@@ -160,8 +164,8 @@ CURLcode Curl_file_connect(struct connectdata *conn)
|
||||
|
||||
file->fd = fd;
|
||||
if(!conn->data->set.upload && (fd == -1)) {
|
||||
failf(conn->data, "Couldn't open file %s", conn->path);
|
||||
Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE);
|
||||
failf(conn->data, "Couldn't open file %s", conn->data->reqdata.path);
|
||||
Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
|
||||
return CURLE_FILE_COULDNT_READ_FILE;
|
||||
}
|
||||
|
||||
@@ -169,10 +173,11 @@ CURLcode Curl_file_connect(struct connectdata *conn)
|
||||
}
|
||||
|
||||
CURLcode Curl_file_done(struct connectdata *conn,
|
||||
CURLcode status)
|
||||
CURLcode status, bool premature)
|
||||
{
|
||||
struct FILEPROTO *file = conn->proto.file;
|
||||
struct FILEPROTO *file = conn->data->reqdata.proto.file;
|
||||
(void)status; /* not used */
|
||||
(void)premature; /* not used */
|
||||
Curl_safefree(file->freepath);
|
||||
|
||||
if(file->fd != -1)
|
||||
@@ -189,7 +194,7 @@ CURLcode Curl_file_done(struct connectdata *conn,
|
||||
|
||||
static CURLcode file_upload(struct connectdata *conn)
|
||||
{
|
||||
struct FILEPROTO *file = conn->proto.file;
|
||||
struct FILEPROTO *file = conn->data->reqdata.proto.file;
|
||||
char *dir = strchr(file->path, DIRSEP);
|
||||
FILE *fp;
|
||||
CURLcode res=CURLE_OK;
|
||||
@@ -206,7 +211,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
*/
|
||||
conn->fread = data->set.fread;
|
||||
conn->fread_in = data->set.in;
|
||||
conn->upload_fromhere = buf;
|
||||
conn->data->reqdata.upload_fromhere = buf;
|
||||
|
||||
if(!dir)
|
||||
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
|
||||
@@ -297,7 +302,7 @@ CURLcode Curl_file(struct connectdata *conn, bool *done)
|
||||
return file_upload(conn);
|
||||
|
||||
/* get the fd from the connection phase */
|
||||
fd = conn->proto.file->fd;
|
||||
fd = conn->data->reqdata.proto.file->fd;
|
||||
|
||||
/* VMS: This only works reliable for STREAMLF files */
|
||||
if( -1 != fstat(fd, &statbuf)) {
|
||||
@@ -346,8 +351,8 @@ CURLcode Curl_file(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (conn->resume_from <= expected_size)
|
||||
expected_size -= conn->resume_from;
|
||||
if (data->reqdata.resume_from <= expected_size)
|
||||
expected_size -= data->reqdata.resume_from;
|
||||
else {
|
||||
failf(data, "failed to resume file:// transfer");
|
||||
return CURLE_BAD_DOWNLOAD_RESUME;
|
||||
@@ -363,8 +368,11 @@ CURLcode Curl_file(struct connectdata *conn, bool *done)
|
||||
if(fstated)
|
||||
Curl_pgrsSetDownloadSize(data, expected_size);
|
||||
|
||||
if(conn->resume_from)
|
||||
lseek(fd, conn->resume_from, SEEK_SET);
|
||||
if(data->reqdata.resume_from) {
|
||||
if(data->reqdata.resume_from !=
|
||||
lseek(fd, data->reqdata.resume_from, SEEK_SET))
|
||||
return CURLE_BAD_DOWNLOAD_RESUME;
|
||||
}
|
||||
|
||||
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -25,7 +25,7 @@
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_FILE
|
||||
CURLcode Curl_file(struct connectdata *, bool *done);
|
||||
CURLcode Curl_file_done(struct connectdata *, CURLcode);
|
||||
CURLcode Curl_file_done(struct connectdata *, CURLcode, bool premature);
|
||||
CURLcode Curl_file_connect(struct connectdata *);
|
||||
#endif
|
||||
#endif
|
||||
|
108
lib/formdata.c
108
lib/formdata.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -24,7 +24,7 @@
|
||||
/*
|
||||
Debug the form generator stand-alone by compiling this source file with:
|
||||
|
||||
gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -o formdata -I../include formdata.c strequal.c
|
||||
gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -DCURLDEBUG -o formdata -I../include formdata.c strequal.c memdebug.c mprintf.c strerror.c
|
||||
|
||||
run the 'formdata' executable the output should end with:
|
||||
All Tests seem to have worked ...
|
||||
@@ -63,7 +63,7 @@ Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz
|
||||
Content-Disposition: attachment; filename="inet_ntoa_r.h"
|
||||
Content-Type: text/plain
|
||||
...
|
||||
Content-Disposition: attachment; filename="Makefile.b32.resp"
|
||||
Content-Disposition: attachment; filename="Makefile.b32"
|
||||
Content-Type: text/plain
|
||||
...
|
||||
|
||||
@@ -73,7 +73,7 @@ Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1
|
||||
Content-Disposition: attachment; filename="inet_ntoa_r.h"
|
||||
Content-Type: text/plain
|
||||
...
|
||||
Content-Disposition: attachment; filename="Makefile.b32.resp"
|
||||
Content-Disposition: attachment; filename="Makefile.b32"
|
||||
Content-Type: text/plain
|
||||
...
|
||||
Content-Disposition: attachment; filename="inet_ntoa_r.h"
|
||||
@@ -87,7 +87,7 @@ Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1
|
||||
Content-Disposition: attachment; filename="inet_ntoa_r.h"
|
||||
Content-Type: text/plain
|
||||
...
|
||||
Content-Disposition: attachment; filename="Makefile.b32.resp"
|
||||
Content-Disposition: attachment; filename="Makefile.b32"
|
||||
Content-Type: text/plain
|
||||
...
|
||||
Content-Disposition: attachment; filename="inet_ntoa_r.h"
|
||||
@@ -118,6 +118,8 @@ Content-Disposition: form-data; name="FILECONTENT"
|
||||
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
#include "urldata.h" /* for struct SessionHandle */
|
||||
#include "easyif.h" /* for Curl_convert_... prototypes */
|
||||
#include "formdata.h"
|
||||
#include "strequal.h"
|
||||
#include "memory.h"
|
||||
@@ -452,7 +454,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
* Set the Name property.
|
||||
*/
|
||||
case CURLFORM_PTRNAME:
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/* treat CURLFORM_PTR like CURLFORM_COPYNAME so we'll
|
||||
have safe memory for the eventual conversion */
|
||||
#else
|
||||
current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
|
||||
#endif
|
||||
case CURLFORM_COPYNAME:
|
||||
if (current_form->name)
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
@@ -835,7 +842,7 @@ static CURLcode AddFormData(struct FormData **formp,
|
||||
*formp = newform;
|
||||
|
||||
if (size) {
|
||||
if(type == FORM_DATA)
|
||||
if((type == FORM_DATA) || (type == FORM_CONTENT))
|
||||
*size += length;
|
||||
else {
|
||||
/* Since this is a file to be uploaded here, add the size of the actual
|
||||
@@ -872,10 +879,11 @@ static CURLcode AddFormDataf(struct FormData **formp,
|
||||
* Curl_formclean() is used from http.c, this cleans a built FormData linked
|
||||
* list
|
||||
*/
|
||||
void Curl_formclean(struct FormData *form)
|
||||
void Curl_formclean(struct FormData **form_ptr)
|
||||
{
|
||||
struct FormData *next;
|
||||
struct FormData *next, *form;
|
||||
|
||||
form = *form_ptr;
|
||||
if(!form)
|
||||
return;
|
||||
|
||||
@@ -885,8 +893,40 @@ void Curl_formclean(struct FormData *form)
|
||||
free(form); /* free the struct */
|
||||
|
||||
} while ((form = next) != NULL); /* continue */
|
||||
|
||||
*form_ptr = NULL;
|
||||
}
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
/*
|
||||
* Curl_formcovert() is used from http.c, this converts any
|
||||
form items that need to be sent in the network encoding.
|
||||
Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_formconvert(struct SessionHandle *data, struct FormData *form)
|
||||
{
|
||||
struct FormData *next;
|
||||
CURLcode rc;
|
||||
|
||||
if(!form)
|
||||
return CURLE_OK;
|
||||
|
||||
if(!data)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
do {
|
||||
next=form->next; /* the following form line */
|
||||
if (form->type == FORM_DATA) {
|
||||
rc = Curl_convert_to_network(data, form->line, form->length);
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
if (rc != CURLE_OK)
|
||||
return rc;
|
||||
}
|
||||
} while ((form = next) != NULL); /* continue */
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
/*
|
||||
* curl_formget()
|
||||
* Serialize a curl_httppost struct.
|
||||
@@ -917,18 +957,18 @@ int curl_formget(struct curl_httppost *form, void *arg,
|
||||
if (temp.fp) {
|
||||
fclose(temp.fp);
|
||||
}
|
||||
Curl_formclean(data);
|
||||
Curl_formclean(&data);
|
||||
return -1;
|
||||
}
|
||||
} while (read == sizeof(buffer));
|
||||
} else {
|
||||
if (ptr->length != append(arg, ptr->line, ptr->length)) {
|
||||
Curl_formclean(data);
|
||||
Curl_formclean(&data);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Curl_formclean(data);
|
||||
Curl_formclean(&data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1179,7 +1219,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
curList = curList->next;
|
||||
}
|
||||
if (result) {
|
||||
Curl_formclean(firstform);
|
||||
Curl_formclean(&firstform);
|
||||
free(boundary);
|
||||
return result;
|
||||
}
|
||||
@@ -1194,7 +1234,10 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
if(file->contenttype &&
|
||||
!checkprefix("text/", file->contenttype)) {
|
||||
/* this is not a text content, mention our binary encoding */
|
||||
size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0);
|
||||
result = AddFormDataf(&form, &size,
|
||||
"\r\nContent-Transfer-Encoding: binary");
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1232,21 +1275,26 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
size_t nread;
|
||||
char buffer[512];
|
||||
while ((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
|
||||
result = AddFormData(&form, FORM_DATA, buffer, nread, &size);
|
||||
result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
Curl_formclean(firstform);
|
||||
Curl_formclean(&firstform);
|
||||
free(boundary);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
Curl_formclean(firstform);
|
||||
#ifdef _FORM_DEBUG
|
||||
fprintf(stderr,
|
||||
"\n==> Curl_getFormData couldn't open/read \"%s\"\n",
|
||||
file->contents);
|
||||
#endif
|
||||
Curl_formclean(&firstform);
|
||||
free(boundary);
|
||||
*finalform = NULL;
|
||||
return CURLE_READ_ERROR;
|
||||
@@ -1255,7 +1303,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
}
|
||||
else if (post->flags & HTTPPOST_BUFFER) {
|
||||
/* include contents of buffer */
|
||||
result = AddFormData(&form, FORM_DATA, post->buffer,
|
||||
result = AddFormData(&form, FORM_CONTENT, post->buffer,
|
||||
post->bufferlength, &size);
|
||||
if (result)
|
||||
break;
|
||||
@@ -1263,14 +1311,14 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
|
||||
else {
|
||||
/* include the contents we got */
|
||||
result = AddFormData(&form, FORM_DATA, post->contents,
|
||||
result = AddFormData(&form, FORM_CONTENT, post->contents,
|
||||
post->contentslength, &size);
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
} while ((file = file->more) != NULL); /* for each specified file for this field */
|
||||
if (result) {
|
||||
Curl_formclean(firstform);
|
||||
Curl_formclean(&firstform);
|
||||
free(boundary);
|
||||
return result;
|
||||
}
|
||||
@@ -1288,7 +1336,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
|
||||
} while ((post = post->next) != NULL); /* for each field */
|
||||
if (result) {
|
||||
Curl_formclean(firstform);
|
||||
Curl_formclean(&firstform);
|
||||
free(boundary);
|
||||
return result;
|
||||
}
|
||||
@@ -1298,7 +1346,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
"\r\n--%s--\r\n",
|
||||
boundary);
|
||||
if (result) {
|
||||
Curl_formclean(firstform);
|
||||
Curl_formclean(&firstform);
|
||||
free(boundary);
|
||||
return result;
|
||||
}
|
||||
@@ -1397,7 +1445,7 @@ size_t Curl_FormReader(char *buffer,
|
||||
|
||||
form->data = form->data->next; /* advance */
|
||||
|
||||
} while(form->data && (form->data->type == FORM_DATA));
|
||||
} while(form->data && (form->data->type != FORM_FILE));
|
||||
/* If we got an empty line and we have more data, we proceed to the next
|
||||
line immediately to avoid returning zero before we've reached the end.
|
||||
This is the bug reported November 22 1999 on curl 6.3. (Daniel) */
|
||||
@@ -1464,7 +1512,7 @@ int main()
|
||||
char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH";
|
||||
char value6[] = "value for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE";
|
||||
char value7[] = "inet_ntoa_r.h";
|
||||
char value8[] = "Makefile.b32.resp";
|
||||
char value8[] = "Makefile.b32";
|
||||
char type2[] = "image/gif";
|
||||
char type6[] = "text/plain";
|
||||
char type7[] = "text/html";
|
||||
@@ -1473,7 +1521,8 @@ int main()
|
||||
int value5length = strlen(value4);
|
||||
int value6length = strlen(value5);
|
||||
int errors = 0;
|
||||
int size;
|
||||
CURLcode rc;
|
||||
size_t size;
|
||||
size_t nread;
|
||||
char buffer[4096];
|
||||
struct curl_httppost *httppost=NULL;
|
||||
@@ -1549,7 +1598,14 @@ int main()
|
||||
CURLFORM_END))
|
||||
++errors;
|
||||
|
||||
form=Curl_getFormData(httppost, &size);
|
||||
rc = Curl_getFormData(&form, httppost, NULL, &size);
|
||||
if(rc != CURLE_OK) {
|
||||
if(rc != CURLE_READ_ERROR) {
|
||||
const char *errortext = curl_easy_strerror(rc);
|
||||
fprintf(stdout, "\n==> Curl_getFormData error: %s\n", errortext);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Curl_FormInit(&formread, form);
|
||||
|
||||
@@ -1557,7 +1613,7 @@ int main()
|
||||
nread = Curl_FormReader(buffer, 1, sizeof(buffer),
|
||||
(FILE *)&formread);
|
||||
|
||||
if(-1 == nread)
|
||||
if(nread < 1)
|
||||
break;
|
||||
fwrite(buffer, nread, 1, stdout);
|
||||
} while(1);
|
||||
|
@@ -8,7 +8,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -25,8 +25,10 @@
|
||||
***************************************************************************/
|
||||
|
||||
enum formtype {
|
||||
FORM_DATA, /* regular data */
|
||||
FORM_FILE /* 'line' points to a file name we should read from */
|
||||
FORM_DATA, /* form metadata (convert to network encoding if necessary) */
|
||||
FORM_CONTENT, /* form content (never convert) */
|
||||
FORM_FILE /* 'line' points to a file name we should read from
|
||||
to create the form data (never convert) */
|
||||
};
|
||||
|
||||
/* plain and simple linked list with lines to send */
|
||||
@@ -87,7 +89,9 @@ char *Curl_formpostheader(void *formp, size_t *len);
|
||||
|
||||
char *Curl_FormBoundary(void);
|
||||
|
||||
void Curl_formclean(struct FormData *);
|
||||
void Curl_formclean(struct FormData **);
|
||||
|
||||
CURLcode Curl_formconvert(struct SessionHandle *, struct FormData *);
|
||||
|
||||
#endif
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user