Compare commits
433 Commits
curl-7_11_
...
pre-aifix
Author | SHA1 | Date | |
---|---|---|---|
![]() |
818aed35e2 | ||
![]() |
2ed524f07e | ||
![]() |
5f1eefd03f | ||
![]() |
522b4d7576 | ||
![]() |
d6dcb08407 | ||
![]() |
806c756a2d | ||
![]() |
2494701347 | ||
![]() |
1c10272e15 | ||
![]() |
0badcf381a | ||
![]() |
35558e6bd7 | ||
![]() |
7659747e6f | ||
![]() |
53189fb2d7 | ||
![]() |
450c178d77 | ||
![]() |
a20eb6df1b | ||
![]() |
d73425061a | ||
![]() |
0051d5ac88 | ||
![]() |
76920413d9 | ||
![]() |
44d9a8ba4e | ||
![]() |
38dc548a87 | ||
![]() |
dca6386234 | ||
![]() |
2a701a1aac | ||
![]() |
0cb297abc9 | ||
![]() |
821a23535b | ||
![]() |
bc80599178 | ||
![]() |
941374b573 | ||
![]() |
1886893d66 | ||
![]() |
7291772b1f | ||
![]() |
8e28721057 | ||
![]() |
8d2120566e | ||
![]() |
67341c4cbe | ||
![]() |
f8188ddfee | ||
![]() |
29c546b426 | ||
![]() |
0d259b898b | ||
![]() |
c136b80af5 | ||
![]() |
83b87d53c1 | ||
![]() |
1e99f1ee41 | ||
![]() |
d7fe136d54 | ||
![]() |
cd7a0f829f | ||
![]() |
cf3f1ef284 | ||
![]() |
a737864a1c | ||
![]() |
c68a6805b3 | ||
![]() |
bd3d5a17b4 | ||
![]() |
d4b577114b | ||
![]() |
713effb6e4 | ||
![]() |
b92e2ab6b1 | ||
![]() |
05baf94b43 | ||
![]() |
a76288b99a | ||
![]() |
557e95c0a3 | ||
![]() |
0a83fa90bb | ||
![]() |
daeb143177 | ||
![]() |
9f752120c0 | ||
![]() |
80a1e972fc | ||
![]() |
5e65d48ffa | ||
![]() |
752ef08141 | ||
![]() |
070e0e8b0a | ||
![]() |
2ed0728cef | ||
![]() |
a79b9e9d4a | ||
![]() |
24572daccc | ||
![]() |
1770563fff | ||
![]() |
4cd96483f6 | ||
![]() |
8f1783b8a7 | ||
![]() |
be72eaa327 | ||
![]() |
61bded1d82 | ||
![]() |
4b3937373a | ||
![]() |
08bf0907d4 | ||
![]() |
eb044f8787 | ||
![]() |
8d0c77403c | ||
![]() |
601062455c | ||
![]() |
5be788ba36 | ||
![]() |
281559b31b | ||
![]() |
ef1aa4e5e9 | ||
![]() |
7b7ac04895 | ||
![]() |
60f5b2b275 | ||
![]() |
c0f9d7fdb7 | ||
![]() |
fc4d6f73a6 | ||
![]() |
295169f9d9 | ||
![]() |
1a3797a699 | ||
![]() |
977e106924 | ||
![]() |
8d76d4016d | ||
![]() |
9f92657f76 | ||
![]() |
9f341f9ce5 | ||
![]() |
2098871509 | ||
![]() |
3d00c86f4c | ||
![]() |
90037b85d1 | ||
![]() |
6ec145d4b4 | ||
![]() |
40a58c392f | ||
![]() |
9733cd59bb | ||
![]() |
b3caf7bfa8 | ||
![]() |
23fbb89805 | ||
![]() |
bd1adaf7ea | ||
![]() |
0c9e23fc0c | ||
![]() |
f091ce64ac | ||
![]() |
55a69ebea6 | ||
![]() |
d6b3850562 | ||
![]() |
80197cf493 | ||
![]() |
8ee564c216 | ||
![]() |
5bfeb60a83 | ||
![]() |
1ab4a2f870 | ||
![]() |
2a627059ac | ||
![]() |
3f739acf24 | ||
![]() |
d3454ceb94 | ||
![]() |
59695c05b1 | ||
![]() |
f0969c9692 | ||
![]() |
18dd8154e2 | ||
![]() |
4c58797607 | ||
![]() |
d620f1e529 | ||
![]() |
e0b436f8e1 | ||
![]() |
e99d1e97de | ||
![]() |
1fb74b4fa2 | ||
![]() |
473f6ea9f0 | ||
![]() |
0b04c52119 | ||
![]() |
8383945acc | ||
![]() |
fce9d51122 | ||
![]() |
7c3ee84295 | ||
![]() |
a8db25f48b | ||
![]() |
20705ca311 | ||
![]() |
af33c6b549 | ||
![]() |
2b8775dff7 | ||
![]() |
ea81dd9e2e | ||
![]() |
7dcb102733 | ||
![]() |
aa0e32060e | ||
![]() |
2e8f37aca5 | ||
![]() |
195d769c4b | ||
![]() |
70f08b5baa | ||
![]() |
9e987ac6a2 | ||
![]() |
de03f172ad | ||
![]() |
0078944486 | ||
![]() |
d3f796ac59 | ||
![]() |
3d38080d54 | ||
![]() |
fe07962f9c | ||
![]() |
938a72b2db | ||
![]() |
a8827b1ed6 | ||
![]() |
ff40cd71ac | ||
![]() |
39626d8cfd | ||
![]() |
67ad29e716 | ||
![]() |
8bbf9b13af | ||
![]() |
cb21851c74 | ||
![]() |
8d611bec6e | ||
![]() |
1de1dc7314 | ||
![]() |
aca79af7de | ||
![]() |
da6eea9b38 | ||
![]() |
dcf7310b2d | ||
![]() |
c2e8ba0fba | ||
![]() |
a5360255ba | ||
![]() |
5690a2b493 | ||
![]() |
ff0429a802 | ||
![]() |
46cdc83b81 | ||
![]() |
76dfef7117 | ||
![]() |
de2aeb9fc2 | ||
![]() |
17a5b44205 | ||
![]() |
f99e347878 | ||
![]() |
f5a0c17322 | ||
![]() |
8442c3942d | ||
![]() |
15cd35f67f | ||
![]() |
459801d6e0 | ||
![]() |
2c43d64302 | ||
![]() |
fd802db39f | ||
![]() |
765754d39d | ||
![]() |
f7f6b288eb | ||
![]() |
11ee9540bf | ||
![]() |
f6319bd706 | ||
![]() |
0912015a5c | ||
![]() |
4e7575fc7a | ||
![]() |
6531a6116d | ||
![]() |
9a33561e80 | ||
![]() |
88229a0f2a | ||
![]() |
120394cc45 | ||
![]() |
1adfe0fe18 | ||
![]() |
d57c178a62 | ||
![]() |
6faa83bc6a | ||
![]() |
9fb4e019fa | ||
![]() |
74551597b1 | ||
![]() |
37c269d0ba | ||
![]() |
5d8b526b80 | ||
![]() |
83dcc3e061 | ||
![]() |
4ed58463f7 | ||
![]() |
85b2056dc7 | ||
![]() |
94ca911dc1 | ||
![]() |
24420c2191 | ||
![]() |
59f904d8de | ||
![]() |
755f98e768 | ||
![]() |
aadc797225 | ||
![]() |
5c882bdfa3 | ||
![]() |
60f9450594 | ||
![]() |
ff52ba7f7b | ||
![]() |
0fbcea45d6 | ||
![]() |
ca6d430561 | ||
![]() |
91601b3bf4 | ||
![]() |
cdd70596df | ||
![]() |
7e186f9a63 | ||
![]() |
a94e117ede | ||
![]() |
662cb30372 | ||
![]() |
bd3aba5d6a | ||
![]() |
29ed6d24bf | ||
![]() |
e2c5c20896 | ||
![]() |
7c4b6cb0d9 | ||
![]() |
aced2904ff | ||
![]() |
17eb1fca7c | ||
![]() |
2511d1193a | ||
![]() |
e9056f5f95 | ||
![]() |
a9893ca79a | ||
![]() |
f39f7c28f0 | ||
![]() |
a807065ccc | ||
![]() |
67532e916c | ||
![]() |
3920b4dae8 | ||
![]() |
d70a335dce | ||
![]() |
8001921112 | ||
![]() |
d7cb09bd18 | ||
![]() |
e11710714c | ||
![]() |
5b0bfc298f | ||
![]() |
0383f7f19d | ||
![]() |
23a43c6e0f | ||
![]() |
eb946690d2 | ||
![]() |
c090fdbdf1 | ||
![]() |
de279099e5 | ||
![]() |
6bd8db3c99 | ||
![]() |
6176f14141 | ||
![]() |
512e54ff85 | ||
![]() |
a5aa569fe3 | ||
![]() |
e2e593a036 | ||
![]() |
9ce0a7b49d | ||
![]() |
4ab0d74250 | ||
![]() |
b5f85ba77d | ||
![]() |
b6ee33c6e1 | ||
![]() |
1c69b15c7c | ||
![]() |
54cd2bee58 | ||
![]() |
5bf02b16a0 | ||
![]() |
594cb8507b | ||
![]() |
78aba6e4cd | ||
![]() |
ccdcdb2a46 | ||
![]() |
b121e41ec3 | ||
![]() |
05d8e56ffd | ||
![]() |
4345c7a712 | ||
![]() |
12d5e33dc9 | ||
![]() |
6d70a82757 | ||
![]() |
47d52d4eca | ||
![]() |
4973b0f88a | ||
![]() |
d1542bf549 | ||
![]() |
2b7727aad1 | ||
![]() |
fd775454ca | ||
![]() |
8e09a389c4 | ||
![]() |
aa3ae01878 | ||
![]() |
c123676825 | ||
![]() |
d60c22572b | ||
![]() |
1d7ce36791 | ||
![]() |
34e8baab9a | ||
![]() |
a219d774fe | ||
![]() |
005042e973 | ||
![]() |
d301d69fbf | ||
![]() |
34af02caca | ||
![]() |
91025d1dd6 | ||
![]() |
c9bab31a7f | ||
![]() |
2f60e91a9b | ||
![]() |
018affe6d0 | ||
![]() |
aeb27ccfdb | ||
![]() |
939866faab | ||
![]() |
98f968f2ee | ||
![]() |
864f1a3366 | ||
![]() |
f42b10242f | ||
![]() |
853134017d | ||
![]() |
d3999e06d1 | ||
![]() |
0b0b37cffe | ||
![]() |
a13f5888d5 | ||
![]() |
c8807438ce | ||
![]() |
3f106afd00 | ||
![]() |
d925057e11 | ||
![]() |
bbafb2eb27 | ||
![]() |
434bc13812 | ||
![]() |
5c592f7dd9 | ||
![]() |
9bf1ba2f7e | ||
![]() |
724e4a3585 | ||
![]() |
f69711fc78 | ||
![]() |
04e2520dbb | ||
![]() |
7a35fb5403 | ||
![]() |
63f97b38eb | ||
![]() |
b8541929c8 | ||
![]() |
329f17ac7c | ||
![]() |
5dcab07c54 | ||
![]() |
1f798affb9 | ||
![]() |
a2ecdf4249 | ||
![]() |
71fdc063bd | ||
![]() |
887d78a9ad | ||
![]() |
00557a5475 | ||
![]() |
e18d27b78a | ||
![]() |
228fea4628 | ||
![]() |
e64dacb40e | ||
![]() |
fff01f24bf | ||
![]() |
e55dee3807 | ||
![]() |
8c2ce33c0b | ||
![]() |
135394f511 | ||
![]() |
fe065dc851 | ||
![]() |
445c7791a7 | ||
![]() |
686ba84128 | ||
![]() |
3394c01826 | ||
![]() |
d67ea8c7ad | ||
![]() |
535046430a | ||
![]() |
9aebdff219 | ||
![]() |
90da930131 | ||
![]() |
fbdc1b1e3d | ||
![]() |
e942df755b | ||
![]() |
91c8be3628 | ||
![]() |
d56c03840b | ||
![]() |
d3d5cdf305 | ||
![]() |
af43ce73e5 | ||
![]() |
84b52e92f4 | ||
![]() |
0aa7d11cc9 | ||
![]() |
933f7cecae | ||
![]() |
8e73e55336 | ||
![]() |
55c015c136 | ||
![]() |
bde6c6685e | ||
![]() |
58387b91f9 | ||
![]() |
6f74820cfc | ||
![]() |
af72f198ba | ||
![]() |
3fc831f9eb | ||
![]() |
9f660862ec | ||
![]() |
1354671c90 | ||
![]() |
1175a226e3 | ||
![]() |
358b72bb12 | ||
![]() |
6c408c885a | ||
![]() |
9cf04dff6a | ||
![]() |
6bdcfecbcf | ||
![]() |
3f21fe60fc | ||
![]() |
b2c290e40e | ||
![]() |
bc5b2fa12c | ||
![]() |
32a9554c92 | ||
![]() |
afc1ed60f7 | ||
![]() |
91018f4f24 | ||
![]() |
fb086b57a8 | ||
![]() |
3fc39a6efb | ||
![]() |
6062ac7c37 | ||
![]() |
caf7854a3c | ||
![]() |
6def0892ea | ||
![]() |
1c0744bde6 | ||
![]() |
7591e07b7c | ||
![]() |
35ab93f484 | ||
![]() |
dcf5e52b62 | ||
![]() |
aae521d086 | ||
![]() |
78e6508e22 | ||
![]() |
4d9517f0b4 | ||
![]() |
a331aa0221 | ||
![]() |
679cabb532 | ||
![]() |
7332350e85 | ||
![]() |
69f4dda74a | ||
![]() |
c19c3bd15a | ||
![]() |
76ff92b811 | ||
![]() |
4250637e7d | ||
![]() |
08d1da106e | ||
![]() |
9e31a0536e | ||
![]() |
2960d37d71 | ||
![]() |
c63af5fc01 | ||
![]() |
fc6eff13b5 | ||
![]() |
e7ee1ccf45 | ||
![]() |
98bf69f8f1 | ||
![]() |
0363fbc411 | ||
![]() |
e3bc92ae53 | ||
![]() |
27e76021e9 | ||
![]() |
93dde29979 | ||
![]() |
d42dcd60cd | ||
![]() |
ade89799f5 | ||
![]() |
6e118ce50f | ||
![]() |
34be9df773 | ||
![]() |
7356a67780 | ||
![]() |
f77949ef3b | ||
![]() |
26b8b3fc53 | ||
![]() |
38cc79a54f | ||
![]() |
ec113aefb9 | ||
![]() |
913e1570bd | ||
![]() |
e2aaf22d5d | ||
![]() |
3304589043 | ||
![]() |
0247642bb6 | ||
![]() |
19f5aa165c | ||
![]() |
1756499b11 | ||
![]() |
15f9a93c25 | ||
![]() |
e99287734b | ||
![]() |
8349dde0f1 | ||
![]() |
59907ebc0e | ||
![]() |
da91d6ac66 | ||
![]() |
7548115a0e | ||
![]() |
8ca37dd1c7 | ||
![]() |
31e9e4bb76 | ||
![]() |
84a322ab23 | ||
![]() |
707f217b2d | ||
![]() |
e6b45a66ec | ||
![]() |
b34c40dcf5 | ||
![]() |
699ebe2f0b | ||
![]() |
e1c6f216c2 | ||
![]() |
630b73bfa8 | ||
![]() |
877f16e5a5 | ||
![]() |
fbe1fa9dcc | ||
![]() |
5b65cc55a2 | ||
![]() |
97769737d0 | ||
![]() |
5b0a5c4050 | ||
![]() |
4b9f8e766d | ||
![]() |
96002646f1 | ||
![]() |
5ef6904ec3 | ||
![]() |
2f53da5e7a | ||
![]() |
58f1cc0b5f | ||
![]() |
98c70b73f2 | ||
![]() |
6bd02a3ab5 | ||
![]() |
372e7a6cd4 | ||
![]() |
211004bb0d | ||
![]() |
80d2fff1a1 | ||
![]() |
cf3cf413c8 | ||
![]() |
e218811ca3 | ||
![]() |
a9f2274bd8 | ||
![]() |
92179ff990 | ||
![]() |
4aac210a83 | ||
![]() |
245e3122df | ||
![]() |
ffc5fa3a2b | ||
![]() |
f5042cce34 | ||
![]() |
712c67b4ae | ||
![]() |
5dcfb8ad66 | ||
![]() |
673ff5eb2c | ||
![]() |
92fc3f07ba | ||
![]() |
cff90cf3f9 | ||
![]() |
a33c53a36b | ||
![]() |
2370d4fa02 | ||
![]() |
f128d904a5 | ||
![]() |
fb1039f2ab | ||
![]() |
923ce98e42 | ||
![]() |
8e935b58a2 | ||
![]() |
c93e972543 | ||
![]() |
1cb66f5262 | ||
![]() |
648e82f05d | ||
![]() |
1dbe60b8b7 | ||
![]() |
9631fa7407 | ||
![]() |
9befc682ee | ||
![]() |
fbeb674479 | ||
![]() |
af641d20a7 | ||
![]() |
d02587750c | ||
![]() |
241a4b3d45 | ||
![]() |
496e81a25a | ||
![]() |
f39b081253 |
420
CHANGES
420
CHANGES
@@ -1,11 +1,423 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
Changelog
|
||||
|
||||
Daniel (22 June 2004)
|
||||
- David Cohen pointed out that RFC2109 says clients should allow cookies to
|
||||
contain least 4096 bytes while libcurl only allowed 2047. I raised the limit
|
||||
to 4999 now and made the used buffer get malloc()ed instead of simply
|
||||
allocated on stack as before. Extended test case 46 to include a cookie with
|
||||
very huge content to verify the fix.
|
||||
|
||||
- G<>nter Knauf fixed getdate.y to remove a few warnings. I removed the
|
||||
ifdef'ed test we never ever use anyway.
|
||||
|
||||
- Gisle Vanem fixed the certificate wildcard checks to support a '*'-letter
|
||||
anywhere in the wildcard string, support multiple '*'-letters in the
|
||||
wildcard and to allow the '*'-letter to match a string that includes a dot.
|
||||
|
||||
Daniel (21 June 2004)
|
||||
- testcurl.sh is now removed completely, tests/testcurl.pl is the script to
|
||||
use when autobuilding curl!
|
||||
|
||||
- Kjetil Jacobsen brought my attention to the fact that you cannot properly
|
||||
abort an upload with the readfunction callback, since returning 0 or -1 only
|
||||
stops the upload and libcurl will continue waiting for downloaded data and
|
||||
the server often waits for the rest of the upload data to arrive.
|
||||
|
||||
Thus, I've now added the ability for read callbacks to return
|
||||
CURL_READFUNC_ABORT to abort an upload from a read callback. This will stop
|
||||
the transfer immediately with a CURLE_ABORTED_BY_CALLBACK return code.
|
||||
|
||||
Test case 513 was added to verify that it works. I had to improve the test
|
||||
HTTP server too to dump the request to a file even when the client
|
||||
disconnects prematurely.
|
||||
|
||||
Daniel (19 June 2004)
|
||||
- Luca Alteas provided a test case with a failing curl operation: when we POST
|
||||
to a site with --digest (or similar) set, and the server responded with a 302
|
||||
Location: to the "authprobe" request, it was not treated correctly. We still
|
||||
will behave badly if FOLLOWLOCATION is enabled for this case, but I'm not
|
||||
in the mood to dive into this right now and will leave it as-is for now.
|
||||
Verified my fix with test case 177.
|
||||
|
||||
Daniel (18 June 2004)
|
||||
- Gisle Vanem's patch that provides more details from the SSL layers (if you
|
||||
use an OpenSSL version that supports it). It also introduces two new types
|
||||
of data that can be sent to the debug callback: CURLINFO_SSL_DATA_IN and
|
||||
CURLINFO_SSL_DATA_OUT.
|
||||
|
||||
- With David Byron's test server I could repeat his problem and make sure that
|
||||
POSTing over HTTPS:// with NTLM works fine now. There was a general problem
|
||||
with multi-pass authentication with non-GET operations with CONNECT.
|
||||
|
||||
Daniel (16 June 2004)
|
||||
- Modified to keep the upload byte counter in an curl_off_t, not an int as
|
||||
before. 32bits is not enough. This is most likely the bug Jean-Louis Lemaire
|
||||
reported that makes 2GB FTP uploads to report error ("unaligned file sizes")
|
||||
when completed.
|
||||
|
||||
Daniel (15 June 2004)
|
||||
- Luca Alteas reported a problem that I fixed: if you did a POST with
|
||||
CURLAUTH_DIGEST set but the server didn't require any authentication,
|
||||
libcurl would repeatedly send HEAD lots of times until it gives up. This was
|
||||
actually the case for all multi-pass authentications. Added test case 174,
|
||||
175 and 176 to verify this.
|
||||
|
||||
Daniel (14 June 2004)
|
||||
- Multipart formposts uploading files no longer inserts the files themselves
|
||||
into the huge prebuilt chunk. This enables libcurl to formpost files that is
|
||||
larger than the amount of system memory. When the file given is passed on
|
||||
stdin, libcurl still uses the old method of reading the full fill before the
|
||||
upload takes place. This approach was selected in order to not alter the
|
||||
behavior for existing applications, as when using stdin libcurl can't know
|
||||
the size of the upload and chunked transfer-encoding can only be used on
|
||||
HTTP 1.1 servers.
|
||||
|
||||
Daniel (13 June 2004)
|
||||
- Gisle found out that we did wildcard cert name checks wrong, so that parts
|
||||
of the check wrongly was case sensitive.
|
||||
|
||||
Daniel (11 June 2004)
|
||||
- Tim Sneddon brought a minor VMS fix to make curl build properly on his VMS
|
||||
machine. He also had some interesting libcurl patches... they might be able
|
||||
to do in a slightly nicer way. Discussions are in progress.
|
||||
|
||||
Daniel (10 June 2004)
|
||||
- Gisle Vanem brought code cleanupsm better verbose output and better connect
|
||||
timeout handling when attempting to connect to a host that resolves to
|
||||
multiple IP addresses.
|
||||
|
||||
- Steven Bazyl and Seshubabu Pasam pointed out a bug on win32 when freeing the
|
||||
path after a file:// transfer.
|
||||
|
||||
Daniel (9 June 2004)
|
||||
- Alexander Krasnostavsky made 'configure --disable-http' work to build libcurl
|
||||
without HTTP support. I added a new return code for curl_formadd() in case
|
||||
libcurl is built with HTTP disable: CURL_FORMADD_DISABLED.
|
||||
|
||||
- Alexander Krasnostavsky pointed out a missing file in the generated
|
||||
curllib.dsp file, and now people building with this should get a libcurl.lib
|
||||
file generated as it used to do before we generated this file.
|
||||
|
||||
Daniel (8 June 2004)
|
||||
- Marty Kuhrt fixed a minor build problem for VMS.
|
||||
|
||||
Daniel (7 June 2004)
|
||||
- Reverted the configure check from the 4th since it obviously didn't work.
|
||||
Remade it in a different manner that hopefully works better.
|
||||
|
||||
Daniel (4 June 2004)
|
||||
- G<>nter Knauf brought patches to make curl build fine on NetWare again.
|
||||
|
||||
- Made the configure checks for strerror_r() not exit the configure script
|
||||
when built for cross-compiling.
|
||||
|
||||
Daniel (3 June 2004)
|
||||
- Chris Gaukroger pointed out that 'make test' attempts to run the tests even
|
||||
if curl is built cross-compiled. I've now made it output a short message
|
||||
instead, saying it isn't possible to do.
|
||||
|
||||
- Alexander Krasnostavsky brought FTP 3rd party transfer support to libcurl.
|
||||
You can now use libcurl to transfer files between two remote hosts using
|
||||
FTP. There are a bunch of new options to control this with:
|
||||
CURLOPT_SOURCE_HOST
|
||||
CURLOPT_SOURCE_USERPWD
|
||||
CURLOPT_SOURCE_PATH
|
||||
CURLOPT_SOURCE_PORT
|
||||
CURLOPT_PASV_HOST
|
||||
CURLOPT_SOURCE_PREQUOTE
|
||||
CURLOPT_SOURCE_POSTQUOTE
|
||||
|
||||
(They still remain to be documented properly in the curl_easy_setopt man
|
||||
page.)
|
||||
|
||||
When using this, the ordinary CURLOPT_URL specifies the target URL, and you
|
||||
specify the source data with these additional options. ftp3rdparty.c is a
|
||||
new example source code showing how to use this.
|
||||
|
||||
- Vincent Bronner fixed the HTTP Digest code to use the proxy user name and
|
||||
password when doing proxy authentication, it previously always used the host
|
||||
user name and password!
|
||||
|
||||
Daniel (2 June 2004)
|
||||
- CURLOPT_UPLOAD and CURLOPT_PUT now do the exact same thing internally, which
|
||||
fixes some old confusions on when which of these should be used and what the
|
||||
differences are.
|
||||
|
||||
- Applied Gisle's fixes to make curl build fine with lcc-win32
|
||||
|
||||
Version 7.12.0 (2 June 2004)
|
||||
|
||||
Daniel (1 June 2004)
|
||||
- I clarified the --create-dirs option somewhat in the curl man page.
|
||||
|
||||
- Renaud Duhaut corrected the curl_unescape man page.
|
||||
|
||||
- David Byron modified one of Massimiliano Ziccardi's recent MSVC makefile
|
||||
changes to now again use the mm lib by default.
|
||||
|
||||
Daniel (26 May 2004)
|
||||
- Mohun Biswas added release-zlib and debug-zlib targets to the MSVC libcurl
|
||||
Makefile
|
||||
|
||||
- David Byron reported a problem with proxy authentication when doing CONNECT,
|
||||
like when accessing HTTPS sites wiht a proxy. This probably broke when I
|
||||
rewrote the auth stuff recently.
|
||||
|
||||
- I added fileupload.c in the examples directory, showing how an upload to a
|
||||
file:// URL is made.
|
||||
|
||||
Daniel (25 May 2004)
|
||||
- Massimiliano Ziccardi updated the MSVC makefiles.
|
||||
|
||||
Daniel (24 May 2004)
|
||||
- libcurl now supports "uploading" to file:// URLs. Test 204 and 205 were
|
||||
added to verify.
|
||||
|
||||
- Simon Josefsson added a idn_free() function in libidn 0.4.5 as a reaction to
|
||||
Gisle's previous mail. We now use this function, and thus we require libidn
|
||||
0.4.5 or later. No earlier version will do.
|
||||
|
||||
- Robert D. Young reported that CURLOPT_COOKIEFILE and CURLOPT_COOKIE could
|
||||
not be used both in one request. Fixed it and added test case 172 to verify.
|
||||
|
||||
Daniel (21 May 2004)
|
||||
- While talking to host a.b.c, libcurl did wrongly not accept cookies that
|
||||
were set to the domain .a.b.c (that is with a dot prefix). This is now fixed
|
||||
and test case 171 verifies it.
|
||||
|
||||
Daniel (20 May 2004)
|
||||
- Jesse Noller reported that the upload speed info reported by libcurl was
|
||||
wrong. The same was true for the download speed. Fixed now.
|
||||
|
||||
Daniel (19 May 2004)
|
||||
- David Byron added test case 170 - this used to crash the previous version of
|
||||
curl.
|
||||
|
||||
Daniel (17 May 2004)
|
||||
- Peter Sylvester's patch that addresses two flaws in the peer certificate
|
||||
name verification:
|
||||
o when multiple common names are used (as in the curl tests), the last name
|
||||
needs to be selected.
|
||||
o allow comparing with encoded values, at least with BMP and ISO latin1
|
||||
encoded T61strings.
|
||||
|
||||
- All 191 test cases run through the torture test OK! 'make test-torture' is
|
||||
now available in the root makefile (on configure-based environments).
|
||||
|
||||
Daniel (14 May 2004)
|
||||
- With a slightly modified ftpserver.pl I've now run almost all tests through
|
||||
with runtests.pl -t. This is goodness!
|
||||
|
||||
- Since I have been unable to contact the CVS admins for several months, I've
|
||||
decided that the current CVS hosting was not good enough. I've now moved the
|
||||
CVS repo once again, see README for updated cvs checkout instructions.
|
||||
|
||||
Daniel (13 May 2004)
|
||||
- runtests.pl -t now runs fine all the way to test 100. I believe test case
|
||||
100 fails because of an FTP server problem.
|
||||
|
||||
Daniel (12 May 2004)
|
||||
- General cleanups all over to make libcurl survive and do well when a memory
|
||||
function returns NULL. runtests.pl -t now works fine for the first 26 test
|
||||
cases.
|
||||
|
||||
Daniel (11 May 2004)
|
||||
- Seshubabu Pasam provided a patch that introduces curl_global_init_mem() -
|
||||
like normal curl_global_init() but allows the app to replace all memory
|
||||
functions with its own set. I modified it slightly.
|
||||
|
||||
- Based on Luca Alteas' comments, I modified the curllib.dsp generation code.
|
||||
|
||||
Daniel (10 May 2004)
|
||||
- Gisle mailed Simon Josefsson (of libidn fame) about the benefits of a
|
||||
separate free()-function by that lib to make sure the memory is freed by the
|
||||
same memory subsystem that allocated it. He responded positively and this
|
||||
will likely cause us to require a newer version of libidn as soon as Simon
|
||||
releases one with such a libidn_free() function.
|
||||
|
||||
- James Bursa made runtests.pl's -t option work for any given test case, and I
|
||||
edited to allow -g too. Not even test case 1 worked...
|
||||
|
||||
- Luca Altea made the nc= field not use quotes in outgoing HTTP Digest headers.
|
||||
|
||||
- Andr<64>s Garc<72>a fixed a problem in the test script that made it fail to
|
||||
recognize our own running HTTP server.
|
||||
|
||||
Daniel (7 May 2004)
|
||||
- James Bursa fixed the memanalyze.pl script to conder malloc(0) areas OK to
|
||||
free() and he made two failed-resolve error messages use the new display-
|
||||
name instead of the internally-used name.
|
||||
|
||||
- Gisle Vanem tried curl with
|
||||
www.etdomenenavnkanmaksimaltinneholdesekstitrebokstaversliksomdette.com
|
||||
which caused problems, and I fixed the single zero byte buffer overwrite
|
||||
that occurred (due to a stupid protocol buffer size and parser).
|
||||
|
||||
- Made the lib/curllib.dsp file get generated automaticly when a distribution
|
||||
package is made, with the msvcproj.* files as templates and all
|
||||
win32-sources added. I think this can be made to work better than the always
|
||||
lagging-behind previous approach. I'm not sure this builds a working project
|
||||
file right now though!
|
||||
|
||||
Daniel (6 May 2004)
|
||||
- Michael Benedict brought a fix that fills in the errorbuffer properly when
|
||||
ares fails to resolve a name for a case not previously dealt with like this.
|
||||
|
||||
Daniel (5 May 2004)
|
||||
- Joe Halpin fixed the annoying typecast warning in lib/ldap.c
|
||||
|
||||
- Gisle Vanem fixes:
|
||||
o memdebug to not access NULL on several places
|
||||
o libcurl.def; curl_formparse is gone.
|
||||
o progress.c; fixed the percent values being trunced to 0.
|
||||
o if2ip.*; constified the 'interface' argument.
|
||||
|
||||
- Tor Arntsen reported that many of his autobuilds froze and I found and fixed
|
||||
a problem introduced with the HTTP auth overhaul that could lead to a
|
||||
never-ending internal request-loop due to un-initialized variables!
|
||||
|
||||
- Removed several compiler warnings on various compilers/platforms.
|
||||
|
||||
Daniel (4 May 2004)
|
||||
- curl_formparse() has been removed from the library. It has been marked and
|
||||
mentioned as deprecated for several years.
|
||||
|
||||
Daniel (3 May 2004)
|
||||
- Rewritten HTTP authentication code. The previous code could not properly
|
||||
deal with the added test cases 167, 168 and 169. I've now rewritten the code
|
||||
to better separate host and proxy authentication and not re-use the same
|
||||
variables as much as before as it proved non working in the more involved
|
||||
cases. All the current tests run OK now, and so do the new ones. The curl
|
||||
tool got a new option named --proxy-digest to enable HTTP Digest
|
||||
authentication with the proxy. I also made the library support it.
|
||||
|
||||
- Gisle Vanem made the LDAP code work with wldap32.dll as supplied with
|
||||
Win-98/ME/2000/XP, so no extra .dlls are required when curl/libcurl is used
|
||||
on these Windows versions.
|
||||
|
||||
Daniel (30 April 2004)
|
||||
- runtests.pl now scans the valgrind log for valgrind-detected memory leaks
|
||||
after each test case if valgrind was found and used.
|
||||
|
||||
- I modified the app-code in curl to include the new lib/curlx.h and only
|
||||
access those functions using the curlx_-prefix in preparation for the future
|
||||
removal of several curl_-functions from the public libcurl API.
|
||||
|
||||
- Introduced lib/curlx.h as a single header to provide the curlx_-functions
|
||||
to apps.
|
||||
|
||||
- Added notices in the man pages for curl_getenv, curl_mprintf, curl_strequal
|
||||
and curl_strnequal that they are subject for removal in a future release.
|
||||
STOP USING THESE FUNCTIONS.
|
||||
|
||||
- Mihai Ionescu noticed he couldn't do formposts with whitespace in the file
|
||||
names and yes, I broke that on April 23. Sigh. I fixed it now and added
|
||||
test case 166 to verify it.
|
||||
|
||||
- Luca Altea pointed out a mistake left from the Digest patch of yesterday.
|
||||
|
||||
Daniel (29 April 2004)
|
||||
- Made IDN domains work when sending requsts over HTTP proxy as well. Added
|
||||
test case 165 to verify the functionality.
|
||||
|
||||
- Fixed a bug in the new internal host name setup when re-using connections.
|
||||
|
||||
- James Bursa found out that curl_easy_duphandle() with ares-built libcurl
|
||||
created a bad handle that would crash in the first name resolve attempt. This
|
||||
is now fixed and test case 512 was added to verify it.
|
||||
|
||||
- Luca Altea provided a major HTTP Digest code fix and cleanup. We now follow
|
||||
the Digest RFC a lot better.
|
||||
|
||||
- Gisle Vanem made the SSL code use ERR_error_string_n() where applicable.
|
||||
|
||||
Daniel (27 April 2004)
|
||||
- I remodeled Gisle's IDN code slightly and now we convert both the host name
|
||||
and proxy name to the ACE encoded version to use internally for resolves and
|
||||
cookies etc. They are now using one 'struct hostname' each that keep both
|
||||
the original name and the possibly encoded name. IDN resolves work for me
|
||||
now using ipv6, ipv4 and ares resolving. Even cookies on IDN sites seem to
|
||||
do right. I got some failures at first when CHARSET wasn't set at all which
|
||||
confused libidn completely and it decided by encoding of choice was
|
||||
'ANSI_X3.4-1968'...
|
||||
|
||||
- made 'configure --without-libidn' work
|
||||
|
||||
Daniel (25 April 2004)
|
||||
- Fixed the src/hugehelp.c file to include "setup.h" instead of "config.h" to
|
||||
make the problems with USE_MANUAL on windows go away.
|
||||
|
||||
- configure --without-ssl could still wrongly include some OpenSSL info in the
|
||||
Makefiles if pkg-config had info about OpenSSL. Bug #941762 reported by
|
||||
Martin.
|
||||
|
||||
- Since we can now build and use quite a large set of 3rd party libraries, I
|
||||
decided I would make configure produce a summary at the end showing what
|
||||
libraries it uses and if not, what option to use to make it use that. I also
|
||||
added some other random info that is nice in a "configure summary" output.
|
||||
|
||||
- Applied TommyTam's patch that now make curl work with telnet and stdin
|
||||
properly on Windows.
|
||||
|
||||
- The changes for today below were made by me and Gisle Vanem.
|
||||
|
||||
The file previously known as hostip.c has now undergone a huge cleanup and
|
||||
split:
|
||||
|
||||
hostip.c explained
|
||||
==================
|
||||
|
||||
The main COMPILE-TIME DEFINES to keep in mind when reading the host*.c
|
||||
source file are these:
|
||||
|
||||
CURLRES_IPV6 - this host has getaddrinfo() and family, and thus we use
|
||||
that. The host may not be able to resolve IPv6, but we don't really have to
|
||||
take that into account. Hosts that aren't IPv6-enabled have CURLRES_IPV4
|
||||
defined.
|
||||
|
||||
CURLRES_ARES - is defined if libcurl is built to use c-ares for asynchronous
|
||||
name resolves. It cannot have ENABLE_IPV6 defined at the same time, as
|
||||
c-ares has no ipv6 support. This can be Windows or *nix.
|
||||
|
||||
CURLRES_THREADED - is defined if libcurl is built to run under (native)
|
||||
Windows, and then the name resolve will be done in a new thread, and the
|
||||
supported asynch API will be the same as for ares-builds.
|
||||
|
||||
If any of the two previous are defined, CURLRES_ASYNCH is defined too. If
|
||||
libcurl is not built to use an asynchronous resolver, CURLRES_SYNCH is
|
||||
defined.
|
||||
|
||||
The host*.c sources files are split up like this:
|
||||
|
||||
hostip.c - method-independent resolver functions and utility functions
|
||||
hostasyn.c - functions for asynchronous name resolves
|
||||
hostsyn.c - functions for synchronous name resolves
|
||||
hostares.c - functions for ares-using name resolves
|
||||
hostthre.c - functions for threaded name resolves
|
||||
hostip4.c - ipv4-specific functions
|
||||
hostip6.c - ipv6-specific functions
|
||||
|
||||
The hostip.h is the single united header file for all this. It defines the
|
||||
CURLRES_* defines based on the config*.h and setup.h defines.
|
||||
|
||||
- Added function header comments to many functions in an attempt to better
|
||||
explain the purpose of them all.
|
||||
|
||||
- configure --with-libidn is now supported. It makes the configure script
|
||||
check for libidn libs and include files in the prefix path given. If you
|
||||
say --with-libidn=/usr/local, it will check for the lib in /usr/local/lib
|
||||
and the includes in /usr/local/include etc.
|
||||
|
||||
- curl_version_info() now returns a struct aged CURLVERSION_THIRD including
|
||||
libidn version info. The string curl_version() returns also includes libidn
|
||||
version info, if available.
|
||||
|
||||
Version 7.11.2 (26 April 2004)
|
||||
|
||||
Daniel (25 April 2004)
|
||||
|
@@ -24,7 +24,7 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
EXTRA_DIST = CHANGES COPYING maketgz reconf Makefile.dist \
|
||||
curl-config.in curl-style.el sample.emacs testcurl.sh RELEASE-NOTES
|
||||
curl-config.in curl-style.el sample.emacs RELEASE-NOTES
|
||||
|
||||
bin_SCRIPTS = curl-config
|
||||
|
||||
@@ -54,6 +54,9 @@ test:
|
||||
test-full:
|
||||
@(cd tests; $(MAKE) all full-test)
|
||||
|
||||
test-torture:
|
||||
@(cd tests; $(MAKE) all torture-test)
|
||||
|
||||
#
|
||||
# Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros
|
||||
# must contain the following line:
|
||||
|
@@ -41,6 +41,10 @@ mingw32-ssl:
|
||||
cd lib & make -f Makefile.m32 SSL=1 ZLIB=1
|
||||
cd src & make -f Makefile.m32 SSL=1 ZLIB=1
|
||||
|
||||
mingw32-clean:
|
||||
cd lib & make -f Makefile.m32 clean
|
||||
cd src & make -f Makefile.m32 clean
|
||||
|
||||
vc:
|
||||
cd lib
|
||||
nmake /f Makefile.vc6 cfg=release
|
||||
@@ -82,8 +86,16 @@ amiga:
|
||||
cd ./src && make -f makefile.amiga
|
||||
|
||||
netware:
|
||||
cd lib && make -f Makefile.netware
|
||||
cd src && make -f Makefile.netware
|
||||
$(MAKE) -C lib -f Makefile.netware
|
||||
$(MAKE) -C src -f Makefile.netware
|
||||
|
||||
netware-ssl:
|
||||
$(MAKE) -C lib -f Makefile.netware SSL=1
|
||||
$(MAKE) -C src -f Makefile.netware SSL=1
|
||||
|
||||
netware-clean:
|
||||
$(MAKE) -C lib -f Makefile.netware clean
|
||||
$(MAKE) -C src -f Makefile.netware clean
|
||||
|
||||
unix: all
|
||||
|
||||
|
15
README
15
README
@@ -17,7 +17,9 @@ README
|
||||
|
||||
You find answers to the most frequent questions we get in the FAQ document.
|
||||
|
||||
Study the COPYING file for distribution terms and similar.
|
||||
Study the COPYING file for distribution terms and similar. If you distribute
|
||||
curl binaries or other binaries that involve libcurl, you might enjoy the
|
||||
LICENSE-MIXING document.
|
||||
|
||||
CONTACT
|
||||
|
||||
@@ -50,6 +52,7 @@ DOWNLOAD
|
||||
Germany -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/
|
||||
Germany -- http://curl.mirror.at.stealer.net/download.html
|
||||
Germany -- http://curl.netmirror.org/download.html
|
||||
Germany -- http://www.mirrorspace.org/curl/
|
||||
Hongkong -- http://www.execve.net/curl/
|
||||
Russia -- http://curl.tsuren.net/download.html
|
||||
Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/
|
||||
@@ -61,18 +64,14 @@ CVS
|
||||
|
||||
To download the very latest source off the CVS server do this:
|
||||
|
||||
cvs -d :pserver:cvsread@cvs.php.net:/repository login
|
||||
cvs -d :pserver:anonymous@cool.haxx.se:/cvsroot/curl login
|
||||
|
||||
(enter "phpfi" when asked for password)
|
||||
(just press enter when asked for password)
|
||||
|
||||
cvs -d :pserver:cvsread@cvs.php.net:/repository co curl
|
||||
cvs -d :pserver:anonymous@cool.haxx.se:/cvsroot/curl co curl
|
||||
|
||||
(you'll get a directory named curl created, filled with the source code)
|
||||
|
||||
cvs -d :pserver:cvsread@cvs.php.net:/repository logout
|
||||
|
||||
(you're off the hook!)
|
||||
|
||||
NOTICE
|
||||
|
||||
Curl contains pieces of source code that is Copyright (c) 1998, 1999
|
||||
|
@@ -1,74 +1,51 @@
|
||||
Curl and libcurl 7.11.2. A bugfix release.
|
||||
Curl and libcurl 7.12.1
|
||||
|
||||
Public curl release number: 80
|
||||
Releases counted from the very beginning: 107
|
||||
Available command line options: 94
|
||||
Available curl_easy_setopt() options: 113
|
||||
Public curl release number: 82
|
||||
Releases counted from the very beginning: 109
|
||||
Available command line options: 96
|
||||
Available curl_easy_setopt() options: 120
|
||||
Number of public functions in libcurl: 36
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o removed maximum user+password+hostname size limit
|
||||
o removed maximum dir depth limit for FTP
|
||||
o the ares build now requires c-ares 1.2.0 or later
|
||||
o --tcp-nodelay and CURLOPT_TCP_NODELAY were added
|
||||
o curl/curlver.h contains the libcurl version info now
|
||||
o read callbacks can stop the transfer by returning CURL_READFUNC_ABORT
|
||||
o libcurl-tutorial.3 is the new man page formerly known as libcurl-the-guide
|
||||
o additional SSL trace data might be sent to the debug callback using two new
|
||||
types: CURLINFO_SSL_DATA_IN and CURLINFO_SSL_DATA_OUT
|
||||
o multipart formposts can upload files larger than system memory
|
||||
o the curl tool continues with the next URL even if one transfer fails
|
||||
o FTP 3rd party transfer support - seven new setopt() options
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o configure --disable-manual works better
|
||||
o removed a memory leak when doing a windows threaded resolve and it failed
|
||||
o --proxy-ntlm now checks if libcurl supports NTLM before using it
|
||||
o minor --fail with authentication bugfix
|
||||
o CURLOPT_IPRESOLVE set to CURL_IPRESOLVE_V6 will now cause a returned error
|
||||
if the host only can resolve ipv4 addresses
|
||||
o curl -4/-6 now actually sets the requested option in libcurl
|
||||
o multi interface on Windows without ares works again
|
||||
o improved resolution for the CURLINFO_*_TIME info variables
|
||||
o getting only a 100 Continue response and nothing else, when talking HTTP,
|
||||
is now treated as an error by libcurl
|
||||
o fixed minor memory leak in libcurl for Windows when statically linked
|
||||
o POST/PUT using Digest/NTLM/Negotiate (including anyauth) now work better
|
||||
o --limit-rate with high speed rates is a lot more accurate now, and supports
|
||||
limiting to speeds >2GB/sec on systems with Large File support.
|
||||
o curl_strnqual.3 "refer-to" man page fix
|
||||
o fixed a minor very old progress meter final update bug
|
||||
o added checks for a working NI_WITHSCOPEID before that is used
|
||||
o fixed a flaw that prevented ares name resolve timeouts to occur
|
||||
o getting user name from http_proxy env variable works now
|
||||
o fixed too early name resolve timeouts with ares
|
||||
o HTTP Digest "re-negotiation" works now
|
||||
o CURLOPT_FAILONERROR (-f/--fail) works with all kinds of authentication
|
||||
o better thread-safety thanks to the internal strerror() replacement
|
||||
o better thread-safety on AIX thanks to better function detection
|
||||
o minor ipv6 build fix for windows
|
||||
o the test suite runs fine with mingw-built curl
|
||||
o the postit2.c example works now
|
||||
o better error message when --interface fails on windows
|
||||
o the progress meter now displays very long times better
|
||||
o CURLINFO_CONTENT_LENGTH_DOWNLOAD with CURLOPT_NOBODY set TRUE now works
|
||||
o passwords longer than 14 letters work with NTLM
|
||||
o 'make netware' in the root dir works now
|
||||
o builds fine on VMS again and even nicer than before
|
||||
o cookies can now hold 4999 bytes of content
|
||||
o HTTP POST/PUT with NTLM/Digest/Negotiate to a URL returning 3XX
|
||||
o HTTPS POST/PUT over a proxy requiring NTLM/Digest/Negotiate works now
|
||||
o less restrictive libidn requirements, 0.4.1 or later is fine
|
||||
o fixed HTTP POST or PUT with Digest/Negotiate/NTLM selected but the server
|
||||
didn't require any authentication
|
||||
o win32 file:// transfer free memory bug
|
||||
o configure --disable-http builds a libcurl without HTTP support
|
||||
o CURLOPT_FILETIME had wrong type, it expects a long argument
|
||||
o builds fine with Borland on Windows again
|
||||
o the msvc curllib.dsp now builds the libcurl.lib file again
|
||||
o builds fine on VMS again
|
||||
o builds fine on NetWare again
|
||||
o HTTP Digest authentication with proxies uses correct user name + password
|
||||
o now builds fine with lcc-win32
|
||||
|
||||
Other curl-related news since the previous public release:
|
||||
|
||||
o PycURL 7.11.1 was released: http://pycurl.sf.net/
|
||||
o CURLHandle 1.9 was released: http://curlhandle.sourceforge.net/
|
||||
o A curl module for the Q language was announced:
|
||||
http://q-lang.sourceforge.net/
|
||||
o c-ares 1.2.0 was released: http://daniel.haxx.se/projects/c-ares/
|
||||
o New curl web mirrors:
|
||||
Germany http://curl.netmirror.org/
|
||||
USA http://curl.signal42.com/
|
||||
Denmark http://curl.cofman.dk/
|
||||
o James Hu took over after Kevin Roth as maintainer of the curl package on
|
||||
cygwin. Many saludos to Kevin for a work well done during many years.
|
||||
o Gambas binding for libcurl: http://gambas.sf.net/
|
||||
o pycurl 7.12.0 was released http://pycurl.sf.net/
|
||||
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Thomas Schwinge, Marty Kuhrt, G<>nter Knauf, Kevin Roth, Glen Nakamura, Gisle
|
||||
Vanem, Greg Hewgill, Joe Halpin, Tor Arntsen, Dirk Manske, Roy Shan, Mitz
|
||||
Wark, Andr<64>s Garc<72>a, Robin Kay, Alan Pinstein, David Byron, Nathan
|
||||
O'Sullivan, Erwin Authried
|
||||
|
||||
Gisle Vanem, Vincent Bronner, Alexander Krasnostavsky, Chris Gaukroger,
|
||||
G<EFBFBD>nter Knauf, Marty Kuhrt, Kjetil Jacobsen, Steven Bazyl, Seshubabu Pasam,
|
||||
Luca Alteas, Jean-Louis Lemaire, David Byron, David Cohen
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
38
TODO-RELEASE
38
TODO-RELEASE
@@ -1,37 +1,17 @@
|
||||
Issues not sorted in any particular order.
|
||||
#[num] refers to bug report numbers.
|
||||
UNASSIGNED means that no person has publicly stated to work on the issue.
|
||||
DELETE means the issue is subject for dismissal
|
||||
|
||||
To get fixed in 7.11.2 (planned release late April 2004)
|
||||
To get fixed in 7.12.1 (planned release: August 2004)
|
||||
======================
|
||||
|
||||
35 - Fix multi interface when connecting to host with multiple IP addresses:
|
||||
http://curl.haxx.se/mail/lib-2004-06/0163.html and
|
||||
http://curl.haxx.se/mail/lib-2004-06/0167.html
|
||||
UNASSIGNED
|
||||
|
||||
To get fixed in 7.12.0 (no date)
|
||||
* Bugfixes reported until late July
|
||||
|
||||
To get fixed in 7.12.2 (planned release: December 2004)
|
||||
======================
|
||||
|
||||
25. curl_easy_strerror() curl_multi_strerror() curl_share_strerror()
|
||||
Code already in CVS. Messages need overview/improvements.
|
||||
Medium prio.
|
||||
|
||||
26. i18n of error messages?
|
||||
Low prio. Nobody has volunteered. Subject for removal.
|
||||
|
||||
33. Add a function to replace the malloc-calls within libcurl.
|
||||
Low prio. Seshubabu Pasam works on this.
|
||||
|
||||
35. Rearrange lib/hostip.c to reduce the amount of #ifdefs and make it easier
|
||||
to understand and edit. Daniel works on this. See
|
||||
http://curl.haxx.se/beta/hostip-cleanup1.patch
|
||||
Medium prio.
|
||||
|
||||
36. Add support for a threaded getaddrinfo() on Windows and IPv6 enabled
|
||||
libcurl.
|
||||
|
||||
37. Configure option "--with-libidn" to support IDNA (Internationalising
|
||||
Domain Names in Applications). Translate to/from ACE encoded domain
|
||||
names as needed.
|
||||
|
||||
38. Make the ldap protocol work with Windows' built-in LDAP-client.
|
||||
I.e. dynamically link to WLDAP32.DLL and add ldap URL parsing
|
||||
(WLDAP32.DLL doesn't have an UTF-8 ldap_url_parse).
|
||||
Bugfixes reported until late November
|
||||
|
42
acinclude.m4
42
acinclude.m4
@@ -396,6 +396,17 @@ AC_DEFUN([CURL_CHECK_STRERROR_R],
|
||||
AC_MSG_RESULT(no))])])
|
||||
|
||||
if test "x$strerror_r" = "xyes"; then
|
||||
|
||||
dnl check if strerror_r is properly declared in the headers
|
||||
AC_CHECK_DECL(strerror_r, ,
|
||||
AC_DEFINE(HAVE_NO_STRERROR_R_DECL, 1, [we have no strerror_r() proto])
|
||||
,
|
||||
[#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
])
|
||||
|
||||
dnl determine if this strerror_r() is glibc or POSIX
|
||||
AC_MSG_CHECKING([for a glibc strerror_r API])
|
||||
AC_TRY_RUN([
|
||||
@@ -412,13 +423,18 @@ main () {
|
||||
return 0;
|
||||
}
|
||||
],
|
||||
GLIBC_STRERROR_R="1"
|
||||
AC_DEFINE(HAVE_GLIBC_STRERROR_R, 1, [we have a glibc-style strerror_r()])
|
||||
AC_MSG_RESULT([yes]),
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_RESULT([no]),
|
||||
dnl cross-compiling!
|
||||
AC_MSG_NOTICE([cannot determine strerror_r() style: edit lib/config.h manually!])
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([for a POSIX strerror_r API])
|
||||
AC_TRY_RUN([
|
||||
if test -z "$GLIBC_STRERROR_R"; then
|
||||
|
||||
AC_MSG_CHECKING([for a POSIX strerror_r API])
|
||||
AC_TRY_RUN([
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
int
|
||||
@@ -433,12 +449,16 @@ main () {
|
||||
return 0;
|
||||
}
|
||||
],
|
||||
AC_DEFINE(HAVE_POSIX_STRERROR_R, 1, [we have a POSIX-style strerror_r()])
|
||||
AC_MSG_RESULT([yes]),
|
||||
AC_MSG_RESULT([no])
|
||||
AC_DEFINE(HAVE_POSIX_STRERROR_R, 1, [we have a POSIX-style strerror_r()])
|
||||
AC_MSG_RESULT([yes]),
|
||||
AC_MSG_RESULT([no]) ,
|
||||
dnl cross-compiling!
|
||||
AC_MSG_NOTICE([cannot determine strerror_r() style: edit lib/config.h manually!])
|
||||
)
|
||||
|
||||
fi
|
||||
fi dnl if not using glibc API
|
||||
|
||||
fi dnl we have a strerror_r
|
||||
|
||||
])
|
||||
|
||||
@@ -658,10 +678,11 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
||||
dnl "invalid format string conversion"
|
||||
dnl * 279 warns on static conditions in while expressions
|
||||
dnl * 981 warns on "operands are evaluated in unspecified order"
|
||||
dnl * 1418 "external definition with no prior declaration"
|
||||
dnl * 1419 warns on "external declaration in primary source file"
|
||||
dnl which we know and do on purpose.
|
||||
|
||||
WARN="-wd279,269,1419,981"
|
||||
WARN="-wd279,269,981,1418,1419"
|
||||
|
||||
if test "$gccnum" -gt "600"; then
|
||||
dnl icc 6.0 and older doesn't have the -Wall flag
|
||||
@@ -697,6 +718,11 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
||||
WARN="$WARN -Wendif-labels -Wstrict-prototypes"
|
||||
fi
|
||||
|
||||
if test "$gccnum" -ge "304"; then
|
||||
# try -Wunreachable-code on gcc 3.4
|
||||
WARN="$WARN -Wunreachable-code"
|
||||
fi
|
||||
|
||||
for flag in $CPPFLAGS; do
|
||||
case "$flag" in
|
||||
-I*)
|
||||
|
29
ares/CHANGES
29
ares/CHANGES
@@ -1,5 +1,34 @@
|
||||
Changelog for the c-ares project
|
||||
|
||||
* June 10
|
||||
- Gisle Vanem's init patch for Windows:
|
||||
|
||||
The init_by_resolv_conf() function fetches the DNS-server(s)
|
||||
from a series of registry branches.
|
||||
|
||||
This can be wrong in the case where DHCP has assigned nameservers, but the
|
||||
user has overridden these servers with other prefered settings. Then it's
|
||||
wrong to use the DHCPNAMESERVER setting in registry.
|
||||
|
||||
In the case of no global DHCP-assigned or fixed servers, but DNS server(s)
|
||||
per adapter, one has to query the adapter branches. But how can c-ares know
|
||||
which adapter is valid for use? AFAICS it can't. There could be one adapter
|
||||
that is down (e.g. a VPN adapter).
|
||||
|
||||
So it's better to leave this to the IP Helper API (iphlapi) available in
|
||||
Win-98/2000 and later. My patch falls-back to the old way if not available.
|
||||
|
||||
* June 8
|
||||
- James Bursa fixed an init issue for RISC OS.
|
||||
|
||||
* May 11
|
||||
- Nico Stappenbelt reported that when processing domain and search lines in
|
||||
the resolv.conf file, the first entry encountered is processed and used as
|
||||
the search list. According to the manual pages for both Linux, Solaris and
|
||||
Tru64, the last entry of either a domain or a search field is used.
|
||||
|
||||
This is now adjusted in the code
|
||||
|
||||
Version 1.2.0 (April 13, 2004)
|
||||
|
||||
* April 2, 2004
|
||||
|
@@ -143,25 +143,29 @@ int ares__get_hostent(FILE *fp, struct hostent **host)
|
||||
free(line);
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
free(line);
|
||||
if(line)
|
||||
free(line);
|
||||
|
||||
if (status == ARES_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure; clean up. */
|
||||
if (hostent)
|
||||
{
|
||||
free((char *) hostent->h_name);
|
||||
if(hostent->h_name)
|
||||
free((char *) hostent->h_name);
|
||||
if (hostent->h_aliases)
|
||||
{
|
||||
for (alias = hostent->h_aliases; *alias; alias++)
|
||||
free(*alias);
|
||||
}
|
||||
free(hostent->h_aliases);
|
||||
if (hostent->h_addr_list)
|
||||
if(hostent->h_aliases)
|
||||
free(hostent->h_aliases);
|
||||
if (hostent->h_addr_list && hostent->h_addr_list[0])
|
||||
free(hostent->h_addr_list[0]);
|
||||
free(hostent->h_addr_list);
|
||||
if(hostent->h_addr_list)
|
||||
free(hostent->h_addr_list);
|
||||
free(hostent);
|
||||
}
|
||||
free(hostent);
|
||||
return ARES_ENOMEM;
|
||||
}
|
||||
|
||||
|
175
ares/ares_init.c
175
ares/ares_init.c
@@ -17,6 +17,8 @@
|
||||
|
||||
#ifdef WIN32
|
||||
#include "nameser.h"
|
||||
#include <iphlpapi.h>
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
@@ -85,6 +87,8 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||
channel->nsort = -1;
|
||||
channel->lookups = NULL;
|
||||
channel->queries = NULL;
|
||||
channel->domains = NULL;
|
||||
channel->sortlist = NULL;
|
||||
|
||||
/* Initialize configuration by each of the four sources, from highest
|
||||
* precedence to lowest.
|
||||
@@ -101,15 +105,16 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||
/* Something failed; clean up memory we may have allocated. */
|
||||
if (channel->nservers != -1)
|
||||
free(channel->servers);
|
||||
if (channel->ndomains != -1)
|
||||
if (channel->domains)
|
||||
{
|
||||
for (i = 0; i < channel->ndomains; i++)
|
||||
free(channel->domains[i]);
|
||||
free(channel->domains);
|
||||
}
|
||||
if (channel->nsort != -1)
|
||||
if (channel->sortlist)
|
||||
free(channel->sortlist);
|
||||
free(channel->lookups);
|
||||
if(channel->lookups)
|
||||
free(channel->lookups);
|
||||
free(channel);
|
||||
return status;
|
||||
}
|
||||
@@ -228,24 +233,24 @@ static int init_by_environment(ares_channel channel)
|
||||
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
#ifdef WIN32
|
||||
static int get_res_size_nt(HKEY hKey, char *subkey, int *size)
|
||||
{
|
||||
return RegQueryValueEx(hKey, subkey, 0, NULL, NULL, size);
|
||||
}
|
||||
|
||||
/* Warning: returns a dynamically allocated buffer, the user MUST
|
||||
#ifdef WIN32
|
||||
/*
|
||||
* Warning: returns a dynamically allocated buffer, the user MUST
|
||||
* use free() if the function returns 1
|
||||
*/
|
||||
static int get_res_nt(HKEY hKey, char *subkey, char **obuf)
|
||||
static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
|
||||
{
|
||||
/* Test for the size we need */
|
||||
int size = 0;
|
||||
DWORD size = 0;
|
||||
int result;
|
||||
|
||||
result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
|
||||
if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
|
||||
return 0;
|
||||
*obuf = malloc(size+1);
|
||||
if (!*obuf)
|
||||
return 0;
|
||||
|
||||
if (RegQueryValueEx(hKey, subkey, 0, NULL, *obuf, &size) != ERROR_SUCCESS)
|
||||
{
|
||||
@@ -260,29 +265,99 @@ static int get_res_nt(HKEY hKey, char *subkey, char **obuf)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int get_res_interfaces_nt(HKEY hKey, char *subkey, char **obuf)
|
||||
static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
|
||||
{
|
||||
char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
|
||||
int enum_size = 39;
|
||||
DWORD enum_size = 39;
|
||||
int idx = 0;
|
||||
HKEY hVal;
|
||||
|
||||
while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
|
||||
NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
|
||||
{
|
||||
int rc;
|
||||
|
||||
enum_size = 39;
|
||||
if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
|
||||
ERROR_SUCCESS)
|
||||
continue;
|
||||
if (!get_res_nt(hVal, subkey, obuf))
|
||||
RegCloseKey(hVal);
|
||||
else
|
||||
{
|
||||
rc = get_res_nt(hVal, subkey, obuf);
|
||||
RegCloseKey(hVal);
|
||||
if (rc)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
|
||||
{
|
||||
FIXED_INFO *fi = alloca (sizeof(*fi));
|
||||
DWORD size = sizeof (*fi);
|
||||
DWORD WINAPI (*GetNetworkParams) (FIXED_INFO*, DWORD*); /* available only on Win-98/2000+ */
|
||||
HMODULE handle;
|
||||
IP_ADDR_STRING *ipAddr;
|
||||
int i, count = 0;
|
||||
int debug = 0;
|
||||
size_t ip_size = sizeof("255.255.255.255,")-1;
|
||||
size_t left = ret_size;
|
||||
char *ret = ret_buf;
|
||||
|
||||
if (!fi)
|
||||
return (0);
|
||||
|
||||
handle = LoadLibrary ("iphlpapi.dll");
|
||||
if (!handle)
|
||||
return (0);
|
||||
|
||||
(void*)GetNetworkParams = GetProcAddress (handle, "GetNetworkParams");
|
||||
if (!GetNetworkParams)
|
||||
goto quit;
|
||||
|
||||
if ((*GetNetworkParams) (fi, &size) != ERROR_BUFFER_OVERFLOW)
|
||||
goto quit;
|
||||
|
||||
fi = alloca (size);
|
||||
if (!fi || (*GetNetworkParams) (fi, &size) != ERROR_SUCCESS)
|
||||
goto quit;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
printf ("Host Name: %s\n", fi->HostName);
|
||||
printf ("Domain Name: %s\n", fi->DomainName);
|
||||
printf ("DNS Servers:\n"
|
||||
" %s (primary)\n", fi->DnsServerList.IpAddress.String);
|
||||
}
|
||||
if (inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
|
||||
left > ip_size)
|
||||
{
|
||||
ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
|
||||
left -= ret - ret_buf;
|
||||
count++;
|
||||
}
|
||||
|
||||
for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
|
||||
ipAddr = ipAddr->Next, i++)
|
||||
{
|
||||
if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
|
||||
{
|
||||
ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
|
||||
left -= ret - ret_buf;
|
||||
count++;
|
||||
}
|
||||
if (debug)
|
||||
printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
|
||||
}
|
||||
|
||||
quit:
|
||||
if (handle)
|
||||
FreeLibrary (handle);
|
||||
|
||||
if (debug && left <= ip_size)
|
||||
printf ("Too many nameservers. Truncating to %d addressess", count);
|
||||
if (ret > ret_buf)
|
||||
ret[-1] = '\0';
|
||||
return (count);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int init_by_resolv_conf(ares_channel channel)
|
||||
@@ -295,6 +370,11 @@ static int init_by_resolv_conf(ares_channel channel)
|
||||
#ifdef WIN32
|
||||
|
||||
/*
|
||||
NameServer info via IPHLPAPI (IP helper API):
|
||||
GetNetworkParams() should be the trusted source for this.
|
||||
Available in Win-98/2000 and later. If that fail, fall-back to
|
||||
registry information.
|
||||
|
||||
NameServer Registry:
|
||||
|
||||
On Windows 9X, the DNS server can be found in:
|
||||
@@ -317,11 +397,19 @@ DhcpNameServer
|
||||
DWORD data_type;
|
||||
DWORD bytes;
|
||||
DWORD result;
|
||||
DWORD keysize = MAX_PATH;
|
||||
char buf[256];
|
||||
|
||||
status = ARES_EFILE;
|
||||
if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
|
||||
return ARES_SUCCESS;
|
||||
|
||||
if (IsNT)
|
||||
if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
|
||||
{
|
||||
status = config_nameserver(&servers, &nservers, buf);
|
||||
if (status == ARES_SUCCESS)
|
||||
goto okay;
|
||||
}
|
||||
|
||||
if (IsNT)
|
||||
{
|
||||
if (RegOpenKeyEx(
|
||||
HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
|
||||
@@ -365,7 +453,7 @@ DhcpNameServer
|
||||
if ((result = RegQueryValueEx(
|
||||
mykey, NAMESERVER, NULL, &data_type,
|
||||
NULL, &bytes
|
||||
)
|
||||
)
|
||||
) == ERROR_SUCCESS ||
|
||||
result == ERROR_MORE_DATA)
|
||||
{
|
||||
@@ -381,19 +469,12 @@ DhcpNameServer
|
||||
free(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(mykey);
|
||||
}
|
||||
|
||||
if (status != ARES_EFILE)
|
||||
{
|
||||
/*
|
||||
if (!channel->lookups) {
|
||||
status = config_lookup(channel, "file bind");
|
||||
}
|
||||
*/
|
||||
|
||||
if (status == ARES_SUCCESS)
|
||||
status = ARES_EOF;
|
||||
}
|
||||
|
||||
#elif defined(riscos)
|
||||
|
||||
@@ -401,7 +482,7 @@ DhcpNameServer
|
||||
system variable Inet$Resolvers, space separated. */
|
||||
|
||||
line = getenv("Inet$Resolvers");
|
||||
status = ARES_EFILE;
|
||||
status = ARES_EOF;
|
||||
if (line) {
|
||||
char *resolvers = strdup(line), *pos, *space;
|
||||
|
||||
@@ -421,7 +502,7 @@ DhcpNameServer
|
||||
|
||||
if (status == ARES_SUCCESS)
|
||||
status = ARES_EOF;
|
||||
|
||||
|
||||
free(resolvers);
|
||||
}
|
||||
|
||||
@@ -430,17 +511,17 @@ DhcpNameServer
|
||||
char *p;
|
||||
FILE *fp;
|
||||
int linesize;
|
||||
|
||||
|
||||
fp = fopen(PATH_RESOLV_CONF, "r");
|
||||
if (!fp)
|
||||
return (errno == ENOENT) ? ARES_SUCCESS : ARES_EFILE;
|
||||
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
|
||||
{
|
||||
if ((p = try_config(line, "domain")) && channel->ndomains == -1)
|
||||
if ((p = try_config(line, "domain")))
|
||||
status = config_domain(channel, p);
|
||||
else if ((p = try_config(line, "lookup")) && !channel->lookups)
|
||||
status = config_lookup(channel, p);
|
||||
else if ((p = try_config(line, "search")) && channel->ndomains == -1)
|
||||
else if ((p = try_config(line, "search")))
|
||||
status = set_search(channel, p);
|
||||
else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
|
||||
status = config_nameserver(&servers, &nservers, p);
|
||||
@@ -453,7 +534,8 @@ DhcpNameServer
|
||||
if (status != ARES_SUCCESS)
|
||||
break;
|
||||
}
|
||||
free(line);
|
||||
if(line)
|
||||
free(line);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
@@ -462,12 +544,17 @@ DhcpNameServer
|
||||
/* Handle errors. */
|
||||
if (status != ARES_EOF)
|
||||
{
|
||||
if (servers != NULL) free(servers);
|
||||
if (sortlist != NULL) free(sortlist);
|
||||
if (servers != NULL)
|
||||
free(servers);
|
||||
if (sortlist != NULL)
|
||||
free(sortlist);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* If we got any name server entries, fill them in. */
|
||||
#ifdef WIN32
|
||||
okay:
|
||||
#endif
|
||||
if (servers)
|
||||
{
|
||||
channel->servers = servers;
|
||||
@@ -701,6 +788,14 @@ static int set_search(ares_channel channel, const char *str)
|
||||
int n;
|
||||
const char *p, *q;
|
||||
|
||||
if(channel->ndomains != -1) {
|
||||
/* if we already have some domains present, free them first */
|
||||
for(n=0; n < channel->ndomains; n++)
|
||||
free(channel->domains[n]);
|
||||
free(channel->domains);
|
||||
channel->ndomains = -1;
|
||||
}
|
||||
|
||||
/* Count the domains given. */
|
||||
n = 0;
|
||||
p = str;
|
||||
|
@@ -124,7 +124,12 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
|
||||
free(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* failed, free the malloc()ed memory */
|
||||
free(squery->name);
|
||||
free(squery);
|
||||
callback(arg, status, NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
14
buildconf
14
buildconf
@@ -157,27 +157,27 @@ fi
|
||||
# run the correct scripts now
|
||||
|
||||
echo "buildconf: running libtoolize"
|
||||
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The command '${LIBTOOLIZE:-libtoolize} --copy --automake --force' failed"
|
||||
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The libtool command failed"
|
||||
echo "buildconf: running aclocal"
|
||||
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The command '${ACLOCAL:-aclocal}${ACLOCAL_FLAGS:+" $ACLOCAL_FLAGS"}' failed"
|
||||
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The aclocal command line failed"
|
||||
echo "buildconf: running aclocal hack to convert all mv to mv -f"
|
||||
perl -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
|
||||
echo "buildconf: running autoheader"
|
||||
${AUTOHEADER:-autoheader} || die "The command '${AUTOHEADER:-autoheader}' failed"
|
||||
${AUTOHEADER:-autoheader} || die "The autoheader command failed"
|
||||
echo "buildconf: running autoconf"
|
||||
${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed"
|
||||
${AUTOCONF:-autoconf} || die "The autoconf command failed"
|
||||
|
||||
if test -d ares; then
|
||||
cd ares
|
||||
echo "buildconf: running aclocal in the ares directory"
|
||||
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The command '${ACLOCAL:-aclocal}${ACLOCAL_FLAGS:+" $ACLOCAL_FLAGS"}' failed"
|
||||
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The ares aclocal command failed"
|
||||
echo "buildconf: running autoconf in the ares directory"
|
||||
${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed"
|
||||
${AUTOCONF:-autoconf} || die "The ares autoconf command failed"
|
||||
cd ..
|
||||
fi
|
||||
|
||||
echo "buildconf: running automake"
|
||||
${AUTOMAKE:-automake} -a || die "The command '${AUTOMAKE:-automake} -a' failed"
|
||||
${AUTOMAKE:-automake} -a || die "The automake command failed"
|
||||
|
||||
echo "buildconf: OK"
|
||||
exit 0
|
||||
|
222
configure.ac
222
configure.ac
@@ -16,12 +16,24 @@ AM_CONFIG_HEADER(lib/config.h src/config.h)
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
dnl SED is needed by some of the tools
|
||||
AC_PATH_PROG( SED, sed, , $PATH:/usr/bin:/usr/local/bin)
|
||||
AC_PATH_PROG( SED, sed, sed-was-not-found-by-configure,
|
||||
$PATH:/usr/bin:/usr/local/bin)
|
||||
AC_SUBST(SED)
|
||||
|
||||
if test "x$SED" = "xsed-was-not-found-by-configure"; then
|
||||
AC_MSG_WARN([sed was not found, this may ruin your chances to build fine])
|
||||
fi
|
||||
|
||||
dnl AR is used by libtool, and try the odd Solaris path too
|
||||
AC_PATH_PROG( AR, ar, , $PATH:/usr/bin:/usr/local/bin:/usr/ccs/bin)
|
||||
dnl we use AC_CHECK_TOOL since this should make a library for the target
|
||||
dnl platform
|
||||
AC_CHECK_TOOL(AR, ar,
|
||||
ar-was-not-found-by-configure,
|
||||
$PATH:/usr/bin:/usr/local/bin:/usr/ccs/bin)
|
||||
AC_SUBST(AR)
|
||||
if test "x$AR" = "xar-was-not-found-by-configure"; then
|
||||
AC_MSG_WARN([ar was not found, this may ruin your chances to build fine])
|
||||
fi
|
||||
|
||||
dnl figure out the libcurl version
|
||||
VERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curlver.h`
|
||||
@@ -42,6 +54,17 @@ AC_SUBST(PKGADD_PKG)
|
||||
AC_SUBST(PKGADD_NAME)
|
||||
AC_SUBST(PKGADD_VENDOR)
|
||||
|
||||
dnl
|
||||
dnl initialize all the info variables to 'no'
|
||||
curl_ssl_msg="no (--with-ssl)"
|
||||
curl_zlib_msg="no (--with-zlib)"
|
||||
curl_krb4_msg="no (--with-krb4*)"
|
||||
curl_gss_msg="no (--with-gssapi)"
|
||||
curl_spnego_msg="no (--with-spnego)"
|
||||
curl_ares_msg="no (--enable-ares)"
|
||||
curl_ipv6_msg="no (--enable-ipv6)"
|
||||
curl_idn_msg="no (--with-libidn)"
|
||||
curl_manual_msg="no (--enable-manual)"
|
||||
|
||||
dnl
|
||||
dnl Detect the canonical host and target build environment
|
||||
@@ -258,7 +281,7 @@ dnl At least one system has been identified to require BOTH nsl and socket
|
||||
dnl libs at the same time to link properly.
|
||||
if test "$HAVE_GETHOSTBYNAME" != "1"
|
||||
then
|
||||
AC_MSG_CHECKING([trying gethostbyname with both nsl and socket libs])
|
||||
AC_MSG_CHECKING([for gethostbyname with both nsl and socket libs])
|
||||
my_ac_save_LIBS=$LIBS
|
||||
LIBS="-lnsl -lsocket $LIBS"
|
||||
AC_TRY_LINK( ,
|
||||
@@ -383,6 +406,8 @@ main()
|
||||
))
|
||||
|
||||
if test "$ipv6" = "yes"; then
|
||||
curl_ipv6_msg="enabled"
|
||||
|
||||
CURL_CHECK_WORKING_GETADDRINFO
|
||||
|
||||
CURL_CHECK_NI_WITHSCOPEID
|
||||
@@ -549,6 +574,8 @@ then
|
||||
KRB4_ENABLED=1
|
||||
AC_SUBST(KRB4_ENABLED)
|
||||
|
||||
curl_krb4_msg="enabled"
|
||||
|
||||
dnl the krb4 stuff needs a strlcpy()
|
||||
AC_CHECK_FUNCS(strlcpy)
|
||||
|
||||
@@ -582,7 +609,9 @@ if test x"$want_spnego" = xyes; then
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SPNEGO, 1, [Define this if you have the SPNEGO library fbopenssl])
|
||||
AC_DEFINE(HAVE_SPNEGO, 1,
|
||||
[Define this if you have the SPNEGO library fbopenssl])
|
||||
curl_spnego_msg="enabled"
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
@@ -638,6 +667,8 @@ if test x"$want_gss" = xyes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GSSAPI, 1, [if you have the gssapi libraries])
|
||||
|
||||
curl_gss_msg="enabled"
|
||||
|
||||
if test -n "$GSSAPI_INCS"; then
|
||||
# cut off the preceding -I from the include path
|
||||
GSSAPI_INCS=`echo $GSSAPI_INCS | sed -e s/^-I//g`
|
||||
@@ -653,33 +684,6 @@ else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
|
||||
dnl Detect the pkg-config tool, as it may have extra info about the
|
||||
dnl openssl installation we can use. I *believe* this is what we are
|
||||
dnl expected to do on really recent Redhat Linux hosts.
|
||||
AC_PATH_PROG( PKGCONFIG, pkg-config, no, $PATH:/usr/bin:/usr/local/bin)
|
||||
if test "$PKGCONFIG" != "no" ; then
|
||||
AC_MSG_CHECKING([for OpenSSL options using pkg-config])
|
||||
|
||||
$PKGCONFIG --exists openssl
|
||||
SSL_EXISTS=$?
|
||||
|
||||
if test "$SSL_EXISTS" -eq "0"; then
|
||||
SSL_LIBS=`$PKGCONFIG --libs-only-l openssl 2>/dev/null`
|
||||
SSL_LDFLAGS=`$PKGCONFIG --libs-only-L openssl 2>/dev/null`
|
||||
SSL_CPPFLAGS=`$PKGCONFIG --cflags-only-I openssl 2>/dev/null`
|
||||
|
||||
LIBS="$LIBS $SSL_LIBS"
|
||||
CPPFLAGS="$CPPFLAGS $SSL_CPPFLAGS"
|
||||
LDFLAGS="$LDFLAGS $SSL_LDFLAGS"
|
||||
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for the presence of SSL libraries and headers
|
||||
dnl **********************************************************************
|
||||
@@ -698,11 +702,36 @@ then
|
||||
AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more])
|
||||
else
|
||||
|
||||
dnl Check for and handle argument to --with-ssl.
|
||||
|
||||
dnl save the pre-ssl check flags for a while
|
||||
dnl backup the pre-ssl variables
|
||||
CLEANLDFLAGS="$LDFLAGS"
|
||||
CLEANCPPFLAGS="$CPPFLAGS"
|
||||
CLEANLIBS="$LIBS"
|
||||
|
||||
dnl Detect the pkg-config tool, as it may have extra info about the openssl
|
||||
dnl installation we can use. I *believe* this is what we are expected to do
|
||||
dnl on really recent Redhat Linux hosts.
|
||||
|
||||
AC_PATH_PROG( PKGCONFIG, pkg-config, no, $PATH:/usr/bin:/usr/local/bin)
|
||||
if test "$PKGCONFIG" != "no" ; then
|
||||
AC_MSG_CHECKING([OpenSSL options with pkg-config])
|
||||
|
||||
$PKGCONFIG --exists openssl
|
||||
SSL_EXISTS=$?
|
||||
|
||||
if test "$SSL_EXISTS" -eq "0"; then
|
||||
SSL_LIBS=`$PKGCONFIG --libs-only-l openssl 2>/dev/null`
|
||||
SSL_LDFLAGS=`$PKGCONFIG --libs-only-L openssl 2>/dev/null`
|
||||
SSL_CPPFLAGS=`$PKGCONFIG --cflags-only-I openssl 2>/dev/null`
|
||||
|
||||
dnl use the values pkg-config reported
|
||||
LIBS="$LIBS $SSL_LIBS"
|
||||
CPPFLAGS="$CPPFLAGS $SSL_CPPFLAGS"
|
||||
LDFLAGS="$LDFLAGS $SSL_LDFLAGS"
|
||||
AC_MSG_RESULT([found])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$OPT_SSL" in
|
||||
yes)
|
||||
@@ -720,14 +749,13 @@ else
|
||||
AC_CHECK_LIB(crypto, CRYPTO_lock,[
|
||||
HAVECRYPTO="yes"
|
||||
],[
|
||||
OLDLDFLAGS="$LDFLAGS"
|
||||
OLDCPPFLAGS="$CPPFLAGS"
|
||||
LDFLAGS="$CLEANLDFLAGS -L$EXTRA_SSL/lib$libsuff"
|
||||
CPPFLAGS="$CLEANCPPFLAGS -I$EXTRA_SSL/include/openssl -I$EXTRA_SSL/include"
|
||||
AC_CHECK_LIB(crypto, CRYPTO_add_lock,[
|
||||
HAVECRYPTO="yes" ], [
|
||||
LDFLAGS="$OLDLDFLAGS"
|
||||
CPPFLAGS="$OLDCPPFLAGS"
|
||||
LDFLAGS="$CLEANLDFLAGS"
|
||||
CPPFLAGS="$CLEANCPPFLAGS"
|
||||
LIBS="$CLEANLIBS"
|
||||
])
|
||||
])
|
||||
|
||||
@@ -772,10 +800,12 @@ else
|
||||
dnl Check for SSLeay headers
|
||||
AC_CHECK_HEADERS(openssl/x509.h openssl/rsa.h openssl/crypto.h \
|
||||
openssl/pem.h openssl/ssl.h openssl/err.h,
|
||||
curl_ssl_msg="enabled"
|
||||
OPENSSL_ENABLED=1)
|
||||
|
||||
if test $ac_cv_header_openssl_x509_h = no; then
|
||||
AC_CHECK_HEADERS(x509.h rsa.h crypto.h pem.h ssl.h err.h,
|
||||
curl_ssl_msg="enabled"
|
||||
OPENSSL_ENABLED=1)
|
||||
fi
|
||||
|
||||
@@ -896,6 +926,7 @@ case "$OPT_ZLIB" in
|
||||
dnl replace 'HAVE_LIBZ' in the automake makefile.ams
|
||||
AMFIXLIB="1"
|
||||
AC_MSG_NOTICE([found both libz and libz.h header])
|
||||
curl_zlib_msg="enabled"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
@@ -903,6 +934,43 @@ esac
|
||||
dnl set variable for use in automakefile(s)
|
||||
AM_CONDITIONAL(HAVE_LIBZ, test x"$AMFIXLIB" = x1)
|
||||
|
||||
AC_MSG_CHECKING([whether to build with libidn])
|
||||
AC_ARG_WITH(libidn,
|
||||
AC_HELP_STRING([--with-libidn=PATH],[Enable libidn usage])
|
||||
AC_HELP_STRING([--without-libidn],[Disable libidn usage]),
|
||||
[LIBIDN="$withval"])
|
||||
|
||||
case "$LIBIDN" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
AC_CHECK_LIB(idn, idna_to_ascii_lz, ,
|
||||
[
|
||||
dnl if there was a given path, try it
|
||||
nolibidn="true"
|
||||
if test "x$LIBIDN" != "xyes"; then
|
||||
nolibidn="" dnl reset to test again
|
||||
oldLDFLAGS=$LDFLAGS
|
||||
oldCPPFLAGS=$CPPFLAGS
|
||||
LDFLAGS="$LDFLAGS -L$LIBIDN/lib"
|
||||
CPPFLAGS="$CPPFLAGS -I$LIBIDN/include"
|
||||
AC_CHECK_LIB(idn, idna_to_ascii_4i, ,
|
||||
nolibidn="true"
|
||||
LDFLAGS=$oldLDFLAGS
|
||||
CPPFLAGS=$oldCPPFLAGS)
|
||||
fi
|
||||
])
|
||||
if test "x$nolibidn" != "xtrue"; then
|
||||
curl_idn_msg="enabled"
|
||||
dnl different versions of libidn have different setups of these:
|
||||
AC_CHECK_FUNCS( idn_free )
|
||||
AC_CHECK_HEADERS( idn-free.h )
|
||||
fi
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl Default is to try the thread-safe versions of a few functions
|
||||
OPT_THREAD=on
|
||||
|
||||
@@ -1055,6 +1123,7 @@ AC_CHECK_SIZEOF(curl_off_t, ,[
|
||||
#include <stdio.h>
|
||||
#include "$srcdir/include/curl/curl.h"
|
||||
])
|
||||
AC_CHECK_SIZEOF(size_t)
|
||||
|
||||
AC_CHECK_TYPE(long long,
|
||||
[AC_DEFINE(HAVE_LONGLONG, 1, [if your compiler supports 'long long'])])
|
||||
@@ -1192,41 +1261,12 @@ dnl manual
|
||||
|
||||
if test "$USE_MANUAL" = "1"; then
|
||||
AC_DEFINE(USE_MANUAL, 1, [If you want to build curl with the built-in manual])
|
||||
curl_manual_msg="enabled"
|
||||
fi
|
||||
|
||||
dnl set variable for use in automakefile(s)
|
||||
AM_CONDITIONAL(USE_MANUAL, test x"$USE_MANUAL" = x1)
|
||||
|
||||
|
||||
dnl AC_PATH_PROG( RANLIB, ranlib, /usr/bin/ranlib,
|
||||
dnl $PATH:/usr/bin/:/usr/local/bin )
|
||||
dnl AC_SUBST(RANLIB)
|
||||
|
||||
dnl ************************************************************
|
||||
dnl lame option to switch on debug options
|
||||
dnl
|
||||
AC_MSG_CHECKING([whether to enable debug options])
|
||||
AC_ARG_ENABLE(debug,
|
||||
AC_HELP_STRING([--enable-debug],[Enable pedantic debug options])
|
||||
AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
|
||||
CPPFLAGS="$CPPFLAGS -DCURLDEBUG"
|
||||
CFLAGS="$CFLAGS -g"
|
||||
|
||||
dnl set compiler "debug" options to become more picky, and remove
|
||||
dnl optimize options from CFLAGS
|
||||
CURL_CC_DEBUG_OPTS
|
||||
;;
|
||||
esac
|
||||
],
|
||||
AC_MSG_RESULT(no)
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([whether to enable ares])
|
||||
AC_ARG_ENABLE(ares,
|
||||
AC_HELP_STRING([--enable-ares=PATH],[Enable ares for name lookups])
|
||||
@@ -1245,6 +1285,7 @@ AC_HELP_STRING([--disable-ares],[Disable ares for name lookups]),
|
||||
dnl substitute HAVE_ARES for curl-config and similar
|
||||
HAVE_ARES="1"
|
||||
AC_SUBST(HAVE_ARES)
|
||||
curl_ares_msg="enabled"
|
||||
|
||||
LIBS="$LIBS -lcares"
|
||||
|
||||
@@ -1299,6 +1340,33 @@ int main(void)
|
||||
AC_MSG_RESULT(no)
|
||||
)
|
||||
|
||||
dnl ************************************************************
|
||||
dnl lame option to switch on debug options
|
||||
dnl
|
||||
AC_MSG_CHECKING([whether to enable debug options])
|
||||
AC_ARG_ENABLE(debug,
|
||||
AC_HELP_STRING([--enable-debug],[Enable pedantic debug options])
|
||||
AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
|
||||
CPPFLAGS="$CPPFLAGS -DCURLDEBUG"
|
||||
CFLAGS="$CFLAGS -g"
|
||||
|
||||
dnl set compiler "debug" options to become more picky, and remove
|
||||
dnl optimize options from CFLAGS
|
||||
CURL_CC_DEBUG_OPTS
|
||||
;;
|
||||
esac
|
||||
],
|
||||
AC_MSG_RESULT(no)
|
||||
)
|
||||
|
||||
AM_CONDITIONAL(CROSSCOMPILING, test x$cross_compiling = xyes)
|
||||
|
||||
AC_CONFIG_FILES([Makefile \
|
||||
docs/Makefile \
|
||||
docs/examples/Makefile \
|
||||
@@ -1326,3 +1394,21 @@ AC_CONFIG_FILES([Makefile \
|
||||
curl-config
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
AC_MSG_NOTICE([Configured to build curl/libcurl:
|
||||
|
||||
curl version: ${VERSION}
|
||||
Host setup: ${host}
|
||||
Install prefix: ${prefix}
|
||||
Compiler: ${CC}
|
||||
SSL support: ${curl_ssl_msg}
|
||||
zlib support: ${curl_zlib_msg}
|
||||
krb4 support: ${curl_krb4_msg}
|
||||
GSSAPI support: ${curl_gss_msg}
|
||||
SNPEGO support: ${curl_spnego_msg}
|
||||
c-ares support: ${curl_ares_msg}
|
||||
ipv6 support: ${curl_ipv6_msg}
|
||||
IDN support: ${curl_idn_msg}
|
||||
Build libcurl: Shared=${enable_shared}, Static=${enable_static}
|
||||
Built-in manual: ${curl_manual_msg}
|
||||
])
|
||||
|
@@ -33,7 +33,10 @@
|
||||
;; keybindings for C, C++, and Objective-C. We can put these in
|
||||
;; c-mode-base-map because of inheritance ...
|
||||
(define-key c-mode-base-map "\M-q" 'c-fill-paragraph)
|
||||
(define-key c-mode-base-map "\M-m" 'delete-trailing-whitespace)
|
||||
(setq c-recognize-knr-p nil)
|
||||
;;; (add-hook 'write-file-hooks 'delete-trailing-whitespace t)
|
||||
(setq show-trailing-whitespace t)
|
||||
)
|
||||
|
||||
;; Set this is in your .emacs if you want to use the c-mode-hook as
|
||||
|
@@ -126,3 +126,5 @@ visitors to the curl.haxx.se site. Five official web mirrors.
|
||||
December 2003, full-fledged SSL for FTP is supported.
|
||||
|
||||
January 2004: curl 7.11.0 introduced large file support.
|
||||
|
||||
June 2004: curl 7.12.0 introduced IDN support. 10 official web mirrors.
|
||||
|
@@ -3,9 +3,13 @@ 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!
|
||||
|
||||
* If you use a very large amount of file descriptors (more than FD_SETSIZE)
|
||||
and then use libcurl, it might crash on its use of select() which then
|
||||
stores data out of bounds. Bug report #948950.
|
||||
|
||||
* --limit-rate using -d or -F does not work. This is because the limit logic
|
||||
is provided by the curl app in its read/write callbacks, and when doing
|
||||
-d/-F the callbacks aren't used!
|
||||
-d/-F the callbacks aren't used! Bug report #921395.
|
||||
|
||||
* Doing resumed upload over HTTP does not work with '-C -', because curl
|
||||
doesn't do a HEAD first to get the initial size. This needs to be done
|
||||
|
83
docs/LICENSE-MIXING
Normal file
83
docs/LICENSE-MIXING
Normal file
@@ -0,0 +1,83 @@
|
||||
License Mixing with apps, libcurl and Third Party Libraries
|
||||
===========================================================
|
||||
|
||||
libcurl can be built to use a fair amount of various third party libraries,
|
||||
libraries that are written and provided by other parties that are distributed
|
||||
using their own licenses. Even libcurl itself contains code that may cause
|
||||
problems to some. This document attempts to describe what licenses libcurl and
|
||||
the other libraries use and what possible dilemmas linking and mixing them all
|
||||
can lead to for end users.
|
||||
|
||||
I am not a lawyer and this is not legal advice!
|
||||
|
||||
One common dilemma is that GPL[*]-licensed code is not allowed to be linked
|
||||
with code licensed under the Original BSD license (with the announcement
|
||||
clause, unless there's a specified exception in the GPL-licensed module). You
|
||||
may still build your own copies that use them all, but distributing them as
|
||||
binaries would be to violate the GPL license. This particular problem was
|
||||
addressed when the Modified BSD license was created, which does not have the
|
||||
annoncement clause that collides with GPL.
|
||||
|
||||
libcurl http://curl.haxx.se/docs/copyright.html
|
||||
|
||||
Uses an MIT (or Modified BSD)-style license that is as liberal as
|
||||
possible. Some of the source files that deal with KRB4 have Original
|
||||
BSD-style announce-clause licenses. You may not distribute binaries
|
||||
with krb4-enabled libcurl that also link with GPL-licensed code!
|
||||
|
||||
OpenSSL http://www.openssl.org/source/license.html
|
||||
|
||||
Uses an Original BSD-style license with an announement clause that
|
||||
makes it "incompatible" with GPL. You are not allowed to ship binaries
|
||||
that link with OpenSSL that includes GPL code (unless that specific
|
||||
GPL code includes an exception for OpenSSL - a habit that is growing
|
||||
more and more common).
|
||||
|
||||
c-ares http://daniel.haxx.se/projects/c-ares/license.html
|
||||
|
||||
Uses an MIT license that is very liberal and imposes no restrictions
|
||||
on any other library or part you may link with.
|
||||
|
||||
zlib http://www.gzip.org/zlib/zlib_license.html
|
||||
|
||||
Uses an MIT-style license that shouldn't collide with any other
|
||||
library.
|
||||
|
||||
krb4
|
||||
|
||||
While nothing in particular says that a Kerberos4 library must use any
|
||||
particular license, the one I've tried and used successfully so far
|
||||
(kth-krb4) is Original BSD-licensed with the announcement clause. Some
|
||||
of the code in libcurl that is written to deal with Kerberos4 likewise
|
||||
have such a license.
|
||||
|
||||
GSSAPI
|
||||
|
||||
While nothing in particular says that a GSS/Kerberos5 library must use
|
||||
any particular license, the one I've used (Heimdal) is Original BSD-
|
||||
licensed with the announcement clause.
|
||||
|
||||
fbopenssl
|
||||
|
||||
Unclear license. Based on its name, I assume that it uses the OpenSSL
|
||||
license and thus shares the same issues as described for OpenSSL
|
||||
above.
|
||||
|
||||
libidn http://www.gnu.org/licenses/lgpl.html
|
||||
|
||||
Uses the GNU Lesser General Public License. LGPL is a variation of GPL
|
||||
with slightly less aggressive "copyleft". This license requires more
|
||||
requirements to be met when distributing binaries, see the license for
|
||||
details. Also note that if you distribute a binary that includes this
|
||||
library, you must also include the full LGPL license text. Please
|
||||
properly point out what parts of the distributed package that the
|
||||
license addresses.
|
||||
|
||||
OpenLDAP http://www.openldap.org/software/release/license.html
|
||||
|
||||
Uses a Modified BSD-style license. Since libcurl uses OpenLDAP as a
|
||||
shared library only, I have not heard of anyone that ships OpenLDAP
|
||||
linked with libcurl in an app.
|
||||
|
||||
|
||||
[*] = GPL - GNU General Public License: http://www.gnu.org/licenses/gpl.html
|
20
docs/MANUAL
20
docs/MANUAL
@@ -851,7 +851,7 @@ MAILING LISTS
|
||||
|
||||
For your convenience, we have several open mailing lists to discuss curl,
|
||||
its development and things relevant to this. Get all info at
|
||||
http://curl.haxx.se/mail/. The lists available are:
|
||||
http://curl.haxx.se/mail/. Some of the lists available are:
|
||||
|
||||
curl-users
|
||||
|
||||
@@ -865,24 +865,18 @@ MAILING LISTS
|
||||
|
||||
curl-announce
|
||||
|
||||
Low-traffic. Only announcements of new public versions.
|
||||
Low-traffic. Only receives announcements of new public versions. At worst,
|
||||
that makes something like one or two mails per month, but usually only one
|
||||
mail every second month.
|
||||
|
||||
curl-and-PHP
|
||||
curl-and-php
|
||||
|
||||
Using the curl functions in PHP. Everything curl with a PHP angle. Or PHP
|
||||
with a curl angle.
|
||||
|
||||
curl-commits
|
||||
curl-and-python
|
||||
|
||||
Receives notifications on all CVS commits done to the curl source module.
|
||||
This can become quite a large amount of mails during intense development,
|
||||
be aware. This is for us who like email...
|
||||
|
||||
curl-www-commits
|
||||
|
||||
Receives notifications on all CVS commits done to the curl www module
|
||||
(basicly the web site). This can become quite a large amount of mails
|
||||
during intense changing, be aware. This is for us who like email...
|
||||
Python hackers using curl with or without the python binding pycurl.
|
||||
|
||||
Please direct curl questions, feature requests and trouble reports to one of
|
||||
these mailing lists instead of mailing any individual.
|
||||
|
@@ -4,28 +4,20 @@
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
|
||||
man_MANS = \
|
||||
curl.1 \
|
||||
curl-config.1
|
||||
|
||||
GENHTMLPAGES = \
|
||||
curl.html \
|
||||
curl-config.html
|
||||
man_MANS = curl.1 curl-config.1
|
||||
GENHTMLPAGES = curl.html curl-config.html
|
||||
PDFPAGES = curl.pdf curl-config.pdf
|
||||
|
||||
HTMLPAGES = $(GENHTMLPAGES) index.html
|
||||
|
||||
PDFPAGES = \
|
||||
curl.pdf \
|
||||
curl-config.pdf
|
||||
|
||||
SUBDIRS = examples libcurl
|
||||
|
||||
CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES)
|
||||
|
||||
EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
|
||||
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS \
|
||||
VERSIONS KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) \
|
||||
HISTORY INSTALL libcurl-the-guide $(PDFPAGES)
|
||||
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
|
||||
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
|
||||
$(PDFPAGES) LICENSE-MIXING
|
||||
|
||||
MAN2HTML= roffit < $< >$@
|
||||
|
||||
|
31
docs/TODO
31
docs/TODO
@@ -36,6 +36,10 @@ TODO
|
||||
* Option to set the SO_KEEPALIVE socket option to make libcurl notice and
|
||||
disconnect very long time idle connections.
|
||||
|
||||
* When posting multipart forms, we should _not_ create the whole data chunk
|
||||
in memory before the upload starts but do it in a "streaming" manner to
|
||||
allow uploads that are way larger than the amount of system memory.
|
||||
|
||||
LIBCURL - multi interface
|
||||
|
||||
* Add curl_multi_timeout() to make libcurl's ares-functionality better.
|
||||
@@ -77,10 +81,16 @@ TODO
|
||||
* Since USERPWD always override the user and password specified in URLs, we
|
||||
might need another way to specify user+password for anonymous ftp logins.
|
||||
|
||||
* The FTP code should get a way of returning errors that is known to still
|
||||
have the control connection alive and sound. Currently, a returned error
|
||||
from within ftp-functions does not tell if the control connection is still
|
||||
OK to use or not. This causes libcurl to fail to re-use connections
|
||||
slightly too often.
|
||||
|
||||
HTTP
|
||||
|
||||
* Digest and GSS-Negotiate support for HTTP proxies. They only work on
|
||||
direct-connections to the server.
|
||||
* GSS-Negotiate support for HTTP proxies. They only work on direct
|
||||
connections to the server.
|
||||
|
||||
* Pipelining. Sending multiple requests before the previous one(s) are done.
|
||||
This could possibly be implemented using the multi interface to queue
|
||||
@@ -104,9 +114,6 @@ TODO
|
||||
* Evaluate/apply Gertjan van Wingerde's SSL patches:
|
||||
http://curl.haxx.se/mail/lib-2004-03/0087.html
|
||||
|
||||
* Peter Sylvester's "Most Significant Common Name" change. Feedback welcome.
|
||||
At least the UTF8 conversion and comparison should be done. Patch?
|
||||
|
||||
* If you really want to improve the SSL situation, you should probably have a
|
||||
look at SSL cafile loading as well - quick traces look to me like these are
|
||||
done on every request as well, when they should only be necessary once per
|
||||
@@ -174,6 +181,18 @@ TODO
|
||||
* --data-encode that URL encodes the data before posting
|
||||
http://curl.haxx.se/mail/archive-2003-11/0091.html (Kevin Roth suggested)
|
||||
|
||||
* Provide a way to make options bound to a specific URL among several on the
|
||||
command line. Possibly by adding a new option that separates options
|
||||
between URLs, similar to this:
|
||||
|
||||
curl --data foo --url url.com --optionseparator
|
||||
--url url2.com --optionseparator \
|
||||
--url url3.com --data foo3
|
||||
|
||||
(--optionseparator used to show my point, it would need a better name)
|
||||
|
||||
The example would do a POST-GET-POST combination on a single command line.
|
||||
|
||||
BUILD
|
||||
|
||||
* Consider extending 'roffit' to produce decent ASCII output, and use that
|
||||
@@ -201,8 +220,6 @@ TODO
|
||||
* curl_easy_cleanup() returns void, but curl_multi_cleanup() returns a
|
||||
CURLMcode. These should be changed to be the same.
|
||||
|
||||
* curl_formparse() should be removed
|
||||
|
||||
* remove obsolete defines from curl/curl.h
|
||||
|
||||
* remove the following functions from the public API:
|
||||
|
60
docs/curl.1
60
docs/curl.1
@@ -1,8 +1,27 @@
|
||||
.\" You can view this file with:
|
||||
.\" nroff -man curl.1
|
||||
.\" Written by Daniel Stenberg
|
||||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2004, 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
|
||||
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
.\" *
|
||||
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
.\" * copies of the Software, and permit persons to whom the Software is
|
||||
.\" * furnished to do so, under the terms of the COPYING file.
|
||||
.\" *
|
||||
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
.\" * KIND, either express or implied.
|
||||
.\" *
|
||||
.\" * $Id$
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl 1 "25 Mar 2004" "Curl 7.11.2" "Curl Manual"
|
||||
.TH curl 1 "3 May 2004" "Curl 7.12" "Curl Manual"
|
||||
.SH NAME
|
||||
curl \- transfer a URL
|
||||
.SH SYNOPSIS
|
||||
@@ -37,9 +56,10 @@ or you can get sequences of alphanumeric series by using [] as in:
|
||||
ftp://ftp.numericals.com/file[001-100].txt (with leading zeros)
|
||||
ftp://ftp.letters.com/file[a-z].txt
|
||||
|
||||
No nesting of the sequences is supported at the moment:
|
||||
No nesting of the sequences is supported at the moment, but you can use
|
||||
several ones next to each other:
|
||||
|
||||
http://www.any.org/archive[1996-1999]/volume[1-4]part{a,b,c,index}.html
|
||||
http://any.org/archive[1996-1999]/vol[1-4]/part{a,b,c}.html
|
||||
|
||||
You can specify any amount of URLs on the command line. They will be fetched
|
||||
in a sequential manner in the specified order.
|
||||
@@ -123,7 +143,7 @@ If this option is used several times, each occurrence will toggle it on/off.
|
||||
.IP "--connect-timeout <seconds>"
|
||||
Maximum time in seconds that you allow the connection to the server to take.
|
||||
This only limits the connection phase, once curl has connected this option is
|
||||
of no more use. See also the \fI--max-time\fP option.
|
||||
of no more use. See also the \fI-m/--max-time\fP option.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-c/--cookie-jar <file name>"
|
||||
@@ -153,8 +173,12 @@ transfer. It then uses the given output/input files to figure that out.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--create-dirs"
|
||||
When used in conjunction with the -o option, curl will create the necessary
|
||||
local directory hierarchy as needed.
|
||||
When used in conjunction with the -o option, curl will create the necessary
|
||||
local directory hierarchy as needed. This option creates the dirs mentioned
|
||||
with the -o option, nothing else. If the -o file name uses no dir or if the
|
||||
dirs it mentions already exist, no dir will be created.
|
||||
|
||||
To create remote directories when using FTP, try \fI--ftp-create-dirs\fP.
|
||||
.IP "--crlf"
|
||||
(FTP) Convert LF to CRLF in upload. Useful for MVS (OS/390).
|
||||
|
||||
@@ -589,11 +613,23 @@ You may use this option as many times as you have number of URLs.
|
||||
(SSL) Pass phrase for the private key
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--proxy-basic"
|
||||
Tells curl to use HTTP Basic authentication when communicating with the given
|
||||
proxy. Use \fI--basic\fP for enabling HTTP Basic with a remote host. Basic is
|
||||
the default authentication method curl uses with proxies.
|
||||
|
||||
If this option is used twice, the second will again disable proxy HTTP Basic
|
||||
authentication.
|
||||
.IP "--proxy-digest"
|
||||
Tells curl to use HTTP Digest authentication when communicating with the given
|
||||
proxy. Use \fI--digest\fP for enabling HTTP Digest with a remote host.
|
||||
|
||||
If this option is used twice, the second will again disable proxy HTTP Digest.
|
||||
.IP "--proxy-ntlm"
|
||||
Tells curl to use NTLM authentication when communicating with the given
|
||||
Tells curl to use HTTP NTLM authentication when communicating with the given
|
||||
proxy. Use \fI--ntlm\fP for enabling NTLM with a remote host.
|
||||
|
||||
If this option is used twice, the second will again disable proxy NTLM.
|
||||
If this option is used twice, the second will again disable proxy HTTP NTLM.
|
||||
.IP "-p/--proxytunnel"
|
||||
When an HTTP proxy is used (\fI-x/--proxy\fP), this option will cause non-HTTP
|
||||
protocols to attempt to tunnel through the proxy instead of merely using it to
|
||||
@@ -821,6 +857,8 @@ This curl uses asynchronous name resolves.
|
||||
SPNEGO Negotiate authenticaion is supported.
|
||||
.IP "Largefile"
|
||||
This curl supports transfers of large files, files larger than 2GB.
|
||||
.IP "IDN"
|
||||
This curl supports IDN - international domain names.
|
||||
.RE
|
||||
.IP "-w/--write-out <format>"
|
||||
Defines what to display after a completed and successful operation. The format
|
||||
|
@@ -5,11 +5,11 @@
|
||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
|
||||
EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \
|
||||
persistant.c ftpget.c Makefile.example \
|
||||
multithread.c getinmemory.c ftpupload.c httpput.c \
|
||||
simplessl.c ftpgetresp.c http-post.c post-callback.c \
|
||||
multi-app.c multi-double.c multi-single.c multi-post.c \
|
||||
fopen.c simplepost.c makefile.dj curlx.c
|
||||
persistant.c ftpget.c Makefile.example multithread.c getinmemory.c \
|
||||
ftpupload.c httpput.c simplessl.c ftpgetresp.c http-post.c \
|
||||
post-callback.c multi-app.c multi-double.c multi-single.c \
|
||||
multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \
|
||||
multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c
|
||||
|
||||
all:
|
||||
@echo "done"
|
||||
|
65
docs/examples/fileupload.c
Normal file
65
docs/examples/fileupload.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
curl_off_t size;
|
||||
struct stat file_info;
|
||||
double speed_upload, total_time;
|
||||
FILE *fd;
|
||||
|
||||
fd = fopen("debugit", "r"); /* open file to upload */
|
||||
if(!fd) {
|
||||
|
||||
return 1; /* can't continue */
|
||||
}
|
||||
|
||||
stat("debugit", &file_info); /* to get the file size */
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* upload to this place */
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"file:///home/dast/src/curl/debug/new");
|
||||
|
||||
/* tell it to "upload" to the URL */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
||||
|
||||
/* set where to read from (on Windows you need to use READFUNCTION too) */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, fd);
|
||||
|
||||
/* and give the size of the upload (optional) */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)file_info.st_size);
|
||||
|
||||
/* enable verbose for easier tracing */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* now extract transfer info */
|
||||
curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed_upload);
|
||||
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time);
|
||||
|
||||
fprintf(stderr, "Speed: %.3f bytes/sec during %.3f seconds\n",
|
||||
speed_upload, total_time);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
104
docs/examples/ftp3rdparty.c
Normal file
104
docs/examples/ftp3rdparty.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
/*
|
||||
* This is an example showing how to transfer a file between two remote hosts.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
char sourceFileName[] = "/tmp/file";
|
||||
char targetFileName[] = "/tmp/curlTargetTest.dat";
|
||||
char sourceHost[] = "source";
|
||||
char targetHost[] = "target";
|
||||
char sourceUserPass[] = "user:pass";
|
||||
char targetUserPass[] = "user:pass";
|
||||
char url[100];
|
||||
|
||||
struct curl_slist *source_pre_cmd = NULL;
|
||||
struct curl_slist *target_pre_cmd = NULL;
|
||||
struct curl_slist *source_post_cmd = NULL;
|
||||
struct curl_slist *target_post_cmd = NULL;
|
||||
char cmd[] = "PWD"; /* just to test */
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (curl) {
|
||||
sprintf(url, "ftp://%s@%s/%s", targetUserPass, targetHost, targetFileName);
|
||||
printf("%s\n", url);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
|
||||
/* Set a proxy host */
|
||||
curl_easy_setopt(curl, CURLOPT_SOURCE_HOST, sourceHost);
|
||||
|
||||
/* Set a proxy user and password */
|
||||
curl_easy_setopt(curl, CURLOPT_SOURCE_USERPWD, sourceUserPass);
|
||||
|
||||
/* Set a proxy full file name */
|
||||
curl_easy_setopt(curl, CURLOPT_SOURCE_PATH, sourceFileName);
|
||||
|
||||
/* Set a proxy passive host */
|
||||
curl_easy_setopt(curl, CURLOPT_PASV_HOST, 0); /* optional */
|
||||
|
||||
/* build a list of commands to pass to libcurl */
|
||||
source_pre_cmd = curl_slist_append(source_pre_cmd, cmd);
|
||||
/* Set a proxy pre-quote command */
|
||||
curl_easy_setopt(curl, CURLOPT_SOURCE_PREQUOTE, source_pre_cmd);
|
||||
|
||||
/* build a list of commands to pass to libcurl */
|
||||
target_pre_cmd = curl_slist_append(target_pre_cmd, cmd);
|
||||
/* Set a pre-quote command */
|
||||
curl_easy_setopt(curl, CURLOPT_PREQUOTE, target_pre_cmd);
|
||||
|
||||
/* build a list of commands to pass to libcurl */
|
||||
source_post_cmd = curl_slist_append(source_post_cmd, cmd);
|
||||
/* Set a proxy post-quote command */
|
||||
curl_easy_setopt(curl, CURLOPT_SOURCE_POSTQUOTE, source_post_cmd);
|
||||
|
||||
/* build a list of commands to pass to libcurl */
|
||||
target_post_cmd = curl_slist_append(target_post_cmd, cmd);
|
||||
/* Set a post-quote command */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTQUOTE, target_post_cmd);
|
||||
|
||||
/* Switch on full protocol/debug output */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* clean up the FTP commands list */
|
||||
curl_slist_free_all(source_pre_cmd);
|
||||
curl_slist_free_all(target_pre_cmd);
|
||||
curl_slist_free_all(source_post_cmd);
|
||||
curl_slist_free_all(target_post_cmd);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(CURLE_OK != res) {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
@@ -46,7 +46,7 @@ int main(int argc, char **argv)
|
||||
close(hd) ;
|
||||
|
||||
/* get a FILE * of the same file, could also be made with
|
||||
fdopen() from the previous descriptor, but hey this is just
|
||||
fdopen() from the previous descriptor, but hey this is just
|
||||
an example! */
|
||||
hd_src = fopen(LOCAL_FILE, "rb");
|
||||
|
||||
|
37
docs/examples/getinfo.c
Normal file
37
docs/examples/getinfo.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se");
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(CURLE_OK == res) {
|
||||
char *ct;
|
||||
/* ask for the content-type */
|
||||
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
|
||||
|
||||
if((CURLE_OK == res) && ct)
|
||||
printf("We received Content-Type: %s\n", ct);
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
@@ -62,6 +62,10 @@ int main(int argc, char **argv)
|
||||
/* we pass our 'chunk' struct to the callback function */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
|
||||
|
||||
/* some servers don't like requests that are made without a user-agent
|
||||
field, so we provide one */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
|
||||
|
||||
/* get it! */
|
||||
curl_easy_perform(curl_handle);
|
||||
|
||||
|
53
docs/examples/https.c
Normal file
53
docs/examples/https.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://sourceforge.net/");
|
||||
|
||||
#ifdef SKIP_PEER_VERIFICATION
|
||||
/*
|
||||
* If you want to connect to a site who isn't using a certificate that is
|
||||
* signed by one of the certs in the CA bundle you have, you can skip the
|
||||
* verification of the server's certificate. This makes the connection
|
||||
* A LOT LESS SECURE.
|
||||
*
|
||||
* If you have a CA cert for the server stored someplace else than in the
|
||||
* default bundle, then the CURLOPT_CAPATH option might come handy for
|
||||
* you.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
#endif
|
||||
|
||||
#ifdef SKIP_HOSTNAME_VERFICATION
|
||||
/*
|
||||
* If the site you're connecting to uses a different host name that what
|
||||
* they have mentioned in their server certificate's commonName (or
|
||||
* subjectAltName) fields, libcurl will refuse to connect. You can skip
|
||||
* this check, but this will make the connection less secure.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
#endif
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
178
docs/examples/multi-debugcallback.c
Normal file
178
docs/examples/multi-debugcallback.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* This is a very simple example using the multi interface and the debug
|
||||
* callback.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
typedef char bool;
|
||||
#define TRUE 1
|
||||
|
||||
static
|
||||
void dump(const char *text,
|
||||
FILE *stream, unsigned char *ptr, size_t size,
|
||||
bool nohex)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
|
||||
unsigned int width=0x10;
|
||||
|
||||
if(nohex)
|
||||
/* without the hex output, we can fit more on screen */
|
||||
width = 0x40;
|
||||
|
||||
fprintf(stream, "%s, %zd bytes (0x%zx)\n", text, size, size);
|
||||
|
||||
for(i=0; i<size; i+= width) {
|
||||
|
||||
fprintf(stream, "%04zx: ", i);
|
||||
|
||||
if(!nohex) {
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++)
|
||||
if(i+c < size)
|
||||
fprintf(stream, "%02x ", ptr[i+c]);
|
||||
else
|
||||
fputs(" ", stream);
|
||||
}
|
||||
|
||||
for(c = 0; (c < width) && (i+c < size); c++) {
|
||||
/* check for 0D0A; if found, skip past and start a new line of output */
|
||||
if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
|
||||
i+=(c+2-width);
|
||||
break;
|
||||
}
|
||||
fprintf(stream, "%c",
|
||||
(ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
|
||||
/* check again for 0D0A, to avoid an extra \n if it's at width */
|
||||
if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
|
||||
i+=(c+3-width);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fputc('\n', stream); /* newline */
|
||||
}
|
||||
fflush(stream);
|
||||
}
|
||||
|
||||
static
|
||||
int my_trace(CURL *handle, curl_infotype type,
|
||||
unsigned char *data, size_t size,
|
||||
void *userp)
|
||||
{
|
||||
const char *text;
|
||||
|
||||
(void)handle; /* prevent compiler warning */
|
||||
|
||||
switch (type) {
|
||||
case CURLINFO_TEXT:
|
||||
fprintf(stderr, "== Info: %s", data);
|
||||
default: /* in case a new one is introduced to shock us */
|
||||
return 0;
|
||||
|
||||
case CURLINFO_HEADER_OUT:
|
||||
text = "=> Send header";
|
||||
break;
|
||||
case CURLINFO_DATA_OUT:
|
||||
text = "=> Send data";
|
||||
break;
|
||||
case CURLINFO_HEADER_IN:
|
||||
text = "<= Recv header";
|
||||
break;
|
||||
case CURLINFO_DATA_IN:
|
||||
text = "<= Recv data";
|
||||
break;
|
||||
}
|
||||
|
||||
dump(text, stderr, data, size, TRUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simply download a HTTP file.
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running; /* keep number of running handles */
|
||||
|
||||
http_handle = curl_easy_init();
|
||||
|
||||
/* set the options (I left out a few, you'll get the point anyway) */
|
||||
curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.haxx.se/");
|
||||
|
||||
curl_easy_setopt(http_handle, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
curl_easy_setopt(http_handle, CURLOPT_VERBOSE, TRUE);
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
curl_multi_add_handle(multi_handle, http_handle);
|
||||
|
||||
/* we start some action by calling perform right away */
|
||||
while(CURLM_CALL_MULTI_PERFORM ==
|
||||
curl_multi_perform(multi_handle, &still_running));
|
||||
|
||||
while(still_running) {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to play around with */
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
still_running = 0;
|
||||
printf("select() returns error, this is badness\n");
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
/* timeout or readable/writable sockets */
|
||||
while(CURLM_CALL_MULTI_PERFORM ==
|
||||
curl_multi_perform(multi_handle, &still_running));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
curl_easy_cleanup(http_handle);
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
|
@@ -1,13 +1,13 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<TITLE>Index to Curl documentation</TITLE>
|
||||
</HEAD>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<title>Index to Curl documentation</title>
|
||||
</head>
|
||||
|
||||
<BODY>
|
||||
<H1 ALIGN="CENTER">Index to Curl documentation</H1>
|
||||
<body>
|
||||
<h1 align="center">Index to Curl documentation</h1>
|
||||
|
||||
<H2>Programs</H2>
|
||||
<h2>Programs</h2>
|
||||
<a href="curl-config.html">curl-config</A>
|
||||
<br><a href="curl.html">curl</A>
|
||||
|
||||
@@ -17,5 +17,4 @@
|
||||
<h2>libcurl</h2>
|
||||
See the <a href="libcurl/index.html">libcurl section</a>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
</body></html>
|
||||
|
@@ -16,7 +16,7 @@ About this Document
|
||||
|
||||
This document will refer to 'the user' as the person writing the source code
|
||||
that uses libcurl. That would probably be you or someone in your position.
|
||||
What will be generally refered to as 'the program' will be the collected
|
||||
What will be generally referred to as 'the program' will be the collected
|
||||
source code that you write that is using libcurl for transfers. The program
|
||||
is outside libcurl and libcurl is outside of the program.
|
||||
|
||||
@@ -44,7 +44,7 @@ Building
|
||||
When having compiled the program, you need to link your object files to
|
||||
create a single executable. For that to succeed, you need to link with
|
||||
libcurl and possibly also with other libraries that libcurl itself depends
|
||||
on. Like OpenSSL librararies, but even some standard OS libraries may be
|
||||
on. Like OpenSSL libraries, but even some standard OS libraries may be
|
||||
needed on the command line. To figure out which flags to use, once again
|
||||
the 'curl-config' tool comes to the rescue:
|
||||
|
||||
@@ -65,6 +65,8 @@ Building
|
||||
possibly together with a few other features that can be on and off on
|
||||
different libcurls.
|
||||
|
||||
See also the "Features libcurl Provides" further down.
|
||||
|
||||
|
||||
Portable Code in a Portable World
|
||||
|
||||
@@ -86,22 +88,22 @@ Global Preparation
|
||||
curl_global_init()
|
||||
|
||||
and it takes one parameter which is a bit pattern that tells libcurl what to
|
||||
intialize. Using CURL_GLOBAL_ALL will make it initialize all known internal
|
||||
initialize. Using CURL_GLOBAL_ALL will make it initialize all known internal
|
||||
sub modules, and might be a good default option. The current two bits that
|
||||
are specified are:
|
||||
|
||||
CURL_GLOBAL_WIN32 which only does anything on Windows machines. When used on
|
||||
a Windows machine, it'll make libcurl intialize the win32 socket
|
||||
a Windows machine, it'll make libcurl initialize the win32 socket
|
||||
stuff. Without having that initialized properly, your program cannot use
|
||||
sockets properly. You should only do this once for each application, so if
|
||||
your program already does this or of another library in use does it, you
|
||||
should not tell libcurl to do this as well.
|
||||
|
||||
CURL_GLOBAL_SSL which only does anything on libcurls compiled and built
|
||||
SSL-enabled. On these systems, this will make libcurl init OpenSSL properly
|
||||
for this application. This is only needed to do once for each application so
|
||||
if your program or another library already does this, this bit should not be
|
||||
needed.
|
||||
SSL-enabled. On these systems, this will make libcurl initialize OpenSSL
|
||||
properly for this application. This is only needed to do once for each
|
||||
application so if your program or another library already does this, this
|
||||
bit should not be needed.
|
||||
|
||||
libcurl has a default protection mechanism that detects if curl_global_init()
|
||||
hasn't been called by the time curl_easy_perform() is called and if that is
|
||||
@@ -117,18 +119,26 @@ Global Preparation
|
||||
avoided. They should only be called once each.
|
||||
|
||||
|
||||
Features libcurl Provides
|
||||
|
||||
It is considered best-practice to determine libcurl features run-time rather
|
||||
than build-time (if possible of course). By calling curl_version_info() and
|
||||
checking tout he details of the returned struct, your program can figure out
|
||||
exactly what the currently running libcurl supports.
|
||||
|
||||
|
||||
Handle the Easy libcurl
|
||||
|
||||
libcurl version 7 is oriented around the so called easy interface. All
|
||||
operations in the easy interface are prefixed with 'curl_easy'.
|
||||
libcurl first introduced the so called easy interface. All operations in the
|
||||
easy interface are prefixed with 'curl_easy'.
|
||||
|
||||
Future libcurls will also offer the multi interface. More about that
|
||||
interface, what it is targeted for and how to use it is still only debated on
|
||||
the libcurl mailing list and developer web pages. Join up to discuss and
|
||||
figure out!
|
||||
Recent libcurl versions also offer the multi interface. More about that
|
||||
interface, what it is targeted for and how to use it is detailed in a
|
||||
separate chapter further down. You still need to understand the easy
|
||||
interface first, so please continue reading for better understanding.
|
||||
|
||||
To use the easy interface, you must first create yourself an easy handle. You
|
||||
need one handle for each easy session you want to perform. Basicly, you
|
||||
need one handle for each easy session you want to perform. Basically, you
|
||||
should use one handle for every thread you plan to use for transferring. You
|
||||
must never share the same handle in multiple threads.
|
||||
|
||||
@@ -145,7 +155,7 @@ Handle the Easy libcurl
|
||||
set in the handle until set again to something different. Alas, multiple
|
||||
requests using the same handle will use the same options.
|
||||
|
||||
Many of the informationals you set in libcurl are "strings", pointers to data
|
||||
Many of the options you set in libcurl are "strings", pointers to data
|
||||
terminated with a zero byte. Keep in mind that when you set strings with
|
||||
curl_easy_setopt(), libcurl will not copy the data. It will merely point to
|
||||
the data. You MUST make sure that the data remains available for libcurl to
|
||||
@@ -157,7 +167,7 @@ Handle the Easy libcurl
|
||||
|
||||
curl_easy_setopt(easyhandle, CURLOPT_URL, "http://curl.haxx.se/");
|
||||
|
||||
Let's assume for a while that you want to receive data as the URL indentifies
|
||||
Let's assume for a while that you want to receive data as the URL identifies
|
||||
a remote resource you want to get here. Since you write a sort of application
|
||||
that needs this transfer, I assume that you would like to get the data passed
|
||||
to you directly instead of simply getting it passed to stdout. So, you write
|
||||
@@ -219,26 +229,21 @@ Handle the Easy libcurl
|
||||
Multi-threading issues
|
||||
|
||||
libcurl is completely thread safe, except for two issues: signals and alarm
|
||||
handlers. Signals are needed for a SIGPIPE handler, and the alarm() syscall
|
||||
is used to catch timeouts (mostly during DNS lookup).
|
||||
handlers. Signals are needed for a SIGPIPE handler, and the alarm() Bacall
|
||||
is used to catch timeouts (mostly during ENS lookup).
|
||||
|
||||
If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are
|
||||
then of course using OpenSSL multi-threaded and it has itself a few
|
||||
requirements on this. Basicly, you need to provide one or two functions to
|
||||
requirements on this. Basilio, you need to provide one or two functions to
|
||||
allow it to function properly. For all details, see this:
|
||||
|
||||
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
|
||||
|
||||
When using multiple threads you should first ignore SIGPIPE in your main
|
||||
thread and set the CURLOPT_NOSIGNAL option to TRUE for all handles.
|
||||
|
||||
Everything will work fine except that timeouts are not honored during the DNS
|
||||
lookup - which you can work around by building libcurl with ares-support.
|
||||
Ares is a library that provides asynchronous name resolves. Unfortunately,
|
||||
ares does not yet support IPv6.
|
||||
|
||||
For SIGPIPE info see the UNIX Socket FAQ at
|
||||
http://www.unixguide.net/network/socketfaq/2.22.shtml
|
||||
When using multiple threads you should set the CURLOPT_NOSIGNAL option to
|
||||
TRUE for all handles. Everything will work fine except that timeouts are not
|
||||
honored during the DNS lookup - which you can work around by building libcurl
|
||||
with c-ares support. c-ares is a library that provides asynchronous name
|
||||
resolves. Unfortunately, c-ares does not yet support IPv6.
|
||||
|
||||
Also, note that CURLOPT_DNS_USE_GLOBAL_CACHE is not thread-safe.
|
||||
|
||||
@@ -251,10 +256,10 @@ When It Doesn't Work
|
||||
|
||||
There's one golden rule when these things occur: set the CURLOPT_VERBOSE
|
||||
option to TRUE. It'll cause the library to spew out the entire protocol
|
||||
details it sends, some internal info and some received protcol data as well
|
||||
details it sends, some internal info and some received protocol data as well
|
||||
(especially when using FTP). If you're using HTTP, adding the headers in the
|
||||
received output to study is also a clever way to get a better understanding
|
||||
wht the server behaves the way it does. Include headers in the normal body
|
||||
why the server behaves the way it does. Include headers in the normal body
|
||||
output with CURLOPT_HEADER set TRUE.
|
||||
|
||||
Of course there are bugs left. We need to get to know about them to be able
|
||||
@@ -342,7 +347,7 @@ Passwords
|
||||
curl_easy_setopt(easyhandle, CURLOPT_USERPWD, "myname:thesecret");
|
||||
|
||||
Another case where name and password might be needed at times, is for those
|
||||
users who need to athenticate themselves to a proxy they use. libcurl offers
|
||||
users who need to authenticate themselves to a proxy they use. libcurl offers
|
||||
another option for this, the CURLOPT_PROXYUSERPWD. It is used quite similar
|
||||
to the CURLOPT_USERPWD option like this:
|
||||
|
||||
@@ -382,7 +387,7 @@ HTTP Authentication
|
||||
many different ways a client can provide those credentials to the server and
|
||||
you can control what way libcurl will (attempt to) use. The default HTTP
|
||||
authentication method is called 'Basic', which is sending the name and
|
||||
password in clear-text in the HTTP request, base64-encoded. This is unsecure.
|
||||
password in clear-text in the HTTP request, base64-encoded. This is insecure.
|
||||
|
||||
At the time of this writing libcurl can be built to use: Basic, Digest, NTLM,
|
||||
Negotiate, GSS-Negotiate and SPNEGO. You can tell libcurl which one to use
|
||||
@@ -427,7 +432,7 @@ HTTP POSTing
|
||||
curl_easy_perform(easyhandle); /* post away! */
|
||||
|
||||
Simple enough, huh? Since you set the POST options with the
|
||||
CURLOPT_POSTFIELDS, this automaticly switches the handle to use POST in the
|
||||
CURLOPT_POSTFIELDS, this automatically switches the handle to use POST in the
|
||||
upcoming request.
|
||||
|
||||
Ok, so what if you want to post binary data that also requires you to set the
|
||||
@@ -454,12 +459,12 @@ HTTP POSTing
|
||||
curl_slist_free_all(headers); /* free the header list */
|
||||
|
||||
While the simple examples above cover the majority of all cases where HTTP
|
||||
POST operations are required, they don't do multipart formposts. Multipart
|
||||
POST operations are required, they don't do multi-part formposts. Multi-part
|
||||
formposts were introduced as a better way to post (possibly large) binary
|
||||
data and was first documented in the RFC1867. They're called multipart
|
||||
data and was first documented in the RFC1867. They're called multi-part
|
||||
because they're built by a chain of parts, each being a single unit. Each
|
||||
part has its own name and contents. You can in fact create and post a
|
||||
multipart formpost with the regular libcurl POST support described above, but
|
||||
multi-part formpost with the regular libcurl POST support described above, but
|
||||
that would require that you build a formpost yourself and provide to
|
||||
libcurl. To make that easier, libcurl provides curl_formadd(). Using this
|
||||
function, you add parts to the form. When you're done adding parts, you post
|
||||
@@ -553,7 +558,7 @@ Showing Progress
|
||||
|
||||
libcurl with C++
|
||||
|
||||
There's basicly only one thing to keep in mind when using C++ instead of C
|
||||
There's basically only one thing to keep in mind when using C++ instead of C
|
||||
when interfacing libcurl:
|
||||
|
||||
"The Callbacks Must Be Plain C"
|
||||
@@ -580,8 +585,8 @@ Proxies
|
||||
as a substitute for another".
|
||||
|
||||
Proxies are exceedingly common these days. Companies often only offer
|
||||
internet access to employees through their HTTP proxies. Network clients or
|
||||
user-agents ask the proxy for docuements, the proxy does the actual request
|
||||
Internet access to employees through their HTTP proxies. Network clients or
|
||||
user-agents ask the proxy for documents, the proxy does the actual request
|
||||
and then it returns them.
|
||||
|
||||
libcurl has full support for HTTP proxies, so when a given URL is wanted,
|
||||
@@ -591,7 +596,7 @@ Proxies
|
||||
The fact that the proxy is a HTTP proxy puts certain restrictions on what can
|
||||
actually happen. A requested URL that might not be a HTTP URL will be still
|
||||
be passed to the HTTP proxy to deliver back to libcurl. This happens
|
||||
transparantly, and an application may not need to know. I say "may", because
|
||||
transparently, and an application may not need to know. I say "may", because
|
||||
at times it is very important to understand that all operations over a HTTP
|
||||
proxy is using the HTTP protocol. For example, you can't invoke your own
|
||||
custom FTP commands or even proper FTP directory listings.
|
||||
@@ -612,9 +617,9 @@ Proxies
|
||||
|
||||
Environment Variables
|
||||
|
||||
libcurl automaticly checks and uses a set of environment variables to know
|
||||
what proxies to use for certain protocols. The names of the variables are
|
||||
following an ancient de facto standard and are built up as
|
||||
libcurl automatically checks and uses a set of environment variables to
|
||||
know what proxies to use for certain protocols. The names of the variables
|
||||
are following an ancient de facto standard and are built up as
|
||||
"[protocol]_proxy" (note the lower casing). Which makes the variable
|
||||
'http_proxy' checked for a name of a proxy to use when the input URL is
|
||||
HTTP. Following the same rule, the variable named 'ftp_proxy' is checked
|
||||
@@ -622,11 +627,12 @@ Proxies
|
||||
names of the variables simply allows different HTTP proxies to be used.
|
||||
|
||||
The proxy environment variable contents should be in the format
|
||||
"[protocol://]machine[:port]". Where the protocol:// part is simply
|
||||
ignored if present (so http://proxy and bluerk://proxy will do the same)
|
||||
and the optional port number specifies on which port the proxy operates on
|
||||
the host. If not specified, the internal default port number will be used
|
||||
and that is most likely *not* the one you would like it to be.
|
||||
"[protocol://][user:password]machine[:port]". Where the protocol:// part
|
||||
is simply ignored if present (so http://proxy and bluerk://proxy will do
|
||||
the same) and the optional port number specifies on which port the proxy
|
||||
operates on the host. If not specified, the internal default port number
|
||||
will be used and that is most likely *not* the one you would like it to
|
||||
be.
|
||||
|
||||
There are two special environment variables. 'all_proxy' is what sets
|
||||
proxy for any URL in case the protocol specific variable wasn't set, and
|
||||
@@ -637,7 +643,7 @@ Proxies
|
||||
SSL and Proxies
|
||||
|
||||
SSL is for secure point-to-point connections. This involves strong
|
||||
encryption and similar things, which effectivly makes it impossible for a
|
||||
encryption and similar things, which effectively makes it impossible for a
|
||||
proxy to operate as a "man in between" which the proxy's task is, as
|
||||
previously discussed. Instead, the only way to have SSL work over a HTTP
|
||||
proxy is to ask the proxy to tunnel trough everything without being able
|
||||
@@ -668,7 +674,7 @@ Proxies
|
||||
operations over a HTTP proxy. You can in fact use things such as FTP
|
||||
upload or FTP custom commands this way.
|
||||
|
||||
Again, this is often prevented by the adminstrators of proxies and is
|
||||
Again, this is often prevented by the administrators of proxies and is
|
||||
rarely allowed.
|
||||
|
||||
Tell libcurl to use proxy tunneling like this:
|
||||
@@ -682,13 +688,13 @@ Proxies
|
||||
|
||||
Proxy Auto-Config
|
||||
|
||||
Netscape first came up with this. It is basicly a web page (usually using
|
||||
a .pac extension) with a javascript that when executed by the browser with
|
||||
the requested URL as input, returns information to the browser on how to
|
||||
connect to the URL. The returned information might be "DIRECT" (which
|
||||
means no proxy should be used), "PROXY host:port" (to tell the browser
|
||||
where the proxy for this particular URL is) or "SOCKS host:port" (to
|
||||
direct the brower to a SOCKS proxy).
|
||||
Netscape first came up with this. It is basically a web page (usually
|
||||
using a .pac extension) with a javascript that when executed by the
|
||||
browser with the requested URL as input, returns information to the
|
||||
browser on how to connect to the URL. The returned information might be
|
||||
"DIRECT" (which means no proxy should be used), "PROXY host:port" (to tell
|
||||
the browser where the proxy for this particular URL is) or "SOCKS
|
||||
host:port" (to direct the browser to a SOCKS proxy).
|
||||
|
||||
libcurl has no means to interpret or evaluate javascript and thus it
|
||||
doesn't support this. If you get yourself in a position where you face
|
||||
@@ -706,7 +712,7 @@ Proxies
|
||||
- Ask your admins to stop this, for a static proxy setup or similar.
|
||||
|
||||
|
||||
Persistancy Is The Way to Happiness
|
||||
Persistence Is The Way to Happiness
|
||||
|
||||
Re-cycling the same easy handle several times when doing multiple requests is
|
||||
the way to go.
|
||||
@@ -717,11 +723,11 @@ Persistancy Is The Way to Happiness
|
||||
reduces network impact a lot.
|
||||
|
||||
Even if the connection is dropped, all connections involving SSL to the same
|
||||
host again, will benefit from libcurl's session ID cache that drasticly
|
||||
host again, will benefit from libcurl's session ID cache that drastically
|
||||
reduces re-connection time.
|
||||
|
||||
FTP connections that are kept alive saves a lot of time, as the command-
|
||||
response roundtrips are skipped, and also you don't risk getting blocked
|
||||
response round-trips are skipped, and also you don't risk getting blocked
|
||||
without permission to login again like on many FTP servers only allowing N
|
||||
persons to be logged in at the same time.
|
||||
|
||||
@@ -747,13 +753,13 @@ Persistancy Is The Way to Happiness
|
||||
used for the longest time. This is the default behavior.
|
||||
|
||||
CURLCLOSEPOLICY_OLDEST closes the oldest connection, the one that was
|
||||
createst the longest time ago.
|
||||
created the longest time ago.
|
||||
|
||||
There are, or at least were, plans to support a close policy that would call
|
||||
a user-specified callback to let the user be able to decide which connection
|
||||
to dump when this is necessary and therefor is the CURLOPT_CLOSEFUNCTION an
|
||||
existing option still today. Nothing ever uses this though and this will not
|
||||
be used within the forseeable future either.
|
||||
be used within the foreseeable future either.
|
||||
|
||||
To force your upcoming request to not use an already existing connection (it
|
||||
will even close one first if there happens to be one alive to the same host
|
||||
@@ -765,8 +771,8 @@ Persistancy Is The Way to Happiness
|
||||
|
||||
HTTP Headers Used by libcurl
|
||||
|
||||
When you use libcurl to do HTTP requeests, it'll pass along a series of
|
||||
headers automaticly. It might be good for you to know and understand these
|
||||
When you use libcurl to do HTTP requests, it'll pass along a series of
|
||||
headers automatically. It might be good for you to know and understand these
|
||||
ones.
|
||||
|
||||
Host
|
||||
@@ -777,7 +783,7 @@ HTTP Headers Used by libcurl
|
||||
|
||||
Pragma
|
||||
|
||||
"no-cache". Tells a possible proxy to not grap a copy from the cache but
|
||||
"no-cache". Tells a possible proxy to not grab a copy from the cache but
|
||||
to fetch a fresh one.
|
||||
|
||||
Accept:
|
||||
@@ -851,7 +857,7 @@ Customizing Operations
|
||||
|
||||
headers = curl_slist_append(headers, "Accept:");
|
||||
|
||||
Both replacing and cancelling internal headers should be done with careful
|
||||
Both replacing and canceling internal headers should be done with careful
|
||||
consideration and you should be aware that you may violate the HTTP
|
||||
protocol when doing so.
|
||||
|
||||
@@ -861,7 +867,7 @@ Customizing Operations
|
||||
chunked" when doing a non-GET HTTP operation, libcurl will switch over to
|
||||
"chunked" upload, even though the size of the data to upload might be
|
||||
known. By default, libcurl usually switches over to chunked upload
|
||||
automaticly if the upload data size is unknown.
|
||||
automatically if the upload data size is unknown.
|
||||
|
||||
HTTP Version
|
||||
|
||||
@@ -881,10 +887,10 @@ Customizing Operations
|
||||
you want to make for example your FTP transfers to behave differently.
|
||||
|
||||
Sending custom commands to a FTP server means that you need to send the
|
||||
comands exactly as the FTP server expects them (RFC959 is a good guide
|
||||
commands exactly as the FTP server expects them (RFC959 is a good guide
|
||||
here), and you can only use commands that work on the control-connection
|
||||
alone. All kinds of commands that requires data interchange and thus needs
|
||||
a data-connection must be left to libcurl's own judgement. Also be aware
|
||||
a data-connection must be left to libcurl's own judgment. Also be aware
|
||||
that libcurl will do its very best to change directory to the target
|
||||
directory before doing any transfer, so if you change directory (with CWD
|
||||
or similar) you might confuse libcurl and then it might not attempt to
|
||||
@@ -948,16 +954,16 @@ Cookies Without Chocolate Chips
|
||||
|
||||
curl_easy_setopt(easyhandle, CURLOPT_COOKIE, "name1=var1; name2=var2;");
|
||||
|
||||
In many cases, that is not enough. You might want to dynamicly save whatever
|
||||
cookies the remote server passes to you, and make sure those cookies are then
|
||||
use accordingly on later requests.
|
||||
In many cases, that is not enough. You might want to dynamically save
|
||||
whatever cookies the remote server passes to you, and make sure those cookies
|
||||
are then use accordingly on later requests.
|
||||
|
||||
One way to do this, is to save all headers you receive in a plain file and
|
||||
when you make a request, you tell libcurl to read the previous headers to
|
||||
figure out which cookies to use. Set header file to read cookies from with
|
||||
CURLOPT_COOKIEFILE.
|
||||
|
||||
The CURLOPT_COOKIEFILE option also automaticly enables the cookie parser in
|
||||
The CURLOPT_COOKIEFILE option also automatically enables the cookie parser in
|
||||
libcurl. Until the cookie parser is enabled, libcurl will not parse or
|
||||
understand incoming cookies and they will just be ignored. However, when the
|
||||
parser is enabled the cookies will be understood and the cookies will be kept
|
||||
@@ -970,7 +976,7 @@ Cookies Without Chocolate Chips
|
||||
If you rather use existing cookies that you've previously received with your
|
||||
Netscape or Mozilla browsers, you can make libcurl use that cookie file as
|
||||
input. The CURLOPT_COOKIEFILE is used for that too, as libcurl will
|
||||
automaticly find out what kind of file it is and act accordingly.
|
||||
automatically find out what kind of file it is and act accordingly.
|
||||
|
||||
The perhaps most advanced cookie operation libcurl offers, is saving the
|
||||
entire internal cookie state back into a Netscape/Mozilla formatted cookie
|
||||
@@ -990,7 +996,7 @@ FTP Peculiarities We Need
|
||||
|
||||
libcurl can either connect to the server a second time or tell the server to
|
||||
connect back to it. The first option is the default and it is also what works
|
||||
best for all the people behind firewalls, NATs or IP-masquarading setups.
|
||||
best for all the people behind firewalls, NATs or IP-masquerading setups.
|
||||
libcurl then tells the server to open up a new port and wait for a second
|
||||
connection. This is by default attempted with EPSV first, and if that doesn't
|
||||
work it tries PASV instead. (EPSV is an extension to the original FTP spec
|
||||
@@ -1063,7 +1069,7 @@ Security Considerations
|
||||
.netrc
|
||||
|
||||
.netrc is a pretty handy file/feature that allows you to login quickly and
|
||||
automaticly to frequently visited sites. The file contains passwords in
|
||||
automatically to frequently visited sites. The file contains passwords in
|
||||
clear text and is a real security risk. In some cases, your .netrc is also
|
||||
stored in a home directory that is NFS mounted or used on another network
|
||||
based file system, so the clear text password will fly through your
|
||||
@@ -1077,8 +1083,8 @@ Security Considerations
|
||||
Many of the protocols libcurl supports send name and password unencrypted
|
||||
as clear text (HTTP Basic authentication, FTP, TELNET etc). It is very
|
||||
easy for anyone on your network or a network nearby yours, to just fire up
|
||||
a network analyzer tool and evesdrop on your passwords. Don't let the fact
|
||||
that HTTP uses base64 encoded passwords fool you. They may not look
|
||||
a network analyzer tool and eavesdrop on your passwords. Don't let the
|
||||
fact that HTTP uses base64 encoded passwords fool you. They may not look
|
||||
readable at a first glance, but they very easily "deciphered" by anyone
|
||||
within seconds.
|
||||
|
||||
@@ -1090,21 +1096,17 @@ Security Considerations
|
||||
Showing What You Do
|
||||
|
||||
On a related issue, be aware that even in situations like when you have
|
||||
problems with libcurl and ask somone for help, everything you reveal in
|
||||
problems with libcurl and ask someone for help, everything you reveal in
|
||||
order to get best possible help might also impose certain security related
|
||||
risks. Host names, user names, paths, operating system specifics etc (not
|
||||
to mention passwords of course) may in fact be used by intruders to gain
|
||||
additional information of a potential target.
|
||||
|
||||
To avoid this problem, you must of course use your common sense. Often,
|
||||
you can just edit out the senstive data or just rearch/replace your true
|
||||
you can just edit out the sensitive data or just search/replace your true
|
||||
information with faked data.
|
||||
|
||||
|
||||
SSL, Certificates and Other Tricks
|
||||
|
||||
[ seeding, passwords, keys, certificates, ENGINE, ca certs ]
|
||||
|
||||
Multiple Transfers Using the multi Interface
|
||||
|
||||
The easy interface as described in detail in this document is a synchronous
|
||||
@@ -1115,18 +1117,69 @@ Multiple Transfers Using the multi Interface
|
||||
multiple files in both directions at the same time, without forcing you to
|
||||
use multiple threads.
|
||||
|
||||
[fill in lots of more multi stuff here]
|
||||
To use this interface, you are better off if you first understand the basics
|
||||
of how to use the easy interface. The multi interface is simply a way to make
|
||||
multiple transfers at the same time, by adding up multiple easy handles in to
|
||||
a "multi stack".
|
||||
|
||||
Future
|
||||
You create the easy handles you want and you set all the options just like
|
||||
you have been told above, and then you create a multi handle with
|
||||
curl_multi_init() and add all those easy handles to that multi handle with
|
||||
curl_multi_add_handle().
|
||||
|
||||
[ sharing between handles, mutexes, pipelining ]
|
||||
When you've added the handles you have for the moment (you can still add new
|
||||
ones at any time), you start the transfers by call curl_multi_perform().
|
||||
|
||||
curl_multi_perform() is asynchronous. It will only execute as little as
|
||||
possible and then return back control to your program. It is designed to
|
||||
never block. If it returns CURLM_CALL_MULTI_PERFORM you better call it again
|
||||
soon, as that is a signal that it still has local data to send or remote data
|
||||
to receive.
|
||||
|
||||
The best usage of this interface is when you do a select() on all possible
|
||||
file descriptors or sockets to know when to call libcurl again. This also
|
||||
makes it easy for you to wait and respond to actions on your own
|
||||
application's sockets/handles. You figure out what to select() for by using
|
||||
curl_multi_fdset(), that fills in a set of fd_set variables for you with the
|
||||
particular file descriptors libcurl uses for the moment.
|
||||
|
||||
When you then call select(), it'll return when one of the file handles signal
|
||||
action and you then call curl_multi_perform() to allow libcurl to do what it
|
||||
wants to do. Take note that libcurl does also feature some time-out code so
|
||||
we advice you to never use very long timeouts on select() before you call
|
||||
curl_multi_perform(), which thus should be called unconditionally every now
|
||||
and then even if none of its file descriptors have signaled ready. Another
|
||||
precaution you should use: always call curl_multi_fdset() immediately before
|
||||
the select() call since the current set of file descriptors may change when
|
||||
calling a curl function.
|
||||
|
||||
If you want to stop the transfer of one of the easy handles in the stack, you
|
||||
can use curl_multi_remove_handle() to remove individual easy
|
||||
handles. Remember that easy handles should be curl_easy_cleanup()ed.
|
||||
|
||||
When a transfer within the multi stack has finished, the counter of running
|
||||
transfers (as filled in by curl_multi_perform()) will decrease. When the
|
||||
number reaches zero, all transfers are done.
|
||||
|
||||
curl_multi_info_read() can be used to get information about completed
|
||||
transfers. It then returns the CURLcode for each easy transfer, to allow you
|
||||
to figure out success on each individual transfer.
|
||||
|
||||
|
||||
SSL, Certificates and Other Tricks
|
||||
|
||||
[ seeding, passwords, keys, certificates, ENGINE, ca certs ]
|
||||
|
||||
|
||||
Sharing Data Between Easy Handles
|
||||
|
||||
[ fill in ]
|
||||
|
||||
-----
|
||||
Footnotes:
|
||||
|
||||
[1] = libcurl 7.10.3 and later have the ability to switch over to chunked
|
||||
Tranfer-Encoding in cases were HTTP uploads are done with data of an
|
||||
Transfer-Encoding in cases were HTTP uploads are done with data of an
|
||||
unknown size.
|
||||
|
||||
[2] = This happens on Windows machines when libcurl is built and used as a
|
||||
|
@@ -4,119 +4,50 @@
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
|
||||
man_MANS = \
|
||||
curl_easy_cleanup.3 \
|
||||
curl_easy_getinfo.3 \
|
||||
curl_easy_init.3 \
|
||||
curl_easy_perform.3 \
|
||||
curl_easy_setopt.3 \
|
||||
curl_easy_duphandle.3 \
|
||||
curl_formparse.3 \
|
||||
curl_formadd.3 \
|
||||
curl_formfree.3 \
|
||||
curl_getdate.3 \
|
||||
curl_getenv.3 \
|
||||
curl_slist_append.3 \
|
||||
curl_slist_free_all.3 \
|
||||
curl_version.3 \
|
||||
curl_version_info.3 \
|
||||
curl_escape.3 \
|
||||
curl_unescape.3 \
|
||||
curl_free.3 \
|
||||
curl_strequal.3 \
|
||||
curl_strnequal.3 \
|
||||
curl_mprintf.3 \
|
||||
curl_global_init.3 \
|
||||
curl_global_cleanup.3 \
|
||||
curl_multi_add_handle.3 \
|
||||
curl_multi_cleanup.3 \
|
||||
curl_multi_fdset.3 \
|
||||
curl_multi_info_read.3 \
|
||||
curl_multi_init.3 \
|
||||
curl_multi_perform.3 \
|
||||
curl_multi_remove_handle.3 \
|
||||
curl_share_cleanup.3 curl_share_init.3 curl_share_setopt.3 \
|
||||
libcurl.3 \
|
||||
libcurl-easy.3 \
|
||||
libcurl-multi.3 \
|
||||
libcurl-share.3 \
|
||||
libcurl-errors.3
|
||||
man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \
|
||||
curl_easy_perform.3 curl_easy_setopt.3 curl_easy_duphandle.3 \
|
||||
curl_formadd.3 curl_formfree.3 curl_getdate.3 curl_getenv.3 \
|
||||
curl_slist_append.3 curl_slist_free_all.3 curl_version.3 \
|
||||
curl_version_info.3 curl_escape.3 curl_unescape.3 curl_free.3 \
|
||||
curl_strequal.3 curl_mprintf.3 curl_global_init.3 \
|
||||
curl_global_cleanup.3 curl_multi_add_handle.3 curl_multi_cleanup.3 \
|
||||
curl_multi_fdset.3 curl_multi_info_read.3 curl_multi_init.3 \
|
||||
curl_multi_perform.3 curl_multi_remove_handle.3 curl_share_cleanup.3 \
|
||||
curl_share_init.3 curl_share_setopt.3 libcurl.3 libcurl-easy.3 \
|
||||
libcurl-multi.3 libcurl-share.3 libcurl-errors.3 curl_easy_strerror.3 \
|
||||
curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3 \
|
||||
libcurl-tutorial.3
|
||||
|
||||
HTMLPAGES = \
|
||||
curl_easy_cleanup.html \
|
||||
curl_easy_getinfo.html \
|
||||
curl_easy_init.html \
|
||||
curl_easy_perform.html \
|
||||
curl_easy_setopt.html \
|
||||
curl_easy_duphandle.html \
|
||||
curl_formadd.html \
|
||||
curl_formparse.html \
|
||||
curl_formfree.html \
|
||||
curl_getdate.html \
|
||||
curl_getenv.html \
|
||||
curl_slist_append.html \
|
||||
curl_slist_free_all.html \
|
||||
curl_version.html \
|
||||
curl_version_info.html \
|
||||
curl_escape.html \
|
||||
curl_unescape.html \
|
||||
curl_free.html \
|
||||
curl_strequal.html \
|
||||
curl_strnequal.html \
|
||||
curl_mprintf.html \
|
||||
curl_global_init.html \
|
||||
curl_global_cleanup.html \
|
||||
curl_multi_add_handle.html \
|
||||
curl_multi_cleanup.html \
|
||||
curl_multi_fdset.html \
|
||||
curl_multi_info_read.html \
|
||||
curl_multi_init.html \
|
||||
curl_multi_perform.html \
|
||||
curl_multi_remove_handle.html \
|
||||
curl_share_cleanup.html curl_share_init.html curl_share_setopt.html \
|
||||
libcurl.html \
|
||||
libcurl-multi.html \
|
||||
libcurl-easy.html \
|
||||
libcurl-share.html \
|
||||
libcurl-errors.html
|
||||
HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
||||
curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \
|
||||
curl_easy_duphandle.html curl_formadd.html curl_formfree.html \
|
||||
curl_getdate.html curl_getenv.html curl_slist_append.html \
|
||||
curl_slist_free_all.html curl_version.html curl_version_info.html \
|
||||
curl_escape.html curl_unescape.html curl_free.html curl_strequal.html \
|
||||
curl_mprintf.html curl_global_init.html curl_global_cleanup.html \
|
||||
curl_multi_add_handle.html curl_multi_cleanup.html \
|
||||
curl_multi_fdset.html curl_multi_info_read.html curl_multi_init.html \
|
||||
curl_multi_perform.html curl_multi_remove_handle.html \
|
||||
curl_share_cleanup.html curl_share_init.html curl_share_setopt.html \
|
||||
libcurl.html libcurl-multi.html libcurl-easy.html libcurl-share.html \
|
||||
libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html \
|
||||
curl_share_strerror.html curl_global_init_mem.html \
|
||||
libcurl-tutorial.html
|
||||
|
||||
PDFPAGES = \
|
||||
curl_easy_cleanup.pdf \
|
||||
curl_easy_getinfo.pdf \
|
||||
curl_easy_init.pdf \
|
||||
curl_easy_perform.pdf \
|
||||
curl_easy_setopt.pdf \
|
||||
curl_easy_duphandle.pdf \
|
||||
curl_formadd.pdf \
|
||||
curl_formparse.pdf \
|
||||
curl_formfree.pdf \
|
||||
curl_getdate.pdf \
|
||||
curl_getenv.pdf \
|
||||
curl_slist_append.pdf \
|
||||
curl_slist_free_all.pdf \
|
||||
curl_version.pdf \
|
||||
curl_version_info.pdf \
|
||||
curl_escape.pdf \
|
||||
curl_unescape.pdf \
|
||||
curl_free.pdf \
|
||||
curl_strequal.pdf \
|
||||
curl_strnequal.pdf \
|
||||
curl_mprintf.pdf \
|
||||
curl_global_init.pdf \
|
||||
curl_global_cleanup.pdf \
|
||||
curl_multi_add_handle.pdf \
|
||||
curl_multi_cleanup.pdf \
|
||||
curl_multi_fdset.pdf \
|
||||
curl_multi_info_read.pdf \
|
||||
curl_multi_init.pdf \
|
||||
curl_multi_perform.pdf \
|
||||
curl_multi_remove_handle.pdf \
|
||||
curl_share_cleanup.pdf curl_share_init.pdf curl_share_setopt.pdf \
|
||||
libcurl.pdf \
|
||||
libcurl-multi.pdf \
|
||||
libcurl-easy.pdf \
|
||||
libcurl-share.pdf \
|
||||
libcurl-errors.pdf
|
||||
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
|
||||
curl_easy_init.pdf curl_easy_perform.pdf curl_easy_setopt.pdf \
|
||||
curl_easy_duphandle.pdf curl_formadd.pdf curl_formfree.pdf \
|
||||
curl_getdate.pdf curl_getenv.pdf curl_slist_append.pdf \
|
||||
curl_slist_free_all.pdf curl_version.pdf curl_version_info.pdf \
|
||||
curl_escape.pdf curl_unescape.pdf curl_free.pdf curl_strequal.pdf \
|
||||
curl_mprintf.pdf curl_global_init.pdf curl_global_cleanup.pdf \
|
||||
curl_multi_add_handle.pdf curl_multi_cleanup.pdf curl_multi_fdset.pdf \
|
||||
curl_multi_info_read.pdf curl_multi_init.pdf curl_multi_perform.pdf \
|
||||
curl_multi_remove_handle.pdf curl_share_cleanup.pdf \
|
||||
curl_share_init.pdf curl_share_setopt.pdf libcurl.pdf \
|
||||
libcurl-multi.pdf libcurl-easy.pdf libcurl-share.pdf \
|
||||
libcurl-errors.pdf curl_easy_strerror.pdf curl_multi_strerror.pdf \
|
||||
curl_share_strerror.pdf curl_global_init_mem.pdf libcurl-tutorial.pdf
|
||||
|
||||
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
||||
|
||||
|
@@ -119,6 +119,15 @@ filled with at most \fIsize\fP multiplied with \fInmemb\fP number of
|
||||
bytes. Your function must return the actual number of bytes that you stored in
|
||||
that memory area. Returning 0 will signal end-of-file to the library and cause
|
||||
it to stop the current transfer.
|
||||
|
||||
If you stop the current transfer by returning 0 "pre-maturely" (i.e before the
|
||||
server expected it, like when you've told you will upload N bytes and you
|
||||
upload less than N bytes), you may experience that the server "hangs" waiting
|
||||
for the rest of the data that won't come.
|
||||
|
||||
In libcurl 7.12.1 and later, the read callback may return
|
||||
\fICURL_READFUNC_ABORT\fP to stop the current operation at once, with a
|
||||
\fICURLE_ABORTED_BY_CALLBACK\fP error code from the transfer.
|
||||
.IP CURLOPT_READDATA
|
||||
Data pointer to pass to the file read function. Note that if you specify the
|
||||
\fICURLOPT_READFUNCTION\fP, this is the pointer you'll get as input. If you
|
||||
@@ -310,7 +319,7 @@ amortizes the overhead of the send. However, in some cases (most
|
||||
notably telnet or rlogin) small segments may need to be sent
|
||||
without delay. This is less efficient than sending larger amounts of
|
||||
data at a time, and can contribute to congestion on the network if
|
||||
overdone.
|
||||
overdone.
|
||||
.SH NAMES and PASSWORDS OPTIONS (Authentication)
|
||||
.IP CURLOPT_NETRC
|
||||
This parameter controls the preference of libcurl between using user names and
|
||||
@@ -340,7 +349,7 @@ This value tells the library that use of the file is required,
|
||||
to ignore the information in the URL,
|
||||
and to search the file with the host only.
|
||||
.RE
|
||||
Only machine name, user name and password are taken into account
|
||||
Only machine name, user name and password are taken into account
|
||||
(init macros and similar things aren't supported).
|
||||
|
||||
\fBNote:\fP libcurl does not verify that the file has the correct properties
|
||||
@@ -456,6 +465,9 @@ redirections have been followed, the next redirect will cause an error
|
||||
.IP CURLOPT_PUT
|
||||
A non-zero parameter tells the library to use HTTP PUT to transfer data. The
|
||||
data should be set with \fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP.
|
||||
|
||||
This option is deprecated and starting with version 7.12.1 you should instead
|
||||
use \fICURLOPT_UPLOAD\fP.
|
||||
.IP CURLOPT_POST
|
||||
A non-zero parameter tells the library to do a regular HTTP post. This is a
|
||||
normal application/x-www-form-urlencoded kind, which is the most commonly used
|
||||
@@ -522,7 +534,9 @@ The first line in a request (usually containing a GET or POST) is not a header
|
||||
and cannot be replaced using this option. Only the lines following the
|
||||
request-line are headers.
|
||||
|
||||
\fBNOTE:\fPThe most commonly replaced headers have "shortcuts" in the options
|
||||
Pass a NULL to this to reset back to no custom headers.
|
||||
|
||||
\fBNOTE:\fP The most commonly replaced headers have "shortcuts" in the options
|
||||
\fICURLOPT_COOKIE\fP, \fICURLOPT_USERAGENT\fP and \fICURLOPT_REFERER\fP.
|
||||
.IP CURLOPT_HTTP200ALIASES
|
||||
Pass a pointer to a linked list of aliases to be treated as valid HTTP 200
|
||||
@@ -535,7 +549,7 @@ The linked list should be a fully valid list of struct curl_slist structs, and
|
||||
be properly filled in. Use \fIcurl_slist_append(3)\fP to create the list and
|
||||
\fIcurl_slist_free_all(3)\fP to clean up an entire list.
|
||||
|
||||
\fBNOTE:\fPThe alias itself is not parsed for any version strings. So if your
|
||||
\fBNOTE:\fP The alias itself is not parsed for any version strings. So if your
|
||||
alias is "MYHTTP/9.9", Libcurl will not treat the server as responding with
|
||||
HTTP version 9.9. Instead Libcurl will use the value set by option
|
||||
\fICURLOPT_HTTP_VERSION\fP.
|
||||
@@ -692,10 +706,11 @@ want. It should be in the format "X-Y", where X or Y may be left out. HTTP
|
||||
transfers also support several intervals, separated with commas as in
|
||||
\fI"X-Y,N-M"\fP. Using this kind of multiple intervals will cause the HTTP
|
||||
server to send the response document in pieces (using standard MIME separation
|
||||
techniques).
|
||||
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.
|
||||
want the transfer to start from. Set this option to 0 to make the transfer
|
||||
start from the beginning (effectively disabling resume).
|
||||
.IP CURLOPT_RESUME_FROM_LARGE
|
||||
Pass an 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)
|
||||
@@ -706,11 +721,11 @@ when doing an ftp directory listing. This is useful for doing DELETE or other
|
||||
more or less obscure HTTP requests. Don't do this at will, make sure your
|
||||
server supports the command first.
|
||||
|
||||
NOTE: many people have wrongly used this option to replace the entire request
|
||||
with their own, including multiple headers and POST contents. While that might
|
||||
work in many cases, it will cause libcurl to send invalid requests and it
|
||||
could possibly confuse the remote server badly. Use \fICURLOPT_POST\fP and
|
||||
\fICURLOPT_POSTFIELDS\fP to set POST data. Use \fICURLOPT_HTTPHEADER\fP to
|
||||
\fBNOTE:\fP Many people have wrongly used this option to replace the entire
|
||||
request with their own, including multiple headers and POST contents. While
|
||||
that might work in many cases, it will cause libcurl to send invalid requests
|
||||
and it could possibly confuse the remote server badly. Use \fICURLOPT_POST\fP
|
||||
and \fICURLOPT_POSTFIELDS\fP to set POST data. Use \fICURLOPT_HTTPHEADER\fP to
|
||||
replace or extend the set of headers sent by libcurl. Use
|
||||
\fICURLOPT_HTTP_VERSION\fP to change HTTP version.
|
||||
.IP CURLOPT_FILETIME
|
||||
@@ -734,35 +749,36 @@ as a curl_off_t. (Added in 7.11.0)
|
||||
.IP CURLOPT_UPLOAD
|
||||
A non-zero parameter tells the library to prepare for an upload. The
|
||||
\fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE_LARGE\fP are also interesting
|
||||
for uploads.
|
||||
for uploads. If the protocol is HTTP, uploading means using the PUT request
|
||||
unless you tell libcurl otherwise.
|
||||
.IP CURLOPT_MAXFILESIZE
|
||||
Pass a long as parameter. This allows you to specify the maximum size (in
|
||||
bytes) of a file to download. If the file requested is larger than this value,
|
||||
the transfer will not start and CURLE_FILESIZE_EXCEEDED will be returned.
|
||||
|
||||
NOTE: The file size is not always known prior to download, and for such files
|
||||
this option has no effect even if the file transfer ends up being larger than
|
||||
this given limit. This concerns both FTP and HTTP transfers.
|
||||
\fBNOTE:\fP The file size is not always known prior to download, and for such
|
||||
files this option has no effect even if the file transfer ends up being larger
|
||||
than this given limit. This concerns both FTP and HTTP transfers.
|
||||
.IP CURLOPT_MAXFILESIZE_LARGE
|
||||
Pass a curl_off_t as parameter. This allows you to specify the maximum size
|
||||
(in bytes) of a file to download. If the file requested is larger than this
|
||||
value, the transfer will not start and \fICURLE_FILESIZE_EXCEEDED\fP will be
|
||||
returned. (Added in 7.11.0)
|
||||
|
||||
NOTE: The file size is not always known prior to download, and for such files
|
||||
this option has no effect even if the file transfer ends up being larger than
|
||||
this given limit. This concerns both FTP and HTTP transfers.
|
||||
\fBNOTE:\fP The file size is not always known prior to download, and for such
|
||||
files this option has no effect even if the file transfer ends up being larger
|
||||
than this given limit. This concerns both FTP and HTTP transfers.
|
||||
.IP CURLOPT_TIMECONDITION
|
||||
Pass a long as parameter. This defines how the \fICURLOPT_TIMEVALUE\fP time
|
||||
value is treated. You can set this parameter to \fICURL_TIMECOND_IFMODSINCE\fP
|
||||
or \fICURL_TIMECOND_IFUNMODSINCE\fP. This feature applies to HTTP and FTP.
|
||||
|
||||
NOTE: The last modification time of a file is not always known and in such
|
||||
\fBNOTE:\fP The last modification time of a file is not always known and in such
|
||||
instances this feature will have no effect even if the given time condition
|
||||
would have not been met.
|
||||
.IP CURLOPT_TIMEVALUE
|
||||
Pass a long as parameter. This should be the time in seconds since 1 jan 1970,
|
||||
and the time will be used in a condition as specified with
|
||||
and the time will be used in a condition as specified with
|
||||
\fICURLOPT_TIMECONDITION\fP.
|
||||
.SH CONNECTION OPTIONS
|
||||
.IP CURLOPT_TIMEOUT
|
||||
@@ -866,9 +882,10 @@ changed with \fICURLOPT_SSLKEYTYPE\fP.
|
||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||
the format of your private key. Supported formats are "PEM", "DER" and "ENG".
|
||||
|
||||
\fBNOTE:\fPThe format "ENG" enables you to load the private key from a crypto
|
||||
engine. in this case \fICURLOPT_SSLKEY\fP is used as an identifier passed to
|
||||
\fBNOTE:\fP The format "ENG" enables you to load the private key from a crypto
|
||||
engine. In this case \fICURLOPT_SSLKEY\fP is used as an identifier passed to
|
||||
the engine. You have to set the crypto engine with \fICURLOPT_SSLENGINE\fP.
|
||||
\&"DER" format key file currently does not work because of a bug in OpenSSL.
|
||||
.IP CURLOPT_SSLKEYPASSWD
|
||||
Pass a pointer to a zero terminated string as parameter. It will be used as
|
||||
the password required to use the \fICURLOPT_SSLKEY\fP private key.
|
||||
@@ -877,13 +894,13 @@ Pass a pointer to a zero terminated string as parameter. It will be used as
|
||||
the identifier for the crypto engine you want to use for your private
|
||||
key.
|
||||
|
||||
\fBNOTE:\fPIf the crypto device cannot be loaded,
|
||||
\fBNOTE:\fP If the crypto device cannot be loaded,
|
||||
\fICURLE_SSL_ENGINE_NOTFOUND\fP is returned.
|
||||
.IP CURLOPT_SSLENGINE_DEFAULT
|
||||
Sets the actual crypto engine as the default for (asymmetric) crypto
|
||||
operations.
|
||||
|
||||
\fBNOTE:\fPIf the crypto device cannot be set,
|
||||
\fBNOTE:\fP If the crypto device cannot be set,
|
||||
\fICURLE_SSL_ENGINE_SETFAILED\fP is returned.
|
||||
.IP CURLOPT_SSLVERSION
|
||||
Pass a long as parameter. Set what version of SSL to attempt to use, 2 or
|
||||
@@ -959,5 +976,9 @@ standard for details.
|
||||
CURLE_OK (zero) means that the option was set properly, non-zero means an
|
||||
error occurred as \fI<curl/curl.h>\fP defines. See the \fIlibcurl-errors(3)\fP
|
||||
man page for the full list with descriptions.
|
||||
|
||||
If you try to set an option that libcurl doesn't know about, perhaps because
|
||||
the library is too old to support it or the option was removed in a recent
|
||||
version, this function will return \fICURLE_FAILED_INIT\fP.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_init "(3), " curl_easy_cleanup "(3), "
|
||||
|
18
docs/libcurl/curl_easy_strerror.3
Normal file
18
docs/libcurl/curl_easy_strerror.3
Normal file
@@ -0,0 +1,18 @@
|
||||
.\" You can view this file with:
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_easy_strerror 3 "26 Apr 2004" "libcurl 7.12" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_strerror - return string describing error code
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B #include <curl/curl.h>
|
||||
.BI "const char *curl_easy_strerror(CURLcode " errornum ");"
|
||||
.SH DESCRIPTION
|
||||
The curl_easy_strerror() function returns a string describing the CURLcode
|
||||
error code passed in the argument \fIerrornum\fP.
|
||||
.SH RETURN VALUE
|
||||
A pointer to a zero terminated string.
|
||||
.SH "SEE ALSO"
|
||||
.BR libcurl-errors "(3), " curl_multi_strerror "(3), " curl_share_strerror "(3)"
|
@@ -205,5 +205,4 @@ defines.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_setopt "(3), "
|
||||
.BR curl_formparse "(3) [deprecated], "
|
||||
.BR curl_formfree "(3)"
|
||||
|
@@ -1,18 +0,0 @@
|
||||
.\" You can view this file with:
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_formparse 3 "17 Dec 2001" "libcurl 7.9.2" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_formparse - add a section to a multipart/formdata HTTP POST:
|
||||
deprecated (use curl_formadd instead)
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
.sp
|
||||
.BI "CURLcode curl_formparse(char * " string, " struct HttpPost ** " firstitem,
|
||||
.BI "struct HttpPost ** " lastitem ");"
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
This has been removed deliberately. The \fBcurl_formadd\fP has been introduced
|
||||
to replace this function. Do not use this. Convert to the new function
|
||||
now. curl_formparse() will be removed from a future version of libcurl.
|
@@ -1,8 +1,6 @@
|
||||
.\" You can view this file with:
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_getenv 3 "15 August 2001" "libcurl 7.8.1" "libcurl Manual"
|
||||
.TH curl_getenv 3 "30 April 2004" "libcurl 7.12" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_getenv - return value for environment name
|
||||
.SH SYNOPSIS
|
||||
@@ -14,6 +12,10 @@ curl_getenv - return value for environment name
|
||||
curl_getenv() is a portable wrapper for the getenv() function, meant to
|
||||
emulate its behaviour and provide an identical interface for all operating
|
||||
systems libcurl builds on (including win32).
|
||||
.SH AVAILABILITY
|
||||
This function will be removed from the public libcurl API in a near future. It
|
||||
will instead be made "available" by source code access only, and then as
|
||||
curlx_getenv().
|
||||
.SH RETURN VALUE
|
||||
If successful, curl_getenv() returns a pointer to the value of the specified
|
||||
environment. The memory it refers to is malloc()ed why the application must
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_global_init 3 "13 Nov 2001" "libcurl 7.9.1" "libcurl Manual"
|
||||
.TH curl_global_init 3 "11 May 2004" "libcurl 7.12" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_global_init - Global libcurl initialisation
|
||||
.SH SYNOPSIS
|
||||
@@ -42,6 +42,5 @@ Initialise nothing extra. This sets no bit.
|
||||
If this function returns non-zero, something went wrong and you cannot use the
|
||||
other curl functions.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_global_init_mem "(3), "
|
||||
.BR curl_global_cleanup "(3), "
|
||||
|
||||
|
||||
|
42
docs/libcurl/curl_global_init_mem.3
Normal file
42
docs/libcurl/curl_global_init_mem.3
Normal file
@@ -0,0 +1,42 @@
|
||||
.\" You can view this file with:
|
||||
.\" nroff -man [file]
|
||||
.\"
|
||||
.TH curl_global_init_mem 3 "10 May 2004" "libcurl 7.12.0" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_global_init_mem - Global libcurl initialisation with memory callbacks
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
.nf
|
||||
.B "CURLcode curl_global_init_mem(long " flags,
|
||||
.B " curl_malloc_callback "m,
|
||||
.B " curl_free_callback "f,
|
||||
.B " curl_realloc_callback "r,
|
||||
.B " curl_strdup_callback "s,
|
||||
.B " curl_calloc_callback "c ");"
|
||||
.SH DESCRIPTION
|
||||
This function works exactly as \fIcurl_global_init(3)\fP with one addition: it
|
||||
allows the application to set callbacks to replace the otherwise used internal
|
||||
memory functions.
|
||||
|
||||
This man page only adds documentation for the callbacks, see the
|
||||
\fIcurl_global_init(3)\fP man page for all the rest. When you use this
|
||||
function, all callback arguments must be set to valid function pointers.
|
||||
|
||||
The prototypes for the given callbacks should match these:
|
||||
.IP "void *malloc_callback(size_t size);"
|
||||
To replace malloc()
|
||||
.IP "void free_callback(void *ptr);"
|
||||
To replace free()
|
||||
.IP "void *realloc_callback(void *ptr, size_t size);"
|
||||
To replace realloc()
|
||||
.IP "char *strdup_callback(const char *str);"
|
||||
To replace strdup()
|
||||
.IP "void *calloc_callback(size_t nmemb, size_t size);"
|
||||
To replace calloc()
|
||||
.SH "CAUTION"
|
||||
Manipulating these gives considerable powers to the application to severly
|
||||
screw things up for libcurl. Take care!
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_global_init "(3), "
|
||||
.BR curl_global_cleanup "(3), "
|
||||
|
@@ -1,8 +1,6 @@
|
||||
.\" You can view this file with:
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_printf 3 "20 April 2001" "libcurl 7.7.2" "libcurl Manual"
|
||||
.TH curl_printf 3 "30 April 2004" "libcurl 7.12" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_maprintf, curl_mfprintf, curl_mprintf, curl_msnprintf, curl_msprintf
|
||||
curl_mvaprintf, curl_mvfprintf, curl_mvprintf, curl_mvsnprintf,
|
||||
@@ -79,6 +77,10 @@ To easily use all these cloned functions instead of the normal ones, #define
|
||||
_MPRINTF_REPLACE before you include the <curl/mprintf.h> file. Then all the
|
||||
normal names like printf, fprintf, sprintf etc will use the curl-functions
|
||||
instead.
|
||||
.SH AVAILABILITY
|
||||
These function will be removed from the public libcurl API in a near
|
||||
future. They will instead be made "available" by source code access only, and
|
||||
then as curlx_-prefixed functions. See lib/README.curlx for further details.
|
||||
.SH RETURN VALUE
|
||||
The \fBcurl_maprintf\fP and \fBcurl_mvaprintf\fP functions return a pointer to
|
||||
a newly allocated string, or NULL it it failed.
|
||||
|
18
docs/libcurl/curl_multi_strerror.3
Normal file
18
docs/libcurl/curl_multi_strerror.3
Normal file
@@ -0,0 +1,18 @@
|
||||
.\" You can view this file with:
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_multi_strerror 3 "26 Apr 2004" "libcurl 7.12" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_multi_strerror - return string describing error code
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B #include <curl/curl.h>
|
||||
.BI "const char *curl_multi_strerror(CURLMcode " errornum ");"
|
||||
.SH DESCRIPTION
|
||||
The curl_multi_strerror() function returns a string describing the CURLMcode
|
||||
error code passed in the argument \fIerrornum\fP.
|
||||
.SH RETURN VALUE
|
||||
A pointer to a zero terminated string.
|
||||
.SH "SEE ALSO"
|
||||
.BR libcurl-errors "(3), " curl_easy_strerror "(3), " curl_share_strerror "(3)"
|
18
docs/libcurl/curl_share_strerror.3
Normal file
18
docs/libcurl/curl_share_strerror.3
Normal file
@@ -0,0 +1,18 @@
|
||||
.\" You can view this file with:
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_share_strerror 3 "26 Apr 2004" "libcurl 7.12" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_share_strerror - return string describing error code
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B #include <curl/curl.h>
|
||||
.BI "const char *curl_share_strerror(CURLSHcode " errornum ");"
|
||||
.SH DESCRIPTION
|
||||
The curl_share_strerror() function returns a string describing the CURLSHcode
|
||||
error code passed in the argument \fIerrornum\fP.
|
||||
.SH RETURN VALUE
|
||||
A pointer to a zero terminated string.
|
||||
.SH "SEE ALSO"
|
||||
.BR libcurl-errors "(3), " curl_multi_strerror "(3), " curl_easy_strerror "(3)"
|
@@ -1,8 +1,6 @@
|
||||
.\" You can view this file with:
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_strequal 3 "20 April 2001" "libcurl 7.7.2" "libcurl Manual"
|
||||
.TH curl_strequal 3 "30 April 2004" "libcurl 7.12" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_strequal, curl_strnequal - case insensitive string comparisons
|
||||
.SH SYNOPSIS
|
||||
@@ -24,6 +22,10 @@ first \fIlen\fP characters of \fIstr1\fP.
|
||||
These functions are provided by libcurl to enable applications to compare
|
||||
strings in a truly portable manner. There are no standard portable case
|
||||
insensitive string comparison functions. These two works on all platforms.
|
||||
.SH AVAILABILITY
|
||||
These functions will be removed from the public libcurl API in a near
|
||||
future. They will instead be made "available" by source code access only, and
|
||||
then as curlx_strequal() and curlx_strenqual().
|
||||
.SH RETURN VALUE
|
||||
Non-zero if the strings are identical. Zero if they're not.
|
||||
.SH "SEE ALSO"
|
||||
|
@@ -13,9 +13,8 @@ curl_unescape - URL decodes the given string
|
||||
.SH DESCRIPTION
|
||||
This function will convert the given URL encoded input string to a "plain
|
||||
string" and return that as a new allocated string. All input characters that
|
||||
are URL encoded (%XX where XX is a two-digit hexadecimal number, or +) will be
|
||||
converted to their plain text versions (up to a ? letter, no + letters to the
|
||||
right of a ? letter will be converted).
|
||||
are URL encoded (%XX where XX is a two-digit hexadecimal number) will be
|
||||
converted to their plain text versions.
|
||||
|
||||
If the 'length' argument is set to 0, curl_unescape() will use strlen() on the
|
||||
input 'url' string to find out the size.
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_version_info 3 "19 Sep 2003" "libcurl 7.10.8" "libcurl Manual"
|
||||
.TH curl_version_info 3 "11 May 2004" "libcurl 7.12" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_version_info - returns run-time libcurl version info
|
||||
.SH SYNOPSIS
|
||||
@@ -28,22 +28,32 @@ The curl_version_info_data struct looks like this
|
||||
|
||||
.nf
|
||||
typedef struct {
|
||||
CURLversion age; /* 0 - this kind of struct */
|
||||
CURLversion age; /* see description below */
|
||||
|
||||
/* when 'age' is 0 or higher, the members below also exist: */
|
||||
const char *version; /* human readable string */
|
||||
unsigned int version_num; /* numeric representation */
|
||||
const char *host; /* human readable string */
|
||||
int features; /* bitmask, see below */
|
||||
char *ssl_version; /* human readable string */
|
||||
long ssl_version_num; /* number */
|
||||
char *libz_version; /* human readable string */
|
||||
const char *protocols[]; /* list of protocols */
|
||||
const char *libz_version; /* human readable string */
|
||||
const char **protocols; /* list of protocols */
|
||||
|
||||
/* when 'age' is 1 or higher, the members below also exist: */
|
||||
const char *ares; /* human readable string */
|
||||
int ares_num; /* number */
|
||||
|
||||
/* when 'age' is 2 or higher, the member below also exists: */
|
||||
const char *libidn; /* human readable string */
|
||||
|
||||
} curl_version_info_data;
|
||||
.fi
|
||||
|
||||
\fIage\fP describes what kind of struct this is. It is always 0 now. In a
|
||||
future libcurl, if this struct changes, this age counter may be increased, and
|
||||
then the struct for number 1 will look different (except for this first struct
|
||||
field).
|
||||
\fIage\fP describes what age of this struct this is. The number depends on how
|
||||
new libcurl you're using. You are however guaranteed to get a struct that you
|
||||
have a matching struct for in the header, as you tell libcurl your "age" with
|
||||
the input argument.
|
||||
|
||||
\fIversion\fP is just an ascii string for the libcurl version.
|
||||
|
||||
@@ -57,38 +67,35 @@ environment.
|
||||
|
||||
\fIfeatures\fP can have none, one or more bits set, and the currently defined
|
||||
bits are:
|
||||
.TP 5.5
|
||||
.B CURL_VERSION_IPV6
|
||||
.RS
|
||||
.IP CURL_VERSION_IPV6
|
||||
supports IPv6
|
||||
.TP
|
||||
.B CURL_VERSION_KERBEROS4
|
||||
.IP CURL_VERSION_KERBEROS4
|
||||
supports kerberos4 (when using FTP)
|
||||
.TP
|
||||
.B CURL_VERSION_SSL
|
||||
.IP CURL_VERSION_SSL
|
||||
supports SSL (HTTPS/FTPS)
|
||||
.TP
|
||||
.B CURL_VERSION_LIBZ
|
||||
.IP CURL_VERSION_LIBZ
|
||||
supports HTTP deflate using libz
|
||||
.TP
|
||||
.B CURL_VERSION_NTLM
|
||||
.IP CURL_VERSION_NTLM
|
||||
supports HTTP NTLM (added in 7.10.6)
|
||||
.TP
|
||||
.B CURL_VERSION_GSSNEGOTIATE
|
||||
.IP CURL_VERSION_GSSNEGOTIATE
|
||||
supports HTTP GSS-Negotiate (added in 7.10.6)
|
||||
.TP
|
||||
.B CURL_VERSION_DEBUG
|
||||
.IP CURL_VERSION_DEBUG
|
||||
libcurl was built with extra debug capabilities built-in. This is mainly of
|
||||
interest for libcurl hackers. (added in 7.10.6)
|
||||
.TP
|
||||
.B CURL_VERSION_ASYNCHDNS
|
||||
.IP CURL_VERSION_ASYNCHDNS
|
||||
libcurl was built with support for asynchronous name lookups, which allows
|
||||
more exact timeouts (even on Windows) and less blocking when using the multi
|
||||
interface. (added in 7.10.7)
|
||||
.TP
|
||||
.B CURL_VERSION_SPNEGO
|
||||
.IP CURL_VERSION_SPNEGO
|
||||
libcurl was built with support for SPNEGO authentication (Simple and Protected
|
||||
GSS-API Negotiation Mechanism, defined in RFC 2478.) (added in 7.10.8)
|
||||
.PP
|
||||
.IP CURL_VERSION_LARGEFILE
|
||||
libcurl was built with support for large files.
|
||||
.IP CURL_VERSION_IDN
|
||||
libcurl was built with support for IDNA, domain names with international
|
||||
letters.
|
||||
.RE
|
||||
\fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
|
||||
has no SSL support, this is NULL.
|
||||
|
||||
|
@@ -1,14 +1,14 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<TITLE>Index to libcurl documentation</TITLE>
|
||||
</HEAD>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<title>Index to libcurl documentation</title>
|
||||
</head>
|
||||
|
||||
<BODY>
|
||||
<H1 ALIGN="CENTER">Index to libcurl documentation</H1>
|
||||
<body>
|
||||
<h1 align="center">Index to libcurl documentation</h1>
|
||||
|
||||
<H2>Programs</H2>
|
||||
<P><A HREF="../index.html">curl and tools</A>
|
||||
<h2>Programs</h2>
|
||||
<p><a href="../index.html">curl and tools</a>
|
||||
|
||||
<h2>Overviews</h2>
|
||||
<A HREF="libcurl.html">libcurl</A>
|
||||
@@ -16,7 +16,7 @@
|
||||
<br><a href="libcurl-multi.html">libcurl-multi</a>
|
||||
<br><a href="libcurl-share.html">libcurl-share</a>
|
||||
<br><a href="libcurl-errors.html">libcurl-errors</a>
|
||||
<br><a href="../libcurl-the-guide">libcurl-the-guide</a> (plain text)
|
||||
<br><a href="libcurl-tutorial.html">libcurl-tutorial</a>
|
||||
|
||||
<H2>Library Functions (A-Z)</H2>
|
||||
<a href="curl_easy_cleanup.html">curl_easy_cleanup</A>
|
||||
@@ -25,15 +25,16 @@
|
||||
<br><a href="curl_easy_init.html">curl_easy_init</A>
|
||||
<br><a href="curl_easy_perform.html">curl_easy_perform</A>
|
||||
<br><a href="curl_easy_setopt.html">curl_easy_setopt</A>
|
||||
<br><a href="curl_easy_strerror.html">curl_easy_strerror</A>
|
||||
<br><a href="curl_escape.html">curl_escape</A>
|
||||
<br><a href="curl_formadd.html">curl_formadd</A>
|
||||
<br><a href="curl_formfree.html">curl_formfree</A>
|
||||
<br><a href="curl_formparse.html">curl_formparse</A>
|
||||
<br><a href="curl_free.html">curl_free</A>
|
||||
<br><a href="curl_getdate.html">curl_getdate</A>
|
||||
<br><a href="curl_getenv.html">curl_getenv</A>
|
||||
<br><a href="curl_global_cleanup.html">curl_global_cleanup</A>
|
||||
<br><a href="curl_global_init.html">curl_global_init</A>
|
||||
<br><a href="curl_global_init_mem.html">curl_global_init_mem</A>
|
||||
<br><a href="curl_mprintf.html">curl_mprintf</A>
|
||||
<br><a href="curl_multi_add_handle.html">curl_multi_add_handle</a>
|
||||
<br><a href="curl_multi_cleanup.html">curl_multi_cleanup</a>
|
||||
@@ -42,16 +43,16 @@
|
||||
<br><a href="curl_multi_init.html">curl_multi_init</a>
|
||||
<br><a href="curl_multi_perform.html">curl_multi_perform</a>
|
||||
<br><a href="curl_multi_remove_handle.html">curl_multi_remove_handle</a>
|
||||
<br><a href="curl_multi_strerror.html">curl_multi_strerror.html</a>
|
||||
<br><a href="curl_share_cleanup.html">curl_share_cleanup</A>
|
||||
<br><a href="curl_share_init.html">curl_share_init</A>
|
||||
<br><a href="curl_share_setopt.html">curl_share_setopt</A>
|
||||
<br><a href="curl_share_strerror.html">curl_share_strerror.html</a>
|
||||
<br><a href="curl_slist_append.html">curl_slist_append</A>
|
||||
<br><a href="curl_slist_free_all.html">curl_slist_free_all</A>
|
||||
<br><a href="curl_strequal.html">curl_strequal</A>
|
||||
<br><a href="curl_strnequal.html">curl_strnequal</A>
|
||||
<br><a href="curl_strequal.html">curl_strequal and curl_strnequal</A>
|
||||
<br><a href="curl_unescape.html">curl_unescape</A>
|
||||
<br><a href="curl_version.html">curl_version</A>
|
||||
<br><a href="curl_version_info.html">curl_version_info</A>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
</body></html>
|
||||
|
@@ -7,9 +7,8 @@
|
||||
libcurl-easy \- easy interface overview
|
||||
.SH DESCRIPTION
|
||||
When using libcurl's "easy" interface you init your session and get a handle
|
||||
(often referred to as an "easy handle" in various docs and sources), which you
|
||||
use as input to the easy interface functions you use. Use
|
||||
\fIcurl_easy_init(3)\fP to get the handle.
|
||||
(often referred to as an "easy handle"), which you use as input to the easy
|
||||
interface functions you use. Use \fIcurl_easy_init(3)\fP to get the handle.
|
||||
|
||||
You continue by setting all the options you want in the upcoming transfer, the
|
||||
most important among them is the URL itself (you can't transfer anything
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH libcurl-errors 3 "8 Mar 2004" "libcurl 7.11.0" "libcurl errors"
|
||||
.TH libcurl-errors 3 "27 Apr 2004" "libcurl 7.12" "libcurl errors"
|
||||
.SH NAME
|
||||
libcurl-errors \- error codes in libcurl
|
||||
.SH DESCRIPTION
|
||||
@@ -10,9 +10,11 @@ This man page includes most, if not all, available error codes in libcurl.
|
||||
Why they occur and possibly what you can do to fix the problem.
|
||||
.SH "CURLcode"
|
||||
Almost all "easy" interface functions return a CURLcode error code. No matter
|
||||
what, using \fICURLOPT_ERRORBUFFER\fP is a good idea as it will give you a
|
||||
human readable error string that may offer more details about the error cause
|
||||
than just the error code does.
|
||||
what, using the \fIcurl_easy_setopt(3)\fP option \fICURLOPT_ERRORBUFFER\fP is
|
||||
a good idea as it will give you a human readable error string that may offer
|
||||
more details about the error cause than just the error code
|
||||
does. \fIcurl_easy_strerror(3)\fP can be called to get an error string from a
|
||||
given CURLcode number.
|
||||
|
||||
CURLcode is one of the following:
|
||||
.IP "CURLE_OK (0)"
|
||||
@@ -168,8 +170,8 @@ Failed setting the selected SSL crypto engine as default!
|
||||
Failed sending network data.
|
||||
.IP "CURLE_RECV_ERROR (56)"
|
||||
Failure with receiving network data.
|
||||
.IP "CURLE_RECV_ERROR (57)"
|
||||
Failure with receiving network data.
|
||||
.IP "CURLE_SHARE_IN_USE (57)"
|
||||
Share is in use
|
||||
.IP "CURLE_SSL_CERTPROBLEM (58)"
|
||||
problem with the local certificate
|
||||
.IP "CURLE_SSL_CIPHER (59)"
|
||||
@@ -186,7 +188,8 @@ Maximum file size exceeded
|
||||
Requested FTP SSL level failed
|
||||
.SH "CURLMcode"
|
||||
This is the generic return code used by functions in the libcurl multi
|
||||
interface.
|
||||
interface. Also consider \fIcurl_multi_strerror(3)\fI.
|
||||
|
||||
.IP "CURLM_CALL_MULTI_PERFORM (-1)"
|
||||
This is not really an error. It means you should call
|
||||
\fIcurl_multi_perform(3)\fP again without doing select() or similar in between.
|
||||
@@ -201,8 +204,8 @@ You are doomed.
|
||||
.IP "CURLM_INTERNAL_ERROR (4)"
|
||||
This can only be returned if libcurl bugs. Please report it to us!
|
||||
.SH "CURLSHcode"
|
||||
The "share" interface will return a CURLSHcode to indicate when an
|
||||
error has occurred.
|
||||
The "share" interface will return a CURLSHcode to indicate when an error has
|
||||
occurred. Also consider \fIcurl_share_strerror(3)\fI.
|
||||
|
||||
CURLSHcode is one of the following:
|
||||
.IP "CURLSHE_OK (0)"
|
||||
|
@@ -8,9 +8,9 @@ libcurl-multi \- how to use the multi interface
|
||||
.SH DESCRIPTION
|
||||
This is an overview on how to use the libcurl multi interface in your C
|
||||
programs. There are specific man pages for each function mentioned in
|
||||
here. There's also the libcurl-the-guide document for a complete tutorial to
|
||||
programming with libcurl and the \fIlibcurl(3)\fP man page for an overview of
|
||||
the libcurl easy interface.
|
||||
here. There's also the \fIlibcurl-tutorial(3)f\P man page for a complete
|
||||
tutorial to programming with libcurl and the \fIlibcurl-easy(3)\fP man page
|
||||
for an overview of the libcurl easy interface.
|
||||
|
||||
All functions in the multi interface are prefixed with curl_multi.
|
||||
.SH "PLEASE NOTICE"
|
||||
|
1171
docs/libcurl/libcurl-tutorial.3
Normal file
1171
docs/libcurl/libcurl-tutorial.3
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,19 +1,17 @@
|
||||
.\" You can view this file with:
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH libcurl 3 "19 March 2002" "libcurl 7.9.6" "libcurl overview"
|
||||
.SH NAME
|
||||
libcurl \- client-side URL transfers
|
||||
.SH DESCRIPTION
|
||||
This is an overview on how to use libcurl in your C programs. There are
|
||||
This is an short overview on how to use libcurl in your C programs. There are
|
||||
specific man pages for each function mentioned in here. There are also the
|
||||
\fIlibcurl-easy(3)\fP man page, the \fIlibcurl-multi(3)\fP man page, the
|
||||
\fIlibcurl-share(3)\fP man page and the \fIlibcurl-the-guide\fP document for
|
||||
further reading on how to do programming with libcurl.
|
||||
\fIlibcurl-share(3)\fP man page and the \fIlibcurl-tutorial(3)\fP man page for
|
||||
in-depth understanding on how to program with libcurl.
|
||||
|
||||
There exist more than a dozen custom bindings that bring libcurl access to
|
||||
your favourite language. Look elsewhere for documentation on those.
|
||||
There are more than a twenty custom bindings available that bring libcurl
|
||||
access to your favourite language. Look elsewhere for documentation on those.
|
||||
|
||||
All applications that use libcurl should call \fIcurl_global_init(3)\fP
|
||||
exactly once before any libcurl function can be used. After all usage of
|
||||
@@ -33,45 +31,28 @@ The multi interface on the other hand is an asynchronous interface, that you
|
||||
call and that performs only a little piece of the transfer on each invoke. It
|
||||
is perfect if you want to do things while the transfer is in progress, or
|
||||
similar. The multi interface allows you to select() on libcurl action, and
|
||||
even to easily download multiple files simultaneously using a single thread.
|
||||
even to easily download multiple files simultaneously using a single thread. See further deails in the \fIlibcurl-multi(3)\fP man page.
|
||||
|
||||
You can have multiple easy handles share certain data, even if they are used
|
||||
in different threads. This magic is setup using the share interface, as
|
||||
described in the \fIlibcurl-share(3)\fP man page.
|
||||
|
||||
There is also a series of other helpful functions to use. They are:
|
||||
|
||||
There is also a series of other helpful functions to use, including these:
|
||||
.RS
|
||||
.TP 10
|
||||
.B curl_version()
|
||||
displays the libcurl version
|
||||
.TP
|
||||
.B curl_getdate()
|
||||
.IP curl_version_info()
|
||||
gets detailed libcurl (and other used libraries) version info
|
||||
.IP curl_getdate()
|
||||
converts a date string to time_t
|
||||
.TP
|
||||
.B curl_getenv()
|
||||
portable environment variable reader
|
||||
.TP
|
||||
.B curl_easy_getinfo()
|
||||
.IP curl_easy_getinfo()
|
||||
get information about a performed transfer
|
||||
.TP
|
||||
.B curl_formadd()
|
||||
.IP curl_formadd()
|
||||
helps building an HTTP form POST
|
||||
.TP
|
||||
.B curl_formfree()
|
||||
.IP curl_formfree()
|
||||
free a list built with \fIcurl_formadd(3)\fP
|
||||
.TP
|
||||
.B curl_slist_append()
|
||||
.IP curl_slist_append()
|
||||
builds a linked list
|
||||
.TP
|
||||
.B curl_slist_free_all()
|
||||
.IP curl_slist_free_all()
|
||||
frees a whole curl_slist
|
||||
.TP
|
||||
.B curl_mprintf()
|
||||
portable printf() functions
|
||||
.TP
|
||||
.B curl_strequal()
|
||||
portable case insensitive string comparisons
|
||||
.RE
|
||||
|
||||
.SH "LINKING WITH LIBCURL"
|
||||
@@ -82,13 +63,17 @@ curl-config is added to make it easier for applications to link with libcurl
|
||||
and developers to learn about libcurl and how to use it.
|
||||
|
||||
Run 'curl-config --libs' to get the (additional) linker options you need to
|
||||
link with the particular version of libcurl you've installed.
|
||||
link with the particular version of libcurl you've installed. See the
|
||||
\fIcurl-config(1)\fP man page for further details.
|
||||
|
||||
Unix-like operating system that ship libcurl as part of their distributions
|
||||
often don't provide the curl-config tool, but simply install the library and
|
||||
headers in the common path for this purpose.
|
||||
|
||||
For details, see the curl-config.1 man page.
|
||||
.SH "LIBCURL SYMBOL NAMES"
|
||||
All public functions in the libcurl interface are prefixed with 'curl_' (with
|
||||
a lowercase c). You can find other functions in the library source code, but
|
||||
other prefixes indicate the functions are private and may change without
|
||||
other prefixes indicate that the functions are private and may change without
|
||||
further notice in the next release.
|
||||
|
||||
Only use documented functions and functionality!
|
||||
|
@@ -1,10 +1,10 @@
|
||||
#ifndef __CURL_CURL_H
|
||||
#define __CURL_CURL_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
@@ -12,7 +12,7 @@
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
@@ -41,7 +41,7 @@
|
||||
# include <time.h>
|
||||
#endif /* defined (vms) */
|
||||
|
||||
#include "types.h"
|
||||
typedef void CURL;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -52,11 +52,11 @@ extern "C" {
|
||||
* platforms. We also provide a CURL_FORMAT_OFF_T define to use in *printf
|
||||
* format strings when outputting a variable of type curl_off_t.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_MSC_VER) || defined(__LCC__)
|
||||
/* MSVC */
|
||||
typedef signed __int64 curl_off_t;
|
||||
#define CURL_FORMAT_OFF_T "%I64d"
|
||||
#else /* MSC_VER */
|
||||
#else /* _MSC_VER || __LCC__ */
|
||||
#if (defined(__GNUC__) && defined(WIN32)) || defined(__WATCOMC__)
|
||||
/* gcc on windows or Watcom */
|
||||
typedef long long curl_off_t;
|
||||
@@ -88,7 +88,7 @@ extern "C" {
|
||||
#define CURL_FORMAT_OFF_T "%ld"
|
||||
#endif
|
||||
#endif /* GCC or Watcom on Windows */
|
||||
#endif /* MSC_VER */
|
||||
#endif /* _MSC_VER || __LCC__ */
|
||||
|
||||
#ifdef UNDEF_FILE_OFFSET_BITS
|
||||
/* this was defined above for our checks, undefine it again */
|
||||
@@ -143,6 +143,9 @@ typedef size_t (*curl_write_callback)(char *buffer,
|
||||
size_t nitems,
|
||||
void *outstream);
|
||||
|
||||
/* This is a brand new return code for the read callback that will signal
|
||||
the caller to immediately abort the current transfer. */
|
||||
#define CURL_READFUNC_ABORT 0x10000000
|
||||
typedef size_t (*curl_read_callback)(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
@@ -154,6 +157,18 @@ typedef int (*curl_passwd_callback)(void *clientp,
|
||||
char *buffer,
|
||||
int buflen);
|
||||
|
||||
/*
|
||||
* The following typedef's are signatures of malloc, free, realloc, strdup and
|
||||
* calloc respectively. Function pointers of these types can be passed to the
|
||||
* curl_global_init_mem() function to set user defined memory management
|
||||
* callback routines.
|
||||
*/
|
||||
typedef void *(*curl_malloc_callback)(size_t size);
|
||||
typedef void (*curl_free_callback)(void *ptr);
|
||||
typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
|
||||
typedef char *(*curl_strdup_callback)(const char *str);
|
||||
typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
|
||||
|
||||
/* the kind of data that is passed to information_callback*/
|
||||
typedef enum {
|
||||
CURLINFO_TEXT = 0,
|
||||
@@ -161,6 +176,8 @@ typedef enum {
|
||||
CURLINFO_HEADER_OUT, /* 2 */
|
||||
CURLINFO_DATA_IN, /* 3 */
|
||||
CURLINFO_DATA_OUT, /* 4 */
|
||||
CURLINFO_SSL_DATA_IN, /* 5 */
|
||||
CURLINFO_SSL_DATA_OUT, /* 6 */
|
||||
CURLINFO_END
|
||||
} curl_infotype;
|
||||
|
||||
@@ -170,7 +187,7 @@ typedef int (*curl_debug_callback)
|
||||
char *data, /* points to the data */
|
||||
size_t size, /* size of the data pointed to */
|
||||
void *userptr); /* whatever the user please */
|
||||
|
||||
|
||||
/* All possible error codes from all sorts of curl functions. Future versions
|
||||
may return other values, stay prepared.
|
||||
|
||||
@@ -183,7 +200,7 @@ typedef enum {
|
||||
CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
|
||||
CURLE_FAILED_INIT, /* 2 */
|
||||
CURLE_URL_MALFORMAT, /* 3 */
|
||||
CURLE_URL_MALFORMAT_USER, /* 4 */
|
||||
CURLE_URL_MALFORMAT_USER, /* 4 (NOT USED) */
|
||||
CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
|
||||
CURLE_COULDNT_RESOLVE_HOST, /* 6 */
|
||||
CURLE_COULDNT_CONNECT, /* 7 */
|
||||
@@ -203,7 +220,7 @@ typedef enum {
|
||||
CURLE_FTP_QUOTE_ERROR, /* 21 */
|
||||
CURLE_HTTP_RETURNED_ERROR, /* 22 */
|
||||
CURLE_WRITE_ERROR, /* 23 */
|
||||
CURLE_MALFORMAT_USER, /* 24 - user name is illegally specified */
|
||||
CURLE_MALFORMAT_USER, /* 24 - NOT USED */
|
||||
CURLE_FTP_COULDNT_STOR_FILE, /* 25 - failed FTP upload */
|
||||
CURLE_READ_ERROR, /* 26 - could open/read from file */
|
||||
CURLE_OUT_OF_MEMORY, /* 27 */
|
||||
@@ -223,13 +240,13 @@ typedef enum {
|
||||
CURLE_FUNCTION_NOT_FOUND, /* 41 */
|
||||
CURLE_ABORTED_BY_CALLBACK, /* 42 */
|
||||
CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */
|
||||
CURLE_BAD_CALLING_ORDER, /* 44 */
|
||||
CURLE_HTTP_PORT_FAILED, /* 45 - HTTP Interface operation failed */
|
||||
CURLE_BAD_PASSWORD_ENTERED, /* 46 - my_getpass() returns fail */
|
||||
CURLE_BAD_CALLING_ORDER, /* 44 - NOT USED */
|
||||
CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */
|
||||
CURLE_BAD_PASSWORD_ENTERED, /* 46 - NOT USED */
|
||||
CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */
|
||||
CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */
|
||||
CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */
|
||||
CURLE_OBSOLETE, /* 50 - removed after 7.7.3 */
|
||||
CURLE_OBSOLETE, /* 50 - NOT USED */
|
||||
CURLE_SSL_PEER_CERTIFICATE, /* 51 - peer's certificate wasn't ok */
|
||||
CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
|
||||
CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */
|
||||
@@ -244,7 +261,7 @@ typedef enum {
|
||||
CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized transfer encoding */
|
||||
CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */
|
||||
CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */
|
||||
CURLE_FTP_SSL_FAILED, /* 64 - Requested FTP SSL level failed */
|
||||
CURLE_FTP_SSL_FAILED, /* 64 - Requested FTP SSL level failed */
|
||||
|
||||
CURL_LAST /* never use! */
|
||||
} CURLcode;
|
||||
@@ -256,7 +273,10 @@ typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
|
||||
|
||||
/* Make a spelling correction for the operation timed-out define */
|
||||
#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
|
||||
|
||||
/* backwards compatibility with older names */
|
||||
#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
|
||||
#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
|
||||
|
||||
typedef enum {
|
||||
CURLPROXY_HTTP = 0,
|
||||
@@ -312,7 +332,7 @@ typedef enum {
|
||||
* platforms.
|
||||
*/
|
||||
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
|
||||
defined(__HP_aCC) || defined(__BORLANDC__)
|
||||
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__)
|
||||
/* This compiler is believed to have an ISO compatible preprocessor */
|
||||
#define CURL_ISOCPP
|
||||
#else
|
||||
@@ -349,7 +369,7 @@ typedef enum {
|
||||
|
||||
/* Name of proxy to use. */
|
||||
CINIT(PROXY, OBJECTPOINT, 4),
|
||||
|
||||
|
||||
/* "name:password" to use when fetching. */
|
||||
CINIT(USERPWD, OBJECTPOINT, 5),
|
||||
|
||||
@@ -406,7 +426,7 @@ typedef enum {
|
||||
/* If the download receives less than "low speed limit" bytes/second
|
||||
* during "low speed time" seconds, the operations is aborted.
|
||||
* You could i.e if you have a pretty high speed connection, abort if
|
||||
* it is less than 2000 bytes/sec during 20 seconds.
|
||||
* it is less than 2000 bytes/sec during 20 seconds.
|
||||
*/
|
||||
|
||||
/* Set the "low speed limit" */
|
||||
@@ -439,7 +459,7 @@ typedef enum {
|
||||
CINIT(SSLCERTPASSWD, OBJECTPOINT, 26),
|
||||
/* password for the SSL private key */
|
||||
CINIT(SSLKEYPASSWD, OBJECTPOINT, 26),
|
||||
|
||||
|
||||
/* send TYPE parameter? */
|
||||
CINIT(CRLF, LONG, 27),
|
||||
|
||||
@@ -503,7 +523,7 @@ typedef enum {
|
||||
CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */
|
||||
|
||||
CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
|
||||
CINIT(PUT, LONG, 54), /* PUT the input file */
|
||||
CINIT(PUT, LONG, 54), /* HTTP PUT */
|
||||
|
||||
/* 55 = OBSOLETE */
|
||||
|
||||
@@ -538,20 +558,20 @@ typedef enum {
|
||||
|
||||
/* Set if we should verify the peer in ssl handshake, set 1 to verify. */
|
||||
CINIT(SSL_VERIFYPEER, LONG, 64),
|
||||
|
||||
|
||||
/* The CApath or CAfile used to validate the peer certificate
|
||||
this option is used only if SSL_VERIFYPEER is true */
|
||||
CINIT(CAINFO, OBJECTPOINT, 65),
|
||||
|
||||
/* 66 = OBSOLETE */
|
||||
/* 67 = OBSOLETE */
|
||||
|
||||
|
||||
/* Maximum number of http redirects to follow */
|
||||
CINIT(MAXREDIRS, LONG, 68),
|
||||
|
||||
/* Pass a pointer to a time_t to get a possible date of the requested
|
||||
document! Pass a NULL to shut it off. */
|
||||
CINIT(FILETIME, OBJECTPOINT, 69),
|
||||
/* Pass a long set to 1 to get the date of the requested document (if
|
||||
possible)! Pass a zero to shut it off. */
|
||||
CINIT(FILETIME, LONG, 69),
|
||||
|
||||
/* This points to a linked list of telnet options */
|
||||
CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
|
||||
@@ -614,7 +634,7 @@ typedef enum {
|
||||
|
||||
/* Specificly switch on or off the FTP engine's use of the EPSV command. By
|
||||
default, that one will always be attempted before the more traditional
|
||||
PASV command. */
|
||||
PASV command. */
|
||||
CINIT(FTP_USE_EPSV, LONG, 85),
|
||||
|
||||
/* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
|
||||
@@ -663,7 +683,7 @@ typedef enum {
|
||||
timeouts. This option is useful for multi-threaded applications.
|
||||
See libcurl-the-guide for more background information. */
|
||||
CINIT(NOSIGNAL, LONG, 99),
|
||||
|
||||
|
||||
/* Provide a CURLShare for mutexing non-ts data */
|
||||
CINIT(SHARE, OBJECTPOINT, 100),
|
||||
|
||||
@@ -674,7 +694,7 @@ typedef enum {
|
||||
/* Set the Accept-Encoding string. Use this to tell a server you would like
|
||||
the response to be compressed. */
|
||||
CINIT(ENCODING, OBJECTPOINT, 102),
|
||||
|
||||
|
||||
/* Set pointer to private data */
|
||||
CINIT(PRIVATE, OBJECTPOINT, 103),
|
||||
|
||||
@@ -688,7 +708,7 @@ typedef enum {
|
||||
|
||||
/* Specificly switch on or off the FTP engine's use of the EPRT command ( it
|
||||
also disables the LPRT attempt). By default, those ones will always be
|
||||
attempted before the good old traditional PORT command. */
|
||||
attempted before the good old traditional PORT command. */
|
||||
CINIT(FTP_USE_EPRT, LONG, 106),
|
||||
|
||||
/* Set this to a bitmask value to enable the particular authentications
|
||||
@@ -713,7 +733,7 @@ typedef enum {
|
||||
Note that setting multiple bits may cause extra network round-trips. */
|
||||
CINIT(PROXYAUTH, LONG, 111),
|
||||
|
||||
/* FTP option that changes the timeout, in seconds, associated with
|
||||
/* FTP option that changes the timeout, in seconds, associated with
|
||||
getting a response. This is different from transfer timeout time and
|
||||
essentially places a demand on the FTP server to acknowledge commands
|
||||
in a timely manner. */
|
||||
@@ -765,6 +785,34 @@ typedef enum {
|
||||
/* Enable/disable the TCP Nagle algorithm */
|
||||
CINIT(TCP_NODELAY, LONG, 121),
|
||||
|
||||
/* When doing 3rd party transfer, set the source host name with this */
|
||||
CINIT(SOURCE_HOST, OBJECTPOINT, 122),
|
||||
|
||||
/* When doing 3rd party transfer, set the source user and password with
|
||||
this */
|
||||
CINIT(SOURCE_USERPWD, OBJECTPOINT, 123),
|
||||
|
||||
/* When doing 3rd party transfer, set the source file path with this */
|
||||
CINIT(SOURCE_PATH, OBJECTPOINT, 124),
|
||||
|
||||
/* When doing 3rd party transfer, set the source server's port number
|
||||
with this */
|
||||
CINIT(SOURCE_PORT, LONG, 125),
|
||||
|
||||
/* When doing 3rd party transfer, decide which server that should get the
|
||||
PASV command (and the other gets the PORT).
|
||||
0 (default) - The target host issues PASV.
|
||||
1 - The source host issues PASV */
|
||||
CINIT(PASV_HOST, LONG, 126),
|
||||
|
||||
/* 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),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -778,7 +826,7 @@ typedef enum {
|
||||
|
||||
/* three convenient "aliases" that follow the name scheme better */
|
||||
#define CURLOPT_WRITEDATA CURLOPT_FILE
|
||||
#define CURLOPT_READDATA CURLOPT_INFILE
|
||||
#define CURLOPT_READDATA CURLOPT_INFILE
|
||||
#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER
|
||||
|
||||
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
|
||||
@@ -792,7 +840,6 @@ typedef enum {
|
||||
|
||||
#else
|
||||
/* This is set if CURL_NO_OLDIES is defined at compile-time */
|
||||
#define curl_formparse "curl_formparse is obsolete"
|
||||
#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
|
||||
#endif
|
||||
|
||||
@@ -804,7 +851,7 @@ enum {
|
||||
for us! */
|
||||
CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */
|
||||
CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */
|
||||
|
||||
|
||||
CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
|
||||
};
|
||||
|
||||
@@ -845,23 +892,11 @@ typedef enum {
|
||||
#endif
|
||||
|
||||
|
||||
/* These functions are in libcurl, they're here for portable reasons and they
|
||||
are used by the 'curl' client. They really should be moved to some kind of
|
||||
"portability library" since it has nothing to do with file transfers and
|
||||
might be usable to other programs...
|
||||
|
||||
NOTE: they return TRUE if the strings match *case insensitively*.
|
||||
*/
|
||||
/* curl_strequal() and curl_strnequal() are subject for removal in a future
|
||||
libcurl, see lib/README.curlx for details */
|
||||
extern int (curl_strequal)(const char *s1, const char *s2);
|
||||
extern int (curl_strnequal)(const char *s1, const char *s2, size_t n);
|
||||
|
||||
#ifdef CURL_OLDSTYLE
|
||||
/* DEPRECATED function to build formdata. Stop using this, it will cease
|
||||
to exist. */
|
||||
int curl_formparse(char *, struct curl_httppost **,
|
||||
struct curl_httppost **_post);
|
||||
#endif
|
||||
|
||||
/* name is uppercase CURLFORM_<name> */
|
||||
#ifdef CFINIT
|
||||
#undef CFINIT
|
||||
@@ -876,7 +911,7 @@ int curl_formparse(char *, struct curl_httppost **,
|
||||
|
||||
typedef enum {
|
||||
CFINIT(NOTHING), /********* the first one is unused ************/
|
||||
|
||||
|
||||
/* */
|
||||
CFINIT(COPYNAME),
|
||||
CFINIT(PTRNAME),
|
||||
@@ -912,7 +947,7 @@ struct curl_forms {
|
||||
|
||||
/* use this for multipart formpost building */
|
||||
/* Returns code for curl_formadd()
|
||||
*
|
||||
*
|
||||
* Returns:
|
||||
* CURL_FORMADD_OK on success
|
||||
* CURL_FORMADD_MEMORY if the FormInfo allocation fails
|
||||
@@ -935,6 +970,7 @@ typedef enum {
|
||||
CURL_FORMADD_UNKNOWN_OPTION,
|
||||
CURL_FORMADD_INCOMPLETE,
|
||||
CURL_FORMADD_ILLEGAL_ARRAY,
|
||||
CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */
|
||||
|
||||
CURL_FORMADD_LAST /* last */
|
||||
} CURLFORMcode;
|
||||
@@ -967,7 +1003,7 @@ void curl_formfree(struct curl_httppost *form);
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Returns a malloc()'ed string that MUST be curl_free()ed after usage is
|
||||
* complete.
|
||||
* complete. DEPRECATED - see lib/README.curlx
|
||||
*/
|
||||
char *curl_getenv(const char *variable);
|
||||
|
||||
@@ -1022,6 +1058,26 @@ void curl_free(void *p);
|
||||
*/
|
||||
CURLcode curl_global_init(long flags);
|
||||
|
||||
/*
|
||||
* NAME curl_global_init_mem()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* curl_global_init() or curl_global_init_mem() should be invoked exactly once
|
||||
* for each application that uses libcurl. This function can be used to
|
||||
* initialize libcurl and set user defined memory management callback
|
||||
* functions. Users can implement memory management routines to check for
|
||||
* memory leaks, check for mis-use of the curl library etc. User registered
|
||||
* callback routines with be invoked by this library instead of the system
|
||||
* memory management routines like malloc, free etc.
|
||||
*/
|
||||
CURLcode curl_global_init_mem(long flags,
|
||||
curl_malloc_callback m,
|
||||
curl_free_callback f,
|
||||
curl_realloc_callback r,
|
||||
curl_strdup_callback s,
|
||||
curl_calloc_callback c);
|
||||
|
||||
/*
|
||||
* NAME curl_global_cleanup()
|
||||
*
|
||||
@@ -1118,7 +1174,7 @@ typedef enum {
|
||||
CURLCLOSEPOLICY_LEAST_TRAFFIC,
|
||||
CURLCLOSEPOLICY_SLOWEST,
|
||||
CURLCLOSEPOLICY_CALLBACK,
|
||||
|
||||
|
||||
CURLCLOSEPOLICY_LAST /* last, never use this */
|
||||
} curl_closepolicy;
|
||||
|
||||
@@ -1140,7 +1196,7 @@ typedef enum {
|
||||
* the locking is just made to change the internal state of the share
|
||||
* itself.
|
||||
*/
|
||||
CURL_LOCK_DATA_SHARE,
|
||||
CURL_LOCK_DATA_SHARE,
|
||||
CURL_LOCK_DATA_COOKIE,
|
||||
CURL_LOCK_DATA_DNS,
|
||||
CURL_LOCK_DATA_SSL_SESSION,
|
||||
@@ -1171,6 +1227,7 @@ typedef enum {
|
||||
CURLSHE_BAD_OPTION, /* 1 */
|
||||
CURLSHE_IN_USE, /* 2 */
|
||||
CURLSHE_INVALID, /* 3 */
|
||||
CURLSHE_NOMEM, /* out of memory */
|
||||
CURLSHE_LAST /* never use */
|
||||
} CURLSHcode;
|
||||
|
||||
@@ -1196,6 +1253,7 @@ CURLSHcode curl_share_cleanup(CURLSH *);
|
||||
typedef enum {
|
||||
CURLVERSION_FIRST,
|
||||
CURLVERSION_SECOND,
|
||||
CURLVERSION_THIRD,
|
||||
CURLVERSION_LAST /* never actually use this */
|
||||
} CURLversion;
|
||||
|
||||
@@ -1204,7 +1262,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 redfine the NOW to another enum
|
||||
from above. */
|
||||
#define CURLVERSION_NOW CURLVERSION_SECOND
|
||||
#define CURLVERSION_NOW CURLVERSION_THIRD
|
||||
|
||||
typedef struct {
|
||||
CURLversion age; /* age of the returned struct */
|
||||
@@ -1221,18 +1279,22 @@ typedef struct {
|
||||
/* The fields below this were added in CURLVERSION_SECOND */
|
||||
const char *ares;
|
||||
int ares_num;
|
||||
|
||||
/* This field was aded in CURLVERSION_THIRD */
|
||||
const char *libidn;
|
||||
} curl_version_info_data;
|
||||
|
||||
#define CURL_VERSION_IPV6 (1<<0)
|
||||
#define CURL_VERSION_KERBEROS4 (1<<1)
|
||||
#define CURL_VERSION_SSL (1<<2)
|
||||
#define CURL_VERSION_LIBZ (1<<3)
|
||||
#define CURL_VERSION_NTLM (1<<4)
|
||||
#define CURL_VERSION_GSSNEGOTIATE (1<<5)
|
||||
#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */
|
||||
#define CURL_VERSION_ASYNCHDNS (1<<7)
|
||||
#define CURL_VERSION_SPNEGO (1<<8)
|
||||
#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */
|
||||
#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */
|
||||
#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */
|
||||
#define CURL_VERSION_SSL (1<<2) /* SSL options are present */
|
||||
#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */
|
||||
#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */
|
||||
#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */
|
||||
#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */
|
||||
#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */
|
||||
#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */
|
||||
#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */
|
||||
#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */
|
||||
|
||||
/*
|
||||
* NAME curl_version_info()
|
||||
|
@@ -1,10 +1,10 @@
|
||||
#ifndef __CURL_CURLVER_H
|
||||
#define __CURL_CURLVER_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
@@ -12,7 +12,7 @@
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.11.2-CVS"
|
||||
#define LIBCURL_VERSION "7.12.1-CVS"
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -44,12 +44,12 @@
|
||||
always a greater number in a more recent release. It makes comparisons with
|
||||
greater than and less than work.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x070b02
|
||||
#define LIBCURL_VERSION_NUM 0x070c01
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 11
|
||||
#define LIBCURL_VERSION_PATCH 2
|
||||
#define LIBCURL_VERSION_MINOR 12
|
||||
#define LIBCURL_VERSION_PATCH 1
|
||||
|
||||
#endif /* __CURL_CURLVER_H */
|
||||
|
@@ -1,28 +1 @@
|
||||
#ifndef __CURL_TYPES_H
|
||||
#define __CURL_TYPES_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, 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
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
typedef void CURL;
|
||||
typedef void CURLconnect;
|
||||
|
||||
#endif /* __CURL_TYPES_H */
|
||||
/* not used */
|
||||
|
@@ -22,13 +22,18 @@
|
||||
###########################################################################
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
|
||||
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp curllib.dsw \
|
||||
config-vms.h config-win32.h config-riscos.h config-mac.h config.h.in \
|
||||
ca-bundle.crt README.encoding README.memoryleak README.ares README.curlx \
|
||||
makefile.dj config.dj libcurl.framework.make libcurl.plist libcurl.rc \
|
||||
config-amigaos.h amigaos.c amigaos.h makefile.amiga config-netware.h \
|
||||
Makefile.netware nwlib.c libcurl.imp
|
||||
DSP = curllib.dsp
|
||||
|
||||
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
|
||||
Makefile.vc6 Makefile.riscos libcurl.def $(DSP) curllib.dsw \
|
||||
config-vms.h config-win32.h config-riscos.h config-mac.h config.h.in \
|
||||
ca-bundle.crt README.encoding README.memoryleak README.ares \
|
||||
README.curlx makefile.dj config.dj libcurl.framework.make \
|
||||
libcurl.plist libcurl.rc config-amigaos.h amigaos.c amigaos.h \
|
||||
makefile.amiga config-netware.h Makefile.netware nwlib.c libcurl.imp \
|
||||
msvcproj.head msvcproj.foot
|
||||
|
||||
CLEANFILES = $(DSP)
|
||||
|
||||
lib_LTLIBRARIES = libcurl.la
|
||||
|
||||
@@ -37,7 +42,7 @@ lib_LTLIBRARIES = libcurl.la
|
||||
# we use srcdir/lib for the lib-private header files
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/lib -I$(top_srcdir)/lib
|
||||
|
||||
VERSION=-version-info 2:2:0
|
||||
VERSION=-version-info 3: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
|
||||
@@ -80,22 +85,29 @@ endif
|
||||
|
||||
libcurl_la_LDFLAGS = $(UNDEF) $(VERSION) $(MIMPURE)
|
||||
|
||||
libcurl_la_SOURCES = arpa_telnet.h file.c netrc.h timeval.c base64.c \
|
||||
file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h \
|
||||
progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.h \
|
||||
sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h dict.h \
|
||||
getdate.c if2ip.h speedcheck.h urldata.h getdate.h ldap.c ssluse.c \
|
||||
version.c getenv.c ldap.h ssluse.h escape.c mprintf.c telnet.c \
|
||||
escape.h netrc.c telnet.h getinfo.c getinfo.h transfer.c strequal.c \
|
||||
strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c \
|
||||
memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c \
|
||||
strtok.h connect.c connect.h llist.c llist.h hash.c hash.h multi.c \
|
||||
content_encoding.c content_encoding.h share.c share.h http_digest.c \
|
||||
md5.c md5.h http_digest.h http_negotiate.c http_negotiate.h \
|
||||
http_ntlm.c http_ntlm.h ca-bundle.h inet_pton.c inet_pton.h \
|
||||
strtoofft.c strtoofft.h strerror.c strerror.h
|
||||
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 \
|
||||
if2ip.h speedcheck.h urldata.h getdate.h ldap.h ssluse.h escape.h \
|
||||
telnet.h getinfo.h strequal.h security.h krb4.h memdebug.h \
|
||||
inet_ntoa_r.h http_chunks.h strtok.h connect.h llist.h hash.h \
|
||||
content_encoding.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
|
||||
|
||||
noinst_HEADERS = setup.h transfer.h
|
||||
CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
|
||||
getdate.c ldap.c ssluse.c version.c getenv.c escape.c mprintf.c \
|
||||
telnet.c netrc.c getinfo.c transfer.c strequal.c easy.c security.c \
|
||||
krb4.c memdebug.c http_chunks.c strtok.c connect.c llist.c hash.c \
|
||||
multi.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
|
||||
|
||||
libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS)
|
||||
|
||||
WIN32SOURCES = $(CSOURCES) libcurl.def
|
||||
WIN32HEADERS = $(HHEADERS) config-win32.h
|
||||
|
||||
BUILT_SOURCES = $(srcdir)/getdate.c $(top_builddir)/lib/ca-bundle.h
|
||||
|
||||
@@ -127,3 +139,26 @@ install-data-hook:
|
||||
dist-hook:
|
||||
chmod 0644 $(distdir)/ca-bundle.h
|
||||
echo "/* ca bundle path set in here*/" > $(distdir)/ca-bundle.h
|
||||
|
||||
DSPOUT = | awk '{printf("%s\r\n", $$0)}' >> $(DSP)
|
||||
|
||||
$(DSP): msvcproj.head msvcproj.foot Makefile.am
|
||||
echo "creating $(DSP)"
|
||||
@(cp msvcproj.head $(DSP); \
|
||||
echo "# Begin Group \"Source Files\"" $(DSPOUT); \
|
||||
for file in $(WIN32SOURCES); do \
|
||||
echo "# Begin Source File" $(DSPOUT); \
|
||||
echo "" $(DSPOUT); \
|
||||
echo "SOURCE=.\\"$$file $(DSPOUT); \
|
||||
echo "# End Source File" $(DSPOUT); \
|
||||
done; \
|
||||
echo "# End Group" $(DSPOUT); \
|
||||
echo "# Begin Group \"Header Files\"" $(DSPOUT); \
|
||||
for file in $(WIN32HEADERS); do \
|
||||
echo "# Begin Source File" $(DSPOUT); \
|
||||
echo "" $(DSPOUT); \
|
||||
echo "SOURCE=.\\"$$file $(DSPOUT); \
|
||||
echo "# End Source File" $(DSPOUT); \
|
||||
done; \
|
||||
echo "# End Group" $(DSPOUT); \
|
||||
cat msvcproj.foot $(DSPOUT) )
|
||||
|
@@ -47,7 +47,8 @@ libcurl_a_SOURCES = arpa_telnet.h file.c netrc.h timeval.c base64.c \
|
||||
strtok.c connect.c hash.c llist.c multi.c share.c share.h \
|
||||
content_encoding.h content_encoding.c http_digest.h http_digest.c \
|
||||
http_negotiate.c http_negotiate.h http_ntlm.c http_ntlm.h md5.h \
|
||||
md5.c strtoofft.c inet_pton.c
|
||||
md5.c strtoofft.c inet_pton.c strerror.c hostares.c hostasyn.c \
|
||||
hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c
|
||||
|
||||
libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
|
||||
formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \
|
||||
@@ -56,7 +57,8 @@ libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
|
||||
strequal.o easy.o security.o krb4.o memdebug.o http_chunks.o \
|
||||
strtok.o connect.o hash.o llist.o multi.o share.o \
|
||||
content_encoding.o http_digest.o http_negotiate.o http_ntlm.o md5.o \
|
||||
strtoofft.o inet_pton.o
|
||||
strtoofft.o inet_pton.o strerror.o hostares.o hostasyn.o hostip4.o \
|
||||
hostip6.o hostsyn.o hostthre.o inet_ntop.o
|
||||
|
||||
LIBRARIES = $(libcurl_a_LIBRARIES)
|
||||
SOURCES = $(libcurl_a_SOURCES)
|
||||
|
@@ -8,11 +8,13 @@
|
||||
#################################################################
|
||||
|
||||
# Edit the path below to point to the base of your Novell NDK.
|
||||
BASE = c:/novell
|
||||
INSTDIR = s:/libcurl
|
||||
ifndef NDKBASE
|
||||
NDKBASE = c:/novell
|
||||
endif
|
||||
INSTDIR = ..\curl-$(LIBCURL_VERSION_STR)-bin-nw
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ZLIB_PATH = ../../../cw/zlib-src-1.1.4
|
||||
#ZLIB_PATH = ../../zlib-1.2.1
|
||||
|
||||
# Edit the vars below to change NLM target settings.
|
||||
TARGET = libcurl
|
||||
@@ -22,7 +24,6 @@ DESCR = cURL libcurl $(LIBCURL_VERSION_STR) - http://curl.haxx.se
|
||||
MTSAFE = YES
|
||||
STACK = 64000
|
||||
SCREEN = none
|
||||
#MODULES = libz.nlm
|
||||
EXPORTS = @libcurl.imp
|
||||
|
||||
# Edit the var below to point to your lib architecture.
|
||||
@@ -33,6 +34,7 @@ endif
|
||||
# must be equal to DEBUG or NDEBUG
|
||||
DB = NDEBUG
|
||||
# DB = DEBUG
|
||||
# DB = CURLDEBUG
|
||||
# Optimization: -O<n> or debugging: -g
|
||||
ifeq ($(DB),NDEBUG)
|
||||
OPT = -O2
|
||||
@@ -42,7 +44,7 @@ else
|
||||
OBJDIR = debug
|
||||
endif
|
||||
|
||||
# Include the version info retrieved from jk_version.h
|
||||
# Include the version info retrieved from curlver.h
|
||||
-include $(OBJDIR)/version.inc
|
||||
|
||||
# The following line defines your compiler.
|
||||
@@ -51,36 +53,39 @@ ifdef METROWERKS
|
||||
else
|
||||
CC = gcc
|
||||
endif
|
||||
CP = cp -afv
|
||||
# RM = rm -f
|
||||
# CP = cp -fv
|
||||
# if you want to mark the target as MTSAFE you will need a tool for
|
||||
# generating the xdc data for the linker; here's a minimal tool:
|
||||
# http://www.gknw.de/development/prgtools/mkxdc.zip
|
||||
# http://www.gknw.com/development/prgtools/mkxdc.zip
|
||||
MPKXDC = mkxdc
|
||||
|
||||
# Global flags for all compilers
|
||||
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc
|
||||
#CFLAGS += -DHAVE_LIBZ
|
||||
|
||||
ifeq ($(CC),mwccnlm)
|
||||
LD = mwldnlm
|
||||
LDFLAGS = -nostdlib $(PRELUDE) $(OBJDIR)/*.o -o $(OBJDIR)/$(TARGET).nlm -commandfile
|
||||
CFLAGS += -gccinc -inline off -opt nointrinsics
|
||||
AR = mwldnlm
|
||||
ARFLAGS = -type library -w nocmdline $(OBJDIR)/*.o -o
|
||||
CFLAGS += -msgstyle gcc -gccinc -inline off -opt nointrinsics -proc 586
|
||||
CFLAGS += -relax_pointers
|
||||
#CFLAGS += -w on
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
PRELUDE = $(SDK_LIBC)/imports/libcpre.o
|
||||
CFLAGS += -align 4 -inst mmx -proc 686
|
||||
CFLAGS += -align 4
|
||||
CFLAGS += -D_POSIX_SOURCE
|
||||
# CFLAGS += -D__ANSIC__
|
||||
else
|
||||
PRELUDE = "$(METROWERKS)/Novell Support/libraries/runtime/prelude.obj"
|
||||
# CFLAGS += -include "$(METROWERKS)/Novell Support/headers/nlm_prefix.h"
|
||||
CFLAGS += -align 1 -proc 586
|
||||
CFLAGS += -align 1
|
||||
endif
|
||||
else
|
||||
LD = nlmconv
|
||||
LDFLAGS = -T
|
||||
AR = ar
|
||||
ARFLAGS = -cq
|
||||
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return
|
||||
CFLAGS += -Wall # -pedantic
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
@@ -89,40 +94,51 @@ ifeq ($(LIBARCH),LIBC)
|
||||
# CFLAGS += -D__ANSIC__
|
||||
else
|
||||
PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o
|
||||
CFLAGS += -include $(BASE)/nlmconv/genlm.h
|
||||
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
|
||||
endif
|
||||
endif
|
||||
|
||||
LDLIBS =
|
||||
|
||||
NDK_ROOT = $(BASE)/ndk
|
||||
NDK_ROOT = $(NDKBASE)/ndk
|
||||
SDK_CLIB = $(NDK_ROOT)/nwsdk
|
||||
SDK_LIBC = $(NDK_ROOT)/libc
|
||||
SDK_LDAP = $(NDK_ROOT)/cldapsdk/netware
|
||||
CURL_INC = ../include
|
||||
|
||||
INCLUDES = -I$(CURL_INC)
|
||||
INCLUDES += -I$(ZLIB_PATH)
|
||||
INCLUDES = -I. -I../include
|
||||
|
||||
ifdef ZLIB_PATH
|
||||
INCLUDES += -I$(ZLIB_PATH)
|
||||
CFLAGS += -DHAVE_ZLIB_H -DHAVE_LIBZ
|
||||
IMPORTS = @$(ZLIB_PATH)/nw/zlib.imp
|
||||
MODULES = libz.nlm
|
||||
endif
|
||||
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
INCLUDES += -I$(SDK_LIBC)/include -I$(SDK_LIBC)/include/nks
|
||||
INCLUDES += -I$(SDK_LIBC)/include/winsock
|
||||
INCLUDES += -I$(SDK_LDAP)/libc/inc
|
||||
# INCLUDES += -I$(SDK_LDAP)/libc/inc
|
||||
else
|
||||
INCLUDES += -I$(SDK_CLIB)/include/nlm -I$(SDK_CLIB)/include
|
||||
# INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete
|
||||
INCLUDES += -I$(SDK_LDAP)/clib/inc
|
||||
# INCLUDES += -I$(SDK_LDAP)/clib/inc
|
||||
CFLAGS += -DNETDB_USE_INTERNET
|
||||
endif
|
||||
CFLAGS += $(INCLUDES)
|
||||
|
||||
ifeq ($(MTSAFE),YES)
|
||||
XDCOPT = -n
|
||||
endif
|
||||
ifeq ($(MTSAFE),NO)
|
||||
XDCOPT = -u
|
||||
endif
|
||||
ifdef XDCOPT
|
||||
XDCDATA = $(OBJDIR)/$(TARGET).xdc
|
||||
endif
|
||||
|
||||
ifeq ($(OSTYPE),linux)
|
||||
DL = '
|
||||
-include $(BASE)/nlmconv/ncpfs.inc
|
||||
#-include $(NDKBASE)/nlmconv/ncpfs.inc
|
||||
endif
|
||||
|
||||
OBJS = \
|
||||
@@ -169,35 +185,57 @@ OBJS = \
|
||||
$(OBJDIR)/http_ntlm.o \
|
||||
$(OBJDIR)/md5.o \
|
||||
$(OBJDIR)/strtoofft.o \
|
||||
$(OBJDIR)/nwlib.o
|
||||
$(OBJDIR)/strerror.o \
|
||||
$(OBJDIR)/hostares.o \
|
||||
$(OBJDIR)/hostasyn.o \
|
||||
$(OBJDIR)/hostip4.o \
|
||||
$(OBJDIR)/hostip6.o \
|
||||
$(OBJDIR)/hostsyn.o \
|
||||
$(OBJDIR)/hostthre.o \
|
||||
$(OBJDIR)/inet_ntop.o \
|
||||
|
||||
OBJL = $(OBJS) $(OBJDIR)/nwlib.o
|
||||
|
||||
all: $(OBJDIR) $(OBJDIR)/version.inc $(OBJDIR)/$(TARGET).nlm
|
||||
nlm: $(OBJDIR) $(OBJDIR)/version.inc $(OBJDIR)/$(TARGET).nlm
|
||||
|
||||
lib: $(OBJDIR) $(OBJDIR)/$(TARGET).lib
|
||||
|
||||
all: lib nlm
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
@echo Compiling $<
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
# @echo Compiling $<
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJDIR)/version.inc: $(CURL_INC)/curl/curl.h $(OBJDIR)
|
||||
$(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
|
||||
-$(RM) $(OBJDIR)/$(TARGET).def $(OBJDIR)/version.inc $(XDCDATA)
|
||||
# -$(CP) ../changes.txt $(OBJDIR)/
|
||||
|
||||
install: all
|
||||
@[ -d $(INSTDIR) ] || mkdir $(INSTDIR)
|
||||
install: $(INSTDIR) all
|
||||
@$(CP) $(TARGET).nlm $(INSTDIR)
|
||||
@$(CP) ../CHANGES $(INSTDIR)
|
||||
@$(CP) ../COPYING $(INSTDIR)
|
||||
@$(CP) ../README $(INSTDIR)
|
||||
@$(CP) ../RELEASE-NOTES $(INSTDIR)
|
||||
|
||||
clean:
|
||||
-$(RM) -r $(OBJDIR)
|
||||
|
||||
$(INSTDIR):
|
||||
@mkdir $(INSTDIR)
|
||||
|
||||
$(OBJDIR):
|
||||
@mkdir $(OBJDIR)
|
||||
|
||||
$(OBJDIR)/$(TARGET).nlm: $(OBJS) $(OBJDIR)/$(TARGET).def $(XDCDATA)
|
||||
$(OBJDIR)/$(TARGET).lib: $(OBJS)
|
||||
@echo Creating $@
|
||||
@-$(RM) $@
|
||||
@$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
$(OBJDIR)/$(TARGET).nlm: $(OBJL) $(OBJDIR)/$(TARGET).def $(XDCDATA)
|
||||
@echo Linking $@
|
||||
@-$(RM) $@
|
||||
@$(LD) $(LDFLAGS) $(OBJDIR)/$(TARGET).def
|
||||
@@ -239,25 +277,21 @@ ifeq ($(LIBARCH),CLIB)
|
||||
@echo $(DL)import @$(SDK_CLIB)/imports/threads.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_CLIB)/imports/nlmlib.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_CLIB)/imports/socklib.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@
|
||||
# @echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@
|
||||
# @echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@
|
||||
# @echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@
|
||||
@echo $(DL)module clib$(DL) >> $@
|
||||
else
|
||||
ifeq ($(LD),nlmconv)
|
||||
@echo $(DL)flag_on 64$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)autounload$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)pseudopreemption$(DL) >> $@
|
||||
@echo $(DL)start _LibCPrelude$(DL) >> $@
|
||||
@echo $(DL)exit _LibCPostlude$(DL) >> $@
|
||||
@echo $(DL)check _LibCCheckUnload$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LIBC)/imports/libc.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LIBC)/imports/netware.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@
|
||||
# @echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@
|
||||
# @echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@
|
||||
# @echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@
|
||||
@echo $(DL)module libc$(DL) >> $@
|
||||
endif
|
||||
ifdef MODULES
|
||||
@@ -275,3 +309,18 @@ ifeq ($(LD),nlmconv)
|
||||
@echo $(DL)output $(TARGET).nlm$(DL) >> $@
|
||||
endif
|
||||
|
||||
ca-bundle.h: 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) >> $@
|
||||
@echo $(DL)#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")$(DL) >> $@
|
||||
|
||||
getdate.c: getdate.c.cvs
|
||||
@echo Creating $@
|
||||
@-$(RM) getdate.y
|
||||
@$(CP) $< $@
|
||||
|
||||
url.c: ca-bundle.h
|
||||
|
||||
|
||||
|
@@ -21,16 +21,6 @@
|
||||
#
|
||||
# $Id: Makefile.vc6,v 1.17 2004/01/13 08:57:01 bagder Exp $
|
||||
##############################################################
|
||||
# CHANGE LOG
|
||||
# ------------------------------------------------------------
|
||||
# 05.11.2001 John Lask Initial Release
|
||||
# 02.05.2002 Miklos Nemeth OPENSSL_PATH environment; no need
|
||||
# for OpenSSL libraries when creating a
|
||||
# static libcurl.lib
|
||||
# 10.14.2003 Added a target release-libcurl-ssl-dll which
|
||||
# is intended to allow static linking of libcurl with dynamic
|
||||
# linking of openssl
|
||||
##############################################################
|
||||
|
||||
LIB_NAME = libcurl
|
||||
LIB_NAME_DEBUG = libcurld
|
||||
@@ -42,6 +32,10 @@ OPENSSL_PATH = ../../openssl-0.9.7a
|
||||
ZLIB_PATH = ../../zlib-1.1.4
|
||||
!ENDIF
|
||||
|
||||
# Use the high resolution time by default. Comment this out to use low
|
||||
# resolution time and not require winmm.lib
|
||||
USEMM_LIBS = YES
|
||||
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
@@ -49,12 +43,17 @@ CCNODBG = cl.exe /MD /O2 /D "NDEBUG"
|
||||
CCDEBUG = cl.exe /MDd /Od /Gm /Zi /D "_DEBUG" /GZ
|
||||
CFLAGSSSL = /D "USE_SSLEAY" /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSZLIB = /D "HAVE_ZLIB_H" /D "HAVE_ZLIB" /D "HAVE_LIBZ" /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I "." /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /D "_LIB" /YX /FD /c /D "MSDOS"
|
||||
|
||||
CFLAGS = /I "." /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /D "_LIB" /YX /FD /c /D "MSDOS"
|
||||
LNKDLL = link.exe /DLL /def:libcurl.def
|
||||
LNKLIB = link.exe /lib
|
||||
LFLAGS = /nologo
|
||||
SSLLIBS = libeay32.lib ssleay32.lib
|
||||
!IFDEF USEMM_LIBS
|
||||
WINLIBS = wsock32.lib winmm.lib
|
||||
!ELSE
|
||||
WINLIBS = wsock32.lib
|
||||
CFLAGS = $(CFLAGS) /D "WITHOUT_MM_LIB"
|
||||
!ENDIF
|
||||
# RSAglue.lib was formerly needed in the SSLLIBS
|
||||
CFGSET = FALSE
|
||||
|
||||
@@ -69,6 +68,18 @@ CC = $(CCNODBG)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET =$(LIB_NAME).lib
|
||||
DIROBJ =.\$(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSZLIB) /out:$(TARGET)
|
||||
CC = $(CCNODBG) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
@@ -100,7 +111,7 @@ CFGSET = TRUE
|
||||
TARGET =$(LIB_NAME).dll
|
||||
DIROBJ =.\$(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32dll"
|
||||
LNK = $(LNKDLL) $(LFLAGSSSL) /out:$(TARGET) /IMPLIB:"$(LIB_NAME).lib"
|
||||
LNK = $(LNKDLL) $(SSLLIBS) $(WINLIBS) $(LFLAGSSSL) /out:$(TARGET) /IMPLIB:"$(LIB_NAME).lib"
|
||||
CC = $(CCNODBG) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
@@ -108,7 +119,6 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
||||
|
||||
######################
|
||||
# release-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-zlib"
|
||||
TARGET =$(LIB_NAME).lib
|
||||
DIROBJ =.\$(CFG)
|
||||
@@ -125,7 +135,7 @@ CFGSET = TRUE
|
||||
TARGET =$(LIB_NAME).lib
|
||||
DIROBJ =.\$(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32dll"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(TARGET)
|
||||
LNK = $(LNKLIB) $(SSLLIBS) $(LFLAGSSSL) /out:$(TARGET)
|
||||
CC = $(CCNODBG) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
@@ -166,6 +176,17 @@ CC = $(CCDEBUG) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib
|
||||
!IF "$(CFG)" == "debug-zlib"
|
||||
TARGET = $(LIB_NAME_DEBUG).lib
|
||||
DIROBJ =.\$(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSZLIB) /out:$(TARGET)
|
||||
CC = $(CCDEBUG) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
@@ -187,12 +208,14 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-dll - release dll
|
||||
!MESSAGE release-zlib - release static library with zlib
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||
!MESSAGE release-ssl-dll - release dll library with ssl
|
||||
!MESSAGE release-libcurl-ssl-dll - static libcurl with shared ssl
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-dll - debug dll
|
||||
!MESSAGE debug-zlib - debug static library with zlib
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-ssl-dll - debug dll library with ssl
|
||||
!MESSAGE <target> can be left blank in which case all is assumed
|
||||
@@ -217,6 +240,13 @@ X_OBJS= \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\hostares.obj \
|
||||
$(DIROBJ)\hostthre.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\inet_ntop.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
|
@@ -13,9 +13,8 @@ part of the official libcurl API, but the source files might be useful for
|
||||
others so apps can optionally compile/build with these sources to gain
|
||||
additional functions.
|
||||
|
||||
|
||||
strtoofft.[ch]
|
||||
==============
|
||||
We provide them through a single header file for easy access for apps:
|
||||
"curlx.h"
|
||||
|
||||
curlx_strtoofft()
|
||||
|
||||
@@ -25,14 +24,6 @@ strtoofft.[ch]
|
||||
strtoll() (or equivalent) function exist on your platform. If curl_off_t
|
||||
is only a 32 bit number on your platform, this macro uses strtol().
|
||||
|
||||
timeval.[ch]
|
||||
============
|
||||
|
||||
Provides a 'struct timeval' for platforms that don't have one already, and
|
||||
includes the proper include files for those that have one. Using this will
|
||||
make the output require the 'winmm' lib on Windows (unless WITHOUT_MM_LIB
|
||||
is defined at compile-time).
|
||||
|
||||
curlx_tvnow()
|
||||
|
||||
returns a struct timeval for the current time.
|
||||
@@ -41,3 +32,31 @@ timeval.[ch]
|
||||
|
||||
returns the difference between two timeval structs, in number of
|
||||
milliseconds.
|
||||
|
||||
curlx_tvdiff_secs()
|
||||
|
||||
returns the same as curlx_tvdiff but with full usec resolution (as a
|
||||
double)
|
||||
|
||||
FUTURE
|
||||
======
|
||||
|
||||
Several functions will be removed from the public curl_ name space in a
|
||||
future libcurl release. They will then only become available as curlx_
|
||||
functions instead. To make the transition easier, we already today provide
|
||||
these functions with the curlx_ prefix to allow sources to get built properly
|
||||
with the new function names. The functions this concerns are:
|
||||
|
||||
curlx_getenv
|
||||
curlx_strequal
|
||||
curlx_strnequal
|
||||
curlx_mvsnprintf
|
||||
curlx_msnprintf
|
||||
curlx_maprintf
|
||||
curlx_mvaprintf
|
||||
curlx_msprintf
|
||||
curlx_mprintf
|
||||
curlx_mfprintf
|
||||
curlx_mvsprintf
|
||||
curlx_mvprintf
|
||||
curlx_mvfprintf
|
||||
|
@@ -41,10 +41,11 @@
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "base64.h"
|
||||
#include "memory.h"
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
/* include memdebug.h last */
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
|
||||
static void decodeQuantum(unsigned char *dest, const char *src)
|
||||
{
|
||||
@@ -131,6 +132,8 @@ size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
|
||||
|
||||
char *indata = (char *)inp;
|
||||
|
||||
*outptr = NULL; /* set to NULL in case of failure before we reach the end */
|
||||
|
||||
if(0 == insize)
|
||||
insize = strlen(indata);
|
||||
|
||||
|
@@ -1,485 +1,484 @@
|
||||
/* lib/config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* to disable DICT */
|
||||
#undef CURL_DISABLE_DICT
|
||||
|
||||
/* to disable FILE */
|
||||
#undef CURL_DISABLE_FILE
|
||||
|
||||
/* to disable FTP */
|
||||
#undef CURL_DISABLE_FTP
|
||||
|
||||
/* to disable GOPHER */
|
||||
#undef CURL_DISABLE_GOPHER
|
||||
|
||||
/* to disable HTTP */
|
||||
#undef CURL_DISABLE_HTTP
|
||||
|
||||
/* to disable LDAP */
|
||||
#undef CURL_DISABLE_LDAP
|
||||
|
||||
/* to disable TELNET */
|
||||
#undef CURL_DISABLE_TELNET
|
||||
|
||||
/* Set to explicitly specify we don't want to use thread-safe functions */
|
||||
#undef DISABLED_THREADSAFE
|
||||
|
||||
/* your Entropy Gathering Daemon socket pathname */
|
||||
#undef EGD_SOCKET
|
||||
|
||||
/* Define if you want to enable IPv6 support */
|
||||
#undef ENABLE_IPV6
|
||||
|
||||
/* Define to 1 if you have the <alloca.h> header file. */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
|
||||
/* Define to 1 if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define to 1 if you have the `closesocket' function. */
|
||||
#undef HAVE_CLOSESOCKET
|
||||
|
||||
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
|
||||
#undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
||||
|
||||
/* Define to 1 if you have the <crypto.h> header file. */
|
||||
#undef HAVE_CRYPTO_H
|
||||
|
||||
/* Define to 1 if you have the <des.h> header file. */
|
||||
#undef HAVE_DES_H
|
||||
|
||||
/* disabled non-blocking sockets */
|
||||
#undef HAVE_DISABLED_NONBLOCKING
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
/* XXX: #undef HAVE_DLFCN_H */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the `dlopen' function. */
|
||||
#define HAVE_DLOPEN 1
|
||||
|
||||
/* Define to 1 if you have the <err.h> header file. */
|
||||
#define HAVE_ERR_H 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* use FIONBIO for non-blocking sockets */
|
||||
/* XXX: #undef HAVE_FIONBIO */
|
||||
#define HAVE_FIONBIO 1
|
||||
|
||||
/* Define if getaddrinfo exists and works */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
||||
/* Define to 1 if you have the `geteuid' function. */
|
||||
#undef HAVE_GETEUID
|
||||
|
||||
/* Define to 1 if you have the `gethostbyaddr' function. */
|
||||
#define HAVE_GETHOSTBYADDR 1
|
||||
|
||||
/* Define to 1 if you have the `gethostbyaddr_r' function. */
|
||||
#undef HAVE_GETHOSTBYADDR_R
|
||||
|
||||
/* gethostbyaddr_r() takes 5 args */
|
||||
#undef HAVE_GETHOSTBYADDR_R_5
|
||||
|
||||
/* gethostbyaddr_r() takes 7 args */
|
||||
#undef HAVE_GETHOSTBYADDR_R_7
|
||||
|
||||
/* gethostbyaddr_r() takes 8 args */
|
||||
#undef HAVE_GETHOSTBYADDR_R_8
|
||||
|
||||
/* Define to 1 if you have the `gethostbyname_r' function. */
|
||||
#undef HAVE_GETHOSTBYNAME_R
|
||||
|
||||
/* gethostbyname_r() takes 3 args */
|
||||
#undef HAVE_GETHOSTBYNAME_R_3
|
||||
|
||||
/* gethostbyname_r() takes 5 args */
|
||||
#undef HAVE_GETHOSTBYNAME_R_5
|
||||
|
||||
/* gethostbyname_r() takes 6 args */
|
||||
#undef HAVE_GETHOSTBYNAME_R_6
|
||||
|
||||
/* Define to 1 if you have the `getpass_r' function. */
|
||||
#undef HAVE_GETPASS_R
|
||||
|
||||
/* Define to 1 if you have the `getpwuid' function. */
|
||||
#undef HAVE_GETPWUID
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define to 1 if you have the `gmtime_r' function. */
|
||||
#undef HAVE_GMTIME_R
|
||||
|
||||
/* if you have the gssapi libraries */
|
||||
#undef HAVE_GSSAPI
|
||||
|
||||
/* if you have the Heimdal gssapi libraries */
|
||||
#undef HAVE_GSSHEIMDAL
|
||||
|
||||
/* if you have the MIT gssapi libraries */
|
||||
#undef HAVE_GSSMIT
|
||||
|
||||
/* Define to 1 if you have the `inet_addr' function. */
|
||||
#define HAVE_INET_ADDR 1
|
||||
|
||||
/* Define to 1 if you have the `inet_ntoa' function. */
|
||||
#define HAVE_INET_NTOA 1
|
||||
|
||||
/* Define to 1 if you have the `inet_ntoa_r' function. */
|
||||
#undef HAVE_INET_NTOA_R
|
||||
|
||||
/* inet_ntoa_r() is declared */
|
||||
#undef HAVE_INET_NTOA_R_DECL
|
||||
|
||||
/* Define to 1 if you have the `inet_pton' function. */
|
||||
#define HAVE_INET_PTON 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* use ioctlsocket() for non-blocking sockets */
|
||||
#undef HAVE_IOCTLSOCKET
|
||||
|
||||
/* use Ioctlsocket() for non-blocking sockets */
|
||||
#undef HAVE_IOCTLSOCKET_CASE
|
||||
|
||||
/* Define to 1 if you have the <io.h> header file. */
|
||||
#undef HAVE_IO_H
|
||||
|
||||
/* if you have the Kerberos4 libraries (including -ldes) */
|
||||
#undef HAVE_KRB4
|
||||
|
||||
/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
|
||||
#undef HAVE_KRB_GET_OUR_IP_FOR_REALM
|
||||
|
||||
/* Define to 1 if you have the <krb.h> header file. */
|
||||
#undef HAVE_KRB_H
|
||||
|
||||
/* Define to 1 if you have the `crypto' library (-lcrypto). */
|
||||
#undef HAVE_LIBCRYPTO
|
||||
|
||||
/* Define to 1 if you have the `dl' library (-ldl). */
|
||||
#undef HAVE_LIBDL
|
||||
|
||||
/* Define to 1 if you have the `nsl' library (-lnsl). */
|
||||
#undef HAVE_LIBNSL
|
||||
|
||||
/* Define to 1 if you have the `resolv' library (-lresolv). */
|
||||
#undef HAVE_LIBRESOLV
|
||||
|
||||
/* Define to 1 if you have the `resolve' library (-lresolve). */
|
||||
#undef HAVE_LIBRESOLVE
|
||||
|
||||
/* Define to 1 if you have the `socket' library (-lsocket). */
|
||||
#undef HAVE_LIBSOCKET
|
||||
|
||||
/* Define to 1 if you have the `ssl' library (-lssl). */
|
||||
#undef HAVE_LIBSSL
|
||||
|
||||
/* If zlib is available */
|
||||
#undef HAVE_LIBZ
|
||||
//#define HAVE_LIBZ 1
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if you have the `localtime_r' function. */
|
||||
#undef HAVE_LOCALTIME_R
|
||||
|
||||
/* if your compiler supports 'long long' */
|
||||
#define HAVE_LONGLONG 1
|
||||
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
#define HAVE_MALLOC_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#define HAVE_NETDB_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Define to 1 if you have the <net/if.h> header file. */
|
||||
#undef HAVE_NET_IF_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/crypto.h> header file. */
|
||||
#undef HAVE_OPENSSL_CRYPTO_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/engine.h> header file. */
|
||||
#undef HAVE_OPENSSL_ENGINE_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/err.h> header file. */
|
||||
#undef HAVE_OPENSSL_ERR_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/pem.h> header file. */
|
||||
#undef HAVE_OPENSSL_PEM_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/rsa.h> header file. */
|
||||
#undef HAVE_OPENSSL_RSA_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/ssl.h> header file. */
|
||||
#undef HAVE_OPENSSL_SSL_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/x509.h> header file. */
|
||||
#undef HAVE_OPENSSL_X509_H
|
||||
|
||||
/* use O_NONBLOCK for non-blocking sockets */
|
||||
#undef HAVE_O_NONBLOCK
|
||||
|
||||
/* Define to 1 if you have the <pem.h> header file. */
|
||||
#undef HAVE_PEM_H
|
||||
|
||||
/* Define to 1 if you have the `perror' function. */
|
||||
#undef HAVE_PERROR
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#undef HAVE_PWD_H
|
||||
|
||||
/* Define to 1 if you have the `RAND_egd' function. */
|
||||
#undef HAVE_RAND_EGD
|
||||
|
||||
/* Define to 1 if you have the `RAND_screen' function. */
|
||||
#undef HAVE_RAND_SCREEN
|
||||
|
||||
/* Define to 1 if you have the `RAND_status' function. */
|
||||
#undef HAVE_RAND_STATUS
|
||||
|
||||
/* Define to 1 if you have the <rsa.h> header file. */
|
||||
#undef HAVE_RSA_H
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Define to 1 if you have the <setjmp.h> header file. */
|
||||
#define HAVE_SETJMP_H 1
|
||||
|
||||
/* Define to 1 if you have the <sgtty.h> header file. */
|
||||
#undef HAVE_SGTTY_H
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#undef HAVE_SIGACTION
|
||||
|
||||
/* Define to 1 if you have the `siginterrupt' function. */
|
||||
#undef HAVE_SIGINTERRUPT
|
||||
|
||||
/* Define to 1 if you have the `signal' function. */
|
||||
#define HAVE_SIGNAL 1
|
||||
|
||||
/* If you have sigsetjmp */
|
||||
#undef HAVE_SIGSETJMP
|
||||
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* use SO_NONBLOCK for non-blocking sockets */
|
||||
#undef HAVE_SO_NONBLOCK
|
||||
|
||||
/* Define this if you have the SPNEGO library fbopenssl */
|
||||
#undef HAVE_SPNEGO
|
||||
|
||||
/* Define to 1 if you have the <ssl.h> header file. */
|
||||
#undef HAVE_SSL_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strcmpi' function. */
|
||||
#undef HAVE_STRCMPI
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define to 1 if you have the `stricmp' function. */
|
||||
#undef HAVE_STRICMP
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strlcat' function. */
|
||||
#define HAVE_STRLCAT 1
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#define HAVE_STRLCPY 1
|
||||
|
||||
/* Define to 1 if you have the `strstr' function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define to 1 if you have the `strtok_r' function. */
|
||||
#undef HAVE_STRTOK_R
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#undef HAVE_STRTOLL
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/poll.h> header file. */
|
||||
#undef HAVE_SYS_POLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
||||
#define HAVE_SYS_SOCKIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/utime.h> header file. */
|
||||
#undef HAVE_SYS_UTIME_H
|
||||
|
||||
/* Define to 1 if you have the `tcgetattr' function. */
|
||||
#undef HAVE_TCGETATTR
|
||||
|
||||
/* Define to 1 if you have the `tcsetattr' function. */
|
||||
#undef HAVE_TCSETATTR
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#define HAVE_TERMIOS_H 1
|
||||
|
||||
/* Define to 1 if you have the <termio.h> header file. */
|
||||
#undef HAVE_TERMIO_H
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the `uname' function. */
|
||||
#define HAVE_UNAME 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `utime' function. */
|
||||
#undef HAVE_UTIME
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#undef HAVE_UTIME_H
|
||||
|
||||
/* Define to 1 if you have the <winsock.h> header file. */
|
||||
#undef HAVE_WINSOCK_H
|
||||
|
||||
/* Define this symbol if your OS supports changing the contents of argv */
|
||||
#undef HAVE_WRITABLE_ARGV
|
||||
|
||||
/* Define to 1 if you have the <x509.h> header file. */
|
||||
#undef HAVE_X509_H
|
||||
|
||||
/* if you have the zlib.h header file */
|
||||
#define HAVE_ZLIB_H 1
|
||||
|
||||
/* need REENTRANT defined */
|
||||
#undef NEED_REENTRANT
|
||||
|
||||
/* cpu-machine-OS */
|
||||
#define OS "i386-pc-NetWare"
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* a suitable file to read random data from */
|
||||
#undef RANDOM_FILE
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to the type of arg 1 for `select'. */
|
||||
#undef SELECT_TYPE_ARG1
|
||||
|
||||
/* Define to the type of args 2, 3 and 4 for `select'. */
|
||||
#undef SELECT_TYPE_ARG234
|
||||
|
||||
/* Define to the type of arg 5 for `select'. */
|
||||
#undef SELECT_TYPE_ARG5
|
||||
|
||||
/* The size of a `curl_off_t', as computed by sizeof. */
|
||||
#define SIZEOF_CURL_OFF_T 4
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
/* XXX: #undef STDC_HEADERS */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Define if you want to enable ares support */
|
||||
#undef USE_ARES
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to 1 if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* type to use in place of in_addr_t if not defined */
|
||||
#undef in_addr_t
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* type to use in place of socklen_t if not defined */
|
||||
#define socklen_t int
|
||||
|
||||
/* the signed version of size_t */
|
||||
#undef ssize_t
|
||||
|
||||
|
||||
/* lib/config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* to disable DICT */
|
||||
#undef CURL_DISABLE_DICT
|
||||
|
||||
/* to disable FILE */
|
||||
#undef CURL_DISABLE_FILE
|
||||
|
||||
/* to disable FTP */
|
||||
#undef CURL_DISABLE_FTP
|
||||
|
||||
/* to disable GOPHER */
|
||||
#undef CURL_DISABLE_GOPHER
|
||||
|
||||
/* to disable HTTP */
|
||||
#undef CURL_DISABLE_HTTP
|
||||
|
||||
/* to disable LDAP */
|
||||
#undef CURL_DISABLE_LDAP
|
||||
|
||||
/* to disable TELNET */
|
||||
#undef CURL_DISABLE_TELNET
|
||||
|
||||
/* Set to explicitly specify we don't want to use thread-safe functions */
|
||||
#undef DISABLED_THREADSAFE
|
||||
|
||||
/* your Entropy Gathering Daemon socket pathname */
|
||||
#undef EGD_SOCKET
|
||||
|
||||
/* Define if you want to enable IPv6 support */
|
||||
#undef ENABLE_IPV6
|
||||
|
||||
/* Define to 1 if you have the <alloca.h> header file. */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
|
||||
/* Define to 1 if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define to 1 if you have the `closesocket' function. */
|
||||
#undef HAVE_CLOSESOCKET
|
||||
|
||||
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
|
||||
#undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
||||
|
||||
/* Define to 1 if you have the <crypto.h> header file. */
|
||||
#undef HAVE_CRYPTO_H
|
||||
|
||||
/* Define to 1 if you have the <des.h> header file. */
|
||||
#undef HAVE_DES_H
|
||||
|
||||
/* disabled non-blocking sockets */
|
||||
#undef HAVE_DISABLED_NONBLOCKING
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
/* XXX: #undef HAVE_DLFCN_H */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the `dlopen' function. */
|
||||
#define HAVE_DLOPEN 1
|
||||
|
||||
/* Define to 1 if you have the <err.h> header file. */
|
||||
#define HAVE_ERR_H 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* use FIONBIO for non-blocking sockets */
|
||||
/* XXX: #undef HAVE_FIONBIO */
|
||||
#define HAVE_FIONBIO 1
|
||||
|
||||
/* Define if getaddrinfo exists and works */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
||||
/* Define to 1 if you have the `geteuid' function. */
|
||||
#undef HAVE_GETEUID
|
||||
|
||||
/* Define to 1 if you have the `gethostbyaddr' function. */
|
||||
#define HAVE_GETHOSTBYADDR 1
|
||||
|
||||
/* Define to 1 if you have the `gethostbyaddr_r' function. */
|
||||
#undef HAVE_GETHOSTBYADDR_R
|
||||
|
||||
/* gethostbyaddr_r() takes 5 args */
|
||||
#undef HAVE_GETHOSTBYADDR_R_5
|
||||
|
||||
/* gethostbyaddr_r() takes 7 args */
|
||||
#undef HAVE_GETHOSTBYADDR_R_7
|
||||
|
||||
/* gethostbyaddr_r() takes 8 args */
|
||||
#undef HAVE_GETHOSTBYADDR_R_8
|
||||
|
||||
/* Define to 1 if you have the `gethostbyname_r' function. */
|
||||
#undef HAVE_GETHOSTBYNAME_R
|
||||
|
||||
/* gethostbyname_r() takes 3 args */
|
||||
#undef HAVE_GETHOSTBYNAME_R_3
|
||||
|
||||
/* gethostbyname_r() takes 5 args */
|
||||
#undef HAVE_GETHOSTBYNAME_R_5
|
||||
|
||||
/* gethostbyname_r() takes 6 args */
|
||||
#undef HAVE_GETHOSTBYNAME_R_6
|
||||
|
||||
/* Define to 1 if you have the `getpass_r' function. */
|
||||
#undef HAVE_GETPASS_R
|
||||
|
||||
/* Define to 1 if you have the `getpwuid' function. */
|
||||
#undef HAVE_GETPWUID
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define to 1 if you have the `gmtime_r' function. */
|
||||
#undef HAVE_GMTIME_R
|
||||
|
||||
/* if you have the gssapi libraries */
|
||||
#undef HAVE_GSSAPI
|
||||
|
||||
/* if you have the Heimdal gssapi libraries */
|
||||
#undef HAVE_GSSHEIMDAL
|
||||
|
||||
/* if you have the MIT gssapi libraries */
|
||||
#undef HAVE_GSSMIT
|
||||
|
||||
/* Define to 1 if you have the `inet_addr' function. */
|
||||
#define HAVE_INET_ADDR 1
|
||||
|
||||
/* Define to 1 if you have the `inet_ntoa' function. */
|
||||
#define HAVE_INET_NTOA 1
|
||||
|
||||
/* Define to 1 if you have the `inet_ntoa_r' function. */
|
||||
#undef HAVE_INET_NTOA_R
|
||||
|
||||
/* inet_ntoa_r() is declared */
|
||||
#undef HAVE_INET_NTOA_R_DECL
|
||||
|
||||
/* Define to 1 if you have the `inet_pton' function. */
|
||||
#define HAVE_INET_PTON 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* use ioctlsocket() for non-blocking sockets */
|
||||
#undef HAVE_IOCTLSOCKET
|
||||
|
||||
/* use Ioctlsocket() for non-blocking sockets */
|
||||
#undef HAVE_IOCTLSOCKET_CASE
|
||||
|
||||
/* Define to 1 if you have the <io.h> header file. */
|
||||
#undef HAVE_IO_H
|
||||
|
||||
/* if you have the Kerberos4 libraries (including -ldes) */
|
||||
#undef HAVE_KRB4
|
||||
|
||||
/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
|
||||
#undef HAVE_KRB_GET_OUR_IP_FOR_REALM
|
||||
|
||||
/* Define to 1 if you have the <krb.h> header file. */
|
||||
#undef HAVE_KRB_H
|
||||
|
||||
/* Define to 1 if you have the `crypto' library (-lcrypto). */
|
||||
#undef HAVE_LIBCRYPTO
|
||||
|
||||
/* Define to 1 if you have the `dl' library (-ldl). */
|
||||
#undef HAVE_LIBDL
|
||||
|
||||
/* Define to 1 if you have the `nsl' library (-lnsl). */
|
||||
#undef HAVE_LIBNSL
|
||||
|
||||
/* Define to 1 if you have the `resolv' library (-lresolv). */
|
||||
#undef HAVE_LIBRESOLV
|
||||
|
||||
/* Define to 1 if you have the `resolve' library (-lresolve). */
|
||||
#undef HAVE_LIBRESOLVE
|
||||
|
||||
/* Define to 1 if you have the `socket' library (-lsocket). */
|
||||
#undef HAVE_LIBSOCKET
|
||||
|
||||
/* Define to 1 if you have the `ssl' library (-lssl). */
|
||||
#undef HAVE_LIBSSL
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if you have the `localtime_r' function. */
|
||||
#undef HAVE_LOCALTIME_R
|
||||
|
||||
/* if your compiler supports 'long long' */
|
||||
#define HAVE_LONGLONG 1
|
||||
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
#define HAVE_MALLOC_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#define HAVE_NETDB_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Define to 1 if you have the <net/if.h> header file. */
|
||||
#undef HAVE_NET_IF_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/crypto.h> header file. */
|
||||
#undef HAVE_OPENSSL_CRYPTO_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/engine.h> header file. */
|
||||
#undef HAVE_OPENSSL_ENGINE_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/err.h> header file. */
|
||||
#undef HAVE_OPENSSL_ERR_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/pem.h> header file. */
|
||||
#undef HAVE_OPENSSL_PEM_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/rsa.h> header file. */
|
||||
#undef HAVE_OPENSSL_RSA_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/ssl.h> header file. */
|
||||
#undef HAVE_OPENSSL_SSL_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/x509.h> header file. */
|
||||
#undef HAVE_OPENSSL_X509_H
|
||||
|
||||
/* use O_NONBLOCK for non-blocking sockets */
|
||||
#undef HAVE_O_NONBLOCK
|
||||
|
||||
/* Define to 1 if you have the <pem.h> header file. */
|
||||
#undef HAVE_PEM_H
|
||||
|
||||
/* Define to 1 if you have the `perror' function. */
|
||||
#undef HAVE_PERROR
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#undef HAVE_PWD_H
|
||||
|
||||
/* Define to 1 if you have the `RAND_egd' function. */
|
||||
#undef HAVE_RAND_EGD
|
||||
|
||||
/* Define to 1 if you have the `RAND_screen' function. */
|
||||
#undef HAVE_RAND_SCREEN
|
||||
|
||||
/* Define to 1 if you have the `RAND_status' function. */
|
||||
#undef HAVE_RAND_STATUS
|
||||
|
||||
/* Define to 1 if you have the <rsa.h> header file. */
|
||||
#undef HAVE_RSA_H
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Define to 1 if you have the <setjmp.h> header file. */
|
||||
#define HAVE_SETJMP_H 1
|
||||
|
||||
/* Define to 1 if you have the <sgtty.h> header file. */
|
||||
#undef HAVE_SGTTY_H
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#undef HAVE_SIGACTION
|
||||
|
||||
/* Define to 1 if you have the `siginterrupt' function. */
|
||||
#undef HAVE_SIGINTERRUPT
|
||||
|
||||
/* Define to 1 if you have the `signal' function. */
|
||||
#define HAVE_SIGNAL 1
|
||||
|
||||
/* If you have sigsetjmp */
|
||||
#undef HAVE_SIGSETJMP
|
||||
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* use SO_NONBLOCK for non-blocking sockets */
|
||||
#undef HAVE_SO_NONBLOCK
|
||||
|
||||
/* Define this if you have the SPNEGO library fbopenssl */
|
||||
#undef HAVE_SPNEGO
|
||||
|
||||
/* Define to 1 if you have the <ssl.h> header file. */
|
||||
#undef HAVE_SSL_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strcmpi' function. */
|
||||
#undef HAVE_STRCMPI
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define to 1 if you have the `stricmp' function. */
|
||||
#undef HAVE_STRICMP
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strlcat' function. */
|
||||
#define HAVE_STRLCAT 1
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#define HAVE_STRLCPY 1
|
||||
|
||||
/* Define to 1 if you have the `strstr' function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define to 1 if you have the `strtok_r' function. */
|
||||
#undef HAVE_STRTOK_R
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#undef HAVE_STRTOLL
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/poll.h> header file. */
|
||||
#undef HAVE_SYS_POLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
||||
#define HAVE_SYS_SOCKIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/utime.h> header file. */
|
||||
#undef HAVE_SYS_UTIME_H
|
||||
|
||||
/* Define to 1 if you have the `tcgetattr' function. */
|
||||
#undef HAVE_TCGETATTR
|
||||
|
||||
/* Define to 1 if you have the `tcsetattr' function. */
|
||||
#undef HAVE_TCSETATTR
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#define HAVE_TERMIOS_H 1
|
||||
|
||||
/* Define to 1 if you have the <termio.h> header file. */
|
||||
#undef HAVE_TERMIO_H
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the `uname' function. */
|
||||
#define HAVE_UNAME 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `utime' function. */
|
||||
#undef HAVE_UTIME
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#undef HAVE_UTIME_H
|
||||
|
||||
/* Define to 1 if you have the <winsock.h> header file. */
|
||||
#undef HAVE_WINSOCK_H
|
||||
|
||||
/* Define this symbol if your OS supports changing the contents of argv */
|
||||
#undef HAVE_WRITABLE_ARGV
|
||||
|
||||
/* Define to 1 if you have the <x509.h> header file. */
|
||||
#undef HAVE_X509_H
|
||||
|
||||
/* if you have the zlib.h header file - set from Makefile */
|
||||
/* #undef HAVE_ZLIB_H */
|
||||
|
||||
/* If zlib is available - set from Makefile */
|
||||
/* #undef HAVE_LIBZ */
|
||||
|
||||
/* need REENTRANT defined */
|
||||
#undef NEED_REENTRANT
|
||||
|
||||
/* cpu-machine-OS */
|
||||
#define OS "i586-pc-NetWare"
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* a suitable file to read random data from */
|
||||
#undef RANDOM_FILE
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to the type of arg 1 for `select'. */
|
||||
#undef SELECT_TYPE_ARG1
|
||||
|
||||
/* Define to the type of args 2, 3 and 4 for `select'. */
|
||||
#undef SELECT_TYPE_ARG234
|
||||
|
||||
/* Define to the type of arg 5 for `select'. */
|
||||
#undef SELECT_TYPE_ARG5
|
||||
|
||||
/* The size of a `curl_off_t', as computed by sizeof. */
|
||||
#define SIZEOF_CURL_OFF_T 4
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
/* XXX: #undef STDC_HEADERS */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Define if you want to enable ares support */
|
||||
#undef USE_ARES
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to 1 if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* type to use in place of in_addr_t if not defined */
|
||||
#undef in_addr_t
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* type to use in place of socklen_t if not defined */
|
||||
#define socklen_t int
|
||||
|
||||
/* the signed version of size_t */
|
||||
#undef ssize_t
|
||||
|
||||
|
||||
|
@@ -1,6 +1,9 @@
|
||||
/* config.h. Generated automatically by configure. */
|
||||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
#ifndef __CONFIG_WIN32_H
|
||||
#define __CONFIG_WIN32_H
|
||||
|
||||
/* Define if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
@@ -223,9 +226,12 @@
|
||||
/*************************************************
|
||||
* This section is for compiler specific defines.*
|
||||
*************************************************/
|
||||
#if defined(MINGW32) || defined(__WATCOMC__) /* Borland and MS don't have this */
|
||||
/* Borland and MS don't have this */
|
||||
#if defined(MINGW32) || defined(__WATCOMC__) || defined(__LCC__)
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
251
lib/connect.c
251
lib/connect.c
@@ -1,8 +1,8 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
@@ -10,7 +10,7 @@
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
@@ -96,14 +96,17 @@
|
||||
#include "if2ip.h"
|
||||
#include "strerror.h"
|
||||
#include "connect.h"
|
||||
#include "memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
static bool verifyconnect(curl_socket_t sockfd);
|
||||
static bool verifyconnect(curl_socket_t sockfd, int *error);
|
||||
|
||||
/*
|
||||
* Curl_ourerrno() returns the errno (or equivalent) on this platform to
|
||||
* hide platform specific for the function that calls this.
|
||||
*/
|
||||
int Curl_ourerrno(void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
@@ -113,13 +116,11 @@ int Curl_ourerrno(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Curl_nonblock
|
||||
*
|
||||
* Description:
|
||||
* Set the socket to either blocking or non-blocking mode.
|
||||
/*
|
||||
* Curl_nonblock() set the given socket to either blocking or non-blocking
|
||||
* mode based on the 'nonblock' boolean argument. This function is highly
|
||||
* portable.
|
||||
*/
|
||||
|
||||
int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
|
||||
int nonblock /* TRUE or FALSE */)
|
||||
{
|
||||
@@ -177,12 +178,19 @@ int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
|
||||
}
|
||||
|
||||
/*
|
||||
* waitconnect() returns:
|
||||
* waitconnect() waits for a TCP connect on the given socket for the specified
|
||||
* number if milliseconds. It returns:
|
||||
* 0 fine connect
|
||||
* -1 select() error
|
||||
* 1 select() timeout
|
||||
* 2 select() returned with an error condition
|
||||
* 2 select() returned with an error condition fd_set
|
||||
*/
|
||||
|
||||
#define WAITCONN_CONNECTED 0
|
||||
#define WAITCONN_SELECT_ERROR -1
|
||||
#define WAITCONN_TIMEOUT 1
|
||||
#define WAITCONN_FDSET_ERROR 2
|
||||
|
||||
static
|
||||
int waitconnect(curl_socket_t sockfd, /* socket */
|
||||
long timeout_msec)
|
||||
@@ -195,7 +203,7 @@ int waitconnect(curl_socket_t sockfd, /* socket */
|
||||
/* Call this function once now, and ignore the results. We do this to
|
||||
"clear" the error state on the socket so that we can later read it
|
||||
reliably. This is reported necessary on the MPE/iX operating system. */
|
||||
verifyconnect(sockfd);
|
||||
verifyconnect(sockfd, NULL);
|
||||
#endif
|
||||
|
||||
/* now select() until we get connect or timeout */
|
||||
@@ -213,18 +221,18 @@ int waitconnect(curl_socket_t sockfd, /* socket */
|
||||
rc = select(sockfd+1, NULL, &fd, &errfd, &interval);
|
||||
if(-1 == rc)
|
||||
/* error, no connect here, try next */
|
||||
return -1;
|
||||
|
||||
return WAITCONN_SELECT_ERROR;
|
||||
|
||||
else if(0 == rc)
|
||||
/* timeout, no connect today */
|
||||
return 1;
|
||||
return WAITCONN_TIMEOUT;
|
||||
|
||||
if(FD_ISSET(sockfd, &errfd))
|
||||
/* error condition caught */
|
||||
return 2;
|
||||
return WAITCONN_FDSET_ERROR;
|
||||
|
||||
/* we have a connect! */
|
||||
return 0;
|
||||
return WAITCONN_CONNECTED;
|
||||
}
|
||||
|
||||
static CURLcode bindlocal(struct connectdata *conn,
|
||||
@@ -247,14 +255,14 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
|
||||
/* First check if the given name is an IP address */
|
||||
in=inet_addr(data->set.device);
|
||||
|
||||
|
||||
if((in == CURL_INADDR_NONE) &&
|
||||
Curl_if2ip(data->set.device, myhost, sizeof(myhost))) {
|
||||
/*
|
||||
* We now have the numerical IPv4-style x.y.z.w in the 'myhost' buffer
|
||||
*/
|
||||
rc = Curl_resolv(conn, myhost, 0, &h);
|
||||
if(rc == 1)
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
(void)Curl_wait_for_resolv(conn, &h);
|
||||
|
||||
if(h)
|
||||
@@ -267,7 +275,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
* or IP number
|
||||
*/
|
||||
rc = Curl_resolv(conn, data->set.device, 0, &h);
|
||||
if(rc == 1)
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
(void)Curl_wait_for_resolv(conn, &h);
|
||||
|
||||
if(h)
|
||||
@@ -328,7 +336,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
struct sockaddr_in6 add;
|
||||
|
||||
bindworked = TRUE;
|
||||
|
||||
|
||||
size = sizeof(add);
|
||||
if(getsockname(sockfd, (struct sockaddr *) &add,
|
||||
(socklen_t *)&size)<0) {
|
||||
@@ -345,13 +353,13 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr.s_addr = in;
|
||||
sa.sin_port = 0; /* get any port */
|
||||
|
||||
|
||||
if( bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) >= 0) {
|
||||
/* we succeeded to bind */
|
||||
struct sockaddr_in add;
|
||||
|
||||
|
||||
bindworked = TRUE;
|
||||
|
||||
|
||||
size = sizeof(add);
|
||||
if(getsockname(sockfd, (struct sockaddr *) &add,
|
||||
(socklen_t *)&size)<0) {
|
||||
@@ -365,7 +373,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
failf(data, "%s", Curl_strerror(conn, Curl_ourerrno()));
|
||||
return CURLE_HTTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
|
||||
} /* end of if h */
|
||||
else {
|
||||
failf(data,"could't find my own IP address (%s)", myhost);
|
||||
@@ -389,25 +397,50 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
/*
|
||||
* verifyconnect() returns TRUE if the connect really has happened.
|
||||
*/
|
||||
static bool verifyconnect(curl_socket_t sockfd)
|
||||
static bool verifyconnect(curl_socket_t sockfd, int *error)
|
||||
{
|
||||
#if defined(SO_ERROR) && !defined(WIN32)
|
||||
bool rc = TRUE;
|
||||
#ifdef SO_ERROR
|
||||
int err = 0;
|
||||
socklen_t errSize = sizeof(err);
|
||||
|
||||
#ifdef WIN32
|
||||
/*
|
||||
* In October 2003 we effectively nullified this function on Windows due to
|
||||
* problems with it using all CPU in multi-threaded cases.
|
||||
*
|
||||
* In May 2004, we bring it back to offer more info back on connect failures.
|
||||
* Gisle Vanem could reproduce the former problems with this function, but
|
||||
* could avoid them by adding this SleepEx() call below:
|
||||
*
|
||||
* "I don't have Rational Quantify, but the hint from his post was
|
||||
* ntdll::NtRemoveIoCompletion(). So I'd assume the SleepEx (or maybe
|
||||
* just Sleep(0) would be enough?) would release whatever
|
||||
* mutex/critical-section the ntdll call is waiting on.
|
||||
*
|
||||
* Someone got to verify this on Win-NT 4.0, 2000."
|
||||
*/
|
||||
SleepEx(0, FALSE);
|
||||
#endif
|
||||
|
||||
if( -1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
|
||||
(void *)&err, &errSize))
|
||||
err = Curl_ourerrno();
|
||||
|
||||
if ((0 == err) || (EISCONN == err))
|
||||
/* we are connected, awesome! */
|
||||
return TRUE;
|
||||
|
||||
/* This wasn't a successful connect */
|
||||
return FALSE;
|
||||
rc = TRUE;
|
||||
else
|
||||
/* This wasn't a successful connect */
|
||||
rc = FALSE;
|
||||
if (error)
|
||||
*error = err;
|
||||
#else
|
||||
(void)sockfd;
|
||||
return TRUE;
|
||||
if (error)
|
||||
*error = Curl_ourerrno();
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -434,7 +467,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
if(data->set.timeout && data->set.connecttimeout) {
|
||||
if (data->set.timeout < data->set.connecttimeout)
|
||||
has_passed -= data->set.timeout*1000;
|
||||
else
|
||||
else
|
||||
has_passed -= data->set.connecttimeout*1000;
|
||||
}
|
||||
else if(data->set.timeout)
|
||||
@@ -457,8 +490,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
/* check for connect without timeout as we want to return immediately */
|
||||
rc = waitconnect(sockfd, 0);
|
||||
|
||||
if(0 == rc) {
|
||||
if (verifyconnect(sockfd)) {
|
||||
if(WAITCONN_CONNECTED == rc) {
|
||||
if (verifyconnect(sockfd, NULL)) {
|
||||
/* we are connected, awesome! */
|
||||
*connected = TRUE;
|
||||
return CURLE_OK;
|
||||
@@ -467,25 +500,22 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
failf(data, "Connection failed");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
else if(1 != rc) {
|
||||
else if(WAITCONN_TIMEOUT != rc) {
|
||||
int error = Curl_ourerrno();
|
||||
failf(data, "Failed connect to %s:%d; %s",
|
||||
conn->hostname, conn->port, Curl_strerror(conn,error));
|
||||
conn->host.name, conn->port, Curl_strerror(conn,error));
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
/*
|
||||
* If the connection phase is "done" here, we should attempt to connect
|
||||
* to the "next address" in the Curl_hostaddr structure that we resolved
|
||||
* before. But we don't have that struct around anymore and we can't just
|
||||
* keep a pointer since the cache might in fact have gotten pruned by the
|
||||
* time we want to read this... Alas, we don't do this yet.
|
||||
* If the connection failed here, we should attempt to connect to the "next
|
||||
* address" for the given host.
|
||||
*/
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void Curl_setNoDelay(struct connectdata *conn,
|
||||
curl_socket_t sockfd)
|
||||
static void tcpnodelay(struct connectdata *conn,
|
||||
curl_socket_t sockfd)
|
||||
{
|
||||
#ifdef TCP_NODELAY
|
||||
struct SessionHandle *data= conn->data;
|
||||
@@ -516,22 +546,22 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
bool *connected) /* really connected? */
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
int rc;
|
||||
curl_socket_t sockfd= CURL_SOCKET_BAD;
|
||||
int aliasindex=0;
|
||||
char *hostname;
|
||||
curl_socket_t sockfd = CURL_SOCKET_BAD;
|
||||
int rc, error;
|
||||
int aliasindex;
|
||||
int num_addr;
|
||||
bool conected;
|
||||
char addr_buf[256];
|
||||
|
||||
Curl_ipconnect *curr_addr;
|
||||
struct timeval after;
|
||||
struct timeval before = Curl_tvnow();
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
struct addrinfo *ai;
|
||||
#endif
|
||||
|
||||
/*************************************************************
|
||||
* Figure out what maximum time we have left
|
||||
*************************************************************/
|
||||
long timeout_ms=300000; /* milliseconds, default to five minutes */
|
||||
long timeout_ms=300000; /* milliseconds, default to five minutes total */
|
||||
long timeout_per_addr;
|
||||
|
||||
*connected = FALSE; /* default to not connected */
|
||||
|
||||
@@ -549,7 +579,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
if(data->set.timeout && data->set.connecttimeout) {
|
||||
if (data->set.timeout < data->set.connecttimeout)
|
||||
timeout_ms = data->set.timeout*1000;
|
||||
else
|
||||
else
|
||||
timeout_ms = data->set.connecttimeout*1000;
|
||||
}
|
||||
else if(data->set.timeout)
|
||||
@@ -567,31 +597,35 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
}
|
||||
}
|
||||
|
||||
hostname = data->change.proxy?conn->proxyhost:conn->hostname;
|
||||
infof(data, "About to connect() to %s port %d\n",
|
||||
hostname, port);
|
||||
/* Max time for each address */
|
||||
num_addr = Curl_num_addresses(remotehost->addr);
|
||||
timeout_per_addr = timeout_ms / num_addr;
|
||||
|
||||
/* Below is the loop that attempts to connect to all IP-addresses we
|
||||
* know for the given host. One by one until one IP succeedes.
|
||||
*/
|
||||
#ifdef ENABLE_IPV6
|
||||
/*
|
||||
* Connecting with a getaddrinfo chain
|
||||
*/
|
||||
for (ai = remotehost->addr; ai; ai = ai->ai_next, aliasindex++) {
|
||||
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (sockfd == CURL_SOCKET_BAD)
|
||||
(void)port; /* the port number is already included in the getaddrinfo
|
||||
struct */
|
||||
for (curr_addr = remotehost->addr, aliasindex=0; curr_addr;
|
||||
curr_addr = curr_addr->ai_next, aliasindex++) {
|
||||
sockfd = socket(curr_addr->ai_family, curr_addr->ai_socktype,
|
||||
curr_addr->ai_protocol);
|
||||
if (sockfd == CURL_SOCKET_BAD) {
|
||||
timeout_per_addr += timeout_per_addr / (num_addr - aliasindex);
|
||||
continue;
|
||||
}
|
||||
|
||||
else if(data->set.tcp_nodelay)
|
||||
Curl_setNoDelay(conn, sockfd);
|
||||
#else
|
||||
/*
|
||||
* Connecting with old style IPv4-only support
|
||||
*/
|
||||
|
||||
/* This is the loop that attempts to connect to all IP-addresses we
|
||||
know for the given host. One by one. */
|
||||
for(rc=-1, aliasindex=0;
|
||||
rc && (struct in_addr *)remotehost->addr->h_addr_list[aliasindex];
|
||||
aliasindex++) {
|
||||
curr_addr = (Curl_ipconnect*)remotehost->addr->h_addr_list[0];
|
||||
for(aliasindex=0; curr_addr;
|
||||
curr_addr=(Curl_ipconnect*)remotehost->addr->h_addr_list[++aliasindex]) {
|
||||
struct sockaddr_in serv_addr;
|
||||
|
||||
/* create an IPv4 TCP socket */
|
||||
@@ -601,18 +635,21 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
return CURLE_COULDNT_CONNECT; /* big time error */
|
||||
}
|
||||
|
||||
else if(data->set.tcp_nodelay)
|
||||
Curl_setNoDelay(conn, sockfd);
|
||||
|
||||
/* nasty address work before connect can be made */
|
||||
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
|
||||
memcpy((char *)&(serv_addr.sin_addr),
|
||||
(struct in_addr *)remotehost->addr->h_addr_list[aliasindex],
|
||||
memcpy((char *)&(serv_addr.sin_addr), curr_addr,
|
||||
sizeof(struct in_addr));
|
||||
serv_addr.sin_family = remotehost->addr->h_addrtype;
|
||||
serv_addr.sin_port = htons((unsigned short)port);
|
||||
#endif
|
||||
|
||||
|
||||
Curl_printable_address(curr_addr, addr_buf, sizeof(addr_buf));
|
||||
infof(data, " Trying %s... ", addr_buf);
|
||||
|
||||
if(data->set.tcp_nodelay)
|
||||
tcpnodelay(conn, sockfd);
|
||||
|
||||
if(conn->data->set.device) {
|
||||
/* user selected to bind the outgoing socket to a specified "device"
|
||||
before doing connect */
|
||||
@@ -628,13 +665,13 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
a defined macro on some platforms and some compilers don't like to mix
|
||||
#ifdefs with macro usage! (AmigaOS is one such platform) */
|
||||
#ifdef ENABLE_IPV6
|
||||
rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
|
||||
rc = connect(sockfd, curr_addr->ai_addr, curr_addr->ai_addrlen);
|
||||
#else
|
||||
rc = connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
|
||||
#endif
|
||||
|
||||
if(-1 == rc) {
|
||||
int error=Curl_ourerrno();
|
||||
error = Curl_ourerrno();
|
||||
|
||||
switch (error) {
|
||||
case EINPROGRESS:
|
||||
@@ -649,40 +686,43 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
/* asynchronous connect, wait for connect or timeout */
|
||||
if(data->state.used_interface == Curl_if_multi)
|
||||
/* don't hang when doing multi */
|
||||
timeout_ms = 0;
|
||||
|
||||
rc = waitconnect(sockfd, timeout_ms);
|
||||
timeout_per_addr = timeout_ms = 0;
|
||||
|
||||
rc = waitconnect(sockfd, timeout_per_addr);
|
||||
break;
|
||||
default:
|
||||
/* unknown error, fallthrough and try another address! */
|
||||
failf(data, "Failed to connect to %s IP number %d: %s",
|
||||
hostname, aliasindex+1, Curl_strerror(conn,error));
|
||||
failf(data, "Failed to connect to %s (IP number %d): %s",
|
||||
addr_buf, aliasindex+1, Curl_strerror(conn,error));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The '1 == rc' comes from the waitconnect(), and not from connect().
|
||||
We can be sure of this since connect() cannot return 1. */
|
||||
if((1 == rc) && (data->state.used_interface == Curl_if_multi)) {
|
||||
/* The 'WAITCONN_TIMEOUT == rc' comes from the waitconnect(), and not from
|
||||
connect(). We can be sure of this since connect() cannot return 1. */
|
||||
if((WAITCONN_TIMEOUT == rc) &&
|
||||
(data->state.used_interface == Curl_if_multi)) {
|
||||
/* Timeout when running the multi interface, we return here with a
|
||||
CURLE_OK return code. */
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(0 == rc) {
|
||||
if (verifyconnect(sockfd)) {
|
||||
/* we are connected, awesome! */
|
||||
*connected = TRUE; /* this is a true connect */
|
||||
break;
|
||||
}
|
||||
/* nope, not connected for real */
|
||||
rc = -1;
|
||||
|
||||
conected = verifyconnect(sockfd, &error);
|
||||
|
||||
if(!rc && conected) {
|
||||
/* we are connected, awesome! */
|
||||
*connected = TRUE; /* this is a true connect */
|
||||
break;
|
||||
}
|
||||
if(WAITCONN_TIMEOUT == rc)
|
||||
infof(data, "Timeout\n");
|
||||
else
|
||||
infof(data, "%s\n", Curl_strerror(conn, error));
|
||||
|
||||
/* connect failed or timed out */
|
||||
sclose(sockfd);
|
||||
sockfd = -1;
|
||||
sockfd = CURL_SOCKET_BAD;
|
||||
|
||||
/* get a new timeout for next attempt */
|
||||
after = Curl_tvnow();
|
||||
@@ -692,24 +732,19 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
return CURLE_OPERATION_TIMEOUTED;
|
||||
}
|
||||
before = after;
|
||||
}
|
||||
} /* end of connect-to-each-address loop */
|
||||
|
||||
if (sockfd == CURL_SOCKET_BAD) {
|
||||
/* no good connect was made */
|
||||
*sockconn = -1;
|
||||
failf(data, "Connect failed; %s", Curl_strerror(conn,Curl_ourerrno()));
|
||||
*sockconn = CURL_SOCKET_BAD;
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* leave the socket in non-blocking mode */
|
||||
|
||||
/* store the address we use */
|
||||
if(addr) {
|
||||
#ifdef ENABLE_IPV6
|
||||
*addr = ai;
|
||||
#else
|
||||
*addr = (struct in_addr *)remotehost->addr->h_addr_list[aliasindex];
|
||||
#endif
|
||||
}
|
||||
if(addr)
|
||||
*addr = curr_addr;
|
||||
|
||||
/* allow NULL-pointers to get passed in */
|
||||
if(sockconn)
|
||||
|
@@ -30,9 +30,11 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include "sendf.h"
|
||||
#include "content_encoding.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include "memdebug.h"
|
||||
|
||||
#define DSIZ 0x10000 /* buffer size for decompressed data */
|
||||
|
||||
@@ -82,7 +84,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data,
|
||||
if (!k->zlib_init) {
|
||||
z->zalloc = (alloc_func)Z_NULL;
|
||||
z->zfree = (free_func)Z_NULL;
|
||||
z->opaque = 0; /* of dubious use 08/27/02 jhrg */
|
||||
z->opaque = 0;
|
||||
z->next_in = NULL;
|
||||
z->avail_in = 0;
|
||||
if (inflateInit(z) != Z_OK)
|
||||
@@ -226,7 +228,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data,
|
||||
if (!k->zlib_init) {
|
||||
z->zalloc = (alloc_func)Z_NULL;
|
||||
z->zfree = (free_func)Z_NULL;
|
||||
z->opaque = 0; /* of dubious use 08/27/02 jhrg */
|
||||
z->opaque = 0;
|
||||
z->next_in = NULL;
|
||||
z->avail_in = 0;
|
||||
if (inflateInit2(z, -MAX_WBITS) != Z_OK)
|
||||
@@ -235,10 +237,11 @@ Curl_unencode_gzip_write(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
/* This next mess is to get around the potential case where there isn't
|
||||
enough data passed in to skip over the gzip header. If that happens,
|
||||
we malloc a block and copy what we have then wait for the next call. If
|
||||
there still isn't enough (this is definitely a worst-case scenario), we
|
||||
make the block bigger, copy the next part in and keep waiting. */
|
||||
* enough data passed in to skip over the gzip header. If that happens, we
|
||||
* malloc a block and copy what we have then wait for the next call. If
|
||||
* there still isn't enough (this is definitely a worst-case scenario), we
|
||||
* make the block bigger, copy the next part in and keep waiting.
|
||||
*/
|
||||
|
||||
/* Skip over gzip header? */
|
||||
if (k->zlib_init == 1) {
|
||||
@@ -253,12 +256,13 @@ Curl_unencode_gzip_write(struct SessionHandle *data,
|
||||
break;
|
||||
|
||||
case GZIP_UNDERFLOW:
|
||||
/* We need more data so we can find the end of the gzip header.
|
||||
It's possible that the memory block we malloc here will never be
|
||||
freed if the transfer abruptly aborts after this point. Since it's
|
||||
unlikely that circumstances will be right for this code path to be
|
||||
followed in the first place, and it's even more unlikely for a transfer
|
||||
to fail immediately afterwards, it should seldom be a problem. */
|
||||
/* We need more data so we can find the end of the gzip header. It's
|
||||
* possible that the memory block we malloc here will never be freed if
|
||||
* the transfer abruptly aborts after this point. Since it's unlikely
|
||||
* that circumstances will be right for this code path to be followed in
|
||||
* the first place, and it's even more unlikely for a transfer to fail
|
||||
* immediately afterwards, it should seldom be a problem.
|
||||
*/
|
||||
z->avail_in = nread;
|
||||
z->next_in = malloc(z->avail_in);
|
||||
if (z->next_in == NULL) {
|
||||
@@ -321,8 +325,8 @@ Curl_unencode_gzip_write(struct SessionHandle *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* because the buffer size is fixed, iteratively decompress
|
||||
and transfer to the client via client_write. */
|
||||
/* because the buffer size is fixed, iteratively decompress and transfer to
|
||||
the client via client_write. */
|
||||
for (;;) {
|
||||
/* (re)set buffer for decompressed output for every iteration */
|
||||
z->next_out = (Bytef *)&decomp[0];
|
||||
|
192
lib/cookie.c
192
lib/cookie.c
@@ -1,8 +1,8 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
@@ -10,7 +10,7 @@
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
@@ -28,7 +28,7 @@ RECEIVING COOKIE INFORMATION
|
||||
============================
|
||||
|
||||
struct CookieInfo *cookie_init(char *file);
|
||||
|
||||
|
||||
Inits a cookie struct to store data in a local file. This is always
|
||||
called before any cookies are set.
|
||||
|
||||
@@ -58,9 +58,9 @@ struct Cookies *cookie_getlist(struct CookieInfo *cookie,
|
||||
|
||||
It shall only return cookies that haven't expired.
|
||||
|
||||
|
||||
|
||||
Example set of cookies:
|
||||
|
||||
|
||||
Set-cookie: PRODUCTINFO=webxpress; domain=.fidelity.com; path=/; secure
|
||||
Set-cookie: PERSONALIZE=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
|
||||
domain=.fidelity.com; path=/ftgw; secure
|
||||
@@ -92,15 +92,17 @@ Example set of cookies:
|
||||
#include "strequal.h"
|
||||
#include "strtok.h"
|
||||
#include "sendf.h"
|
||||
#include "memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
static void
|
||||
free_cookiemess(struct Cookie *co)
|
||||
static void freecookie(struct Cookie *co)
|
||||
{
|
||||
if(co->expirestr)
|
||||
free(co->expirestr);
|
||||
if(co->domain)
|
||||
free(co->domain);
|
||||
if(co->path)
|
||||
@@ -137,7 +139,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
/* The 'data' pointer here may be NULL at times, and thus
|
||||
must only be used very carefully for things that can deal
|
||||
with data being NULL. Such as infof() and similar */
|
||||
|
||||
|
||||
struct CookieInfo *c,
|
||||
bool httpheader, /* TRUE if HTTP header-style line */
|
||||
char *lineptr, /* first character of the line */
|
||||
@@ -147,7 +149,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
unless set */
|
||||
{
|
||||
struct Cookie *clist;
|
||||
char what[MAX_COOKIE_LINE];
|
||||
char *what;
|
||||
char name[MAX_NAME];
|
||||
char *ptr;
|
||||
char *semiptr;
|
||||
@@ -165,6 +167,13 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
if(httpheader) {
|
||||
/* This line was read off a HTTP-header */
|
||||
char *sep;
|
||||
|
||||
what = malloc(MAX_COOKIE_LINE);
|
||||
if(!what) {
|
||||
free(co);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
semiptr=strchr(lineptr, ';'); /* first, find a semicolon */
|
||||
|
||||
while(*lineptr && isspace((int)*lineptr))
|
||||
@@ -203,6 +212,10 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
|
||||
if(strequal("path", name)) {
|
||||
co->path=strdup(whatptr);
|
||||
if(!co->path) {
|
||||
badcookie = TRUE; /* out of memory bad */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(strequal("domain", name)) {
|
||||
/* note that this name may or may not have a preceeding dot, but
|
||||
@@ -243,7 +256,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
but it seems that these kinds of cookies are in use "out there"
|
||||
so we cannot be that strict. I've therefore lowered the check
|
||||
to not allow less than two dots. */
|
||||
|
||||
|
||||
if(dotcount < 2) {
|
||||
/* Received and skipped a cookie with a domain using too few
|
||||
dots. */
|
||||
@@ -255,11 +268,19 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
/* Now, we make sure that our host is within the given domain,
|
||||
or the given domain is not valid and thus cannot be set. */
|
||||
|
||||
if('.' == whatptr[0])
|
||||
whatptr++; /* ignore preceeding dot */
|
||||
|
||||
if(!domain || tailmatch(whatptr, domain)) {
|
||||
const char *tailptr=whatptr;
|
||||
if(tailptr[0] == '.')
|
||||
tailptr++;
|
||||
co->domain=strdup(tailptr); /* don't prefix w/dots internally */
|
||||
co->domain=strdup(tailptr); /* don't prefix w/dots
|
||||
internally */
|
||||
if(!co->domain) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
co->tailmatch=TRUE; /* we always do that if the domain name was
|
||||
given */
|
||||
}
|
||||
@@ -275,6 +296,10 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
}
|
||||
else if(strequal("version", name)) {
|
||||
co->version=strdup(whatptr);
|
||||
if(!co->version) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(strequal("max-age", name)) {
|
||||
/* Defined in RFC2109:
|
||||
@@ -287,16 +312,28 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
|
||||
*/
|
||||
co->maxage = strdup(whatptr);
|
||||
if(!co->maxage) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
co->expires =
|
||||
atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + now;
|
||||
}
|
||||
else if(strequal("expires", name)) {
|
||||
co->expirestr=strdup(whatptr);
|
||||
if(!co->expirestr) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
co->expires = curl_getdate(what, &now);
|
||||
}
|
||||
else if(!co->name) {
|
||||
co->name = strdup(name);
|
||||
co->value = strdup(whatptr);
|
||||
if(!co->name || !co->value) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
else this is the second (or more) name we don't know
|
||||
@@ -333,28 +370,17 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
semiptr=strchr(ptr, '\0');
|
||||
} while(semiptr);
|
||||
|
||||
if(badcookie || (NULL == co->name)) {
|
||||
/* we didn't get a cookie name or a bad one,
|
||||
this is an illegal line, bail out */
|
||||
if(co->expirestr)
|
||||
free(co->expirestr);
|
||||
if(co->domain)
|
||||
free(co->domain);
|
||||
if(co->path)
|
||||
free(co->path);
|
||||
if(co->name)
|
||||
free(co->name);
|
||||
if(co->value)
|
||||
free(co->value);
|
||||
free(co);
|
||||
return NULL;
|
||||
if(!badcookie && !co->domain) {
|
||||
if(domain) {
|
||||
/* no domain was given in the header line, set the default */
|
||||
co->domain=strdup(domain);
|
||||
if(!co->domain)
|
||||
badcookie = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(NULL == co->domain)
|
||||
/* no domain was given in the header line, set the default now */
|
||||
co->domain=domain?strdup(domain):NULL;
|
||||
if((NULL == co->path) && path) {
|
||||
/* no path was given in the header line, set the default now */
|
||||
if(!badcookie && !co->path && path) {
|
||||
/* no path was given in the header line, set the default */
|
||||
char *endslash = strrchr(path, '/');
|
||||
if(endslash) {
|
||||
size_t pathlen = endslash-path+1; /* include the ending slash */
|
||||
@@ -363,8 +389,20 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
memcpy(co->path, path, pathlen);
|
||||
co->path[pathlen]=0; /* zero terminate */
|
||||
}
|
||||
else
|
||||
badcookie = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
free(what);
|
||||
|
||||
if(badcookie || !co->name) {
|
||||
/* we didn't get a cookie name or a bad one,
|
||||
this is an illegal line, bail out */
|
||||
freecookie(co);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* This line is NOT a HTTP header style line, we do offer support for
|
||||
@@ -386,7 +424,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
if(ptr)
|
||||
*ptr=0; /* clear it */
|
||||
|
||||
firstptr=strtok_r(lineptr, "\t", &tok_buf); /* first tokenize it on the TAB */
|
||||
firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */
|
||||
|
||||
/* Here's a quick check to eliminate normal HTTP-headers from this */
|
||||
if(!firstptr || strchr(firstptr, ':')) {
|
||||
@@ -396,13 +434,15 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
|
||||
/* Now loop through the fields and init the struct we already have
|
||||
allocated */
|
||||
for(ptr=firstptr, fields=0; ptr;
|
||||
for(ptr=firstptr, fields=0; ptr && !badcookie;
|
||||
ptr=strtok_r(NULL, "\t", &tok_buf), fields++) {
|
||||
switch(fields) {
|
||||
case 0:
|
||||
if(ptr[0]=='.') /* skip preceeding dots */
|
||||
ptr++;
|
||||
co->domain = strdup(ptr);
|
||||
if(!co->domain)
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
case 1:
|
||||
/* This field got its explanation on the 23rd of May 2001 by
|
||||
@@ -424,10 +464,14 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
if (strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) {
|
||||
/* only if the path doesn't look like a boolean option! */
|
||||
co->path = strdup(ptr);
|
||||
if(!co->path)
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
/* this doesn't look like a path, make one up! */
|
||||
co->path = strdup("/");
|
||||
if(!co->path)
|
||||
badcookie = TRUE;
|
||||
fields++; /* add a field and fall down to secure */
|
||||
/* FALLTHROUGH */
|
||||
case 3:
|
||||
@@ -438,29 +482,40 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
break;
|
||||
case 5:
|
||||
co->name = strdup(ptr);
|
||||
if(!co->name)
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
case 6:
|
||||
co->value = strdup(ptr);
|
||||
if(!co->value)
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(6 == fields) {
|
||||
/* we got a cookie with blank contents, fix it */
|
||||
co->value = strdup("");
|
||||
if(!co->value)
|
||||
badcookie = TRUE;
|
||||
else
|
||||
fields++;
|
||||
}
|
||||
else if(7 != fields) {
|
||||
/* we did not find the sufficient number of fields to recognize this
|
||||
as a valid line, abort and go home */
|
||||
free_cookiemess(co);
|
||||
|
||||
if(!badcookie && (7 != fields))
|
||||
/* we did not find the sufficient number of fields */
|
||||
badcookie = TRUE;
|
||||
|
||||
if(badcookie) {
|
||||
freecookie(co);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!c->running && /* read from a file */
|
||||
c->newsession && /* clean session cookies */
|
||||
!co->expires) { /* this is a session cookie since it doesn't expire! */
|
||||
free_cookiemess(co);
|
||||
freecookie(co);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -498,7 +553,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
replace_old = TRUE;
|
||||
else
|
||||
replace_old = FALSE;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(replace_old && !co->livecookie && clist->livecookie) {
|
||||
@@ -508,16 +563,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
live cookies stay alive */
|
||||
|
||||
/* Free the newcomer and get out of here! */
|
||||
if(co->domain)
|
||||
free(co->domain);
|
||||
if(co->path)
|
||||
free(co->path);
|
||||
if(co->name)
|
||||
free(co->name);
|
||||
if(co->value)
|
||||
free(co->value);
|
||||
|
||||
free(co);
|
||||
freecookie(co);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -596,7 +642,7 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
struct CookieInfo *c;
|
||||
FILE *fp;
|
||||
bool fromfile=TRUE;
|
||||
|
||||
|
||||
if(NULL == inc) {
|
||||
/* we didn't get a struct, create one */
|
||||
c = (struct CookieInfo *)malloc(sizeof(struct CookieInfo));
|
||||
@@ -678,14 +724,14 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
continue if we are! */
|
||||
if( (co->expires<=0 || (co->expires> now)) &&
|
||||
(co->secure?secure:TRUE) ) {
|
||||
|
||||
|
||||
/* now check if the domain is correct */
|
||||
if(!co->domain ||
|
||||
(co->tailmatch && tailmatch(co->domain, host)) ||
|
||||
(!co->tailmatch && strequal(host, co->domain)) ) {
|
||||
/* the right part of the host matches the domain stuff in the
|
||||
cookie data */
|
||||
|
||||
|
||||
/* now check the left part of the path with the cookies path
|
||||
requirement */
|
||||
if(!co->path ||
|
||||
@@ -693,7 +739,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
|
||||
/* and now, we know this is a match and we should create an
|
||||
entry for the return-linked-list */
|
||||
|
||||
|
||||
newco = (struct Cookie *)malloc(sizeof(struct Cookie));
|
||||
if(newco) {
|
||||
/* first, copy the whole source cookie: */
|
||||
@@ -701,10 +747,20 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
|
||||
/* then modify our next */
|
||||
newco->next = mainco;
|
||||
|
||||
|
||||
/* point the main to us */
|
||||
mainco = newco;
|
||||
}
|
||||
else {
|
||||
/* failure, clear up the allocated chain and return NULL */
|
||||
while(mainco) {
|
||||
co = mainco->next;
|
||||
free(mainco);
|
||||
mainco = co;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -753,24 +809,8 @@ void Curl_cookie_cleanup(struct CookieInfo *c)
|
||||
co = c->cookies;
|
||||
|
||||
while(co) {
|
||||
if(co->name)
|
||||
free(co->name);
|
||||
if(co->value)
|
||||
free(co->value);
|
||||
if(co->domain)
|
||||
free(co->domain);
|
||||
if(co->path)
|
||||
free(co->path);
|
||||
if(co->expirestr)
|
||||
free(co->expirestr);
|
||||
|
||||
if(co->version)
|
||||
free(co->version);
|
||||
if(co->maxage)
|
||||
free(co->maxage);
|
||||
|
||||
next = co->next;
|
||||
free(co);
|
||||
freecookie(co);
|
||||
co = next;
|
||||
}
|
||||
free(c); /* free the base struct as well */
|
||||
@@ -813,7 +853,7 @@ int Curl_cookie_output(struct CookieInfo *c, char *dumphere)
|
||||
"# This file was generated by libcurl! Edit at your own risk.\n\n",
|
||||
out);
|
||||
co = c->cookies;
|
||||
|
||||
|
||||
while(co) {
|
||||
fprintf(out,
|
||||
"%s%s\t" /* domain */
|
||||
|
31
lib/cookie.h
31
lib/cookie.h
@@ -1,10 +1,10 @@
|
||||
#ifndef __COOKIE_H
|
||||
#define __COOKIE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
@@ -12,7 +12,7 @@
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
@@ -41,11 +41,11 @@ struct Cookie {
|
||||
long expires; /* expires = <this> */
|
||||
char *expirestr; /* the plain text version */
|
||||
bool tailmatch; /* weather we do tail-matchning of the domain name */
|
||||
|
||||
|
||||
/* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
|
||||
char *version; /* Version = <value> */
|
||||
char *maxage; /* Max-Age = <value> */
|
||||
|
||||
|
||||
bool secure; /* whether the 'secure' keyword was used */
|
||||
bool livecookie; /* updated from a server, not a stored file */
|
||||
};
|
||||
@@ -60,13 +60,20 @@ struct CookieInfo {
|
||||
bool newsession; /* new session, discard session cookies on load */
|
||||
};
|
||||
|
||||
/* This is the maximum line length we accept for a cookie line */
|
||||
#define MAX_COOKIE_LINE 2048
|
||||
#define MAX_COOKIE_LINE_TXT "2047"
|
||||
/* This is the maximum line length we accept for a cookie line. RFC 2109
|
||||
section 6.3 says:
|
||||
|
||||
"at least 4096 bytes per cookie (as measured by the size of the characters
|
||||
that comprise the cookie non-terminal in the syntax description of the
|
||||
Set-Cookie header)"
|
||||
|
||||
*/
|
||||
#define MAX_COOKIE_LINE 5000
|
||||
#define MAX_COOKIE_LINE_TXT "4999"
|
||||
|
||||
/* This is the maximum length of a cookie name we deal with: */
|
||||
#define MAX_NAME 256
|
||||
#define MAX_NAME_TXT "255"
|
||||
#define MAX_NAME 1024
|
||||
#define MAX_NAME_TXT "1023"
|
||||
|
||||
struct SessionHandle;
|
||||
/*
|
||||
|
422
lib/curllib.dsp
422
lib/curllib.dsp
@@ -1,422 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="curllib" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=curllib - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "curllib.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "curllib.mak" CFG="curllib - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "curllib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "curllib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "curllib - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "." /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /D "_WINDLL" /FR /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib ws2_32.lib winmm.lib /nologo /dll /map /debug /machine:I386 /out:"Release/libcurl.dll"
|
||||
|
||||
!ELSEIF "$(CFG)" == "curllib - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /FR /FD /GZ /c
|
||||
# SUBTRACT CPP /WX /YX
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib ws2_32.lib winmm.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug/libcurl.dll" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /nodefaultlib
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "curllib - Win32 Release"
|
||||
# Name "curllib - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\base64.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\connect.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cookie.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dict.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\easy.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\escape.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\file.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\formdata.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ftp.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\getdate.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\getenv.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\getinfo.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hash.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hostip.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\http.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\http_chunks.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\if2ip.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\krb4.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ldap.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\libcurl.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\llist.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\memdebug.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\mprintf.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\multi.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\netrc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\progress.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\security.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sendf.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\speedcheck.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ssluse.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\strequal.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\strtok.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\telnet.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\timeval.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\transfer.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\url.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\share.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\version.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\arpa_telnet.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\base64.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\connect.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cookie.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dict.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\escape.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\file.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\formdata.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ftp.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\getdate.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\getenv.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hostip.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\http.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\http_chunks.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\if2ip.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\inet_ntoa_r.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\krb4.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ldap.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\memdebug.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\netrc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\progress.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\security.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sendf.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\setup.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\speedcheck.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ssluse.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\strequal.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\strtok.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\telnet.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\timeval.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\transfer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\url.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\urldata.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\http_digest.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\http_ntlm.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\http_ntlm.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\inet_pton.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\inet_pton.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\md5.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\http_digest.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\md5.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
95
lib/curlx.h
Normal file
95
lib/curlx.h
Normal file
@@ -0,0 +1,95 @@
|
||||
#ifndef __CURLX_H
|
||||
#define __CURLX_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, 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
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Defines protos and includes all header files that provide the curlx_*
|
||||
* functions. The curlx_* functions are not part of the libcurl API, but are
|
||||
* stand-alone functions whose sources can be built and linked by apps if need
|
||||
* be.
|
||||
*/
|
||||
|
||||
#include <curl/mprintf.h>
|
||||
/* this is still a public header file that provides the curl_mprintf()
|
||||
functions while they still are offered publicly. They will be made library-
|
||||
private one day */
|
||||
|
||||
#include "strequal.h"
|
||||
/* "strequal.h" provides the strequal protos */
|
||||
|
||||
#include "strtoofft.h"
|
||||
/* "strtoofft.h" provides this function: curlx_strtoofft(), returns a
|
||||
curl_off_t number from a given string.
|
||||
*/
|
||||
|
||||
#include "timeval.h"
|
||||
/*
|
||||
"timeval.h" sets up a 'struct timeval' even for platforms that otherwise
|
||||
don't have one and has protos for these functions:
|
||||
|
||||
curlx_tvnow()
|
||||
curlx_tvdiff()
|
||||
curlx_tvdiff_secs()
|
||||
*/
|
||||
|
||||
/* Now setup curlx_ * names for the functions that are to become curlx_ and
|
||||
be removed from a future libcurl official API:
|
||||
curlx_getenv
|
||||
curlx_mprintf (and its variations)
|
||||
curlx_strequal
|
||||
curlx_strnequal
|
||||
|
||||
*/
|
||||
|
||||
#define curlx_getenv curl_getenv
|
||||
#define curlx_strequal curl_strequal
|
||||
#define curlx_strnequal curl_strnequal
|
||||
#define curlx_mvsnprintf curl_mvsnprintf
|
||||
#define curlx_msnprintf curl_msnprintf
|
||||
#define curlx_maprintf curl_maprintf
|
||||
#define curlx_mvaprintf curl_mvaprintf
|
||||
#define curlx_msprintf curl_msprintf
|
||||
#define curlx_mprintf curl_mprintf
|
||||
#define curlx_mfprintf curl_mfprintf
|
||||
#define curlx_mvsprintf curl_mvsprintf
|
||||
#define curlx_mvprintf curl_mvprintf
|
||||
#define curlx_mvfprintf curl_mvfprintf
|
||||
|
||||
#ifdef ENABLE_CURLX_PRINTF
|
||||
/* If this define is set, we define all "standard" printf() functions to use
|
||||
the curlx_* version instead. It makes the source code transparant and
|
||||
easier to understand/patch. */
|
||||
# define printf curlx_mprintf
|
||||
# define fprintf curlx_mfprintf
|
||||
# define sprintf curlx_msprintf
|
||||
# define snprintf curlx_msnprintf
|
||||
# define vprintf curlx_mvprintf
|
||||
# define vfprintf curlx_mvfprintf
|
||||
# define vsprintf curlx_mvsprintf
|
||||
# define vsnprintf curlx_mvsnprintf
|
||||
# define aprintf curlx_maprintf
|
||||
# define vaprintf curlx_mvaprintf
|
||||
#endif /* ENABLE_CURLX_PRINTF */
|
||||
|
||||
#endif /* __CURLX_H */
|
262
lib/easy.c
262
lib/easy.c
@@ -66,7 +66,7 @@
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* WIN32 ... */
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
@@ -76,23 +76,24 @@
|
||||
#include "getinfo.h"
|
||||
#include "hostip.h"
|
||||
#include "share.h"
|
||||
#include "memory.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
/* Silly win32 socket initialization functions */
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
|
||||
of win32_init() */
|
||||
static void win32_cleanup(void)
|
||||
{
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
/* win32_init() performs win32 socket initialization to properly setup the
|
||||
stack to allow networking */
|
||||
static CURLcode win32_init(void)
|
||||
{
|
||||
WORD wVersionRequested;
|
||||
@@ -126,29 +127,68 @@ static CURLcode win32_init(void)
|
||||
WSACleanup();
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
/* The Windows Sockets DLL is acceptable. Proceed. */
|
||||
return CURLE_OK;
|
||||
}
|
||||
/* The Windows Sockets DLL is acceptable. Proceed. */
|
||||
|
||||
#else
|
||||
/* These functions exist merely to prevent compiler warnings */
|
||||
static CURLcode win32_init(void) { return CURLE_OK; }
|
||||
static void win32_cleanup(void) { }
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
/*
|
||||
* Initialise use of IDNA library.
|
||||
* It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
|
||||
* idna_to_ascii_lz().
|
||||
*/
|
||||
static void idna_init (void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char buf[60];
|
||||
UINT cp = GetACP();
|
||||
|
||||
if (!getenv("CHARSET") && cp > 0) {
|
||||
snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
|
||||
putenv(buf);
|
||||
}
|
||||
#else
|
||||
/* to do? */
|
||||
#endif
|
||||
}
|
||||
#endif /* USE_LIBIDN */
|
||||
|
||||
/* true globals -- for curl_global_init() and curl_global_cleanup() */
|
||||
static unsigned int initialized = 0;
|
||||
static long init_flags = 0;
|
||||
|
||||
/*
|
||||
* If a memory-using function (like curl_getenv) is used before
|
||||
* curl_global_init() is called, we need to have these pointers set already.
|
||||
*/
|
||||
curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
|
||||
curl_free_callback Curl_cfree = (curl_free_callback)free;
|
||||
curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
|
||||
curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup;
|
||||
curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
|
||||
|
||||
/**
|
||||
* Globally initializes cURL given a bitwise set of
|
||||
* the different features to initialize.
|
||||
* curl_global_init() globally initializes cURL given a bitwise set of the
|
||||
* different features of what to initialize.
|
||||
*/
|
||||
CURLcode curl_global_init(long flags)
|
||||
{
|
||||
if (initialized)
|
||||
return CURLE_OK;
|
||||
|
||||
/* Setup the default memory functions here (again) */
|
||||
Curl_cmalloc = (curl_malloc_callback)malloc;
|
||||
Curl_cfree = (curl_free_callback)free;
|
||||
Curl_crealloc = (curl_realloc_callback)realloc;
|
||||
Curl_cstrdup = (curl_strdup_callback)strdup;
|
||||
Curl_ccalloc = (curl_calloc_callback)calloc;
|
||||
|
||||
if (flags & CURL_GLOBAL_SSL)
|
||||
Curl_SSL_init();
|
||||
|
||||
@@ -161,15 +201,50 @@ CURLcode curl_global_init(long flags)
|
||||
return CURLE_FAILED_INIT;
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
idna_init();
|
||||
#endif
|
||||
|
||||
initialized = 1;
|
||||
init_flags = flags;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_global_init_mem() globally initializes cURL and also registers the
|
||||
* user provided callback routines.
|
||||
*/
|
||||
CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
||||
curl_free_callback f, curl_realloc_callback r,
|
||||
curl_strdup_callback s, curl_calloc_callback c)
|
||||
{
|
||||
CURLcode code = CURLE_OK;
|
||||
|
||||
/* Invalid input, return immediately */
|
||||
if (!m || !f || !r || !s || !c)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Already initialized, don't do it again */
|
||||
if ( initialized )
|
||||
return CURLE_OK;
|
||||
|
||||
/* Call the actual init function first */
|
||||
code = curl_global_init(flags);
|
||||
if (code == CURLE_OK) {
|
||||
Curl_cmalloc = m;
|
||||
Curl_cfree = f;
|
||||
Curl_cstrdup = s;
|
||||
Curl_crealloc = r;
|
||||
Curl_ccalloc = c;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Globally cleanup cURL, uses the value of "init_flags" to determine
|
||||
* what needs to be cleaned up and what doesn't
|
||||
* curl_global_cleanup() globally cleanups cURL, uses the value of
|
||||
* "init_flags" to determine what needs to be cleaned up and what doesn't.
|
||||
*/
|
||||
void curl_global_cleanup(void)
|
||||
{
|
||||
@@ -192,6 +267,10 @@ void curl_global_cleanup(void)
|
||||
init_flags = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_easy_init() is the external interface to alloc, setup and init an
|
||||
* easy handle that is returned. If anything goes wrong, NULL is returned.
|
||||
*/
|
||||
CURL *curl_easy_init(void)
|
||||
{
|
||||
CURLcode res;
|
||||
@@ -213,6 +292,10 @@ CURL *curl_easy_init(void)
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_easy_setopt() is the external interface for setting options on an
|
||||
* easy handle.
|
||||
*/
|
||||
typedef int (*func_T)(void);
|
||||
CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
|
||||
{
|
||||
@@ -224,6 +307,9 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
|
||||
struct SessionHandle *data = curl;
|
||||
CURLcode ret=CURLE_FAILED_INIT;
|
||||
|
||||
if(!curl)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
va_start(arg, tag);
|
||||
|
||||
/* PORTING NOTE:
|
||||
@@ -247,7 +333,8 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
|
||||
/* This is a function pointer type */
|
||||
param_func = va_arg(arg, func_T );
|
||||
ret = Curl_setopt(data, tag, param_func);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* This is a curl_off_t type */
|
||||
param_offset = va_arg(arg, curl_off_t);
|
||||
ret = Curl_setopt(data, tag, param_offset);
|
||||
@@ -257,10 +344,17 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_easy_perform() is the external interface that performs a transfer
|
||||
* previously setup.
|
||||
*/
|
||||
CURLcode curl_easy_perform(CURL *curl)
|
||||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
if(!data)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
if ( ! (data->share && data->share->hostcache) ) {
|
||||
|
||||
if (Curl_global_host_cache_use(data) &&
|
||||
@@ -285,9 +379,17 @@ CURLcode curl_easy_perform(CURL *curl)
|
||||
return Curl_perform(data);
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_easy_cleanup() is the external interface to cleaning/freeing the given
|
||||
* easy handle.
|
||||
*/
|
||||
void curl_easy_cleanup(CURL *curl)
|
||||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
if ( ! (data->share && data->share->hostcache) ) {
|
||||
if ( !Curl_global_host_cache_use(data)) {
|
||||
Curl_hash_destroy(data->hostcache);
|
||||
@@ -296,6 +398,10 @@ void curl_easy_cleanup(CURL *curl)
|
||||
Curl_close(data);
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_easy_getinfo() is an external interface that allows an app to retrieve
|
||||
* information from a performed transfer and similar.
|
||||
*/
|
||||
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
|
||||
{
|
||||
va_list arg;
|
||||
@@ -308,68 +414,110 @@ CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
|
||||
return Curl_getinfo(data, info, paramp);
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_easy_duphandle() is an external interface to allow duplication of a
|
||||
* given input easy handle. The returned handle will be a new working handle
|
||||
* with all options set exactly as the input source handle.
|
||||
*/
|
||||
CURL *curl_easy_duphandle(CURL *incurl)
|
||||
{
|
||||
bool fail = TRUE;
|
||||
struct SessionHandle *data=(struct SessionHandle *)incurl;
|
||||
|
||||
struct SessionHandle *outcurl = (struct SessionHandle *)
|
||||
malloc(sizeof(struct SessionHandle));
|
||||
calloc(sizeof(struct SessionHandle), 1);
|
||||
|
||||
if(NULL == outcurl)
|
||||
return NULL; /* failure */
|
||||
|
||||
/* start with clearing the entire new struct */
|
||||
memset(outcurl, 0, sizeof(struct SessionHandle));
|
||||
do {
|
||||
|
||||
/*
|
||||
* We setup a few buffers we need. We should probably make them
|
||||
* get setup on-demand in the code, as that would probably decrease
|
||||
* the likeliness of us forgetting to init a buffer here in the future.
|
||||
*/
|
||||
outcurl->state.headerbuff=(char*)malloc(HEADERSIZE);
|
||||
if(!outcurl->state.headerbuff) {
|
||||
free(outcurl); /* free the memory again */
|
||||
return NULL;
|
||||
}
|
||||
outcurl->state.headersize=HEADERSIZE;
|
||||
/*
|
||||
* We setup a few buffers we need. We should probably make them
|
||||
* get setup on-demand in the code, as that would probably decrease
|
||||
* the likeliness of us forgetting to init a buffer here in the future.
|
||||
*/
|
||||
outcurl->state.headerbuff=(char*)malloc(HEADERSIZE);
|
||||
if(!outcurl->state.headerbuff) {
|
||||
break;
|
||||
}
|
||||
outcurl->state.headersize=HEADERSIZE;
|
||||
|
||||
/* copy all userdefined values */
|
||||
outcurl->set = data->set;
|
||||
outcurl->state.numconnects = data->state.numconnects;
|
||||
outcurl->state.connects = (struct connectdata **)
|
||||
/* 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) {
|
||||
free(outcurl->state.headerbuff);
|
||||
free(outcurl);
|
||||
return NULL;
|
||||
}
|
||||
memset(outcurl->state.connects, 0,
|
||||
sizeof(struct connectdata *)*outcurl->state.numconnects);
|
||||
if(!outcurl->state.connects) {
|
||||
break;
|
||||
}
|
||||
|
||||
outcurl->progress.flags = data->progress.flags;
|
||||
outcurl->progress.callback = data->progress.callback;
|
||||
memset(outcurl->state.connects, 0,
|
||||
sizeof(struct connectdata *)*outcurl->state.numconnects);
|
||||
|
||||
if(data->cookies)
|
||||
/* If cookies are enabled in the parent handle, we enable them
|
||||
in the clone as well! */
|
||||
outcurl->cookies = Curl_cookie_init(data,
|
||||
data->cookies->filename,
|
||||
outcurl->cookies,
|
||||
data->set.cookiesession);
|
||||
outcurl->progress.flags = data->progress.flags;
|
||||
outcurl->progress.callback = data->progress.callback;
|
||||
|
||||
/* duplicate all values in 'change' */
|
||||
if(data->change.url) {
|
||||
outcurl->change.url = strdup(data->change.url);
|
||||
outcurl->change.url_alloc = TRUE;
|
||||
}
|
||||
if(data->change.proxy) {
|
||||
outcurl->change.proxy = strdup(data->change.proxy);
|
||||
outcurl->change.proxy_alloc = TRUE;
|
||||
}
|
||||
if(data->change.referer) {
|
||||
outcurl->change.referer = strdup(data->change.referer);
|
||||
outcurl->change.referer_alloc = TRUE;
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
if(data->cookies) {
|
||||
/* If cookies are enabled in the parent handle, we enable them
|
||||
in the clone as well! */
|
||||
outcurl->cookies = Curl_cookie_init(data,
|
||||
data->cookies->filename,
|
||||
outcurl->cookies,
|
||||
data->set.cookiesession);
|
||||
if(!outcurl->cookies) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#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)
|
||||
break;
|
||||
outcurl->change.referer_alloc = TRUE;
|
||||
}
|
||||
|
||||
#ifdef USE_ARES
|
||||
/* If we use ares, we setup a new ares channel for the new handle */
|
||||
if(ARES_SUCCESS != ares_init(&outcurl->state.areschannel))
|
||||
break;
|
||||
#endif
|
||||
|
||||
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.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)
|
||||
free(outcurl->change.referer);
|
||||
free(outcurl); /* free the memory again */
|
||||
outcurl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return outcurl;
|
||||
|
15
lib/escape.c
15
lib/escape.c
@@ -31,21 +31,24 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
char *curl_escape(const char *string, int length)
|
||||
{
|
||||
size_t alloc = (length?(size_t)length:strlen(string))+1;
|
||||
char *ns = malloc(alloc);
|
||||
char *ns;
|
||||
char *testing_ptr = NULL;
|
||||
unsigned char in;
|
||||
size_t newlen = alloc;
|
||||
int strindex=0;
|
||||
|
||||
ns = malloc(alloc);
|
||||
if(!ns)
|
||||
return NULL;
|
||||
|
||||
length = alloc-1;
|
||||
while(length--) {
|
||||
in = *string;
|
||||
@@ -91,9 +94,8 @@ char *curl_unescape(const char *string, int length)
|
||||
int strindex=0;
|
||||
long hex;
|
||||
|
||||
if( !ns ) {
|
||||
if( !ns )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while(--alloc > 0) {
|
||||
in = *string;
|
||||
@@ -124,5 +126,6 @@ char *curl_unescape(const char *string, int length)
|
||||
the library's memory system */
|
||||
void curl_free(void *p)
|
||||
{
|
||||
free(p);
|
||||
if(p)
|
||||
free(p);
|
||||
}
|
||||
|
140
lib/file.c
140
lib/file.c
@@ -1,8 +1,8 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
@@ -10,7 +10,7 @@
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
@@ -73,7 +73,6 @@
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
@@ -84,17 +83,21 @@
|
||||
#include "file.h"
|
||||
#include "speedcheck.h"
|
||||
#include "getinfo.h"
|
||||
#include "transfer.h" /* for Curl_readwrite_init() */
|
||||
#include "transfer.h"
|
||||
#include "url.h"
|
||||
#include "memory.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
/* Emulate a connect-then-transfer protocol. We connect to the file here */
|
||||
/*
|
||||
* Curl_file_connect() gets called from Curl_protocol_connect() to allow us to
|
||||
* do protocol-specific actions at connect-time. We emulate a
|
||||
* connect-then-transfer protocol and "connect" to the file here
|
||||
*/
|
||||
CURLcode Curl_file_connect(struct connectdata *conn)
|
||||
{
|
||||
char *real_path = curl_unescape(conn->path, 0);
|
||||
@@ -105,10 +108,15 @@ CURLcode Curl_file_connect(struct connectdata *conn)
|
||||
char *actual_path;
|
||||
#endif
|
||||
|
||||
file = (struct FILEPROTO *)calloc(sizeof(struct FILEPROTO), 1);
|
||||
if(!file)
|
||||
if(!real_path)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
file = (struct FILEPROTO *)calloc(sizeof(struct FILEPROTO), 1);
|
||||
if(!file) {
|
||||
free(real_path);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
conn->proto.file = file;
|
||||
|
||||
#if defined(WIN32) || defined(__EMX__)
|
||||
@@ -141,13 +149,16 @@ CURLcode Curl_file_connect(struct connectdata *conn)
|
||||
actual_path[i] = '\\';
|
||||
|
||||
fd = open(actual_path, O_RDONLY | O_BINARY); /* no CR/LF translation! */
|
||||
file->path = actual_path;
|
||||
#else
|
||||
fd = open(real_path, O_RDONLY);
|
||||
file->path = real_path;
|
||||
#endif
|
||||
free(real_path);
|
||||
file->freepath = real_path; /* free this when done */
|
||||
|
||||
if(fd == -1) {
|
||||
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);
|
||||
return CURLE_FILE_COULDNT_READ_FILE;
|
||||
}
|
||||
file->fd = fd;
|
||||
@@ -159,11 +170,99 @@ CURLcode Curl_file_connect(struct connectdata *conn)
|
||||
#define lseek(x,y,z) _lseeki64(x, y, z)
|
||||
#endif
|
||||
|
||||
/* This is the do-phase, separated from the connect-phase above */
|
||||
CURLcode Curl_file_done(struct connectdata *conn,
|
||||
CURLcode status)
|
||||
{
|
||||
struct FILEPROTO *file = conn->proto.file;
|
||||
(void)status; /* not used */
|
||||
Curl_safefree(file->freepath);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode file_upload(struct connectdata *conn)
|
||||
{
|
||||
struct FILEPROTO *file = conn->proto.file;
|
||||
char *dir = strchr(file->path, '/');
|
||||
FILE *fp;
|
||||
CURLcode res=CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
char *buf = data->state.buffer;
|
||||
size_t nread;
|
||||
size_t nwrite;
|
||||
curl_off_t bytecount = 0;
|
||||
struct timeval now = Curl_tvnow();
|
||||
|
||||
/*
|
||||
* Since FILE: doesn't do the full init, we need to provide some extra
|
||||
* assignments here.
|
||||
*/
|
||||
conn->fread = data->set.fread;
|
||||
conn->fread_in = data->set.in;
|
||||
conn->upload_fromhere = buf;
|
||||
|
||||
if(!dir)
|
||||
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
|
||||
|
||||
if(!dir[1])
|
||||
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
|
||||
|
||||
fp = fopen(file->path, "wb");
|
||||
if(!fp) {
|
||||
failf(data, "Can't open %s for writing", file->path);
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
if(-1 != data->set.infilesize)
|
||||
/* known size of data to "upload" */
|
||||
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
||||
|
||||
while (res == CURLE_OK) {
|
||||
int readcount;
|
||||
res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
nread = (size_t)readcount;
|
||||
|
||||
if (nread <= 0)
|
||||
break;
|
||||
|
||||
/* write the data to the target */
|
||||
nwrite = fwrite(buf, 1, nread, fp);
|
||||
if(nwrite != nread) {
|
||||
res = CURLE_SEND_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
bytecount += nread;
|
||||
|
||||
Curl_pgrsSetUploadCounter(data, bytecount);
|
||||
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
res = CURLE_ABORTED_BY_CALLBACK;
|
||||
else
|
||||
res = Curl_speedcheck(data, now);
|
||||
}
|
||||
if(!res && Curl_pgrsUpdate(conn))
|
||||
res = CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_file() is the protocol-specific function for the do-phase, separated
|
||||
* from the connect-phase above. Other protocols merely setup the transfer in
|
||||
* the do-phase, to have it done in the main transfer loop but since some
|
||||
* platforms we support don't allow select()ing etc on file handles (as
|
||||
* opposed to sockets) we instead perform the whole do-operation in this
|
||||
* function.
|
||||
*/
|
||||
CURLcode Curl_file(struct connectdata *conn)
|
||||
{
|
||||
/* This implementation ignores the host name in conformance with
|
||||
/* This implementation ignores the host name in conformance with
|
||||
RFC 1738. Only local files (reachable via the standard file system)
|
||||
are supported. This means that files on remotely mounted directories
|
||||
(via NFS, Samba, NT sharing) can be accessed through a file:// URL
|
||||
@@ -183,6 +282,9 @@ CURLcode Curl_file(struct connectdata *conn)
|
||||
Curl_initinfo(data);
|
||||
Curl_pgrsStartNow(data);
|
||||
|
||||
if(data->set.upload)
|
||||
return file_upload(conn);
|
||||
|
||||
/* get the fd from the connection phase */
|
||||
fd = conn->proto.file->fd;
|
||||
|
||||
@@ -259,10 +361,6 @@ CURLcode Curl_file(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
bytecount += nread;
|
||||
/* NOTE: The following call to fwrite does CR/LF translation on
|
||||
Windows systems if the target is stdout. Use -O or -o parameters
|
||||
to prevent CR/LF translation (this then goes to a binary mode
|
||||
file descriptor). */
|
||||
|
||||
res = Curl_client_write(data, CLIENTWRITE_BODY, buf, nread);
|
||||
if(res)
|
||||
@@ -273,7 +371,7 @@ CURLcode Curl_file(struct connectdata *conn)
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
res = CURLE_ABORTED_BY_CALLBACK;
|
||||
else
|
||||
res = Curl_speedcheck (data, now);
|
||||
res = Curl_speedcheck(data, now);
|
||||
}
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
res = CURLE_ABORTED_BY_CALLBACK;
|
||||
|
@@ -24,7 +24,8 @@
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_FILE
|
||||
CURLcode Curl_file(struct connectdata *conn);
|
||||
CURLcode Curl_file_connect(struct connectdata *conn);
|
||||
CURLcode Curl_file(struct connectdata *);
|
||||
CURLcode Curl_file_done(struct connectdata *, CURLcode);
|
||||
CURLcode Curl_file_connect(struct connectdata *);
|
||||
#endif
|
||||
#endif
|
||||
|
800
lib/formdata.c
800
lib/formdata.c
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,10 @@
|
||||
#define __FORMDATA_H
|
||||
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
@@ -13,7 +13,7 @@
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
@@ -23,31 +23,43 @@
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
enum formtype {
|
||||
FORM_DATA, /* regular data */
|
||||
FORM_FILE /* 'line' points to a file name we should read from */
|
||||
};
|
||||
|
||||
/* plain and simple linked list with lines to send */
|
||||
struct FormData {
|
||||
struct FormData *next;
|
||||
enum formtype type;
|
||||
char *line;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
struct Form {
|
||||
struct FormData *data; /* current form line to send */
|
||||
unsigned int sent; /* number of bytes of the current line that has already
|
||||
been sent in a previous invoke */
|
||||
size_t sent; /* number of bytes of the current line that has
|
||||
already been sent in a previous invoke */
|
||||
FILE *fp; /* file to read from */
|
||||
};
|
||||
|
||||
/* used by FormAdd for temporary storage */
|
||||
typedef struct FormInfo {
|
||||
char *name;
|
||||
bool name_alloc;
|
||||
size_t namelength;
|
||||
char *value;
|
||||
bool value_alloc;
|
||||
size_t contentslength;
|
||||
char *contenttype;
|
||||
bool contenttype_alloc;
|
||||
long flags;
|
||||
char *buffer; /* pointer to existing buffer used for file upload */
|
||||
size_t bufferlength;
|
||||
char *showfilename; /* The file name to show. If not set, the actual
|
||||
file name will be used */
|
||||
bool showfilename_alloc;
|
||||
struct curl_slist* contentheader;
|
||||
struct FormInfo *more;
|
||||
} FormInfo;
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
CURLcode Curl_ftp(struct connectdata *conn);
|
||||
CURLcode Curl_ftp_done(struct connectdata *conn);
|
||||
CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode);
|
||||
CURLcode Curl_ftp_connect(struct connectdata *conn);
|
||||
CURLcode Curl_ftp_disconnect(struct connectdata *conn);
|
||||
CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
|
||||
|
@@ -1758,7 +1758,8 @@ ToHour (Hours, Meridian)
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
/* NOTREACHED */
|
||||
/* NOTREACHED - but make gcc happy! */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@@ -26,6 +26,11 @@
|
||||
#define YYDEBUG 0
|
||||
#endif
|
||||
|
||||
#ifndef YYSTACK_USE_ALLOCA
|
||||
/* to satisfy gcc -Wundef, we set this to 0 */
|
||||
#define YYSTACK_USE_ALLOCA 0
|
||||
#endif
|
||||
|
||||
/* Since the code of getdate.y is not included in the Emacs executable
|
||||
itself, there is no need to #define static in this file. Even if
|
||||
the code were included in the Emacs executable, it probably
|
||||
@@ -81,10 +86,9 @@
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#include "memory.h"
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
#ifndef YYMAXDEPTH
|
||||
#define YYMAXDEPTH 0
|
||||
@@ -718,9 +722,10 @@ ToHour (int Hours, MERIDIAN Meridian)
|
||||
Hours = 0;
|
||||
return Hours + 12;
|
||||
default:
|
||||
abort ();
|
||||
break; /* used to do abort() here */
|
||||
}
|
||||
/* NOTREACHED */
|
||||
/* NOTREACHED - but make gcc happy! */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1074,31 +1079,3 @@ curl_getdate (const char *p, const time_t *now)
|
||||
|
||||
return Start;
|
||||
}
|
||||
|
||||
#if defined (TEST)
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
main (int ac, char *av[])
|
||||
{
|
||||
char buff[MAX_BUFF_LEN + 1];
|
||||
time_t d;
|
||||
|
||||
(void) printf ("Enter date, or blank line to exit.\n\t> ");
|
||||
(void) fflush (stdout);
|
||||
|
||||
buff[MAX_BUFF_LEN] = 0;
|
||||
while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
|
||||
{
|
||||
d = curl_getdate (buff, (time_t *) NULL);
|
||||
if (d == -1)
|
||||
(void) printf ("Bad format - couldn't convert.\n");
|
||||
else
|
||||
(void) printf ("%s", ctime (&d));
|
||||
(void) printf ("\t> ");
|
||||
(void) fflush (stdout);
|
||||
}
|
||||
exit (0);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#endif /* defined (TEST) */
|
||||
|
@@ -36,10 +36,9 @@
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "memory.h"
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
static
|
||||
char *GetEnv(const char *variable)
|
||||
|
@@ -31,17 +31,11 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef VMS
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include "memory.h"
|
||||
|
||||
/* Make this the last #include */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is supposed to be called in the beginning of a permform() session
|
||||
|
30
lib/hash.c
30
lib/hash.c
@@ -28,12 +28,10 @@
|
||||
|
||||
#include "hash.h"
|
||||
#include "llist.h"
|
||||
#include "memory.h"
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
/* this must be the last include file */
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
|
||||
static unsigned long
|
||||
hash_str(const char *key, size_t key_length)
|
||||
@@ -127,9 +125,17 @@ mk_hash_element(char *key, size_t key_len, const void *p)
|
||||
(curl_hash_element *) malloc(sizeof(curl_hash_element));
|
||||
|
||||
if(he) {
|
||||
he->key = strdup(key);
|
||||
he->key_len = key_len;
|
||||
he->ptr = (void *) p;
|
||||
char *dup = strdup(key);
|
||||
if(dup) {
|
||||
he->key = dup;
|
||||
he->key_len = key_len;
|
||||
he->ptr = (void *) p;
|
||||
}
|
||||
else {
|
||||
/* failed to duplicate the key, free memory and fail */
|
||||
free(he);
|
||||
he = NULL;
|
||||
}
|
||||
}
|
||||
return he;
|
||||
}
|
||||
@@ -161,10 +167,16 @@ Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p)
|
||||
++h->size;
|
||||
return p; /* return the new entry */
|
||||
}
|
||||
/* couldn't insert it, destroy the 'he' element again */
|
||||
hash_element_dtor(h, he);
|
||||
/*
|
||||
* Couldn't insert it, destroy the 'he' element and the key again. We
|
||||
* don't call hash_element_dtor() since that would also call the
|
||||
* "destructor" for the actual data 'p'. When we fail, we shall not touch
|
||||
* that data.
|
||||
*/
|
||||
free(he->key);
|
||||
free(he);
|
||||
}
|
||||
h->dtor(p); /* remove the NEW entry */
|
||||
|
||||
return NULL; /* failure */
|
||||
}
|
||||
|
||||
|
300
lib/hostares.c
Normal file
300
lib/hostares.c
Normal file
@@ -0,0 +1,300 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, 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
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define _REENTRANT
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETJMP_H
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||
#undef in_addr_t
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||
#include "inet_ntoa_r.h"
|
||||
#endif
|
||||
|
||||
#include "memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for ares-enabled builds
|
||||
**********************************************************************/
|
||||
|
||||
#ifdef CURLRES_ARES
|
||||
|
||||
/*
|
||||
* Curl_fdset() is called when someone from the outside world (using
|
||||
* curl_multi_fdset()) wants to get our fd_set setup and we're talking with
|
||||
* ares. The caller must make sure that this function is only called when we
|
||||
* have a working ares channel.
|
||||
*
|
||||
* Returns: CURLE_OK always!
|
||||
*/
|
||||
|
||||
CURLcode Curl_fdset(struct connectdata *conn,
|
||||
fd_set *read_fd_set,
|
||||
fd_set *write_fd_set,
|
||||
int *max_fdp)
|
||||
|
||||
{
|
||||
int max = ares_fds(conn->data->state.areschannel,
|
||||
read_fd_set, write_fd_set);
|
||||
*max_fdp = max;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_is_resolved() is called repeatedly to check if a previous name resolve
|
||||
* request has completed. It should also make sure to time-out if the
|
||||
* operation seems to take too long.
|
||||
*
|
||||
* Returns normal CURLcode errors.
|
||||
*/
|
||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dns)
|
||||
{
|
||||
fd_set read_fds, write_fds;
|
||||
struct timeval tv={0,0};
|
||||
struct SessionHandle *data = conn->data;
|
||||
int nfds;
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_ZERO(&write_fds);
|
||||
|
||||
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
|
||||
|
||||
(void)select(nfds, &read_fds, &write_fds, NULL,
|
||||
(struct timeval *)&tv);
|
||||
|
||||
/* Call ares_process() unconditonally here, even if we simply timed out
|
||||
above, as otherwise the ares name resolve won't timeout! */
|
||||
ares_process(data->state.areschannel, &read_fds, &write_fds);
|
||||
|
||||
*dns = NULL;
|
||||
|
||||
if(conn->async.done) {
|
||||
/* we're done, kill the ares handle */
|
||||
if(!conn->async.dns) {
|
||||
failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
|
||||
ares_strerror(conn->async.status));
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
*dns = conn->async.dns;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_wait_for_resolv() waits for a resolve to finish. This function should
|
||||
* be avoided since using this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
*
|
||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
|
||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred.
|
||||
*/
|
||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
CURLcode rc=CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
long timeout = CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
|
||||
|
||||
/* now, see if there's a connect timeout or a regular timeout to
|
||||
use instead of the default one */
|
||||
if(conn->data->set.connecttimeout)
|
||||
timeout = conn->data->set.connecttimeout;
|
||||
else if(conn->data->set.timeout)
|
||||
timeout = conn->data->set.timeout;
|
||||
|
||||
/* We convert the number of seconds into number of milliseconds here: */
|
||||
if(timeout < 2147483)
|
||||
/* maximum amount of seconds that can be multiplied with 1000 and
|
||||
still fit within 31 bits */
|
||||
timeout *= 1000;
|
||||
else
|
||||
timeout = 0x7fffffff; /* ridiculous amount of time anyway */
|
||||
|
||||
/* Wait for the name resolve query to complete. */
|
||||
while (1) {
|
||||
int nfds=0;
|
||||
fd_set read_fds, write_fds;
|
||||
struct timeval *tvp, tv, store;
|
||||
int count;
|
||||
struct timeval now = Curl_tvnow();
|
||||
long timediff;
|
||||
|
||||
store.tv_sec = (int)timeout/1000;
|
||||
store.tv_usec = (timeout%1000)*1000;
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_ZERO(&write_fds);
|
||||
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
|
||||
if (nfds == 0)
|
||||
/* no file descriptors means we're done waiting */
|
||||
break;
|
||||
tvp = ares_timeout(data->state.areschannel, &store, &tv);
|
||||
count = select(nfds, &read_fds, &write_fds, NULL, tvp);
|
||||
if (count < 0 && errno != EINVAL)
|
||||
break;
|
||||
|
||||
ares_process(data->state.areschannel, &read_fds, &write_fds);
|
||||
|
||||
timediff = Curl_tvdiff(Curl_tvnow(), now); /* spent time */
|
||||
timeout -= timediff?timediff:1; /* always deduct at least 1 */
|
||||
if (timeout < 0) {
|
||||
/* our timeout, so we cancel the ares operation */
|
||||
ares_cancel(data->state.areschannel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Operation complete, if the lookup was successful we now have the entry
|
||||
in the cache. */
|
||||
|
||||
if(entry)
|
||||
*entry = conn->async.dns;
|
||||
|
||||
if(!conn->async.dns) {
|
||||
/* a name was not resolved */
|
||||
if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) {
|
||||
failf(data, "Resolving host timed out: %s", conn->host.dispname);
|
||||
rc = CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
else if(conn->async.done) {
|
||||
failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
|
||||
ares_strerror(conn->async.status));
|
||||
rc = CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
else
|
||||
rc = CURLE_OPERATION_TIMEDOUT;
|
||||
|
||||
/* close the connection, since we can't return failure here without
|
||||
cleaning up this connection properly */
|
||||
Curl_disconnect(conn);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_getaddrinfo() - when using ares
|
||||
*
|
||||
* Returns name information about the given hostname and port number. If
|
||||
* successful, the 'hostent' is returned and the forth argument will point to
|
||||
* memory we need to free after use. That memory *MUST* be freed with
|
||||
* Curl_freeaddrinfo(), nothing else.
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
char *bufp;
|
||||
struct SessionHandle *data = conn->data;
|
||||
in_addr_t in = inet_addr(hostname);
|
||||
|
||||
*waitp = FALSE;
|
||||
|
||||
if (in != CURL_INADDR_NONE)
|
||||
/* This is a dotted IP address 123.123.123.123-style */
|
||||
return Curl_ip2addr(in, hostname);
|
||||
|
||||
bufp = strdup(hostname);
|
||||
|
||||
if(bufp) {
|
||||
Curl_safefree(conn->async.hostname);
|
||||
conn->async.hostname = bufp;
|
||||
conn->async.port = port;
|
||||
conn->async.done = FALSE; /* not done */
|
||||
conn->async.status = 0; /* clear */
|
||||
conn->async.dns = NULL; /* clear */
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
ares_gethostbyname(data->state.areschannel, hostname, PF_INET,
|
||||
Curl_addrinfo_callback, conn);
|
||||
|
||||
*waitp = TRUE; /* please wait for the response */
|
||||
}
|
||||
return NULL; /* no struct yet */
|
||||
}
|
||||
|
||||
#endif /* CURLRES_ARES */
|
154
lib/hostasyn.c
Normal file
154
lib/hostasyn.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, 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
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define _REENTRANT
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETJMP_H
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||
#undef in_addr_t
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||
#include "inet_ntoa_r.h"
|
||||
#endif
|
||||
|
||||
#include "memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for builds using asynchronous name resolves
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_ASYNCH
|
||||
/*
|
||||
* Curl_addrinfo_callback() gets called by ares/gethostbyname_thread() when we
|
||||
* got the name resolved (or not!).
|
||||
*
|
||||
* If the status argument is CURL_ASYNC_SUCCESS, we might need to copy the
|
||||
* address field since it might be freed when this function returns. This
|
||||
* operation stores the resolved data in the DNS cache.
|
||||
*
|
||||
* NOTE: for IPv6 operations, Curl_addrinfo_copy() returns the same
|
||||
* pointer it is given as argument!
|
||||
*
|
||||
* The storage operation locks and unlocks the DNS cache.
|
||||
*/
|
||||
void Curl_addrinfo_callback(void *arg, /* "struct connectdata *" */
|
||||
int status,
|
||||
Curl_addrinfo *hostent)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)arg;
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
|
||||
conn->async.done = TRUE;
|
||||
conn->async.status = status;
|
||||
|
||||
if(CURL_ASYNC_SUCCESS == status) {
|
||||
|
||||
/*
|
||||
* IPv4: Curl_addrinfo_copy() copies the address and returns an allocated
|
||||
* version.
|
||||
*
|
||||
* IPv6: Curl_addrinfo_copy() returns the input pointer!
|
||||
*/
|
||||
Curl_addrinfo *he = Curl_addrinfo_copy(hostent);
|
||||
if(he) {
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
dns = Curl_cache_addr(data, he,
|
||||
conn->async.hostname,
|
||||
conn->async.port);
|
||||
if(!dns)
|
||||
/* failed to store, cleanup and return error */
|
||||
Curl_freeaddrinfo(he);
|
||||
|
||||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
}
|
||||
}
|
||||
|
||||
conn->async.dns = dns;
|
||||
|
||||
/* ipv4: The input hostent struct will be freed by ares when we return from
|
||||
this function */
|
||||
}
|
||||
|
||||
#endif /* CURLRES_ASYNC */
|
1260
lib/hostip.c
1260
lib/hostip.c
File diff suppressed because it is too large
Load Diff
165
lib/hostip.h
165
lib/hostip.h
@@ -1,10 +1,10 @@
|
||||
#ifndef __HOSTIP_H
|
||||
#define __HOSTIP_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
@@ -12,7 +12,7 @@
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
@@ -51,20 +51,42 @@ struct Curl_dns_entry {
|
||||
* The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
|
||||
* use, or we'll leak memory!
|
||||
*/
|
||||
/* return codes */
|
||||
#define CURLRESOLV_ERROR -1
|
||||
#define CURLRESOLV_RESOLVED 0
|
||||
#define CURLRESOLV_PENDING 1
|
||||
int Curl_resolv(struct connectdata *conn, char *hostname,
|
||||
int port, struct Curl_dns_entry **dnsentry);
|
||||
|
||||
int Curl_resolv(struct connectdata *conn,
|
||||
char *hostname,
|
||||
int port,
|
||||
struct Curl_dns_entry **dnsentry);
|
||||
/*
|
||||
* Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
|
||||
* been set and returns TRUE if they are OK.
|
||||
*/
|
||||
bool Curl_ipvalid(struct SessionHandle *data);
|
||||
|
||||
/*
|
||||
* Curl_getaddrinfo() is the generic low-level name resolve API within this
|
||||
* source file. There are several versions of this function - for different
|
||||
* name resolve layers (selected at build-time). They all take this same set
|
||||
* of arguments
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
char *hostname,
|
||||
int port,
|
||||
int *waitp);
|
||||
|
||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dns);
|
||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dnsentry);
|
||||
CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
|
||||
fd_set *read_fd_set,
|
||||
fd_set *write_fd_set,
|
||||
int *max_fdp);
|
||||
|
||||
/* Curl_fdset() is a generic function that exists in multiple versions
|
||||
depending on what name resolve technology we've built to use. The function
|
||||
is called from the curl_multi_fdset() function */
|
||||
CURLcode Curl_fdset(struct connectdata *conn,
|
||||
fd_set *read_fd_set,
|
||||
fd_set *write_fd_set,
|
||||
int *max_fdp);
|
||||
/* unlock a previously resolved dns entry */
|
||||
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns);
|
||||
|
||||
@@ -80,20 +102,127 @@ curl_hash *Curl_mk_dnscache(void);
|
||||
/* prune old entries from the DNS cache */
|
||||
void Curl_hostcache_prune(struct SessionHandle *data);
|
||||
|
||||
/* Return # of adresses in a Curl_addrinfo struct */
|
||||
int Curl_num_addresses (const Curl_addrinfo *addr);
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
void curl_freeaddrinfo(struct addrinfo *freethis,
|
||||
void curl_dofreeaddrinfo(struct addrinfo *freethis,
|
||||
int line, const char *source);
|
||||
int curl_dogetaddrinfo(char *hostname, char *service,
|
||||
struct addrinfo *hints,
|
||||
struct addrinfo **result,
|
||||
int line, const char *source);
|
||||
int curl_dogetnameinfo(const struct sockaddr *sa, socklen_t salen,
|
||||
char *host, size_t hostlen,
|
||||
char *serv, size_t servlen, int flags,
|
||||
int line, const char *source);
|
||||
int curl_getaddrinfo(char *hostname, char *service,
|
||||
struct addrinfo *hints,
|
||||
struct addrinfo **result,
|
||||
int line, const char *source);
|
||||
#endif
|
||||
|
||||
/* This is the callback function that is used when we build with asynch
|
||||
resolve */
|
||||
void Curl_addrinfo_callback(void *arg,
|
||||
int status,
|
||||
Curl_addrinfo *hostent);
|
||||
|
||||
/* This is a utility-function for ipv4-builds to create a hostent struct
|
||||
from a numerical-only IP address */
|
||||
Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname);
|
||||
|
||||
/* relocate a hostent struct */
|
||||
void Curl_hostent_relocate(struct hostent *h, long offset);
|
||||
|
||||
/* copy a Curl_addrinfo struct, currently this only supports copying
|
||||
a hostent (ipv4-style) struct */
|
||||
Curl_addrinfo *Curl_addrinfo_copy(Curl_addrinfo *orig);
|
||||
|
||||
/*
|
||||
* Curl_printable_address() returns a printable version of the 1st address
|
||||
* given in the 'ip' argument. The result will be stored in the buf that is
|
||||
* bufsize bytes big.
|
||||
*/
|
||||
const char *Curl_printable_address(const Curl_ipconnect *ip,
|
||||
char *buf, size_t bufsize);
|
||||
|
||||
/*
|
||||
* Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
|
||||
*
|
||||
* Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
|
||||
*/
|
||||
struct Curl_dns_entry *
|
||||
Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,
|
||||
char *hostname, int port);
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define CURL_INADDR_NONE (in_addr_t) ~0
|
||||
#else
|
||||
#define CURL_INADDR_NONE INADDR_NONE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup comfortable CURLRES_* defines to use in the host*.c sources.
|
||||
*/
|
||||
|
||||
#ifdef USE_ARES
|
||||
#define CURLRES_ASYNCH
|
||||
#define CURLRES_ARES
|
||||
#endif
|
||||
|
||||
#ifdef USE_THREADING_GETHOSTBYNAME
|
||||
#define CURLRES_ASYNCH
|
||||
#define CURLRES_THREADED
|
||||
#endif
|
||||
|
||||
#ifdef USE_THREADING_GETADDRINFO
|
||||
#define CURLRES_ASYNCH
|
||||
#define CURLRES_THREADED
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
#define CURLRES_IPV6
|
||||
#else
|
||||
#define CURLRES_IPV4
|
||||
#endif
|
||||
|
||||
#ifdef CURLRES_IPV4
|
||||
#if !defined(HAVE_GETHOSTBYNAME_R) || defined(CURLRES_ASYNCH)
|
||||
/* If built for ipv4 and missing gethostbyname_r(), or if using async name
|
||||
resolve, we need the Curl_addrinfo_copy() function (which itself needs the
|
||||
Curl_hostent_relocate() function)) */
|
||||
#define CURLRES_ADDRINFO_COPY
|
||||
#define CURLRES_HOSTENT_RELOCATE
|
||||
#endif
|
||||
#endif /* IPv4-only */
|
||||
|
||||
#ifdef HAVE_GETHOSTBYNAME_R_6
|
||||
#define CURLRES_HOSTENT_RELOCATE
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETHOSTBYNAME_R_5
|
||||
#define CURLRES_HOSTENT_RELOCATE
|
||||
#endif
|
||||
|
||||
#ifndef CURLRES_ASYNCH
|
||||
#define CURLRES_SYNCH
|
||||
#endif
|
||||
|
||||
#ifndef USE_LIBIDN
|
||||
#define CURLRES_IDN
|
||||
#endif
|
||||
|
||||
/* Allocate enough memory to hold the full name information structs and
|
||||
* everything. OSF1 is known to require at least 8872 bytes. The buffer
|
||||
* required for storing all possible aliases and IP numbers is according to
|
||||
* Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes!
|
||||
*/
|
||||
#define CURL_HOSTENT_SIZE 9000
|
||||
|
||||
#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this
|
||||
many seconds for a name resolve */
|
||||
|
||||
#ifdef CURLRES_ARES
|
||||
#define CURL_ASYNC_SUCCESS ARES_SUCCESS
|
||||
#else
|
||||
#define CURL_ASYNC_SUCCESS CURLE_OK
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
399
lib/hostip4.c
Normal file
399
lib/hostip4.c
Normal file
@@ -0,0 +1,399 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, 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
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define _REENTRANT
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETJMP_H
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||
#undef in_addr_t
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||
#include "inet_ntoa_r.h"
|
||||
#endif
|
||||
|
||||
#include "memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for plain-ipv4 builds
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_IPV4 /* plain ipv4 code coming up */
|
||||
|
||||
/*
|
||||
* This is a wrapper function for freeing name information in a protocol
|
||||
* independent way. This takes care of using the appropriate underlying
|
||||
* function.
|
||||
*/
|
||||
void Curl_freeaddrinfo(Curl_addrinfo *p)
|
||||
{
|
||||
free(p); /* works fine for the ARES case too */
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
|
||||
* been set and returns TRUE if they are OK.
|
||||
*/
|
||||
bool Curl_ipvalid(struct SessionHandle *data)
|
||||
{
|
||||
if(data->set.ip_version == CURL_IPRESOLVE_V6)
|
||||
/* an ipv6 address was requested and we can't get/use one */
|
||||
return FALSE;
|
||||
|
||||
return TRUE; /* OK, proceed */
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_ip2addr() takes a 32bit ipv4 internet address as input parameter
|
||||
* together with a pointer to the string version of the address, and it
|
||||
* retruns a malloc()ed version of a hostent struct filled in correctly with
|
||||
* information for this address/host.
|
||||
*
|
||||
* The input parameters ARE NOT checked for validity but they are expected
|
||||
* to have been checked already when this is called.
|
||||
*/
|
||||
Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname)
|
||||
{
|
||||
struct hostent *h;
|
||||
struct in_addr *addrentry;
|
||||
struct namebuf {
|
||||
struct hostent hostentry;
|
||||
char *h_addr_list[2];
|
||||
struct in_addr addrentry;
|
||||
char h_name[16]; /* 123.123.123.123 = 15 letters is maximum */
|
||||
} *buf = (struct namebuf *)malloc(sizeof(struct namebuf));
|
||||
|
||||
if(!buf)
|
||||
return NULL; /* major failure */
|
||||
|
||||
h = &buf->hostentry;
|
||||
h->h_addr_list = &buf->h_addr_list[0];
|
||||
addrentry = &buf->addrentry;
|
||||
addrentry->s_addr = num;
|
||||
h->h_addr_list[0] = (char*)addrentry;
|
||||
h->h_addr_list[1] = NULL;
|
||||
h->h_addrtype = AF_INET;
|
||||
h->h_length = sizeof(*addrentry);
|
||||
h->h_name = &buf->h_name[0];
|
||||
h->h_aliases = NULL;
|
||||
|
||||
/* Now store the dotted version of the address */
|
||||
snprintf(h->h_name, 16, "%s", hostname);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
#ifdef CURLRES_SYNCH /* the functions below are for synchronous resolves */
|
||||
|
||||
/*
|
||||
* Curl_getaddrinfo() - the ipv4 synchronous version.
|
||||
*
|
||||
* The original code to this function was once stolen from the Dancer source
|
||||
* code, written by Bjorn Reese, it has since been patched and modified
|
||||
* considerably.
|
||||
*
|
||||
* gethostbyname_r() is the thread-safe version of the gethostbyname()
|
||||
* function. When we build for plain IPv4, we attempt to use this
|
||||
* function. There are _three_ different gethostbyname_r() versions, and we
|
||||
* detect which one this platform supports in the configure script and set up
|
||||
* the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or
|
||||
* HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME
|
||||
* has the corresponding rules. This is primarily on *nix. Note that some unix
|
||||
* flavours have thread-safe versions of the plain gethostbyname() etc.
|
||||
*
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct hostent *h = NULL;
|
||||
in_addr_t in;
|
||||
struct SessionHandle *data = conn->data;
|
||||
(void)port; /* unused in IPv4 code */
|
||||
|
||||
*waitp = 0; /* don't wait, we act synchronously */
|
||||
|
||||
in=inet_addr(hostname);
|
||||
if (in != CURL_INADDR_NONE)
|
||||
/* This is a dotted IP address 123.123.123.123-style */
|
||||
return Curl_ip2addr(in, hostname);
|
||||
|
||||
#if defined(HAVE_GETHOSTBYNAME_R)
|
||||
/*
|
||||
* gethostbyname_r() is the preferred resolve function for many platforms.
|
||||
* Since there are three different versions of it, the following code is
|
||||
* somewhat #ifdef-ridden.
|
||||
*/
|
||||
else {
|
||||
int h_errnop;
|
||||
int res=ERANGE;
|
||||
int step_size=200;
|
||||
int *buf = (int *)calloc(CURL_HOSTENT_SIZE, 1);
|
||||
if(!buf)
|
||||
return NULL; /* major failure */
|
||||
/*
|
||||
* The clearing of the buffer is a workaround for a gethostbyname_r bug in
|
||||
* qnx nto and it is also _required_ for some of these functions on some
|
||||
* platforms.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_GETHOSTBYNAME_R_5
|
||||
/* Solaris, IRIX and more */
|
||||
(void)res; /* prevent compiler warning */
|
||||
while(!h) {
|
||||
h = gethostbyname_r(hostname,
|
||||
(struct hostent *)buf,
|
||||
(char *)buf + sizeof(struct hostent),
|
||||
step_size - sizeof(struct hostent),
|
||||
&h_errnop);
|
||||
|
||||
/* If the buffer is too small, it returns NULL and sets errno to
|
||||
* ERANGE. The errno is thread safe if this is compiled with
|
||||
* -D_REENTRANT as then the 'errno' variable is a macro defined to get
|
||||
* used properly for threads.
|
||||
*/
|
||||
|
||||
if(h || (errno != ERANGE))
|
||||
break;
|
||||
|
||||
step_size+=200;
|
||||
}
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
||||
#endif
|
||||
|
||||
if(h) {
|
||||
int offset;
|
||||
h=(struct hostent *)realloc(buf, step_size);
|
||||
offset=(long)h-(long)buf;
|
||||
Curl_hostent_relocate(h, offset);
|
||||
buf=(int *)h;
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_GETHOSTBYNAME_R_5 */
|
||||
#ifdef HAVE_GETHOSTBYNAME_R_6
|
||||
/* Linux */
|
||||
do {
|
||||
res=gethostbyname_r(hostname,
|
||||
(struct hostent *)buf,
|
||||
(char *)buf + sizeof(struct hostent),
|
||||
step_size - sizeof(struct hostent),
|
||||
&h, /* DIFFERENCE */
|
||||
&h_errnop);
|
||||
/* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
|
||||
* sudden this function returns EAGAIN if the given buffer size is too
|
||||
* small. Previous versions are known to return ERANGE for the same
|
||||
* problem.
|
||||
*
|
||||
* This wouldn't be such a big problem if older versions wouldn't
|
||||
* sometimes return EAGAIN on a common failure case. Alas, we can't
|
||||
* assume that EAGAIN *or* ERANGE means ERANGE for any given version of
|
||||
* glibc.
|
||||
*
|
||||
* For now, we do that and thus we may call the function repeatedly and
|
||||
* fail for older glibc versions that return EAGAIN, until we run out of
|
||||
* buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
|
||||
*
|
||||
* If anyone has a better fix, please tell us!
|
||||
*
|
||||
* -------------------------------------------------------------------
|
||||
*
|
||||
* On October 23rd 2003, Dan C dug up more details on the mysteries of
|
||||
* gethostbyname_r() in glibc:
|
||||
*
|
||||
* In glibc 2.2.5 the interface is different (this has also been
|
||||
* discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
|
||||
* explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
|
||||
* (shipped/upgraded by Redhat 7.2) don't show this behavior!
|
||||
*
|
||||
* In this "buggy" version, the return code is -1 on error and 'errno'
|
||||
* is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
|
||||
* thread-safe variable.
|
||||
*/
|
||||
|
||||
if(((ERANGE == res) || (EAGAIN == res)) ||
|
||||
((res<0) && ((ERANGE == errno) || (EAGAIN == errno))))
|
||||
step_size+=200;
|
||||
else
|
||||
break;
|
||||
} while(step_size <= CURL_HOSTENT_SIZE);
|
||||
|
||||
if(!h) /* failure */
|
||||
res=1;
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
||||
#endif
|
||||
if(!res) {
|
||||
int offset;
|
||||
h=(struct hostent *)realloc(buf, step_size);
|
||||
offset=(long)h-(long)buf;
|
||||
Curl_hostent_relocate(h, offset);
|
||||
buf=(int *)h;
|
||||
}
|
||||
else
|
||||
#endif/* HAVE_GETHOSTBYNAME_R_6 */
|
||||
#ifdef HAVE_GETHOSTBYNAME_R_3
|
||||
/* AIX, Digital Unix/Tru64, HPUX 10, more? */
|
||||
|
||||
/* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of
|
||||
* the plain fact that it does not return unique full buffers on each
|
||||
* call, but instead several of the pointers in the hostent structs will
|
||||
* point to the same actual data! This have the unfortunate down-side that
|
||||
* our caching system breaks down horribly. Luckily for us though, AIX 4.3
|
||||
* and more recent versions have a "completely thread-safe"[*] libc where
|
||||
* all the data is stored in thread-specific memory areas making calls to
|
||||
* the plain old gethostbyname() work fine even for multi-threaded
|
||||
* programs.
|
||||
*
|
||||
* This AIX 4.3 or later detection is all made in the configure script.
|
||||
*
|
||||
* Troels Walsted Hansen helped us work this out on March 3rd, 2003.
|
||||
*
|
||||
* [*] = much later we've found out that it isn't at all "completely
|
||||
* thread-safe", but at least the gethostbyname() function is.
|
||||
*/
|
||||
|
||||
if(CURL_HOSTENT_SIZE >=
|
||||
(sizeof(struct hostent)+sizeof(struct hostent_data))) {
|
||||
|
||||
/* August 22nd, 2000: Albert Chin-A-Young brought an updated version
|
||||
* that should work! September 20: Richard Prescott worked on the buffer
|
||||
* size dilemma.
|
||||
*/
|
||||
|
||||
res = gethostbyname_r(hostname,
|
||||
(struct hostent *)buf,
|
||||
(struct hostent_data *)((char *)buf +
|
||||
sizeof(struct hostent)));
|
||||
h_errnop= errno; /* we don't deal with this, but set it anyway */
|
||||
}
|
||||
else
|
||||
res = -1; /* failure, too smallish buffer size */
|
||||
|
||||
if(!res) { /* success */
|
||||
|
||||
h = (struct hostent*)buf; /* result expected in h */
|
||||
|
||||
/* This is the worst kind of the different gethostbyname_r() interfaces.
|
||||
* Since we don't know how big buffer this particular lookup required,
|
||||
* we can't realloc down the huge alloc without doing closer analysis of
|
||||
* the returned data. Thus, we always use CURL_HOSTENT_SIZE for every
|
||||
* name lookup. Fixing this would require an extra malloc() and then
|
||||
* calling Curl_addrinfo_copy() that subsequent realloc()s down the new
|
||||
* memory area to the actually used amount.
|
||||
*/
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_GETHOSTBYNAME_R_3 */
|
||||
{
|
||||
infof(data, "gethostbyname_r(2) failed for %s\n", hostname);
|
||||
h = NULL; /* set return code to NULL */
|
||||
free(buf);
|
||||
}
|
||||
#else /* HAVE_GETHOSTBYNAME_R */
|
||||
/*
|
||||
* Here is code for platforms that don't have gethostbyname_r() or for
|
||||
* which the gethostbyname() is the preferred() function.
|
||||
*/
|
||||
else {
|
||||
h = gethostbyname(hostname);
|
||||
if (!h)
|
||||
infof(data, "gethostbyname(2) failed for %s\n", hostname);
|
||||
else {
|
||||
/*
|
||||
* Copy the hostent struct right here, as the static one we got a
|
||||
* pointer to might get removed when we don't want/expect that. Windows
|
||||
* (other platforms?) also doesn't allow passing of the returned data
|
||||
* between threads, which thus the copying here them allows the app to
|
||||
* do.
|
||||
*/
|
||||
h = Curl_addrinfo_copy(h);
|
||||
}
|
||||
#endif /*HAVE_GETHOSTBYNAME_R */
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
#endif /* CURLRES_SYNCH */
|
||||
|
||||
#endif /* CURLRES_IPV4 */
|
262
lib/hostip6.c
Normal file
262
lib/hostip6.c
Normal file
@@ -0,0 +1,262 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, 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
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define _REENTRANT
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETJMP_H
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||
#undef in_addr_t
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||
#include "inet_ntoa_r.h"
|
||||
#endif
|
||||
|
||||
#include "memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for ipv6-enabled builds
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_IPV6
|
||||
/*
|
||||
* This is a wrapper function for freeing name information in a protocol
|
||||
* independent way. This takes care of using the appropriate underlaying
|
||||
* function.
|
||||
*/
|
||||
void Curl_freeaddrinfo(Curl_addrinfo *p)
|
||||
{
|
||||
freeaddrinfo(p);
|
||||
}
|
||||
|
||||
#ifdef CURLRES_ASYNCH
|
||||
/*
|
||||
* Curl_addrinfo_copy() is used by the asynch callback to copy a given
|
||||
* address. But this is an ipv6 build and then we don't copy the address, we
|
||||
* just return the same pointer!
|
||||
*/
|
||||
Curl_addrinfo *Curl_addrinfo_copy(Curl_addrinfo *source)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
/* These are strictly for memory tracing and are using the same style as the
|
||||
* family otherwise present in memdebug.c. I put these ones here since they
|
||||
* require a bunch of structs I didn't wanna include in memdebug.c
|
||||
*/
|
||||
int curl_dogetaddrinfo(char *hostname, char *service,
|
||||
struct addrinfo *hints,
|
||||
struct addrinfo **result,
|
||||
int line, const char *source)
|
||||
{
|
||||
int res=(getaddrinfo)(hostname, service, hints, result);
|
||||
if(0 == res) {
|
||||
/* success */
|
||||
if(logfile)
|
||||
fprintf(logfile, "ADDR %s:%d getaddrinfo() = %p\n",
|
||||
source, line, (void *)*result);
|
||||
}
|
||||
else {
|
||||
if(logfile)
|
||||
fprintf(logfile, "ADDR %s:%d getaddrinfo() failed\n",
|
||||
source, line);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int curl_dogetnameinfo(const struct sockaddr *sa, socklen_t salen,
|
||||
char *host, size_t hostlen,
|
||||
char *serv, size_t servlen, int flags,
|
||||
int line, const char *source)
|
||||
{
|
||||
int res=(getnameinfo)(sa, salen, host, hostlen, serv, servlen, flags);
|
||||
if(0 == res) {
|
||||
/* success */
|
||||
if(logfile)
|
||||
fprintf(logfile, "GETNAME %s:%d getnameinfo()\n",
|
||||
source, line);
|
||||
}
|
||||
else {
|
||||
if(logfile)
|
||||
fprintf(logfile, "GETNAME %s:%d getnameinfo() failed = %d\n",
|
||||
source, line, res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void curl_dofreeaddrinfo(struct addrinfo *freethis,
|
||||
int line, const char *source)
|
||||
{
|
||||
(freeaddrinfo)(freethis);
|
||||
if(logfile)
|
||||
fprintf(logfile, "ADDR %s:%d freeaddrinfo(%p)\n",
|
||||
source, line, (void *)freethis);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
|
||||
* been set and returns TRUE if they are OK.
|
||||
*/
|
||||
bool Curl_ipvalid(struct SessionHandle *data)
|
||||
{
|
||||
if(data->set.ip_version == CURL_IPRESOLVE_V6) {
|
||||
/* see if we have an IPv6 stack */
|
||||
curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
if (s == CURL_SOCKET_BAD)
|
||||
/* an ipv6 address was requested and we can't get/use one */
|
||||
return FALSE;
|
||||
sclose(s);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifndef USE_THREADING_GETADDRINFO
|
||||
/*
|
||||
* Curl_getaddrinfo() when built ipv6-enabled (non-threading version).
|
||||
*
|
||||
* Returns name information about the given hostname and port number. If
|
||||
* successful, the 'addrinfo' is returned and the forth argument will point to
|
||||
* memory we need to free after use. That memory *MUST* be freed with
|
||||
* Curl_freeaddrinfo(), nothing else.
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct addrinfo hints, *res;
|
||||
int error;
|
||||
char sbuf[NI_MAXSERV];
|
||||
curl_socket_t s;
|
||||
int pf;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
*waitp=0; /* don't wait, we have the response now */
|
||||
|
||||
/* see if we have an IPv6 stack */
|
||||
s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
/* Some non-IPv6 stacks have been found to make very slow name resolves
|
||||
* when PF_UNSPEC is used, so thus we switch to a mere PF_INET lookup if
|
||||
* the stack seems to be a non-ipv6 one. */
|
||||
|
||||
pf = PF_INET;
|
||||
}
|
||||
else {
|
||||
/* This seems to be an IPv6-capable stack, use PF_UNSPEC for the widest
|
||||
* possible checks. And close the socket again.
|
||||
*/
|
||||
sclose(s);
|
||||
|
||||
/*
|
||||
* Check if a more limited name resolve has been requested.
|
||||
*/
|
||||
switch(data->set.ip_version) {
|
||||
case CURL_IPRESOLVE_V4:
|
||||
pf = PF_INET;
|
||||
break;
|
||||
case CURL_IPRESOLVE_V6:
|
||||
pf = PF_INET6;
|
||||
break;
|
||||
default:
|
||||
pf = PF_UNSPEC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = pf;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
snprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
error = getaddrinfo(hostname, sbuf, &hints, &res);
|
||||
if (error) {
|
||||
infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif /* USE_THREADING_GETADDRINFO */
|
||||
#endif /* ipv6 */
|
||||
|
149
lib/hostsyn.c
Normal file
149
lib/hostsyn.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, 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
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define _REENTRANT
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETJMP_H
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||
#undef in_addr_t
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||
#include "inet_ntoa_r.h"
|
||||
#endif
|
||||
|
||||
#include "memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for builds using synchronous name resolves
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_SYNCH
|
||||
|
||||
/*
|
||||
* Curl_wait_for_resolv() for synch-builds. Curl_resolv() can never return
|
||||
* wait==TRUE, so this function will never be called. If it still gets called,
|
||||
* we return failure at once.
|
||||
*
|
||||
* We provide this function only to allow multi.c to remain unaware if we are
|
||||
* doing asynch resolves or not.
|
||||
*/
|
||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
(void)conn;
|
||||
*entry=NULL;
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will never be called when synch-built. If it still gets
|
||||
* called, we return failure at once.
|
||||
*
|
||||
* We provide this function only to allow multi.c to remain unaware if we are
|
||||
* doing asynch resolves or not.
|
||||
*/
|
||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dns)
|
||||
{
|
||||
(void)conn;
|
||||
*dns = NULL;
|
||||
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
|
||||
/*
|
||||
* We just return OK, this function is never actually used for synch builds.
|
||||
* It is present here to keep #ifdefs out from multi.c
|
||||
*/
|
||||
|
||||
CURLcode Curl_fdset(struct connectdata *conn,
|
||||
fd_set *read_fd_set,
|
||||
fd_set *write_fd_set,
|
||||
int *max_fdp)
|
||||
{
|
||||
(void)conn;
|
||||
(void)read_fd_set;
|
||||
(void)write_fd_set;
|
||||
(void)max_fdp;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* truly sync */
|
550
lib/hostthre.c
Normal file
550
lib/hostthre.c
Normal file
@@ -0,0 +1,550 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, 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
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define _REENTRANT
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETJMP_H
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||
#undef in_addr_t
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "inet_ntop.h"
|
||||
|
||||
#include "memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for Windows threaded name resolves builds
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_THREADED
|
||||
|
||||
/* This function is used to init a threaded resolve */
|
||||
static bool init_resolve_thread(struct connectdata *conn,
|
||||
const char *hostname, int port,
|
||||
const Curl_addrinfo *hints);
|
||||
|
||||
#ifdef CURLRES_IPV4
|
||||
#define THREAD_FUNC gethostbyname_thread
|
||||
#define THREAD_NAME "gethostbyname_thread"
|
||||
#else
|
||||
#define THREAD_FUNC getaddrinfo_thread
|
||||
#define THREAD_NAME "getaddrinfo_thread"
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_THREADING_GETHOSTBYNAME) || \
|
||||
defined(DEBUG_THREADING_GETADDRINFO)
|
||||
/* If this is defined, provide tracing */
|
||||
#define TRACE(args) \
|
||||
do { trace_it("%u: ", __LINE__); trace_it args; } while (0)
|
||||
|
||||
static void trace_it (const char *fmt, ...)
|
||||
{
|
||||
static int do_trace = -1;
|
||||
va_list args;
|
||||
|
||||
if (do_trace == -1) {
|
||||
const char *env = getenv("CURL_TRACE");
|
||||
do_trace = (env && atoi(env) > 0);
|
||||
}
|
||||
if (!do_trace)
|
||||
return;
|
||||
va_start (args, fmt);
|
||||
vfprintf (stderr, fmt, args);
|
||||
fflush (stderr);
|
||||
va_end (args);
|
||||
}
|
||||
#else
|
||||
#define TRACE(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_THREADING_GETADDRINFO
|
||||
static void dump_addrinfo (struct connectdata *conn, const struct addrinfo *ai)
|
||||
{
|
||||
TRACE(("dump_addrinfo:\n"));
|
||||
for ( ; ai; ai = ai->ai_next) {
|
||||
char buf [INET6_ADDRSTRLEN];
|
||||
|
||||
trace_it(" fam %2d, CNAME %s, ",
|
||||
ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
|
||||
if (Curl_printable_address(ai, buf, sizeof(buf)))
|
||||
trace_it("%s\n", buf);
|
||||
else
|
||||
trace_it("failed; %s\n", Curl_strerror(conn,WSAGetLastError()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct thread_data {
|
||||
HANDLE thread_hnd;
|
||||
unsigned thread_id;
|
||||
DWORD thread_status;
|
||||
curl_socket_t dummy_sock; /* dummy for Curl_fdset() */
|
||||
FILE *stderr_file;
|
||||
#ifdef CURLRES_IPV6
|
||||
struct addrinfo hints;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(CURLRES_IPV4)
|
||||
/*
|
||||
* gethostbyname_thread() resolves a name, calls the Curl_addrinfo_callback
|
||||
* and then exits.
|
||||
*
|
||||
* For builds without ARES/ENABLE_IPV6, create a resolver thread and wait on
|
||||
* it.
|
||||
*/
|
||||
static unsigned __stdcall gethostbyname_thread (void *arg)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata*) arg;
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
struct hostent *he;
|
||||
int rc;
|
||||
|
||||
/* Sharing the same _iob[] element with our parent thread should
|
||||
* hopefully make printouts synchronised. I'm not sure it works
|
||||
* with a static runtime lib (MSVC's libc.lib).
|
||||
*/
|
||||
*stderr = *td->stderr_file;
|
||||
|
||||
WSASetLastError (conn->async.status = NO_DATA); /* pending status */
|
||||
he = gethostbyname (conn->async.hostname);
|
||||
if (he) {
|
||||
Curl_addrinfo_callback(conn, CURL_ASYNC_SUCCESS, he);
|
||||
rc = 1;
|
||||
}
|
||||
else {
|
||||
Curl_addrinfo_callback(conn, (int)WSAGetLastError(), NULL);
|
||||
rc = 0;
|
||||
}
|
||||
TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
|
||||
he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
|
||||
return (rc);
|
||||
/* An implicit _endthreadex() here */
|
||||
}
|
||||
|
||||
#elif defined(CURLRES_IPV6)
|
||||
|
||||
/*
|
||||
* getaddrinfo_thread() resolves a name, calls Curl_addrinfo_callback and then
|
||||
* exits.
|
||||
*
|
||||
* For builds without ARES, but with ENABLE_IPV6, create a resolver thread
|
||||
* and wait on it.
|
||||
*/
|
||||
static unsigned __stdcall getaddrinfo_thread (void *arg)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata*) arg;
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
struct addrinfo *res;
|
||||
char service [NI_MAXSERV];
|
||||
int rc;
|
||||
|
||||
*stderr = *td->stderr_file;
|
||||
|
||||
itoa(conn->async.port, service, 10);
|
||||
|
||||
WSASetLastError(conn->async.status = NO_DATA); /* pending status */
|
||||
|
||||
rc = getaddrinfo(conn->async.hostname, service, &td->hints, &res);
|
||||
|
||||
if (rc == 0) {
|
||||
#ifdef DEBUG_THREADING_GETADDRINFO
|
||||
dump_addrinfo (conn, res);
|
||||
#endif
|
||||
Curl_addrinfo_callback(conn, CURL_ASYNC_SUCCESS, res);
|
||||
}
|
||||
else {
|
||||
Curl_addrinfo_callback(conn, (int)WSAGetLastError(), NULL);
|
||||
TRACE(("Winsock-error %d, no address\n", conn->async.status));
|
||||
}
|
||||
return (rc);
|
||||
/* An implicit _endthreadex() here */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* destroy_thread_data() cleans up async resolver data.
|
||||
* Complementary of ares_destroy.
|
||||
*/
|
||||
static void destroy_thread_data (struct Curl_async *async)
|
||||
{
|
||||
if (async->hostname)
|
||||
free(async->hostname);
|
||||
|
||||
if (async->os_specific) {
|
||||
curl_socket_t sock = ((const struct thread_data*)async->os_specific)->dummy_sock;
|
||||
|
||||
if (sock != CURL_SOCKET_BAD)
|
||||
sclose(sock);
|
||||
free(async->os_specific);
|
||||
}
|
||||
async->hostname = NULL;
|
||||
async->os_specific = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* init_resolve_thread() starts a new thread that performs the actual
|
||||
* resolve. This function returns before the resolve is done.
|
||||
*
|
||||
* Returns FALSE in case of failure, otherwise TRUE.
|
||||
*/
|
||||
static bool init_resolve_thread (struct connectdata *conn,
|
||||
const char *hostname, int port,
|
||||
const Curl_addrinfo *hints)
|
||||
{
|
||||
struct thread_data *td = calloc(sizeof(*td), 1);
|
||||
|
||||
if (!td) {
|
||||
SetLastError(ENOMEM);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Curl_safefree(conn->async.hostname);
|
||||
conn->async.hostname = strdup(hostname);
|
||||
if (!conn->async.hostname) {
|
||||
free(td);
|
||||
SetLastError(ENOMEM);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
conn->async.port = port;
|
||||
conn->async.done = FALSE;
|
||||
conn->async.status = 0;
|
||||
conn->async.dns = NULL;
|
||||
conn->async.os_specific = (void*) td;
|
||||
|
||||
td->dummy_sock = CURL_SOCKET_BAD;
|
||||
td->stderr_file = stderr;
|
||||
td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, THREAD_FUNC,
|
||||
conn, 0, &td->thread_id);
|
||||
#ifdef CURLRES_IPV6
|
||||
curlassert(hints);
|
||||
td->hints = *hints;
|
||||
#else
|
||||
(void) hints;
|
||||
#endif
|
||||
|
||||
if (!td->thread_hnd) {
|
||||
SetLastError(errno);
|
||||
TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno)));
|
||||
destroy_thread_data(&conn->async);
|
||||
return FALSE;
|
||||
}
|
||||
/* This socket is only to keep Curl_fdset() and select() happy; should never
|
||||
* become signalled for read/write since it's unbound but Windows needs
|
||||
* atleast 1 socket in select().
|
||||
*/
|
||||
td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Curl_wait_for_resolv() waits for a resolve to finish. This function should
|
||||
* be avoided since using this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
*
|
||||
* This is the version for resolves-in-a-thread.
|
||||
*/
|
||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
struct SessionHandle *data = conn->data;
|
||||
long timeout;
|
||||
DWORD status, ticks;
|
||||
CURLcode rc;
|
||||
|
||||
curlassert (conn && td);
|
||||
|
||||
/* now, see if there's a connect timeout or a regular timeout to
|
||||
use instead of the default one */
|
||||
timeout =
|
||||
conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
|
||||
conn->data->set.timeout ? conn->data->set.timeout :
|
||||
CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
|
||||
ticks = GetTickCount();
|
||||
|
||||
status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout);
|
||||
if (status == WAIT_OBJECT_0 || status == WAIT_ABANDONED) {
|
||||
/* Thread finished before timeout; propagate Winsock error to this thread.
|
||||
* 'conn->async.done = TRUE' is set in Curl_addrinfo_callback().
|
||||
*/
|
||||
WSASetLastError(conn->async.status);
|
||||
GetExitCodeThread(td->thread_hnd, &td->thread_status);
|
||||
TRACE(("%s() status %lu, thread retval %lu, ",
|
||||
THREAD_NAME, status, td->thread_status));
|
||||
}
|
||||
else {
|
||||
conn->async.done = TRUE;
|
||||
td->thread_status = (DWORD)-1;
|
||||
TRACE(("%s() timeout, ", THREAD_NAME));
|
||||
}
|
||||
|
||||
TRACE(("elapsed %lu ms\n", GetTickCount()-ticks));
|
||||
|
||||
CloseHandle(td->thread_hnd);
|
||||
|
||||
if(entry)
|
||||
*entry = conn->async.dns;
|
||||
|
||||
rc = CURLE_OK;
|
||||
|
||||
if (!conn->async.dns) {
|
||||
/* a name was not resolved */
|
||||
if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) {
|
||||
failf(data, "Resolving host timed out: %s", conn->host.name);
|
||||
rc = CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
else if(conn->async.done) {
|
||||
failf(data, "Could not resolve host: %s; %s",
|
||||
conn->host.name, Curl_strerror(conn,conn->async.status));
|
||||
rc = CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
else
|
||||
rc = CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
destroy_thread_data(&conn->async);
|
||||
|
||||
if(CURLE_OK != rc)
|
||||
/* close the connection, since we must not return failure from here
|
||||
without cleaning up this connection properly */
|
||||
Curl_disconnect(conn);
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_is_resolved() is called repeatedly to check if a previous name resolve
|
||||
* request has completed. It should also make sure to time-out if the
|
||||
* operation seems to take too long.
|
||||
*/
|
||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
*entry = NULL;
|
||||
|
||||
if (conn->async.done) {
|
||||
/* we're done */
|
||||
destroy_thread_data(&conn->async);
|
||||
if (!conn->async.dns) {
|
||||
TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n"));
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
*entry = conn->async.dns;
|
||||
TRACE(("resolved okay, dns %p\n", *entry));
|
||||
}
|
||||
else
|
||||
TRACE(("not yet\n"));
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_fdset(struct connectdata *conn,
|
||||
fd_set *read_fd_set,
|
||||
fd_set *write_fd_set,
|
||||
int *max_fdp)
|
||||
{
|
||||
const struct thread_data *td =
|
||||
(const struct thread_data *) conn->async.os_specific;
|
||||
|
||||
if (td && td->dummy_sock != CURL_SOCKET_BAD) {
|
||||
FD_SET(td->dummy_sock,write_fd_set);
|
||||
*max_fdp = td->dummy_sock;
|
||||
}
|
||||
(void) read_fd_set;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifdef CURLRES_IPV4
|
||||
/*
|
||||
* Curl_getaddrinfo() - for Windows threading without ENABLE_IPV6.
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct hostent *h = NULL;
|
||||
struct SessionHandle *data = conn->data;
|
||||
in_addr_t in;
|
||||
|
||||
*waitp = 0; /* don't wait, we act synchronously */
|
||||
|
||||
in = inet_addr(hostname);
|
||||
if (in != CURL_INADDR_NONE)
|
||||
/* This is a dotted IP address 123.123.123.123-style */
|
||||
return Curl_ip2addr(in, hostname);
|
||||
|
||||
/* fire up a new resolver thread! */
|
||||
if (init_resolve_thread(conn, hostname, port, NULL)) {
|
||||
*waitp = TRUE; /* please wait for the response */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* fall-back to blocking version */
|
||||
infof(data, "init_resolve_thread() failed for %s; code %lu\n",
|
||||
hostname, GetLastError());
|
||||
|
||||
h = gethostbyname(hostname);
|
||||
if (!h) {
|
||||
infof(data, "gethostbyname(2) failed for %s:%d; %s\n",
|
||||
hostname, port, Curl_strerror(conn,WSAGetLastError()));
|
||||
return NULL;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
#endif /* CURLRES_IPV4 */
|
||||
|
||||
#ifdef CURLRES_IPV6
|
||||
/*
|
||||
* Curl_getaddrinfo() - for Windows threading IPv6 enabled
|
||||
*/
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct addrinfo hints, *res;
|
||||
int error;
|
||||
char sbuf[NI_MAXSERV];
|
||||
curl_socket_t s;
|
||||
int pf;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
*waitp = FALSE; /* default to synch response */
|
||||
|
||||
/* see if we have an IPv6 stack */
|
||||
s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
if (s == CURL_SOCKET_BAD) {
|
||||
/* Some non-IPv6 stacks have been found to make very slow name resolves
|
||||
* when PF_UNSPEC is used, so thus we switch to a mere PF_INET lookup if
|
||||
* the stack seems to be a non-ipv6 one. */
|
||||
|
||||
pf = PF_INET;
|
||||
}
|
||||
else {
|
||||
/* This seems to be an IPv6-capable stack, use PF_UNSPEC for the widest
|
||||
* possible checks. And close the socket again.
|
||||
*/
|
||||
sclose(s);
|
||||
|
||||
/*
|
||||
* Check if a more limited name resolve has been requested.
|
||||
*/
|
||||
switch(data->set.ip_version) {
|
||||
case CURL_IPRESOLVE_V4:
|
||||
pf = PF_INET;
|
||||
break;
|
||||
case CURL_IPRESOLVE_V6:
|
||||
pf = PF_INET6;
|
||||
break;
|
||||
default:
|
||||
pf = PF_UNSPEC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = pf;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
itoa(port, sbuf, 10);
|
||||
|
||||
/* fire up a new resolver thread! */
|
||||
if (init_resolve_thread(conn, hostname, port, &hints)) {
|
||||
*waitp = TRUE; /* please wait for the response */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* fall-back to blocking version */
|
||||
infof(data, "init_resolve_thread() failed for %s; code %lu\n",
|
||||
hostname, GetLastError());
|
||||
|
||||
error = getaddrinfo(hostname, sbuf, &hints, &res);
|
||||
if (error) {
|
||||
infof(data, "getaddrinfo() failed for %s:%d; %s\n",
|
||||
hostname, port, Curl_strerror(conn,WSAGetLastError()));
|
||||
return NULL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#endif /* CURLRES_IPV6 */
|
||||
#endif /* CURLRES_THREADED */
|
764
lib/http.c
764
lib/http.c
File diff suppressed because it is too large
Load Diff
25
lib/http.h
25
lib/http.h
@@ -2,10 +2,10 @@
|
||||
#define __HTTP_H
|
||||
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
@@ -13,7 +13,7 @@
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
@@ -35,7 +35,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
|
||||
/* protocol-specific functions set up to be called by the main engine */
|
||||
CURLcode Curl_http(struct connectdata *conn);
|
||||
CURLcode Curl_http_done(struct connectdata *conn);
|
||||
CURLcode Curl_http_done(struct connectdata *, CURLcode);
|
||||
CURLcode Curl_http_connect(struct connectdata *conn);
|
||||
|
||||
/* The following functions are defined in http_chunks.c */
|
||||
@@ -45,10 +45,17 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
|
||||
|
||||
/* These functions are in http.c */
|
||||
void Curl_http_auth_stage(struct SessionHandle *data, int stage);
|
||||
CURLcode Curl_http_auth(struct connectdata *conn,
|
||||
int httpcode, char *header);
|
||||
void Curl_http_auth_act(struct connectdata *conn);
|
||||
CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||
int httpcode, char *header);
|
||||
CURLcode Curl_http_auth_act(struct connectdata *conn);
|
||||
|
||||
int Curl_http_should_fail(struct connectdata *conn);
|
||||
|
||||
/* If only the PICKNONE bit is set, there has been a round-trip and we
|
||||
selected to use no auth at all. Ie, we actively select no auth, as opposed
|
||||
to not having one selected. The other CURLAUTH_* defines are present in the
|
||||
public curl/curl.h header. */
|
||||
#define CURLAUTH_PICKNONE (1<<30) /* don't use auth */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -33,16 +33,15 @@
|
||||
#include "urldata.h" /* it includes http_chunks.h */
|
||||
#include "sendf.h" /* for the client write stuff */
|
||||
|
||||
#include "content_encoding.h" /* 08/29/02 jhrg */
|
||||
#include "content_encoding.h"
|
||||
#include "http.h"
|
||||
#include "memory.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Chunk format (simplified):
|
||||
@@ -179,8 +178,6 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
piece = (ch->datasize >= length)?length:ch->datasize;
|
||||
|
||||
/* Write the data portion available */
|
||||
/* Added content-encoding here; untested but almost identical to the
|
||||
tested code in transfer.c. 08/29/02 jhrg */
|
||||
#ifdef HAVE_LIBZ
|
||||
switch (conn->keep.content_encoding) {
|
||||
case IDENTITY:
|
||||
@@ -194,13 +191,15 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
case DEFLATE:
|
||||
/* update conn->keep.str to point to the chunk data. */
|
||||
conn->keep.str = datap;
|
||||
result = Curl_unencode_deflate_write(conn->data, &conn->keep, piece);
|
||||
result = Curl_unencode_deflate_write(conn->data, &conn->keep,
|
||||
(ssize_t)piece);
|
||||
break;
|
||||
|
||||
case GZIP:
|
||||
/* update conn->keep.str to point to the chunk data. */
|
||||
conn->keep.str = datap;
|
||||
result = Curl_unencode_gzip_write(conn->data, &conn->keep, piece);
|
||||
result = Curl_unencode_gzip_write(conn->data, &conn->keep,
|
||||
(ssize_t)piece);
|
||||
break;
|
||||
|
||||
case COMPRESS:
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
@@ -10,7 +10,7 @@
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
@@ -33,33 +33,46 @@
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "strequal.h"
|
||||
|
||||
#include "base64.h"
|
||||
#include "md5.h"
|
||||
#include "http_digest.h"
|
||||
#include "strtok.h"
|
||||
#include "url.h" /* for Curl_safefree() */
|
||||
#include "memory.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
/* Test example header:
|
||||
/* Test example headers:
|
||||
|
||||
WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
|
||||
Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598"
|
||||
|
||||
*/
|
||||
|
||||
CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
char *header) /* rest of the www-authenticate:
|
||||
bool proxy,
|
||||
char *header) /* rest of the *-authenticate:
|
||||
header */
|
||||
{
|
||||
bool more = TRUE;
|
||||
char *token = NULL;
|
||||
char *tmp = NULL;
|
||||
bool foundAuth = FALSE;
|
||||
bool foundAuthInt = FALSE;
|
||||
struct SessionHandle *data=conn->data;
|
||||
bool before = FALSE; /* got a nonce before */
|
||||
struct digestdata *d = &data->state.digest;
|
||||
struct digestdata *d;
|
||||
|
||||
if(proxy) {
|
||||
d = &data->state.proxydigest;
|
||||
}
|
||||
else {
|
||||
d = &data->state.digest;
|
||||
}
|
||||
|
||||
/* skip initial whitespaces */
|
||||
while(*header && isspace((int)*header))
|
||||
@@ -73,7 +86,7 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
before = TRUE;
|
||||
|
||||
/* clear off any former leftovers and init to defaults */
|
||||
Curl_digest_cleanup(data);
|
||||
Curl_digest_cleanup_one(d);
|
||||
|
||||
while(more) {
|
||||
char value[32];
|
||||
@@ -82,7 +95,7 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
|
||||
while(*header && isspace((int)*header))
|
||||
header++;
|
||||
|
||||
|
||||
/* how big can these strings be? */
|
||||
if((2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
|
||||
value, content)) ||
|
||||
@@ -92,18 +105,59 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
value, content)) ) {
|
||||
if(strequal(value, "nonce")) {
|
||||
d->nonce = strdup(content);
|
||||
if(!d->nonce)
|
||||
return CURLDIGEST_NOMEM;
|
||||
}
|
||||
else if(strequal(value, "stale")) {
|
||||
if(strequal(content, "true"))
|
||||
if(strequal(content, "true")) {
|
||||
d->stale = TRUE;
|
||||
}
|
||||
else if(strequal(value, "cnonce")) {
|
||||
d->cnonce = strdup(content);
|
||||
d->nc = 1; /* we make a new nonce now */
|
||||
}
|
||||
}
|
||||
else if(strequal(value, "realm")) {
|
||||
d->realm = strdup(content);
|
||||
if(!d->realm)
|
||||
return CURLDIGEST_NOMEM;
|
||||
}
|
||||
else if(strequal(value, "opaque")) {
|
||||
d->opaque = strdup(content);
|
||||
if(!d->opaque)
|
||||
return CURLDIGEST_NOMEM;
|
||||
}
|
||||
else if(strequal(value, "qop")) {
|
||||
char *tok_buf;
|
||||
/* tokenize the list and choose auth if possible, use a temporary
|
||||
clone of the buffer since strtok_r() ruins it */
|
||||
tmp = strdup(content);
|
||||
if(!tmp)
|
||||
return CURLDIGEST_NOMEM;
|
||||
token = strtok_r(tmp, ",", &tok_buf);
|
||||
while (token != NULL) {
|
||||
if (strequal(token, "auth")) {
|
||||
foundAuth = TRUE;
|
||||
}
|
||||
else if (strequal(token, "auth-int")) {
|
||||
foundAuthInt = TRUE;
|
||||
}
|
||||
token = strtok_r(NULL, ",", &tok_buf);
|
||||
}
|
||||
free(tmp);
|
||||
/*select only auth o auth-int. Otherwise, ignore*/
|
||||
if (foundAuth) {
|
||||
d->qop = strdup("auth");
|
||||
if(!d->qop)
|
||||
return CURLDIGEST_NOMEM;
|
||||
}
|
||||
else if (foundAuthInt) {
|
||||
d->qop = strdup("auth-int");
|
||||
if(!d->qop)
|
||||
return CURLDIGEST_NOMEM;
|
||||
}
|
||||
}
|
||||
else if(strequal(value, "algorithm")) {
|
||||
d->algorithm = strdup(content);
|
||||
if(!d->algorithm)
|
||||
return CURLDIGEST_NOMEM;
|
||||
if(strequal(content, "MD5-sess"))
|
||||
d->algo = CURLDIGESTALGO_MD5SESS;
|
||||
else if(strequal(content, "MD5"))
|
||||
@@ -116,18 +170,17 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
}
|
||||
totlen = strlen(value)+strlen(content)+3;
|
||||
}
|
||||
else
|
||||
else
|
||||
break; /* we're done here */
|
||||
|
||||
|
||||
header += totlen;
|
||||
if(',' == *header)
|
||||
/* allow the list to be comma-separated */
|
||||
header++;
|
||||
header++;
|
||||
}
|
||||
/* We had a nonce since before, and we got another one now without
|
||||
'stale=true'. This means we provided bad credentials in the previous
|
||||
request */
|
||||
|
||||
'stale=true'. This means we provided bad credentials in the previous
|
||||
request */
|
||||
if(before && !d->stale)
|
||||
return CURLDIGEST_BAD;
|
||||
|
||||
@@ -135,7 +188,7 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
if(!d->nonce)
|
||||
return CURLDIGEST_BAD;
|
||||
}
|
||||
else
|
||||
else
|
||||
/* else not a digest, get out */
|
||||
return CURLDIGEST_NONE;
|
||||
|
||||
@@ -152,6 +205,7 @@ static void md5_to_ascii(unsigned char *source, /* 16 bytes */
|
||||
}
|
||||
|
||||
CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
bool proxy,
|
||||
unsigned char *request,
|
||||
unsigned char *uripath)
|
||||
{
|
||||
@@ -159,17 +213,67 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
this sorted out, I must urge you dear friend to read up on the RFC2617
|
||||
section 3.2.2, */
|
||||
unsigned char md5buf[16]; /* 16 bytes/128 bits */
|
||||
unsigned char ha1[33]; /* 32 digits and 1 zero byte */
|
||||
unsigned char ha2[33];
|
||||
unsigned char request_digest[33];
|
||||
unsigned char *md5this;
|
||||
unsigned char *ha1;
|
||||
unsigned char ha2[33];/* 32 digits and 1 zero byte */
|
||||
char cnoncebuf[7];
|
||||
char *cnonce;
|
||||
char *tmp = NULL;
|
||||
struct timeval now;
|
||||
|
||||
char **allocuserpwd;
|
||||
char *userp;
|
||||
char *passwdp;
|
||||
struct auth *authp;
|
||||
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct digestdata *d = &data->state.digest;
|
||||
struct digestdata *d;
|
||||
|
||||
if(proxy) {
|
||||
d = &data->state.proxydigest;
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
authp = &data->state.authproxy;
|
||||
}
|
||||
else {
|
||||
d = &data->state.digest;
|
||||
allocuserpwd = &conn->allocptr.userpwd;
|
||||
userp = conn->user;
|
||||
passwdp = conn->passwd;
|
||||
authp = &data->state.authhost;
|
||||
}
|
||||
|
||||
/* not set means empty */
|
||||
if(!userp)
|
||||
userp=(char *)"";
|
||||
|
||||
if(!passwdp)
|
||||
passwdp=(char *)"";
|
||||
|
||||
if(!d->nonce) {
|
||||
authp->done = FALSE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
authp->done = TRUE;
|
||||
|
||||
if(!d->nc)
|
||||
d->nc = 1;
|
||||
|
||||
if(!d->cnonce) {
|
||||
/* Generate a cnonce */
|
||||
now = Curl_tvnow();
|
||||
snprintf(cnoncebuf, sizeof(cnoncebuf), "%06ld", now.tv_sec);
|
||||
if(Curl_base64_encode(cnoncebuf, strlen(cnoncebuf), &cnonce))
|
||||
d->cnonce = cnonce;
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
if the algorithm is "MD5" or unspecified (which then defaults to MD5):
|
||||
|
||||
|
||||
A1 = unq(username-value) ":" unq(realm-value) ":" passwd
|
||||
|
||||
if the algorithm is "MD5-sess" then:
|
||||
@@ -177,40 +281,76 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
|
||||
":" unq(nonce-value) ":" unq(cnonce-value)
|
||||
*/
|
||||
if(d->algo == CURLDIGESTALGO_MD5SESS) {
|
||||
md5this = (unsigned char *)
|
||||
aprintf("%s:%s:%s:%s:%s",
|
||||
conn->user,
|
||||
d->realm,
|
||||
conn->passwd,
|
||||
d->nonce,
|
||||
d->cnonce);
|
||||
}
|
||||
else {
|
||||
md5this = (unsigned char *)
|
||||
aprintf("%s:%s:%s",
|
||||
conn->user,
|
||||
d->realm,
|
||||
conn->passwd);
|
||||
}
|
||||
|
||||
md5this = (unsigned char *)
|
||||
aprintf("%s:%s:%s", userp, d->realm, passwdp);
|
||||
if(!md5this)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
Curl_md5it(md5buf, md5this);
|
||||
free(md5this); /* free this again */
|
||||
|
||||
ha1 = (unsigned char *)malloc(33); /* 32 digits and 1 zero byte */
|
||||
if(!ha1)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
md5_to_ascii(md5buf, ha1);
|
||||
|
||||
if(d->algo == CURLDIGESTALGO_MD5SESS) {
|
||||
/* nonce and cnonce are OUTSIDE the hash */
|
||||
tmp = aprintf("%s:%s:%s", ha1, d->nonce, d->cnonce);
|
||||
free(ha1);
|
||||
if(!tmp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
ha1 = (unsigned char *)tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
A2 = Method ":" digest-uri-value
|
||||
|
||||
If the "qop" directive's value is "auth" or is unspecified, then A2 is:
|
||||
|
||||
A2 = Method ":" digest-uri-value
|
||||
|
||||
If the "qop" value is "auth-int", then A2 is:
|
||||
|
||||
A2 = Method ":" digest-uri-value ":" H(entity-body)
|
||||
|
||||
(The "Method" value is the HTTP request method as specified in section
|
||||
5.1.1 of RFC 2616)
|
||||
*/
|
||||
|
||||
md5this = (unsigned char *)aprintf("%s:%s", request, uripath);
|
||||
if(!md5this) {
|
||||
free(ha1);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (d->qop && strequal(d->qop, "auth-int")) {
|
||||
/* We don't support auth-int at the moment. I can't see a easy way to get
|
||||
entity-body here */
|
||||
/* TODO: Append H(entity-body)*/
|
||||
}
|
||||
Curl_md5it(md5buf, md5this);
|
||||
free(md5this); /* free this again */
|
||||
md5_to_ascii(md5buf, ha2);
|
||||
|
||||
md5this = (unsigned char *)aprintf("%s:%s:%s", ha1, d->nonce,
|
||||
ha2);
|
||||
|
||||
if (d->qop) {
|
||||
md5this = (unsigned char *)aprintf("%s:%s:%08x:%s:%s:%s",
|
||||
ha1,
|
||||
d->nonce,
|
||||
d->nc,
|
||||
d->cnonce,
|
||||
d->qop,
|
||||
ha2);
|
||||
}
|
||||
else {
|
||||
md5this = (unsigned char *)aprintf("%s:%s:%s",
|
||||
ha1,
|
||||
d->nonce,
|
||||
ha2);
|
||||
}
|
||||
free(ha1);
|
||||
if(!md5this)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
Curl_md5it(md5buf, md5this);
|
||||
free(md5this); /* free this again */
|
||||
md5_to_ascii(md5buf, request_digest);
|
||||
@@ -221,27 +361,83 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
|
||||
*/
|
||||
|
||||
Curl_safefree(conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd =
|
||||
aprintf( "Authorization: Digest "
|
||||
"username=\"%s\", "
|
||||
"realm=\"%s\", "
|
||||
"nonce=\"%s\", "
|
||||
"uri=\"%s\", "
|
||||
"response=\"%s\"\r\n",
|
||||
conn->user,
|
||||
d->realm,
|
||||
d->nonce,
|
||||
uripath, /* this is the PATH part of the URL */
|
||||
request_digest );
|
||||
Curl_safefree(*allocuserpwd);
|
||||
|
||||
if (d->qop) {
|
||||
*allocuserpwd =
|
||||
aprintf( "%sAuthorization: Digest "
|
||||
"username=\"%s\", "
|
||||
"realm=\"%s\", "
|
||||
"nonce=\"%s\", "
|
||||
"uri=\"%s\", "
|
||||
"cnonce=\"%s\", "
|
||||
"nc=%08x, "
|
||||
"qop=\"%s\", "
|
||||
"response=\"%s\"",
|
||||
proxy?"Proxy-":"",
|
||||
userp,
|
||||
d->realm,
|
||||
d->nonce,
|
||||
uripath, /* this is the PATH part of the URL */
|
||||
d->cnonce,
|
||||
d->nc,
|
||||
d->qop,
|
||||
request_digest);
|
||||
|
||||
if(strequal(d->qop, "auth"))
|
||||
d->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0 padded
|
||||
which tells to the server how many times you are using the
|
||||
same nonce in the qop=auth mode. */
|
||||
}
|
||||
else {
|
||||
*allocuserpwd =
|
||||
aprintf( "%sAuthorization: Digest "
|
||||
"username=\"%s\", "
|
||||
"realm=\"%s\", "
|
||||
"nonce=\"%s\", "
|
||||
"uri=\"%s\", "
|
||||
"response=\"%s\"",
|
||||
proxy?"Proxy-":"",
|
||||
userp,
|
||||
d->realm,
|
||||
d->nonce,
|
||||
uripath, /* this is the PATH part of the URL */
|
||||
request_digest);
|
||||
}
|
||||
if(!*allocuserpwd)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Add optional fields */
|
||||
if(d->opaque) {
|
||||
/* append opaque */
|
||||
tmp = aprintf("%s, opaque=\"%s\"", *allocuserpwd, d->opaque);
|
||||
if(!tmp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd = tmp;
|
||||
}
|
||||
|
||||
if(d->algorithm) {
|
||||
/* append algorithm */
|
||||
tmp = aprintf("%s, algorithm=\"%s\"", *allocuserpwd, d->algorithm);
|
||||
if(!tmp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd = tmp;
|
||||
}
|
||||
|
||||
/* append CRLF to the userpwd header */
|
||||
tmp = (char*) realloc(*allocuserpwd, strlen(*allocuserpwd) + 3 + 1);
|
||||
if(!tmp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
strcat(tmp, "\r\n");
|
||||
*allocuserpwd = tmp;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_digest_cleanup(struct SessionHandle *data)
|
||||
void Curl_digest_cleanup_one(struct digestdata *d)
|
||||
{
|
||||
struct digestdata *d = &data->state.digest;
|
||||
|
||||
if(d->nonce)
|
||||
free(d->nonce);
|
||||
d->nonce = NULL;
|
||||
@@ -254,9 +450,28 @@ void Curl_digest_cleanup(struct SessionHandle *data)
|
||||
free(d->realm);
|
||||
d->realm = NULL;
|
||||
|
||||
d->algo = CURLDIGESTALGO_MD5; /* default algorithm */
|
||||
if(d->opaque)
|
||||
free(d->opaque);
|
||||
d->opaque = NULL;
|
||||
|
||||
if(d->qop)
|
||||
free(d->qop);
|
||||
d->qop = NULL;
|
||||
|
||||
if(d->algorithm)
|
||||
free(d->algorithm);
|
||||
d->algorithm = NULL;
|
||||
|
||||
d->nc = 0;
|
||||
d->algo = CURLDIGESTALGO_MD5; /* default algorithm */
|
||||
d->stale = FALSE; /* default means normal, not stale */
|
||||
}
|
||||
|
||||
|
||||
void Curl_digest_cleanup(struct SessionHandle *data)
|
||||
{
|
||||
Curl_digest_cleanup_one(&data->state.digest);
|
||||
Curl_digest_cleanup_one(&data->state.proxydigest);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -27,6 +27,7 @@ typedef enum {
|
||||
CURLDIGEST_NONE, /* not a digest */
|
||||
CURLDIGEST_BAD, /* a digest, but one we don't like */
|
||||
CURLDIGEST_BADALGO, /* unsupported algorithm requested */
|
||||
CURLDIGEST_NOMEM,
|
||||
CURLDIGEST_FINE, /* a digest we act on */
|
||||
|
||||
CURLDIGEST_LAST /* last entry in this enum, don't use */
|
||||
@@ -38,12 +39,15 @@ enum {
|
||||
};
|
||||
|
||||
/* this is for digest header input */
|
||||
CURLdigest Curl_input_digest(struct connectdata *conn, char *header);
|
||||
CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
bool proxy, char *header);
|
||||
|
||||
/* this is for creating digest header output */
|
||||
CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
bool proxy,
|
||||
unsigned char *request,
|
||||
unsigned char *uripath);
|
||||
void Curl_digest_cleanup(struct SessionHandle *data);
|
||||
void Curl_digest_cleanup_one(struct digestdata *dig);
|
||||
|
||||
#endif
|
||||
|
@@ -41,14 +41,13 @@
|
||||
#include "strequal.h"
|
||||
#include "base64.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "memory.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
static int
|
||||
get_gss_name(struct connectdata *conn, gss_name_t *server)
|
||||
@@ -71,10 +70,10 @@ get_gss_name(struct connectdata *conn, gss_name_t *server)
|
||||
else
|
||||
service = "http";
|
||||
|
||||
token.length = strlen(service) + 1 + strlen(conn->hostname) + 1;
|
||||
token.length = strlen(service) + 1 + strlen(conn->host.name) + 1;
|
||||
if (token.length + 1 > sizeof(name))
|
||||
return EMSGSIZE;
|
||||
sprintf(name, "%s@%s", service, conn->hostname);
|
||||
sprintf(name, "%s@%s", service, conn->host.name);
|
||||
|
||||
token.value = (void *) name;
|
||||
major_status = gss_import_name(&minor_status,
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
@@ -10,7 +10,7 @@
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "setup.h"
|
||||
|
||||
/* NTLM details:
|
||||
|
||||
|
||||
http://davenport.sourceforge.net/ntlm.html
|
||||
http://www.innovation.ch/java/ntlm.html
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#include "base64.h"
|
||||
#include "http_ntlm.h"
|
||||
#include "url.h"
|
||||
#include "http.h" /* for Curl_http_auth_stage() */
|
||||
#include "memory.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -72,9 +72,7 @@
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
/* Define this to make the type-3 message include the NT response message */
|
||||
#define USE_NTRESPONSES 1
|
||||
@@ -135,7 +133,7 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn,
|
||||
memcpy(ntlm->nonce, &buffer[24], 8);
|
||||
|
||||
/* at index decimal 20, there's a 32bit NTLM flag field */
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
if(ntlm->state >= NTLMSTATE_TYPE1)
|
||||
@@ -222,7 +220,7 @@ static void mkhash(char *password,
|
||||
|
||||
if (len > 14)
|
||||
len = 14;
|
||||
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
pw[i] = toupper(password[i]);
|
||||
|
||||
@@ -236,7 +234,7 @@ static void mkhash(char *password,
|
||||
setup_des_key(pw, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
|
||||
setup_des_key(pw+7, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
@@ -298,23 +296,26 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
char *passwdp;
|
||||
/* point to the correct struct with this */
|
||||
struct ntlmdata *ntlm;
|
||||
struct auth *authp;
|
||||
|
||||
curlassert(conn);
|
||||
curlassert(conn->data);
|
||||
conn->data->state.authdone = FALSE;
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
ntlm = &conn->proxyntlm;
|
||||
authp = &conn->data->state.authproxy;
|
||||
}
|
||||
else {
|
||||
allocuserpwd = &conn->allocptr.userpwd;
|
||||
userp = conn->user;
|
||||
passwdp = conn->passwd;
|
||||
ntlm = &conn->ntlm;
|
||||
authp = &conn->data->state.authhost;
|
||||
}
|
||||
authp->done = FALSE;
|
||||
|
||||
/* not set means empty */
|
||||
if(!userp)
|
||||
@@ -322,13 +323,13 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
|
||||
if(!passwdp)
|
||||
passwdp=(char *)"";
|
||||
|
||||
|
||||
switch(ntlm->state) {
|
||||
case NTLMSTATE_TYPE1:
|
||||
default: /* for the weird cases we (re)start here */
|
||||
hostoff = 32;
|
||||
domoff = hostoff + hostlen;
|
||||
|
||||
|
||||
/* Create and send a type-1 message:
|
||||
|
||||
Index Description Content
|
||||
@@ -390,7 +391,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case NTLMSTATE_TYPE2:
|
||||
/* We received the type-2 already, create a type-3 message:
|
||||
|
||||
@@ -408,7 +409,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
52 (64) start of data block
|
||||
|
||||
*/
|
||||
|
||||
|
||||
{
|
||||
int lmrespoff;
|
||||
int ntrespoff;
|
||||
@@ -426,12 +427,12 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
|
||||
if (user) {
|
||||
domain = userp;
|
||||
domlen = user - domain;
|
||||
domlen = (int)(user - domain);
|
||||
user++;
|
||||
}
|
||||
else
|
||||
user = userp;
|
||||
userlen = strlen(user);
|
||||
userlen = (int)strlen(user);
|
||||
|
||||
mkhash(passwdp, &ntlm->nonce[0], lmresp
|
||||
#ifdef USE_NTRESPONSES
|
||||
@@ -458,25 +459,25 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
"%c%c" /* NT-response allocated space */
|
||||
"%c%c" /* NT-response offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
|
||||
"%c%c" /* domain length */
|
||||
"%c%c" /* domain allocated space */
|
||||
"%c%c" /* domain name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
|
||||
"%c%c" /* user length */
|
||||
"%c%c" /* user allocated space */
|
||||
"%c%c" /* user offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host allocated space */
|
||||
"%c%c" /* host offset */
|
||||
"%c%c%c%c%c%c" /* 6 zeroes */
|
||||
|
||||
|
||||
"\xff\xff" /* message length */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
|
||||
"\x01\x82" /* flags */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
@@ -493,7 +494,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
SHORTPAIR(0x18),
|
||||
SHORTPAIR(lmrespoff),
|
||||
0x0, 0x0,
|
||||
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
SHORTPAIR(0x18), /* NT-response length, twice */
|
||||
SHORTPAIR(0x18),
|
||||
@@ -513,12 +514,12 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
SHORTPAIR(userlen),
|
||||
SHORTPAIR(useroff),
|
||||
0x0, 0x0,
|
||||
|
||||
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostoff),
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
|
||||
0x0, 0x0,
|
||||
|
||||
0x0, 0x0);
|
||||
@@ -540,7 +541,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
}
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
|
||||
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
|
||||
memcpy(&ntlmbuf[size], ntresp, 0x18);
|
||||
size += 0x18;
|
||||
}
|
||||
@@ -563,11 +564,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
||||
conn->data->state.authdone = TRUE;
|
||||
|
||||
/* Switch to web authentication after proxy authentication is done */
|
||||
if (proxy)
|
||||
Curl_http_auth_stage(conn->data, 401);
|
||||
authp->done = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -578,7 +575,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd=NULL;
|
||||
}
|
||||
conn->data->state.authdone = TRUE;
|
||||
authp->done = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
10
lib/if2ip.c
10
lib/if2ip.c
@@ -73,15 +73,14 @@
|
||||
#endif
|
||||
|
||||
#include "if2ip.h"
|
||||
#include "memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
#define SYS_ERROR -1
|
||||
|
||||
char *Curl_if2ip(char *interface, char *buf, int buf_size)
|
||||
char *Curl_if2ip(const char *interface, char *buf, int buf_size)
|
||||
{
|
||||
int dummy;
|
||||
char *ip=NULL;
|
||||
@@ -125,8 +124,11 @@ char *Curl_if2ip(char *interface, char *buf, int buf_size)
|
||||
|
||||
/* -- end of if2ip() -- */
|
||||
#else
|
||||
char *Curl_if2ip(char *interface, char *buf, int buf_size)
|
||||
char *Curl_if2ip(const char *interface, char *buf, int buf_size)
|
||||
{
|
||||
(void) interface;
|
||||
(void) buf;
|
||||
(void) buf_size;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
@@ -26,7 +26,7 @@
|
||||
|
||||
#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN32__) && \
|
||||
!defined(__riscos__) && !defined(__INTERIX)
|
||||
extern char *Curl_if2ip(char *interface, char *buf, int buf_size);
|
||||
extern char *Curl_if2ip(const char *interface, char *buf, int buf_size);
|
||||
#else
|
||||
#define Curl_if2ip(a,b,c) NULL
|
||||
#endif
|
||||
|
195
lib/inet_ntop.c
Normal file
195
lib/inet_ntop.c
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Original code by Paul Vixie. "curlified" by Gisle Vanem.
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef HAVE_INET_NTOP
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "inet_ntop.h"
|
||||
|
||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||
/* this platform has a inet_ntoa_r() function, but no proto declared anywhere
|
||||
so we include our own proto to make compilers happy */
|
||||
#include "inet_ntoa_r.h"
|
||||
#endif
|
||||
|
||||
#define IN6ADDRSZ 16
|
||||
#define INADDRSZ 4
|
||||
#define INT16SZ 2
|
||||
|
||||
#ifdef WIN32
|
||||
#define EAFNOSUPPORT WSAEAFNOSUPPORT
|
||||
#define SET_ERRNO(e) WSASetLastError(errno = (e))
|
||||
#else
|
||||
#define SET_ERRNO(e) errno = e
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Format an IPv4 address, more or less like inet_ntoa().
|
||||
*
|
||||
* Returns `dst' (as a const)
|
||||
* Note:
|
||||
* - uses no statics
|
||||
* - takes a u_char* not an in_addr as input
|
||||
*/
|
||||
static const char *inet_ntop4 (const u_char *src, char *dst, size_t size)
|
||||
{
|
||||
#ifdef HAVE_INET_NTOA_R
|
||||
return inet_ntoa_r(*(struct in_addr*)src, dst, size);
|
||||
#else
|
||||
const char *addr = inet_ntoa(*(struct in_addr*)src);
|
||||
|
||||
if (strlen(addr) >= size)
|
||||
{
|
||||
SET_ERRNO(ENOSPC);
|
||||
return (NULL);
|
||||
}
|
||||
return strcpy(dst, addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
/*
|
||||
* Convert IPv6 binary address into presentation (printable) format.
|
||||
*/
|
||||
static const char *inet_ntop6 (const u_char *src, char *dst, size_t size)
|
||||
{
|
||||
/*
|
||||
* Note that int32_t and int16_t need only be "at least" large enough
|
||||
* to contain a value of the specified size. On some systems, like
|
||||
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp [sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
|
||||
char *tp;
|
||||
struct {
|
||||
long base;
|
||||
long len;
|
||||
} best, cur;
|
||||
u_long words [IN6ADDRSZ / INT16SZ];
|
||||
int i;
|
||||
|
||||
/* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, 0, sizeof(words));
|
||||
for (i = 0; i < IN6ADDRSZ; i++)
|
||||
words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
|
||||
{
|
||||
if (words[i] == 0)
|
||||
{
|
||||
if (cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
}
|
||||
else if (cur.base != -1)
|
||||
{
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
if ((cur.base != -1) && (best.base == -1 || cur.len > best.len))
|
||||
best = cur;
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
|
||||
{
|
||||
/* Are we inside the best run of 0x00's?
|
||||
*/
|
||||
if (best.base != -1 && i >= best.base && i < (best.base + best.len))
|
||||
{
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Are we following an initial run of 0x00s or any real hex?
|
||||
*/
|
||||
if (i != 0)
|
||||
*tp++ = ':';
|
||||
|
||||
/* Is this address an encapsulated IPv4?
|
||||
*/
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
|
||||
{
|
||||
if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
|
||||
{
|
||||
SET_ERRNO(ENOSPC);
|
||||
return (NULL);
|
||||
}
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += sprintf (tp, "%lx", words[i]);
|
||||
}
|
||||
|
||||
/* Was it a trailing run of 0x00's?
|
||||
*/
|
||||
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
|
||||
/* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((size_t)(tp - tmp) > size)
|
||||
{
|
||||
SET_ERRNO(ENOSPC);
|
||||
return (NULL);
|
||||
}
|
||||
return strcpy (dst, tmp);
|
||||
}
|
||||
#endif /* ENABLE_IPV6 */
|
||||
|
||||
/*
|
||||
* Convert a network format address to presentation format.
|
||||
*
|
||||
* Returns pointer to presentation format address (`dst'),
|
||||
* Returns NULL on error (see errno).
|
||||
*/
|
||||
const char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return inet_ntop4((const u_char*)src, buf, size);
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
return inet_ntop6((const u_char*)src, buf, size);
|
||||
#endif
|
||||
default:
|
||||
SET_ERRNO(EAFNOSUPPORT);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_INET_NTOP */
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user