Compare commits
444 Commits
curl-7_13_
...
curl-7_14_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6e1a986e0f | ||
![]() |
e0785ade35 | ||
![]() |
0177ed6f03 | ||
![]() |
c62635a3b5 | ||
![]() |
0177476fd2 | ||
![]() |
76d7dface7 | ||
![]() |
982ba21460 | ||
![]() |
6081c60556 | ||
![]() |
2fe3c22108 | ||
![]() |
75dbb3189a | ||
![]() |
32330300a9 | ||
![]() |
64414df27e | ||
![]() |
f98ec86798 | ||
![]() |
87bbd13899 | ||
![]() |
51a4493add | ||
![]() |
5effe8f336 | ||
![]() |
296eb2bd61 | ||
![]() |
9853acba66 | ||
![]() |
09cb9c782d | ||
![]() |
575ce905b2 | ||
![]() |
54887af471 | ||
![]() |
573350637e | ||
![]() |
49a16f7121 | ||
![]() |
a4773fcbbb | ||
![]() |
1e038c4bc6 | ||
![]() |
6ba19692a3 | ||
![]() |
432dfe2b8f | ||
![]() |
a142372750 | ||
![]() |
f14195f786 | ||
![]() |
9d54f9a6b7 | ||
![]() |
ebb91191bf | ||
![]() |
8742e294d4 | ||
![]() |
8882d1fa1b | ||
![]() |
0c37ab5255 | ||
![]() |
747a05844d | ||
![]() |
c7b7bf32f8 | ||
![]() |
710ee3b0e0 | ||
![]() |
7a8993892d | ||
![]() |
5e16a77fa9 | ||
![]() |
ef35519696 | ||
![]() |
d5baaf7756 | ||
![]() |
2a94387fc3 | ||
![]() |
6a5c2b0fc3 | ||
![]() |
fc281d6440 | ||
![]() |
e22ac39da4 | ||
![]() |
34cadb1e54 | ||
![]() |
94692b904e | ||
![]() |
18f3087afd | ||
![]() |
15bc228ae9 | ||
![]() |
2b7a38d032 | ||
![]() |
90e1a6905a | ||
![]() |
c36af24cbd | ||
![]() |
a676c18502 | ||
![]() |
362912ff83 | ||
![]() |
46ff13f243 | ||
![]() |
340a67a6f8 | ||
![]() |
9294c1e76c | ||
![]() |
fd704f8de0 | ||
![]() |
d9ca9154d1 | ||
![]() |
35110eca73 | ||
![]() |
9ad92b3007 | ||
![]() |
2f78c96330 | ||
![]() |
639857ceb2 | ||
![]() |
162f58c53c | ||
![]() |
84c4d96e71 | ||
![]() |
c0d343d56d | ||
![]() |
6d14a80608 | ||
![]() |
f451bb7c49 | ||
![]() |
20b17d6b04 | ||
![]() |
bb2317b63c | ||
![]() |
189461dc98 | ||
![]() |
69af552bc1 | ||
![]() |
0ae6ff9f72 | ||
![]() |
8b571fbbb1 | ||
![]() |
f3fcd409d5 | ||
![]() |
a47532f88a | ||
![]() |
6c157a404b | ||
![]() |
4f8a49143d | ||
![]() |
493d6033aa | ||
![]() |
8f219af884 | ||
![]() |
aeb04136f7 | ||
![]() |
0b8f57bf06 | ||
![]() |
6508d446e1 | ||
![]() |
82cb462bb4 | ||
![]() |
9a264bf610 | ||
![]() |
57007e80a9 | ||
![]() |
b6c876bdb6 | ||
![]() |
57afae79eb | ||
![]() |
84c2184909 | ||
![]() |
e358a24a75 | ||
![]() |
9da9d00c62 | ||
![]() |
ec3f269d1f | ||
![]() |
1c388a52a5 | ||
![]() |
34a827bbfe | ||
![]() |
726b9e2240 | ||
![]() |
2236ba0d20 | ||
![]() |
463c0f7096 | ||
![]() |
e49a7e361c | ||
![]() |
6e87cf5b30 | ||
![]() |
5872e8dd7e | ||
![]() |
e81d4ac8c8 | ||
![]() |
4922904991 | ||
![]() |
decae2dcda | ||
![]() |
16bbd13af7 | ||
![]() |
ee0666c8df | ||
![]() |
a8a8ae2e92 | ||
![]() |
fd1148a728 | ||
![]() |
74c7b41ee7 | ||
![]() |
465e19dbe9 | ||
![]() |
86660c73e5 | ||
![]() |
6d8a208df2 | ||
![]() |
c3a826fdce | ||
![]() |
c5d6a42abf | ||
![]() |
d49c144297 | ||
![]() |
e7de7d5eb3 | ||
![]() |
20005a83d2 | ||
![]() |
27926030f9 | ||
![]() |
701de67b79 | ||
![]() |
883479f01e | ||
![]() |
b37a0b0512 | ||
![]() |
5c5d5270d2 | ||
![]() |
36461fb2aa | ||
![]() |
d8dcd5e472 | ||
![]() |
c51b46c982 | ||
![]() |
b1b63c1dd1 | ||
![]() |
30c93d66eb | ||
![]() |
3b60bb7259 | ||
![]() |
c73f8e835f | ||
![]() |
93558c4299 | ||
![]() |
396cff5779 | ||
![]() |
336154e729 | ||
![]() |
bb0aba34fa | ||
![]() |
1dc0ce9562 | ||
![]() |
e4aee168b5 | ||
![]() |
2c10c895da | ||
![]() |
c04fae3096 | ||
![]() |
a214af0830 | ||
![]() |
f21bc46e82 | ||
![]() |
044327a488 | ||
![]() |
c4bbcc83b6 | ||
![]() |
eb162b73c2 | ||
![]() |
29aafb9cea | ||
![]() |
40eb7d0d48 | ||
![]() |
1dcb2b7e65 | ||
![]() |
5470b9aa73 | ||
![]() |
050bd7dd0b | ||
![]() |
f75038634f | ||
![]() |
300b4a9158 | ||
![]() |
52071f3476 | ||
![]() |
42ddd745f8 | ||
![]() |
a7846189cd | ||
![]() |
4762995d1f | ||
![]() |
e3a530eb61 | ||
![]() |
d1235ff058 | ||
![]() |
4370e92dbd | ||
![]() |
50e9522a06 | ||
![]() |
b5bb9aa8e3 | ||
![]() |
cf2e365f23 | ||
![]() |
72e532cb67 | ||
![]() |
ac5635f77d | ||
![]() |
640d67c119 | ||
![]() |
3e79693e3b | ||
![]() |
d55d3c2fd0 | ||
![]() |
3aced17c75 | ||
![]() |
bac63914db | ||
![]() |
6a63c51f7c | ||
![]() |
632cf13767 | ||
![]() |
e7012a515c | ||
![]() |
6b638af92f | ||
![]() |
c654b79c53 | ||
![]() |
bee7b874ea | ||
![]() |
9c3fc592f7 | ||
![]() |
4eab7a1ebc | ||
![]() |
3d985688e4 | ||
![]() |
17ea2631cd | ||
![]() |
b749910e6c | ||
![]() |
eff36caea8 | ||
![]() |
6ff092f140 | ||
![]() |
28bb36e53d | ||
![]() |
4a091bbd8a | ||
![]() |
e99a6b813e | ||
![]() |
b9e5302f27 | ||
![]() |
dd7b6aef39 | ||
![]() |
910b8b6a69 | ||
![]() |
c3207e215f | ||
![]() |
f83be11b85 | ||
![]() |
45bce1062a | ||
![]() |
8cb344bf3c | ||
![]() |
fcc4518cdc | ||
![]() |
c84839eb91 | ||
![]() |
1f878aee69 | ||
![]() |
84fd4686e2 | ||
![]() |
ede9fb4fcc | ||
![]() |
723aef71e8 | ||
![]() |
48964a911e | ||
![]() |
6a35cb60fd | ||
![]() |
1e51c3a832 | ||
![]() |
205dda2b39 | ||
![]() |
1c18d19da0 | ||
![]() |
645729e943 | ||
![]() |
f425a25c98 | ||
![]() |
aaace2e802 | ||
![]() |
3f16d9fbc9 | ||
![]() |
3afc57bab8 | ||
![]() |
55225106b6 | ||
![]() |
1a31bff9fe | ||
![]() |
4eaa3329ec | ||
![]() |
028d78b993 | ||
![]() |
944af98be6 | ||
![]() |
2789b2b0ad | ||
![]() |
7dded571de | ||
![]() |
95fe8372e8 | ||
![]() |
ecdcb0ef67 | ||
![]() |
6a04a03eb5 | ||
![]() |
0c96056a94 | ||
![]() |
f518a5e231 | ||
![]() |
f581c1062e | ||
![]() |
0b3deceea3 | ||
![]() |
fa4cd8868c | ||
![]() |
8c573ca7f3 | ||
![]() |
5a5cf3a51d | ||
![]() |
3f23e8443e | ||
![]() |
a00f9b093c | ||
![]() |
5f538ce3f8 | ||
![]() |
ebcaa3d579 | ||
![]() |
60e26199a2 | ||
![]() |
11defd180c | ||
![]() |
c82c1691ee | ||
![]() |
364562f209 | ||
![]() |
5d9fc28fa7 | ||
![]() |
e5ec5c284f | ||
![]() |
a90e33ad71 | ||
![]() |
62ab21ce7d | ||
![]() |
cc8e8db1e5 | ||
![]() |
b19cba2016 | ||
![]() |
315a9c95d5 | ||
![]() |
e010ac9706 | ||
![]() |
e4c0a85da0 | ||
![]() |
d3e4cdd5b0 | ||
![]() |
763b812dc7 | ||
![]() |
3269dfb4ab | ||
![]() |
e816bd259f | ||
![]() |
a295408e09 | ||
![]() |
42a34c7cd7 | ||
![]() |
9a72751958 | ||
![]() |
314e6fa80b | ||
![]() |
b2b66f749a | ||
![]() |
708ed6fded | ||
![]() |
5c30fa50d6 | ||
![]() |
fc33c424d9 | ||
![]() |
b04d6dd0b1 | ||
![]() |
9c5f79c56a | ||
![]() |
ef5eea689a | ||
![]() |
fd191deb49 | ||
![]() |
e1da1ff7d3 | ||
![]() |
2b00ed7ef8 | ||
![]() |
d960ea959d | ||
![]() |
274842ec41 | ||
![]() |
c06da7c84a | ||
![]() |
cea117b509 | ||
![]() |
6078c938b2 | ||
![]() |
9e95dd4821 | ||
![]() |
0cc8b57d4f | ||
![]() |
2179e6e797 | ||
![]() |
7dde3d1825 | ||
![]() |
a0fe950b75 | ||
![]() |
44985e8884 | ||
![]() |
f03366bcbf | ||
![]() |
d43ea83033 | ||
![]() |
11bdba0007 | ||
![]() |
07e58aaa79 | ||
![]() |
a31ddd363b | ||
![]() |
ed9e10f2d8 | ||
![]() |
02ae3c2810 | ||
![]() |
669ebb5f71 | ||
![]() |
9a3e0e52cb | ||
![]() |
b0f856213d | ||
![]() |
6f4ff1f2bf | ||
![]() |
d3eea61f1f | ||
![]() |
d59d81fae8 | ||
![]() |
329ca40b6f | ||
![]() |
e71bd416f4 | ||
![]() |
ad66fc6cc2 | ||
![]() |
d12b44204b | ||
![]() |
4be2136de4 | ||
![]() |
c4dbed040b | ||
![]() |
366b62af2d | ||
![]() |
a6955aa486 | ||
![]() |
ad30341fa2 | ||
![]() |
23da55a9f1 | ||
![]() |
41e6292e7b | ||
![]() |
ae1d6f29d9 | ||
![]() |
ccfc1ddbef | ||
![]() |
002de1eae2 | ||
![]() |
63621bae81 | ||
![]() |
85f9e6c4b9 | ||
![]() |
967ec296c0 | ||
![]() |
c6aae9b1d7 | ||
![]() |
913c370c25 | ||
![]() |
e5472bbd21 | ||
![]() |
957c258c6d | ||
![]() |
abee109cd1 | ||
![]() |
502e5ae6e1 | ||
![]() |
b8417be1f2 | ||
![]() |
9e037431b4 | ||
![]() |
f71b3676bb | ||
![]() |
50fe7b5e35 | ||
![]() |
9fb253388b | ||
![]() |
8cf1786296 | ||
![]() |
51b17b299c | ||
![]() |
78882e4642 | ||
![]() |
8465a367a4 | ||
![]() |
3bcfe678ab | ||
![]() |
d5403f3a5b | ||
![]() |
26abb48533 | ||
![]() |
177848ed27 | ||
![]() |
656a2e93d7 | ||
![]() |
6b1220b61d | ||
![]() |
9d7330d879 | ||
![]() |
26a5954fa0 | ||
![]() |
01165e08e0 | ||
![]() |
6e1633a6c5 | ||
![]() |
a8ff0a21bf | ||
![]() |
b8bc6bed97 | ||
![]() |
1a4402038c | ||
![]() |
5ac51cc9b5 | ||
![]() |
c12159ce21 | ||
![]() |
4485503ecc | ||
![]() |
200ac588cc | ||
![]() |
0bb040822d | ||
![]() |
543fbe14ee | ||
![]() |
e02ab66120 | ||
![]() |
76c7c694c5 | ||
![]() |
f0057977b7 | ||
![]() |
e8e43f06af | ||
![]() |
04b35e86d5 | ||
![]() |
64ab85da4f | ||
![]() |
b8d7a13ea3 | ||
![]() |
78a76dc905 | ||
![]() |
5fa5fff0e9 | ||
![]() |
d323b3d816 | ||
![]() |
b685b5672a | ||
![]() |
8f6c2f87c8 | ||
![]() |
f30e8b11eb | ||
![]() |
8bd6d6a4de | ||
![]() |
b3a8f438fc | ||
![]() |
e78ddf0a95 | ||
![]() |
5f0366c2cb | ||
![]() |
779ca09775 | ||
![]() |
313f1a1e83 | ||
![]() |
21337f4776 | ||
![]() |
53a8e5655b | ||
![]() |
2d85585ae1 | ||
![]() |
63d109f7be | ||
![]() |
c904b6b5bf | ||
![]() |
6a27449922 | ||
![]() |
9a9c07f571 | ||
![]() |
4382204e1b | ||
![]() |
6d3114efe2 | ||
![]() |
b62baaed95 | ||
![]() |
9b391e531b | ||
![]() |
a0c7a6d22b | ||
![]() |
14424f7058 | ||
![]() |
6063dff8d0 | ||
![]() |
7fba9ed398 | ||
![]() |
53280a196b | ||
![]() |
0bf9a5704b | ||
![]() |
8182d17ae1 | ||
![]() |
69b1ac7dcd | ||
![]() |
b15507aac3 | ||
![]() |
6c2f583f51 | ||
![]() |
a72eaddda3 | ||
![]() |
dc050e45df | ||
![]() |
2fcbf13920 | ||
![]() |
099ae31523 | ||
![]() |
c2fcdf3a02 | ||
![]() |
2056a538b9 | ||
![]() |
cd1144dc24 | ||
![]() |
e9d068b913 | ||
![]() |
ec2ad57c32 | ||
![]() |
316adac511 | ||
![]() |
d7b11d4c33 | ||
![]() |
c52aa6df33 | ||
![]() |
a19b23b59f | ||
![]() |
4e26b2a65b | ||
![]() |
7c4feac6db | ||
![]() |
e01e364c37 | ||
![]() |
c13a3d7b84 | ||
![]() |
67805b6dc5 | ||
![]() |
0050ab2a3d | ||
![]() |
60e66c6cbf | ||
![]() |
5ad2a253e8 | ||
![]() |
b5d50e9298 | ||
![]() |
37f7362aca | ||
![]() |
bee198def5 | ||
![]() |
f09e479fd6 | ||
![]() |
80fe93bc33 | ||
![]() |
ea03ad3bee | ||
![]() |
feec421744 | ||
![]() |
634982840e | ||
![]() |
fb3c85ab2f | ||
![]() |
a9b7c3531c | ||
![]() |
a7ba0d908d | ||
![]() |
2fc70e2c5d | ||
![]() |
7ae3f0e70c | ||
![]() |
9afaa51e3f | ||
![]() |
c736a719f1 | ||
![]() |
37a547842b | ||
![]() |
b9f1d43921 | ||
![]() |
bec6423c02 | ||
![]() |
241b2b4ae3 | ||
![]() |
14d9b56937 | ||
![]() |
1c3766eb46 | ||
![]() |
70024d61eb | ||
![]() |
2085f133d6 | ||
![]() |
2a045dfceb | ||
![]() |
893cbaaf2f | ||
![]() |
6e61939382 | ||
![]() |
015a618172 | ||
![]() |
2a8b91cdb9 | ||
![]() |
bebd5dbc5a | ||
![]() |
018dbfe058 | ||
![]() |
c6ea597817 | ||
![]() |
175b00c0a2 | ||
![]() |
5ebc6e305e | ||
![]() |
993600761f | ||
![]() |
1d9fff80b7 | ||
![]() |
c712b84dd5 | ||
![]() |
dcf8dd4b5e | ||
![]() |
ba26c3fb22 | ||
![]() |
41563607a8 | ||
![]() |
2d4dcfb740 | ||
![]() |
34854e70cf | ||
![]() |
758d9fe852 | ||
![]() |
6a6c0e7a73 | ||
![]() |
ee44eec3e1 | ||
![]() |
eccd0d8e37 | ||
![]() |
983be0ec60 | ||
![]() |
243a45d840 | ||
![]() |
60ec804047 | ||
![]() |
c53e9ccf4a | ||
![]() |
6e8e0418fc | ||
![]() |
e9eb52305f | ||
![]() |
8501ae748c |
419
CHANGES
419
CHANGES
@@ -7,6 +7,425 @@
|
||||
Changelog
|
||||
|
||||
|
||||
Version 7.14.1 (1 September 2005)
|
||||
|
||||
Daniel (29 August 2005)
|
||||
- Kevin Lussier pointed out a problem with curllib.dsp and how to fix it.
|
||||
|
||||
- Igor Polyakov fixed a rather nasty problem with the threaded name resolver
|
||||
for Windows, that could lead to an Access Violation when the multi interface
|
||||
was used due to an issue with how the resolver thread was and was not
|
||||
terminated.
|
||||
|
||||
- Simon Josefsson brought a patch that allows curl to get built to use GNU GSS
|
||||
instead of MIT/Heimdal for GSS capabilities.
|
||||
|
||||
Daniel (24 August 2005)
|
||||
- Toby Peterson added CURLOPT_IGNORE_CONTENT_LENGTH to the library, accessible
|
||||
from the command line tool with --ignore-content-length. This will make it
|
||||
easier to download files from Apache 1.x (and similar) servers that are
|
||||
still having problems serving files larger than 2 or 4 GB. When this option
|
||||
is enabled, curl will simply have to wait for the server to close the
|
||||
connection to signal end of transfer. I wrote test case 269 that runs a
|
||||
simple test to verify that this works.
|
||||
|
||||
- (Trying hard to exclude emotions now.) valgrind version 3 suddenly renamed
|
||||
the --logfile command line option to --log-file, and thus the test script
|
||||
valgrind autodetection now has yet another version check to do and then it
|
||||
alters the valgrind command line accordingly.
|
||||
|
||||
- Fixed CA cert verification using GnuTLS with the default bundle, which
|
||||
previously failed due to GnuTLS not allowing x509 v1 CA certs by default.
|
||||
Ralph Mitchell reported.
|
||||
|
||||
Daniel (19 August 2005)
|
||||
- Norbert Novotny had problems with FTPS and he helped me work out a patch
|
||||
that made curl run fine in his end. The key was to make sure we do the
|
||||
SSL/TLS negotiation immediately after the TCP connect is done and not after
|
||||
a few other commands have been sent like we did previously. I don't consider
|
||||
this change necessary to obey the standards, I think this server is pickier
|
||||
than what the specs allow it to be, but I can't see how this modified
|
||||
libcurl code can add any problems to those who are interpreting the
|
||||
standards more liberally.
|
||||
|
||||
Daniel (17 August 2005)
|
||||
- Jeff Pohlmeyer found out that if you ask libcurl to load a cookiefile (with
|
||||
CURLOPT_COOKIEFILE), add a cookie (with CURLOPT_COOKIELIST), tell it to
|
||||
write the result to a given cookie jar and then never actually call
|
||||
curl_easy_perform() - the given file(s) to read was never read but the
|
||||
output file was written and thus it caused a "funny" result.
|
||||
|
||||
- While doing some tests for the bug above, I noticed that Firefox generates
|
||||
large numbers (for the expire time) in the cookies.txt file and libcurl
|
||||
didn't treat them properly. Now it does.
|
||||
|
||||
Daniel (15 August 2005)
|
||||
- Added more verbose "warning" messages to the curl client for cases where it
|
||||
fails to open/read files etc to help users diagnose why it doesn't do what
|
||||
you'd expect it to. Converted lots of old messages to use the new generic
|
||||
function I wrote for this purpose.
|
||||
|
||||
Daniel (13 August 2005)
|
||||
- James Bursa identified a libcurl HTTP bug and a good way to repeat it. If a
|
||||
site responds with bad HTTP response that doesn't contain any header at all,
|
||||
only a response body, and the write callback returns 0 to abort the
|
||||
transfer, it didn't have any real effect but the write callback would be
|
||||
called once more anyway.
|
||||
|
||||
Daniel (12 August 2005)
|
||||
- Based on Richard Clayton's reports, I found out that using curl -d @filename
|
||||
when 'filename' was not possible to access made curl use a GET request
|
||||
instead.
|
||||
|
||||
- The time condition illegal syntax warning is now inhibited if -s is used.
|
||||
|
||||
Daniel (10 August 2005)
|
||||
- Mario Schroeder found out that one of the debug callbacks calls that regards
|
||||
SSL data with the CURLINFO_TEXT type claimed that the data was one byte
|
||||
larger than it actually is, thus falsely telling the application that the
|
||||
terminating zero was part of the data.
|
||||
|
||||
Daniel (9 August 2005)
|
||||
- Christopher R. Palmer fixed the offsets used for date parsings when the time
|
||||
zone name of a daylight savings time was used. For example, PDT vs PDS. This
|
||||
flaw was introduced with the new date parser (11 sep 2004 - 7.12.2).
|
||||
Fortunately, no web server or cookie string etc should be using such time
|
||||
zone names thus limiting the effect of this bug.
|
||||
|
||||
Daniel (8 August 2005)
|
||||
- Jon Grubbs filed bug report #1249962 which identified a problem with NTLM on
|
||||
a HTTP proxy if an FTP URL was given. libcurl now properly switches to pure
|
||||
HTTP internally when an HTTP proxy is used, even for FTP URLs. The problem
|
||||
would also occur with other multi-pass auth methods.
|
||||
|
||||
Daniel (7 August 2005)
|
||||
- When curl is built with GnuTLS, curl-config didn't include "SSL" when
|
||||
--features was used.
|
||||
|
||||
Daniel (28 July 2005)
|
||||
- If any of the options CURLOPT_HTTPGET, CURLOPT_POST and CURLOPT_HTTPPOST is
|
||||
set to 1, CURLOPT_NOBODY will now automatically be set to 0.
|
||||
|
||||
Daniel (27 July 2005)
|
||||
- Dan Fandrich changes over the last week: fixed numerous minor configure
|
||||
option parsing flaws: --without-gnutls, --without-spnego --without-gssapi
|
||||
and --without-krb4. Spellfixed several error messages.
|
||||
|
||||
- Peteris Krumins added CURLOPT_COOKIELIST and CURLINFO_COOKIELIST, which is a
|
||||
simple interface to extracting and setting cookies in libcurl's internal
|
||||
"cookie jar". See the new cookie_interface.c example code.
|
||||
|
||||
Daniel (13 July 2005)
|
||||
- Diego Casorran provided patches to make curl build fine on Amiga again.
|
||||
|
||||
Daniel (12 July 2005)
|
||||
- Adrian Schuur added trailer support in the chunked encoding stream. The
|
||||
trailer is then sent to the normal header callback/stream. I wrote up test
|
||||
case 266 to verify the basic functionality. Do note that test case 34
|
||||
contains a flawed chunked encoding stream that still works the same.
|
||||
|
||||
Daniel (5 July 2005)
|
||||
- Gisle Vanem came up with a nice little work-around for bug #1230118. It
|
||||
seems the Windows (MSVC) libc time functions may return data one hour off if
|
||||
TZ is not set and automatic DST adjustment is enabled. This made
|
||||
curl_getdate() return wrong value, and it also concerned internal cookie
|
||||
expirations etc.
|
||||
|
||||
Daniel (4 July 2005)
|
||||
- Andrew Bushnell provided enough info for me to tell that we badly needed to
|
||||
fix the CONNECT authentication code with multi-pass auth methods (such as
|
||||
NTLM) as it didn't previously properly ignore response-bodies - in fact it
|
||||
stopped reading after all response headers had been received. This could
|
||||
lead to libcurl sending the next request and reading the body from the first
|
||||
request as response to the second request. (I also renamed the function,
|
||||
which wasn't strictly necessary but...)
|
||||
|
||||
The best fix would to once and for all make the CONNECT code use the
|
||||
ordinary request sending/receiving code, treating it as any ordinary request
|
||||
instead of the special-purpose function we have now. It should make it
|
||||
better for multi-interface too. And possibly lead to less code...
|
||||
|
||||
Added test case 265 for this. It doesn't work as a _really_ good test case
|
||||
since the test proxy is too stupid, but the test case helps when running the
|
||||
debugger to verify.
|
||||
|
||||
Daniel (30 June 2005)
|
||||
- Dan Fandrich improved the configure script's ability to figure out what kind
|
||||
of strerror_r() API that is used when cross-compiling. If __GLIB__ is
|
||||
defined, it assumes the glibc API. If not, it issues a notice as before that
|
||||
the user needs to manually edit lib/config.h for this.
|
||||
|
||||
Daniel (23 June 2005)
|
||||
- David Shaw's fix that unifies proxy string treatment so that a proxy given
|
||||
with CURLOPT_PROXY can use a http:// prefix and user + password. The user
|
||||
and password fields are now also URL decoded properly. Test case 264 added
|
||||
to verify.
|
||||
|
||||
Daniel (22 June 2005)
|
||||
- David Shaw updated libcurl.m4
|
||||
|
||||
Daniel (14 June 2005)
|
||||
- Gisle Vanem fixed a potential thread handle leak. Bug report #1216500.
|
||||
Comment in http://curl.haxx.se/mail/lib-2005-06/0059.html
|
||||
|
||||
Daniel (13 June 2005)
|
||||
- Made buildconf run libtoolize in the ares dir too (inspired by Tupone's
|
||||
reverted patch).
|
||||
|
||||
Daniel (9 June 2005)
|
||||
- Incorporated Tupone's findtool fix in buildconf (slightly edited)
|
||||
|
||||
- Incorporated Tupone's head -n fix in buildconf.
|
||||
|
||||
Daniel (8 June 2005)
|
||||
- Reverted Tupone's patch again, it broke numerous autobuilds. Let's apply it
|
||||
in pieces, one by one and see what we need to adjust to work all over.
|
||||
|
||||
Daniel (6 June 2005)
|
||||
- Tupone Alfredo fixed three problems in buildconf:
|
||||
|
||||
1) findtool does look per tool in PATH and think ./perl is the perl
|
||||
executable, while is just a local directory (I have . in the PATH)
|
||||
|
||||
2) I got several warning for head -1 deprecated in favour of head -n 1
|
||||
|
||||
3) ares directory is missing some file (missing is missing :-) ) because
|
||||
automake and friends is not run.
|
||||
|
||||
Daniel (3 June 2005)
|
||||
- Added docs/libcurl/getinfo-times, based on feedback from 'Edi':
|
||||
http://curl.haxx.se/feedback/display.cgi?id=11178325798299&support=yes
|
||||
|
||||
- Andres Garcia provided yet another text mode patch for several test cases so
|
||||
that they do text comparisions better on Windows (newline-wise).
|
||||
|
||||
Daniel (1 June 2005)
|
||||
- The configure check for c-ares now adds the cares lib before the other libs,
|
||||
to make it build fine with mingw. Inspired by Tupone Alfredo's bug report
|
||||
(and patch) #1212940
|
||||
|
||||
Daniel (31 May 2005)
|
||||
- Todd Kulesza reported a flaw in the proxy option, since a numerical IPv6
|
||||
address was not possible to use. It is now, but requires it written
|
||||
RFC2732-style, within brackets - which incidently is how you enter numerical
|
||||
IPv6 addresses in URLs. Test case 263 added to verify.
|
||||
|
||||
Daniel (30 May 2005)
|
||||
- Eric Cooper reported about a problem with HTTP servers that responds with
|
||||
binary zeroes within the headers. They confused libcurl to do wrong so the
|
||||
downloaded headers become incomplete. The fix is now verified with test case
|
||||
262.
|
||||
|
||||
Daniel (25 May 2005)
|
||||
- Fixed problems with the test suite, and in particular the FTP test cases
|
||||
since it previously was failing every now and then in a nonsense manner.
|
||||
|
||||
- --trace-time now outputs the full microsecond, all 6 digits.
|
||||
|
||||
Daniel (24 May 2005)
|
||||
- Andres Garcia provided a text mode patch for several test cases so that they
|
||||
do text comparisions better on Windows (newline-wise).
|
||||
|
||||
- Any 2xx response (and not just 200) is now considered a fine response to
|
||||
TYPE, as some servers obviously sends a 226 there. Added test case 261 to
|
||||
verify. Based on a question/report by Georg Wicherski.
|
||||
|
||||
Daniel (20 May 2005)
|
||||
- Improved runtests.pl to allow stdout tests to be mode=text as well, just
|
||||
as file comparisons already supports. Added this info to the FILEFORMAT
|
||||
docs.
|
||||
|
||||
Daniel (18 May 2005)
|
||||
- John McGowan identified a problem in bug report #1204435 with malformed URLs
|
||||
like "http://somehost?data" as it added a slash too much in the request
|
||||
("GET /?data/"...). Added test case 260 to verify.
|
||||
|
||||
- The configure check for strerror_r() failed to detect the proper API at
|
||||
times, like on HP-UX 10.20. Then lib/strerror.c badly assumed the glibc
|
||||
version if the posix define wasn't set (since it _had_ found a strerror_r).
|
||||
|
||||
Daniel (16 May 2005)
|
||||
- The gmtime_r() function in HP-UX 10.20 is broken. About 13 test cases fail
|
||||
due to this. There's now a configure check that attempts to detect the bad
|
||||
function and not use it on such systems.
|
||||
|
||||
Version 7.14.0 (16 May 2005)
|
||||
|
||||
Daniel (13 May 2005)
|
||||
- Grigory Entin reported that curl's configure detects a fine poll() for Mac
|
||||
OS X 10.4 (while 10.3 or later detected a "bad" one), but the executable
|
||||
doesn't work as good as if built without poll(). I've adjusted the configure
|
||||
to always skip the fine-poll() test on Mac OS X (darwin).
|
||||
|
||||
Daniel (12 May 2005)
|
||||
- When doing a second request (after a disconnect) using the same easy handle,
|
||||
over a proxy that uses NTLM authentication, libcurl failed to use NTLM again
|
||||
properly (the auth method was accidentally reset to the same as had been set
|
||||
for host auth, which defaults to Basic). Bug report #1200661 identified the
|
||||
the problem and the fix.
|
||||
|
||||
- If -z/--time-cond is used with an invalid date syntax, this is no longer
|
||||
silently discarded. Instead a proper warning message is diplayed that
|
||||
informs about it. But it still continues without the condition.
|
||||
|
||||
Version 7.14.0-pre2 (11 May 2005)
|
||||
|
||||
Daniel (11 May 2005)
|
||||
- Starting now, libcurl sends a little different set of headers in its default
|
||||
HTTP requests:
|
||||
|
||||
A) Normal non-proxy HTTP:
|
||||
- no more "Pragma: no-cache" (this only makes sense to proxies)
|
||||
|
||||
B) Non-CONNECT HTTP request over proxy:
|
||||
- "Pragma: no-cache" is used (like before)
|
||||
- "Proxy-Connection: Keep-alive" (for older style 1.0-proxies)
|
||||
|
||||
C) CONNECT HTTP request over proxy:
|
||||
- "Host: [name]:[port]"
|
||||
- "Proxy-Connection: Keep-alive"
|
||||
|
||||
The A) case is mostly to reduce the default header size and remove a
|
||||
pointless header.
|
||||
|
||||
The B) is to address (rare) problems with HTTP 1.0 proxies
|
||||
|
||||
The C) headers are both to address (rare) problems with some proxies. The
|
||||
code in libcurl that deals with CONNECT requests need a rewrite, but it
|
||||
feels like a too big a job for me to do now. Details are added in the code
|
||||
comments for now.
|
||||
|
||||
Updated a large amount of test cases to reflect the news.
|
||||
|
||||
Daniel (10 May 2005)
|
||||
- Half-baked attempt to bail out if select() returns _only_ errorfds when the
|
||||
transfer is in progress. An attempt to fix Allan's problem. See
|
||||
http://curl.haxx.se/mail/lib-2005-05/0073.html and the rest of that thread
|
||||
for details.
|
||||
|
||||
I'm still not sure this is the right fix, but...
|
||||
|
||||
Version 7.14.0-pre1 (9 May 2005)
|
||||
|
||||
Daniel (2 May 2005)
|
||||
- Sort of "fixed" KNOWN_BUGS #4: curl now builds IPv6 enabled on AIX 4.3. At
|
||||
least it should no longer cause a compiler error. However, it does not have
|
||||
AI_NUMERICHOST so we cannot getaddrinfo() any numerical addresses with it
|
||||
(we use that for FTP PORT/EPRT)! So, I modified the configure check that
|
||||
checks if the getaddrinfo() is working, to use AI_NUMERICHOST since then
|
||||
it'll fail on AIX 4.3 and it will automatically build with IPv6 support
|
||||
disabled.
|
||||
|
||||
- Added --trace-time that when used adds a time stamp to each trace line that
|
||||
--trace, --trace-ascii and --verbose output. I also made the '>' display
|
||||
separate each line on the linefeed so that HTTP requests etc look nicer in
|
||||
the -v output.
|
||||
|
||||
- Made curl recognize the environment variables Lynx (and others?) support for
|
||||
pointing out the CA cert path/file: SSL_CERT_DIR and SSL_CERT_FILE. If
|
||||
CURL_CA_BUNDLE is not set, they are checked afterwards.
|
||||
|
||||
Like before: on windows if none of these are set, it checks for the ca cert
|
||||
file like this:
|
||||
|
||||
1. application's directory
|
||||
2. current working directory
|
||||
3. Windows System directory (e.g. C:\windows\system32)
|
||||
4. Windows Directory (e.g. C:\windows)
|
||||
5. all directories along %PATH%
|
||||
|
||||
Daniel (1 May 2005)
|
||||
- The runtests.pl script now starts test servers by doing fork() and exec()
|
||||
instead of the previous approach. This is less complicated and should
|
||||
hopefully lead to less "leaked" servers (servers that aren't stopped
|
||||
properly when the tests are stopped).
|
||||
|
||||
- Alexander Zhuravlev found a case when you did "curl -I [URL]" and it
|
||||
complained on the chunked encoding, even though a HEAD should never return a
|
||||
body and thus it cannot be a chunked-encoding problem!
|
||||
|
||||
Daniel (30 April 2005)
|
||||
- Alexander Zhuravlev found out that (lib)curl SIGSEGVed when using
|
||||
--interface on an address that can't be bound.
|
||||
|
||||
Daniel (28 April 2005)
|
||||
- Working on fixing up test cases to mark sections as 'mode=text' for things
|
||||
that curl writes as text files, since then they can get different line
|
||||
endings depending on OS. Andr<64>s Garc<72>a helps me work this out.
|
||||
|
||||
Did lots of other minor tweaks on the test scripts to work better and more
|
||||
reliably find test servers and also kill test servers.
|
||||
|
||||
- Dan Fandrich pointed out how the runtests.pl script killed the HTTP server
|
||||
instead of the HTTPS server when closing it down.
|
||||
|
||||
Daniel (27 April 2005)
|
||||
- Paul Moore made curl check for the .curlrc file (_curlrc on windows) on two
|
||||
more places. First, CURL_HOME is a new environment variable that is used
|
||||
instead of HOME if it is set, to point out where the default config file
|
||||
lives. If there's no config file in the dir pointed out by one of the
|
||||
environment variables, the Windows version will instead check the same
|
||||
directory the executable curl is located in.
|
||||
|
||||
Daniel (26 April 2005)
|
||||
- Cory Nelson's work on nuking compiler warnings when building on x64 with
|
||||
VS2005.
|
||||
|
||||
Daniel (25 April 2005)
|
||||
- Fred New reported a bug where we used Basic auth and user name and password
|
||||
in .netrc, and when following a Location: the subsequent requests didn't
|
||||
properly use the auth as found in the netrc file. Added test case 257 to
|
||||
verify my fix.
|
||||
|
||||
- Based on feedback from Cory Nelson, I added some preprocessor magic in
|
||||
*/setup.h and */config-win32.h to build fine with VS2005 on x64.
|
||||
|
||||
Daniel (23 April 2005)
|
||||
- Alex Suykov made the curl tool now assume that uploads using HTTP:// or
|
||||
HTTPS:// are the only ones that show output and thus motivates a switched
|
||||
off progress meter if the output is sent to the terminal. This makes FTP
|
||||
uploads without '>', -o or -O show the progress meter.
|
||||
|
||||
Daniel (22 April 2005)
|
||||
- Dave Dribin's MSVC makefile fix: set CURL_STATICLIB when it builds static
|
||||
library variants.
|
||||
|
||||
- Andres Garcia fixed configure to set the proper define when building static
|
||||
libcurl on windows.
|
||||
|
||||
- --retry-delay didn't work.
|
||||
|
||||
Daniel (18 April 2005)
|
||||
- Olivier reported that even though he used CURLOPT_PORT, libcurl clearly
|
||||
still used the default port. He was right. I fixed the problem and added the
|
||||
test cases 521, 522 and 523 to verify the fix.
|
||||
|
||||
- Toshiyuki Maezawa reported that when doing a POST with a read callback,
|
||||
libcurl didn't properly send an Expect: 100-continue header. It does now.
|
||||
|
||||
- I committed by mig change in the test suite's FTP server that moves out all
|
||||
socket/TCP code to a separate C program named sockfilt. And added 4 new
|
||||
test cases for FTP over IPv6.
|
||||
|
||||
Daniel (8 April 2005)
|
||||
- Cory Nelson reported a problem with a HTTP server that responded with a 304
|
||||
response containing an "illegal" Content-Length: header, which was not
|
||||
properly ignored by libcurl. Now it is. Test case 249 verifies.
|
||||
|
||||
Daniel (7 April 2005)
|
||||
- Added ability to build and run with GnuTLS as an alternative to OpenSSL for
|
||||
the secure layer. configure --with-gnutls enables with. Note that the
|
||||
previous OpenSSL check still has preference and if it first detects OpenSSL,
|
||||
it will not check for GnuTLS. You may need to explictly diable OpenSSL with
|
||||
--without-ssl.
|
||||
|
||||
This work has been sponsored by The Written Word.
|
||||
|
||||
Daniel (5 April 2005)
|
||||
- Christophe Legry fixed the post-upload check for FTP to not complain if the
|
||||
upload was skipped due to a time-condition as set with
|
||||
CURLOPT_TIMECONDITION. I added test case 247 and 248 to verify.
|
||||
|
||||
Version 7.13.2 (5 April 2005)
|
||||
|
||||
Daniel (4 April 2005)
|
||||
|
@@ -200,9 +200,21 @@ netware:
|
||||
$(MAKE) -C lib -f Makefile.netware
|
||||
$(MAKE) -C src -f Makefile.netware
|
||||
|
||||
netware-ares:
|
||||
$(MAKE) -C lib -f Makefile.netware WITH_ARES=1
|
||||
$(MAKE) -C src -f Makefile.netware WITH_ARES=1
|
||||
|
||||
netware-ssl:
|
||||
$(MAKE) -C lib -f Makefile.netware SSL=1
|
||||
$(MAKE) -C src -f Makefile.netware SSL=1
|
||||
$(MAKE) -C lib -f Makefile.netware WITH_SSL=1
|
||||
$(MAKE) -C src -f Makefile.netware WITH_SSL=1
|
||||
|
||||
netware-ssl-zlib:
|
||||
$(MAKE) -C lib -f Makefile.netware WITH_SSL=1 WITH_ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.netware WITH_SSL=1 WITH_ZLIB=1
|
||||
|
||||
netware-zlib:
|
||||
$(MAKE) -C lib -f Makefile.netware WITH_ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.netware WITH_ZLIB=1
|
||||
|
||||
netware-clean:
|
||||
$(MAKE) -C lib -f Makefile.netware clean
|
||||
|
37
README
37
README
@@ -26,50 +26,37 @@ CONTACT
|
||||
If you have problems, questions, ideas or suggestions, please contact us
|
||||
by posting to a suitable mailing list. See http://curl.haxx.se/mail/
|
||||
|
||||
Many major contributors to the project are listed in the THANKS document.
|
||||
All contributors to the project are listed in the THANKS document.
|
||||
|
||||
WEB SITE
|
||||
|
||||
Visit the curl web site or mirrors for the latest news:
|
||||
Visit the curl web site or mirrors for the latest news and downloads:
|
||||
|
||||
Sweden -- http://curl.haxx.se/
|
||||
Australia -- http://curl.planetmirror.com/
|
||||
Austria -- http://curl.gds.tuwien.ac.at/
|
||||
Canada -- http://curl.meulie.net/
|
||||
Denmark -- http://curl.cofman.dk/
|
||||
Estonia -- http://curl.wildyou.net/
|
||||
France -- http://curl.mirror.internet.tp/
|
||||
Germany -- http://curl.kgt.org/
|
||||
Germany -- http://curl.miscellaneousmirror.org/
|
||||
Germany -- http://curl.mirror.at.stealer.net/
|
||||
Germany -- http://curl.mirroring.de/
|
||||
Germany -- http://curl.mons-new-media.de/
|
||||
Germany -- http://curl.netmirror.org/
|
||||
Russia -- http://curl.tsuren.net/
|
||||
Taiwan -- http://curl.cs.pu.edu.tw/
|
||||
Thailand -- http://curl.siamu.ac.th/
|
||||
US (AZ) -- http://curl.islandofpoker.com/
|
||||
US (CA) -- http://curl.mirror.redwire.net/
|
||||
US (CA) -- http://curl.mirrormonster.com/
|
||||
US (CA) -- http://curl.signal42.com/
|
||||
US (CA) -- http://curl.tolix.org/
|
||||
US (CA) -- http://curl.webhosting76.com/
|
||||
US (TX) -- http://curl.109k.com/
|
||||
|
||||
DOWNLOAD
|
||||
|
||||
The official download mirror sites are:
|
||||
|
||||
Australia -- http://curl.planetmirror.com/download.html
|
||||
Austria -- http://curl.gds.tuwien.ac.at/download.html
|
||||
Estonia -- http://curl.wildyou.net/download.html
|
||||
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/
|
||||
Sweden -- http://cool.haxx.se/curl/
|
||||
Taiwan -- http://curl.cs.pu.edu.tw/download.html
|
||||
Thailand -- http://curl.siamu.ac.th/download.html
|
||||
US (CA) -- http://curl.mirror.redwire.net/download.html
|
||||
US (CA) -- http://curl.mirrormonster.com/download.html
|
||||
US (CA) -- http://curl.signal42.com/download.html
|
||||
US (TX) -- http://curl.109k.com/download.html
|
||||
US (TX) -- http://curl.mirrors.cyberservers.net/
|
||||
US (TX) -- http://curl.seekmeup.com/
|
||||
US (TX) -- http://curl.hostingzero.com/
|
||||
|
||||
CVS
|
||||
|
||||
|
@@ -1,57 +1,74 @@
|
||||
Curl and libcurl 7.13.2
|
||||
Curl and libcurl 7.14.1
|
||||
|
||||
Public curl release number: 87
|
||||
Releases counted from the very beginning: 114
|
||||
Available command line options: 106
|
||||
Available curl_easy_setopt() options: 122
|
||||
Public curl release number: 89
|
||||
Releases counted from the very beginning: 116
|
||||
Available command line options: 108
|
||||
Available curl_easy_setopt() options: 123
|
||||
Number of public functions in libcurl: 46
|
||||
Amount of public web site mirrors: 20
|
||||
Amount of public web site mirrors: 25
|
||||
Number of known libcurl bindings: 31
|
||||
Number of contributors: 447
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o Added --form-string
|
||||
o libcurl can be built with SSPI support. curl_version_info() then returns
|
||||
a new feature bit: CURL_VERSION_SSPI. configure --enable-sspi added
|
||||
o Added --proxy-anyauth
|
||||
o Added runtests.1 and testcurl.1 man pages
|
||||
o GNU GSS support
|
||||
o --ignore-content-length and CURLOPT_IGNORE_CONTENT_LENGTH added
|
||||
o negotiates data connection SSL earlier when doing FTPS with PASV
|
||||
o CURLOPT_COOKIELIST and CURLINFO_COOKIELIST
|
||||
o trailer support for chunked encoded data streams
|
||||
o -x/CURL_PROXY strings may now contain user+password
|
||||
o --trace-time now outputs the full microsecond, all 6 digits
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o the MSVC libcurl Makefile was fixed
|
||||
o libcurl on Windows crash if resolver was active when easy handle was killed
|
||||
o HTTP POST with auth and an initial 100 response before the 401/407
|
||||
o configure's SSL-detection for msys/mingw
|
||||
o better connection keep-alive when POSTing with HTTP Digest
|
||||
o FTP-SSL
|
||||
o reading FTP server response in multiple reads
|
||||
o picking one out of multiple proxy auth methods
|
||||
o inet_ntoa_r() when built with uClibc
|
||||
o the so name issue for the LDAP library dynamic load
|
||||
o crash when using SOCKS4 proxy
|
||||
o a debug printf() was removed
|
||||
o CURLOPT_FILETIME when downloading FTP corrupted data
|
||||
o FTP upload resume now works even if no file is present on the site
|
||||
o SSL seeding no longer attempts to read the whole random file
|
||||
o MSVC build problem with the DSP file
|
||||
o windows threaded resolver access violation with multi interface
|
||||
o test suite works with valgrind 3
|
||||
o CA cert verification with GnuTLS builds
|
||||
o handles expiry times in cookie files that go beyond 32 bits in size
|
||||
o several client problems with files, such as doing -d @file when the file
|
||||
isn't readable now gets a warning displayed
|
||||
o write callback abort didn't always "take"
|
||||
o the curl -z "bad syntax" warning is now hidden when -s is used
|
||||
o curl -d @nonexisting no longer makes a GET
|
||||
o minor debug callback data size
|
||||
o date parsing of dates including daylight savings time zone names
|
||||
o using NTLM over proxy with an FTP URL
|
||||
o curl-config --features now displays SSL when built with GnuTLS too
|
||||
o CURLOPT_HTTPGET, CURLOPT_POST and CURLOPT_HTTPPOST reset CURLOPT_NOBODY
|
||||
o builds fine on AmigaOS again
|
||||
o corrected date parsing on Windows with auto-DST-adjust enabled
|
||||
o treats CONNECT 407 responses with bodies better during Digest/NTLM auth
|
||||
o improved strerror_r() API guessing when cross-compiling
|
||||
o debug builds work on Tru64
|
||||
o improved libcurl.m4
|
||||
o possible memory leak in windows name resolves
|
||||
o c-ares enabled build with mingw
|
||||
o proxy host set with numerical IPv6 address
|
||||
o better treatment of binary zeroes in HTTP response headers
|
||||
o fixed the notorious FTP server failure in the test suite
|
||||
o better checking of text output in the test suite on windows
|
||||
o FTP servers' TYPE command response check made less strict
|
||||
o URL-without-slash as in http://somehost?data
|
||||
o strerror_r() configure check for HP-UX 10.20 (and others)
|
||||
o time parse work-around on HP-UX 10.20 since its gmtime_r() is broken
|
||||
|
||||
Other curl-related news since the previous public release:
|
||||
|
||||
o the cURL project is now over 7 years old
|
||||
o daily curl binary builds for Windows fresh from CVS:
|
||||
http://cool.haxx.se/curl-daily/
|
||||
o curl-tracker is a new mailinglist for "tracker" activities:
|
||||
http://cool.haxx.se/mailman/listinfo/curl-tracker
|
||||
o libcurl binding for Common Lisp: http://common-lisp.net/project/cl-curl/
|
||||
o pycurl 7.13.1 http://pycurl.sf.net
|
||||
o http://curl.tolix.org is a new Californian mirror
|
||||
o http://curl.seekmeup.com/ is a new mirror in US Texas
|
||||
o cURLpp 0.5.2 was released at http://rrette.com/curlpp.html
|
||||
o Rexx/CURL 1.3 was released at http://rexxcurl.sf.net/
|
||||
o http://curl.miscellaneousmirror.org is a new German curl mirror
|
||||
o LuaCURL by Alexander Marinov at http://luacurl.luaforge.net/
|
||||
o http://curl.hostingzero.com/ is a new US curl mirror
|
||||
o ocurl 0.2.1 was released at http://sourceforge.net/projects/ocurl
|
||||
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Dan Fandrich, Ignacio Vazquez-Abrams, Randy McMurchy, Dominick Meglio,
|
||||
Jean-Marc Ranger, Tor Arntsen, Nodak Sodak, David Houlder, Gisle Vanem,
|
||||
Christopher R. Palmer, Gwenole Beauchesne, Augustus Saunders, Jesper Jensen,
|
||||
Tom Moers, Andres Garcia, Hardeep Singh, Marcelo Juchem
|
||||
John McGowan, Georg Wicherski, Andres Garcia, Eric Cooper, Todd Kulesza,
|
||||
Tupone Alfredo, Gisle Vanem, David Shaw, Andrew Bushnell, Dan Fandrich,
|
||||
Adrian Schuur, Diego Casorran, Peteris Krumins, Jon Grubbs, Christopher
|
||||
R. Palmer, Mario Schroeder, Richard Clayton, James Bursa, Jeff Pohlmeyer,
|
||||
Norbert Novotny, Toby Peterson, Simon Josefsson, Igor Polyakov, Kevin Lussier
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
31
TODO-RELEASE
31
TODO-RELEASE
@@ -1,35 +1,12 @@
|
||||
Issues not sorted in any particular order.
|
||||
|
||||
To get fixed in 7.13.3 (planned release: June 2005)
|
||||
To get fixed in 7.14.1 (planned release: August 2005)
|
||||
======================
|
||||
|
||||
58 - Fix KNOWN_BUGS #19: "FTP 3rd party transfers with the multi interface
|
||||
doesn't work"
|
||||
|
||||
47 - Peter Sylvester's patch for SRP on the TLS layer
|
||||
Awaits OpenSSL support for this, no need to support this in libcurl before
|
||||
there's an OpenSSL release that does it.
|
||||
|
||||
To get fixed in 7.14.0
|
||||
To get fixed in 7.14.2 (planned release: October 2005)
|
||||
======================
|
||||
|
||||
55 - Add a function to the multi interface that gets file descriptors, as an
|
||||
alternative to the curl_multi_fdset(). This is necessary to allow apps to
|
||||
properly avoid the FD_SETSIZE problem.
|
||||
60 - CONNECT 407 responses that kills the connection
|
||||
|
||||
56 - Make curl_easy_perform() a wrapper-function that simply creates a multi
|
||||
handle, adds the easy handle to it, runs curl_multi_perform() until the
|
||||
transfer is done, then detach the easy handle, destroy the multi handle
|
||||
and return the easy handle's return code. This will thus make everything
|
||||
internally use and assume the multi interface. The select()-loop should
|
||||
use the new function from (55).
|
||||
63 -
|
||||
|
||||
To get fixed in 7.15.0
|
||||
======================
|
||||
|
||||
57 - Add an interface to libcurl for getting and setting cookies from an easy
|
||||
handle. One idea: http://curl.haxx.se/mail/lib-2004-12/0195.html the
|
||||
older idea: http://curl.haxx.se/dev/COOKIES. We need to settle on some
|
||||
middle ground I guess.
|
||||
|
||||
60 -
|
||||
|
86
acinclude.m4
86
acinclude.m4
@@ -122,6 +122,30 @@ dnl end of non-blocking try-compile test
|
||||
fi
|
||||
])
|
||||
|
||||
dnl Check for struct sockaddr_storage. Most IPv6-enabled hosts have it, but
|
||||
dnl AIX 4.3 is one known exception.
|
||||
AC_DEFUN([TYPE_SOCKADDR_STORAGE],
|
||||
[
|
||||
AC_CHECK_TYPE([struct sockaddr_storage],
|
||||
AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1,
|
||||
[if struct sockaddr_storage is defined]), ,
|
||||
[
|
||||
#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
|
||||
])
|
||||
|
||||
])
|
||||
|
||||
dnl Check for socklen_t: historically on BSD it is an int, and in
|
||||
dnl POSIX 1g it is a type of its own, but some platforms use different
|
||||
dnl types for the argument to getsockopt, getpeername, etc. So we
|
||||
@@ -168,8 +192,7 @@ AC_DEFUN([TYPE_SOCKLEN_T],
|
||||
])
|
||||
|
||||
dnl Check for in_addr_t: it is used to receive the return code of inet_addr()
|
||||
dnl and a few other things. If not found, we set it to unsigned int, as even
|
||||
dnl 64-bit implementations use to set it to a 32-bit type.
|
||||
dnl and a few other things.
|
||||
AC_DEFUN([TYPE_IN_ADDR_T],
|
||||
[
|
||||
AC_CHECK_TYPE([in_addr_t], ,[
|
||||
@@ -234,7 +257,7 @@ exit (h == NULL ? 1 : 0); }],[
|
||||
])
|
||||
|
||||
dnl ************************************************************
|
||||
dnl check for working getaddrinfo()
|
||||
dnl check for working getaddrinfo() that works with AI_NUMERICHOST
|
||||
dnl
|
||||
AC_DEFUN([CURL_CHECK_WORKING_GETADDRINFO],[
|
||||
AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
|
||||
@@ -249,6 +272,7 @@ int main(void)
|
||||
int error;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
|
||||
@@ -392,34 +416,25 @@ dnl int strerror_r(int errnum, char *buf, size_t n);
|
||||
dnl
|
||||
AC_DEFUN([CURL_CHECK_STRERROR_R],
|
||||
[
|
||||
dnl determine of strerror_r is present
|
||||
AC_CHECK_FUNCS(strerror_r,[
|
||||
AC_CHECK_FUNCS(strerror_r)
|
||||
|
||||
if test "x$ac_cv_func_strerror_r" = "xyes"; then
|
||||
|
||||
AC_MSG_CHECKING(whether strerror_r is declared)
|
||||
AC_EGREP_CPP(strerror_r,[
|
||||
#include <string.h>],[
|
||||
strerror_r="yes"
|
||||
AC_MSG_RESULT(yes)],[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(whether strerror_r with -D_THREAD_SAFE is declared)
|
||||
AC_MSG_CHECKING(whether strerror_r with -D_REENTRANT is declared)
|
||||
AC_EGREP_CPP(strerror_r,[
|
||||
#define _THREAD_SAFE
|
||||
#define _REENTRANT
|
||||
#include <string.h>],[
|
||||
strerror_r="yes"
|
||||
CPPFLAGS="-D_THREAD_SAFE $CPPFLAGS"
|
||||
CPPFLAGS="-D_REENTRANT $CPPFLAGS"
|
||||
AC_MSG_RESULT(yes)],
|
||||
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>
|
||||
])
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(HAVE_NO_STRERROR_R_DECL, 1, [we have no strerror_r() proto])
|
||||
) dnl with _THREAD_SAFE
|
||||
]) dnl plain cpp for it
|
||||
|
||||
dnl determine if this strerror_r() is glibc or POSIX
|
||||
AC_MSG_CHECKING([for a glibc strerror_r API])
|
||||
@@ -441,8 +456,20 @@ main () {
|
||||
AC_DEFINE(HAVE_GLIBC_STRERROR_R, 1, [we have a glibc-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!])
|
||||
|
||||
dnl Use an inferior method of strerror_r detection while cross-compiling
|
||||
AC_EGREP_CPP(yes, [
|
||||
#include <features.h>
|
||||
#ifdef __GLIBC__
|
||||
yes
|
||||
#endif
|
||||
],
|
||||
dnl looks like glibc, so assume a glibc-style strerror_r()
|
||||
GLIBC_STRERROR_R="1"
|
||||
AC_DEFINE(HAVE_GLIBC_STRERROR_R, 1, [we have a glibc-style strerror_r()])
|
||||
AC_MSG_RESULT([yes]),
|
||||
AC_MSG_NOTICE([cannot determine strerror_r() style: edit lib/config.h manually!])
|
||||
) dnl while cross-compiling
|
||||
)
|
||||
|
||||
if test -z "$GLIBC_STRERROR_R"; then
|
||||
@@ -731,15 +758,18 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
||||
fi
|
||||
|
||||
dnl -Wunreachable-code seems totally unreliable on my gcc 3.3.2 on
|
||||
dnl on i686-Linux as it gives us heaps with false positives
|
||||
dnl on i686-Linux as it gives us heaps with false positives.
|
||||
dnl Also, on gcc 4.0.X it is totally unbearable and complains all
|
||||
dnl over making it unusable for generic purposes. Let's not use it.
|
||||
|
||||
if test "$gccnum" -ge "303"; then
|
||||
dnl gcc 3.3 and later
|
||||
WARN="$WARN -Wendif-labels -Wstrict-prototypes"
|
||||
fi
|
||||
|
||||
if test "$gccnum" -ge "304"; then
|
||||
# try -Wunreachable-code on gcc 3.4
|
||||
WARN="$WARN -Wunreachable-code"
|
||||
# try these on gcc 3.4
|
||||
WARN="$WARN -Wdeclaration-after-statement"
|
||||
fi
|
||||
|
||||
for flag in $CPPFLAGS; do
|
||||
|
13
ares/AUTHORS
Normal file
13
ares/AUTHORS
Normal file
@@ -0,0 +1,13 @@
|
||||
c-ares is based on ares, and these are the people that have worked on it since
|
||||
the fork was made:
|
||||
|
||||
Daniel Stenberg
|
||||
Dominick Meglio
|
||||
liren at vivisimo.com
|
||||
James Bursa
|
||||
Duncan Wilcox
|
||||
Dirk Manske
|
||||
Dan Fandrich
|
||||
Gisle Vanem
|
||||
Gunter Knauf
|
||||
Henrik Stoerner
|
67
ares/CHANGES
67
ares/CHANGES
@@ -1,5 +1,72 @@
|
||||
Changelog for the c-ares project
|
||||
|
||||
Version 1.3.0 (August 29, 2004)
|
||||
|
||||
* August 21
|
||||
|
||||
- Alfredo Tupone provided a fix for the Windows code in get_iphlpapi_dns_info()
|
||||
when getting the DNS server etc.
|
||||
|
||||
* June 19
|
||||
|
||||
- Added some checks for the addrinfo structure.
|
||||
|
||||
* June 2
|
||||
|
||||
- William Ahern:
|
||||
|
||||
Make UDP sockets non-blocking. I've confirmed that at least on Linux 2.4 a
|
||||
read event can come back from poll() on a valid SOCK_DGRAM socket but
|
||||
recv(2) will still block. This patch doesn't ignore EAGAIN in
|
||||
read_udp_packets(), though maybe it should. (This patch was edited by Daniel
|
||||
Stenberg and a new configure test was added (imported from curl's configure)
|
||||
to properly detect what non-blocking socket approach to use.)
|
||||
|
||||
I'm not quite sure how this was happening, but I've been seeing PTR queries
|
||||
which seem to return empty responses. At least, they were empty when calling
|
||||
ares_expand_name() on the record. Here's a patch which guarantees to
|
||||
NUL-terminate the expanded name. The old behavior failed to NUL-terminate if
|
||||
len was 0, and this was causing strlen() to run past the end of the buffer
|
||||
after calling ares_expand_name() and getting ARES_SUCCESS as the return
|
||||
value. If q is not greater than *s then it's equal and *s is always
|
||||
allocated with at least one byte.
|
||||
|
||||
* May 16
|
||||
|
||||
- Added ares_getnameinfo which mimics the getnameinfo API (another feature
|
||||
that could use testing).
|
||||
|
||||
* May 14
|
||||
|
||||
- Added an inet_ntop function from BIND for systems that do not have it.
|
||||
|
||||
* April 9
|
||||
|
||||
- Made sortlist support IPv6 (this can probably use some testing).
|
||||
|
||||
- Made sortlist support CIDR matching for IPv4.
|
||||
|
||||
* April 8
|
||||
|
||||
- Added preliminary IPv6 support to ares_gethostbyname. Currently, sortlist
|
||||
does not work with IPv6. Also provided an implementation of bitncmp from
|
||||
BIND for systems that do not supply this function. This will be used to add
|
||||
IPv6 support to sortlist.
|
||||
|
||||
- Made ares_gethostbyaddr support IPv6 by specifying AF_INET6 as the family.
|
||||
The function can lookup IPv6 addresses both from files (/etc/hosts) and
|
||||
DNS lookups.
|
||||
|
||||
* April 7
|
||||
|
||||
- Tupone Alfredo fixed includes of arpa/nameser_compat.h to build fine on Mac
|
||||
OS X.
|
||||
|
||||
* April 5
|
||||
|
||||
- Dominick Meglio: Provided implementations of inet_net_pton and inet_pton
|
||||
from BIND for systems that do not include these functions.
|
||||
|
||||
* March 11, 2005
|
||||
|
||||
- Dominick Meglio added ares_parse_aaaa_reply.c and did various
|
||||
|
@@ -12,10 +12,10 @@ MSVCFILES = vc/adig/adig.dep vc/adig/adig.dsp vc/adig/adig.mak \
|
||||
# adig and ahost are just sample programs and thus not mentioned with the
|
||||
# regular sources and headers
|
||||
EXTRA_DIST = CHANGES README.cares Makefile.inc adig.c ahost.c $(man_MANS) \
|
||||
$(MSVCFILES)
|
||||
$(MSVCFILES) AUTHORS
|
||||
|
||||
|
||||
VER=-version-info 0:0:0
|
||||
VER=-version-info 1: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
|
||||
# 1.
|
||||
|
@@ -1,16 +1,18 @@
|
||||
CSOURCES = ares_fds.c ares_process.c ares_free_hostent.c ares_query.c \
|
||||
ares__close_sockets.c ares_free_string.c ares_search.c ares__get_hostent.c \
|
||||
ares_gethostbyaddr.c ares_send.c ares__read_line.c ares_gethostbyname.c \
|
||||
ares_strerror.c ares_cancel.c ares_init.c ares_timeout.c ares_destroy.c \
|
||||
ares_mkquery.c ares_version.c ares_expand_name.c ares_parse_a_reply.c \
|
||||
windows_port.c ares_expand_string.c ares_parse_ptr_reply.c \
|
||||
ares_parse_aaaa_reply.c
|
||||
CSOURCES = ares_fds.c ares_process.c ares_free_hostent.c ares_query.c \
|
||||
ares__close_sockets.c ares_free_string.c ares_search.c ares__get_hostent.c \
|
||||
ares_gethostbyaddr.c ares_send.c ares__read_line.c ares_gethostbyname.c \
|
||||
ares_strerror.c ares_cancel.c ares_init.c ares_timeout.c ares_destroy.c \
|
||||
ares_mkquery.c ares_version.c ares_expand_name.c ares_parse_a_reply.c \
|
||||
windows_port.c ares_expand_string.c ares_parse_ptr_reply.c \
|
||||
ares_parse_aaaa_reply.c ares_getnameinfo.c inet_net_pton.c bitncmp.c \
|
||||
inet_ntop.c
|
||||
|
||||
HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h nameser.h
|
||||
HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h \
|
||||
nameser.h inet_net_pton.h inet_ntop.h ares_ipv6.h bitncmp.h
|
||||
|
||||
MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
|
||||
ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \
|
||||
ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3 \
|
||||
ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \
|
||||
ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \
|
||||
ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3
|
||||
ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \
|
||||
ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3 \
|
||||
ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \
|
||||
ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \
|
||||
ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3
|
||||
|
@@ -89,7 +89,7 @@ LDFLAGS = -T
|
||||
AR = ar
|
||||
ARFLAGS = -cq
|
||||
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return -fno-strict-aliasing
|
||||
CFLAGS += -Wall -Wno-format # -pedantic
|
||||
CFLAGS += -Wall -Wno-format -Wno-uninitialized # -pedantic
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
||||
else
|
||||
@@ -104,7 +104,7 @@ SDK_LIBC = $(NDK_ROOT)/libc
|
||||
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
INCLUDES += -I$(SDK_LIBC)/include -I$(SDK_LIBC)/include/nks
|
||||
INCLUDES += -I$(SDK_LIBC)/include/winsock
|
||||
# INCLUDES += -I$(SDK_LIBC)/include/winsock
|
||||
CFLAGS += -D_POSIX_SOURCE
|
||||
# CFLAGS += -D__ANSIC__
|
||||
else
|
||||
@@ -126,7 +126,10 @@ DL = '
|
||||
#-include $(NDKBASE)/nlmconv/ncpfs.inc
|
||||
endif
|
||||
|
||||
OBJS := $(patsubst %.c,$(OBJDIR)/%.o,$(wildcard ares_*.c))
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include Makefile.inc
|
||||
|
||||
OBJS := $(patsubst %.c,$(OBJDIR)/%.o,$(strip $(CSOURCES)))
|
||||
|
||||
.PHONY: lib nlm prebuild dist install clean
|
||||
|
||||
@@ -256,6 +259,7 @@ config.h: Makefile.netware
|
||||
@echo $(DL)#define VERSION "$(LIBCURL_VERSION_STR)"$(DL) >> $@
|
||||
@echo $(DL)#define PACKAGE_BUGREPORT "curl-bug@haxx.se"$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ARPA_NAMESER_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_DLFCN_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_DLOPEN 1$(DL) >> $@
|
||||
@@ -297,8 +301,13 @@ config.h: Makefile.netware
|
||||
@echo $(DL)#define SIZEOF_CURL_OFF_T 4$(DL) >> $@
|
||||
@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@
|
||||
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@
|
||||
ifdef NW_WINSOCK
|
||||
@echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@
|
||||
else
|
||||
|
@@ -1,3 +1,126 @@
|
||||
dnl Check for how to set a socket to non-blocking state. There seems to exist
|
||||
dnl four known different ways, with the one used almost everywhere being POSIX
|
||||
dnl and XPG3, while the other different ways for different systems (old BSD,
|
||||
dnl Windows and Amiga).
|
||||
dnl
|
||||
dnl There are two known platforms (AIX 3.x and SunOS 4.1.x) where the
|
||||
dnl O_NONBLOCK define is found but does not work. This condition is attempted
|
||||
dnl to get caught in this script by using an excessive number of #ifdefs...
|
||||
dnl
|
||||
AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET],
|
||||
[
|
||||
AC_MSG_CHECKING([non-blocking sockets style])
|
||||
|
||||
AC_TRY_COMPILE([
|
||||
/* headers for O_NONBLOCK test */
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
],[
|
||||
/* try to compile O_NONBLOCK */
|
||||
|
||||
#if defined(sun) || defined(__sun__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
# if defined(__SVR4) || defined(__srv4__)
|
||||
# define PLATFORM_SOLARIS
|
||||
# else
|
||||
# define PLATFORM_SUNOS4
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX4)
|
||||
# define PLATFORM_AIX_V3
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__)
|
||||
#error "O_NONBLOCK does not work on this platform"
|
||||
#endif
|
||||
int socket;
|
||||
int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK);
|
||||
],[
|
||||
dnl the O_NONBLOCK test was fine
|
||||
nonblock="O_NONBLOCK"
|
||||
AC_DEFINE(HAVE_O_NONBLOCK, 1, [use O_NONBLOCK for non-blocking sockets])
|
||||
],[
|
||||
dnl the code was bad, try a different program now, test 2
|
||||
|
||||
AC_TRY_COMPILE([
|
||||
/* headers for FIONBIO test */
|
||||
#include <unistd.h>
|
||||
#include <stropts.h>
|
||||
],[
|
||||
/* FIONBIO source test (old-style unix) */
|
||||
int socket;
|
||||
int flags = ioctl(socket, FIONBIO, &flags);
|
||||
],[
|
||||
dnl FIONBIO test was good
|
||||
nonblock="FIONBIO"
|
||||
AC_DEFINE(HAVE_FIONBIO, 1, [use FIONBIO for non-blocking sockets])
|
||||
],[
|
||||
dnl FIONBIO test was also bad
|
||||
dnl the code was bad, try a different program now, test 3
|
||||
|
||||
AC_TRY_COMPILE([
|
||||
/* headers for ioctlsocket test (cygwin?) */
|
||||
#include <windows.h>
|
||||
],[
|
||||
/* ioctlsocket source code */
|
||||
int socket;
|
||||
unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
|
||||
],[
|
||||
dnl ioctlsocket test was good
|
||||
nonblock="ioctlsocket"
|
||||
AC_DEFINE(HAVE_IOCTLSOCKET, 1, [use ioctlsocket() for non-blocking sockets])
|
||||
],[
|
||||
dnl ioctlsocket didnt compile!, go to test 4
|
||||
|
||||
AC_TRY_LINK([
|
||||
/* headers for IoctlSocket test (Amiga?) */
|
||||
#include <sys/ioctl.h>
|
||||
],[
|
||||
/* IoctlSocket source code */
|
||||
int socket;
|
||||
int flags = IoctlSocket(socket, FIONBIO, (long)1);
|
||||
],[
|
||||
dnl ioctlsocket test was good
|
||||
nonblock="IoctlSocket"
|
||||
AC_DEFINE(HAVE_IOCTLSOCKET_CASE, 1, [use Ioctlsocket() for non-blocking sockets])
|
||||
],[
|
||||
dnl Ioctlsocket didnt compile, do test 5!
|
||||
AC_TRY_COMPILE([
|
||||
/* headers for SO_NONBLOCK test (BeOS) */
|
||||
#include <socket.h>
|
||||
],[
|
||||
/* SO_NONBLOCK source code */
|
||||
long b = 1;
|
||||
int socket;
|
||||
int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||
],[
|
||||
dnl the SO_NONBLOCK test was good
|
||||
nonblock="SO_NONBLOCK"
|
||||
AC_DEFINE(HAVE_SO_NONBLOCK, 1, [use SO_NONBLOCK for non-blocking sockets])
|
||||
],[
|
||||
dnl test 5 didnt compile!
|
||||
nonblock="nada"
|
||||
AC_DEFINE(HAVE_DISABLED_NONBLOCKING, 1, [disabled non-blocking sockets])
|
||||
])
|
||||
dnl end of fifth test
|
||||
|
||||
])
|
||||
dnl end of forth test
|
||||
|
||||
])
|
||||
dnl end of third test
|
||||
|
||||
])
|
||||
dnl end of second test
|
||||
|
||||
])
|
||||
dnl end of non-blocking try-compile test
|
||||
AC_MSG_RESULT($nonblock)
|
||||
|
||||
if test "$nonblock" = "nada"; then
|
||||
AC_MSG_WARN([non-block sockets disabled])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl We create a function for detecting which compiler we use and then set as
|
||||
dnl pendantic compiler options as possible for that particular compiler. The
|
||||
@@ -119,6 +242,26 @@ AC_DEFUN([CARES_CHECK_STRUCT], [
|
||||
fi
|
||||
])
|
||||
|
||||
dnl This macro determins if the specified struct contains a specific member.
|
||||
dnl Syntax:
|
||||
dnl CARES_CHECK_STRUCT_MEMBER(headers, struct name, member name, if found, [if not found])
|
||||
|
||||
AC_DEFUN([CARES_CHECK_STRUCT_MEMBER], [
|
||||
AC_MSG_CHECKING([if struct $2 has member $3])
|
||||
AC_TRY_COMPILE([$1],
|
||||
[
|
||||
struct $2 struct_instance;
|
||||
struct_instance.$3 = 0;
|
||||
], ac_struct="yes", ac_found="no")
|
||||
if test "$ac_struct" = "yes" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
$4
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
$5
|
||||
fi
|
||||
])
|
||||
|
||||
dnl This macro determines if the specified constant exists in the specified file
|
||||
dnl Syntax:
|
||||
dnl CARES_CHECK_CONSTANT(headers, constant name, if found, [if not found])
|
||||
|
30
ares/ares.h
30
ares/ares.h
@@ -29,12 +29,14 @@
|
||||
|
||||
#if defined(WATT32)
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <tcp.h>
|
||||
#elif defined(WIN32)
|
||||
#include <winsock.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -64,6 +66,9 @@ extern "C" {
|
||||
#define ARES_EDESTRUCTION 16
|
||||
#define ARES_EBADSTR 17
|
||||
|
||||
/* ares_getnameinfo error codes */
|
||||
#define ARES_EBADFLAGS 18
|
||||
|
||||
/* Flag values */
|
||||
#define ARES_FLAG_USEVC (1 << 0)
|
||||
#define ARES_FLAG_PRIMARY (1 << 1)
|
||||
@@ -85,6 +90,24 @@ extern "C" {
|
||||
#define ARES_OPT_DOMAINS (1 << 7)
|
||||
#define ARES_OPT_LOOKUPS (1 << 8)
|
||||
|
||||
/* Nameinfo flag values */
|
||||
#define ARES_NI_NOFQDN (1 << 0)
|
||||
#define ARES_NI_NUMERICHOST (1 << 1)
|
||||
#define ARES_NI_NAMEREQD (1 << 2)
|
||||
#define ARES_NI_NUMERICSERV (1 << 3)
|
||||
#define ARES_NI_DGRAM (1 << 4)
|
||||
#define ARES_NI_TCP 0
|
||||
#define ARES_NI_UDP ARES_NI_DGRAM
|
||||
#define ARES_NI_SCTP (1 << 5)
|
||||
#define ARES_NI_DCCP (1 << 6)
|
||||
#define ARES_NI_NUMERICSCOPE (1 << 7)
|
||||
#define ARES_NI_LOOKUPHOST (1 << 8)
|
||||
#define ARES_NI_LOOKUPSERVICE (1 << 9)
|
||||
/* Reserved for future use */
|
||||
#define ARES_NI_IDN (1 << 10)
|
||||
#define ARES_NI_ALLOW_UNASSIGNED (1 << 11)
|
||||
#define ARES_NI_USE_STD3_ASCII_RULES (1 << 12)
|
||||
|
||||
struct ares_options {
|
||||
int flags;
|
||||
int timeout;
|
||||
@@ -101,12 +124,15 @@ struct ares_options {
|
||||
|
||||
struct hostent;
|
||||
struct timeval;
|
||||
struct sockaddr;
|
||||
struct ares_channeldata;
|
||||
typedef struct ares_channeldata *ares_channel;
|
||||
typedef void (*ares_callback)(void *arg, int status, unsigned char *abuf,
|
||||
int alen);
|
||||
typedef void (*ares_host_callback)(void *arg, int status,
|
||||
struct hostent *hostent);
|
||||
typedef void (*ares_nameinfo_callback)(void *arg, int status,
|
||||
char *node, char *service);
|
||||
|
||||
int ares_init(ares_channel *channelptr);
|
||||
int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||
@@ -123,7 +149,9 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
||||
ares_host_callback callback, void *arg);
|
||||
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
||||
int family, ares_host_callback callback, void *arg);
|
||||
|
||||
void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
|
||||
socklen_t salen, int flags, ares_nameinfo_callback callback,
|
||||
void *arg);
|
||||
int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
|
||||
struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
|
||||
struct timeval *tv);
|
||||
|
@@ -30,12 +30,15 @@
|
||||
|
||||
#include "ares.h"
|
||||
#include "ares_private.h"
|
||||
#include "inet_net_pton.h"
|
||||
|
||||
int ares__get_hostent(FILE *fp, struct hostent **host)
|
||||
int ares__get_hostent(FILE *fp, int family, struct hostent **host)
|
||||
{
|
||||
char *line = NULL, *p, *q, *canonical, **alias;
|
||||
int status, linesize, end_at_hostname, naliases;
|
||||
struct in_addr addr;
|
||||
struct in6_addr addr6;
|
||||
int addrlen = sizeof(struct in_addr);
|
||||
struct hostent *hostent = NULL;
|
||||
|
||||
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
|
||||
@@ -56,6 +59,17 @@ int ares__get_hostent(FILE *fp, struct hostent **host)
|
||||
*p = 0;
|
||||
addr.s_addr = inet_addr(line);
|
||||
if (addr.s_addr == INADDR_NONE)
|
||||
{
|
||||
if (ares_inet_pton(AF_INET6, line, &addr6) > 0)
|
||||
{
|
||||
if (family != AF_INET6)
|
||||
continue;
|
||||
addrlen = sizeof(struct in6_addr);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else if (family != AF_INET)
|
||||
continue;
|
||||
|
||||
/* Get the canonical hostname. */
|
||||
@@ -100,7 +114,7 @@ int ares__get_hostent(FILE *fp, struct hostent **host)
|
||||
hostent->h_addr_list = malloc(2 * sizeof(char *));
|
||||
if (!hostent->h_addr_list)
|
||||
break;
|
||||
hostent->h_addr_list[0] = malloc(sizeof(struct in_addr));
|
||||
hostent->h_addr_list[0] = malloc(addrlen);
|
||||
if (!hostent->h_addr_list[0])
|
||||
break;
|
||||
hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
|
||||
@@ -134,9 +148,12 @@ int ares__get_hostent(FILE *fp, struct hostent **host)
|
||||
}
|
||||
hostent->h_aliases[naliases] = NULL;
|
||||
|
||||
hostent->h_addrtype = AF_INET;
|
||||
hostent->h_length = sizeof(struct in_addr);
|
||||
memcpy(hostent->h_addr_list[0], &addr, sizeof(struct in_addr));
|
||||
hostent->h_addrtype = family;
|
||||
hostent->h_length = addrlen;
|
||||
if (family == AF_INET)
|
||||
memcpy(hostent->h_addr_list[0], &addr, addrlen);
|
||||
else if (family == AF_INET6)
|
||||
memcpy(hostent->h_addr_list[0], &addr6, addrlen);
|
||||
hostent->h_addr_list[1] = NULL;
|
||||
*host = hostent;
|
||||
free(line);
|
||||
|
@@ -21,6 +21,9 @@
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -103,6 +106,8 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
|
||||
/* Nuke the trailing period if we wrote one. */
|
||||
if (q > *s)
|
||||
*(q - 1) = 0;
|
||||
else
|
||||
*q = 0; /* zero terminate */
|
||||
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
@@ -28,8 +28,8 @@ The
|
||||
.I ares_free_hostent
|
||||
function frees a
|
||||
.B struct hostent
|
||||
allocated by one of the functions \fIares_parse_a_reply(3)\fP or
|
||||
\fIares_parse_ptr_reply(3)\fP.
|
||||
allocated by one of the functions \fIares_parse_a_reply(3)\fP,
|
||||
\fIares_parse_aaaa_reply(3)\fP, or \fIares_parse_ptr_reply(3)\fP.
|
||||
.SH NOTES
|
||||
It is not necessary (and is not correct) to free the host structure passed to
|
||||
the callback functions for \fIares_gethostbyname(3)\fP or
|
||||
@@ -37,6 +37,7 @@ the callback functions for \fIares_gethostbyname(3)\fP or
|
||||
host structures when the callback returns.
|
||||
.SH SEE ALSO
|
||||
.BR ares_parse_a_reply (3),
|
||||
.BR ares_parse_aaaa_reply (3),
|
||||
.BR ares_parse_ptr_reply (3)
|
||||
.SH AUTHOR
|
||||
Greg Hudson, MIT Information Systems
|
||||
|
@@ -12,7 +12,6 @@
|
||||
* this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -23,6 +22,9 @@
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -31,6 +33,7 @@
|
||||
|
||||
#include "ares.h"
|
||||
#include "ares_private.h"
|
||||
#include "inet_net_pton.h"
|
||||
|
||||
#ifdef WATT32
|
||||
#undef WIN32
|
||||
@@ -39,7 +42,8 @@
|
||||
struct addr_query {
|
||||
/* Arguments passed to ares_gethostbyaddr() */
|
||||
ares_channel channel;
|
||||
struct in_addr addr;
|
||||
union ares_addr addr;
|
||||
int family;
|
||||
ares_host_callback callback;
|
||||
void *arg;
|
||||
|
||||
@@ -51,14 +55,21 @@ static void addr_callback(void *arg, int status, unsigned char *abuf,
|
||||
int alen);
|
||||
static void end_aquery(struct addr_query *aquery, int status,
|
||||
struct hostent *host);
|
||||
static int file_lookup(struct in_addr *addr, struct hostent **host);
|
||||
static int file_lookup(union ares_addr *addr, int family, struct hostent **host);
|
||||
|
||||
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
||||
int family, ares_host_callback callback, void *arg)
|
||||
{
|
||||
struct addr_query *aquery;
|
||||
|
||||
if (family != AF_INET || addrlen != sizeof(struct in_addr))
|
||||
if (family != AF_INET && family != AF_INET6)
|
||||
{
|
||||
callback(arg, ARES_ENOTIMP, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((family == AF_INET && addrlen != sizeof(struct in_addr)) ||
|
||||
(family == AF_INET6 && addrlen != sizeof(struct in6_addr)))
|
||||
{
|
||||
callback(arg, ARES_ENOTIMP, NULL);
|
||||
return;
|
||||
@@ -71,7 +82,11 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
||||
return;
|
||||
}
|
||||
aquery->channel = channel;
|
||||
memcpy(&aquery->addr, addr, sizeof(aquery->addr));
|
||||
if (family == AF_INET)
|
||||
memcpy(&aquery->addr.addr4, addr, sizeof(struct in_addr));
|
||||
else
|
||||
memcpy(&aquery->addr.addr6, addr, sizeof(struct in6_addr));
|
||||
aquery->family = family;
|
||||
aquery->callback = callback;
|
||||
aquery->arg = arg;
|
||||
aquery->remaining_lookups = channel->lookups;
|
||||
@@ -82,7 +97,7 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
||||
static void next_lookup(struct addr_query *aquery)
|
||||
{
|
||||
const char *p;
|
||||
char name[64];
|
||||
char name[128];
|
||||
int a1, a2, a3, a4, status;
|
||||
struct hostent *host;
|
||||
unsigned long addr;
|
||||
@@ -92,18 +107,38 @@ static void next_lookup(struct addr_query *aquery)
|
||||
switch (*p)
|
||||
{
|
||||
case 'b':
|
||||
addr = ntohl(aquery->addr.s_addr);
|
||||
a1 = (int)((addr >> 24) & 0xff);
|
||||
a2 = (int)((addr >> 16) & 0xff);
|
||||
a3 = (int)((addr >> 8) & 0xff);
|
||||
a4 = (int)(addr & 0xff);
|
||||
sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1);
|
||||
aquery->remaining_lookups = p + 1;
|
||||
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
||||
aquery);
|
||||
if (aquery->family == AF_INET)
|
||||
{
|
||||
addr = ntohl(aquery->addr.addr4.s_addr);
|
||||
a1 = (int)((addr >> 24) & 0xff);
|
||||
a2 = (int)((addr >> 16) & 0xff);
|
||||
a3 = (int)((addr >> 8) & 0xff);
|
||||
a4 = (int)(addr & 0xff);
|
||||
sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1);
|
||||
aquery->remaining_lookups = p + 1;
|
||||
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
||||
aquery);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char *bytes;
|
||||
bytes = (unsigned char *)&aquery->addr.addr6.s6_addr;
|
||||
sprintf(name, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
|
||||
bytes[15]&0xf, bytes[15] >> 4, bytes[14]&0xf, bytes[14] >> 4,
|
||||
bytes[13]&0xf, bytes[13] >> 4, bytes[12]&0xf, bytes[12] >> 4,
|
||||
bytes[11]&0xf, bytes[11] >> 4, bytes[10]&0xf, bytes[10] >> 4,
|
||||
bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4,
|
||||
bytes[7]&0xf, bytes[7] >> 4, bytes[6]&0xf, bytes[6] >> 4,
|
||||
bytes[5]&0xf, bytes[5] >> 4, bytes[4]&0xf, bytes[4] >> 4,
|
||||
bytes[3]&0xf, bytes[3] >> 4, bytes[2]&0xf, bytes[2] >> 4,
|
||||
bytes[1]&0xf, bytes[1] >> 4, bytes[0]&0xf, bytes[0] >> 4);
|
||||
aquery->remaining_lookups = p + 1;
|
||||
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
||||
aquery);
|
||||
}
|
||||
return;
|
||||
case 'f':
|
||||
status = file_lookup(&aquery->addr, &host);
|
||||
status = file_lookup(&aquery->addr, aquery->family, &host);
|
||||
if (status != ARES_ENOTFOUND)
|
||||
{
|
||||
end_aquery(aquery, status, host);
|
||||
@@ -122,8 +157,12 @@ static void addr_callback(void *arg, int status, unsigned char *abuf, int alen)
|
||||
|
||||
if (status == ARES_SUCCESS)
|
||||
{
|
||||
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr,
|
||||
sizeof(struct in_addr), AF_INET, &host);
|
||||
if (aquery->family == AF_INET)
|
||||
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addr4,
|
||||
sizeof(struct in_addr), AF_INET, &host);
|
||||
else
|
||||
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addr6,
|
||||
sizeof(struct in6_addr), AF_INET6, &host);
|
||||
end_aquery(aquery, status, host);
|
||||
}
|
||||
else if (status == ARES_EDESTRUCTION)
|
||||
@@ -141,7 +180,7 @@ static void end_aquery(struct addr_query *aquery, int status,
|
||||
free(aquery);
|
||||
}
|
||||
|
||||
static int file_lookup(struct in_addr *addr, struct hostent **host)
|
||||
static int file_lookup(union ares_addr *addr, int family, struct hostent **host)
|
||||
{
|
||||
FILE *fp;
|
||||
int status;
|
||||
@@ -178,11 +217,23 @@ static int file_lookup(struct in_addr *addr, struct hostent **host)
|
||||
fp = fopen(PATH_HOSTS, "r");
|
||||
if (!fp)
|
||||
return ARES_ENOTFOUND;
|
||||
|
||||
while ((status = ares__get_hostent(fp, host)) == ARES_SUCCESS)
|
||||
while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS)
|
||||
{
|
||||
if (memcmp((*host)->h_addr, addr, sizeof(struct in_addr)) == 0)
|
||||
break;
|
||||
if (family != (*host)->h_addrtype)
|
||||
{
|
||||
ares_free_hostent(*host);
|
||||
continue;
|
||||
}
|
||||
if (family == AF_INET)
|
||||
{
|
||||
if (memcmp((*host)->h_addr, &addr->addr4, sizeof(struct in_addr)) == 0)
|
||||
break;
|
||||
}
|
||||
else if (family == AF_INET6)
|
||||
{
|
||||
if (memcmp((*host)->h_addr, &addr->addr6, sizeof(struct in6_addr)) == 0)
|
||||
break;
|
||||
}
|
||||
ares_free_hostent(*host);
|
||||
}
|
||||
fclose(fp);
|
||||
|
@@ -23,8 +23,13 @@
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -33,6 +38,8 @@
|
||||
|
||||
#include "ares.h"
|
||||
#include "ares_private.h"
|
||||
#include "inet_net_pton.h"
|
||||
#include "bitncmp.h"
|
||||
|
||||
#ifdef WATT32
|
||||
#undef WIN32
|
||||
@@ -44,7 +51,7 @@ struct host_query {
|
||||
char *name;
|
||||
ares_host_callback callback;
|
||||
void *arg;
|
||||
|
||||
int family;
|
||||
const char *remaining_lookups;
|
||||
};
|
||||
|
||||
@@ -53,13 +60,17 @@ static void host_callback(void *arg, int status, unsigned char *abuf,
|
||||
int alen);
|
||||
static void end_hquery(struct host_query *hquery, int status,
|
||||
struct hostent *host);
|
||||
static int fake_hostent(const char *name, ares_host_callback callback,
|
||||
static int fake_hostent(const char *name, int family, ares_host_callback callback,
|
||||
void *arg);
|
||||
static int file_lookup(const char *name, struct hostent **host);
|
||||
static int file_lookup(const char *name, int family, struct hostent **host);
|
||||
static void sort_addresses(struct hostent *host, struct apattern *sortlist,
|
||||
int nsort);
|
||||
static void sort6_addresses(struct hostent *host, struct apattern *sortlist,
|
||||
int nsort);
|
||||
static int get_address_index(struct in_addr *addr, struct apattern *sortlist,
|
||||
int nsort);
|
||||
static int get6_address_index(struct in6_addr *addr, struct apattern *sortlist,
|
||||
int nsort);
|
||||
|
||||
void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
||||
ares_host_callback callback, void *arg)
|
||||
@@ -67,13 +78,13 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
||||
struct host_query *hquery;
|
||||
|
||||
/* Right now we only know how to look up Internet addresses. */
|
||||
if (family != AF_INET)
|
||||
if (family != AF_INET && family != AF_INET6)
|
||||
{
|
||||
callback(arg, ARES_ENOTIMP, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fake_hostent(name, callback, arg))
|
||||
if (fake_hostent(name, family, callback, arg))
|
||||
return;
|
||||
|
||||
/* Allocate and fill in the host query structure. */
|
||||
@@ -85,6 +96,7 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
||||
}
|
||||
hquery->channel = channel;
|
||||
hquery->name = strdup(name);
|
||||
hquery->family = family;
|
||||
if (!hquery->name)
|
||||
{
|
||||
free(hquery);
|
||||
@@ -112,13 +124,17 @@ static void next_lookup(struct host_query *hquery)
|
||||
case 'b':
|
||||
/* DNS lookup */
|
||||
hquery->remaining_lookups = p + 1;
|
||||
ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
|
||||
hquery);
|
||||
if (hquery->family == AF_INET6)
|
||||
ares_search(hquery->channel, hquery->name, C_IN, T_AAAA, host_callback,
|
||||
hquery);
|
||||
else
|
||||
ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
|
||||
hquery);
|
||||
return;
|
||||
|
||||
case 'f':
|
||||
/* Host file lookup */
|
||||
status = file_lookup(hquery->name, &host);
|
||||
status = file_lookup(hquery->name, hquery->family, &host);
|
||||
if (status != ARES_ENOTFOUND)
|
||||
{
|
||||
end_hquery(hquery, status, host);
|
||||
@@ -138,11 +154,27 @@ static void host_callback(void *arg, int status, unsigned char *abuf, int alen)
|
||||
|
||||
if (status == ARES_SUCCESS)
|
||||
{
|
||||
status = ares_parse_a_reply(abuf, alen, &host);
|
||||
if (host && channel->nsort)
|
||||
sort_addresses(host, channel->sortlist, channel->nsort);
|
||||
if (hquery->family == AF_INET)
|
||||
{
|
||||
status = ares_parse_a_reply(abuf, alen, &host);
|
||||
if (host && channel->nsort)
|
||||
sort_addresses(host, channel->sortlist, channel->nsort);
|
||||
}
|
||||
else if (hquery->family == AF_INET6)
|
||||
{
|
||||
status = ares_parse_aaaa_reply(abuf, alen, &host);
|
||||
if (host && channel->nsort)
|
||||
sort6_addresses(host, channel->sortlist, channel->nsort);
|
||||
}
|
||||
end_hquery(hquery, status, host);
|
||||
}
|
||||
else if (status == ARES_ENODATA && hquery->family == AF_INET6)
|
||||
{
|
||||
/* There was no AAAA now lookup an A */
|
||||
hquery->family = AF_INET;
|
||||
ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
|
||||
hquery);
|
||||
}
|
||||
else if (status == ARES_EDESTRUCTION)
|
||||
end_hquery(hquery, status, NULL);
|
||||
else
|
||||
@@ -162,36 +194,34 @@ static void end_hquery(struct host_query *hquery, int status,
|
||||
/* If the name looks like an IP address, fake up a host entry, end the
|
||||
* query immediately, and return true. Otherwise return false.
|
||||
*/
|
||||
static int fake_hostent(const char *name, ares_host_callback callback,
|
||||
static int fake_hostent(const char *name, int family, ares_host_callback callback,
|
||||
void *arg)
|
||||
{
|
||||
struct in_addr addr;
|
||||
struct hostent hostent;
|
||||
const char *p;
|
||||
char *aliases[1] = { NULL };
|
||||
char *addrs[2];
|
||||
int result = 0;
|
||||
struct in_addr in;
|
||||
struct in6_addr in6;
|
||||
|
||||
/* It only looks like an IP address if it's all numbers and dots. */
|
||||
for (p = name; *p; p++)
|
||||
{
|
||||
if (!isdigit((unsigned char)*p) && *p != '.')
|
||||
return 0;
|
||||
}
|
||||
if (family == AF_INET)
|
||||
result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1);
|
||||
else if (family == AF_INET6)
|
||||
result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1);
|
||||
|
||||
/* It also only looks like an IP address if it's non-zero-length and
|
||||
* doesn't end with a dot.
|
||||
*/
|
||||
if (p == name || *(p - 1) == '.')
|
||||
if (!result)
|
||||
return 0;
|
||||
|
||||
/* It looks like an IP address. Figure out what IP address it is. */
|
||||
addr.s_addr = inet_addr(name);
|
||||
if (addr.s_addr == INADDR_NONE)
|
||||
if (family == AF_INET)
|
||||
{
|
||||
callback(arg, ARES_EBADNAME, NULL);
|
||||
return 1;
|
||||
hostent.h_length = sizeof(struct in_addr);
|
||||
addrs[0] = (char *)∈
|
||||
}
|
||||
else if (family == AF_INET6)
|
||||
{
|
||||
hostent.h_length = sizeof(struct in6_addr);
|
||||
addrs[0] = (char *)&in6;
|
||||
}
|
||||
|
||||
/* Duplicate the name, to avoid a constness violation. */
|
||||
hostent.h_name = strdup(name);
|
||||
if (!hostent.h_name)
|
||||
@@ -201,11 +231,9 @@ static int fake_hostent(const char *name, ares_host_callback callback,
|
||||
}
|
||||
|
||||
/* Fill in the rest of the host structure and terminate the query. */
|
||||
addrs[0] = (char *) &addr;
|
||||
addrs[1] = NULL;
|
||||
hostent.h_aliases = aliases;
|
||||
hostent.h_addrtype = AF_INET;
|
||||
hostent.h_length = sizeof(struct in_addr);
|
||||
hostent.h_addrtype = family;
|
||||
hostent.h_addr_list = addrs;
|
||||
callback(arg, ARES_SUCCESS, &hostent);
|
||||
|
||||
@@ -213,7 +241,7 @@ static int fake_hostent(const char *name, ares_host_callback callback,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int file_lookup(const char *name, struct hostent **host)
|
||||
static int file_lookup(const char *name, int family, struct hostent **host)
|
||||
{
|
||||
FILE *fp;
|
||||
char **alias;
|
||||
@@ -252,7 +280,7 @@ static int file_lookup(const char *name, struct hostent **host)
|
||||
if (!fp)
|
||||
return ARES_ENOTFOUND;
|
||||
|
||||
while ((status = ares__get_hostent(fp, host)) == ARES_SUCCESS)
|
||||
while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS)
|
||||
{
|
||||
if (strcasecmp((*host)->h_name, name) == 0)
|
||||
break;
|
||||
@@ -310,8 +338,66 @@ static int get_address_index(struct in_addr *addr, struct apattern *sortlist,
|
||||
|
||||
for (i = 0; i < nsort; i++)
|
||||
{
|
||||
if ((addr->s_addr & sortlist[i].mask.s_addr) == sortlist[i].addr.s_addr)
|
||||
break;
|
||||
if (sortlist[i].family != AF_INET)
|
||||
continue;
|
||||
if (sortlist[i].type == PATTERN_MASK)
|
||||
{
|
||||
if ((addr->s_addr & sortlist[i].mask.addr.addr4.s_addr)
|
||||
== sortlist[i].addr.addr4.s_addr)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ares_bitncmp(&addr->s_addr, &sortlist[i].addr.addr4.s_addr,
|
||||
sortlist[i].mask.bits))
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static void sort6_addresses(struct hostent *host, struct apattern *sortlist,
|
||||
int nsort)
|
||||
{
|
||||
struct in6_addr a1, a2;
|
||||
int i1, i2, ind1, ind2;
|
||||
|
||||
/* This is a simple insertion sort, not optimized at all. i1 walks
|
||||
* through the address list, with the loop invariant that everything
|
||||
* to the left of i1 is sorted. In the loop body, the value at i1 is moved
|
||||
* back through the list (via i2) until it is in sorted order.
|
||||
*/
|
||||
for (i1 = 0; host->h_addr_list[i1]; i1++)
|
||||
{
|
||||
memcpy(&a1, host->h_addr_list[i1], sizeof(struct in6_addr));
|
||||
ind1 = get6_address_index(&a1, sortlist, nsort);
|
||||
for (i2 = i1 - 1; i2 >= 0; i2--)
|
||||
{
|
||||
memcpy(&a2, host->h_addr_list[i2], sizeof(struct in6_addr));
|
||||
ind2 = get6_address_index(&a2, sortlist, nsort);
|
||||
if (ind2 <= ind1)
|
||||
break;
|
||||
memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in6_addr));
|
||||
}
|
||||
memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in6_addr));
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the first entry in sortlist which matches addr. Return nsort
|
||||
* if none of them match.
|
||||
*/
|
||||
static int get6_address_index(struct in6_addr *addr, struct apattern *sortlist,
|
||||
int nsort)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nsort; i++)
|
||||
{
|
||||
if (sortlist[i].family != AF_INET6)
|
||||
continue;
|
||||
if (!ares_bitncmp(&addr->s6_addr, &sortlist[i].addr.addr6.s6_addr, sortlist[i].mask.bits))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
145
ares/ares_getnameinfo.3
Normal file
145
ares/ares_getnameinfo.3
Normal file
@@ -0,0 +1,145 @@
|
||||
.\" $Id$
|
||||
.\"
|
||||
.\" Copyright 2005 by Dominick Meglio.
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this
|
||||
.\" software and its documentation for any purpose and without
|
||||
.\" fee is hereby granted, provided that the above copyright
|
||||
.\" notice appear in all copies and that both that copyright
|
||||
.\" notice and this permission notice appear in supporting
|
||||
.\" documentation, and that the name of M.I.T. not be used in
|
||||
.\" advertising or publicity pertaining to distribution of the
|
||||
.\" software without specific, written prior permission.
|
||||
.\" M.I.T. makes no representations about the suitability of
|
||||
.\" this software for any purpose. It is provided "as is"
|
||||
.\" without express or implied warranty.
|
||||
.\"
|
||||
.TH ARES_GETNAMEINFO 3 "16 May 2005"
|
||||
.SH NAME
|
||||
ares_getnameinfo \- Address-to-nodename translation in protocol-independent manner
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B #include <ares.h>
|
||||
.PP
|
||||
.B typedef void (*ares_nameinfo_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||
.B char *\fInode\fP, char *\fIservice\fP)
|
||||
.PP
|
||||
.B void ares_getnameinfo(ares_channel \fIchannel\fP, const struct sockaddr *\fIsa\fP,
|
||||
.B socklen_t \fIsalen\fP, int \fIflags\fP, ares_nameinfo_callback \fIcallback\fP,
|
||||
.B void *\fIarg\fP)
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B ares_getnameinfo
|
||||
function is defined for protocol-independent address translation. The function
|
||||
is a combination of \fIares_gethostbyaddr(3)\fP and \fIgetservbyport(3)\fP. The function will
|
||||
translate the address either by executing a host query on the name service channel
|
||||
identified by
|
||||
.IR channel
|
||||
or it will attempt to resolve it locally if possible.
|
||||
The parameters
|
||||
.I sa
|
||||
and
|
||||
.I len
|
||||
give the address as a sockaddr structure, and
|
||||
.I flags
|
||||
gives the options that the function will use. Valid flags are listed below:
|
||||
.TP 19
|
||||
.B ARES_NI_NOFQDN
|
||||
Only the nodename portion of the FQDN is returned for local hosts.
|
||||
.TP 19
|
||||
.B ARES_NI_NUMERICHOST
|
||||
The numeric form of the hostname is returned rather than the name.
|
||||
.TP 19
|
||||
.B ARES_NI_NAMEREQD
|
||||
An error is returned if the hostname cannot be found in the DNS.
|
||||
.TP 19
|
||||
.B ARES_NI_NUMERICSERV
|
||||
The numeric form of the service is returned rather than the name.
|
||||
.TP 19
|
||||
.B ARES_NI_TCP
|
||||
The service name is to be looked up for the TCP protocol.
|
||||
.TP 19
|
||||
.B ARES_NI_UDP
|
||||
The service name is to be looked up for the UDP protocol.
|
||||
.TP 19
|
||||
.B ARES_NI_SCTP
|
||||
The service name is to be looked up for the SCTP protocol.
|
||||
.TP 19
|
||||
.B ARES_NI_DCCP
|
||||
The service name is to be looked up for the DCCP protocol.
|
||||
.TP 19
|
||||
.B ARES_NI_NUMERICSCOPE
|
||||
The numeric form of the scope ID is returned rather than the name.
|
||||
.TP 19
|
||||
.B ARES_NI_LOOKUPHOST
|
||||
A hostname lookup is being requested.
|
||||
.TP 19
|
||||
.B ARES_NI_LOOKUPSERVICE
|
||||
A service name lookup is being requested.
|
||||
.PP
|
||||
When the query
|
||||
is complete or has
|
||||
failed, the ares library will invoke \fIcallback\fP. Completion or failure of
|
||||
the query may happen immediately, or may happen during a later call to
|
||||
\fIares_process(3)\fP, \fIares_destroy(3)\fP or \fIares_cancel(3)\fP.
|
||||
.PP
|
||||
The callback argument
|
||||
.I arg
|
||||
is copied from the
|
||||
.B ares_getnameinfo
|
||||
argument
|
||||
.IR arg .
|
||||
The callback argument
|
||||
.I status
|
||||
indicates whether the query succeeded and, if not, how it failed. It
|
||||
may have any of the following values:
|
||||
.TP 19
|
||||
.B ARES_SUCCESS
|
||||
The host lookup completed successfully.
|
||||
.TP 19
|
||||
.B ARES_ENOTIMP
|
||||
The ares library does not know how to look up addresses of type
|
||||
.IR family .
|
||||
.TP 19
|
||||
.B ARES_ENOTFOUND
|
||||
The address
|
||||
.I addr
|
||||
was not found.
|
||||
.TP 19
|
||||
.B ARES_ENOMEM
|
||||
Memory was exhausted.
|
||||
.TP 19
|
||||
.B ARES_EDESTRUCTION
|
||||
The name service channel
|
||||
.I channel
|
||||
is being destroyed; the query will not be completed.
|
||||
.TP 19
|
||||
.B ARES_EBADFLAGS
|
||||
The
|
||||
.I flags
|
||||
parameter contains an illegal value.
|
||||
.PP
|
||||
On successful completion of the query, the callback argument
|
||||
.I node
|
||||
contains a string representing the hostname (assuming
|
||||
.B ARES_NI_LOOKUPHOST
|
||||
was specified). Additionally,
|
||||
.I service
|
||||
contains a string representing the service name (assuming
|
||||
.B ARES_NI_LOOKUPSERVICE
|
||||
was specified).
|
||||
If the query did not complete successfully, or one of the values
|
||||
was not requested,
|
||||
.I node
|
||||
or
|
||||
.I service
|
||||
will be
|
||||
.BR NULL .
|
||||
.SH SEE ALSO
|
||||
.BR ares_process (3),
|
||||
.BR ares_getaddrinfo (3)
|
||||
.SH AUTHOR
|
||||
Dominick Meglio
|
||||
.br
|
||||
Copyright 2005 by Dominick Meglio.
|
331
ares/ares_getnameinfo.c
Normal file
331
ares/ares_getnameinfo.c
Normal file
@@ -0,0 +1,331 @@
|
||||
/* Copyright 2005 by Dominick Meglio
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of M.I.T. not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* M.I.T. makes no representations about the suitability of
|
||||
* this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*/
|
||||
#include "setup.h"
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined(WIN32) && !defined(WATT32)
|
||||
#include "nameser.h"
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ares.h"
|
||||
#include "ares_private.h"
|
||||
#include "ares_ipv6.h"
|
||||
#include "inet_ntop.h"
|
||||
|
||||
#ifdef WATT32
|
||||
#undef WIN32
|
||||
#endif
|
||||
|
||||
struct nameinfo_query {
|
||||
ares_nameinfo_callback callback;
|
||||
void *arg;
|
||||
union {
|
||||
struct sockaddr_in addr4;
|
||||
struct sockaddr_in6 addr6;
|
||||
} addr;
|
||||
int family;
|
||||
int flags;
|
||||
};
|
||||
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
#define IPBUFSIZ 40+IF_NAMESIZE
|
||||
#else
|
||||
#define IPBUFSIZ 40
|
||||
#endif
|
||||
|
||||
static void nameinfo_callback(void *arg, int status, struct hostent *host);
|
||||
static char *lookup_service(unsigned short port, int flags, char *buf);
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
static char *append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid, char *buf);
|
||||
#endif
|
||||
static char *ares_striendstr(const char *s1, const char *s2);
|
||||
|
||||
void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t salen,
|
||||
int flags, ares_nameinfo_callback callback, void *arg)
|
||||
{
|
||||
struct sockaddr_in *addr;
|
||||
struct sockaddr_in6 *addr6;
|
||||
struct nameinfo_query *niquery;
|
||||
|
||||
/* Verify the buffer size */
|
||||
if (salen == sizeof(struct sockaddr_in))
|
||||
addr = (struct sockaddr_in *)sa;
|
||||
else if (salen == sizeof(struct sockaddr_in6))
|
||||
addr6 = (struct sockaddr_in6 *)sa;
|
||||
else
|
||||
{
|
||||
callback(arg, ARES_ENOTIMP, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If neither, assume they want a host */
|
||||
if (!(flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST))
|
||||
flags |= ARES_NI_LOOKUPHOST;
|
||||
|
||||
/* All they want is a service, no need for DNS */
|
||||
if ((flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST))
|
||||
{
|
||||
char buf[33], *service;
|
||||
unsigned int port = 0;
|
||||
|
||||
if (salen == sizeof(struct sockaddr_in))
|
||||
port = addr->sin_port;
|
||||
else
|
||||
port = addr6->sin6_port;
|
||||
service = lookup_service(port, flags, buf);
|
||||
callback(arg, ARES_SUCCESS, NULL, service);
|
||||
return;
|
||||
}
|
||||
|
||||
/* They want a host lookup */
|
||||
if ((flags & ARES_NI_LOOKUPHOST))
|
||||
{
|
||||
/* A numeric host can be handled without DNS */
|
||||
if ((flags & ARES_NI_NUMERICHOST))
|
||||
{
|
||||
unsigned int port = 0;
|
||||
char ipbuf[IPBUFSIZ];
|
||||
char srvbuf[32];
|
||||
char *service = NULL;
|
||||
ipbuf[0] = 0;
|
||||
|
||||
/* Specifying not to lookup a host, but then saying a host
|
||||
* is required has to be illegal.
|
||||
*/
|
||||
if (flags & ARES_NI_NAMEREQD)
|
||||
{
|
||||
callback(arg, ARES_EBADFLAGS, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
if (salen == sizeof(struct sockaddr_in6))
|
||||
{
|
||||
ares_inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, IPBUFSIZ);
|
||||
port = addr6->sin6_port;
|
||||
/* If the system supports scope IDs, use it */
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
append_scopeid(addr6, flags, ipbuf);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
ares_inet_ntop(AF_INET, &addr->sin_addr, ipbuf, IPBUFSIZ);
|
||||
port = addr->sin_port;
|
||||
}
|
||||
/* They also want a service */
|
||||
if (flags & ARES_NI_LOOKUPSERVICE)
|
||||
service = lookup_service(port, flags, srvbuf);
|
||||
callback(arg, ARES_SUCCESS, ipbuf, service);
|
||||
return;
|
||||
}
|
||||
/* This is where a DNS lookup becomes necessary */
|
||||
else
|
||||
{
|
||||
niquery = malloc(sizeof(struct nameinfo_query));
|
||||
if (!niquery)
|
||||
{
|
||||
callback(arg, ARES_ENOMEM, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
niquery->callback = callback;
|
||||
niquery->arg = arg;
|
||||
niquery->flags = flags;
|
||||
if (sa->sa_family == AF_INET)
|
||||
{
|
||||
niquery->family = AF_INET;
|
||||
memcpy(&niquery->addr.addr4, addr, sizeof(addr));
|
||||
ares_gethostbyaddr(channel, &addr->sin_addr, sizeof(struct in_addr), AF_INET,
|
||||
nameinfo_callback, niquery);
|
||||
}
|
||||
else
|
||||
{
|
||||
niquery->family = AF_INET6;
|
||||
memcpy(&niquery->addr.addr6, addr6, sizeof(addr6));
|
||||
ares_gethostbyaddr(channel, &addr6->sin6_addr, sizeof(struct in6_addr), AF_INET6,
|
||||
nameinfo_callback, niquery);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void nameinfo_callback(void *arg, int status, struct hostent *host)
|
||||
{
|
||||
struct nameinfo_query *niquery = (struct nameinfo_query *) arg;
|
||||
char srvbuf[33];
|
||||
char *service = NULL;
|
||||
|
||||
|
||||
if (status == ARES_SUCCESS)
|
||||
{
|
||||
/* They want a service too */
|
||||
if (niquery->flags & ARES_NI_LOOKUPSERVICE)
|
||||
{
|
||||
if (niquery->family == AF_INET)
|
||||
service = lookup_service(niquery->addr.addr4.sin_port, niquery->flags, srvbuf);
|
||||
else
|
||||
service = lookup_service(niquery->addr.addr6.sin6_port, niquery->flags, srvbuf);
|
||||
}
|
||||
/* NOFQDN means we have to strip off the domain name portion.
|
||||
We do this by determining our own domain name, then searching the string
|
||||
for this domain name and removing it.
|
||||
*/
|
||||
if (niquery->flags & ARES_NI_NOFQDN)
|
||||
{
|
||||
char buf[255];
|
||||
char *domain;
|
||||
gethostname(buf, 255);
|
||||
if ((domain = strchr(buf, '.')))
|
||||
{
|
||||
char *end = ares_striendstr(host->h_name, domain);
|
||||
if (end)
|
||||
*end = 0;
|
||||
}
|
||||
}
|
||||
niquery->callback(niquery->arg, ARES_SUCCESS, host->h_name, service);
|
||||
return;
|
||||
}
|
||||
/* We couldn't find the host, but it's OK, we can use the IP */
|
||||
else if (status == ARES_ENOTFOUND && !(niquery->flags & ARES_NI_NAMEREQD))
|
||||
{
|
||||
char ipbuf[IPBUFSIZ];
|
||||
if (niquery->family == AF_INET)
|
||||
ares_inet_ntop(AF_INET, &niquery->addr.addr4.sin_addr, ipbuf, IPBUFSIZ);
|
||||
else
|
||||
{
|
||||
ares_inet_ntop(AF_INET6, &niquery->addr.addr6.sin6_addr, ipbuf, IPBUFSIZ);
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
append_scopeid(&niquery->addr.addr6, niquery->flags, ipbuf);
|
||||
#endif
|
||||
}
|
||||
/* They want a service too */
|
||||
if (niquery->flags & ARES_NI_LOOKUPSERVICE)
|
||||
{
|
||||
if (niquery->family == AF_INET)
|
||||
service = lookup_service(niquery->addr.addr4.sin_port, niquery->flags, srvbuf);
|
||||
else
|
||||
service = lookup_service(niquery->addr.addr6.sin6_port, niquery->flags, srvbuf);
|
||||
}
|
||||
niquery->callback(niquery->arg, ARES_SUCCESS, ipbuf, service);
|
||||
return;
|
||||
}
|
||||
niquery->callback(niquery->arg, status, NULL, NULL);
|
||||
free(niquery);
|
||||
}
|
||||
|
||||
static char *lookup_service(unsigned short port, int flags, char *buf)
|
||||
{
|
||||
if (port)
|
||||
{
|
||||
/* Just return the port as a string */
|
||||
if (flags & ARES_NI_NUMERICSERV)
|
||||
sprintf(buf, "%u", ntohs(port));
|
||||
else
|
||||
{
|
||||
struct servent *se;
|
||||
const char *proto;
|
||||
|
||||
if (flags & ARES_NI_UDP)
|
||||
proto = "udp";
|
||||
else if (flags & ARES_NI_SCTP)
|
||||
proto = "sctp";
|
||||
else if (flags & ARES_NI_DCCP)
|
||||
proto = "dccp";
|
||||
else
|
||||
proto = "tcp";
|
||||
se = getservbyport(port, proto);
|
||||
if (se && se->s_name)
|
||||
strcpy(buf, se->s_name);
|
||||
else
|
||||
sprintf(buf, "%u", ntohs(port));
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
static char *append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags, char *buf)
|
||||
{
|
||||
char tmpbuf[IF_NAMESIZE + 1];
|
||||
|
||||
tmpbuf[0] = '%';
|
||||
#ifdef HAVE_IF_INDEXTONAME
|
||||
if ((flags & ARES_NI_NUMERICSCOPE) || (!IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)
|
||||
&& !IN6_IS_ADDR_MC_LINKLOCAL(&addr6->sin6_addr)))
|
||||
{
|
||||
sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL)
|
||||
sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id);
|
||||
}
|
||||
#else
|
||||
sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id);
|
||||
#endif
|
||||
strcat(buf, tmpbuf);
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Determines if s1 ends with the string in s2 (case-insensitive) */
|
||||
static char *ares_striendstr(const char *s1, const char *s2)
|
||||
{
|
||||
const char *c1, *c2, *c1_begin;
|
||||
size_t s1_len = strlen(s1), s2_len = strlen(s2);
|
||||
|
||||
/* If the substr is longer than the full str, it can't match */
|
||||
if (s2_len > s1_len)
|
||||
return NULL;
|
||||
|
||||
/* Jump to the end of s1 minus the length of s2 */
|
||||
c1_begin = s1+s1_len-s2_len;
|
||||
c1 = (const char *)c1_begin;
|
||||
c2 = s2;
|
||||
while (c2 < s2+s2_len)
|
||||
{
|
||||
if (tolower(*c1) != tolower(*c2))
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
c1++;
|
||||
c2++;
|
||||
}
|
||||
}
|
||||
if (c2 == c1 && c2 == NULL)
|
||||
return (char *)c1_begin;
|
||||
return NULL;
|
||||
}
|
103
ares/ares_init.c
103
ares/ares_init.c
@@ -27,10 +27,17 @@
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -44,6 +51,7 @@
|
||||
#include <errno.h>
|
||||
#include "ares.h"
|
||||
#include "ares_private.h"
|
||||
#include "inet_net_pton.h"
|
||||
|
||||
#ifdef WATT32
|
||||
#undef WIN32 /* Redefined in MingW/MSVC headers */
|
||||
@@ -61,6 +69,7 @@ static int set_search(ares_channel channel, const char *str);
|
||||
static int set_options(ares_channel channel, const char *str);
|
||||
static const char *try_option(const char *p, const char *q, const char *opt);
|
||||
#ifndef WIN32
|
||||
static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
|
||||
static int ip_addr(const char *s, int len, struct in_addr *addr);
|
||||
static void natural_mask(struct apattern *pat);
|
||||
static int config_domain(ares_channel channel, char *str);
|
||||
@@ -318,6 +327,7 @@ static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
|
||||
size_t ip_size = sizeof("255.255.255.255,")-1;
|
||||
size_t left = ret_size;
|
||||
char *ret = ret_buf;
|
||||
HRESULT res;
|
||||
|
||||
if (!fi)
|
||||
return (0);
|
||||
@@ -330,7 +340,8 @@ static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
|
||||
if (!GetNetworkParams)
|
||||
goto quit;
|
||||
|
||||
if ((*GetNetworkParams) (fi, &size) != ERROR_BUFFER_OVERFLOW)
|
||||
res = (*GetNetworkParams) (fi, &size);
|
||||
if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
|
||||
goto quit;
|
||||
|
||||
fi = alloca (size);
|
||||
@@ -821,36 +832,70 @@ static int config_nameserver(struct server_state **servers, int *nservers,
|
||||
static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||
const char *str)
|
||||
{
|
||||
struct apattern pat, *newsort;
|
||||
struct apattern pat;
|
||||
const char *q;
|
||||
|
||||
/* Add sortlist entries. */
|
||||
while (*str && *str != ';')
|
||||
{
|
||||
int bits;
|
||||
char ipbuf[16], ipbufpfx[32];
|
||||
/* Find just the IP */
|
||||
q = str;
|
||||
while (*q && *q != '/' && *q != ';' && !isspace((unsigned char)*q))
|
||||
q++;
|
||||
if (ip_addr(str, (int)(q - str), &pat.addr) == 0)
|
||||
memcpy(ipbuf, str, (int)(q-str));
|
||||
ipbuf[(int)(q-str)] = 0;
|
||||
/* Find the prefix */
|
||||
if (*q == '/')
|
||||
{
|
||||
/* We have a pattern address; now determine the mask. */
|
||||
if (*q == '/')
|
||||
const char *str2 = q+1;
|
||||
while (*q && *q != ';' && !isspace((unsigned char)*q))
|
||||
q++;
|
||||
memcpy(ipbufpfx, str, (int)(q-str));
|
||||
ipbufpfx[(int)(q-str)] = 0;
|
||||
str = str2;
|
||||
}
|
||||
else
|
||||
ipbufpfx[0] = 0;
|
||||
/* Lets see if it is CIDR */
|
||||
/* First we'll try IPv6 */
|
||||
if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx ? ipbufpfx : ipbuf,
|
||||
&pat.addr.addr6,
|
||||
sizeof(pat.addr.addr6))) > 0)
|
||||
{
|
||||
pat.type = PATTERN_CIDR;
|
||||
pat.mask.bits = bits;
|
||||
pat.family = AF_INET6;
|
||||
if (!sortlist_alloc(sortlist, nsort, &pat))
|
||||
return ARES_ENOMEM;
|
||||
}
|
||||
if (ipbufpfx &&
|
||||
(bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addr.addr4,
|
||||
sizeof(pat.addr.addr4))) > 0)
|
||||
{
|
||||
pat.type = PATTERN_CIDR;
|
||||
pat.mask.bits = bits;
|
||||
pat.family = AF_INET;
|
||||
if (!sortlist_alloc(sortlist, nsort, &pat))
|
||||
return ARES_ENOMEM;
|
||||
}
|
||||
/* See if it is just a regular IP */
|
||||
else if (ip_addr(ipbuf, (int)(q-str), &pat.addr.addr4) == 0)
|
||||
{
|
||||
if (ipbufpfx)
|
||||
{
|
||||
str = q + 1;
|
||||
while (*q && *q != ';' && !isspace((unsigned char)*q))
|
||||
q++;
|
||||
if (ip_addr(str, (int)(q - str), &pat.mask) != 0)
|
||||
memcpy(ipbuf, str, (int)(q-str));
|
||||
ipbuf[(int)(q-str)] = 0;
|
||||
if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr.addr4) != 0)
|
||||
natural_mask(&pat);
|
||||
}
|
||||
else
|
||||
natural_mask(&pat);
|
||||
|
||||
/* Add this pattern to our list. */
|
||||
newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
|
||||
if (!newsort)
|
||||
pat.family = AF_INET;
|
||||
pat.type = PATTERN_MASK;
|
||||
if (!sortlist_alloc(sortlist, nsort, &pat))
|
||||
return ARES_ENOMEM;
|
||||
newsort[*nsort] = pat;
|
||||
*sortlist = newsort;
|
||||
(*nsort)++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -969,15 +1014,25 @@ static const char *try_option(const char *p, const char *q, const char *opt)
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
static int ip_addr(const char *s, int len, struct in_addr *addr)
|
||||
static int sortlist_alloc(struct apattern **sortlist, int *nsort,
|
||||
struct apattern *pat)
|
||||
{
|
||||
struct apattern *newsort;
|
||||
newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
|
||||
if (!newsort)
|
||||
return 0;
|
||||
newsort[*nsort] = *pat;
|
||||
*sortlist = newsort;
|
||||
(*nsort)++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ip_addr(const char *ipbuf, int len, struct in_addr *addr)
|
||||
{
|
||||
char ipbuf[16];
|
||||
|
||||
/* Four octets and three periods yields at most 15 characters. */
|
||||
if (len > 15)
|
||||
return -1;
|
||||
memcpy(ipbuf, s, len);
|
||||
ipbuf[len] = 0;
|
||||
|
||||
addr->s_addr = inet_addr(ipbuf);
|
||||
if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
|
||||
@@ -992,16 +1047,16 @@ static void natural_mask(struct apattern *pat)
|
||||
/* Store a host-byte-order copy of pat in a struct in_addr. Icky,
|
||||
* but portable.
|
||||
*/
|
||||
addr.s_addr = ntohl(pat->addr.s_addr);
|
||||
addr.s_addr = ntohl(pat->addr.addr4.s_addr);
|
||||
|
||||
/* This is out of date in the CIDR world, but some people might
|
||||
* still rely on it.
|
||||
*/
|
||||
if (IN_CLASSA(addr.s_addr))
|
||||
pat->mask.s_addr = htonl(IN_CLASSA_NET);
|
||||
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSA_NET);
|
||||
else if (IN_CLASSB(addr.s_addr))
|
||||
pat->mask.s_addr = htonl(IN_CLASSB_NET);
|
||||
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSB_NET);
|
||||
else
|
||||
pat->mask.s_addr = htonl(IN_CLASSC_NET);
|
||||
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSC_NET);
|
||||
}
|
||||
#endif
|
||||
|
81
ares/ares_ipv6.h
Normal file
81
ares/ares_ipv6.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of M.I.T. not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* M.I.T. makes no representations about the suitability of
|
||||
* this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*/
|
||||
|
||||
#ifndef ARES_IPV6_H
|
||||
#define ARES_IPV6_H
|
||||
|
||||
#ifndef HAVE_PF_INET6
|
||||
#define PF_INET6 AF_INET6
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_IN6_ADDR
|
||||
struct in6_addr
|
||||
{
|
||||
unsigned char s6_addr[16];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_SOCKADDR_IN6
|
||||
struct sockaddr_in6
|
||||
{
|
||||
unsigned short sin6_family;
|
||||
unsigned short sin6_port;
|
||||
unsigned long sin6_flowinfo;
|
||||
struct in6_addr sin6_addr;
|
||||
unsigned int sin6_scope_id;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ADDRINFO
|
||||
struct addrinfo
|
||||
{
|
||||
int ai_flags;
|
||||
int ai_family;
|
||||
int ai_socktype;
|
||||
int ai_protocol;
|
||||
size_t ai_addrlen;
|
||||
char *ai_cannonname;
|
||||
struct sockaddr *ai_addr;
|
||||
struct addrinfo *ai_next;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef NS_IN6ADDRSZ
|
||||
#if SIZEOF_STRUCT_IN6_ADDR == 0
|
||||
/* We cannot have it set to zero, so we pick a fixed value here */
|
||||
#define NS_IN6ADDRSZ 16
|
||||
#else
|
||||
#define NS_IN6ADDRSZ SIZEOF_STRUCT_IN6_ADDR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NS_INADDRSZ
|
||||
#define NS_INADDRSZ SIZEOF_STRUCT_IN_ADDR
|
||||
#endif
|
||||
|
||||
#ifndef NS_INT16SZ
|
||||
#define NS_INT16SZ 2
|
||||
#endif
|
||||
|
||||
#ifndef IF_NAMESIZE
|
||||
#ifdef IFNAMSIZ
|
||||
#define IF_NAMESIZE IFNAMSIZ
|
||||
#else
|
||||
#define IF_NAMESIZE 256
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* ARES_IPV6_H */
|
@@ -21,6 +21,9 @@
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@@ -24,6 +24,9 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@@ -23,13 +23,19 @@
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ares.h"
|
||||
#include "ares_dns.h"
|
||||
#include "inet_net_pton.h"
|
||||
#include "ares_private.h"
|
||||
|
||||
int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
||||
|
@@ -23,6 +23,9 @@
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@@ -33,6 +33,10 @@
|
||||
#define writev(s,v,c) writev_s(s,v,c)
|
||||
#endif
|
||||
|
||||
#ifdef NETWARE
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#define DEFAULT_TIMEOUT 5
|
||||
#define DEFAULT_TRIES 4
|
||||
#ifndef INADDR_NONE
|
||||
@@ -69,6 +73,8 @@
|
||||
|
||||
#endif
|
||||
|
||||
#include "ares_ipv6.h"
|
||||
|
||||
struct send_request {
|
||||
/* Remaining data to send */
|
||||
const unsigned char *data;
|
||||
@@ -124,9 +130,23 @@ struct query {
|
||||
};
|
||||
|
||||
/* An IP address pattern; matches an IP address X if X & mask == addr */
|
||||
#define PATTERN_MASK 0x1
|
||||
#define PATTERN_CIDR 0x2
|
||||
|
||||
union ares_addr {
|
||||
struct in_addr addr4;
|
||||
struct in6_addr addr6;
|
||||
};
|
||||
|
||||
struct apattern {
|
||||
struct in_addr addr;
|
||||
struct in_addr mask;
|
||||
union ares_addr addr;
|
||||
union
|
||||
{
|
||||
union ares_addr addr;
|
||||
unsigned short bits;
|
||||
} mask;
|
||||
int family;
|
||||
unsigned short type;
|
||||
};
|
||||
|
||||
struct ares_channeldata {
|
||||
@@ -156,7 +176,7 @@ struct ares_channeldata {
|
||||
|
||||
void ares__send_query(ares_channel channel, struct query *query, time_t now);
|
||||
void ares__close_sockets(struct server_state *server);
|
||||
int ares__get_hostent(FILE *fp, struct hostent **host);
|
||||
int ares__get_hostent(FILE *fp, int family, struct hostent **host);
|
||||
int ares__read_line(FILE *fp, char **buf, int *bufsize);
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
|
@@ -27,9 +27,18 @@
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef NETWARE
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
@@ -42,6 +51,11 @@
|
||||
#include "ares_dns.h"
|
||||
#include "ares_private.h"
|
||||
|
||||
#ifndef TRUE
|
||||
/* at least Solaris 7 does not have TRUE at this point */
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#if (defined(WIN32) || defined(WATT32)) && !defined(MSDOS)
|
||||
#define GET_ERRNO() WSAGetLastError()
|
||||
#else
|
||||
@@ -463,13 +477,76 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* nonblock() set the given socket to either blocking or non-blocking mode
|
||||
* based on the 'nonblock' boolean argument. This function is highly portable.
|
||||
*/
|
||||
static int nonblock(ares_socket_t sockfd, /* operate on this */
|
||||
int nonblock /* TRUE or FALSE */)
|
||||
{
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 0
|
||||
#ifdef HAVE_O_NONBLOCK
|
||||
/* most recent unix versions */
|
||||
int flags;
|
||||
|
||||
flags = fcntl(sockfd, F_GETFL, 0);
|
||||
if (TRUE == nonblock)
|
||||
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
else
|
||||
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 1
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
|
||||
/* older unix versions */
|
||||
int flags;
|
||||
|
||||
flags = nonblock;
|
||||
return ioctl(sockfd, FIONBIO, &flags);
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 2
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
|
||||
/* Windows? */
|
||||
unsigned long flags;
|
||||
flags = nonblock;
|
||||
|
||||
return ioctlsocket(sockfd, FIONBIO, &flags);
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 3
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
|
||||
/* presumably for Amiga */
|
||||
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 4
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
|
||||
/* BeOS */
|
||||
long b = nonblock ? 1 : 0;
|
||||
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 5
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DISABLED_NONBLOCKING
|
||||
return 0; /* returns success */
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 6
|
||||
#endif
|
||||
|
||||
#if (SETBLOCK == 0)
|
||||
#error "no non-blocking method was found/used/set"
|
||||
#endif
|
||||
}
|
||||
|
||||
static int open_tcp_socket(ares_channel channel, struct server_state *server)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
u_long flags;
|
||||
#else
|
||||
int flags;
|
||||
#endif
|
||||
ares_socket_t s;
|
||||
struct sockaddr_in sockin;
|
||||
|
||||
@@ -479,25 +556,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
|
||||
return -1;
|
||||
|
||||
/* Set the socket non-blocking. */
|
||||
|
||||
#if defined(WIN32) || defined(WATT32)
|
||||
flags = 1;
|
||||
ioctlsocket(s, FIONBIO, &flags);
|
||||
#else
|
||||
flags = fcntl(s, F_GETFL, 0);
|
||||
|
||||
if (flags == -1)
|
||||
{
|
||||
closesocket(s);
|
||||
return -1;
|
||||
}
|
||||
flags |= O_NONBLOCK;
|
||||
if (fcntl(s, F_SETFL, flags) == -1)
|
||||
{
|
||||
closesocket(s);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
nonblock(s, TRUE);
|
||||
|
||||
/* Connect to the server. */
|
||||
memset(&sockin, 0, sizeof(sockin));
|
||||
@@ -528,6 +587,9 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
|
||||
if (s == ARES_SOCKET_BAD)
|
||||
return -1;
|
||||
|
||||
/* Set the socket non-blocking. */
|
||||
nonblock(s, TRUE);
|
||||
|
||||
/* Connect to the server. */
|
||||
memset(&sockin, 0, sizeof(sockin));
|
||||
sockin.sin_family = AF_INET;
|
||||
|
@@ -21,6 +21,9 @@
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@@ -21,6 +21,9 @@
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@@ -38,7 +38,8 @@ const char *ares_strerror(int code)
|
||||
"Error reading file",
|
||||
"Out of memory",
|
||||
"Channel is being destroyed",
|
||||
"Misformatted string"
|
||||
"Misformatted string",
|
||||
"Illegal flags specified"
|
||||
};
|
||||
|
||||
assert(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext)));
|
||||
|
@@ -4,12 +4,12 @@
|
||||
#define ARES__VERSION_H
|
||||
|
||||
#define ARES_VERSION_MAJOR 1
|
||||
#define ARES_VERSION_MINOR 2
|
||||
#define ARES_VERSION_MINOR 3
|
||||
#define ARES_VERSION_PATCH 0
|
||||
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
|
||||
(ARES_VERSION_MINOR<<8)|\
|
||||
(ARES_VERSION_PATCH))
|
||||
#define ARES_VERSION_STR "1.2.0"
|
||||
#define ARES_VERSION_STR "1.3.0"
|
||||
|
||||
const char *ares_version(int *version);
|
||||
|
||||
|
60
ares/bitncmp.c
Normal file
60
ares/bitncmp.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_BITNCMP
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "bitncmp.h"
|
||||
|
||||
/*
|
||||
* int
|
||||
* bitncmp(l, r, n)
|
||||
* compare bit masks l and r, for n bits.
|
||||
* return:
|
||||
* -1, 1, or 0 in the libc tradition.
|
||||
* note:
|
||||
* network byte order assumed. this means 192.5.5.240/28 has
|
||||
* 0x11110000 in its fourth octet.
|
||||
* author:
|
||||
* Paul Vixie (ISC), June 1996
|
||||
*/
|
||||
int
|
||||
ares_bitncmp(const void *l, const void *r, int n) {
|
||||
unsigned int lb, rb;
|
||||
int x, b;
|
||||
|
||||
b = n / 8;
|
||||
x = memcmp(l, r, b);
|
||||
if (x)
|
||||
return (x);
|
||||
|
||||
lb = ((const unsigned char *)l)[b];
|
||||
rb = ((const unsigned char *)r)[b];
|
||||
for (b = n % 8; b > 0; b--) {
|
||||
if ((lb & 0x80) != (rb & 0x80)) {
|
||||
if (lb & 0x80)
|
||||
return (1);
|
||||
return (-1);
|
||||
}
|
||||
lb <<= 1;
|
||||
rb <<= 1;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
26
ares/bitncmp.h
Normal file
26
ares/bitncmp.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of M.I.T. not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* M.I.T. makes no representations about the suitability of
|
||||
* this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*/
|
||||
|
||||
#ifndef BITNCMP_H
|
||||
#define BITNCMP_H
|
||||
|
||||
#ifndef HAVE_BITNCMP
|
||||
int ares_bitncmp(const void *l, const void *r, int n);
|
||||
#else
|
||||
#define ares_bitncmp(x,y,z) bitncmp(x,y,z)
|
||||
#endif
|
||||
|
||||
#endif /* BITNCMP_H */
|
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
libtoolize --copy --automake --force
|
||||
aclocal
|
||||
autoheader
|
||||
autoconf
|
||||
automake --add-missing
|
||||
${LIBTOOLIZE:-libtoolize} --copy --automake --force
|
||||
${ACLOCAL:-aclocal}
|
||||
${AUTOHEADER:-autoheader}
|
||||
${AUTOCONF:-autoconf}
|
||||
${AUTOMAKE:-automake} --add-missing
|
||||
|
@@ -65,10 +65,48 @@ AC_CHECK_HEADERS(
|
||||
sys/time.h \
|
||||
sys/select.h \
|
||||
sys/socket.h \
|
||||
sys/ioctl.h \
|
||||
winsock.h \
|
||||
netinet/in.h \
|
||||
net/if.h \
|
||||
arpa/nameser.h \
|
||||
arpa/nameser_compat.h \
|
||||
arpa/inet.h, , ,
|
||||
[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
dnl We do this default-include simply to make sure that the nameser_compat.h
|
||||
dnl header *REALLY* can be include after the new nameser.h. It seems AIX 5.1
|
||||
dnl (and others?) is not designed to allow this.
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
|
||||
dnl *Sigh* these are needed in order for net/if.h to get properly detected.
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
]
|
||||
)
|
||||
|
||||
AC_CHECK_TYPE(socklen_t, ,
|
||||
AC_DEFINE(socklen_t, int, [the length of a socket address]),
|
||||
[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
dnl check for AF_INET6
|
||||
CARES_CHECK_CONSTANT(
|
||||
[
|
||||
@@ -120,4 +158,194 @@ CARES_CHECK_STRUCT(
|
||||
AC_DEFINE_UNQUOTED(HAVE_STRUCT_IN6_ADDR,1,[Define to 1 if you have struct in6_addr.])
|
||||
)
|
||||
|
||||
dnl check for the sockaddr_in6 structure
|
||||
CARES_CHECK_STRUCT(
|
||||
[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
], [sockaddr_in6],
|
||||
AC_DEFINE_UNQUOTED(HAVE_STRUCT_SOCKADDR_IN6,1,
|
||||
[Define to 1 if you have struct sockaddr_in6.]) ac_have_sockaddr_in6=yes
|
||||
)
|
||||
|
||||
if test "$ac_have_sockaddr_in6" = "yes" ; then
|
||||
CARES_CHECK_STRUCT_MEMBER(
|
||||
[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
], [sockaddr_in6], [sin6_scope_id],
|
||||
AC_DEFINE_UNQUOTED(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID,1,
|
||||
[Define to 1 if your struct sockaddr_in6 has sin6_scope_id.])
|
||||
)
|
||||
fi
|
||||
|
||||
dnl check for the addrinfo structure
|
||||
CARES_CHECK_STRUCT(
|
||||
[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
], [addrinfo],
|
||||
AC_DEFINE_UNQUOTED(HAVE_STRUCT_ADDRINFO,1,
|
||||
[Define to 1 if you have struct addrinfo.])
|
||||
)
|
||||
|
||||
dnl check for inet_pton
|
||||
AC_CHECK_FUNCS(inet_pton)
|
||||
dnl Some systems have it, but not IPv6
|
||||
if test "$ac_cv_func_inet_pton" = "yes" ; then
|
||||
AC_MSG_CHECKING(if inet_pton supports IPv6)
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
int main()
|
||||
{
|
||||
struct in6_addr addr6;
|
||||
if (inet_pton(AF_INET6, "::1", &addr6) < 1)
|
||||
exit(1);
|
||||
else
|
||||
exit(0);
|
||||
}
|
||||
], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE_UNQUOTED(HAVE_INET_PTON_IPV6,1,[Define to 1 if inet_pton supports IPv6.])
|
||||
], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
|
||||
fi
|
||||
dnl Check for inet_net_pton
|
||||
AC_CHECK_FUNCS(inet_net_pton)
|
||||
dnl Again, some systems have it, but not IPv6
|
||||
if test "$ac_cv_func_inet_net_pton" = "yes" ; then
|
||||
AC_MSG_CHECKING(if inet_net_pton supports IPv6)
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
int main()
|
||||
{
|
||||
struct in6_addr addr6;
|
||||
if (inet_net_pton(AF_INET6, "::1", &addr6, sizeof(addr6)) < 1)
|
||||
exit(1);
|
||||
else
|
||||
exit(0);
|
||||
}
|
||||
], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE_UNQUOTED(HAVE_INET_NET_PTON_IPV6,1,[Define to 1 if inet_net_pton supports IPv6.])
|
||||
], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
|
||||
fi
|
||||
|
||||
|
||||
dnl Check for inet_ntop
|
||||
AC_CHECK_FUNCS(inet_ntop)
|
||||
dnl Again, some systems have it, but not IPv6
|
||||
if test "$ac_cv_func_inet_ntop" = "yes" ; then
|
||||
AC_MSG_CHECKING(if inet_ntop supports IPv6)
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
int main()
|
||||
{
|
||||
struct in6_addr addr6;
|
||||
char buf[128];
|
||||
if (inet_ntop(AF_INET6, &addr6, buf, 128) == 0 && errno == EAFNOSUPPORT)
|
||||
exit(1);
|
||||
else
|
||||
exit(0);
|
||||
}
|
||||
], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6,1,[Define to 1 if inet_ntop supports IPv6.])
|
||||
], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
|
||||
fi
|
||||
|
||||
AC_CHECK_SIZEOF(struct in6_addr, ,
|
||||
[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
]
|
||||
)
|
||||
AC_CHECK_SIZEOF(struct in_addr, ,
|
||||
[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
]
|
||||
)
|
||||
|
||||
AC_CHECK_FUNCS([bitncmp if_indextoname])
|
||||
|
||||
CURL_CHECK_NONBLOCKING_SOCKET
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
|
439
ares/inet_net_pton.c
Normal file
439
ares/inet_net_pton.c
Normal file
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(WIN32) && !defined(WATT32)
|
||||
#include "nameser.h"
|
||||
#else
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ares_ipv6.h"
|
||||
#include "inet_net_pton.h"
|
||||
|
||||
#if !defined(HAVE_INET_NET_PTON) || !defined(HAVE_INET_NET_PTON_IPV6) || \
|
||||
!defined(HAVE_INET_PTON) || !defined(HAVE_INET_PTON_IPV6)
|
||||
|
||||
/*
|
||||
* static int
|
||||
* inet_net_pton_ipv4(src, dst, size)
|
||||
* convert IPv4 network number from presentation to network format.
|
||||
* accepts hex octets, hex strings, decimal octets, and /CIDR.
|
||||
* "size" is in bytes and describes "dst".
|
||||
* return:
|
||||
* number of bits, either imputed classfully or specified with /CIDR,
|
||||
* or -1 if some failure occurred (check errno). ENOENT means it was
|
||||
* not an IPv4 network specification.
|
||||
* note:
|
||||
* network byte order assumed. this means 192.5.5.240/28 has
|
||||
* 0b11110000 in its fourth octet.
|
||||
* author:
|
||||
* Paul Vixie (ISC), June 1996
|
||||
*/
|
||||
static int
|
||||
inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
|
||||
{
|
||||
static const char xdigits[] = "0123456789abcdef";
|
||||
static const char digits[] = "0123456789";
|
||||
int n, ch, tmp = 0, dirty, bits;
|
||||
const unsigned char *odst = dst;
|
||||
|
||||
ch = *src++;
|
||||
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
|
||||
&& isascii((unsigned char)(src[1]))
|
||||
&& isxdigit((unsigned char)(src[1]))) {
|
||||
/* Hexadecimal: Eat nybble string. */
|
||||
if (size <= 0U)
|
||||
goto emsgsize;
|
||||
dirty = 0;
|
||||
src++; /* skip x or X. */
|
||||
while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) {
|
||||
if (isupper(ch))
|
||||
ch = tolower(ch);
|
||||
n = (int)(strchr(xdigits, ch) - xdigits);
|
||||
if (dirty == 0)
|
||||
tmp = n;
|
||||
else
|
||||
tmp = (tmp << 4) | n;
|
||||
if (++dirty == 2) {
|
||||
if (size-- <= 0U)
|
||||
goto emsgsize;
|
||||
*dst++ = (unsigned char) tmp;
|
||||
dirty = 0;
|
||||
}
|
||||
}
|
||||
if (dirty) { /* Odd trailing nybble? */
|
||||
if (size-- <= 0U)
|
||||
goto emsgsize;
|
||||
*dst++ = (unsigned char) (tmp << 4);
|
||||
}
|
||||
} else if (isascii(ch) && isdigit(ch)) {
|
||||
/* Decimal: eat dotted digit string. */
|
||||
for (;;) {
|
||||
tmp = 0;
|
||||
do {
|
||||
n = (int)(strchr(digits, ch) - digits);
|
||||
tmp *= 10;
|
||||
tmp += n;
|
||||
if (tmp > 255)
|
||||
goto enoent;
|
||||
} while ((ch = *src++) != '\0' &&
|
||||
isascii(ch) && isdigit(ch));
|
||||
if (size-- <= 0U)
|
||||
goto emsgsize;
|
||||
*dst++ = (unsigned char) tmp;
|
||||
if (ch == '\0' || ch == '/')
|
||||
break;
|
||||
if (ch != '.')
|
||||
goto enoent;
|
||||
ch = *src++;
|
||||
if (!isascii(ch) || !isdigit(ch))
|
||||
goto enoent;
|
||||
}
|
||||
} else
|
||||
goto enoent;
|
||||
|
||||
bits = -1;
|
||||
if (ch == '/' && isascii((unsigned char)(src[0])) &&
|
||||
isdigit((unsigned char)(src[0])) && dst > odst) {
|
||||
/* CIDR width specifier. Nothing can follow it. */
|
||||
ch = *src++; /* Skip over the /. */
|
||||
bits = 0;
|
||||
do {
|
||||
n = (int)(strchr(digits, ch) - digits);
|
||||
bits *= 10;
|
||||
bits += n;
|
||||
} while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
|
||||
if (ch != '\0')
|
||||
goto enoent;
|
||||
if (bits > 32)
|
||||
goto emsgsize;
|
||||
}
|
||||
|
||||
/* Firey death and destruction unless we prefetched EOS. */
|
||||
if (ch != '\0')
|
||||
goto enoent;
|
||||
|
||||
/* If nothing was written to the destination, we found no address. */
|
||||
if (dst == odst)
|
||||
goto enoent;
|
||||
/* If no CIDR spec was given, infer width from net class. */
|
||||
if (bits == -1) {
|
||||
if (*odst >= 240) /* Class E */
|
||||
bits = 32;
|
||||
else if (*odst >= 224) /* Class D */
|
||||
bits = 8;
|
||||
else if (*odst >= 192) /* Class C */
|
||||
bits = 24;
|
||||
else if (*odst >= 128) /* Class B */
|
||||
bits = 16;
|
||||
else /* Class A */
|
||||
bits = 8;
|
||||
/* If imputed mask is narrower than specified octets, widen. */
|
||||
if (bits < ((dst - odst) * 8))
|
||||
bits = (int)(dst - odst) * 8;
|
||||
/*
|
||||
* If there are no additional bits specified for a class D
|
||||
* address adjust bits to 4.
|
||||
*/
|
||||
if (bits == 8 && *odst == 224)
|
||||
bits = 4;
|
||||
}
|
||||
/* Extend network to cover the actual mask. */
|
||||
while (bits > ((dst - odst) * 8)) {
|
||||
if (size-- <= 0U)
|
||||
goto emsgsize;
|
||||
*dst++ = '\0';
|
||||
}
|
||||
return (bits);
|
||||
|
||||
enoent:
|
||||
errno = ENOENT;
|
||||
return (-1);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
getbits(const char *src, int *bitsp)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int n;
|
||||
int val;
|
||||
char ch;
|
||||
|
||||
val = 0;
|
||||
n = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
pch = strchr(digits, ch);
|
||||
if (pch != NULL) {
|
||||
if (n++ != 0 && val == 0) /* no leading zeros */
|
||||
return (0);
|
||||
val *= 10;
|
||||
val += (pch - digits);
|
||||
if (val > 128) /* range */
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (n == 0)
|
||||
return (0);
|
||||
*bitsp = val;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
getv4(const char *src, unsigned char *dst, int *bitsp)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
unsigned char *odst = dst;
|
||||
int n;
|
||||
unsigned int val;
|
||||
char ch;
|
||||
|
||||
val = 0;
|
||||
n = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
pch = strchr(digits, ch);
|
||||
if (pch != NULL) {
|
||||
if (n++ != 0 && val == 0) /* no leading zeros */
|
||||
return (0);
|
||||
val *= 10;
|
||||
val += (pch - digits);
|
||||
if (val > 255) /* range */
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' || ch == '/') {
|
||||
if (dst - odst > 3) /* too many octets? */
|
||||
return (0);
|
||||
*dst++ = val;
|
||||
if (ch == '/')
|
||||
return (getbits(src, bitsp));
|
||||
val = 0;
|
||||
n = 0;
|
||||
continue;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (n == 0)
|
||||
return (0);
|
||||
if (dst - odst > 3) /* too many octets? */
|
||||
return (0);
|
||||
*dst++ = val;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size)
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
unsigned int val;
|
||||
int digits;
|
||||
int bits;
|
||||
size_t bytes;
|
||||
int words;
|
||||
int ipv4;
|
||||
|
||||
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
goto enoent;
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
digits = 0;
|
||||
bits = -1;
|
||||
ipv4 = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (++digits > 4)
|
||||
goto enoent;
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = src;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp)
|
||||
goto enoent;
|
||||
colonp = tp;
|
||||
continue;
|
||||
} else if (*src == '\0')
|
||||
goto enoent;
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
digits = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
getv4(curtok, tp, &bits) > 0) {
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
ipv4 = 1;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
if (ch == '/' && getbits(src, &bits) > 0)
|
||||
break;
|
||||
goto enoent;
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
goto enoent;
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
}
|
||||
if (bits == -1)
|
||||
bits = 128;
|
||||
|
||||
words = (bits + 15) / 16;
|
||||
if (words < 2)
|
||||
words = 2;
|
||||
if (ipv4)
|
||||
words = 8;
|
||||
endp = tmp + 2 * words;
|
||||
|
||||
if (colonp != NULL) {
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = (int)(tp - colonp);
|
||||
int i;
|
||||
|
||||
if (tp == endp)
|
||||
goto enoent;
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp)
|
||||
goto enoent;
|
||||
|
||||
bytes = (bits + 7) / 8;
|
||||
if (bytes > size)
|
||||
goto emsgsize;
|
||||
memcpy(dst, tmp, bytes);
|
||||
return (bits);
|
||||
|
||||
enoent:
|
||||
errno = ENOENT;
|
||||
return (-1);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* int
|
||||
* inet_net_pton(af, src, dst, size)
|
||||
* convert network number from presentation to network format.
|
||||
* accepts hex octets, hex strings, decimal octets, and /CIDR.
|
||||
* "size" is in bytes and describes "dst".
|
||||
* return:
|
||||
* number of bits, either imputed classfully or specified with /CIDR,
|
||||
* or -1 if some failure occurred (check errno). ENOENT means it was
|
||||
* not a valid network specification.
|
||||
* author:
|
||||
* Paul Vixie (ISC), June 1996
|
||||
*/
|
||||
int
|
||||
ares_inet_net_pton(int af, const char *src, void *dst, size_t size)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_net_pton_ipv4(src, dst, size));
|
||||
case AF_INET6:
|
||||
return (inet_net_pton_ipv6(src, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_INET_PTON) || !defined(HAVE_INET_PTON_IPV6)
|
||||
int ares_inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
int size, result;
|
||||
|
||||
if (af == AF_INET)
|
||||
size = sizeof(struct in_addr);
|
||||
else if (af == AF_INET6)
|
||||
size = sizeof(struct in6_addr);
|
||||
else
|
||||
{
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
result = ares_inet_net_pton(af, src, dst, size);
|
||||
if (result == -1 && errno == ENOENT)
|
||||
return 0;
|
||||
return (result > -1 ? 1 : -1);
|
||||
}
|
||||
#endif
|
31
ares/inet_net_pton.h
Normal file
31
ares/inet_net_pton.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of M.I.T. not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* M.I.T. makes no representations about the suitability of
|
||||
* this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*/
|
||||
|
||||
#ifndef INET_NET_PTON_H
|
||||
#define INET_NET_PTON_H
|
||||
|
||||
#if defined(HAVE_INET_PTON) && defined(HAVE_INET_PTON_IPV6)
|
||||
#define ares_inet_pton(x,y,z) inet_pton(x,y,z)
|
||||
#else
|
||||
int ares_inet_pton(int af, const char *src, void *dst);
|
||||
#endif
|
||||
#if defined(HAVE_INET_NET_PTON) && defined(HAVE_INET_NET_PTON_IPV6)
|
||||
#define ares_inet_net_pton(w,x,y,z) inet_net_pton(w,x,y,z)
|
||||
#else
|
||||
int ares_inet_net_pton(int af, const char *src, void *dst, size_t size);
|
||||
#endif
|
||||
|
||||
#endif /* INET_NET_PTON_H */
|
206
ares/inet_ntop.c
Normal file
206
ares/inet_ntop.c
Normal file
@@ -0,0 +1,206 @@
|
||||
/* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(WIN32) && !defined(WATT32)
|
||||
#include "nameser.h"
|
||||
#else
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ares_ipv6.h"
|
||||
#include "inet_ntop.h"
|
||||
|
||||
|
||||
#if !defined(HAVE_INET_NTOP) || !defined(HAVE_INET_NTOP_IPV6)
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size);
|
||||
static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size);
|
||||
|
||||
/* char *
|
||||
* inet_ntop(af, src, dst, size)
|
||||
* convert a network format address to presentation format.
|
||||
* return:
|
||||
* pointer to presentation format address (`dst'), or NULL (see errno).
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
const char *
|
||||
ares_inet_ntop(int af, const void *src, char *dst, size_t size)
|
||||
{
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_ntop4(src, dst, size));
|
||||
case AF_INET6:
|
||||
return (inet_ntop6(src, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop4(src, dst, size)
|
||||
* format an IPv4 address, more or less like inet_ntoa()
|
||||
* return:
|
||||
* `dst' (as a const)
|
||||
* notes:
|
||||
* (1) uses no statics
|
||||
* (2) takes a unsigned char* not an in_addr as input
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop4(const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
static const char fmt[] = "%u.%u.%u.%u";
|
||||
char tmp[sizeof "255.255.255.255"];
|
||||
|
||||
if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop6(src, dst, size)
|
||||
* convert IPv6 binary address into presentation (printable) format
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop6(const unsigned 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"], *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
unsigned int words[NS_IN6ADDRSZ / NS_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 < NS_IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_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) {
|
||||
if (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 < (NS_IN6ADDRSZ / NS_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)))
|
||||
return (NULL);
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += SPRINTF((tp, "%x", words[i]));
|
||||
}
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
|
||||
/*
|
||||
* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((size_t)(tp - tmp) > size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
#endif
|
26
ares/inet_ntop.h
Normal file
26
ares/inet_ntop.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of M.I.T. not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* M.I.T. makes no representations about the suitability of
|
||||
* this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*/
|
||||
|
||||
#ifndef INET_NTOP_H
|
||||
#define INET_NTOP_H
|
||||
|
||||
#ifdef HAVE_INET_NTOP
|
||||
#define ares_inet_ntop(w,x,y,z) inet_ntop(w,x,y,z)
|
||||
#else
|
||||
const char *ares_inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif
|
||||
|
||||
#endif /* INET_NET_NTOP_H */
|
@@ -16,6 +16,8 @@
|
||||
|
||||
#define EINPROGRESS WSAEINPROGRESS
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#define EMSGSIZE WSAEMSGSIZE
|
||||
#define EAFNOSUPPORT WSAEAFNOSUPPORT
|
||||
|
||||
/* Structure for scatter/gather I/O. */
|
||||
struct iovec
|
||||
@@ -37,7 +39,9 @@ int ares_gettimeofday(struct timeval *tv, struct timezone *tz);
|
||||
#endif /* !NETWARE */
|
||||
|
||||
#define NS_CMPRSFLGS 0xc0
|
||||
|
||||
#define NS_IN6ADDRSZ 16
|
||||
#define NS_INT16SZ 2
|
||||
#define NS_INADDRSZ 4
|
||||
|
||||
/* Flag bits indicating name compression. */
|
||||
#define INDIR_MASK NS_CMPRSFLGS
|
||||
|
12
ares/setup.h
12
ares/setup.h
@@ -19,6 +19,7 @@
|
||||
#else
|
||||
/* simple work-around for now, for systems without configure support */
|
||||
#define ssize_t int
|
||||
#define socklen_t int
|
||||
#endif
|
||||
|
||||
/* Recent autoconf versions define these symbols in config.h. We don't want
|
||||
@@ -78,15 +79,4 @@ int ares_strcasecmp(const char *s1, const char *s2);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_PF_INET6
|
||||
#define PF_INET6 AF_INET6
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_IN6_ADDR
|
||||
struct in6_addr
|
||||
{
|
||||
unsigned char s6_addr[16];
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* ARES_SETUP_H */
|
||||
|
46
buildconf
46
buildconf
@@ -13,7 +13,7 @@ findtool(){
|
||||
IFS=":"
|
||||
for path in $PATH
|
||||
do
|
||||
if test -r "$path/$file"; then
|
||||
if test -f "$path/$file"; then
|
||||
echo "$path/$file"
|
||||
return
|
||||
fi
|
||||
@@ -24,7 +24,7 @@ findtool(){
|
||||
# autoconf 2.57 or newer
|
||||
#
|
||||
need_autoconf="2.57"
|
||||
ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|head -1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
||||
ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|head -n 1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
||||
if test -z "$ac_version"; then
|
||||
echo "buildconf: autoconf not found."
|
||||
echo " You need autoconf version $need_autoconf or newer installed."
|
||||
@@ -45,7 +45,7 @@ echo "buildconf: autoconf version $ac_version (ok)"
|
||||
#--------------------------------------------------------------------------
|
||||
# autoheader 2.50 or newer
|
||||
#
|
||||
ah_version=`${AUTOHEADER:-autoheader} --version 2>/dev/null|head -1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
||||
ah_version=`${AUTOHEADER:-autoheader} --version 2>/dev/null|head -n 1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
||||
if test -z "$ah_version"; then
|
||||
echo "buildconf: autoheader not found."
|
||||
echo " You need autoheader version 2.50 or newer installed."
|
||||
@@ -67,7 +67,7 @@ echo "buildconf: autoheader version $ah_version (ok)"
|
||||
# automake 1.7 or newer
|
||||
#
|
||||
need_automake="1.7"
|
||||
am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|head -1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'`
|
||||
am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|head -n 1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'`
|
||||
if test -z "$am_version"; then
|
||||
echo "buildconf: automake not found."
|
||||
echo " You need automake version $need_automake or newer installed."
|
||||
@@ -85,6 +85,14 @@ fi
|
||||
|
||||
echo "buildconf: automake version $am_version (ok)"
|
||||
|
||||
ac=`findtool aclocal`
|
||||
|
||||
if test -z "$ac"; then
|
||||
echo "buildconf: aclocal not found. Weird automake installation!"
|
||||
exit 1
|
||||
else
|
||||
echo "buildconf: aclocal found"
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# libtool check
|
||||
@@ -105,7 +113,7 @@ fi
|
||||
# set the LIBTOOLIZE here so that glibtoolize is used if glibtool was found
|
||||
LIBTOOLIZE="${libtool}ize"
|
||||
|
||||
lt_pversion=`$libtool --version 2>/dev/null|head -1|sed -e 's/^[^0-9]*//g' -e 's/[- ].*//'`
|
||||
lt_pversion=`$libtool --version 2>/dev/null|head -n 1|sed -e 's/^[^0-9]*//g' -e 's/[- ].*//'`
|
||||
if test -z "$lt_pversion"; then
|
||||
echo "buildconf: libtool not found."
|
||||
echo " You need libtool version $LIBTOOL_WANTED_VERSION or newer installed"
|
||||
@@ -142,10 +150,17 @@ fi
|
||||
|
||||
echo "buildconf: libtool version $lt_version (ok)"
|
||||
|
||||
if test -f "$LIBTOOLIZE"; then
|
||||
echo "buildconf: libtoolize found"
|
||||
else
|
||||
echo "buildconf: libtoolize not found. Weird libtool installation!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# m4 check
|
||||
#
|
||||
m4=`${M4:-m4} --version 2>/dev/null|head -1`;
|
||||
m4=`${M4:-m4} --version 2>/dev/null|head -n 1`;
|
||||
m4_version=`echo $m4 | sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'`
|
||||
|
||||
if { echo $m4 | grep "GNU" >/dev/null 2>&1; } then
|
||||
@@ -155,6 +170,10 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# perl check
|
||||
#
|
||||
PERL=`findtool perl`
|
||||
|
||||
# ------------------------------------------------------------
|
||||
|
||||
@@ -164,8 +183,13 @@ echo "buildconf: running libtoolize"
|
||||
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The libtool command failed"
|
||||
echo "buildconf: running aclocal"
|
||||
${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
|
||||
if test -n "$PERL"; then
|
||||
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
|
||||
else
|
||||
echo "buildconf: perl not found"
|
||||
exit 1
|
||||
fi
|
||||
echo "buildconf: running autoheader"
|
||||
${AUTOHEADER:-autoheader} || die "The autoheader command failed"
|
||||
echo "buildconf: cp lib/config.h.in src/config.h.in"
|
||||
@@ -175,9 +199,11 @@ ${AUTOCONF:-autoconf} || die "The autoconf command failed"
|
||||
|
||||
if test -d ares; then
|
||||
cd ares
|
||||
echo "buildconf: running aclocal in the ares directory"
|
||||
echo "buildconf: running ares/libtoolize"
|
||||
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The libtool command failed"
|
||||
echo "buildconf: running ares/aclocal"
|
||||
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The ares aclocal command failed"
|
||||
echo "buildconf: running autoconf in the ares directory"
|
||||
echo "buildconf: running ares/autoconf"
|
||||
${AUTOCONF:-autoconf} || die "The ares autoconf command failed"
|
||||
cd ..
|
||||
fi
|
||||
|
400
configure.ac
400
configure.ac
@@ -7,7 +7,7 @@ dnl We don't know the version number "staticly" so we use a dash here
|
||||
AC_INIT(curl, [-], [a suitable curl mailing list => http://curl.haxx.se/mail/])
|
||||
|
||||
dnl configure script copyright
|
||||
AC_COPYRIGHT([Copyright (c) 1998 - 2004 Daniel Stenberg, <daniel@haxx.se>
|
||||
AC_COPYRIGHT([Copyright (c) 1998 - 2005 Daniel Stenberg, <daniel@haxx.se>
|
||||
This configure script may be copied, distributed and modified under the
|
||||
terms of the curl license; see COPYING for more details])
|
||||
|
||||
@@ -56,7 +56,7 @@ AC_SUBST(PKGADD_VENDOR)
|
||||
|
||||
dnl
|
||||
dnl initialize all the info variables
|
||||
curl_ssl_msg="no (--with-ssl)"
|
||||
curl_ssl_msg="no (--with-ssl / --with-gnutls)"
|
||||
curl_zlib_msg="no (--with-zlib)"
|
||||
curl_krb4_msg="no (--with-krb4*)"
|
||||
curl_gss_msg="no (--with-gssapi)"
|
||||
@@ -122,6 +122,14 @@ case $host in
|
||||
*-*-mingw*)
|
||||
AC_DEFINE(BUILDING_LIBCURL, 1, [when building libcurl itself])
|
||||
AC_MSG_RESULT(yes)
|
||||
<20> <20>AC_MSG_CHECKING([if we need CURL_STATICLIB])
|
||||
if test "X$enable_shared" = "Xno"
|
||||
then
|
||||
AC_DEFINE(CURL_STATICLIB, 1, [when not building a shared library])
|
||||
AC_MSG_RESULT(yes)
|
||||
<20> <20>else
|
||||
<20> <20> <20>AC_MSG_RESULT(no)
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(no)
|
||||
@@ -559,14 +567,15 @@ OPT_KRB4=off
|
||||
AC_ARG_WITH(krb4,dnl
|
||||
AC_HELP_STRING([--with-krb4=DIR],[where to look for Kerberos4]),[
|
||||
OPT_KRB4="$withval"
|
||||
if test X"$OPT_KRB4" != Xyes
|
||||
then
|
||||
LDFLAGS="$LDFLAGS -L$OPT_KRB4/lib$libsuff"
|
||||
KRB4LIB="$OPT_KRB4/lib$libsuff"
|
||||
CPPFLAGS="$CPPFLAGS -I$OPT_KRB4/include"
|
||||
KRB4INC="$OPT_KRB4/include"
|
||||
if test X"$OPT_KRB4" != Xno; then
|
||||
want_krb4="yes"
|
||||
if test X"$OPT_KRB4" != Xyes; then
|
||||
LDFLAGS="$LDFLAGS -L$OPT_KRB4/lib$libsuff"
|
||||
KRB4LIB="$OPT_KRB4/lib$libsuff"
|
||||
CPPFLAGS="$CPPFLAGS -I$OPT_KRB4/include"
|
||||
KRB4INC="$OPT_KRB4/include"
|
||||
fi
|
||||
fi
|
||||
want_krb4="yes"
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([if Kerberos4 support is requested])
|
||||
@@ -635,10 +644,13 @@ dnl **********************************************************************
|
||||
|
||||
AC_ARG_WITH(spnego,
|
||||
AC_HELP_STRING([--with-spnego=DIR],
|
||||
[Specify location of SPNEGO library fbopenssl]),
|
||||
[ SPNEGO_ROOT="$withval"
|
||||
want_spnego="yes" ]
|
||||
)
|
||||
[Specify location of SPNEGO library fbopenssl]), [
|
||||
SPNEGO_ROOT="$withval"
|
||||
if test x"$SPNEGO_ROOT" != xno; then
|
||||
want_spnego="yes"
|
||||
fi
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([if SPNEGO support is requested])
|
||||
if test x"$want_spnego" = xyes; then
|
||||
|
||||
@@ -675,19 +687,24 @@ AC_ARG_WITH(gssapi-includes,
|
||||
AC_ARG_WITH(gssapi-libs,
|
||||
AC_HELP_STRING([--with-gssapi-libs=DIR],
|
||||
[Specify location of GSSAPI libs]),
|
||||
[ GSSAPI_LIBS="-L$withval -lgssapi"
|
||||
[ GSSAPI_LIBS="-L$withval"
|
||||
want_gss="yes" ]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(gssapi,
|
||||
AC_HELP_STRING([--with-gssapi=DIR],
|
||||
[Where to look for GSSAPI]),
|
||||
[ GSSAPI_ROOT="$withval"
|
||||
want_gss="yes" ]
|
||||
)
|
||||
[Where to look for GSSAPI]), [
|
||||
GSSAPI_ROOT="$withval"
|
||||
if test x"$GSSAPI_ROOT" != xno; then
|
||||
want_gss="yes"
|
||||
fi
|
||||
])
|
||||
|
||||
save_CPPFLAGS="$CPPFLAGS"
|
||||
AC_MSG_CHECKING([if GSSAPI support is requested])
|
||||
if test x"$want_gss" = xyes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
if test -z "$GSSAPI_INCS"; then
|
||||
if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
|
||||
GSSAPI_INCS=`$GSSAPI_ROOT/bin/krb5-config --cflags gssapi`
|
||||
@@ -697,7 +714,48 @@ if test x"$want_gss" = xyes; then
|
||||
fi
|
||||
CPPFLAGS="$CPPFLAGS $GSSAPI_INCS"
|
||||
|
||||
if test -z "$GSSAPI_LIB_DIR"; then
|
||||
AC_CHECK_HEADER(gss.h,
|
||||
[
|
||||
dnl found in the given dirs
|
||||
AC_DEFINE(HAVE_GSSGNU, 1, [if you have the GNU gssapi libraries])
|
||||
gnu_gss=yes
|
||||
],
|
||||
[
|
||||
dnl not found, check Heimdal
|
||||
AC_CHECK_HEADER(gssapi.h,
|
||||
[
|
||||
dnl found in the given dirs
|
||||
AC_DEFINE(HAVE_GSSHEIMDAL, 1, [if you have the Heimdal gssapi libraries])
|
||||
],
|
||||
[
|
||||
dnl not found, check in gssapi/ subdir
|
||||
AC_CHECK_HEADER(gssapi/gssapi.h,
|
||||
[
|
||||
dnl found
|
||||
AC_DEFINE(HAVE_GSSMIT, 1, [if you have the MIT gssapi libraries])
|
||||
],
|
||||
[
|
||||
dnl no header found, disabling GSS
|
||||
want_gss=no
|
||||
AC_MSG_WARN(disabling GSSAPI since no header files was found)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
if test x"$want_gss" = xyes; then
|
||||
AC_DEFINE(HAVE_GSSAPI, 1, [if you have the gssapi libraries])
|
||||
|
||||
curl_gss_msg="enabled (MIT/Heimdal)"
|
||||
|
||||
if test -n "$gnu_gss"; then
|
||||
curl_gss_msg="enabled (GNU GSS)"
|
||||
LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR -lgss"
|
||||
elif test -z "$GSSAPI_LIB_DIR"; then
|
||||
if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
|
||||
gss_ldflags=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi`
|
||||
LDFLAGS="$LDFLAGS $gss_ldflags"
|
||||
@@ -707,31 +765,10 @@ if test x"$want_gss" = xyes; then
|
||||
LDFLAGS="$LDFLAGS -lgssapi"
|
||||
fi
|
||||
else
|
||||
LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR"
|
||||
LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR -lgssapi"
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GSSAPI, 1, [if you have the gssapi libraries])
|
||||
|
||||
curl_gss_msg="enabled"
|
||||
|
||||
AC_CHECK_HEADER(gssapi.h,
|
||||
[
|
||||
dnl found in the given dirs
|
||||
AC_DEFINE(HAVE_GSSHEIMDAL, 1, [if you have the Heimdal gssapi libraries])
|
||||
],
|
||||
[
|
||||
dnl not found, check in gssapi/ subdir
|
||||
AC_CHECK_HEADER(gssapi/gssapi.h,
|
||||
dnl found
|
||||
AC_DEFINE(HAVE_GSSMIT, 1, [if you have the MIT gssapi libraries])
|
||||
)
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
fi
|
||||
|
||||
dnl **********************************************************************
|
||||
@@ -747,11 +784,7 @@ AC_HELP_STRING([--with-ssl=PATH],[where to look for SSL, PATH points to the SSL
|
||||
AC_HELP_STRING([--without-ssl], [disable SSL]),
|
||||
OPT_SSL=$withval)
|
||||
|
||||
if test X"$OPT_SSL" = Xno
|
||||
then
|
||||
AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more])
|
||||
else
|
||||
|
||||
if test X"$OPT_SSL" != Xno; then
|
||||
dnl backup the pre-ssl variables
|
||||
CLEANLDFLAGS="$LDFLAGS"
|
||||
CLEANCPPFLAGS="$CPPFLAGS"
|
||||
@@ -764,20 +797,24 @@ else
|
||||
dnl only do pkg-config magic when not cross-compiling
|
||||
PKGTEST="yes"
|
||||
fi
|
||||
EXTRA_SSL=/usr/local/ssl ;;
|
||||
PREFIX_OPENSSL=/usr/local/ssl
|
||||
LIB_OPENSSL="$PREFIX_OPENSSL/lib$libsuff"
|
||||
;;
|
||||
off)
|
||||
dnl no --with-ssl option given, just check default places
|
||||
if test x$cross_compiling != xyes; then
|
||||
dnl only do pkg-config magic when not cross-compiling
|
||||
PKGTEST="yes"
|
||||
fi
|
||||
EXTRA_SSL= ;;
|
||||
PREFIX_OPENSSL=
|
||||
;;
|
||||
*)
|
||||
dnl check the given --with-ssl spot
|
||||
PKGTEST="no"
|
||||
EXTRA_SSL=$OPT_SSL
|
||||
LDFLAGS="$LDFLAGS -L$EXTRA_SSL/lib$libsuff"
|
||||
CPPFLAGS="$CPPFLAGS -I$EXTRA_SSL/include/openssl -I$EXTRA_SSL/include"
|
||||
PREFIX_OPENSSL=$OPT_SSL
|
||||
LIB_OPENSSL="$PREFIX_OPENSSL/lib$libsuff"
|
||||
LDFLAGS="$LDFLAGS -L$LIB_OPENSSL"
|
||||
CPPFLAGS="$CPPFLAGS -I$PREFIX_OPENSSL/include/openssl -I$PREFIX_OPENSSL/include"
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -799,6 +836,8 @@ else
|
||||
SSL_LDFLAGS=`$PKGCONFIG --libs-only-L openssl 2>/dev/null`
|
||||
SSL_CPPFLAGS=`$PKGCONFIG --cflags-only-I openssl 2>/dev/null`
|
||||
|
||||
LIB_OPENSSL=`echo $SSL_LDFLAGS | sed -e 's/-L//g'`
|
||||
|
||||
dnl use the values pkg-config reported
|
||||
LIBS="$LIBS $SSL_LIBS"
|
||||
CPPFLAGS="$CPPFLAGS $SSL_CPPFLAGS"
|
||||
@@ -828,8 +867,8 @@ else
|
||||
HAVECRYPTO="yes"
|
||||
LIBS="-lcrypto $LIBS"
|
||||
],[
|
||||
LDFLAGS="$CLEANLDFLAGS -L$EXTRA_SSL/lib$libsuff"
|
||||
CPPFLAGS="$CLEANCPPFLAGS -I$EXTRA_SSL/include/openssl -I$EXTRA_SSL/include"
|
||||
LDFLAGS="$CLEANLDFLAGS -L$LIB_OPENSSL"
|
||||
CPPFLAGS="$CLEANCPPFLAGS -I$PREFIX_OPENSSL/include/openssl -I$PREFIX_OPENSSL/include"
|
||||
AC_CHECK_LIB(crypto, CRYPTO_add_lock,[
|
||||
HAVECRYPTO="yes"
|
||||
LIBS="-lcrypto $LIBS"], [
|
||||
@@ -840,10 +879,7 @@ else
|
||||
])
|
||||
|
||||
|
||||
if test X"$HAVECRYPTO" != X"yes"; then
|
||||
AC_MSG_WARN([crypto lib was not found; SSL will be disabled])
|
||||
|
||||
else
|
||||
if test X"$HAVECRYPTO" = X"yes"; then
|
||||
dnl This is only reasonable to do if crypto actually is there: check for
|
||||
dnl SSL libs NOTE: it is important to do this AFTER the crypto lib
|
||||
|
||||
@@ -868,13 +904,13 @@ else
|
||||
dnl Have the libraries--check for SSLeay/OpenSSL 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"
|
||||
curl_ssl_msg="enabled (OpenSSL)"
|
||||
OPENSSL_ENABLED=1
|
||||
AC_DEFINE(USE_OPENSSL, 1, [if OpenSSL is in use]))
|
||||
|
||||
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"
|
||||
curl_ssl_msg="enabled (OpenSSL)"
|
||||
OPENSSL_ENABLED=1)
|
||||
fi
|
||||
fi
|
||||
@@ -898,11 +934,6 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for the CA bundle
|
||||
dnl **********************************************************************
|
||||
|
||||
if test X"$OPENSSL_ENABLED" = X"1"; then
|
||||
dnl If the ENGINE library seems to be around, check for the OpenSSL engine
|
||||
dnl stuff, it is kind of "separated" from the main SSL check
|
||||
@@ -912,30 +943,6 @@ dnl **********************************************************************
|
||||
AC_CHECK_FUNCS( ENGINE_load_builtin_engines )
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([CA cert bundle install path])
|
||||
|
||||
AC_ARG_WITH(ca-bundle,
|
||||
AC_HELP_STRING([--with-ca-bundle=FILE], [File name to install the CA bundle as])
|
||||
AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
|
||||
[ ca="$withval" ],
|
||||
[
|
||||
if test "x$prefix" != xNONE; then
|
||||
ca="\${prefix}/share/curl/curl-ca-bundle.crt"
|
||||
else
|
||||
ca="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
|
||||
fi
|
||||
] )
|
||||
|
||||
if test X"$OPT_SSL" = Xno; then
|
||||
ca="no"
|
||||
fi
|
||||
|
||||
if test "x$ca" != "xno"; then
|
||||
CURL_CA_BUNDLE='"'$ca'"'
|
||||
AC_SUBST(CURL_CA_BUNDLE)
|
||||
fi
|
||||
AC_MSG_RESULT([$ca])
|
||||
|
||||
dnl these can only exist if openssl exists
|
||||
|
||||
AC_CHECK_FUNCS( RAND_status \
|
||||
@@ -946,17 +953,19 @@ AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
|
||||
fi
|
||||
|
||||
if test "$OPENSSL_ENABLED" = "1"; then
|
||||
dnl when the ssl shared libs were found in a path that the run-time linker
|
||||
dnl doesn't search through, we need to add it to LD_LIBRARY_PATH to
|
||||
dnl prevent further configure tests to fail due to this
|
||||
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$EXTRA_SSL/lib$libsuff"
|
||||
export LD_LIBRARY_PATH
|
||||
if test -n "$LIB_OPENSSL"; then
|
||||
dnl when the ssl shared libs were found in a path that the run-time
|
||||
dnl linker doesn't search through, we need to add it to LD_LIBRARY_PATH
|
||||
dnl to prevent further configure tests to fail due to this
|
||||
|
||||
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$LIB_OPENSSL"
|
||||
export LD_LIBRARY_PATH
|
||||
AC_MSG_NOTICE([Added $LIB_OPENSSL to LD_LIBRARY_PATH])
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(CABUNDLE, test x$ca != xno)
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for the random seed preferences
|
||||
dnl **********************************************************************
|
||||
@@ -989,6 +998,116 @@ if test X"$OPENSSL_ENABLED" = X"1"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl ----------------------------------------------------
|
||||
dnl FIX: only check for GnuTLS if OpenSSL is not enabled
|
||||
dnl ----------------------------------------------------
|
||||
|
||||
dnl Default to compiler & linker defaults for GnuTLS files & libraries.
|
||||
OPT_GNUTLS=no
|
||||
|
||||
AC_ARG_WITH(gnutls,dnl
|
||||
AC_HELP_STRING([--with-gnutls=PATH],[where to look for GnuTLS, PATH points to the installation root (default: /usr/local/)])
|
||||
AC_HELP_STRING([--without-gnutls], [disable GnuTLS detection]),
|
||||
OPT_GNUTLS=$withval)
|
||||
|
||||
if test "$OPENSSL_ENABLED" != "1"; then
|
||||
|
||||
if test X"$OPT_GNUTLS" != Xno; then
|
||||
if test "x$OPT_GNUTLS" = "xyes"; then
|
||||
check=`libgnutls-config --version 2>/dev/null`
|
||||
if test -n "$check"; then
|
||||
addlib=`libgnutls-config --libs`
|
||||
addcflags=`libgnutls-config --cflags`
|
||||
version=`libgnutls-config --version`
|
||||
gtlsprefix=`libgnutls-config --prefix`
|
||||
fi
|
||||
else
|
||||
addlib=`$OPT_GNUTLS/bin/libgnutls-config --libs`
|
||||
addcflags=`$OPT_GNUTLS/bin/libgnutls-config --cflags`
|
||||
version=`$OPT_GNUTLS/bin/libgnutls-config --version 2>/dev/null`
|
||||
gtlsprefix=$OPT_GNUTLS
|
||||
if test -z "$version"; then
|
||||
version="unknown"
|
||||
fi
|
||||
fi
|
||||
if test -n "$addlib"; then
|
||||
|
||||
CLEANLDFLAGS="$LDFLAGS"
|
||||
CLEANCPPFLAGS="$CPPFLAGS"
|
||||
|
||||
LDFLAGS="$LDFLAGS $addlib"
|
||||
if test "$addcflags" != "-I/usr/include"; then
|
||||
CPPFLAGS="$CPPFLAGS $addcflags"
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB(gnutls, gnutls_check_version,
|
||||
[
|
||||
AC_DEFINE(USE_GNUTLS, 1, [if GnuTLS is enabled])
|
||||
AC_SUBST(USE_GNUTLS, [1])
|
||||
USE_GNUTLS="yes"
|
||||
curl_ssl_msg="enabled (GnuTLS)"
|
||||
],
|
||||
[
|
||||
LDFLAGS="$CLEANLDFLAGS"
|
||||
CPPFLAGS="$CLEANCPPFLAGS"
|
||||
])
|
||||
|
||||
if test "x$USE_GNUTLS" = "xyes"; then
|
||||
AC_MSG_NOTICE([detected GnuTLS version $version])
|
||||
|
||||
dnl when shared libs were found in a path that the run-time
|
||||
dnl linker doesn't search through, we need to add it to
|
||||
dnl LD_LIBRARY_PATH to prevent further configure tests to fail
|
||||
dnl due to this
|
||||
|
||||
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$gtlsprefix/lib$libsuff"
|
||||
export LD_LIBRARY_PATH
|
||||
AC_MSG_NOTICE([Added $gtlsprefix/lib$libsuff to LD_LIBRARY_PATH])
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
fi dnl GNUTLS not disabled
|
||||
|
||||
if test X"$USE_GNUTLS" != "Xyes"; then
|
||||
AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more.])
|
||||
AC_MSG_WARN([Use --with-ssl or --with-gnutls to address this.])
|
||||
fi
|
||||
|
||||
fi dnl OPENSSL != 1
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for the CA bundle
|
||||
dnl **********************************************************************
|
||||
|
||||
if test X"$USE_GNUTLS$OPENSSL_ENABLED" != "X"; then
|
||||
|
||||
AC_MSG_CHECKING([CA cert bundle install path])
|
||||
|
||||
AC_ARG_WITH(ca-bundle,
|
||||
AC_HELP_STRING([--with-ca-bundle=FILE], [File name to install the CA bundle as])
|
||||
AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
|
||||
[ ca="$withval" ],
|
||||
[
|
||||
if test "x$prefix" != xNONE; then
|
||||
ca="\${prefix}/share/curl/curl-ca-bundle.crt"
|
||||
else
|
||||
ca="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
|
||||
fi
|
||||
] )
|
||||
|
||||
if test "x$ca" != "xno"; then
|
||||
CURL_CA_BUNDLE='"'$ca'"'
|
||||
AC_SUBST(CURL_CA_BUNDLE)
|
||||
fi
|
||||
AC_MSG_RESULT([$ca])
|
||||
fi dnl only done if some kind of SSL was enabled
|
||||
|
||||
AM_CONDITIONAL(CABUNDLE, test x$ca != xno)
|
||||
|
||||
|
||||
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for the presence of ZLIB libraries and headers
|
||||
dnl **********************************************************************
|
||||
@@ -1089,7 +1208,6 @@ case "$LIBIDN" in
|
||||
dnl if there is a given path, check that FIRST
|
||||
if test -n "$LIBIDN"; then
|
||||
if test "x$LIBIDN" != "xyes"; then
|
||||
AC_MSG_WARN([moo moo $LIBIDN])
|
||||
oldLDFLAGS=$LDFLAGS
|
||||
oldCPPFLAGS=$CPPFLAGS
|
||||
LDFLAGS="$LDFLAGS -L$LIBIDN/lib"
|
||||
@@ -1175,7 +1293,7 @@ else
|
||||
dnl is there a strerror_r()
|
||||
CURL_CHECK_STRERROR_R()
|
||||
|
||||
AC_CHECK_FUNCS( gmtime_r )
|
||||
checkfor_gmtime_r="yes"
|
||||
fi
|
||||
|
||||
dnl for recent AIX versions, we skip all the thread-safe checks above since
|
||||
@@ -1211,7 +1329,47 @@ if test "x$RECENTAIX" = "xyes"; then
|
||||
dnl is there a strerror_r()
|
||||
CURL_CHECK_STRERROR_R()
|
||||
|
||||
AC_CHECK_FUNCS( gmtime_r )
|
||||
checkfor_gmtime_r="yes"
|
||||
fi
|
||||
|
||||
if test x$cross_compiling != xyes; then
|
||||
|
||||
if test x$checkfor_gmtime_r = xyes; then
|
||||
|
||||
dnl if gmtime_r was found, verify that it actuall works, as (at least) HPUX
|
||||
dnl 10.20 is known to have a buggy one. If it doesn't work, disable use of
|
||||
dnl it.
|
||||
|
||||
AC_MSG_CHECKING([if gmtime_r exists and works])
|
||||
AC_RUN_IFELSE([[
|
||||
#include <time.h>
|
||||
int main(void)
|
||||
{
|
||||
time_t local = 1170352587;
|
||||
struct tm *gmt;
|
||||
struct tm keeper;
|
||||
putenv("TZ=CST6CDT");
|
||||
tzset();
|
||||
gmt = gmtime_r(&local, &keeper);
|
||||
if(gmt) {
|
||||
return 0;
|
||||
}
|
||||
return 1; /* failure */
|
||||
}
|
||||
]],
|
||||
dnl success, do nothing
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GMTIME_R, 1, [if you have (a working) gmtime_r])
|
||||
,
|
||||
dnl failure, now disable the function
|
||||
AC_MSG_RESULT(no)
|
||||
,
|
||||
dnl not invoked when crosscompiling)
|
||||
])
|
||||
fi
|
||||
else
|
||||
dnl and for crosscompilings
|
||||
AC_CHECK_FUNCS(gmtime_r)
|
||||
fi
|
||||
|
||||
|
||||
@@ -1321,6 +1479,8 @@ AC_CHECK_TYPE(ssize_t, ,
|
||||
TYPE_SOCKLEN_T
|
||||
TYPE_IN_ADDR_T
|
||||
|
||||
TYPE_SOCKADDR_STORAGE
|
||||
|
||||
AC_FUNC_SELECT_ARGTYPES
|
||||
|
||||
dnl Checks for library functions.
|
||||
@@ -1414,11 +1574,24 @@ AC_CHECK_DECL(basename, ,
|
||||
#endif
|
||||
)
|
||||
|
||||
dnl poll() might be badly emulated, as in Mac OS X 10.3 (and other BSDs?) and
|
||||
dnl to find out we make an extra check here!
|
||||
if test "$ac_cv_func_poll" = "yes"; then
|
||||
AC_MSG_CHECKING([if poll works with NULL inputs])
|
||||
AC_RUN_IFELSE([
|
||||
AC_MSG_CHECKING([if we are Mac OS X (to disable poll)])
|
||||
disable_poll=no
|
||||
case $host in
|
||||
*-*-darwin*)
|
||||
disable_poll="yes";
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT($disable_poll)
|
||||
|
||||
if test "$disable_poll" = "no"; then
|
||||
|
||||
dnl poll() might be badly emulated, as in Mac OS X 10.3 (and other BSDs?) and
|
||||
dnl to find out we make an extra check here!
|
||||
if test "$ac_cv_func_poll" = "yes"; then
|
||||
AC_MSG_CHECKING([if poll works with NULL inputs])
|
||||
AC_RUN_IFELSE([
|
||||
#ifdef HAVE_SYS_POLL_H
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
@@ -1429,14 +1602,14 @@ if test "$ac_cv_func_poll" = "yes"; then
|
||||
return poll((void *)0, 0, 10 /*ms*/);
|
||||
}
|
||||
],
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_POLL_FINE, 1, [If you have a fine poll]),
|
||||
AC_MSG_RESULT(no),
|
||||
AC_MSG_RESULT(cross-compiling assumes yes)
|
||||
AC_DEFINE(HAVE_POLL_FINE, 1, [If you have a fine poll])
|
||||
) dnl end of AC_RUN_IFELSE
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_POLL_FINE, 1, [If you have a fine poll]),
|
||||
AC_MSG_RESULT(no),
|
||||
AC_MSG_RESULT(cross-compiling assumes yes)
|
||||
AC_DEFINE(HAVE_POLL_FINE, 1, [If you have a fine poll])
|
||||
) dnl end of AC_RUN_IFELSE
|
||||
fi dnl poll() was found
|
||||
fi dnl poll()-check is not disabled
|
||||
|
||||
|
||||
AC_PATH_PROG( PERL, perl, ,
|
||||
@@ -1509,7 +1682,7 @@ AC_HELP_STRING([--disable-ares],[Disable ares for name lookups]),
|
||||
AC_SUBST(HAVE_ARES)
|
||||
curl_ares_msg="enabled"
|
||||
|
||||
LIBS="$LIBS -lcares"
|
||||
LIBS="-lcares $LIBS"
|
||||
|
||||
dnl For backwards compatibility default to includes/lib in srcdir/ares
|
||||
dnl If a value is specified it is assumed that the libs are in $val/lib
|
||||
@@ -1727,4 +1900,5 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
|
||||
Built-in manual: ${curl_manual_msg}
|
||||
Verbose errors: ${curl_verbose_msg}
|
||||
SSPI support: ${curl_sspi_msg}
|
||||
ca cert path: ${ca}
|
||||
])
|
||||
|
@@ -60,7 +60,9 @@ while test $# -gt 0; do
|
||||
--feature|--features)
|
||||
if test "@USE_SSLEAY@" = "1"; then
|
||||
echo "SSL"
|
||||
NTLM=1
|
||||
NTLM=1 # OpenSSL implies NTLM
|
||||
elif test -n "@USE_GNUTLS@"; then
|
||||
echo "SSL"
|
||||
fi
|
||||
if test "@KRB4_ENABLED@" = "1"; then
|
||||
echo "KRB4"
|
||||
|
@@ -82,8 +82,8 @@ Lisp
|
||||
|
||||
Lua
|
||||
|
||||
Written by Steve Dekorte
|
||||
http://curl.haxx.se/libcurl/lua/
|
||||
LuaCURL Written by Alexander Marinov
|
||||
http://luacurl.luaforge.net/
|
||||
|
||||
Mono
|
||||
|
||||
|
186
docs/DISTRO-DILEMMA
Normal file
186
docs/DISTRO-DILEMMA
Normal file
@@ -0,0 +1,186 @@
|
||||
Date: September 1, 2005
|
||||
Author: Daniel Stenberg <daniel@haxx.se>
|
||||
URL: http://curl.haxx.se/legal/distro-dilemma.html
|
||||
|
||||
Condition
|
||||
|
||||
This document is written to describe the sitution as it is right now. libcurl
|
||||
7.14.0 is currently the latest version available. Things may (or perhaps
|
||||
will) of course change in the future.
|
||||
|
||||
This document reflects my view and understanding of these things. Please tell
|
||||
me where and how you think I'm wrong, and I'll try to correct my mistakes.
|
||||
|
||||
Background
|
||||
|
||||
The Free Software Foundation has deemed the Original BSD license[1] to be
|
||||
"incompatible"[2] with GPL[3]. I'd rather say it is the other way around, but
|
||||
the point is the same: if you distribute a binary version of a GPL program,
|
||||
it MUST NOT be linked with any Original BSD-licenced parts or
|
||||
libraries. Doing so will violate the GPL license. For a long time, very many
|
||||
GPL licensed programs have avoided this license mess by adding an
|
||||
exception[8] to their license. And many others have just closed their eyes
|
||||
for this problem.
|
||||
|
||||
libcurl is MIT-style[4] licensed - how on earth did this dilemma fall onto
|
||||
our plates?
|
||||
|
||||
libcurl is only a little library. libcurl can be built to use OpenSSL for its
|
||||
SSL/TLS capabilities. OpenSSL is basically Original BSD licensed[5].
|
||||
|
||||
If libcurl built to use OpenSSL is used by a GPL-licensed application and you
|
||||
decide to distribute a binary version of it (Linux distros - for example -
|
||||
tend to), you have a clash. GPL vs Original BSD.
|
||||
|
||||
This dilemma is not libcurl-specific nor is it specific to any particular
|
||||
Linux distro.
|
||||
|
||||
Part of the Operating System
|
||||
|
||||
This would not be a problem if the used lib would be considered part of the
|
||||
uderlying operating system, as then the GPL license has an exception
|
||||
clause[6] that allows applications to use such libs without having to be
|
||||
allowed to distribute it or its sources. Possibly some distros will claim
|
||||
that OpenSSL is part of their operating system.
|
||||
|
||||
Debian does however not take this stance and has officially(?) claimed that
|
||||
OpenSSL is not a required part of the Debian operating system
|
||||
|
||||
Debian-legal
|
||||
|
||||
In August 2004 I figured I should start pulling people's attention to this to
|
||||
see if anyone has any bright ideas or if they would dismiss my worries based
|
||||
on some elegant writing I had missed somewhere:
|
||||
|
||||
My post to debian-legal on August 12 2004:
|
||||
|
||||
http://lists.debian.org/debian-legal/2004/08/msg00279.html
|
||||
|
||||
Several people agreed then that this is a known and rather big problem, but
|
||||
the following discussion didn't result in much.
|
||||
|
||||
GnuTLS
|
||||
|
||||
With the release of libcurl 7.14.0 (May 2005), it can now get built to use
|
||||
GnuTLS instead of OpenSSL. GnuTLS is a LGPL[7] licensed library that offers a
|
||||
matching set of features as OpenSSL does. Now, you can build and distribute
|
||||
an SSL capable libcurl without including any Original BSD licensed code.
|
||||
|
||||
I believe Debian is the first distro to provide libcurl/GnutTLS packages.
|
||||
|
||||
GnuTLS vs OpenSSL
|
||||
|
||||
While these two libraries offer similar features, they are not equal. Both
|
||||
libraries have features the other one lacks. libcurl does not (yet) offer a
|
||||
standardized stable ABI if you decide to switch from using libcurl-openssl to
|
||||
libcurl-gnutls or vice versa. The GnuTLS support is very recent in libcurl
|
||||
and it has not been tested nor used very extensively, while the OpenSSL
|
||||
equivalent code has been used and thus matured for more than seven (7) years.
|
||||
|
||||
In August 2005, the debian-devel mailing list discovered the license issue as
|
||||
a GPL licensed application wanted SSL capabilities from libcurl and thus was
|
||||
forced to use the GnuTLS powered libcurl. For a reason that is unknown to me,
|
||||
the application authors didn't want to or was unable to add an exception to
|
||||
their GPL license. Alas, the license problem hit the fan again.
|
||||
|
||||
The Better License, Original BSD or LGPL?
|
||||
|
||||
It isn't obvious or without debate to any objective interested party that
|
||||
either of these licenses are the "better" or even the "preferred" one in a
|
||||
generic situation.
|
||||
|
||||
Instead, I think we should accept the fact that the SSL/TLS libraries and
|
||||
their different licenses will fit different applications and their authors
|
||||
differently depending on the applications' licenses and their general usage
|
||||
pattern (considering how LGPL libraries can be burdonsome for embedded
|
||||
systems usage).
|
||||
|
||||
More SSL Libraries
|
||||
|
||||
In libcurl, there's no stopping us here. There are at least a few more Open
|
||||
Source/Free SSL/TLS libraries and we would very much like to support them as
|
||||
well, to offer application authors an even wider scope of choice.
|
||||
|
||||
Application Angle of this Problem
|
||||
|
||||
libcurl is built to use one SSL/TLS library. It uses a single fixed name (by
|
||||
default), and applications are built/linked to use that single lib. Replacing
|
||||
one libcurl instance with another one that uses the other SSL/TLS library
|
||||
might break one or more applications (due to ABI differences and/or different
|
||||
feature set). You want your application to use the libcurl it was built for.
|
||||
|
||||
Project cURL Angle of this Problem
|
||||
|
||||
We distribute libcurl and everyone may build libcurl with either library. At
|
||||
their choice. This problem is not directly a problem of ours. It merely
|
||||
affects users - GPL application authors only - of our lib as it comes
|
||||
included and delivered on some distros.
|
||||
|
||||
Distro Angle of this Problem
|
||||
|
||||
A distro can provide separate libcurls built with different SSL/TLS libraries
|
||||
to work around this, but at least Debian seems to be very hostile against
|
||||
such an approach, probably since it makes things like devel packages for the
|
||||
different libs collide since they would provide the same include files and
|
||||
man pages etc.
|
||||
|
||||
Fixing the Only Problem
|
||||
|
||||
The only problem is thus for distributions that want to offer libcurl
|
||||
versions built with more than one SSL/TLS library.
|
||||
|
||||
Since multiple libcurl binaries using different names are ruled out, we need
|
||||
to come up with a way to have one single libcurl that someone uses different
|
||||
underlying libraries. The best(?) approach currently suggested involves this:
|
||||
|
||||
A new intermediate library (named lib2 so far in the discussions) with the
|
||||
single purpose of providing libcurl with SSL/TLS capabilities. It would have
|
||||
a unified API and ABI no matter what underlying library it would use.
|
||||
|
||||
There would be one lib2 binary provided for each supported SSL/TLS library.
|
||||
For example: lib2-openssl, lib2-gnutls, lib2-yassl, lib2-matrixssl and
|
||||
lib2-nossl. Yes, take note of the last one that provides the lib2 ABI but
|
||||
that lacks the actual powers.
|
||||
|
||||
When libcurl is built and linked, it will be linked against a lib2 with the
|
||||
set ABI.
|
||||
|
||||
When you link an app against libcurl, it would also need to provide one of
|
||||
the (many) lib2 libs to decide what approach that fits the app. An app that
|
||||
doesn't want SSL at all would still need to link with the lib2-nossl lib.
|
||||
|
||||
GPL apps can pick the lib2-gnutls, others may pick the lib2-openssl.
|
||||
|
||||
This concept works equally well both for shared and static libraries.
|
||||
|
||||
A positive side effect of this approach could be a more generic "de facto"
|
||||
standard API for SSL/TLS libraries.
|
||||
|
||||
When Will This Happen
|
||||
|
||||
Note again that this is not a problem in curl, it doesn't solve any actual
|
||||
technical problems in our project. Don't hold your breath for this to happen
|
||||
very soon (if at all) unless you step forward and contribute.
|
||||
|
||||
The suggestion that is outlined above is still only a suggestion. Feel free
|
||||
to bring a better idea!
|
||||
|
||||
Also, to keep in mind: I don't want this new concept to have too much of an
|
||||
impact on the existing code. Preferably it should be possible to build the
|
||||
code like today (without the use of lib2), should you decide to ignore the
|
||||
problems outlined in this document.
|
||||
|
||||
Footnotes
|
||||
|
||||
[1] = http://www.xfree86.org/3.3.6/COPYRIGHT2.html#6
|
||||
[2] = http://www.fsf.org/licensing/essays/bsd.html
|
||||
[3] = http://www.fsf.org/licensing/licenses/gpl.html
|
||||
[4] = http://curl.haxx.se/docs/copyright.html
|
||||
[5] = http://www.openssl.org/source/license.html
|
||||
[6] = http://www.fsf.org/licensing/licenses/gpl.html end of section 3
|
||||
[7] = http://www.fsf.org/licensing/licenses/lgpl.html
|
||||
[8] = http://en.wikipedia.org/wiki/OpenSSL_exception
|
||||
|
||||
Feedback/Updates provided by
|
||||
|
||||
Eric Cooper
|
127
docs/FAQ
127
docs/FAQ
@@ -1,4 +1,4 @@
|
||||
Updated: December 21, 2004 (http://curl.haxx.se/docs/faq.html)
|
||||
Updated: August 26, 2005 (http://curl.haxx.se/docs/faq.html)
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
@@ -43,6 +43,7 @@ FAQ
|
||||
3.15 Can I do recursive fetches with curl?
|
||||
3.16 What certificates do I need when I use SSL?
|
||||
3.17 How do I list the root dir of an FTP server?
|
||||
3.18 Can I use curl to send a POST/PUT and not wait for a response?
|
||||
|
||||
4. Running Problems
|
||||
4.1 Problems connecting to SSL servers.
|
||||
@@ -63,6 +64,8 @@ FAQ
|
||||
4.10 My HTTP request using HEAD, PUT or DELETE doesn't work!
|
||||
4.11 Why does my HTTP range requests return the full document?
|
||||
4.12 Why do I get "certificate verify failed" ?
|
||||
4.13 Why is curl -R on Windows one hour off?
|
||||
4.14 Redirects work in browser but not with curl!
|
||||
|
||||
5. libcurl Issues
|
||||
5.1 Is libcurl thread-safe?
|
||||
@@ -74,6 +77,9 @@ FAQ
|
||||
5.7 Link errors when building libcurl on Windows!
|
||||
5.8 libcurl.so.3: open failed: No such file or directory
|
||||
5.9 How does libcurl resolve host names?
|
||||
5.10 How do I prevent libcurl from writing the response to stdout?
|
||||
5.11 How do I make libcurl not receive the whole HTTP response?
|
||||
5.12 Can I make libcurl fake or hide my real IP address?
|
||||
|
||||
6. License Issues
|
||||
6.1 I have a GPL program, can I use the libcurl library?
|
||||
@@ -97,7 +103,7 @@ FAQ
|
||||
cURL is the name of the project. The name is a play on 'Client for URLs',
|
||||
originally with URL spelled in uppercase to make it obvious it deals with
|
||||
URLs. The fact it can also be pronounced 'see URL' also helped, it works as
|
||||
an abbrivation for "Client URL Request Library" or why not the recursive
|
||||
an abbreviation for "Client URL Request Library" or why not the recursive
|
||||
version: "Curl URL Request Library".
|
||||
|
||||
The cURL project produces two products:
|
||||
@@ -128,11 +134,11 @@ FAQ
|
||||
|
||||
We pronounce curl and cURL with an initial k sound: [kurl].
|
||||
|
||||
NOTE: there are numerous sub-projects and related projects that also use the
|
||||
word curl in the project names in various combinations, but you should take
|
||||
There are numerous sub-projects and related projects that also use the word
|
||||
curl in the project names in various combinations, but you should take
|
||||
notice that this FAQ is directed at the command-line tool named curl (and
|
||||
libcurl the library), and may therefore not be valid for other curl-related
|
||||
projects.
|
||||
projects. (There is however a small section for the PHP/CURL in this FAQ.)
|
||||
|
||||
1.2 What is libcurl?
|
||||
|
||||
@@ -193,15 +199,14 @@ FAQ
|
||||
|
||||
1.5 Who makes curl?
|
||||
|
||||
curl and libcurl are not made by any single individual. Sure, Daniel
|
||||
Stenberg writes the major parts, but other persons' submissions are
|
||||
curl and libcurl are not made by any single individual. Daniel Stenberg is
|
||||
project leader and main developer, but other persons' submissions are
|
||||
important and crucial. Anyone can contribute and post their changes and
|
||||
improvements and have them inserted in the main sources (of course on the
|
||||
condition that developers agree on that the fixes are good).
|
||||
|
||||
The list of contributors in the docs/THANKS file is only a small part of all
|
||||
the people that every day provide us with bug reports, suggestions, ideas
|
||||
and source code.
|
||||
The full list of the more than 400 contributors is found in the docs/THANKS
|
||||
file.
|
||||
|
||||
curl is developed by a community, with Daniel at the wheel.
|
||||
|
||||
@@ -216,12 +221,8 @@ FAQ
|
||||
have sponsored certain parts of the development in the past and I hope some
|
||||
will continue to do so in the future.
|
||||
|
||||
If you want to support our project with a donation or similar, one way of
|
||||
doing that would be to buy "gift certificates" at useful online shopping
|
||||
sites, such as amazon.com or thinkgeek.com. Another way would be to sponsor
|
||||
us through a banner-program or even better: by helping us coding,
|
||||
documenting, testing etc. You're welcome to send us a buck using paypal, as
|
||||
described here: http://curl.haxx.se/donation.html
|
||||
If you want to support our project, consider a donation or a banner-program
|
||||
or even better: by helping us coding, documenting, testing etc.
|
||||
|
||||
1.7 What about CURL from curl.com?
|
||||
|
||||
@@ -252,6 +253,12 @@ FAQ
|
||||
users thanks to the web based archives of the mailing lists), thus saving us
|
||||
from having to repeat ourselves even more. Thanks for respecting this.
|
||||
|
||||
If you have found or simply suspect a security problem in curl or libcurl,
|
||||
mail curl-security at haxx.se (closed list of receivers, mails are not
|
||||
disclosed) and tell. Then we can produce a fix in a timely manner before the
|
||||
flaw is announced to the world, thus lessen the impact the problem will have
|
||||
on existing users.
|
||||
|
||||
|
||||
2. Install Related Problems
|
||||
|
||||
@@ -296,8 +303,8 @@ FAQ
|
||||
|
||||
2.2 Does curl work/build with other SSL libraries?
|
||||
|
||||
Curl has been written to use OpenSSL, although there should not be much
|
||||
problems using a different library. If anyone does "port" curl to use a
|
||||
Curl has been written to use OpenSSL or GnuTLS, although there should not be
|
||||
many problems using a different library. If anyone does "port" curl to use a
|
||||
different SSL library, we are of course very interested in getting the
|
||||
patch!
|
||||
|
||||
@@ -392,6 +399,8 @@ FAQ
|
||||
|
||||
curl -L http://redirector.com
|
||||
|
||||
Not all redirects are HTTP ones, see 4.14
|
||||
|
||||
3.9 How do I use curl in my favorite programming language?
|
||||
|
||||
There exist many language interfaces/bindings for curl that integrates it
|
||||
@@ -503,9 +512,9 @@ FAQ
|
||||
If the server doesn't require this, you don't need a client certificate.
|
||||
|
||||
- Server certificate. The server you communicate with has a server
|
||||
certificate. You can and should verify this certficate to make sure that
|
||||
certificate. You can and should verify this certificate to make sure that
|
||||
you are truly talking to the real server and not a server impersonating
|
||||
it. The server certificate verifaction process is made by using a
|
||||
it. The server certificate verification process is made by using a
|
||||
Certificate Authority certificate ("CA cert") that was used to sign the
|
||||
server certificate. Server certificate verification is enabled by default
|
||||
in curl and libcurl and is often the reason for problems as explained in
|
||||
@@ -533,6 +542,10 @@ FAQ
|
||||
|
||||
curl ftp://ftp.sunet.se//tmp/
|
||||
|
||||
3.18 Can I use curl to send a POST/PUT and not wait for a response?
|
||||
|
||||
No.
|
||||
|
||||
|
||||
4. Running Problems
|
||||
|
||||
@@ -726,6 +739,28 @@ FAQ
|
||||
Details are also in the SSLCERTS file in the release archives, found online
|
||||
here: http://curl.haxx.se/docs/sslcerts.html
|
||||
|
||||
4.13 Why is curl -R on Windows one hour off?
|
||||
|
||||
During daylight savings time, when -R is used, curl will set a time that
|
||||
appears one hour off. This happens due to a flaw in how Windows stores and
|
||||
uses file modification times and it is not easily worked around. For details
|
||||
on this problem, read this: http://www.codeproject.com/datetime/dstbugs.asp
|
||||
|
||||
4.14 Redirects work in browser but not with curl!
|
||||
|
||||
curl supports HTTP redirects fine (see item 3.8). Browsers generally support
|
||||
at least two other ways to perform directs that curl does not:
|
||||
|
||||
1 - Meta tags. You can write a HTML tag that will cause the browser to
|
||||
redirect to another given URL after a certain time.
|
||||
|
||||
2 - Javascript. You can write a javascript program embeded in a HTML page
|
||||
that redirects the browser to another given URL.
|
||||
|
||||
There is no way to make curl follow these redirects. You must either
|
||||
manually figure out what the page is set to do, or you write a script that
|
||||
parses the results and fetches the new URL.
|
||||
|
||||
|
||||
5. libcurl Issues
|
||||
|
||||
@@ -733,12 +768,20 @@ FAQ
|
||||
|
||||
Yes.
|
||||
|
||||
We have written the libcurl code specificly adjusted for multi-threaded
|
||||
We have written the libcurl code specifically adjusted for multi-threaded
|
||||
programs. libcurl will use thread-safe functions instead of non-safe ones if
|
||||
your system has such.
|
||||
|
||||
We would appreciate some kind of report or README file from those who have
|
||||
used libcurl in a threaded environment.
|
||||
If you use a OpenSSL-powered libcurl in a multi-threaded environment, you
|
||||
need to provide one or two locking functions:
|
||||
|
||||
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
|
||||
|
||||
If you use a GnuTLS-powered libcurl in a multi-threaded environment, you
|
||||
need to provide locking function(s) for libgcrypt (which is used by GnuTLS
|
||||
for the crypto functions).
|
||||
|
||||
http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html
|
||||
|
||||
5.2 How can I receive all data into a large memory chunk?
|
||||
|
||||
@@ -877,6 +920,35 @@ FAQ
|
||||
A - gethostbyname() on plain ipv4 windows hosts
|
||||
B - getaddrinfo() on ipv6-enabled windows hosts
|
||||
|
||||
Also note that libcurl never resolves or reverse-lookups addresses given as
|
||||
pure numbers, such as 127.0.0.1 or ::1.
|
||||
|
||||
5.10 How do I prevent libcurl from writing the response to stdout?
|
||||
|
||||
libcurl provides a default built-in write function that writes received data
|
||||
to stdout. Set a WRITEFUNCTION to receive the data, or possibly set
|
||||
WRITEDATA to a different FILE * handle.
|
||||
|
||||
5.11 How do I make libcurl not receive the whole HTTP response?
|
||||
|
||||
You make the write callback (or progress callback) return an error and
|
||||
libcurl will then abort the transfer.
|
||||
|
||||
5.12 Can I make libcurl fake or hide my real IP address?
|
||||
|
||||
No. libcurl operates on a higher level than so. Besides, faking IP address
|
||||
would imply sending IP packages with a made-up source address, and then you
|
||||
normally get a problem with intercepting the packages sent back as they
|
||||
would then not be routed to you!
|
||||
|
||||
If you use a proxy to access remote sites, the sites will not see your local
|
||||
IP address but instead the address of the proxy.
|
||||
|
||||
Also note that on many networks NATs or other IP-munging techniques are used
|
||||
that makes you see and use a different IP address locally than what the
|
||||
remote server will see you coming from.
|
||||
|
||||
|
||||
6. License Issues
|
||||
|
||||
Curl and libcurl are released under a MIT/X derivate license. The license is
|
||||
@@ -933,8 +1005,13 @@ FAQ
|
||||
7.1 What is PHP/CURL?
|
||||
|
||||
The module for PHP that makes it possible for PHP programs to access curl-
|
||||
functions from within PHP. We often call it PHP/CURL to differentiate from
|
||||
curl the command line tool and libcurl the library.
|
||||
functions from within PHP.
|
||||
|
||||
In the cURL project we call this module PHP/CURL to differentiate it from
|
||||
curl the command line tool and libcurl the library. The PHP team however
|
||||
does not refer to it like this (for unknown reasons). They call it plain
|
||||
CURL (often using all caps) which causes much confusion to users which in
|
||||
turn gives us a higher question load.
|
||||
|
||||
7.2 Who write PHP/CURL?
|
||||
|
||||
|
@@ -62,11 +62,11 @@ HTTP
|
||||
|
||||
HTTPS (*1)
|
||||
- (all the HTTP features)
|
||||
- using certificates
|
||||
- using client certificates
|
||||
- verify server certificate
|
||||
- via http-proxy
|
||||
- select desired encryption
|
||||
- force usage of a specific SSL version (SSLv2, SSLv3 or TLSv1)
|
||||
- force usage of a specific SSL version (SSLv2(*7), SSLv3 or TLSv1)
|
||||
|
||||
FTP
|
||||
- download
|
||||
@@ -118,9 +118,10 @@ FILE
|
||||
FOOTNOTES
|
||||
=========
|
||||
|
||||
*1 = requires OpenSSL
|
||||
*1 = requires OpenSSL or GnuTLS
|
||||
*2 = requires OpenLDAP
|
||||
*3 = requires a GSSAPI-compliant library, such as Heimdal or similar.
|
||||
*4 = requires FBopenssl
|
||||
*5 = requires a krb4 library, such as the MIT one or similar.
|
||||
*6 = requires c-ares
|
||||
*7 = requires OpenSSL specificly, as GnuTLS only supports SSLv3 and TLSv1
|
||||
|
@@ -114,6 +114,8 @@ distributions and otherwise retrieved as part of other software.
|
||||
September 2002, with the release of curl 7.10 it is released under the MIT
|
||||
license only.
|
||||
|
||||
January 2003. Started working on the distributed curl tests. The autobuilds.
|
||||
|
||||
February 2003, the curl site averages at 20000 visits weekly. At any given
|
||||
moment, there's an average of 3 people browsing the curl.haxx.se site.
|
||||
|
||||
@@ -139,3 +141,7 @@ August 2004:
|
||||
Number of public functions in libcurl: 36
|
||||
Amount of public web site mirrors: 12
|
||||
Number of known libcurl bindings: 26
|
||||
|
||||
April 2005:
|
||||
|
||||
GnuTLS can now optionally be used for the secure layer when curl is built.
|
||||
|
32
docs/INSTALL
32
docs/INSTALL
@@ -462,21 +462,19 @@ NetWare
|
||||
- optional zlib sources (at the moment only dynamic linking with zlib.imp);
|
||||
sources with NetWare Makefile can be obtained from:
|
||||
http://www.gknw.com/mirror/zlib/
|
||||
- optional OpenSSL sources (version 0.9.8 or later which builds with BSD);
|
||||
|
||||
Set a search path to your compiler, linker and tools; if you want to have
|
||||
zlib support then set the environment var ZLIB_PATH pointing to your zlib
|
||||
sources, on Linux make sure the var OSTYPE contains the string 'linux';
|
||||
and finally type 'make netware' from the top source directory...
|
||||
I found on some Linux systems (RH9) that OS detection didnlt work although
|
||||
Set a search path to your compiler, linker and tools; on Linux make
|
||||
sure that the var OSTYPE contains the string 'linux'; and then type
|
||||
'make netware' from the top source directory; other tagets available
|
||||
are 'netware-ssl', 'netware-ssl-zlib', 'netware-zlib' and 'netware-ares';
|
||||
if you need other combinations you can control the build with the
|
||||
environment variables WITH_SSL, WITH_ZLIB, WITH_ARES and ENABLE_IPV6.
|
||||
I found on some Linux systems (RH9) that OS detection didnt work although
|
||||
a 'set | grep OSTYPE' shows the var present and set; I simply overwrote it
|
||||
with 'OSTYPE=linux-rh9-gnu' and the detection in the Makefile worked...;
|
||||
other options are currently not supported, although partly prepared.
|
||||
The Ares lib builds arlready fine, and both test tools work fine at least
|
||||
when build with CodeWarrior...; don't know yet why they fail when build with
|
||||
gcc though; if you want to compile with Ares support then set an env var
|
||||
WITH_ARES=1; I've not tested yet including libares into curl.
|
||||
with 'OSTYPE=linux-rh9-gnu' and the detection in the Makefile worked...
|
||||
Any help in testing appreciated!
|
||||
Builds automatically created 4 times a day from current CVS are here:
|
||||
Builds automatically created 8 times a day from current CVS are here:
|
||||
http://www.gknw.com/mirror/curl/autobuilds/
|
||||
the status of these builds can be viewed at the autobuild table:
|
||||
http://curl.haxx.se/auto/
|
||||
@@ -578,17 +576,17 @@ PORTS
|
||||
- MIPS IRIX 6.2, 6.5
|
||||
- MIPS Linux
|
||||
- Pocket PC/Win CE 3.0
|
||||
- Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1
|
||||
- Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2
|
||||
- PowerPC Darwin 1.0
|
||||
- PowerPC Linux
|
||||
- PowerPC Mac OS 9
|
||||
- PowerPC Mac OS X
|
||||
- SINIX-Z v5
|
||||
- Sparc Linux
|
||||
- Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8
|
||||
- Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8, 9, 10
|
||||
- Sparc SunOS 4.1.X
|
||||
- StrongARM (and other ARM) RISC OS 3.1, 4.02
|
||||
- StrongARM Linux 2.4
|
||||
- StrongARM/ARM7/ARM9 Linux 2.4, 2.6
|
||||
- StrongARM NetBSD 1.4.1
|
||||
- Ultrix 4.3a
|
||||
- i386 BeOS
|
||||
@@ -596,14 +594,14 @@ PORTS
|
||||
- i386 Esix 4.1
|
||||
- i386 FreeBSD
|
||||
- i386 HURD
|
||||
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4
|
||||
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6
|
||||
- i386 NetBSD
|
||||
- i386 Novell NetWare
|
||||
- i386 OS/2
|
||||
- i386 OpenBSD
|
||||
- i386 SCO unix
|
||||
- i386 Solaris 2.7
|
||||
- i386 Windows 95, 98, ME, NT, 2000
|
||||
- i386 Windows 95, 98, ME, NT, 2000, XP, 2003
|
||||
- i386 QNX 6
|
||||
- i486 ncr-sysv4.3.03 (NCR MP-RAS)
|
||||
- ia64 Linux 2.3.99
|
||||
|
@@ -3,6 +3,22 @@ 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!
|
||||
|
||||
25. When doing a CONNECT request with curl it doesn't properly handle if the
|
||||
proxy closes the connection within the authentication "negotiation phase".
|
||||
Like if you do HTTPS or similar over a proxy and you use perhaps
|
||||
--proxy-anyauth. There's work in progress on this problem, and a recent
|
||||
patch was posted here: http://curl.haxx.se/mail/lib-2005-08/0074.html
|
||||
|
||||
24. Harshal Pradhan's Use-after-free with libcurl+ares. This probably occurs
|
||||
because there is a pending ares callback that gets called after the
|
||||
connection struct has been freed in libcurl:
|
||||
http://curl.haxx.se/mail/lib-2005-08/0022.html
|
||||
Fixing this properly most likely requires a new c-ares function.
|
||||
|
||||
23. We don't support SOCKS for IPv6. We don't support FTPS over a SOCKS proxy.
|
||||
We don't have any test cases for SOCKS proxy. We probably have even more
|
||||
bugs and lack of features when a SOCKS proxy is used.
|
||||
|
||||
22. Sending files to a FTP server using curl on VMS, might lead to curl
|
||||
complaining on "unaligned file size" on completion. The problem is related
|
||||
to VMS file structures and the perceived file sizes stat() returns. A
|
||||
@@ -18,14 +34,6 @@ may have been fixed since this was written!
|
||||
specification). The receiver will convert the data from the standard
|
||||
form to his own internal form.
|
||||
|
||||
20. valgrind errors occur too often when 'make test' is used. It is because
|
||||
too many third-party libs and tools have problems. When curl is built
|
||||
without --disable-shared, the testing is done with a front-end script which
|
||||
makes the valgrind testing include (ba)sh as well and that often causes
|
||||
valgrind errors. Either we improve the valgrind error scanner a lot to
|
||||
better identify (lib)curl errors only, or we disable valgrind checking by
|
||||
default.
|
||||
|
||||
19. FTP 3rd party transfers with the multi interface doesn't work. Test:
|
||||
define CURL_MULTIEASY, rebuild curl, run test case 230 - 232.
|
||||
|
||||
@@ -42,10 +50,6 @@ may have been fixed since this was written!
|
||||
would not meaningfully support NUL characters within RFC 959 <string>,
|
||||
anyway (e.g., UNIX pathnames may not contain NUL).
|
||||
|
||||
15. Test case 241 fails on all systems that support IPv6 but that don't have
|
||||
the host name 'ip6-localhost' in /etc/hosts (or similar) since the test case
|
||||
uses that host name to test the IPv6 name to address resolver.
|
||||
|
||||
14. Test case 165 might fail on system which has libidn present, but with an
|
||||
old iconv version (2.1.3 is a known bad version), since it doesn't recognize
|
||||
the charset when named ISO8859-1. Changing the name to ISO-8859-1 makes the
|
||||
@@ -92,9 +96,6 @@ may have been fixed since this was written!
|
||||
libcurl thinks of it as the *compressed* length. Some explanations are here:
|
||||
http://curl.haxx.se/mail/lib-2003-06/0146.html
|
||||
|
||||
4. IPv6 support on AIX 4.3.3 doesn't work due to a missing sockaddr_storage
|
||||
struct. It has been reported to work on AIX 5.1 though.
|
||||
|
||||
3. GOPHER transfers seem broken
|
||||
|
||||
2. If a HTTP server responds to a HEAD request and includes a body (thus
|
||||
|
@@ -12,12 +12,11 @@ I am not a lawyer and this is not legal advice!
|
||||
|
||||
One common dilemma is that GPL[1]-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 - unless you accompany your
|
||||
license with an exception[2]. This particular problem was addressed when the
|
||||
Modified BSD license was created, which does not have the annoncement clause
|
||||
that collides with GPL.
|
||||
clause). You may still build your own copies that use them all, but
|
||||
distributing them as binaries would be to violate the GPL license - unless you
|
||||
accompany your license with an exception[2]. 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
|
||||
|
||||
@@ -28,21 +27,30 @@ libcurl http://curl.haxx.se/docs/copyright.html
|
||||
|
||||
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).
|
||||
(May be used for SSL/TLS support) 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). If OpenSSL's
|
||||
licensing is a problem for you, consider using GnuTLS instead.
|
||||
|
||||
GnuTLS http://www.gnutls.org/
|
||||
|
||||
(May be used for SSL/TLS support) Uses the LGPL[3] license. If this is
|
||||
a problem for you, consider using OpenSSL instead. Also note that
|
||||
GnuTLS itself depends on and uses other libs (libgcrypt and
|
||||
libgpg-error) and they too are LGPL- or GPL-licensed.
|
||||
|
||||
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.
|
||||
(Used for asynchronous name resolves) 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.
|
||||
(Used for compressed Transfer-Encoding support) Uses an MIT-style
|
||||
license that shouldn't collide with any other library.
|
||||
|
||||
krb4
|
||||
|
||||
@@ -52,35 +60,47 @@ krb4
|
||||
of the code in libcurl that is written to deal with Kerberos4 likewise
|
||||
have such a license.
|
||||
|
||||
GSSAPI
|
||||
MIT Kerberos http://web.mit.edu/kerberos/www/dist/
|
||||
|
||||
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.
|
||||
(May be used for GSS support) MIT licensed, that shouldn't collide
|
||||
with any other parts.
|
||||
|
||||
Heimdal http://www.pdc.kth.se/heimdal/
|
||||
|
||||
(May be used for GSS support) Heimdal is Original BSD licensed with
|
||||
the announcement clause.
|
||||
|
||||
GNU GSS http://www.gnu.org/software/gss/
|
||||
|
||||
(May be used for GSS support) GNU GSS is GPL licensed. Note that you
|
||||
may not distribute binary curl packages that uses this if you build
|
||||
curl to also link and use any Original BSD licensed libraries!
|
||||
|
||||
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.
|
||||
(Used for SPNEGO support) 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.
|
||||
(Used for IDNA support) 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.
|
||||
(Used for LDAP support) 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.
|
||||
|
||||
|
||||
[1] = GPL - GNU General Public License: http://www.gnu.org/licenses/gpl.html
|
||||
[2] = http://www.fsf.org/licenses/gpl-faq.html#GPLIncompatibleLibs details on
|
||||
how to write such an exception to the GPL
|
||||
[3] = LGPL - GNU Lesser General Public License:
|
||||
http://www.gnu.org/licenses/lgpl.html
|
||||
|
@@ -17,7 +17,7 @@ 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 \
|
||||
$(PDFPAGES) LICENSE-MIXING README.netware
|
||||
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA
|
||||
|
||||
MAN2HTML= roffit < $< >$@
|
||||
|
||||
|
553
docs/THANKS
553
docs/THANKS
@@ -1,110 +1,453 @@
|
||||
This project has been alive for several years. Countless people have provided
|
||||
feedback that have improved curl. Here follows a (incomplete) list of people
|
||||
that have contributed with non-trivial parts:
|
||||
This project has been alive for many years. Countless people have provided
|
||||
feedback that have improved curl. Here follows a list of people that have
|
||||
contributed (a-z order).
|
||||
|
||||
Daniel Stenberg <daniel@haxx.se>
|
||||
Rafael Sagula <sagula@inf.ufrgs.br>
|
||||
Sampo Kellomaki <sampo@iki.fi>
|
||||
Linas Vepstas <linas@linas.org>
|
||||
Bjorn Reese <breese@mail1.stofanet.dk>
|
||||
Johan Anderson <johan@homemail.com>
|
||||
Kjell Ericson <Kjell.Ericson@haxx.se>
|
||||
Troy Engel <tengel@sonic.net>
|
||||
Ryan Nelson <ryan@inch.com>
|
||||
Bj<EFBFBD>rn Stenberg <bjorn@haxx.se>
|
||||
Angus Mackay <amackay@gus.ml.org>
|
||||
Eric Young <eay@cryptsoft.com>
|
||||
Simon Dick <simond@totally.irrelevant.org>
|
||||
Oren Tirosh <oren@monty.hishome.net>
|
||||
Steven G. Johnson <stevenj@alum.mit.edu>
|
||||
Gilbert Ramirez Jr. <gram@verdict.uthscsa.edu>
|
||||
Andr<EFBFBD>s Garc<72>a <ornalux@redestb.es>
|
||||
Douglas E. Wegscheid <wegscd@whirlpool.com>
|
||||
Mark Butler <butlerm@xmission.com>
|
||||
Eric Thelin <eric@generation-i.com>
|
||||
Marc Boucher <marc@mbsi.ca>
|
||||
Greg Onufer <Greg.Onufer@Eng.Sun.COM>
|
||||
Doug Kaufman <dkaufman@rahul.net>
|
||||
David Eriksson <david@2good.com>
|
||||
Ralph Beckmann <rabe@uni-paderborn.de>
|
||||
T. Yamada <tai@imasy.or.jp>
|
||||
Lars J. Aas <larsa@sim.no>
|
||||
J<EFBFBD>rn Hartroth <Joern.Hartroth@computer.org>
|
||||
Matthew Clarke <clamat@van.maves.ca>
|
||||
Linus Nielsen Feltzing <linus@haxx.se>
|
||||
Felix von Leitner <felix@convergence.de>
|
||||
Dan Zitter <dzitter@zitter.net>
|
||||
Jongki Suwandi <Jongki.Suwandi@eng.sun.com>
|
||||
Chris Maltby <chris@aurema.com>
|
||||
Ron Zapp <rzapper@yahoo.com>
|
||||
Paul Marquis <pmarquis@iname.com>
|
||||
Ellis Pritchard <ellis@citria.com>
|
||||
Damien Adant <dams@usa.net>
|
||||
Chris <cbayliss@csc.come>
|
||||
Marco G. Salvagno <mgs@whiz.cjb.net>
|
||||
Paul Marquis <pmarquis@iname.com>
|
||||
David LeBlanc <dleblanc@qnx.com>
|
||||
Rich Gray at Plus Technologies
|
||||
Luong Dinh Dung <u8luong@lhsystems.hu>
|
||||
Torsten Foertsch <torsten.foertsch@gmx.net>
|
||||
Kristian K<>hntopp <kris@koehntopp.de>
|
||||
Fred Noz <FNoz@siac.com>
|
||||
Caolan McNamara <caolan@csn.ul.ie>
|
||||
Albert Chin-A-Young <china@thewrittenword.com>
|
||||
Stephen Kick <skick@epicrealm.com>
|
||||
Martin Hedenfalk <mhe@stacken.kth.se>
|
||||
Richard Prescott <rip at step.polymtl.ca>
|
||||
Jason S. Priebe <priebe@wral-tv.com>
|
||||
T. Bharath <TBharath@responsenetworks.com>
|
||||
Alexander Kourakos <awk@users.sourceforge.net>
|
||||
James Griffiths <griffiths_james@yahoo.com>
|
||||
Loic Dachary <loic@senga.org>
|
||||
Robert Weaver <robert.weaver@sabre.com>
|
||||
Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
|
||||
Jun-ichiro itojun Hagino <itojun@iijlab.net>
|
||||
Frederic Lepied <flepied@mandrakesoft.com>
|
||||
Georg Horn <horn@koblenz-net.de>
|
||||
Cris Bailiff <c.bailiff@awayweb.com>
|
||||
Sterling Hughes <sterling@designmultimedia.com>
|
||||
S. Moonesamy
|
||||
Ingo Wilken <iw@WWW.Ecce-Terram.DE>
|
||||
Pawel A. Gajda <mis@k2.net.pl>
|
||||
Patrick Bihan-Faou
|
||||
Nico Baggus <Nico.Baggus@mail.ing.nl>
|
||||
Sergio Ballestrero
|
||||
Andrew Francis <locust@familyhealth.com.au>
|
||||
Tomasz Lacki <Tomasz.Lacki@primark.pl>
|
||||
Georg Huettenegger <georg@ist.org>
|
||||
John Lask <johnlask@hotmail.com>
|
||||
Eric Lavigne <erlavigne@wanadoo.fr>
|
||||
Marcus Webster <marcus.webster@phocis.com>
|
||||
G<EFBFBD>tz Babin-Ebell <babin<69>ebell@trustcenter.de>
|
||||
Andreas Damm <andreas-sourceforge@radab.org>
|
||||
Jacky Lam <sylam@emsoftltd.com>
|
||||
James Gallagher <jgallagher@gso.uri.edu>
|
||||
Kjetil Jacobsen <kjetilja@cs.uit.no>
|
||||
Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
Miklos Nemeth <mnemeth@kfkisystems.com>
|
||||
Kevin Roth <kproth@users.sourceforge.net>
|
||||
Ralph Mitchell <rmitchell@eds.com>
|
||||
Dan Fandrich <dan@coneharvesters.com>
|
||||
Jean-Philippe Barrette-LaPierre <jpb@rrette.com>
|
||||
Richard Bramante <RBramante@on.com>
|
||||
Daniel Kouril <kouril@ics.muni.cz>
|
||||
Dirk Manske <dm@nettraffic.de>
|
||||
David Meyer <meyer@paracel.com>
|
||||
Dominick Meglio <codemstr@ptd.net>
|
||||
Gisle Vanem <gvanem@broadpark.no>
|
||||
Giuseppe Attardi <attardi@di.unipi.it>
|
||||
Tor Arntsen <tor@spacetec.no>
|
||||
David Byron <DByron@everdreamcorp.com>
|
||||
David Phillips
|
||||
If you have contributed but are missing here, please let us know!
|
||||
|
||||
Adrian Schuur
|
||||
Alan Pinstein
|
||||
Albert Chin-A-Young
|
||||
Albert Choy
|
||||
Aleksandar Milivojevic
|
||||
Alex aka WindEagle
|
||||
Alex Neblett
|
||||
Alex Suykov
|
||||
Alexander Kourakos
|
||||
Alexander Krasnostavsky
|
||||
G<EFBFBD>nter Knauf
|
||||
Alexander Zhuravlev
|
||||
Alexis Carvalho
|
||||
Andi Jahja
|
||||
Andr<EFBFBD>s Garc<72>a
|
||||
Andreas Damm
|
||||
Andreas Olsson
|
||||
Andreas Rieke
|
||||
Andres Garcia
|
||||
Andrew Bushnell
|
||||
Andrew Francis
|
||||
Andrew Fuller
|
||||
Andy Cedilnik
|
||||
Andy Serpa
|
||||
Angus Mackay
|
||||
Antoine Calando
|
||||
Anton Kalmykov
|
||||
Arkadiusz Miskiewicz
|
||||
Augustus Saunders
|
||||
Avery Fay
|
||||
Ben Greear
|
||||
Benjamin Gerard
|
||||
Bertrand Demiddelaer
|
||||
Peter Sylvester
|
||||
Alexis S. L. Carvalho
|
||||
Bj<EFBFBD>rn Stenberg
|
||||
Bjorn Reese
|
||||
Bob Schader
|
||||
Brad Burdick
|
||||
Brent Beardsley
|
||||
Brian Akins
|
||||
Brian R Duffy
|
||||
Bruce Mitchener
|
||||
Bryan Henderson
|
||||
Bryan Henderson
|
||||
Bryan Kemp
|
||||
Caolan McNamara
|
||||
Casey O'Donnell
|
||||
Marty Kuhrt
|
||||
James Bursa
|
||||
Chih-Chung Chang
|
||||
Chris "Bob Bob"
|
||||
Chris Combes
|
||||
Chris Gaukroger
|
||||
Chris Maltby
|
||||
Christian Kurz
|
||||
Christian Robottom Reis
|
||||
Christophe Demory
|
||||
Christophe Legry
|
||||
Christopher R. Palmer
|
||||
Clarence Gardner
|
||||
Clifford Wolf
|
||||
Cody Jones
|
||||
Colin Watson
|
||||
Colm Buckley
|
||||
Cory Nelson
|
||||
Craig Davison
|
||||
Craig Markwardt
|
||||
Cris Bailiff
|
||||
Cyrill Osterwalder
|
||||
Damien Adant
|
||||
Dan Becker
|
||||
Dan C
|
||||
Dan Fandrich
|
||||
Dan Torop
|
||||
Dan Zitter
|
||||
Daniel at touchtunes
|
||||
Daniel Stenberg
|
||||
Dave Dribin
|
||||
Dave Halbakken
|
||||
Dave Hamilton
|
||||
Dave May
|
||||
David Byron
|
||||
David Cohen
|
||||
David Eriksson
|
||||
David Houlder
|
||||
David Hull
|
||||
David J Meyer
|
||||
David James
|
||||
David Kimdon
|
||||
David LeBlanc
|
||||
David Odin
|
||||
David Phillips
|
||||
David Shaw
|
||||
David Tarendash
|
||||
David Thiel
|
||||
Detlef Schmier
|
||||
Diego Casorran
|
||||
Dimitris Sarris
|
||||
Dinar
|
||||
Dirk Eddelbuettel
|
||||
Dirk Manske
|
||||
Dolbneff A.V
|
||||
Domenico Andreoli
|
||||
Dominick Meglio
|
||||
Doug Kaufman
|
||||
Doug Porter
|
||||
Douglas E. Wegscheid
|
||||
Douglas R. Horner
|
||||
Dustin Boswell
|
||||
Dylan Ellicott
|
||||
Dylan Salisbury
|
||||
Early Ehlinger
|
||||
Edin Kadribasic
|
||||
Ellis Pritchard
|
||||
Emiliano Ida
|
||||
Enrico Scholz
|
||||
Enrik Berkhan
|
||||
Eric Cooper
|
||||
Eric Lavigne
|
||||
Eric Melville
|
||||
Eric Rautman
|
||||
Eric Thelin
|
||||
Eric Vergnaud
|
||||
Eric Young
|
||||
Erick Nuwendam
|
||||
Erwan Legrand
|
||||
Erwin Authried
|
||||
Evan Jordan
|
||||
Fabrizio Ammollo
|
||||
Fedor Karpelevitch
|
||||
Felix von Leitner
|
||||
Florian Schoppmann
|
||||
Forrest Cahoon
|
||||
Frank Keeney
|
||||
Frank Ticheler
|
||||
Fred New
|
||||
Fred Noz
|
||||
Frederic Lepied
|
||||
G<EFBFBD>nter Knauf
|
||||
G<EFBFBD>tz Babin-Ebell
|
||||
Gautam Mani
|
||||
Gaz Iqbal
|
||||
Georg Horn
|
||||
Georg Huettenegger
|
||||
Georg Wicherski
|
||||
Gerd v. Egidy
|
||||
Gerhard Herre
|
||||
Giaslas Georgios
|
||||
Gilad
|
||||
Gilbert Ramirez Jr.
|
||||
Gisle Vanem
|
||||
Giuseppe Attardi
|
||||
Giuseppe D'Ambrosio
|
||||
Glen Nakamura
|
||||
Glen Scott
|
||||
Greg Hewgill
|
||||
Greg Onufer
|
||||
Grigory Entin
|
||||
Guenole Bescon
|
||||
Guillaume Arluison
|
||||
Gustaf Hui
|
||||
Gwenole Beauchesne
|
||||
Hamish Mackenzie
|
||||
Hanno Kranzhoff
|
||||
Hans Steegers
|
||||
Hardeep Singh
|
||||
Harshal Pradhan
|
||||
Heikki Korpela
|
||||
Henrik Storner
|
||||
Hzhijun
|
||||
Ian Ford
|
||||
Ian Gulliver
|
||||
Ian Wilkes
|
||||
Ignacio Vazquez-Abrams
|
||||
Ilguiz Latypov
|
||||
Ingo Ralf Blum
|
||||
Ingo Wilken
|
||||
J<EFBFBD>rg Mueller-Tolk
|
||||
J<EFBFBD>rn Hartroth
|
||||
Jacky Lam
|
||||
Jacob Meuser
|
||||
James Bursa
|
||||
James Clancy
|
||||
James Cone
|
||||
James Gallagher
|
||||
James Griffiths
|
||||
James MacMillan
|
||||
Jamie Lokier
|
||||
Jamie Wilkinson
|
||||
Jason S. Priebe
|
||||
Jean-Claude Chauve
|
||||
Jean-Louis Lemaire
|
||||
Jean-Marc Ranger
|
||||
Jean-Philippe Barrette-LaPierre
|
||||
Jeff Lawson
|
||||
Jeff Phillips
|
||||
Jeff Pohlmeyer
|
||||
Jeffrey Pohlmeyer
|
||||
Jeremy Friesner
|
||||
Jesper Jensen
|
||||
Jesse Noller
|
||||
Jim Drash
|
||||
Joe Halpin
|
||||
Joel Chen
|
||||
Johan Anderson
|
||||
Johan Nilsson
|
||||
John Crow
|
||||
John Janssen
|
||||
John Lask
|
||||
John McGowan
|
||||
Jon Grubbs
|
||||
Jon Travis
|
||||
Jon Turner
|
||||
Jonas Forsman
|
||||
Jonatan Lander
|
||||
Jonathan Hseu
|
||||
Jongki Suwandi
|
||||
Josh Kapell
|
||||
Juan F. Codagnone
|
||||
Juan Ignacio Herv<72>s
|
||||
Juergen Wilke
|
||||
Jukka Pihl
|
||||
Julian Noble
|
||||
Jun-ichiro itojun Hagino
|
||||
Jurij Smakov
|
||||
Kai Sommerfeld
|
||||
Kai-Uwe Rommel
|
||||
Kang-Jin Lee
|
||||
Karol Pietrzak
|
||||
Keith MacDonald
|
||||
Keith McGuigan
|
||||
Ken Hirsch
|
||||
Ken Rastatter
|
||||
Kevin Fisk
|
||||
Kevin Roth
|
||||
Kimmo Kinnunen
|
||||
Kjell Ericson
|
||||
Kjetil Jacobsen
|
||||
Klevtsov Vadim
|
||||
Kris Kennaway
|
||||
Krishnendu Majumdar
|
||||
Kristian K<>hntopp
|
||||
Kyle Sallee
|
||||
Lachlan O'Dea
|
||||
Larry Campbell
|
||||
Larry Fahnoe
|
||||
Lars Gustafsson
|
||||
Lars J. Aas
|
||||
Lars Nilsson
|
||||
Lars Torben Wilson
|
||||
Legoff Vincent
|
||||
Lehel Bernadt
|
||||
Len Krause
|
||||
Linas Vepstas
|
||||
Ling Thio
|
||||
Linus Nielsen Feltzing
|
||||
Loic Dachary
|
||||
Loren Kirkby
|
||||
Luca Altea
|
||||
Luca Alteas
|
||||
Lucas Adamski
|
||||
Lukasz Czekierda
|
||||
Luke Call
|
||||
Luong Dinh Dung
|
||||
Maciej W. Rozycki
|
||||
Marc Boucher
|
||||
Marcelo Juchem
|
||||
Marcin Konicki
|
||||
Marco G. Salvagno
|
||||
Marcus Webster
|
||||
Mario Schroeder
|
||||
Mark Butler
|
||||
Markus Moeller
|
||||
Markus Oberhumer
|
||||
Martijn Koster
|
||||
Martin C. Martin
|
||||
Martin Hedenfalk
|
||||
Marty Kuhrt
|
||||
Maruko
|
||||
Massimiliano Ziccardi
|
||||
Mathias Axelsson
|
||||
Mats Lidell
|
||||
Matt Veenstra
|
||||
Matthew Blain
|
||||
Matthew Clarke
|
||||
Maurice Barnum
|
||||
Mekonikum
|
||||
Mettgut Jamalla
|
||||
Michael Benedict
|
||||
Michael Curtis
|
||||
Michael Mealling
|
||||
Michal Bonino
|
||||
Mihai Ionescu
|
||||
Mike Bytnar
|
||||
Mike Dobbs
|
||||
Miklos Nemeth
|
||||
Mitz Wark
|
||||
Mohamed Lrhazi
|
||||
Mohun Biswas
|
||||
Moonesamy
|
||||
Nathan O'Sullivan
|
||||
Naveen Noel
|
||||
Neil Dunbar
|
||||
Neil Spring
|
||||
Nic Roets
|
||||
Nick Gimbrone
|
||||
Nick Humfrey
|
||||
Nico Baggus
|
||||
Nicolas Berloquin
|
||||
Nicolas Croiset
|
||||
Niels van Tongeren
|
||||
Nikita Schmidt
|
||||
nk
|
||||
Nodak Sodak
|
||||
Oren Tirosh
|
||||
P R Schaffner
|
||||
Patrick Bihan-Faou
|
||||
Patrick Smith
|
||||
Paul Harrington
|
||||
Paul Marquis
|
||||
Paul Moore
|
||||
Paul Nolan
|
||||
Pavel Cenek
|
||||
Pavel Orehov
|
||||
Pawel A. Gajda
|
||||
Pedro Neves
|
||||
Pete Su
|
||||
Peter Bray
|
||||
Peter Forret
|
||||
Peter Pentchev
|
||||
Peter Sylvester
|
||||
Peter Todd
|
||||
Peter Verhas
|
||||
Peter Wullinger
|
||||
Peteris Krumins
|
||||
Phil Karn
|
||||
Philip Gladstone
|
||||
Philippe Hameau
|
||||
Philippe Raoult
|
||||
Pierre
|
||||
Puneet Pawaia
|
||||
Rafael Sagula
|
||||
Ralph Beckmann
|
||||
Ralph Mitchell
|
||||
Ramana Mokkapati
|
||||
Randy McMurchy
|
||||
Reinout van Schouwen
|
||||
Renaud Chaillat
|
||||
Renaud Duhaut
|
||||
Rene Bernhardt
|
||||
Rene Rebe
|
||||
Ricardo Cadime
|
||||
Rich Gray
|
||||
Richard Archer
|
||||
Richard Atterer
|
||||
Richard Bramante
|
||||
Richard Clayton
|
||||
Richard Cooper
|
||||
Richard Gorton
|
||||
Richard Prescott
|
||||
Rick Jones
|
||||
Rick Richardson
|
||||
Rob Stanzel
|
||||
Robert D. Young
|
||||
Robert Olson
|
||||
Robert Weaver
|
||||
Robin Kay
|
||||
Rodney Simmons
|
||||
Roland Krikava
|
||||
Roland Zimmermann
|
||||
Roman Koifman
|
||||
Ron Zapp
|
||||
Rosimildo da Silva
|
||||
Roy Shan
|
||||
Rune Kleveland
|
||||
Ryan Nelson
|
||||
S<EFBFBD>bastien Willemijns
|
||||
S. Moonesamy
|
||||
Salvador D<>vila
|
||||
Salvatore Sorrentino
|
||||
Sampo Kellomaki
|
||||
Samuel D<>az Garc<72>a
|
||||
Samuel Listopad
|
||||
Sander Gates
|
||||
Saul good
|
||||
Sebastien Willemijns
|
||||
Sergio Ballestrero
|
||||
Seshubabu Pasam
|
||||
Shard
|
||||
Shawn Poulson
|
||||
Siddhartha Prakash Jain
|
||||
Simon Dick
|
||||
Simon Liu
|
||||
Spiridonoff A.V
|
||||
Stadler Stephan
|
||||
Stefan Ulrich
|
||||
Stephan Bergmann
|
||||
Stephen Kick
|
||||
Stephen More
|
||||
Sterling Hughes
|
||||
Steve Green
|
||||
Steve Lhomme
|
||||
Steve Marx
|
||||
Steve Oliphant
|
||||
Steven Bazyl
|
||||
Steven G. Johnson
|
||||
Stoned Elipot
|
||||
Sven Neuhaus
|
||||
swalkaus at yahoo.com
|
||||
T. Bharath
|
||||
T. Yamada
|
||||
Thomas Schwinge
|
||||
Thomas Tonino
|
||||
Tim Baker
|
||||
Tim Bartley
|
||||
Tim Costello
|
||||
Tim Sneddon
|
||||
Toby Peterson
|
||||
Todd Kulesza
|
||||
Tom Benoist
|
||||
Tom Lee
|
||||
Tom Mattison
|
||||
Tom Moers
|
||||
Tom Zerucha
|
||||
Tomas Pospisek
|
||||
Tomas Szepe
|
||||
Tomasz Lacki
|
||||
Tommy Tam
|
||||
Ton Voon
|
||||
Tor Arntsen
|
||||
Torsten Foertsch
|
||||
Toshiyuki Maezawa
|
||||
Traian Nicolescu
|
||||
Troels Walsted Hansen
|
||||
Troy Engel
|
||||
Tupone Alfredo
|
||||
Ulrich Zadow
|
||||
Vincent Bronner
|
||||
Vincent Penquerc'h
|
||||
Vincent Sanders
|
||||
Vojtech Janota
|
||||
Vojtech Minarik
|
||||
Walter J. Mack
|
||||
Wayne Haigh
|
||||
Werner Koch
|
||||
Wesley Laxton
|
||||
Wez Furlong
|
||||
Wilfredo Sanchez
|
||||
Wojciech Zwiefka
|
||||
Yarram Sunil
|
||||
Zvi Har'El
|
||||
|
59
docs/TODO
59
docs/TODO
@@ -26,7 +26,7 @@ TODO
|
||||
|
||||
* More data sharing. curl_share_* functions already exist and work, and they
|
||||
can be extended to share more. For example, enable sharing of the ares
|
||||
channel.
|
||||
channel and the connection cache.
|
||||
|
||||
* Introduce a new error code indicating authentication problems (for proxy
|
||||
CONNECT error 407 for example). This cannot be an error code, we must not
|
||||
@@ -35,16 +35,18 @@ TODO
|
||||
|
||||
* Use 'struct lifreq' and SIOCGLIFADDR instead of 'struct ifreq' and
|
||||
SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
|
||||
To support ipv6 interface addresses properly.
|
||||
|
||||
* Add the following to curl_easy_getinfo(): GET_HTTP_IP, GET_FTP_IP and
|
||||
GET_FTP_DATA_IP. Return a string with the used IP. Suggested by Alan.
|
||||
|
||||
* Add option that changes the interval in which the progress callback is
|
||||
called at most.
|
||||
|
||||
LIBCURL - multi interface
|
||||
|
||||
* Add a curl_multi_fdset() alternative that returns only two arrays with file
|
||||
desrciptors for reading and writing to allow the app to use whatever
|
||||
function it prefers. Plus, this allows apps to avoid the FD_SETSIZE problem
|
||||
with select().
|
||||
* Add a curl_multi_fdset() alternative. this allows apps to avoid the
|
||||
FD_SETSIZE problem with select().
|
||||
|
||||
* Add curl_multi_timeout() to make libcurl's ares-functionality better.
|
||||
|
||||
@@ -59,6 +61,17 @@ TODO
|
||||
ready to accept read data. Today libcurl feeds the data as soon as it is
|
||||
available for reading, no matter what.
|
||||
|
||||
* Add curl_multi_socket() and family to the multi interface that gets file
|
||||
descriptors, as an alternative to the curl_multi_fdset(). This is necessary
|
||||
to allow apps to properly avoid the FD_SETSIZE problem.
|
||||
|
||||
* Make curl_easy_perform() a wrapper-function that simply creates a multi
|
||||
handle, adds the easy handle to it, runs curl_multi_perform() until the
|
||||
transfer is done, then detach the easy handle, destroy the multi handle and
|
||||
return the easy handle's return code. This will thus make everything
|
||||
internally use and assume the multi interface. The select()-loop should use
|
||||
curl_multi_socket().
|
||||
|
||||
DOCUMENTATION
|
||||
|
||||
* More and better
|
||||
@@ -68,9 +81,6 @@ TODO
|
||||
* Make the detection of (bad) %0d and %0a codes in FTP url parts earlier in
|
||||
the process to avoid doing a resolve and connect in vain.
|
||||
|
||||
* Code overhaul to make it more state-machine like and to _never_ block on
|
||||
waiting for server responses when used with the multi interface.
|
||||
|
||||
* Support GSS/Kerberos 5 for ftp file transfer. This will allow user
|
||||
authentication and file encryption. Possible libraries and example clients
|
||||
are available from MIT or Heimdal. Requsted by Markus Moeller.
|
||||
@@ -146,14 +156,31 @@ TODO
|
||||
it be? There's so much that could be done if it were! (brought by Chris
|
||||
Clark)
|
||||
|
||||
* Make curl's SSL layer option capable of using other free SSL libraries.
|
||||
Such as the Mozilla Security Services
|
||||
(http://www.mozilla.org/projects/security/pki/nss/) and GnuTLS
|
||||
(http://www.gnu.org/software/gnutls/) This subject has been brought up
|
||||
again recently since GPL-licensed applications that link with libcurl MAY
|
||||
NOT distribute binaries that use OpenSSL without adding an exception clause
|
||||
to the GPL license. See the LICENSE-MIXING document and this:
|
||||
http://www.gnome.org/~markmc/openssl-and-the-gpl.html
|
||||
* Make curl's SSL layer capable of using other free SSL libraries. Such as
|
||||
Mozilla Security Services
|
||||
(http://www.mozilla.org/projects/security/pki/nss/), MatrixSSL
|
||||
(http://www.matrixssl.org/) or yaSSL (http://yassl.com/). At least the
|
||||
latter two could be alternatives for those looking to reduce the footprint
|
||||
of libcurl built with OpenSSL or GnuTLS.
|
||||
|
||||
* Peter Sylvester's patch for SRP on the TLS layer.
|
||||
Awaits OpenSSL support for this, no need to support this in libcurl before
|
||||
there's an OpenSSL release that does it.
|
||||
|
||||
* make the configure --with-ssl option first check for OpenSSL and then for
|
||||
GnuTLS if OpenSSL wasn't detected.
|
||||
|
||||
GnuTLS
|
||||
|
||||
* Get NTLM working using the functions provided by libgcrypt, since GnuTLS
|
||||
already depends on that to function. Not strictly SSL/TLS related, but
|
||||
hey... Another option is to get available DES and MD4 source code from the
|
||||
cryptopp library. They are fine license-wise, but are C++.
|
||||
|
||||
* SSL engine stuff?
|
||||
|
||||
* Work out a common method with Peter Sylvester's OpenSSL-patch for SRP
|
||||
on the TLS to provide name and password
|
||||
|
||||
LDAP
|
||||
|
||||
|
@@ -20,7 +20,7 @@ Version Numbers and Releases
|
||||
N is pre-release number
|
||||
|
||||
One of these numbers will get bumped in each new release. The numbers to the
|
||||
right of a bumped number will be reset to zero. If Z is zero, it is not
|
||||
right of a bumped number will be reset to zero. If Z is zero, it may not be
|
||||
included in the version number. The pre release number is only included in
|
||||
pre releases (they're never used in public, official, releases).
|
||||
|
||||
@@ -49,7 +49,7 @@ Version Numbers and Releases
|
||||
|
||||
As a service to any application that might want to support new libcurl
|
||||
features while still being able to build with older versions, all releases
|
||||
have the libcurl version stored in the curl/curl.h file using a static
|
||||
have the libcurl version stored in the curl/curlver.h file using a static
|
||||
numbering scheme that can be used for comparison. The version number is
|
||||
defined as:
|
||||
|
||||
@@ -62,3 +62,6 @@ Version Numbers and Releases
|
||||
This 6-digit hexadecimal number does not show pre-release number, and it is
|
||||
always a greater number in a more recent release. It makes comparisons with
|
||||
greater than and less than work.
|
||||
|
||||
This number is also available as three separate defines:
|
||||
LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR and LIBCURL_VERSION_PATCH.
|
||||
|
69
docs/curl.1
69
docs/curl.1
@@ -21,7 +21,7 @@
|
||||
.\" * $Id$
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl 1 "29 Mar 2005" "Curl 7.13.2" "Curl Manual"
|
||||
.TH curl 1 "12 Aug 2005" "Curl 7.14.1" "Curl Manual"
|
||||
.SH NAME
|
||||
curl \- transfer a URL
|
||||
.SH SYNOPSIS
|
||||
@@ -421,9 +421,19 @@ set headers without knowing perfectly well what you're doing. Replacing an
|
||||
internal header with one without content on the right side of the colon will
|
||||
prevent that header from appearing.
|
||||
|
||||
curl will make sure that each header you add/replace get sent with the proper
|
||||
end of line marker, you should thus \fBnot\fP add that as a part of the header
|
||||
content: do not add newlines or carriage returns they will only mess things up
|
||||
for you.
|
||||
|
||||
See also the \fI-A/--user-agent\fP and \fI-e/--referer\fP options.
|
||||
|
||||
This option can be used multiple times to add/replace/remove multiple headers.
|
||||
.IP "--ignore-content-length"
|
||||
(HTTP)
|
||||
Ignore the Content-Length header. This is particularly useful for servers
|
||||
running Apache 1.x, which will report incorrect Content-Length for files
|
||||
larger than 2 gigabytes.
|
||||
.IP "-i/--include"
|
||||
(HTTP)
|
||||
Include the HTTP-header in the output. The HTTP-header includes things
|
||||
@@ -497,6 +507,20 @@ line. So, it could look similar to this:
|
||||
url = "http://curl.haxx.se/docs/"
|
||||
|
||||
This option can be used multiple times.
|
||||
|
||||
When curl is invoked, it always (unless \fI-q\fP is used) checks for a default
|
||||
config file and uses it if found. The default config file is checked for in
|
||||
the following places in this order:
|
||||
|
||||
1) curl tries to find the "home dir": It first checks for the CURL_HOME and
|
||||
then the HOME environment variables. Failing that, it uses getpwuid() on
|
||||
unix-like systems (which returns the home dir given the current user in your
|
||||
system). On Windows, it then checks for the APPDATA variable, or as a last
|
||||
resort the '%USERPROFILE%\Application Data'.
|
||||
|
||||
2) On windows, if there is no _curlrc file in the home dir, it checks for one
|
||||
in the same dir the executable curl is placed. On unix-like systems, it will
|
||||
simply try to load .curlrc from the determined home dir.
|
||||
.IP "--limit-rate <speed>"
|
||||
Specify the maximum transfer rate you want curl to use. This feature is useful
|
||||
if you have a limited pipe and you'd like your transfer not use your entire
|
||||
@@ -700,8 +724,9 @@ If this option is used several times, the last one will be used. Disable the
|
||||
use of PORT with \fI--ftp-pasv\fP. Disable the attempt to use the EPRT command
|
||||
instead of PORT by using \fI--disable-eprt\fP. EPRT is really PORT++.
|
||||
.IP "-q"
|
||||
If used as the first parameter on the command line, the \fI$HOME/.curlrc\fP
|
||||
file will not be read and used as a config file.
|
||||
If used as the first parameter on the command line, the \fIcurlrc\fP config
|
||||
file will not be read and used. See the \fI-K/--config\fP for details on the
|
||||
default config file search path.
|
||||
.IP "-Q/--quote <command>"
|
||||
(FTP) Send an arbitrary command to the remote FTP server. Quote commands are
|
||||
sent BEFORE the transfer is taking place (just after the initial PWD command
|
||||
@@ -870,6 +895,11 @@ to read for untrained humans.
|
||||
|
||||
If this option is used several times, the last one will be used. (Added in
|
||||
7.9.7)
|
||||
.IP "--trace-time"
|
||||
Prepends a time stamp to each trace or verbose line that curl displays.
|
||||
|
||||
If this option is used several times, each occurrence will toggle it on/off.
|
||||
(Added in 7.14.0 )
|
||||
.IP "-u/--user <user:password>"
|
||||
Specify user and password to use for server authentication. Overrides
|
||||
\fI-n/--netrc\fP and \fI--netrc-optional\fP.
|
||||
@@ -887,9 +917,9 @@ This option may be used any number of times. To control where this URL is
|
||||
written, use the \fI-o/--output\fP or the \fI-O/--remote-name\fP options.
|
||||
.IP "-v/--verbose"
|
||||
Makes the fetching more verbose/talkative. Mostly usable for debugging. Lines
|
||||
starting with '>' means data sent by curl, '<' means data received by curl
|
||||
that is hidden in normal cases and lines starting with '*' means additional
|
||||
info provided by curl.
|
||||
starting with '>' means "header data" sent by curl, '<' means "header data"
|
||||
received by curl that is hidden in normal cases and lines starting with '*'
|
||||
means additional info provided by curl.
|
||||
|
||||
Note that if you only want HTTP headers in the output, \fI-i/--include\fP
|
||||
might be option you're looking for.
|
||||
@@ -933,13 +963,16 @@ SPNEGO Negotiate authentication is supported.
|
||||
This curl supports transfers of large files, files larger than 2GB.
|
||||
.IP "IDN"
|
||||
This curl supports IDN - international domain names.
|
||||
.IP "SSPI"
|
||||
SSPI is supported. If you use NTLM and set a blank user name, curl will
|
||||
authenticate with your current user and password.
|
||||
.RE
|
||||
.IP "-w/--write-out <format>"
|
||||
Defines what to display after a completed and successful operation. The format
|
||||
is a string that may contain plain text mixed with any number of variables. The
|
||||
string can be specified as "string", to get read from a particular file you
|
||||
specify it "@filename" and to tell curl to read the format from stdin you
|
||||
write "@-".
|
||||
Defines what to display on stdout after a completed and successful
|
||||
operation. The format is a string that may contain plain text mixed with any
|
||||
number of variables. The string can be specified as "string", to get read from
|
||||
a particular file you specify it "@filename" and to tell curl to read the
|
||||
format from stdin you write "@-".
|
||||
|
||||
The variables present in the output format will be substituted by the value or
|
||||
text that curl thinks fit, as described below. All variables are specified
|
||||
@@ -1035,12 +1068,16 @@ transparently be converted to HTTP. It means that certain protocol specific
|
||||
operations might not be available. This is not the case if you can tunnel
|
||||
through the proxy, as done with the \fI-p/--proxytunnel\fP option.
|
||||
|
||||
Starting with 7.14.1, the proxy host can be specified the exact same way as
|
||||
the proxy environment variables, include protocol prefix (http://) and
|
||||
embedded user + password.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-X/--request <command>"
|
||||
(HTTP)
|
||||
Specifies a custom request to use when communicating with the HTTP server.
|
||||
The specified request will be used instead of the standard GET. Read the
|
||||
HTTP 1.1 specification for details and explanations.
|
||||
(HTTP) Specifies a custom request method to use when communicating with the
|
||||
HTTP server. The specified request will be used instead of the method
|
||||
otherwise used (which defaults to GET). Read the HTTP 1.1 specification for
|
||||
details and explanations.
|
||||
|
||||
(FTP)
|
||||
Specifies a custom FTP command to use instead of LIST when doing file lists
|
||||
@@ -1284,5 +1321,5 @@ http://curl.haxx.se
|
||||
ftp://ftp.sunet.se/pub/www/utilities/curl/
|
||||
.SH "SEE ALSO"
|
||||
.BR ftp (1),
|
||||
.BR wget (1),
|
||||
.BR wget (1)
|
||||
|
||||
|
@@ -10,7 +10,8 @@ EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.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 debug.c \
|
||||
anyauthput.c htmltitle.cc htmltidy.c
|
||||
anyauthput.c htmltitle.cc htmltidy.c opensslthreadlock.c \
|
||||
cookie_interface.c cacertinmem.c
|
||||
|
||||
all:
|
||||
@echo "done"
|
||||
|
138
docs/examples/cacertinmem.c
Normal file
138
docs/examples/cacertinmem.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Example using a "in core" PEM certificate to retrieve a https page.
|
||||
* Written by Theo Borm
|
||||
*/
|
||||
|
||||
/* on a netBSD system with OPENSSL& LIBCURL installed from
|
||||
* pkgsrc (using default paths) this program can be compiled using:
|
||||
* gcc -I/usr/pkg/include -L/usr/pkg/lib -lcurl -Wl,-R/usr/pkg/lib -lssl
|
||||
* -lcrypto -lz -o curlcacerttest curlcacerttest.c
|
||||
* on other operating systems you may want to change paths to headers
|
||||
* and libraries
|
||||
*/
|
||||
#include <openssl/ssl.h>
|
||||
#include <curl/curl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
size_t writefunction( void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
fwrite(ptr,size,nmemb,stream);
|
||||
return(nmemb*size);
|
||||
}
|
||||
|
||||
static CURLcode sslctx_function(CURL * curl, void * sslctx, void * parm)
|
||||
{
|
||||
X509_STORE * store;
|
||||
X509 * cert=NULL;
|
||||
BIO * bio;
|
||||
char * mypem = /* www.cacert.org */
|
||||
"-----BEGIN CERTIFICATE-----\n"\
|
||||
"MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\
|
||||
"IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\
|
||||
"IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n"\
|
||||
"Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n"\
|
||||
"BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi\n"\
|
||||
"MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ\n"\
|
||||
"ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC\n"\
|
||||
"CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ\n"\
|
||||
"8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6\n"\
|
||||
"zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y\n"\
|
||||
"fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7\n"\
|
||||
"w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc\n"\
|
||||
"G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k\n"\
|
||||
"epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q\n"\
|
||||
"laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ\n"\
|
||||
"QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU\n"\
|
||||
"fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826\n"\
|
||||
"YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w\n"\
|
||||
"ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY\n"\
|
||||
"gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe\n"\
|
||||
"MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0\n"\
|
||||
"IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy\n"\
|
||||
"dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw\n"\
|
||||
"czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0\n"\
|
||||
"dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl\n"\
|
||||
"aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC\n"\
|
||||
"AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg\n"\
|
||||
"b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB\n"\
|
||||
"ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc\n"\
|
||||
"nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg\n"\
|
||||
"18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c\n"\
|
||||
"gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl\n"\
|
||||
"Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY\n"\
|
||||
"sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T\n"\
|
||||
"SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF\n"\
|
||||
"CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum\n"\
|
||||
"GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n"\
|
||||
"zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n"\
|
||||
"omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\
|
||||
"-----END CERTIFICATE-----\n";
|
||||
/* get a BIO */
|
||||
bio=BIO_new_mem_buf(mypem, -1);
|
||||
/* use it to read the PEM formatted certificate from memory into an X509
|
||||
* structure that SSL can use
|
||||
*/
|
||||
PEM_read_bio_X509(bio, &cert, 0, NULL);
|
||||
if (cert == NULL)
|
||||
printf("PEM_read_bio_X509 failed...\n");
|
||||
|
||||
/* get a pointer to the X509 certificate store (which may be empty!) */
|
||||
store=SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
|
||||
|
||||
/* add our certificate to this store */
|
||||
if (X509_STORE_add_cert(store, cert)==0)
|
||||
printf("error adding certificate\n");
|
||||
|
||||
/* all set to go */
|
||||
return CURLE_OK ;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL * ch;
|
||||
CURLcode rv;
|
||||
|
||||
rv=curl_global_init(CURL_GLOBAL_ALL);
|
||||
ch=curl_easy_init();
|
||||
rv=curl_easy_setopt(ch,CURLOPT_VERBOSE, 0);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_HEADER, 0);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_NOPROGRESS, 1);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_NOSIGNAL, 1);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_WRITEFUNCTION, *writefunction);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_WRITEDATA, stdout);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_HEADERFUNCTION, *writefunction);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_WRITEHEADER, stderr);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_SSLCERTTYPE,"PEM");
|
||||
rv=curl_easy_setopt(ch,CURLOPT_SSL_VERIFYPEER,1);
|
||||
rv=curl_easy_setopt(ch, CURLOPT_URL, "https://www.cacert.org/");
|
||||
|
||||
/* first try: retrieve page without cacerts' certificate -> will fail
|
||||
*/
|
||||
rv=curl_easy_perform(ch);
|
||||
if (rv==CURLE_OK)
|
||||
printf("*** transfer succeeded ***\n");
|
||||
else
|
||||
printf("*** transfer failed ***\n");
|
||||
|
||||
/* second try: retrieve page using cacerts' certificate -> will succeed
|
||||
* load the certificate by installing a function doing the nescessary
|
||||
* "modifications" to the SSL CONTEXT just before link init
|
||||
*/
|
||||
rv=curl_easy_setopt(ch,CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);
|
||||
rv=curl_easy_perform(ch);
|
||||
if (rv==CURLE_OK)
|
||||
printf("*** transfer succeeded ***\n");
|
||||
else
|
||||
printf("*** transfer failed ***\n");
|
||||
|
||||
curl_easy_cleanup(ch);
|
||||
curl_global_cleanup();
|
||||
}
|
110
docs/examples/cookie_interface.c
Normal file
110
docs/examples/cookie_interface.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* This example shows usage of simple cookie interface.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
static void
|
||||
print_cookies(CURL *curl)
|
||||
{
|
||||
CURLcode res;
|
||||
struct curl_slist *cookies;
|
||||
struct curl_slist *nc;
|
||||
int i;
|
||||
|
||||
printf("Cookies, curl knows:\n");
|
||||
res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl curl_easy_getinfo failed: %s\n", curl_easy_strerror(res));
|
||||
exit(1);
|
||||
}
|
||||
nc = cookies, i = 1;
|
||||
while (nc) {
|
||||
printf("[%d]: %s\n", i, nc->data);
|
||||
nc = nc->next;
|
||||
i++;
|
||||
}
|
||||
if (i == 1) {
|
||||
printf("(none)\n");
|
||||
}
|
||||
curl_slist_free_all(cookies);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl = curl_easy_init();
|
||||
if (curl) {
|
||||
char nline[256];
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://www.google.com/"); /* google.com sets "PREF" cookie */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); /* just to start the cookie engine */
|
||||
res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_cookies(curl);
|
||||
|
||||
printf("Erasing curl's knowledge of cookies!\n");
|
||||
curl_easy_setopt(curl, CURLOPT_COOKIELIST, "ALL");
|
||||
|
||||
print_cookies(curl);
|
||||
|
||||
printf("-----------------------------------------------\n"
|
||||
"Setting a cookie \"PREF\" via cookie interface:\n");
|
||||
#ifdef WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
/* Netscape format cookie */
|
||||
snprintf(nline, 256, "%s\t%s\t%s\t%s\t%u\t%s\t%s",
|
||||
".google.com", "TRUE", "/", "FALSE", time(NULL) + 31337, "PREF", "hello google, i like you very much!");
|
||||
res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl curl_easy_setopt failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* HTTP-header style cookie */
|
||||
snprintf(nline, 256,
|
||||
"Set-Cookie: OLD_PREF=3d141414bf4209321; "
|
||||
"expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com");
|
||||
res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl curl_easy_setopt failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_cookies(curl);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Curl init failed!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
@@ -20,7 +20,8 @@ PROGRAMS = fopen.exe ftpget.exe ftpgetresp.exe ftpupload.exe \
|
||||
multi-double.exe multi-post.exe multi-single.exe \
|
||||
persistant.exe post-callback.exe postit2.exe \
|
||||
sepheaders.exe simple.exe simplessl.exe https.exe \
|
||||
ftp3rdparty.exe getinfo.exe anyauthput.exe
|
||||
ftp3rdparty.exe getinfo.exe anyauthput.exe \
|
||||
cookie_interface.exe
|
||||
|
||||
all: $(PROGRAMS)
|
||||
|
||||
|
77
docs/examples/opensslthreadlock.c
Normal file
77
docs/examples/opensslthreadlock.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Example source code to show one way to set the necessary OpenSSL locking
|
||||
* callbacks if you want to do multi-threaded transfers with HTTPS/FTPS with
|
||||
* libcurl built to use OpenSSL.
|
||||
*
|
||||
* This is not a complete stand-alone example.
|
||||
*
|
||||
* Author: Jeremy Brown
|
||||
*/
|
||||
|
||||
#define MUTEX_TYPE pthread_mutex_t
|
||||
#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
|
||||
#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
|
||||
#define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
|
||||
#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
|
||||
#define THREAD_ID pthread_self( )
|
||||
|
||||
|
||||
void handle_error(const char *file, int lineno, const char *msg){
|
||||
fprintf(stderr, ** %s:%i %s\n, file, lineno, msg);
|
||||
ERR_print_errors_fp(stderr);
|
||||
/* exit(-1); */
|
||||
}
|
||||
|
||||
/* This array will store all of the mutexes available to OpenSSL. */
|
||||
static MUTEX_TYPE *mutex_buf= NULL;
|
||||
|
||||
|
||||
static void locking_function(int mode, int n, const char * file, int line)
|
||||
{
|
||||
if (mode & CRYPTO_LOCK)
|
||||
MUTEX_LOCK(mutex_buf[n]);
|
||||
else
|
||||
MUTEX_UNLOCK(mutex_buf[n]);
|
||||
}
|
||||
|
||||
static unsigned long id_function(void)
|
||||
{
|
||||
return ((unsigned long)THREAD_ID);
|
||||
}
|
||||
|
||||
int thread_setup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
mutex_buf = (MUTEX_TYPE *)malloc(CRYPTO_num_locks( ) * sizeof(MUTEX_TYPE));
|
||||
if (!mutex_buf)
|
||||
return 0;
|
||||
for (i = 0; i < CRYPTO_num_locks( ); i++)
|
||||
MUTEX_SETUP(mutex_buf[i]);
|
||||
CRYPTO_set_id_callback(id_function);
|
||||
CRYPTO_set_locking_callback(locking_function);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int thread_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!mutex_buf)
|
||||
return 0;
|
||||
CRYPTO_set_id_callback(NULL);
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
for (i = 0; i < CRYPTO_num_locks( ); i++)
|
||||
MUTEX_CLEANUP(mutex_buf[i]);
|
||||
free(mutex_buf);
|
||||
mutex_buf = NULL;
|
||||
return 1;
|
||||
}
|
@@ -52,7 +52,8 @@ PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
|
||||
|
||||
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
||||
|
||||
EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) libcurl.m4
|
||||
EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) libcurl.m4 \
|
||||
getinfo-times
|
||||
|
||||
MAN2HTML= roffit --mandir=. < $< >$@
|
||||
|
||||
|
@@ -15,9 +15,9 @@ Request internal information from the curl session with this function. The
|
||||
third argument \fBMUST\fP be a pointer to a long, a pointer to a char *, a
|
||||
pointer to a struct curl_slist * or a pointer to a double (as this
|
||||
documentation describes further down). The data pointed-to will be filled in
|
||||
accordingly and can be relied upon only if the function returns CURLE_OK.
|
||||
This function is intended to get used AFTER a performed transfer, all results
|
||||
from this function are undefined until the transfer is completed.
|
||||
accordingly and can be relied upon only if the function returns CURLE_OK. Use
|
||||
this function AFTER a performed transfer if you want to get transfer- oriented
|
||||
data.
|
||||
|
||||
You should not free the memory returned by this function unless it is
|
||||
explictly mentioned below.
|
||||
@@ -35,12 +35,14 @@ this.
|
||||
Pass a pointer to a long to receive the last received proxy response code to a
|
||||
CONNECT request.
|
||||
.IP CURLINFO_FILETIME
|
||||
Pass a pointer to a long to receive the remote time of the retrieved
|
||||
document. If you get -1, it can be because of many reasons (unknown, the
|
||||
server hides it or the server doesn't support the command that tells document
|
||||
time etc) and the time of the document is unknown. Note that you must tell the
|
||||
server to collect this information before the transfer is made, by using the
|
||||
CURLOPT_FILETIME option to \fIcurl_easy_setopt(3)\fP. (Added in 7.5)
|
||||
Pass a pointer to a long to receive the remote time of the retrieved document
|
||||
(in number of seconds since 1 jan 1970 in the GMT/UTC time zone). If you get
|
||||
-1, it can be because of many reasons (unknown, the server hides it or the
|
||||
server doesn't support the command that tells document time etc) and the time
|
||||
of the document is unknown. Note that you must tell the server to collect this
|
||||
information before the transfer is made, by using the CURLOPT_FILETIME option
|
||||
to \fIcurl_easy_setopt(3)\fP or you will unconditionally get a -1 back. (Added
|
||||
in 7.5)
|
||||
.IP CURLINFO_TOTAL_TIME
|
||||
Pass a pointer to a double to receive the total transaction time in seconds
|
||||
for the previous transfer. This time does not include the connect time, so if
|
||||
@@ -132,6 +134,13 @@ counted). Combined with \fICURLINFO_REDIRECT_COUNT\fP you are able to know
|
||||
how many times libcurl successfully reused existing connection(s) or not. See
|
||||
the Connection Options of \fIcurl_easy_setopt(3)\fP to see how libcurl tries
|
||||
to make persistent connections to save time. (Added in 7.12.3)
|
||||
.IP CURLINFO_COOKIELIST
|
||||
Pass a pointer to a 'struct curl_slist *' to receive a linked-list of all
|
||||
cookies cURL knows (expired ones, too). Don't forget to
|
||||
\fIcurl_slist_free_all(3)\fP the list after it has been used. If there are no
|
||||
cookies (cookies for the handle have not been enabled or simply none have been
|
||||
received) 'struct curl_slist *' will be set to point to NULL. (Added in
|
||||
7.14.1)
|
||||
.SH RETURN VALUE
|
||||
If the operation was successful, CURLE_OK is returned. Otherwise an
|
||||
appropriate error code will be returned.
|
||||
|
@@ -21,7 +21,7 @@
|
||||
.\" * $Id$
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl_easy_setopt 3 "25 Jan 2005" "libcurl 7.13.0" "libcurl Manual"
|
||||
.TH curl_easy_setopt 3 "28 Jul 2005" "libcurl 7.14.1" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_setopt - set options for a curl easy handle
|
||||
.SH SYNOPSIS
|
||||
@@ -171,20 +171,30 @@ argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP.
|
||||
.IP CURLOPT_HEADERFUNCTION
|
||||
Function pointer that should match the following prototype: \fIsize_t
|
||||
function( void *ptr, size_t size, size_t nmemb, void *stream);\fP. This
|
||||
function gets called by libcurl as soon as there is received header data that
|
||||
needs to be written down. The headers are guaranteed to be written one-by-one
|
||||
and only complete lines are written. Parsing headers should be easy enough
|
||||
function gets called by libcurl as soon as it has received header data. The
|
||||
header callback will be called once for each header and only complete header
|
||||
lines are passed on to the callback. Parsing headers should be easy enough
|
||||
using this. The size of the data pointed to by \fIptr\fP is \fIsize\fP
|
||||
multiplied with \fInmemb\fP. The pointer named \fIstream\fP will be the one
|
||||
you passed to libcurl with the \fICURLOPT_WRITEHEADER\fP option. Return the
|
||||
number of bytes actually written or return -1 to signal error to the library
|
||||
multiplied with \fInmemb\fP. Do not assume that the header line is zero
|
||||
terminated! The pointer named \fIstream\fP is the one you set with the
|
||||
\fICURLOPT_WRITEHEADER\fP option. The callback function must return the number
|
||||
of bytes actually taken care of, or return -1 to signal error to the library
|
||||
(it will cause it to abort the transfer with a \fICURLE_WRITE_ERROR\fP return
|
||||
code).
|
||||
|
||||
Since 7.14.1: When a server sends a chunked encoded transfer, it may contain a
|
||||
trailer. That trailer is identical to a HTTP header and if such a trailer is
|
||||
received it is passed to the application using this callback as well. There
|
||||
are several ways to detect it being a trailer and not an ordinary header: 1)
|
||||
it comes after the response-body. 2) it comes after the final header line (CR
|
||||
LF) 3) a Trailer: header among the response-headers mention what header to
|
||||
expect in the trailer.
|
||||
.IP CURLOPT_WRITEHEADER
|
||||
Pass a pointer to be used to write the header part of the received data to. If
|
||||
you don't use your own callback to take care of the writing, this must be a
|
||||
valid FILE *. See also the \fICURLOPT_HEADERFUNCTION\fP option above on how to
|
||||
set a custom get-all-headers callback.
|
||||
(This option is also known as \fBCURLOPT_HEADERDATA\fP) Pass a pointer to be
|
||||
used to write the header part of the received data to. If you don't use your
|
||||
own callback to take care of the writing, this must be a valid FILE *. See
|
||||
also the \fICURLOPT_HEADERFUNCTION\fP option above on how to set a custom
|
||||
get-all-headers callback.
|
||||
.IP CURLOPT_DEBUGFUNCTION
|
||||
Function pointer that should match the following prototype: \fIint
|
||||
curl_debug_callback (CURL *, curl_infotype, char *, size_t, void *);\fP
|
||||
@@ -223,6 +233,9 @@ perform operation will return the error code from this callback function. Set
|
||||
the \fIparm\fP argument with the \fICURLOPT_SSL_CTX_DATA\fP option. This
|
||||
option was introduced in 7.11.0.
|
||||
|
||||
This function will get called on all new connections made to a server, during
|
||||
the SSL negotiation. The SSL_CTX pointer will be a new one every time.
|
||||
|
||||
\fBNOTE:\fP To use this properly, a non-trivial amount of knowledge of the
|
||||
openssl libraries is necessary. Using this function allows for example to use
|
||||
openssl callbacks to add additional validation code for certificates, and even
|
||||
@@ -274,15 +287,20 @@ be prefixed with [protocol]:// since any such prefix will be ignored. The
|
||||
proxy's port number may optionally be specified with the separate option
|
||||
\fICURLOPT_PROXYPORT\fP.
|
||||
|
||||
\fBNOTE:\fP when you tell the library to use an HTTP proxy, libcurl will
|
||||
transparently convert operations to HTTP even if you specify an FTP URL
|
||||
etc. This may have an impact on what other features of the library you can
|
||||
use, such as \fICURLOPT_QUOTE\fP and similar FTP specifics that don't work
|
||||
unless you tunnel through the HTTP proxy. Such tunneling is activated with
|
||||
When you tell the library to use an HTTP proxy, libcurl will transparently
|
||||
convert operations to HTTP even if you specify an FTP URL etc. This may have
|
||||
an impact on what other features of the library you can use, such as
|
||||
\fICURLOPT_QUOTE\fP and similar FTP specifics that don't work unless you
|
||||
tunnel through the HTTP proxy. Such tunneling is activated with
|
||||
\fICURLOPT_HTTPPROXYTUNNEL\fP.
|
||||
|
||||
\fBNOTE2:\fP libcurl respects the environment variables \fBhttp_proxy\fP,
|
||||
\fBftp_proxy\fP, \fBall_proxy\fP etc, if any of those is set.
|
||||
libcurl respects the environment variables \fBhttp_proxy\fP, \fBftp_proxy\fP,
|
||||
\fBall_proxy\fP etc, if any of those is set. The \fICURLOPT_PROXY\fP option
|
||||
does however override any possibly set environment variables.
|
||||
|
||||
Starting with 7.14.1, the proxy host string can be specified the exact same
|
||||
way as the proxy environment variables, include protocol prefix (http://) and
|
||||
embedded user + password.
|
||||
.IP CURLOPT_PROXYPORT
|
||||
Pass a long with this option to set the proxy port to connect to unless it is
|
||||
specified in the proxy string \fICURLOPT_PROXY\fP.
|
||||
@@ -410,7 +428,7 @@ is a more secure way to do authentication over public networks than the
|
||||
regular old-fashioned Basic method.
|
||||
.IP CURLAUTH_GSSNEGOTIATE
|
||||
HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain
|
||||
"Negotiate") method was designed by Microsoft and is used in their web
|
||||
\&"Negotiate") method was designed by Microsoft and is used in their web
|
||||
applications. It is primarily meant as a support for Kerberos5 authentication
|
||||
but may be also used along with another authentication methods. For more
|
||||
information see IETF draft draft-brezak-spnego-http-04.txt.
|
||||
@@ -442,7 +460,7 @@ use. Note that for some methods, this will induce an extra network
|
||||
round-trip. Set the actual name and password with the
|
||||
\fICURLOPT_PROXYUSERPWD\fP option. The bitmask can be constructed by or'ing
|
||||
together the bits listed above for the \fICURLOPT_HTTPAUTH\fP option. As of
|
||||
this writing, only Basic and NTLM work. (Added in 7.10.7)
|
||||
this writing, only Basic, Digest and NTLM work. (Added in 7.10.7)
|
||||
.SH HTTP OPTIONS
|
||||
.IP CURLOPT_AUTOREFERER
|
||||
Pass a non-zero parameter to enable this. When enabled, libcurl will
|
||||
@@ -511,8 +529,11 @@ adding a header like "Transfer-Encoding: chunked" with
|
||||
\fICURLOPT_HTTPHEADER\fP. With HTTP 1.0 or without chunked transfer, you must
|
||||
specify the size in the request.
|
||||
|
||||
NOTE: if you have issued a POST request and want to make a HEAD or GET
|
||||
instead, you must explictly pick the new request type using
|
||||
When setting \fICURLOPT_POST\fP to a non-zero value, it will automatically set
|
||||
\fICURLOPT_NOBODY\fP to 0 (since 7.14.1).
|
||||
|
||||
If you issue a POST request and then want to make a HEAD or GET using the same
|
||||
re-used handle, you must explictly set the new request type using
|
||||
\fICURLOPT_NOBODY\fP or \fICURLOPT_HTTPGET\fP or similar.
|
||||
.IP CURLOPT_POSTFIELDS
|
||||
Pass a char * as parameter, which should be the full data to post in an HTTP
|
||||
@@ -550,6 +571,9 @@ must remain intact until you close this curl handle again with
|
||||
|
||||
Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header.
|
||||
You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual.
|
||||
|
||||
When setting \fICURLOPT_HTTPPOST\fP, it will automatically set
|
||||
\fICURLOPT_NOBODY\fP to 0 (since 7.14.1).
|
||||
.IP CURLOPT_REFERER
|
||||
Pass a pointer to a zero terminated string as parameter. It will be used to
|
||||
set the Referer: header in the http request sent to the remote server. This
|
||||
@@ -620,6 +644,9 @@ dumped to a file.
|
||||
Given an empty or non-existing file or by passing the empty string (""), this
|
||||
option will enable cookies for this curl handle, making it understand and
|
||||
parse received cookies and then use matching cookies in future request.
|
||||
|
||||
If you use this option multiple times, you just add more files to read.
|
||||
Subsequent files will add more cookies.
|
||||
.IP CURLOPT_COOKIEJAR
|
||||
Pass a file name as char *, zero terminated. This will make libcurl write all
|
||||
internally known cookies to the specified file when \fIcurl_easy_cleanup(3)\fP
|
||||
@@ -640,10 +667,18 @@ cookies" from the previous session. By default, libcurl always stores and
|
||||
loads all cookies, independent if they are session cookies are not. Session
|
||||
cookies are cookies without expiry date and they are meant to be alive and
|
||||
existing for this "session" only.
|
||||
.IP CURLOPT_COOKIELIST
|
||||
Pass a char * to a cookie string. Cookie can be either in Netscape / Mozilla
|
||||
format or just regular HTTP-style header (Set-Cookie: ...) format. If cURL
|
||||
cookie engine was not enabled it will enable its cookie engine. Passing a
|
||||
magic string \&"ALL" will erase all cookies known by cURL. (Added in 7.14.1)
|
||||
.IP CURLOPT_HTTPGET
|
||||
Pass a long. If the long is non-zero, this forces the HTTP request to get back
|
||||
to GET. usable if a POST, HEAD, PUT or a custom request have been used
|
||||
previously using the same curl handle.
|
||||
|
||||
When setting \fICURLOPT_HTTPGET\fP to a non-zero value, it will automatically
|
||||
set \fICURLOPT_NOBODY\fP to 0 (since 7.14.1).
|
||||
.IP CURLOPT_HTTP_VERSION
|
||||
Pass a long, set to one of the values described below. They force libcurl to
|
||||
use the specific HTTP versions. This is not sensible to do unless you have a
|
||||
@@ -656,6 +691,12 @@ it thinks fit.
|
||||
Enforce HTTP 1.0 requests.
|
||||
.IP CURL_HTTP_VERSION_1_1
|
||||
Enforce HTTP 1.1 requests.
|
||||
.IP CURLOPT_IGNORE_CONTENT_LENGTH
|
||||
Ignore the Content-Length header. This is useful for Apache 1.x (and similar
|
||||
servers) which will report incorrect content length for files over 2
|
||||
gigabytes. If this option is used, curl will not be able to accurately report
|
||||
progress, and will simply stop the download when the server ends the
|
||||
connection. (added in 7.14.1)
|
||||
.RE
|
||||
.SH FTP OPTIONS
|
||||
.IP CURLOPT_FTPPORT
|
||||
@@ -770,11 +811,15 @@ this data is sent off using the ACCT command. (Added in 7.13.0)
|
||||
.SH PROTOCOL OPTIONS
|
||||
.IP CURLOPT_TRANSFERTEXT
|
||||
A non-zero parameter tells the library to use ASCII mode for ftp transfers,
|
||||
instead of the default binary transfer. For LDAP transfers it gets the data in
|
||||
plain text instead of HTML and for win32 systems it does not set the stdout to
|
||||
binary mode. This option can be usable when transferring text data between
|
||||
systems with different views on certain characters, such as newlines or
|
||||
similar.
|
||||
instead of the default binary transfer. For win32 systems it does not set the
|
||||
stdout to binary mode. This option can be usable when transferring text data
|
||||
between systems with different views on certain characters, such as newlines
|
||||
or similar.
|
||||
|
||||
\fBNOTE:\fP libcurl does not do a complete ASCII conversion when doing ASCII
|
||||
transfers over FTP. This is a known limitation/flaw that nobody has
|
||||
rectified. libcurl simply sets the mode to ascii and performs a standard
|
||||
transfer.
|
||||
.IP CURLOPT_CRLF
|
||||
Convert Unix newlines to CRLF newlines on transfers.
|
||||
.IP CURLOPT_RANGE
|
||||
@@ -818,9 +863,8 @@ A non-zero parameter tells the library to not include the body-part in the
|
||||
output. This is only relevant for protocols that have separate header and body
|
||||
parts. On HTTP(S) servers, this will make libcurl do a HEAD request.
|
||||
|
||||
To change back to GET, you should use \fICURLOPT_HTTPGET\fP. To change back to
|
||||
POST, you should use \fICURLOPT_POST\fP. Setting \fICURLOPT_NOBODY\fP to zero
|
||||
has no effect.
|
||||
To change request to GET, you should use \fICURLOPT_HTTPGET\fP. Change request
|
||||
to POST with \fICURLOPT_POST\fP etc.
|
||||
.IP CURLOPT_INFILESIZE
|
||||
When uploading a file to a remote site, this option should be used to tell
|
||||
libcurl what the expected size of the infile is. This value should be passed
|
||||
@@ -996,28 +1040,60 @@ operations.
|
||||
\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
|
||||
3. By default, the SSL library will try to solve this by itself although some
|
||||
servers make this difficult why you at times may have to use this option.
|
||||
Pass a long as parameter to control what version of SSL/TLS to attempt to use.
|
||||
The available options are:
|
||||
.RS
|
||||
.IP CURL_SSLVERSION_DEFAULT
|
||||
The default action. When libcurl built with OpenSSL, this will attempt to
|
||||
figure out the remote SSL protocol version. Unfortunately there are a lot of
|
||||
ancient and broken servers in use which cannot handle this technique and will
|
||||
fail to connect. When libcurl is built with GnuTLS, this will mean SSLv3.
|
||||
.IP CURL_SSLVERSION_TLSv1
|
||||
Force TLSv1
|
||||
.IP CURL_SSLVERSION_SSLv2
|
||||
Force SSLv2
|
||||
.IP CURL_SSLVERSION_SSLv3
|
||||
Force SSLv3
|
||||
.RE
|
||||
.IP CURLOPT_SSL_VERIFYPEER
|
||||
Pass a long that is set to a zero value to stop curl from verifying the peer's
|
||||
certificate (7.10 starting setting this option to non-zero by default).
|
||||
Alternate certificates to verify against can be specified with the
|
||||
\fICURLOPT_CAINFO\fP option or a certificate directory can be specified with
|
||||
the \fICURLOPT_CAPATH\fP option. As of 7.10, curl installs a default bundle.
|
||||
\fICURLOPT_SSL_VERIFYHOST\fP may also need to be set to 1 or 0 if
|
||||
\fICURLOPT_SSL_VERIFYPEER\fP is disabled (it defaults to 2).
|
||||
Pass a long as parameter.
|
||||
|
||||
This option determines whether curl verifies the authenticity of the
|
||||
peer's certificate. A nonzero value means curl verifies; zero means it
|
||||
doesn't. The default is nonzero, but before 7.10, it was zero.
|
||||
|
||||
When negotiating an SSL connection, the server sends a certificate
|
||||
indicating its identity. Curl verifies whether the certificate is
|
||||
authentic, i.e. that you can trust that the server is who the
|
||||
certificate says it is. This trust is based on a chain of digital
|
||||
signatures, rooted in certification authority (CA) certificates you
|
||||
supply. As of 7.10, curl installs a default bundle of CA certificates
|
||||
and you can specify alternate certificates with the
|
||||
\fICURLOPT_CAINFO\fP option or the \fICURLOPT_CAPATH\fP option.
|
||||
|
||||
When \fICURLOPT_SSL_VERIFYPEER\fP is nonzero, and the verification
|
||||
fails to prove that the certificate is authentic, the connection
|
||||
fails. When the option is zero, the connection succeeds regardless.
|
||||
|
||||
Authenticating the certificate is not by itself very useful. You
|
||||
typically want to ensure that the server, as authentically identified
|
||||
by its certificate, is the server you mean to be talking to. Use
|
||||
\fICURLOPT_SSL_VERIFYHOST\fP to control that.
|
||||
.IP CURLOPT_CAINFO
|
||||
Pass a char * to a zero terminated string naming a file holding one or more
|
||||
certificates to verify the peer with. This only makes sense when used in
|
||||
combination with the \fICURLOPT_SSL_VERIFYPEER\fP option.
|
||||
certificates to verify the peer with. This makes sense only when used in
|
||||
combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If
|
||||
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAINFO\fP need not
|
||||
even indicate an accessible file.
|
||||
.IP CURLOPT_CAPATH
|
||||
Pass a char * to a zero terminated string naming a directory holding multiple
|
||||
CA certificates to verify the peer with. The certificate directory must be
|
||||
prepared using the openssl c_rehash utility. This only makes sense when used
|
||||
in combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. The
|
||||
\fICURLOPT_CAPATH\fP function apparently does not work in Windows due to some
|
||||
limitation in openssl. (Added in 7.9.8)
|
||||
Pass a char * to a zero terminated string naming a directory holding
|
||||
multiple CA certificates to verify the peer with. The certificate
|
||||
directory must be prepared using the openssl c_rehash utility. This
|
||||
makes sense only when used in combination with the
|
||||
\fICURLOPT_SSL_VERIFYPEER\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP
|
||||
is zero, \fICURLOPT_CAPATH\fP need not even indicate an accessible
|
||||
path. The \fICURLOPT_CAPATH\fP function apparently does not work in
|
||||
Windows due to some limitation in openssl. (Added in 7.9.8)
|
||||
.IP CURLOPT_RANDOM_FILE
|
||||
Pass a char * to a zero terminated file name. The file will be used to read
|
||||
from to seed the random engine for SSL. The more random the specified file is,
|
||||
@@ -1026,9 +1102,34 @@ the more secure the SSL connection will become.
|
||||
Pass a char * to the zero terminated path name to the Entropy Gathering Daemon
|
||||
socket. It will be used to seed the random engine for SSL.
|
||||
.IP CURLOPT_SSL_VERIFYHOST
|
||||
Pass a long. Set if we should verify the Common name from the peer certificate
|
||||
in the SSL handshake, set 1 to check existence, 2 to ensure that it matches
|
||||
the provided hostname. This is by default set to 2. (default changed in 7.10)
|
||||
Pass a long as parameter.
|
||||
|
||||
This option determines whether curl verifies that the server claims to be
|
||||
who you want it to be.
|
||||
|
||||
When negotiating an SSL connection, the server sends a certificate
|
||||
indicating its identity.
|
||||
|
||||
When \fICURLOPT_SSL_VERIFYHOST\fP is 2, that certificate must indicate
|
||||
that the server is the server to which you meant to connect, or the
|
||||
connection fails.
|
||||
|
||||
Curl considers the server the intended one when the Common Name field
|
||||
or a Subject Alternate Name field in the certificate matches the host
|
||||
name in the URL to which you told Curl to connect.
|
||||
|
||||
When the value is 1, the certificate must contain a Common Name field,
|
||||
but it doesn't matter what name it says. (This is not ordinarily a
|
||||
useful setting).
|
||||
|
||||
When the value is 0, the connection succeeds regardless of the names in
|
||||
the certificate.
|
||||
|
||||
The default, since 7.10, is 2.
|
||||
|
||||
The checking this option controls is of the identity that the server
|
||||
\fIclaims\fP. The server could be lying. To control lying, see
|
||||
\fICURLOPT_SSL_VERIFYPEER\fP.
|
||||
.IP CURLOPT_SSL_CIPHER_LIST
|
||||
Pass a char *, pointing to a zero terminated string holding the list of
|
||||
ciphers to use for the SSL connection. The list must be syntactically correct,
|
||||
|
@@ -90,7 +90,7 @@ followed by a pointer to a string to a name, will make libcurl use the given
|
||||
name in the file upload part, instead of the actual file name given to
|
||||
\fICURLFORM_FILE\fP.
|
||||
|
||||
.IP BCURLFORM_BUFFER
|
||||
.IP CURLFORM_BUFFER
|
||||
followed by a string, tells libcurl that a buffer is to be used to upload data
|
||||
instead of using a file. The given string is used as the value of the file
|
||||
name field in the content header.
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_getdate 3 "5 March 2001" "libcurl 7.0" "libcurl Manual"
|
||||
.TH curl_getdate 3 "12 Aug 2005" "libcurl 7.0" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_getdate - Convert an date string to number of seconds since January 1,
|
||||
1970
|
||||
@@ -26,7 +26,7 @@ order of the items is immaterial. A date string may contain many flavors of
|
||||
items:
|
||||
.TP 0.8i
|
||||
.B calendar date items
|
||||
Can be specified several ways. Month names can only be three-letter
|
||||
Can be specified several ways. Month names can only be three-letter english
|
||||
abbrivations, numbers can be zero-prefixed and the year may use 2 or 4 digits.
|
||||
Examples: 06 Nov 1994, 06-Nov-94 and Nov-94 6.
|
||||
.TP
|
||||
@@ -94,7 +94,7 @@ crippled mktime(), \fIcurl_getdate\fP will return -1 in this case.
|
||||
.SH REWRITE
|
||||
The former version of this function was built with yacc and was not only very
|
||||
large, it was also never quite understood and it wasn't possible to build with
|
||||
non-GNU tools since only Bison could make it thread-safe!
|
||||
non-GNU tools since only GNU Bison could make it thread-safe!
|
||||
|
||||
The rewrite was done for 7.12.2. The new one is much smaller and use simpler
|
||||
code.
|
||||
|
@@ -1,6 +1,6 @@
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_multi_fdset 3 "15 Apr 2004" "libcurl 7.9.5" "libcurl Manual"
|
||||
.TH curl_multi_fdset 3 "25 Apr 2005" "libcurl 7.9.5" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_multi_fdset - extracts file descriptor information from a multi handle
|
||||
.SH SYNOPSIS
|
||||
@@ -15,15 +15,21 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
This function extracts file descriptor information from a given multi_handle.
|
||||
libcurl returns its fd_set sets. The application can use these to select()
|
||||
on. The \fIcurl_multi_perform(3)\fP function should be called as soon as one
|
||||
of them are ready to be read from or written to.
|
||||
libcurl returns its fd_set sets. The application can use these to select() on,
|
||||
but be sure to FD_ZERO them before calling this function as
|
||||
\fIcurl_multi_fdset(3)\fP only adds its own descriptors it doesn't zero or
|
||||
otherwise remove any other. The \fIcurl_multi_perform(3)\fP function should be
|
||||
called as soon as one of them are ready to be read from or written to.
|
||||
|
||||
If no file descriptors are set by libcurl, \fImax_fd\fP will contain -1 when
|
||||
this function returns. Otherwise it will contain the higher descriptor number
|
||||
libcurl set.
|
||||
|
||||
You should also be aware that when doing select(), you should consider using a
|
||||
rather small (single-digit number of seconds) timeout and call
|
||||
\fIcurl_multi_perform\fP regularly - even if no activity has been seen on the
|
||||
fd_sets - as otherwise libcurl-internal retries and timeouts may not work as
|
||||
you'd think.
|
||||
you'd think and want.
|
||||
.SH RETURN VALUE
|
||||
CURLMcode type, general libcurl multi interface error code. See
|
||||
\fIlibcurl-errors(3)\fP
|
||||
|
@@ -34,7 +34,7 @@ typedef struct {
|
||||
const char *host; /* human readable string */
|
||||
int features; /* bitmask, see below */
|
||||
char *ssl_version; /* human readable string */
|
||||
long ssl_version_num; /* number */
|
||||
long ssl_version_num; /* not used, always zero */
|
||||
const char *libz_version; /* human readable string */
|
||||
const char **protocols; /* list of protocols */
|
||||
|
||||
|
27
docs/libcurl/getinfo-times
Normal file
27
docs/libcurl/getinfo-times
Normal file
@@ -0,0 +1,27 @@
|
||||
An overview of the six time values available from curl_easy_getinfo()
|
||||
|
||||
curk_easy_perform()
|
||||
|
|
||||
|--NT
|
||||
|--|--CT
|
||||
|--|--|--PT
|
||||
|--|--|--|--ST
|
||||
|--|--|--TT
|
||||
|--|--|--|--|--RT
|
||||
|
||||
NT = CURLINFO_NAMELOOKUP_TIME. The time it took from the start until the name
|
||||
resolving was completed.
|
||||
CT = CURLINFO_CONNECT_TIME. The time it took from the start until the connect
|
||||
to the remote host (or proxy) was completed.
|
||||
PT = CURLINFO_PRETRANSFER_TIME. The time it took from the start until the file
|
||||
transfer is just about to begin. This includes all pre-transfer commands
|
||||
and negotiations that are specific to the particular protocol(s)
|
||||
involved.
|
||||
ST = CURLINFO_STARTTRANSFER_TIME. The time it took from the start until the
|
||||
first byte is just about to be transferred.
|
||||
TT = CURLINFO_TOTAL_TIME. Time of the previous transfer. This time does not
|
||||
include the connect time (CT), so if you want the complete operation
|
||||
time, you should add that.
|
||||
RT = CURLINFO_REDIRECT_TIME. The time it took for all redirection steps
|
||||
include name lookup, connect, pretransfer and transfer before final
|
||||
transaction was started. So, this is zero if no redirection took place.
|
@@ -196,8 +196,7 @@ Initiating the SSL Engine failed
|
||||
The remote server denied curl to login (Added in 7.13.1)
|
||||
.SH "CURLMcode"
|
||||
This is the generic return code used by functions in the libcurl multi
|
||||
interface. Also consider \fIcurl_multi_strerror(3)\fI.
|
||||
|
||||
interface. Also consider \fIcurl_multi_strerror(3)\fP.
|
||||
.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.
|
||||
@@ -213,9 +212,7 @@ You are doomed.
|
||||
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. Also consider \fIcurl_share_strerror(3)\fI.
|
||||
|
||||
CURLSHcode is one of the following:
|
||||
occurred. Also consider \fIcurl_share_strerror(3)\fP.
|
||||
.IP "CURLSHE_OK (0)"
|
||||
All fine. Proceed as usual.
|
||||
.IP "CURLSHE_BAD_OPTION (1)"
|
||||
|
@@ -21,7 +21,7 @@
|
||||
.\" * $Id$
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH libcurl-tutorial 3 "25 Jan 2005" "libcurl" "libcurl programming"
|
||||
.TH libcurl-tutorial 3 "9 May 2005" "libcurl" "libcurl programming"
|
||||
.SH NAME
|
||||
libcurl-tutorial \- libcurl programming tutorial
|
||||
.SH "Objective"
|
||||
@@ -246,16 +246,26 @@ you intend to make another transfer. libcurl will then attempt to re-use the
|
||||
previous
|
||||
|
||||
.SH "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() call is
|
||||
used to deal with timeouts (during DNS lookup).
|
||||
The first basic rule is that you must \fBnever\fP share a libcurl handle (be
|
||||
it easy or multi or whatever) between multiple threads. Only use one handle in
|
||||
one thread at a time.
|
||||
|
||||
libcurl is completely thread safe, except for two issues: signals and SSL/TLS
|
||||
handlers. Signals are used timeouting name resolves (during DNS lookup) - when
|
||||
built without c-ares support and not on Windows..
|
||||
|
||||
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. Basically, you need to provide one or two functions to
|
||||
allow it to function properly. For all details, see this:
|
||||
then of course using OpenSSL/GnuTLS multi-threaded and those libs have their
|
||||
own requirements on this issue. Basically, 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
|
||||
OpenSSL
|
||||
|
||||
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
|
||||
|
||||
GnuTLS
|
||||
|
||||
http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html
|
||||
|
||||
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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
|
||||
# [ACTION-IF-YES], [ACTION-IF-NO])
|
||||
# ----------------------------------------------------------
|
||||
# David Shaw <dshaw@jabberwocky.com> Jan-23-2005
|
||||
# David Shaw <dshaw@jabberwocky.com> Jun-21-2005
|
||||
#
|
||||
# Checks for libcurl. DEFAULT-ACTION is the string yes or no to
|
||||
# specify whether to default to --with-libcurl or --without-libcurl.
|
||||
@@ -32,13 +32,7 @@
|
||||
# found is after version 7.7.2, the first version that included the
|
||||
# curl-config script. Note that it is very important for people
|
||||
# packaging binary versions of libcurl to include this script!
|
||||
# Without curl-config, we can only make educated guesses as to what
|
||||
# protocols are available. Specifically, we assume that all of HTTP,
|
||||
# FTP, GOPHER, FILE, TELNET, LDAP, and DICT exist, and (if SSL exists)
|
||||
# HTTPS is present. All of these protocols existed when libcurl was
|
||||
# first created in version 7, so this is a safe assumption. If the
|
||||
# version is 7.11.0 or later, FTPS is assumed to be present as well.
|
||||
# FTPS existed before then, but was not yet fully standards compliant.
|
||||
# Without curl-config, we can only guess what protocols are available.
|
||||
|
||||
AC_DEFUN([LIBCURL_CHECK_CONFIG],
|
||||
[
|
||||
@@ -103,6 +97,15 @@ AC_DEFUN([LIBCURL_CHECK_CONFIG],
|
||||
fi
|
||||
if test x"$LIBCURL" = "x" ; then
|
||||
LIBCURL=`$_libcurl_config --libs`
|
||||
|
||||
# This is so silly, but Apple actually has a bug in their
|
||||
# curl-config script. Fixed in Tiger, but there are still
|
||||
# lots of Panther installs around.
|
||||
case "${host}" in
|
||||
powerpc-apple-darwin7*)
|
||||
LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'`
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# All curl-config scripts support --feature
|
||||
@@ -130,8 +133,8 @@ AC_DEFUN([LIBCURL_CHECK_CONFIG],
|
||||
[
|
||||
_libcurl_save_cppflags=$CPPFLAGS
|
||||
CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS"
|
||||
_libcurl_save_ldflags=$LDFLAGS
|
||||
LDFLAGS="$LDFLAGS $LIBCURL"
|
||||
_libcurl_save_libs=$LIBS
|
||||
LIBS="$LIBS $LIBCURL"
|
||||
|
||||
AC_LINK_IFELSE(AC_LANG_PROGRAM([#include <curl/curl.h>],[
|
||||
/* Try and use a few common options to force a failure if we are
|
||||
@@ -147,12 +150,30 @@ x=CURLOPT_VERBOSE;
|
||||
]),libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no)
|
||||
|
||||
CPPFLAGS=$_libcurl_save_cppflags
|
||||
LDFLAGS=$_libcurl_save_ldflags
|
||||
LIBS=$_libcurl_save_libs
|
||||
unset _libcurl_save_cppflags
|
||||
unset _libcurl_save_ldflags
|
||||
unset _libcurl_save_libs
|
||||
])
|
||||
|
||||
if test $libcurl_cv_lib_curl_usable = yes ; then
|
||||
|
||||
# Does curl_free() exist in this version of libcurl?
|
||||
# If not, fake it with free()
|
||||
|
||||
_libcurl_save_cppflags=$CPPFLAGS
|
||||
CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS"
|
||||
_libcurl_save_libs=$LIBS
|
||||
LIBS="$LIBS $LIBCURL"
|
||||
|
||||
AC_CHECK_FUNC(curl_free,,
|
||||
AC_DEFINE(curl_free,free,
|
||||
[Define curl_free() as free() if our version of curl lacks curl_free.]))
|
||||
|
||||
CPPFLAGS=$_libcurl_save_cppflags
|
||||
LIBS=$_libcurl_save_libs
|
||||
unset _libcurl_save_cppflags
|
||||
unset _libcurl_save_libs
|
||||
|
||||
AC_DEFINE(HAVE_LIBCURL,1,
|
||||
[Define to 1 if you have a functional curl library.])
|
||||
AC_SUBST(LIBCURL_CPPFLAGS)
|
||||
|
@@ -890,6 +890,12 @@ typedef enum {
|
||||
"account" info */
|
||||
CINIT(FTP_ACCOUNT, OBJECTPOINT, 134),
|
||||
|
||||
/* feed cookies into cookie engine */
|
||||
CINIT(COOKIELIST, OBJECTPOINT, 135),
|
||||
|
||||
/* ignore Content-Length */
|
||||
CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -1202,11 +1208,10 @@ CURL_EXTERN void curl_slist_free_all(struct curl_slist *);
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Returns the time, in seconds since 1 Jan 1970 of the time string given in
|
||||
* the first argument. The time argument in the second parameter is for cases
|
||||
* where the specified time is relative now, like 'two weeks' or 'tomorrow'
|
||||
* etc.
|
||||
* the first argument. The time argument in the second parameter is unused
|
||||
* and should be set to NULL.
|
||||
*/
|
||||
CURL_EXTERN time_t curl_getdate(const char *p, const time_t *now);
|
||||
CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
|
||||
|
||||
#define CURLINFO_STRING 0x100000
|
||||
#define CURLINFO_LONG 0x200000
|
||||
@@ -1244,6 +1249,7 @@ typedef enum {
|
||||
CURLINFO_OS_ERRNO = CURLINFO_LONG + 25,
|
||||
CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26,
|
||||
CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
|
||||
CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
|
||||
/* Fill in new entries below here! */
|
||||
|
||||
CURLINFO_LASTONE = 28
|
||||
@@ -1358,8 +1364,8 @@ typedef struct {
|
||||
const char *host; /* OS/host/cpu/machine when configured */
|
||||
int features; /* bitmask, see defines below */
|
||||
const char *ssl_version; /* human readable string */
|
||||
long ssl_version_num; /* number */
|
||||
const char *libz_version; /* human readable string */
|
||||
long ssl_version_num; /* not used anymore, always 0 */
|
||||
const char *libz_version; /* human readable string */
|
||||
/* protocols is terminated by an entry with a NULL protoname */
|
||||
const char * const *protocols;
|
||||
|
||||
|
@@ -28,7 +28,7 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.13.2-CVS"
|
||||
#define LIBCURL_VERSION "7.14.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 0x070d02
|
||||
#define LIBCURL_VERSION_NUM 0x070e01
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 13
|
||||
#define LIBCURL_VERSION_PATCH 2
|
||||
#define LIBCURL_VERSION_MINOR 14
|
||||
#define LIBCURL_VERSION_PATCH 1
|
||||
|
||||
#endif /* __CURL_CURLVER_H */
|
||||
|
@@ -23,16 +23,8 @@
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
/*
|
||||
This is meant to be the "external" header file. Don't give away any
|
||||
internals here!
|
||||
This is an "external" header file. Don't give away any internals here!
|
||||
|
||||
This document presents a mixture of ideas from at least:
|
||||
- Daniel Stenberg
|
||||
- Steve Dekorte
|
||||
- Sterling Hughes
|
||||
- Ben Greear
|
||||
|
||||
-------------------------------------------
|
||||
GOALS
|
||||
|
||||
o Enable a "pull" interface. The application that uses libcurl decides where
|
||||
@@ -82,6 +74,22 @@ extern "C" {
|
||||
|
||||
typedef void CURLM;
|
||||
|
||||
#ifdef HAVE_CURL_MULTI_SOCKET /* this is not set by anything yet */
|
||||
|
||||
#ifndef curl_socket_typedef
|
||||
/* Public socket typedef */
|
||||
#ifdef WIN32
|
||||
typedef SOCKET curl_socket_t;
|
||||
#define CURL_SOCKET_BAD INVALID_SOCKET
|
||||
#else
|
||||
typedef int curl_socket_t;
|
||||
#define CURL_SOCKET_BAD -1
|
||||
#endif
|
||||
#define curl_socket_typedef
|
||||
#endif /* curl_socket_typedef */
|
||||
|
||||
#endif /* HAVE_CURL_MULTI_SOCKET */
|
||||
|
||||
typedef enum {
|
||||
CURLM_CALL_MULTI_PERFORM=-1, /* please call curl_multi_perform() soon */
|
||||
CURLM_OK,
|
||||
@@ -113,6 +121,7 @@ typedef struct CURLMsg CURLMsg;
|
||||
* Name: curl_multi_init()
|
||||
*
|
||||
* Desc: inititalize multi-style curl usage
|
||||
*
|
||||
* Returns: a new CURLM handle to use in all 'curl_multi' functions.
|
||||
*/
|
||||
CURL_EXTERN CURLM *curl_multi_init(void);
|
||||
@@ -121,6 +130,7 @@ CURL_EXTERN CURLM *curl_multi_init(void);
|
||||
* Name: curl_multi_add_handle()
|
||||
*
|
||||
* Desc: add a standard curl handle to the multi stack
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
@@ -130,6 +140,7 @@ CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
* Name: curl_multi_remove_handle()
|
||||
*
|
||||
* Desc: removes a curl handle from the multi stack again
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
@@ -141,6 +152,7 @@ CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
* Desc: Ask curl for its fd_set sets. The app can use these to select() or
|
||||
* poll() on. We want curl_multi_perform() called as soon as one of
|
||||
* them are ready.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
@@ -175,6 +187,7 @@ CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
|
||||
* touch any individual easy handles in any way. We need to define
|
||||
* in what state those handles will be if this function is called
|
||||
* in the middle of a transfer.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
|
||||
@@ -211,16 +224,107 @@ CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
|
||||
int *msgs_in_queue);
|
||||
|
||||
/*
|
||||
* NAME curl_multi_strerror()
|
||||
* Name: curl_multi_strerror()
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Desc: The curl_multi_strerror function may be used to turn a CURLMcode
|
||||
* value into the equivalent human readable error string. This is
|
||||
* useful for printing meaningful error messages.
|
||||
*
|
||||
* The curl_multi_strerror function may be used to turn a CURLMcode value
|
||||
* into the equivalent human readable error string. This is useful
|
||||
* for printing meaningful error messages.
|
||||
* Returns: A pointer to a zero-terminated error message.
|
||||
*/
|
||||
CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
||||
|
||||
#ifdef HAVE_CURL_MULTI_SOCKET
|
||||
/*
|
||||
* Name: curl_multi_socket() and
|
||||
* curl_multi_socket_all()
|
||||
*
|
||||
* Desc: An alternative version of curl_multi_perform() that allows the
|
||||
* application to pass in one of the file descriptors that have been
|
||||
* detected to have "action" on them and let libcurl perform. This
|
||||
* allows libcurl to not have to scan through all possible file
|
||||
* descriptors to check for this. The app is recommended to pass in
|
||||
* the 'easy' argument (or set it to CURL_EASY_NONE) to make libcurl
|
||||
* figure out the internal structure even faster and easier. If the
|
||||
* easy argument is set to something else than CURL_EASY_NONE, the
|
||||
* 's' (socket) argument will be ignored by libcurl.
|
||||
*
|
||||
* It also informs the application about updates in the socket (file
|
||||
* descriptor) status by doing none, one or multiple calls to the
|
||||
* curl_socket_callback. It thus updates the status with changes
|
||||
* since the previous time this function was used. If 'callback' is
|
||||
* NULL, no callback will be called. A status change may also be a
|
||||
* new timeout only, having the same IN/OUT status as before.
|
||||
*
|
||||
* If a previous wait for socket action(s) timed out, you should call
|
||||
* this function with the socket argument set to
|
||||
* CURL_SOCKET_TIMEOUT. If you want to force libcurl to (re-)check
|
||||
* all its internal sockets, and call the callback with status for
|
||||
* all sockets no matter what the previous state is, you call
|
||||
* curl_multi_socket_all() instead.
|
||||
*
|
||||
* curl_multi_perform() is thus the equivalent of calling
|
||||
* curl_multi_socket_all(handle, NULL, NULL);
|
||||
*
|
||||
* IMPLEMENTATION: libcurl will need an internal hash table to map
|
||||
* socket numbers to internal easy handles for the cases when 'easy'
|
||||
* is set to CURL_EASY_NONE.
|
||||
*
|
||||
* Regarding the timeout argument in the callback: it is the timeout
|
||||
* (in milliseconds) for waiting on action on this socket (and the
|
||||
* given time period starts when the callback is called) until you
|
||||
* should call curl_multi_socket() with the timeout stuff mentioned
|
||||
* above. If "actions" happens on the socket before the timeout
|
||||
* happens, remember that the timout timer keeps ticking until told
|
||||
* otherwise.
|
||||
*
|
||||
* The "what" argument has one of five values:
|
||||
*
|
||||
* 0 CURL_POLL_NONE (0) - register, not interested in readiness
|
||||
* 1 CURL_POLL_IN - register, interested in read readiness
|
||||
* 2 CURL_POLL_OUT - register, interested in write readiness
|
||||
* 3 CURL_POLL_INOUT - register, interested in both
|
||||
* 4 CURL_POLL_REMOVE - deregister
|
||||
*/
|
||||
#define CURL_POLL_NONE 0
|
||||
#define CURL_POLL_IN 1
|
||||
#define CURL_POLL_OUT 2
|
||||
#define CURL_POLL_INOUT 3
|
||||
#define CURL_POLL_REMOVE 4
|
||||
|
||||
#define CURL_EASY_NONE (CURL *)0
|
||||
#define CURL_EASY_TIMEOUT (CURL *)0
|
||||
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
|
||||
|
||||
typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
|
||||
curl_socket_t s, /* socket */
|
||||
int what, /* see above */
|
||||
long ms, /* timeout for wait */
|
||||
void *userp); /* "private" pointer */
|
||||
|
||||
CURLMcode curl_multi_socket(CURLM *multi_handle,
|
||||
curl_socket_t s,
|
||||
CURL *easy,
|
||||
curl_socket_callback callback,
|
||||
void *userp); /* passed to callback */
|
||||
|
||||
CURLMcode curl_multi_socket_all(CURLM *multi_handle,
|
||||
curl_socket_callback callback,
|
||||
void *userp); /* passed to callback */
|
||||
|
||||
/*
|
||||
* Name: curl_multi_timeout()
|
||||
*
|
||||
* Desc: Returns the maximum number of milliseconds the app is allowed to
|
||||
* wait before curl_multi_socket() or curl_multi_perform() must be
|
||||
* called (to allow libcurl's timed events to take place).
|
||||
*
|
||||
* Returns: CURLM error code.
|
||||
*/
|
||||
CURLMcode curl_multi_timeout(CURLM *multi_handle, long *milliseconds);
|
||||
|
||||
#endif /* HAVE_CURL_MULTI_SOCKET */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
@@ -43,7 +43,8 @@ OBJS = $(OBJ_DIR)\transfer.obj $(OBJ_DIR)\file.obj &
|
||||
$(OBJ_DIR)\hostip4.obj $(OBJ_DIR)\hostthre.obj &
|
||||
$(OBJ_DIR)\hostip6.obj $(OBJ_DIR)\inet_ntop.obj &
|
||||
$(OBJ_DIR)\hostsyn.obj $(OBJ_DIR)\parsedate.obj &
|
||||
$(OBJ_DIR)\select.obj
|
||||
$(OBJ_DIR)\select.obj $(OBJ_DIR)\sslgen.obj &
|
||||
$(OBJ_DIR)\gtls.obj
|
||||
|
||||
RESOURCE = $(OBJ_DIR)\libcurl.res
|
||||
|
||||
@@ -355,3 +356,9 @@ $(OBJ_DIR)\parsedate.obj: parsedate.c setup.h config-win32.h ..\include\curl\cur
|
||||
..\include\curl\multi.h ..\include\curl\curl.h
|
||||
|
||||
$(OBJ_DIR)\select.obj: select.c setup.h config-win32.h select.h
|
||||
|
||||
$(OBJ_DIR)\gtls.obj: gtls.c setup.h config-win32.h
|
||||
|
||||
$(OBJ_DIR)\sslgen.obj: sslgen.c setup.h config-win32.h urldata.h cookie.h &
|
||||
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sslgen.h &
|
||||
ssluse.h gtls.h sendf.h strequal.h url.h memory.h memdebug.h
|
||||
|
@@ -8,7 +8,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
content_encoding.c share.c http_digest.c md5.c http_negotiate.c \
|
||||
http_ntlm.c inet_pton.c strtoofft.c strerror.c hostares.c hostasyn.c \
|
||||
hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c \
|
||||
select.c
|
||||
select.c gtls.c sslgen.c
|
||||
|
||||
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
||||
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
||||
@@ -17,4 +17,6 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.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 select.h easyif.h multiif.h parsedate.h
|
||||
setup.h transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h \
|
||||
gtls.h
|
||||
|
||||
|
@@ -13,15 +13,17 @@ NDKBASE = c:/novell
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
#ZLIB_PATH = ../../zlib-1.2.1
|
||||
ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.3
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.7d
|
||||
OPENSSL_PATH = ../../openssl-0.9.8
|
||||
endif
|
||||
|
||||
ifndef INSTDIR
|
||||
INSTDIR = ../curl-$(LIBCURL_VERSION_STR)-bin-nw
|
||||
INSTDIR = ..$(DS)curl-$(LIBCURL_VERSION_STR)-bin-nw
|
||||
endif
|
||||
|
||||
# Edit the vars below to change NLM target settings.
|
||||
@@ -103,8 +105,6 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
LDLIBS =
|
||||
|
||||
NDK_ROOT = $(NDKBASE)/ndk
|
||||
SDK_CLIB = $(NDK_ROOT)/nwsdk
|
||||
SDK_LIBC = $(NDK_ROOT)/libc
|
||||
@@ -114,21 +114,26 @@ INCLUDES = -I. -I../include
|
||||
|
||||
ifdef WITH_ARES
|
||||
INCLUDES += -I../ares
|
||||
LIBCARES = ../ares/libcares.lib
|
||||
LDLIBS = ../ares/libcares.lib
|
||||
endif
|
||||
ifdef ZLIB_PATH
|
||||
INCLUDES += -I$(ZLIB_PATH)
|
||||
IMPORTS = @$(ZLIB_PATH)/nw/zlib.imp
|
||||
MODULES = libz.nlm
|
||||
endif
|
||||
ifdef SSL
|
||||
ifdef WITH_SSL
|
||||
INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_libc -I$(OPENSSL_PATH)/outinc_nw_libc/openssl
|
||||
LIBSSL = $(OPENSSL_PATH)/out_nw_libc/crypto.lib $(OPENSSL_PATH)/out_nw_libc/ssl.lib
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_libc/crypto.lib $(OPENSSL_PATH)/out_nw_libc/ssl.lib
|
||||
IMPORTS += GetProcessSwitchCount RunningProcess
|
||||
endif
|
||||
ifdef WITH_ZLIB
|
||||
INCLUDES += -I$(ZLIB_PATH)
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(ZLIB_PATH)/nw/libz.lib
|
||||
else
|
||||
IMPORTS += @$(ZLIB_PATH)/nw/libz.imp
|
||||
MODULES += libz.nlm
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
INCLUDES += -I$(SDK_LIBC)/include -I$(SDK_LIBC)/include/nks
|
||||
INCLUDES += -I$(SDK_LIBC)/include/winsock
|
||||
# INCLUDES += -I$(SDK_LIBC)/include/winsock
|
||||
# INCLUDES += -I$(SDK_LDAP)/libc/inc
|
||||
CFLAGS += -D_POSIX_SOURCE
|
||||
# CFLAGS += -D__ANSIC__
|
||||
@@ -152,13 +157,16 @@ endif
|
||||
|
||||
ifeq ($(findstring linux,$(OSTYPE)),linux)
|
||||
DL = '
|
||||
DS = /
|
||||
#-include $(NDKBASE)/nlmconv/ncpfs.inc
|
||||
else
|
||||
DS = \\
|
||||
endif
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include Makefile.inc
|
||||
|
||||
OBJS := $(patsubst %.c,$(OBJDIR)/%.o,$(strip $(CSOURCES))) $(LIBCARES) $(LIBSSL)
|
||||
OBJS := $(patsubst %.c,$(OBJDIR)/%.o,$(strip $(CSOURCES))) $(LDLIBS)
|
||||
|
||||
OBJL = $(OBJS) $(OBJDIR)/nwlib.o
|
||||
|
||||
@@ -189,6 +197,9 @@ install: $(INSTDIR) all
|
||||
@$(CP) ../COPYING $(INSTDIR)
|
||||
@$(CP) ../README $(INSTDIR)
|
||||
@$(CP) ../RELEASE-NOTES $(INSTDIR)
|
||||
ifdef WITH_SSL
|
||||
@$(CP) ca-bundle.crt $(INSTDIR)
|
||||
endif
|
||||
|
||||
clean:
|
||||
-$(RM) config.h ca-bundle.h
|
||||
@@ -274,11 +285,8 @@ ifdef IMPORTS
|
||||
@echo $(DL)import $(IMPORTS)$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(LD),nlmconv)
|
||||
ifdef WITH_ARES
|
||||
@echo $(DL)input $(LIBCARES)$(DL) >> $@
|
||||
endif
|
||||
ifdef SSL
|
||||
@echo $(DL)input $(LIBSSL)$(DL) >> $@
|
||||
ifdef LDLIBS
|
||||
@echo $(DL)input $(LDLIBS)$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)input $(OBJL)$(DL) >> $@
|
||||
@echo $(DL)input $(PRELUDE)$(DL) >> $@
|
||||
@@ -336,7 +344,21 @@ config.h: Makefile.netware
|
||||
@echo $(DL)#define SIZEOF_CURL_OFF_T 4$(DL) >> $@
|
||||
@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@
|
||||
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@
|
||||
ifdef DISABLE_LDAP
|
||||
@echo $(DL)#define CURL_DISABLE_LDAP 1$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)#define DL_LDAP_FILE "lldapsdk.nlm"$(DL) >> $@
|
||||
endif
|
||||
ifdef ENABLE_IPV6
|
||||
@echo $(DL)#define ENABLE_IPV6 1$(DL) >> $@
|
||||
endif
|
||||
ifdef NW_WINSOCK
|
||||
@echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@
|
||||
else
|
||||
@@ -348,11 +370,11 @@ endif
|
||||
ifdef WITH_ARES
|
||||
@echo $(DL)#define USE_ARES 1$(DL) >> $@
|
||||
endif
|
||||
ifdef ZLIB_PATH
|
||||
ifdef WITH_ZLIB
|
||||
@echo $(DL)#define HAVE_ZLIB_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBZ 1$(DL) >> $@
|
||||
endif
|
||||
ifdef SSL
|
||||
ifdef WITH_SSL
|
||||
@echo $(DL)#define USE_SSLEAY 1$(DL) >> $@
|
||||
@echo $(DL)#define USE_OPENSSL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_X509_H 1$(DL) >> $@
|
||||
|
@@ -12,7 +12,7 @@ objs = o.base64 o.connect o.cookie o.dict \
|
||||
o.memdebug o.mprintf o.netrc o.parsedate o.progress \
|
||||
o.security o.select o.sendf o.speedcheck o.ssluse \
|
||||
o.strequal o.strtok o.telnet o.timeval \
|
||||
o.transfer o.url o.version o.strtoofft
|
||||
o.transfer o.url o.version o.strtoofft o.sslgen o.gtls
|
||||
|
||||
# Compile options:
|
||||
linkopts = -o libcurl
|
||||
@@ -119,6 +119,12 @@ o.sendf: c.sendf
|
||||
o.speedcheck: c.speedcheck
|
||||
gcc $(compileropts) -c -o speedcheck.o c.speedcheck
|
||||
|
||||
o.gtls: c.gtls
|
||||
gcc $(compileropts) -c -o gtls.o c.gtls
|
||||
|
||||
o.sslgen: c.sslgen
|
||||
gcc $(compileropts) -c -o sslgen.o c.sslgen
|
||||
|
||||
o.ssluse: c.ssluse
|
||||
gcc $(compileropts) -c -o ssluse.o c.ssluse
|
||||
|
||||
|
@@ -72,6 +72,7 @@ CCDEBUG = cl.exe /MDd /Od /Gm /Zi /D_DEBUG /GZ
|
||||
CFLAGSSSL = /DUSE_SSLEAY /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL
|
||||
CFLAGSLIB = /DCURL_STATICLIB
|
||||
LNKDLL = link.exe /DLL
|
||||
LNKLIB = link.exe /lib
|
||||
LFLAGS = /nologo
|
||||
@@ -99,7 +100,7 @@ LFLAGS = $(LFLAGS) $(WINDOWS_SDK_PATH)\lib\secur32.lib
|
||||
TARGET = $(LIB_NAME).lib
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG)
|
||||
CC = $(CCNODBG) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -111,7 +112,7 @@ TARGET = $(LIB_NAME).lib
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(CFLAGSZLIB)
|
||||
CC = $(CCNODBG) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -135,7 +136,7 @@ TARGET = $(LIB_NAME).lib
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(CFLAGSSSL)
|
||||
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -160,7 +161,7 @@ DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -185,7 +186,7 @@ TARGET = $(LIB_NAME).lib
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(CFLAGSZLIB)
|
||||
CC = $(CCNODBG) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -198,7 +199,7 @@ DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -236,7 +237,7 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
||||
TARGET = $(LIB_NAME_DEBUG).lib
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG)
|
||||
CC = $(CCDEBUG) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -248,7 +249,7 @@ TARGET = $(LIB_NAME_DEBUG).lib
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(CFLAGSSSL)
|
||||
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -260,7 +261,7 @@ TARGET = $(LIB_NAME_DEBUG).lib
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(CFLAGSZLIB)
|
||||
CC = $(CCDEBUG) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -272,7 +273,7 @@ TARGET = $(LIB_NAME_DEBUG).lib
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(CFLAGSSSL)
|
||||
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -285,7 +286,7 @@ DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(SSLLIBS) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -297,7 +298,7 @@ TARGET = $(LIB_NAME_DEBUG).lib
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(CFLAGSZLIB)
|
||||
CC = $(CCDEBUG) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -310,7 +311,7 @@ DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -428,6 +429,7 @@ X_OBJS= \
|
||||
$(DIROBJ)\telnet.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
@@ -443,6 +445,7 @@ X_OBJS= \
|
||||
$(DIROBJ)\progress.obj \
|
||||
$(DIROBJ)\sendf.obj \
|
||||
$(DIROBJ)\speedcheck.obj \
|
||||
$(DIROBJ)\sslgen.obj \
|
||||
$(DIROBJ)\ssluse.obj \
|
||||
$(DIROBJ)\timeval.obj \
|
||||
$(DIROBJ)\url.obj \
|
||||
|
@@ -22,28 +22,53 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "amigaos.h"
|
||||
#include <stdio.h> /* for stderr */
|
||||
#include <amitcp/socketbasetags.h>
|
||||
|
||||
struct Library *SocketBase = NULL;
|
||||
extern int errno, h_errno;
|
||||
|
||||
#ifdef __libnix__
|
||||
#include <stabs.h>
|
||||
void __request(const char *msg);
|
||||
#else
|
||||
# define __request( msg ) Printf( msg "\n\a")
|
||||
#endif
|
||||
|
||||
void amiga_cleanup()
|
||||
{
|
||||
if(SocketBase)
|
||||
CloseLibrary(SocketBase);
|
||||
|
||||
SocketBase = NULL;
|
||||
if(SocketBase) {
|
||||
CloseLibrary(SocketBase);
|
||||
SocketBase = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL amiga_init()
|
||||
{
|
||||
if(!SocketBase)
|
||||
SocketBase = OpenLibrary("bsdsocket.library", 4);
|
||||
if(!SocketBase)
|
||||
SocketBase = OpenLibrary("bsdsocket.library", 4);
|
||||
|
||||
if(!SocketBase) {
|
||||
fprintf(stderr, "No TCP/IP Stack running!\n\a");
|
||||
return FALSE;
|
||||
}
|
||||
if(!SocketBase) {
|
||||
__request("No TCP/IP Stack running!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
atexit(amiga_cleanup);
|
||||
return TRUE;
|
||||
if(SocketBaseTags(
|
||||
SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
|
||||
// SBTM_SETVAL(SBTC_HERRNOLONGPTR), (ULONG) &h_errno,
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "cURL",
|
||||
TAG_DONE)) {
|
||||
|
||||
__request("SocketBaseTags ERROR");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef __libnix__
|
||||
atexit(amiga_cleanup);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef __libnix__
|
||||
ADD2EXIT(amiga_cleanup,-50);
|
||||
#endif
|
||||
|
@@ -32,13 +32,19 @@
|
||||
#include <proto/exec.h>
|
||||
#include <proto/dos.h>
|
||||
|
||||
#include <bsdsocket.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "config-amigaos.h"
|
||||
|
||||
#define select(args...) WaitSelect( args, NULL)
|
||||
#define inet_ntoa(x) Inet_NtoA( x ## .s_addr)
|
||||
#define ioctl(a,b,c,d) IoctlSocket( (LONG)a, (ULONG)b, (char*)c)
|
||||
#ifndef select
|
||||
# define select(args...) WaitSelect( args, NULL)
|
||||
#endif
|
||||
#ifndef inet_ntoa
|
||||
# define inet_ntoa(x) Inet_NtoA( x ## .s_addr)
|
||||
#endif
|
||||
#ifndef ioctl
|
||||
# define ioctl(a,b,c,d) IoctlSocket( (LONG)a, (ULONG)b, (char*)c)
|
||||
#endif
|
||||
#define _AMIGASF 1
|
||||
|
||||
extern void amiga_cleanup();
|
||||
|
@@ -54,6 +54,7 @@
|
||||
#define HAVE_UTIME_H 1
|
||||
#define HAVE_WRITABLE_ARGV 1
|
||||
#define HAVE_ZLIB_H 1
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
|
||||
#define USE_OPENSSL 1
|
||||
#define USE_SSLEAY 1
|
||||
@@ -80,7 +81,9 @@
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
#define in_addr_t int
|
||||
#define socklen_t int
|
||||
#ifndef socklen_t
|
||||
# define socklen_t int
|
||||
#endif
|
||||
|
||||
#ifndef O_RDONLY
|
||||
# define O_RDONLY 0x0000
|
||||
|
@@ -235,6 +235,10 @@
|
||||
/* lber dynamic library file */
|
||||
/* #undef DL_LBER_FILE */
|
||||
|
||||
/* Defines set for VS2005 to _not_ deprecate a few functions we use. */
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE
|
||||
|
||||
/* ldap dynamic library file */
|
||||
#define DL_LDAP_FILE "wldap32.dll"
|
||||
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#define HAVE_BASENAME 1
|
||||
#define HAVE_CLOSESOCKET 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
#define HAVE_FIONBIO 1
|
||||
#define HAVE_GETHOSTBYADDR 1
|
||||
#define HAVE_GETHOSTNAME 1
|
||||
#define HAVE_GETPASS 1
|
||||
@@ -104,7 +105,10 @@
|
||||
|
||||
#define in_addr_t u_long
|
||||
#define socklen_t int
|
||||
|
||||
#if __GNUC__ < 4 /* gcc 4.x built-in ? */
|
||||
#define ssize_t int
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@@ -133,6 +133,7 @@ int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
|
||||
int nonblock /* TRUE or FALSE */)
|
||||
{
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 0
|
||||
#ifdef HAVE_O_NONBLOCK
|
||||
/* most recent unix versions */
|
||||
int flags;
|
||||
@@ -142,46 +143,52 @@ int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
|
||||
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
else
|
||||
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FIONBIO
|
||||
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
|
||||
/* older unix versions */
|
||||
int flags;
|
||||
|
||||
flags = nonblock;
|
||||
return ioctl(sockfd, FIONBIO, &flags);
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 2
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IOCTLSOCKET
|
||||
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
|
||||
/* Windows? */
|
||||
unsigned long flags;
|
||||
flags = nonblock;
|
||||
|
||||
return ioctlsocket(sockfd, FIONBIO, &flags);
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 3
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IOCTLSOCKET_CASE
|
||||
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
|
||||
/* presumably for Amiga */
|
||||
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 4
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SO_NONBLOCK
|
||||
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
|
||||
/* BeOS */
|
||||
long b = nonblock ? 1 : 0;
|
||||
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 5
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DISABLED_NONBLOCKING
|
||||
return 0; /* returns success */
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 6
|
||||
#endif
|
||||
|
||||
#ifndef SETBLOCK
|
||||
#if (SETBLOCK == 0)
|
||||
#error "no non-blocking method was found/used/set"
|
||||
#endif
|
||||
}
|
||||
@@ -345,19 +352,20 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
|
||||
if(!bindworked) {
|
||||
data->state.os_errno = Curl_ourerrno();
|
||||
failf(data, "%s", Curl_strerror(conn, data->state.os_errno));
|
||||
failf(data, "bind failure: %s",
|
||||
Curl_strerror(conn, data->state.os_errno));
|
||||
return CURLE_HTTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
} /* end of if h */
|
||||
else {
|
||||
failf(data,"could't find my own IP address (%s)", myhost);
|
||||
failf(data,"couldn't find my own IP address (%s)", myhost);
|
||||
return CURLE_HTTP_PORT_FAILED;
|
||||
}
|
||||
} /* end of inet_addr */
|
||||
|
||||
else {
|
||||
failf(data, "could't find my own IP address (%s)", myhost);
|
||||
failf(data, "couldn't find my own IP address (%s)", myhost);
|
||||
return CURLE_HTTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
@@ -645,14 +653,14 @@ singleipconnect(struct connectdata *conn,
|
||||
CURLcode res = bindlocal(conn, sockfd);
|
||||
if(res) {
|
||||
sclose(sockfd); /* close socket and bail out */
|
||||
return res;
|
||||
return CURL_SOCKET_BAD;
|
||||
}
|
||||
}
|
||||
|
||||
/* set socket non-blocking */
|
||||
Curl_nonblock(sockfd, TRUE);
|
||||
|
||||
rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
|
||||
rc = connect(sockfd, ai->ai_addr, (socklen_t)ai->ai_addrlen);
|
||||
|
||||
if(-1 == rc) {
|
||||
error = Curl_ourerrno();
|
||||
|
118
lib/cookie.c
118
lib/cookie.c
@@ -85,12 +85,17 @@ Example set of cookies:
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define _MPRINTF_REPLACE /* without this on windows OS we get undefined reference to snprintf */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "cookie.h"
|
||||
#include "strequal.h"
|
||||
#include "strtok.h"
|
||||
#include "sendf.h"
|
||||
#include "memory.h"
|
||||
#include "share.h"
|
||||
#include "strtoofft.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
@@ -130,6 +135,27 @@ static bool tailmatch(const char *little, const char *bigone)
|
||||
return (bool)strequal(little, bigone+biglen-littlelen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
|
||||
*/
|
||||
void Curl_cookie_loadfiles(struct SessionHandle *data)
|
||||
{
|
||||
struct curl_slist *list = data->change.cookielist;
|
||||
if(list) {
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
while(list) {
|
||||
data->cookies = Curl_cookie_init(data,
|
||||
list->data,
|
||||
data->cookies,
|
||||
data->set.cookiesession);
|
||||
list = list->next;
|
||||
}
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
curl_slist_free_all(data->change.cookielist); /* clean up list */
|
||||
data->change.cookielist = NULL; /* don't do this again! */
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Curl_cookie_add()
|
||||
@@ -309,7 +335,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
break;
|
||||
}
|
||||
co->expires =
|
||||
atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + now;
|
||||
atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + (long)now;
|
||||
}
|
||||
else if(strequal("expires", name)) {
|
||||
co->expirestr=strdup(whatptr);
|
||||
@@ -470,7 +496,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
co->secure = (bool)strequal(ptr, "TRUE");
|
||||
break;
|
||||
case 4:
|
||||
co->expires = atoi(ptr);
|
||||
co->expires = curlx_strtoofft(ptr, NULL, 10);
|
||||
break;
|
||||
case 5:
|
||||
co->name = strdup(ptr);
|
||||
@@ -816,6 +842,34 @@ void Curl_cookie_cleanup(struct CookieInfo *c)
|
||||
}
|
||||
}
|
||||
|
||||
/* get_netscape_format()
|
||||
*
|
||||
* Formats a string for Netscape output file, w/o a newline at the end.
|
||||
*
|
||||
* Function returns a char * to a formatted line. Has to be free()d
|
||||
*/
|
||||
static char *get_netscape_format(const struct Cookie *co)
|
||||
{
|
||||
return aprintf(
|
||||
"%s%s\t" /* domain */
|
||||
"%s\t" /* tailmatch */
|
||||
"%s\t" /* path */
|
||||
"%s\t" /* secure */
|
||||
"%" FORMAT_OFF_T "\t" /* expires */
|
||||
"%s\t" /* name */
|
||||
"%s", /* value */
|
||||
/* Make sure all domains are prefixed with a dot if they allow
|
||||
tailmatching. This is Mozilla-style. */
|
||||
(co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
|
||||
co->domain?co->domain:"unknown",
|
||||
co->tailmatch?"TRUE":"FALSE",
|
||||
co->path?co->path:"/",
|
||||
co->secure?"TRUE":"FALSE",
|
||||
co->expires,
|
||||
co->name,
|
||||
co->value?co->value:"");
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_cookie_output()
|
||||
*
|
||||
@@ -847,6 +901,8 @@ int Curl_cookie_output(struct CookieInfo *c, char *dumphere)
|
||||
}
|
||||
|
||||
if(c) {
|
||||
char *format_ptr;
|
||||
|
||||
fputs("# Netscape HTTP Cookie File\n"
|
||||
"# http://www.netscape.com/newsref/std/cookie_spec.html\n"
|
||||
"# This file was generated by libcurl! Edit at your own risk.\n\n",
|
||||
@@ -854,26 +910,13 @@ int Curl_cookie_output(struct CookieInfo *c, char *dumphere)
|
||||
co = c->cookies;
|
||||
|
||||
while(co) {
|
||||
fprintf(out,
|
||||
"%s%s\t" /* domain */
|
||||
"%s\t" /* tailmatch */
|
||||
"%s\t" /* path */
|
||||
"%s\t" /* secure */
|
||||
"%u\t" /* expires */
|
||||
"%s\t" /* name */
|
||||
"%s\n", /* value */
|
||||
|
||||
/* Make sure all domains are prefixed with a dot if they allow
|
||||
tailmatching. This is Mozilla-style. */
|
||||
(co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
|
||||
co->domain?co->domain:"unknown",
|
||||
co->tailmatch?"TRUE":"FALSE",
|
||||
co->path?co->path:"/",
|
||||
co->secure?"TRUE":"FALSE",
|
||||
(unsigned int)co->expires,
|
||||
co->name,
|
||||
co->value?co->value:"");
|
||||
|
||||
format_ptr = get_netscape_format(co);
|
||||
if (format_ptr == NULL) {
|
||||
fprintf(out, "#\n# Fatal libcurl error\n");
|
||||
return 1;
|
||||
}
|
||||
fprintf(out, "%s\n", format_ptr);
|
||||
free(format_ptr);
|
||||
co=co->next;
|
||||
}
|
||||
}
|
||||
@@ -884,4 +927,35 @@ int Curl_cookie_output(struct CookieInfo *c, char *dumphere)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
|
||||
{
|
||||
struct curl_slist *list = NULL;
|
||||
struct curl_slist *beg;
|
||||
struct Cookie *c;
|
||||
char *line;
|
||||
|
||||
if ((data->cookies == NULL) ||
|
||||
(data->cookies->numcookies == 0))
|
||||
return NULL;
|
||||
|
||||
c = data->cookies->cookies;
|
||||
|
||||
beg = list;
|
||||
while (c) {
|
||||
/* fill the list with _all_ the cookies we know */
|
||||
line = get_netscape_format(c);
|
||||
if (line == NULL) {
|
||||
/* get_netscape_format returns null only if we run out of memory */
|
||||
|
||||
curl_slist_free_all(beg); /* free some memory */
|
||||
return NULL;
|
||||
}
|
||||
list = curl_slist_append(list, line);
|
||||
free(line);
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */
|
||||
|
10
lib/cookie.h
10
lib/cookie.h
@@ -38,7 +38,7 @@ struct Cookie {
|
||||
char *value; /* name = <this> */
|
||||
char *path; /* path = <this> */
|
||||
char *domain; /* domain = <this> */
|
||||
long expires; /* expires = <this> */
|
||||
curl_off_t expires; /* expires = <this> */
|
||||
char *expirestr; /* the plain text version */
|
||||
bool tailmatch; /* weather we do tail-matchning of the domain name */
|
||||
|
||||
@@ -92,4 +92,12 @@ void Curl_cookie_freelist(struct Cookie *);
|
||||
void Curl_cookie_cleanup(struct CookieInfo *);
|
||||
int Curl_cookie_output(struct CookieInfo *, char *);
|
||||
|
||||
#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
|
||||
#define Curl_cookie_list(x) NULL
|
||||
#define Curl_cookie_loadfiles(x)
|
||||
#else
|
||||
struct curl_slist *Curl_cookie_list(struct SessionHandle *data);
|
||||
void Curl_cookie_loadfiles(struct SessionHandle *data);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
42
lib/easy.c
42
lib/easy.c
@@ -75,7 +75,7 @@
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
#include "ssluse.h"
|
||||
#include "sslgen.h"
|
||||
#include "url.h"
|
||||
#include "getinfo.h"
|
||||
#include "hostip.h"
|
||||
@@ -201,7 +201,7 @@ CURLcode curl_global_init(long flags)
|
||||
Curl_ccalloc = (curl_calloc_callback)calloc;
|
||||
|
||||
if (flags & CURL_GLOBAL_SSL)
|
||||
if (!Curl_SSL_init())
|
||||
if (!Curl_ssl_init())
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
if (flags & CURL_GLOBAL_WIN32)
|
||||
@@ -266,7 +266,7 @@ void curl_global_cleanup(void)
|
||||
Curl_global_host_cache_dtor();
|
||||
|
||||
if (init_flags & CURL_GLOBAL_SSL)
|
||||
Curl_SSL_cleanup();
|
||||
Curl_ssl_cleanup();
|
||||
|
||||
if (init_flags & CURL_GLOBAL_WIN32)
|
||||
win32_cleanup();
|
||||
@@ -308,49 +308,19 @@ CURL *curl_easy_init(void)
|
||||
* 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, ...)
|
||||
{
|
||||
va_list arg;
|
||||
func_T param_func = (func_T)0;
|
||||
long param_long = 0;
|
||||
void *param_obj = NULL;
|
||||
curl_off_t param_offset = 0;
|
||||
struct SessionHandle *data = curl;
|
||||
CURLcode ret=CURLE_FAILED_INIT;
|
||||
CURLcode ret;
|
||||
|
||||
if(!curl)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
va_start(arg, tag);
|
||||
|
||||
/* PORTING NOTE:
|
||||
Object pointers can't necessarily be casted to function pointers and
|
||||
therefore we need to know what type it is and read the correct type
|
||||
at once. This should also correct problems with different sizes of
|
||||
the types.
|
||||
*/
|
||||
|
||||
if(tag < CURLOPTTYPE_OBJECTPOINT) {
|
||||
/* This is a LONG type */
|
||||
param_long = va_arg(arg, long);
|
||||
ret = Curl_setopt(data, tag, param_long);
|
||||
}
|
||||
else if(tag < CURLOPTTYPE_FUNCTIONPOINT) {
|
||||
/* This is a object pointer type */
|
||||
param_obj = va_arg(arg, void *);
|
||||
ret = Curl_setopt(data, tag, param_obj);
|
||||
}
|
||||
else if(tag < CURLOPTTYPE_OFF_T) {
|
||||
/* This is a function pointer type */
|
||||
param_func = va_arg(arg, func_T );
|
||||
ret = Curl_setopt(data, tag, param_func);
|
||||
}
|
||||
else {
|
||||
/* This is a curl_off_t type */
|
||||
param_offset = va_arg(arg, curl_off_t);
|
||||
ret = Curl_setopt(data, tag, param_offset);
|
||||
}
|
||||
ret = Curl_setopt(data, tag, arg);
|
||||
|
||||
va_end(arg);
|
||||
return ret;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2005, 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
|
||||
@@ -464,7 +464,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else
|
||||
current_form->namelength =
|
||||
array_state?(long)array_value:va_arg(params, long);
|
||||
array_state?(long)array_value:(long)va_arg(params, long);
|
||||
break;
|
||||
|
||||
/*
|
||||
@@ -1550,7 +1550,7 @@ char *Curl_FormBoundary(void)
|
||||
if(!retstring)
|
||||
return NULL; /* failed */
|
||||
|
||||
srand(time(NULL)+randomizer++); /* seed */
|
||||
srand((unsigned int)time(NULL)+randomizer++); /* seed */
|
||||
|
||||
strcpy(retstring, "----------------------------");
|
||||
|
||||
|
143
lib/ftp.c
143
lib/ftp.c
@@ -87,7 +87,7 @@
|
||||
|
||||
#include "strtoofft.h"
|
||||
#include "strequal.h"
|
||||
#include "ssluse.h"
|
||||
#include "sslgen.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
#include "memory.h"
|
||||
@@ -174,9 +174,13 @@ static bool isBadFtpString(const char *string)
|
||||
* to us. This function will sit and wait here until the server has
|
||||
* connected.
|
||||
*
|
||||
* If FTP-SSL is used and SSL is requested for the data connection, this
|
||||
* function will do that transport layer handshake too.
|
||||
*
|
||||
*/
|
||||
static CURLcode AllowServerConnect(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result;
|
||||
int timeout_ms;
|
||||
struct SessionHandle *data = conn->data;
|
||||
curl_socket_t sock = conn->sock[SECONDARYSOCKET];
|
||||
@@ -209,12 +213,12 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
|
||||
default:
|
||||
/* we have received data here */
|
||||
{
|
||||
curl_socket_t s;
|
||||
size_t size = sizeof(struct sockaddr_in);
|
||||
curl_socket_t s = CURL_SOCKET_BAD;
|
||||
socklen_t size = (socklen_t) sizeof(struct sockaddr_in);
|
||||
struct sockaddr_in add;
|
||||
|
||||
getsockname(sock, (struct sockaddr *) &add, (socklen_t *)&size);
|
||||
s=accept(sock, (struct sockaddr *) &add, (socklen_t *)&size);
|
||||
if(0 == getsockname(sock, (struct sockaddr *) &add, &size))
|
||||
s=accept(sock, (struct sockaddr *) &add, &size);
|
||||
|
||||
sclose(sock); /* close the first socket */
|
||||
|
||||
@@ -231,6 +235,17 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
|
||||
break;
|
||||
}
|
||||
|
||||
/* If PASV is used, this is is made elsewhere */
|
||||
if(conn->ssl[SECONDARYSOCKET].use) {
|
||||
/* since we only have a plaintext TCP connection here, we must now
|
||||
do the TLS stuff */
|
||||
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
|
||||
/* BLOCKING */
|
||||
result = Curl_ssl_connect(conn, SECONDARYSOCKET);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -266,8 +281,8 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
|
||||
|
||||
ptr=buf + ftp->nread_resp;
|
||||
|
||||
perline= ptr-ftp->linestart_resp; /* number of bytes in the current line,
|
||||
so far */
|
||||
perline= (int)(ptr-ftp->linestart_resp); /* number of bytes in the current
|
||||
line, so far */
|
||||
keepon=TRUE;
|
||||
|
||||
while((ftp->nread_resp<BUFSIZE) && (keepon && !result)) {
|
||||
@@ -777,9 +792,12 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
/******************************************************************
|
||||
* IPv6-specific section
|
||||
*/
|
||||
|
||||
struct addrinfo *res, *ai;
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
|
||||
struct sockaddr_storage ss;
|
||||
#else
|
||||
char ss[256]; /* this should be big enough to fit a lot */
|
||||
#endif
|
||||
struct addrinfo *res, *ai;
|
||||
socklen_t sslen;
|
||||
char hbuf[NI_MAXHOST];
|
||||
struct sockaddr *sa=(struct sockaddr *)&ss;
|
||||
@@ -866,13 +884,13 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if (portsock == CURL_SOCKET_BAD) {
|
||||
failf(data, "%s", Curl_strerror(conn,error));
|
||||
failf(data, "socket failure: %s", Curl_strerror(conn,error));
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
sslen = sizeof(ss);
|
||||
if (getsockname(portsock, sa, &sslen) < 0) {
|
||||
failf(data, "%s", Curl_strerror(conn,Curl_ourerrno()));
|
||||
failf(data, "getsockname(): %s", Curl_strerror(conn,Curl_ourerrno()));
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
@@ -1107,7 +1125,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
else {
|
||||
failf(data, "could't find IP address to use");
|
||||
failf(data, "couldn't find IP address to use");
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
@@ -1667,8 +1685,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
|
||||
/* BLOCKING */
|
||||
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
||||
result = Curl_ConnectHTTPProxyTunnel(conn, SECONDARYSOCKET,
|
||||
newhost, newport);
|
||||
result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport);
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
}
|
||||
@@ -1739,7 +1756,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||||
"%04d%02d%02d %02d:%02d:%02d GMT",
|
||||
year, month, day, hour, minute, second);
|
||||
/* now, convert this into a time() value: */
|
||||
data->info.filetime = curl_getdate(buf, &secs);
|
||||
data->info.filetime = (long)curl_getdate(buf, &secs);
|
||||
}
|
||||
|
||||
/* If we asked for a time of the file and we actually got one as well,
|
||||
@@ -1823,10 +1840,17 @@ static CURLcode ftp_state_type_resp(struct connectdata *conn,
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data=conn->data;
|
||||
|
||||
if(ftpcode != 200) {
|
||||
if(ftpcode/100 != 2) {
|
||||
/* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a
|
||||
successful 'TYPE I'. While that is not as RFC959 says, it is still a
|
||||
positive response code and we allow that. */
|
||||
failf(data, "Couldn't set desired mode");
|
||||
return CURLE_FTP_COULDNT_SET_BINARY; /* FIX */
|
||||
}
|
||||
if(ftpcode != 200)
|
||||
infof(data, "Got a %03d response code instead of the assumed 200\n",
|
||||
ftpcode);
|
||||
|
||||
if(instate == FTP_TYPE)
|
||||
result = ftp_state_post_type(conn);
|
||||
else if(instate == FTP_LIST_TYPE)
|
||||
@@ -2008,16 +2032,6 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
if(conn->ssl[SECONDARYSOCKET].use) {
|
||||
/* since we only have a plaintext TCP connection here, we must now
|
||||
do the TLS stuff */
|
||||
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
|
||||
/* BLOCKING */
|
||||
result = Curl_SSLConnect(conn, SECONDARYSOCKET);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
*(ftp->bytecountp)=0;
|
||||
|
||||
/* When we know we're uploading a specified file, we can get the file
|
||||
@@ -2086,7 +2100,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
||||
char *bytes;
|
||||
bytes=strstr(buf, " bytes");
|
||||
if(bytes--) {
|
||||
long in=bytes-buf;
|
||||
long in=(long)(bytes-buf);
|
||||
/* this is a hint there is size information in there! ;-) */
|
||||
while(--in) {
|
||||
/* scan for the left parenthesis and break there */
|
||||
@@ -2117,15 +2131,6 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
if(conn->ssl[SECONDARYSOCKET].use) {
|
||||
/* since we only have a plaintext TCP connection here, we must now
|
||||
do the TLS stuff */
|
||||
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
|
||||
result = Curl_SSLConnect(conn, SECONDARYSOCKET);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if(size > conn->maxdownload && conn->maxdownload > 0)
|
||||
size = conn->size = conn->maxdownload;
|
||||
|
||||
@@ -2148,7 +2153,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
||||
state(conn, FTP_STOP); /* this phase is over */
|
||||
}
|
||||
else {
|
||||
failf(data, "%s", buf+4);
|
||||
failf(data, "RETR response: %03d", ftpcode);
|
||||
return CURLE_FTP_COULDNT_RETR_FILE;
|
||||
}
|
||||
}
|
||||
@@ -2160,11 +2165,9 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
||||
static CURLcode ftp_state_loggedin(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
infof(data, "We have successfully logged in\n");
|
||||
|
||||
#ifdef HAVE_KRB4
|
||||
if(data->set.krb4) {
|
||||
if(conn->data->set.krb4) {
|
||||
/* We are logged in, asked to use Kerberos. Set the requested
|
||||
* protection level
|
||||
*/
|
||||
@@ -2276,7 +2279,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
static const char * const ftpauth[] = {
|
||||
"SSL", "TLS"
|
||||
};
|
||||
size_t nread;
|
||||
size_t nread = 0;
|
||||
|
||||
if(ftp->sendleft) {
|
||||
/* we have a piece of a command still left to send */
|
||||
@@ -2373,8 +2376,8 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
*/
|
||||
|
||||
if((ftpcode == 234) || (ftpcode == 334)) {
|
||||
/* Curl_SSLConnect is BLOCKING */
|
||||
result = Curl_SSLConnect(conn, FIRSTSOCKET);
|
||||
/* Curl_ssl_connect is BLOCKING */
|
||||
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||
if(CURLE_OK == result) {
|
||||
conn->protocol |= PROT_FTPS;
|
||||
conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
|
||||
@@ -2487,7 +2490,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
}
|
||||
}
|
||||
state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
|
||||
infof(data, "protocol connect phase DONE\n");
|
||||
DEBUGF(infof(data, "protocol connect phase DONE\n"));
|
||||
break;
|
||||
|
||||
case FTP_QUOTE:
|
||||
@@ -2677,7 +2680,7 @@ static CURLcode ftp_easy_statemach(struct connectdata *conn)
|
||||
|
||||
rc = Curl_select(ftp->sendleft?CURL_SOCKET_BAD:sock, /* reading */
|
||||
ftp->sendleft?sock:CURL_SOCKET_BAD, /* writing */
|
||||
timeout_ms);
|
||||
(int)timeout_ms);
|
||||
|
||||
if(rc == -1) {
|
||||
failf(data, "select error");
|
||||
@@ -2737,8 +2740,8 @@ CURLcode Curl_ftp_connect(struct connectdata *conn,
|
||||
if (conn->bits.tunnel_proxy) {
|
||||
/* BLOCKING */
|
||||
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
||||
result = Curl_ConnectHTTPProxyTunnel(conn, FIRSTSOCKET,
|
||||
conn->host.name, conn->remote_port);
|
||||
result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
|
||||
conn->host.name, conn->remote_port);
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
}
|
||||
@@ -2748,7 +2751,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn,
|
||||
/* BLOCKING */
|
||||
/* FTPS is simply ftp with SSL for the control channel */
|
||||
/* now, perform the SSL initialization for this socket */
|
||||
result = Curl_SSLConnect(conn, FIRSTSOCKET);
|
||||
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@@ -2820,7 +2823,8 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
|
||||
if(data->set.upload) {
|
||||
if((-1 != data->set.infilesize) &&
|
||||
(data->set.infilesize != *ftp->bytecountp) &&
|
||||
!data->set.crlf) {
|
||||
!data->set.crlf &&
|
||||
!ftp->no_transfer) {
|
||||
failf(data, "Uploaded unaligned file size (%" FORMAT_OFF_T
|
||||
" out of %" FORMAT_OFF_T " bytes)",
|
||||
*ftp->bytecountp, data->set.infilesize);
|
||||
@@ -3025,7 +3029,6 @@ static CURLcode ftp_range(struct connectdata *conn)
|
||||
curl_off_t totalsize=-1;
|
||||
char *ptr;
|
||||
char *ptr2;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct FTP *ftp = conn->proto.ftp;
|
||||
|
||||
if(conn->bits.use_range && conn->range) {
|
||||
@@ -3040,26 +3043,29 @@ static CURLcode ftp_range(struct connectdata *conn)
|
||||
if((-1 == to) && (from>=0)) {
|
||||
/* X - */
|
||||
conn->resume_from = from;
|
||||
infof(data, "FTP RANGE %" FORMAT_OFF_T " to end of file\n", from);
|
||||
DEBUGF(infof(conn->data, "FTP RANGE %" FORMAT_OFF_T " to end of file\n",
|
||||
from));
|
||||
}
|
||||
else if(from < 0) {
|
||||
/* -Y */
|
||||
totalsize = -from;
|
||||
conn->maxdownload = -from;
|
||||
conn->resume_from = from;
|
||||
infof(data, "FTP RANGE the last %" FORMAT_OFF_T " bytes\n", totalsize);
|
||||
DEBUGF(infof(conn->data, "FTP RANGE the last %" FORMAT_OFF_T " bytes\n",
|
||||
totalsize));
|
||||
}
|
||||
else {
|
||||
/* X-Y */
|
||||
totalsize = to-from;
|
||||
conn->maxdownload = totalsize+1; /* include the last mentioned byte */
|
||||
conn->resume_from = from;
|
||||
infof(data, "FTP RANGE from %" FORMAT_OFF_T
|
||||
" getting %" FORMAT_OFF_T " bytes\n", from, conn->maxdownload);
|
||||
DEBUGF(infof(conn->data, "FTP RANGE from %" FORMAT_OFF_T
|
||||
" getting %" FORMAT_OFF_T " bytes\n",
|
||||
from, conn->maxdownload));
|
||||
}
|
||||
infof(data, "range-download from %" FORMAT_OFF_T
|
||||
" to %" FORMAT_OFF_T ", totally %" FORMAT_OFF_T " bytes\n",
|
||||
from, to, conn->maxdownload);
|
||||
DEBUGF(infof(conn->data, "range-download from %" FORMAT_OFF_T
|
||||
" to %" FORMAT_OFF_T ", totally %" FORMAT_OFF_T " bytes\n",
|
||||
from, to, conn->maxdownload));
|
||||
ftp->dont_check = TRUE; /* dont check for successful transfer */
|
||||
}
|
||||
return CURLE_OK;
|
||||
@@ -3081,11 +3087,23 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
||||
/* the ftp struct is inited in Curl_ftp_connect() */
|
||||
struct FTP *ftp = conn->proto.ftp;
|
||||
|
||||
infof(data, "DO-MORE phase starts\n");
|
||||
DEBUGF(infof(data, "DO-MORE phase starts\n"));
|
||||
|
||||
if(!ftp->no_transfer && !conn->bits.no_body) {
|
||||
/* a transfer is about to take place */
|
||||
|
||||
if(conn->ssl[SECONDARYSOCKET].use &&
|
||||
!data->set.ftp_use_port) {
|
||||
/* PASV is used and we just got the data connection connected, then
|
||||
it is time to handshake the secure stuff. */
|
||||
|
||||
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
|
||||
/* BLOCKING */
|
||||
result = Curl_ssl_connect(conn, SECONDARYSOCKET);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if(data->set.upload) {
|
||||
NBFTPSENDF(conn, "TYPE %c", data->set.ftp_ascii?'A':'I');
|
||||
state(conn, FTP_STOR_TYPE);
|
||||
@@ -3118,7 +3136,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
||||
result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
|
||||
/* end of transfer */
|
||||
infof(data, "DO-MORE phase ends\n");
|
||||
DEBUGF(infof(data, "DO-MORE phase ends\n"));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -3140,9 +3158,8 @@ CURLcode ftp_perform(struct connectdata *conn,
|
||||
{
|
||||
/* this is FTP and no proxy */
|
||||
CURLcode result=CURLE_OK;
|
||||
struct SessionHandle *data=conn->data;
|
||||
|
||||
infof(data, "DO phase starts\n");
|
||||
DEBUGF(infof(conn->data, "DO phase starts\n"));
|
||||
|
||||
*dophase_done = FALSE; /* not done yet */
|
||||
|
||||
@@ -3161,7 +3178,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
||||
*connected = conn->bits.tcpconnect;
|
||||
|
||||
if(*dophase_done)
|
||||
infof(data, "DO phase is comlete\n");
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -3818,7 +3835,7 @@ CURLcode Curl_ftp_doing(struct connectdata *conn,
|
||||
if(*dophase_done) {
|
||||
result = ftp_dophase_done(conn, FALSE /* not connected */);
|
||||
|
||||
infof(conn->data, "DO phase is comlete\n");
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2005, 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
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include "memory.h"
|
||||
#include "ssluse.h"
|
||||
#include "sslgen.h"
|
||||
|
||||
/* Make this the last #include */
|
||||
#include "memdebug.h"
|
||||
@@ -182,7 +182,10 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
||||
*param_longp = data->info.numconnects;
|
||||
break;
|
||||
case CURLINFO_SSL_ENGINES:
|
||||
*param_slistp = Curl_SSL_engines_list(data);
|
||||
*param_slistp = Curl_ssl_engines_list(data);
|
||||
break;
|
||||
case CURLINFO_COOKIELIST:
|
||||
*param_slistp = Curl_cookie_list(data);
|
||||
break;
|
||||
default:
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
495
lib/gtls.c
Normal file
495
lib/gtls.c
Normal file
@@ -0,0 +1,495 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2005, 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$
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Source file for all GnuTLS-specific code for the TLS/SSL layer. No code
|
||||
* but sslgen.c should ever call or use these functions.
|
||||
*
|
||||
* Note: don't use the GnuTLS' *_t variable type names in this source code,
|
||||
* since they were not present in 1.0.X.
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
#ifdef USE_GNUTLS
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/x509.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "gtls.h"
|
||||
#include "sslgen.h"
|
||||
#include "parsedate.h"
|
||||
#include "connect.h" /* for the connect timeout */
|
||||
#include "select.h"
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
#include "memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Enable GnuTLS debugging by defining GTLSDEBUG */
|
||||
/*#define GTLSDEBUG */
|
||||
|
||||
#ifdef GTLSDEBUG
|
||||
static void tls_log_func(int level, const char *str)
|
||||
{
|
||||
fprintf(stderr, "|<%d>| %s", level, str);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Global GnuTLS init, called from Curl_ssl_init() */
|
||||
int Curl_gtls_init(void)
|
||||
{
|
||||
gnutls_global_init();
|
||||
#ifdef GTLSDEBUG
|
||||
gnutls_global_set_log_function(tls_log_func);
|
||||
gnutls_global_set_log_level(2);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Curl_gtls_cleanup(void)
|
||||
{
|
||||
gnutls_global_deinit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void showtime(struct SessionHandle *data,
|
||||
const char *text,
|
||||
time_t stamp)
|
||||
{
|
||||
struct tm *tm;
|
||||
#ifdef HAVE_GMTIME_R
|
||||
struct tm buffer;
|
||||
tm = (struct tm *)gmtime_r(&stamp, &buffer);
|
||||
#else
|
||||
tm = gmtime(&stamp);
|
||||
#endif
|
||||
snprintf(data->state.buffer,
|
||||
BUFSIZE,
|
||||
"\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT\n",
|
||||
text,
|
||||
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
|
||||
tm->tm_mday,
|
||||
Curl_month[tm->tm_mon],
|
||||
tm->tm_year + 1900,
|
||||
tm->tm_hour,
|
||||
tm->tm_min,
|
||||
tm->tm_sec);
|
||||
infof(data, "%s", data->state.buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called after the TCP connect has completed. Setup the TLS
|
||||
* layer and do all necessary magic.
|
||||
*/
|
||||
CURLcode
|
||||
Curl_gtls_connect(struct connectdata *conn,
|
||||
int sockindex)
|
||||
|
||||
{
|
||||
const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
|
||||
struct SessionHandle *data = conn->data;
|
||||
gnutls_session session;
|
||||
int rc;
|
||||
unsigned int cert_list_size;
|
||||
const gnutls_datum *chainp;
|
||||
unsigned int verify_status;
|
||||
gnutls_x509_crt x509_cert;
|
||||
char certbuf[256]; /* big enough? */
|
||||
size_t size;
|
||||
unsigned int algo;
|
||||
unsigned int bits;
|
||||
time_t clock;
|
||||
const char *ptr;
|
||||
void *ssl_sessionid;
|
||||
size_t ssl_idsize;
|
||||
|
||||
/* GnuTLS only supports TLSv1 (and SSLv3?) */
|
||||
if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
|
||||
failf(data, "GnuTLS does not support SSLv2");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
/* allocate a cred struct */
|
||||
rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
|
||||
if(rc < 0) {
|
||||
failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
if(data->set.ssl.CAfile) {
|
||||
/* set the trusted CA cert bundle file */
|
||||
gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
|
||||
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
|
||||
|
||||
rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
|
||||
data->set.ssl.CAfile,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if(rc < 0)
|
||||
infof(data, "error reading ca cert file %s (%s)\n",
|
||||
data->set.ssl.CAfile, gnutls_strerror(rc));
|
||||
else
|
||||
infof(data, "found %d certificates in %s\n",
|
||||
rc, data->set.ssl.CAfile);
|
||||
}
|
||||
|
||||
/* Initialize TLS session as a client */
|
||||
rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
|
||||
if(rc) {
|
||||
failf(data, "gnutls_init() failed: %d", rc);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
/* convenient assign */
|
||||
session = conn->ssl[sockindex].session;
|
||||
|
||||
/* Use default priorities */
|
||||
rc = gnutls_set_default_priority(session);
|
||||
if(rc < 0)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
/* Sets the priority on the certificate types supported by gnutls. Priority
|
||||
is higher for types specified before others. After specifying the types
|
||||
you want, you must append a 0. */
|
||||
rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
|
||||
if(rc < 0)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
/* put the anonymous credentials to the current session */
|
||||
rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
|
||||
conn->ssl[sockindex].cred);
|
||||
|
||||
/* set the connection handle (file descriptor for the socket) */
|
||||
gnutls_transport_set_ptr(session,
|
||||
(gnutls_transport_ptr)conn->sock[sockindex]);
|
||||
|
||||
/* This might be a reconnect, so we check for a session ID in the cache
|
||||
to speed up things */
|
||||
|
||||
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
|
||||
/* we got a session id, use it! */
|
||||
gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
|
||||
|
||||
/* Informational message */
|
||||
infof (data, "SSL re-using session ID\n");
|
||||
}
|
||||
|
||||
do {
|
||||
rc = gnutls_handshake(session);
|
||||
|
||||
if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
|
||||
long timeout_ms;
|
||||
long has_passed;
|
||||
|
||||
if(data->set.timeout || data->set.connecttimeout) {
|
||||
/* get the most strict timeout of the ones converted to milliseconds */
|
||||
if(data->set.timeout &&
|
||||
(data->set.timeout>data->set.connecttimeout))
|
||||
timeout_ms = data->set.timeout*1000;
|
||||
else
|
||||
timeout_ms = data->set.connecttimeout*1000;
|
||||
}
|
||||
else
|
||||
timeout_ms = DEFAULT_CONNECT_TIMEOUT;
|
||||
|
||||
/* Evaluate in milliseconds how much time that has passed */
|
||||
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
|
||||
|
||||
/* subtract the passed time */
|
||||
timeout_ms -= has_passed;
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* a precaution, no need to continue if time already is up */
|
||||
failf(data, "SSL connection timeout");
|
||||
return CURLE_OPERATION_TIMEOUTED;
|
||||
}
|
||||
|
||||
rc = Curl_select(conn->sock[sockindex],
|
||||
conn->sock[sockindex], (int)timeout_ms);
|
||||
if(rc > 0)
|
||||
/* reabable or writable, go loop*/
|
||||
continue;
|
||||
else if(0 == rc) {
|
||||
/* timeout */
|
||||
failf(data, "SSL connection timeout");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
else {
|
||||
/* anything that gets here is fatally bad */
|
||||
failf(data, "select on SSL socket, errno: %d", Curl_ourerrno());
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
} while(1);
|
||||
|
||||
if (rc < 0) {
|
||||
failf(data, "gnutls_handshake() failed: %d", rc);
|
||||
/* gnutls_perror(ret); */
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
/* This function will return the peer's raw certificate (chain) as sent by
|
||||
the peer. These certificates are in raw format (DER encoded for
|
||||
X.509). In case of a X.509 then a certificate list may be present. The
|
||||
first certificate in the list is the peer's certificate, following the
|
||||
issuer's certificate, then the issuer's issuer etc. */
|
||||
|
||||
chainp = gnutls_certificate_get_peers(session, &cert_list_size);
|
||||
if(!chainp) {
|
||||
if(data->set.ssl.verifyhost) {
|
||||
failf(data, "failed to get server cert");
|
||||
return CURLE_SSL_PEER_CERTIFICATE;
|
||||
}
|
||||
infof(data, "\t common name: WARNING couldn't obtain\n");
|
||||
}
|
||||
|
||||
/* This function will try to verify the peer's certificate and return its
|
||||
status (trusted, invalid etc.). The value of status should be one or more
|
||||
of the gnutls_certificate_status_t enumerated elements bitwise or'd. To
|
||||
avoid denial of service attacks some default upper limits regarding the
|
||||
certificate key size and chain size are set. To override them use
|
||||
gnutls_certificate_set_verify_limits(). */
|
||||
|
||||
rc = gnutls_certificate_verify_peers2(session, &verify_status);
|
||||
if (rc < 0) {
|
||||
failf(data, "server cert verify failed: %d", rc);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
/* verify_status is a bitmask of gnutls_certificate_status bits */
|
||||
if(verify_status & GNUTLS_CERT_INVALID) {
|
||||
if (data->set.ssl.verifypeer) {
|
||||
failf(data, "server certificate verification failed. CAfile: %s",
|
||||
data->set.ssl.CAfile?data->set.ssl.CAfile:"none");
|
||||
return CURLE_SSL_CACERT;
|
||||
}
|
||||
else
|
||||
infof(data, "\t server certificate verification FAILED\n");
|
||||
}
|
||||
else
|
||||
infof(data, "\t server certificate verification OK\n");
|
||||
|
||||
/* initialize an X.509 certificate structure. */
|
||||
gnutls_x509_crt_init(&x509_cert);
|
||||
|
||||
/* convert the given DER or PEM encoded Certificate to the native
|
||||
gnutls_x509_crt_t format */
|
||||
gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
|
||||
|
||||
size=sizeof(certbuf);
|
||||
rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
|
||||
0, /* the first and only one */
|
||||
FALSE,
|
||||
certbuf,
|
||||
&size);
|
||||
if(rc) {
|
||||
infof(data, "error fetching CN from cert:%s\n",
|
||||
gnutls_strerror(rc));
|
||||
}
|
||||
|
||||
/* This function will check if the given certificate's subject matches the
|
||||
given hostname. This is a basic implementation of the matching described
|
||||
in RFC2818 (HTTPS), which takes into account wildcards, and the subject
|
||||
alternative name PKIX extension. Returns non zero on success, and zero on
|
||||
failure. */
|
||||
rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
|
||||
|
||||
if(!rc) {
|
||||
if (data->set.ssl.verifyhost > 1) {
|
||||
failf(data, "SSL: certificate subject name (%s) does not match "
|
||||
"target host name '%s'", certbuf, conn->host.dispname);
|
||||
gnutls_x509_crt_deinit(x509_cert);
|
||||
return CURLE_SSL_PEER_CERTIFICATE;
|
||||
}
|
||||
else
|
||||
infof(data, "\t common name: %s (does not match '%s')\n",
|
||||
certbuf, conn->host.dispname);
|
||||
}
|
||||
else
|
||||
infof(data, "\t common name: %s (matched)\n", certbuf);
|
||||
|
||||
/* Show:
|
||||
|
||||
- ciphers used
|
||||
- subject
|
||||
- start date
|
||||
- expire date
|
||||
- common name
|
||||
- issuer
|
||||
|
||||
*/
|
||||
|
||||
/* public key algorithm's parameters */
|
||||
algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
|
||||
infof(data, "\t certificate public key: %s\n",
|
||||
gnutls_pk_algorithm_get_name(algo));
|
||||
|
||||
/* version of the X.509 certificate. */
|
||||
infof(data, "\t certificate version: #%d\n",
|
||||
gnutls_x509_crt_get_version(x509_cert));
|
||||
|
||||
|
||||
size = sizeof(certbuf);
|
||||
gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
|
||||
infof(data, "\t subject: %s\n", certbuf);
|
||||
|
||||
clock = gnutls_x509_crt_get_activation_time(x509_cert);
|
||||
showtime(data, "start date", clock);
|
||||
|
||||
clock = gnutls_x509_crt_get_expiration_time(x509_cert);
|
||||
showtime(data, "expire date", clock);
|
||||
|
||||
size = sizeof(certbuf);
|
||||
gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
|
||||
infof(data, "\t issuer: %s\n", certbuf);
|
||||
|
||||
gnutls_x509_crt_deinit(x509_cert);
|
||||
|
||||
/* compression algorithm (if any) */
|
||||
ptr = gnutls_compression_get_name(gnutls_compression_get(session));
|
||||
/* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
|
||||
infof(data, "\t compression: %s\n", ptr);
|
||||
|
||||
/* the name of the cipher used. ie 3DES. */
|
||||
ptr = gnutls_cipher_get_name(gnutls_cipher_get(session));
|
||||
infof(data, "\t cipher: %s\n", ptr);
|
||||
|
||||
/* the MAC algorithms name. ie SHA1 */
|
||||
ptr = gnutls_mac_get_name(gnutls_mac_get(session));
|
||||
infof(data, "\t MAC: %s\n", ptr);
|
||||
|
||||
if(!ssl_sessionid) {
|
||||
/* this session was not previously in the cache, add it now */
|
||||
|
||||
/* get the session ID data size */
|
||||
gnutls_session_get_data(session, NULL, &ssl_idsize);
|
||||
ssl_sessionid = malloc(ssl_idsize); /* get a buffer for it */
|
||||
|
||||
if(ssl_sessionid) {
|
||||
/* extract session ID to the allocated buffer */
|
||||
gnutls_session_get_data(session, ssl_sessionid, &ssl_idsize);
|
||||
|
||||
/* store this session id */
|
||||
return Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_idsize);
|
||||
}
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* return number of sent (non-SSL) bytes */
|
||||
int Curl_gtls_send(struct connectdata *conn,
|
||||
int sockindex,
|
||||
void *mem,
|
||||
size_t len)
|
||||
{
|
||||
int rc;
|
||||
rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void Curl_gtls_close_all(struct SessionHandle *data)
|
||||
{
|
||||
/* FIX: make the OpenSSL code more generic and use parts of it here */
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static void close_one(struct connectdata *conn,
|
||||
int index)
|
||||
{
|
||||
if(conn->ssl[index].session) {
|
||||
gnutls_bye(conn->ssl[index].session, GNUTLS_SHUT_RDWR);
|
||||
gnutls_deinit(conn->ssl[index].session);
|
||||
}
|
||||
gnutls_certificate_free_credentials(conn->ssl[index].cred);
|
||||
}
|
||||
|
||||
void Curl_gtls_close(struct connectdata *conn)
|
||||
{
|
||||
if(conn->ssl[0].use)
|
||||
close_one(conn, 0);
|
||||
if(conn->ssl[1].use)
|
||||
close_one(conn, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the read would block we return -1 and set 'wouldblock' to TRUE.
|
||||
* Otherwise we return the amount of data read. Other errors should return -1
|
||||
* and set 'wouldblock' to FALSE.
|
||||
*/
|
||||
ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
|
||||
int num, /* socketindex */
|
||||
char *buf, /* store read data here */
|
||||
size_t buffersize, /* max amount to read */
|
||||
bool *wouldblock)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
|
||||
if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
|
||||
*wouldblock = TRUE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*wouldblock = FALSE;
|
||||
if (!ret) {
|
||||
failf(conn->data, "Peer closed the TLS connection");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
failf(conn->data, "GnuTLS recv error (%d): %s",
|
||||
(int)ret, gnutls_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Curl_gtls_session_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
size_t Curl_gtls_version(char *buffer, size_t size)
|
||||
{
|
||||
return snprintf(buffer, size, " GnuTLS/%s", gnutls_check_version(NULL));
|
||||
}
|
||||
|
||||
#endif /* USE_GNUTLS */
|
45
lib/gtls.h
Normal file
45
lib/gtls.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef __GTLS_H
|
||||
#define __GTLS_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2005, 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$
|
||||
***************************************************************************/
|
||||
int Curl_gtls_init(void);
|
||||
int Curl_gtls_cleanup(void);
|
||||
CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex);
|
||||
|
||||
/* tell GnuTLS to close down all open information regarding connections (and
|
||||
thus session ID caching etc) */
|
||||
void Curl_gtls_close_all(struct SessionHandle *data);
|
||||
void Curl_gtls_close(struct connectdata *conn); /* close a SSL connection */
|
||||
|
||||
/* return number of sent (non-SSL) bytes */
|
||||
int Curl_gtls_send(struct connectdata *conn, int sockindex,
|
||||
void *mem, size_t len);
|
||||
ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
|
||||
int num, /* socketindex */
|
||||
char *buf, /* store read data here */
|
||||
size_t buffersize, /* max amount to read */
|
||||
bool *wouldblock);
|
||||
void Curl_gtls_session_free(void *ptr);
|
||||
size_t Curl_gtls_version(char *buffer, size_t size);
|
||||
|
||||
#endif
|
@@ -26,8 +26,6 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define _REENTRANT
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
|
@@ -26,8 +26,6 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define _REENTRANT
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
|
@@ -26,8 +26,6 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define _REENTRANT
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
|
@@ -26,8 +26,6 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define _REENTRANT
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
@@ -174,9 +172,8 @@ Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname, int port)
|
||||
/*
|
||||
* 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.
|
||||
* The original code to this function was 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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user