Compare commits
295 Commits
curl-7_14_
...
curl-7_15_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
96cec4dfd7 | ||
![]() |
943aea6267 | ||
![]() |
b433e4a1e7 | ||
![]() |
20f1966c0e | ||
![]() |
ab1f5c3edd | ||
![]() |
b2be6799f2 | ||
![]() |
ea2618fc6f | ||
![]() |
62fdf8eaed | ||
![]() |
d3569a3572 | ||
![]() |
89df76e449 | ||
![]() |
e5b2f33b4f | ||
![]() |
934d312f50 | ||
![]() |
68917eb517 | ||
![]() |
3beb2f6b5d | ||
![]() |
b29017f15b | ||
![]() |
db83a0ebbc | ||
![]() |
6d9fddb95d | ||
![]() |
4284190cc4 | ||
![]() |
5e4cbd2d24 | ||
![]() |
06c3bec65d | ||
![]() |
e8c3bb45ba | ||
![]() |
4ec55a964d | ||
![]() |
b9420864c0 | ||
![]() |
bf6588b6a7 | ||
![]() |
e43217e664 | ||
![]() |
e19ee2d102 | ||
![]() |
b4c53e2cfd | ||
![]() |
a2902de67c | ||
![]() |
da192f7955 | ||
![]() |
a2210d23c3 | ||
![]() |
bd5a622400 | ||
![]() |
b9494cb0d6 | ||
![]() |
0f73af4470 | ||
![]() |
45e26b5c02 | ||
![]() |
6af5ea38ce | ||
![]() |
b6f0aa4394 | ||
![]() |
774dab58f6 | ||
![]() |
e3bdb98f7a | ||
![]() |
58d628c9f8 | ||
![]() |
1e69394545 | ||
![]() |
1cf798ad14 | ||
![]() |
da3992d2e9 | ||
![]() |
48908e4633 | ||
![]() |
f5ae149338 | ||
![]() |
3fe5311967 | ||
![]() |
6a48639c68 | ||
![]() |
e7093b3ca8 | ||
![]() |
d0a4104c0c | ||
![]() |
90559bed53 | ||
![]() |
973a18cf03 | ||
![]() |
3c666ce57a | ||
![]() |
a1287ec64f | ||
![]() |
5fbfa1bfa8 | ||
![]() |
da3ecc91f8 | ||
![]() |
09c8f558f7 | ||
![]() |
528a149def | ||
![]() |
29e36afb6b | ||
![]() |
0e39543d35 | ||
![]() |
0de20d8ee6 | ||
![]() |
cd5de5c0e5 | ||
![]() |
bd5afc26bd | ||
![]() |
9542dfdcdc | ||
![]() |
97a6d7b1a8 | ||
![]() |
209b9d4374 | ||
![]() |
0b8ccd0ae7 | ||
![]() |
0b7f5ad508 | ||
![]() |
8a38805e82 | ||
![]() |
836d88a4b8 | ||
![]() |
d5268ed511 | ||
![]() |
0e7d93858d | ||
![]() |
2164d760b7 | ||
![]() |
b9c8de598b | ||
![]() |
9889a811db | ||
![]() |
9e38d882b9 | ||
![]() |
e8635044b5 | ||
![]() |
56dea0ac9a | ||
![]() |
e8b77477c7 | ||
![]() |
64298e528d | ||
![]() |
4f1465e7c7 | ||
![]() |
6120041b69 | ||
![]() |
8c1213627d | ||
![]() |
3e6ae6eeb8 | ||
![]() |
291e9aeabd | ||
![]() |
a3d776187a | ||
![]() |
e55f502e2f | ||
![]() |
e369270f88 | ||
![]() |
7e845e7cfd | ||
![]() |
56d9624b56 | ||
![]() |
911d135deb | ||
![]() |
8107b90678 | ||
![]() |
7722452b98 | ||
![]() |
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 |
344
CHANGES
344
CHANGES
@@ -7,6 +7,345 @@
|
||||
Changelog
|
||||
|
||||
|
||||
|
||||
Version 7.15.0 (13 October 2005)
|
||||
|
||||
Daniel (12 October 2005)
|
||||
- Michael Sutton of iDEFENSE reported and I fixed a securitfy flaw in the NTLM
|
||||
code that would overflow a buffer if given a too long user name or domain
|
||||
name. This would happen if you enable NTLM authentication and either
|
||||
|
||||
A - pass in a user name and domain name to libcurl that together are longer
|
||||
than 192 bytes
|
||||
|
||||
B - allow (lib)curl to follow HTTP "redirects" (Location: and the
|
||||
appropriate HTTP 30x response code) and the new URL contains a URL with
|
||||
a user name and domain name that together are longer than 192 bytes
|
||||
|
||||
See http://curl.haxx.se/docs/security.html for further details and updates
|
||||
|
||||
Daniel (5 October 2005)
|
||||
- Darryl House reported a problem with using -z to download files from FTP.
|
||||
It turned out that if the given time stamp was exact the same as the remote
|
||||
time stamp, the file would still wrongly be downloaded. Added test case 272
|
||||
to verify.
|
||||
|
||||
Daniel (4 October 2005)
|
||||
- Domenico Andreoli fixed a man page malformat and removed odd (0xa0) bytes
|
||||
from the configure script.
|
||||
|
||||
- Michael Wallner reported that the date parser had wrong offset stored for
|
||||
the MEST and CEST time zones.
|
||||
|
||||
Daniel (27 September 2005)
|
||||
- David Yan filed bug #1299181 (http://curl.haxx.se/bug/view.cgi?id=1299181)
|
||||
that identified a silly problem with Content-Range: headers with the 'bytes'
|
||||
keyword written in a different case than all lowercase! It would cause a
|
||||
segfault!
|
||||
|
||||
- TJ Saunders of the proftpd project identified and pointed out problems with
|
||||
the modified FTPS negotiation change of August 19 2005. Thus, we revert the
|
||||
change back to pre-7.14.1 status.
|
||||
|
||||
Daniel (21 September 2005)
|
||||
- Fixed "cut off" sentence in the libcurl-tutorial man page:
|
||||
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=329305
|
||||
|
||||
- Clarified in the curl_easy_setopt man page what the default
|
||||
CURLOPT_WRITEFUNCTION and CURLOPT_WRITEDATA mean:
|
||||
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=329311
|
||||
|
||||
- Clarified in the curl_easy_setopt man page that CURLOPT_ERRORBUFFER
|
||||
sometimes doesn't fill in the buffer even though it is supposed to:
|
||||
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=329313
|
||||
|
||||
- When CURLE_URL_MALFORMAT is returned due to a missing URL, it now has an
|
||||
error string set.
|
||||
|
||||
Daniel (19 September 2005)
|
||||
- Dmitry Bartsevich made the SSPI support work on Windows 9x as well.
|
||||
|
||||
Daniel (15 September 2005)
|
||||
- Added a TFTP server to the test suite and made the test suite capable of
|
||||
using it.
|
||||
|
||||
Daniel (7 September 2005)
|
||||
- Ben Madsen's detailed reports that funnily enough only occurred with certain
|
||||
glibc versions turned out to be curl using an already closed file handle
|
||||
during certain conditions (like when saving FTP server "headers").
|
||||
|
||||
- Scott Davis helped me track down a problem in the test HTTP server that made
|
||||
test case 56 wrongly fail at times. It turned out it was due to the server
|
||||
finding the end of a chunked-encoded POST too early.
|
||||
|
||||
Daniel (6 September 2005)
|
||||
- Now curl warns if an unknown variable is used in the -w/--writeout argument.
|
||||
|
||||
Daniel (4 September 2005)
|
||||
- I applied Nicolas Fran<61>ois' man page patch he posted to the Debian bug
|
||||
tracker. It corrected two lines that started with apostrophes, which isn't
|
||||
legal nroff format. http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=326511
|
||||
|
||||
- Added --ftp-skip-pasv-ip to the command line tool, that sets the new
|
||||
CURLOPT_FTP_SKIP_PASV_IP option. It makes libcurl re-use the control
|
||||
connection's IP address when setting up the data connection instead of
|
||||
extractting the IP address from the PASV response. It has turned out this
|
||||
feature is frequently needed by people to circumvent silly servers and silly
|
||||
firewalls, especially when FTPS is used and the PASV command-response is
|
||||
sent encrtyped.
|
||||
|
||||
Sponsored by CU*Answers
|
||||
|
||||
Daniel (1 September 2005)
|
||||
- John Kelly added TFTP support to libcurl. A bunch of new error codes was
|
||||
added. TODO: add them to docs. add TFTP server to test suite. add TFTP to
|
||||
list of protocols whereever those are mentioned.
|
||||
|
||||
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
|
||||
(http://curl.haxx.se/bug/view.cgi?id=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
|
||||
(http://curl.haxx.se/bug/view.cgi?id=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
|
||||
(http://curl.haxx.se/bug/view.cgi?id=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: http://curl.haxx.se/bug/view.cgi?id=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. http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=310948
|
||||
|
||||
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
|
||||
(http://curl.haxx.se/bug/view.cgi?id=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)
|
||||
@@ -19,8 +358,9 @@ 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.
|
||||
for host auth, which defaults to Basic). Bug report #1200661
|
||||
(http://curl.haxx.se/bug/view.cgi?id=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
|
||||
|
@@ -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,58 +1,46 @@
|
||||
Curl and libcurl 7.14.0
|
||||
Curl and libcurl 7.15.0
|
||||
|
||||
Public curl release number: 88
|
||||
Releases counted from the very beginning: 115
|
||||
Available command line options: 107
|
||||
Available curl_easy_setopt() options: 122
|
||||
Public curl release number: 90
|
||||
Releases counted from the very beginning: 117
|
||||
Available command line options: 109
|
||||
Available curl_easy_setopt() options: 124
|
||||
Number of public functions in libcurl: 46
|
||||
Amount of public web site mirrors: 23
|
||||
Number of known libcurl bindings: 31
|
||||
Number of contributors: 437
|
||||
Amount of public web site mirrors: 24
|
||||
Number of known libcurl bindings: 32
|
||||
Number of contributors: 451
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o modified default HTTP request headers
|
||||
o curl --trace-time added for time stamping trace logs
|
||||
o curl now respects the SSL_CERT_DIR and SSL_CERT_PATH environment variables
|
||||
o more search paths for curl's default .curlrc config file check
|
||||
o GnuTLS support, use configure --with-gnutls. Work on this was sponsored
|
||||
by The Written Word.
|
||||
o --ftp-skip-pasv-ip / CURLOPT_FTP_SKIP_PASV_IP (sponsored by CU*Answers)
|
||||
o TFTP support added
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o uses select() instead of poll() even on Mac OS X 10.4
|
||||
o reconnected proxy use with NTLM auth on the same handle
|
||||
o warns about bad -z date syntax
|
||||
o docs/THANKS now contains all known contributors
|
||||
o builds out-of-the-box on (presumably ipv6-enabled) AIX 4.3 hosts
|
||||
o curl --head could wrongly complain on bad chunked-encoding
|
||||
o --interface SIGSEGVed on a bad address
|
||||
o kill the HTTPS server better when stopping the test suite
|
||||
o builds fine with VS2005 on x64
|
||||
o auth fix for HTTP redirects and .netrc usage
|
||||
o FTP uploads show the progress meter easier
|
||||
o MSVC makefile fixes for static libcurl builds
|
||||
o configure fix for static libcurl build on Windows
|
||||
o --retry-delay
|
||||
o POST with read callback now uses Expect: 100-continue
|
||||
o CURLOPT_PORT didn't actually use the set port number
|
||||
o HTTP 304 response with Content-Length: header
|
||||
o time-conditioned FTP uploads
|
||||
o user+domain name buffer overflow in the NTLM code (security flaw)
|
||||
o -z over FTP now considers equal timestamps "not modified since"
|
||||
o Weird characters removed from the configure script
|
||||
o Fixed time zone offsets for MEST and CEST for the time parser
|
||||
o HTTP Content-Range header parser crash
|
||||
o FTPS negotiation timeouts/errors
|
||||
o SSPI works even for Windows 9x
|
||||
o crash in --dump-header on FTP
|
||||
o test 56 runs better
|
||||
|
||||
Other curl-related news since the previous public release:
|
||||
|
||||
o http://curl.mirroring.de/ is a new german curl mirror
|
||||
o pycurl 7.13.2: http://pycurl.sf.net/
|
||||
o TclCurl 0.13.2: http://personal1.iddeo.es/andresgarci/tclcurl/english/
|
||||
o http://curl.webhosting76.com/ is a new US curl mirror
|
||||
o http://curl.meulie.net/ is a new Canadian curl mirror
|
||||
o http://curl.freemirror.de/ is a new German mirror
|
||||
o All curl relatd mailing list information and subscribers on cool.haxx.se
|
||||
were lost due to a malicious user exploiting a security hole on the
|
||||
server. Attempts have been made to put back susbcribers on the lists, but
|
||||
many have been lost: http://curl.haxx.se/mail/lost.html
|
||||
o New S-Lang binding: http://curl.haxx.se/libcurl/slang/
|
||||
o TclCurl 0.14.1: http://personal1.iddeo.es/andresgarci/tclcurl/english/
|
||||
o pycurl 7.14.1: http://pycurl.sf.net/
|
||||
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Christophe Legry, Cory Nelson, Gisle Vanem, Dan Fandrich, Toshiyuki Maezawa,
|
||||
Olivier, Andres Garcia, Dave Dribin, Alex Suykov, Cory Nelson, Fred New,
|
||||
Paul Moore, Alexander Zhuravlev, Bryan Henderson, Jeremy Brown, Allan,
|
||||
Grigory Entin
|
||||
o John Kelly, Nicolas Fran<61>ois, Scott Davis, Ben Madsen, Dmitry Bartsevich,
|
||||
David Yan, Michael Wallner, Domenico Andreoli, Darryl House
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
39
TODO-RELEASE
39
TODO-RELEASE
@@ -1,40 +1,7 @@
|
||||
Issues not sorted in any particular order.
|
||||
|
||||
To get fixed in 7.14.0 (planned release: May/June 2005)
|
||||
To get fixed in 7.15.0 (planned release: November 2005)
|
||||
======================
|
||||
|
||||
- Make the tests run better on more platforms.
|
||||
60 - CONNECT 407 responses that kills the connection (not very likely though)
|
||||
|
||||
To get fixed in 7.14.1 (planned release: June 2005)
|
||||
======================
|
||||
63 -
|
||||
|
||||
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.15.0
|
||||
======================
|
||||
|
||||
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.
|
||||
|
||||
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).
|
||||
|
||||
To get fixed in 7.16.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 -
|
||||
|
59
acinclude.m4
59
acinclude.m4
@@ -192,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], ,[
|
||||
@@ -417,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])
|
||||
@@ -466,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
|
||||
@@ -756,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
|
||||
|
48
ares/CHANGES
48
ares/CHANGES
@@ -1,5 +1,53 @@
|
||||
Changelog for the c-ares project
|
||||
|
||||
* September 18
|
||||
|
||||
- Added constants that will be used by ares_getaddrinfo
|
||||
|
||||
- Made ares_getnameinfo use the reentrant getservbyport (getservbyport_r) if it is
|
||||
available to ensure it works properly in a threaded environment.
|
||||
|
||||
* September 10
|
||||
|
||||
- configure fix for detecting a member in the sockaddr_in6 struct which failed
|
||||
on ipv6-enabled HP-UX 11.00
|
||||
|
||||
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.
|
||||
|
@@ -15,7 +15,7 @@ EXTRA_DIST = CHANGES README.cares Makefile.inc adig.c ahost.c $(man_MANS) \
|
||||
$(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,17 +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 inet_net_pton.c bitncmp.c inet_ntop.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 \
|
||||
inet_net_pton.h ares_ipv6.h bitncmp.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
|
||||
@@ -304,6 +304,8 @@ config.h: Makefile.netware
|
||||
@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
|
||||
|
@@ -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
|
||||
@@ -146,3 +269,50 @@ AC_DEFUN([CARES_CHECK_CONSTANT], [
|
||||
])
|
||||
|
||||
|
||||
dnl This macro determines how many parameters getservbyport_r takes
|
||||
AC_DEFUN([CARES_CHECK_GETSERVBYPORT_R], [
|
||||
AC_MSG_CHECKING([how many arguments getservbyport_r takes])
|
||||
AC_TRY_COMPILE(
|
||||
[#include <netdb.h>],
|
||||
[
|
||||
int p1, p5;
|
||||
char *p2, p4[4096];
|
||||
struct servent *p3, *p6;
|
||||
getservbyport_r(p1, p2, p3, p4, p5, &p6);
|
||||
], ac_func_getservbyport_r=6,
|
||||
[AC_TRY_COMPILE(
|
||||
[#include <netdb.h>],
|
||||
[
|
||||
int p1, p5;
|
||||
char *p2, p4[4096];
|
||||
struct servent *p3;
|
||||
getservbyport_r(p1, p2, p3, p4, p5);
|
||||
], ac_func_getservbyport_r=5,
|
||||
[AC_TRY_COMPILE(
|
||||
[#include <netdb.h>],
|
||||
[
|
||||
int p1;
|
||||
char *p2;
|
||||
struct servent *p3;
|
||||
struct servent_data p4;
|
||||
getservbyport_r(p1, p2, p3, &p4);
|
||||
], ac_func_getservbyport_r=4, ac_func_getservbyport_r=0
|
||||
)]
|
||||
)]
|
||||
)
|
||||
if test $ac_func_getservbyport_r != "0" ; then
|
||||
AC_MSG_RESULT($ac_func_getservbyport_r)
|
||||
AC_DEFINE(HAVE_GETSERVBYPORT_R, 1, [Specifies whether getservbyport_r is present])
|
||||
AC_DEFINE_UNQUOTED(GETSERVBYPORT_R_ARGS, $ac_func_getservbyport_r, [Specifies the number of arguments to
|
||||
getservbyport_r])
|
||||
if test $ac_func_getservbyport_r = "4" ; then
|
||||
AC_DEFINE(GETSERVBYPORT_R_BUFSIZE, sizeof(struct servent_data), [Specifies the size of the buffer to pass to
|
||||
getservbyport_r])
|
||||
else
|
||||
AC_DEFINE(GETSERVBYPORT_R_BUFSIZE, 4096, [Specifies the size of the buffer to pass to getservbyport_r])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([not found])
|
||||
fi
|
||||
])
|
||||
|
||||
|
52
ares/ares.h
52
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,13 @@ extern "C" {
|
||||
#define ARES_EDESTRUCTION 16
|
||||
#define ARES_EBADSTR 17
|
||||
|
||||
/* ares_getnameinfo error codes */
|
||||
#define ARES_EBADFLAGS 18
|
||||
|
||||
/* ares_getaddrinfo error codes */
|
||||
#define ARES_ENONAME 19
|
||||
#define ARES_EBADHINTS 20
|
||||
|
||||
/* Flag values */
|
||||
#define ARES_FLAG_USEVC (1 << 0)
|
||||
#define ARES_FLAG_PRIMARY (1 << 1)
|
||||
@@ -85,6 +94,42 @@ 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_IDN_ALLOW_UNASSIGNED (1 << 11)
|
||||
#define ARES_NI_IDN_USE_STD3_ASCII_RULES (1 << 12)
|
||||
|
||||
/* Addrinfo flag values */
|
||||
#define ARES_AI_CANONNAME (1 << 0)
|
||||
#define ARES_AI_NUMERICHOST (1 << 1)
|
||||
#define ARES_AI_PASSIVE (1 << 2)
|
||||
#define ARES_AI_NUMERICSERV (1 << 3)
|
||||
#define ARES_AI_V4MAPPED (1 << 4)
|
||||
#define ARES_AI_ALL (1 << 5)
|
||||
#define ARES_AI_ADDRCONFIG (1 << 6)
|
||||
/* Reserved for future use */
|
||||
#define ARES_AI_IDN (1 << 10)
|
||||
#define ARES_AI_IDN_ALLOW_UNASSIGNED (1 << 11)
|
||||
#define ARES_AI_IDN_USE_STD3_ASCII_RULES (1 << 12)
|
||||
#define ARES_AI_CANONIDN (1 << 13)
|
||||
|
||||
#define ARES_AI_MASK (ARES_AI_CANONNAME|ARES_AI_NUMERICHOST|ARES_AI_PASSIVE| \
|
||||
ARES_AI_NUMERICSERV|ARES_AI_V4MAPPED|ARES_AI_ALL| \
|
||||
ARES_AI_ADDRCONFIG)
|
||||
|
||||
struct ares_options {
|
||||
int flags;
|
||||
int timeout;
|
||||
@@ -101,12 +146,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 +171,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);
|
||||
|
@@ -106,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
|
||||
|
@@ -107,7 +107,7 @@ static void next_lookup(struct addr_query *aquery)
|
||||
switch (*p)
|
||||
{
|
||||
case 'b':
|
||||
if (aquery->family == AF_INET)
|
||||
if (aquery->family == AF_INET)
|
||||
{
|
||||
addr = ntohl(aquery->addr.addr4.s_addr);
|
||||
a1 = (int)((addr >> 24) & 0xff);
|
||||
|
@@ -124,10 +124,10 @@ static void next_lookup(struct host_query *hquery)
|
||||
case 'b':
|
||||
/* DNS lookup */
|
||||
hquery->remaining_lookups = p + 1;
|
||||
if (hquery->family == AF_INET6)
|
||||
ares_search(hquery->channel, hquery->name, C_IN, T_AAAA, host_callback,
|
||||
hquery);
|
||||
else
|
||||
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;
|
||||
|
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.
|
373
ares/ares_getnameinfo.c
Normal file
373
ares/ares_getnameinfo.c
Normal file
@@ -0,0 +1,373 @@
|
||||
/* 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) /* 33 bytes buffer */
|
||||
{
|
||||
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 GETSERVBYPORT_R_ARGS == 6
|
||||
struct servent ret;
|
||||
char buf[4096];
|
||||
int len = 4096;
|
||||
#elif GETSERVBYPORT_R_ARGS == 5
|
||||
char buf[4096];
|
||||
int len = 4096;
|
||||
#elif GETSERVBYPORT_R_ARGS == 4
|
||||
struct servent ret;
|
||||
struct servent_data sed;
|
||||
#endif
|
||||
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";
|
||||
#ifdef HAVE_GETSERVBYPORT_R
|
||||
#if GETSERVBYPORT_R_ARGS == 6
|
||||
se = &ret;
|
||||
if (getservbyport_r(port, proto, se, buf, len, &ret))
|
||||
se = NULL;
|
||||
#elif GETSERVBYPORT_R_ARGS == 5
|
||||
se = getservbyport_r(port, proto, se, buf, len);
|
||||
#elif GETSERVBYPORT_R_ARGS == 4
|
||||
se = &ret;
|
||||
if (getservbyport_r(port, proto, se, &sed) == -1)
|
||||
se = NULL;
|
||||
#else
|
||||
/* Lets just hope the OS uses TLS! */
|
||||
se = getservbyport(port, proto);
|
||||
#endif
|
||||
#else
|
||||
/* Lets just hope the OS uses TLS! */
|
||||
se = getservbyport(port, proto);
|
||||
#endif
|
||||
if (se && se->s_name) {
|
||||
size_t len = strlen(se->s_name);
|
||||
if(len < 33) {
|
||||
strcpy(buf, se->s_name);
|
||||
}
|
||||
else
|
||||
/* too big name to fit the buffer */
|
||||
buf[0]=0;
|
||||
}
|
||||
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;
|
||||
}
|
@@ -327,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);
|
||||
@@ -339,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);
|
||||
@@ -858,7 +860,8 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||
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,
|
||||
if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx ? ipbufpfx : ipbuf,
|
||||
&pat.addr.addr6,
|
||||
sizeof(pat.addr.addr6))) > 0)
|
||||
{
|
||||
pat.type = PATTERN_CIDR;
|
||||
@@ -890,7 +893,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||
else
|
||||
natural_mask(&pat);
|
||||
pat.family = AF_INET;
|
||||
pat.type = PATTERN_MASK;
|
||||
pat.type = PATTERN_MASK;
|
||||
if (!sortlist_alloc(sortlist, nsort, &pat))
|
||||
return ARES_ENOMEM;
|
||||
}
|
||||
@@ -1011,7 +1014,8 @@ 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 sortlist_alloc(struct apattern **sortlist, int *nsort,
|
||||
struct apattern *pat)
|
||||
{
|
||||
struct apattern *newsort;
|
||||
newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
|
||||
|
@@ -28,6 +28,31 @@ struct in6_addr
|
||||
};
|
||||
#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 */
|
||||
@@ -45,4 +70,12 @@ struct in6_addr
|
||||
#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 */
|
||||
|
@@ -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
|
||||
|
@@ -33,6 +33,12 @@
|
||||
#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>
|
||||
@@ -45,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
|
||||
@@ -466,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;
|
||||
|
||||
@@ -482,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));
|
||||
@@ -531,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;
|
||||
|
@@ -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)));
|
||||
|
@@ -65,8 +65,11 @@ AC_CHECK_HEADERS(
|
||||
sys/time.h \
|
||||
sys/select.h \
|
||||
sys/socket.h \
|
||||
sys/ioctl.h \
|
||||
netdb.h \
|
||||
winsock.h \
|
||||
netinet/in.h \
|
||||
net/if.h \
|
||||
arpa/nameser.h \
|
||||
arpa/nameser_compat.h \
|
||||
arpa/inet.h, , ,
|
||||
@@ -80,9 +83,31 @@ 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(
|
||||
[
|
||||
@@ -134,6 +159,62 @@ 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
|
||||
)
|
||||
|
||||
AC_CHECK_MEMBER(struct 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.])
|
||||
, ,
|
||||
[
|
||||
#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
|
||||
])
|
||||
|
||||
dnl check for the addrinfo structure
|
||||
AC_CHECK_MEMBER(struct addrinfo.ai_flags,
|
||||
AC_DEFINE_UNQUOTED(HAVE_STRUCT_ADDRINFO,1,
|
||||
[Define to 1 if you have struct addrinfo.]),,
|
||||
[
|
||||
#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
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
]
|
||||
)
|
||||
|
||||
dnl check for inet_pton
|
||||
AC_CHECK_FUNCS(inet_pton)
|
||||
dnl Some systems have it, but not IPv6
|
||||
@@ -268,7 +349,11 @@ AC_CHECK_SIZEOF(struct in_addr, ,
|
||||
]
|
||||
)
|
||||
|
||||
AC_CHECK_FUNCS(bitncmp)
|
||||
AC_CHECK_FUNCS([bitncmp if_indextoname])
|
||||
|
||||
dnl God bless non-standardized functions! We need to see which getservbyport_r variant is available
|
||||
CARES_CHECK_GETSERVBYPORT_R
|
||||
|
||||
CURL_CHECK_NONBLOCKING_SOCKET
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
|
@@ -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
|
||||
|
20
buildconf
20
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."
|
||||
@@ -113,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"
|
||||
@@ -160,7 +160,7 @@ 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
|
||||
@@ -199,15 +199,17 @@ ${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
|
||||
|
||||
echo "buildconf: running automake"
|
||||
${AUTOMAKE:-automake} -a || die "The automake command failed"
|
||||
${AUTOMAKE:-automake} -a -c || die "The automake command failed"
|
||||
|
||||
echo "buildconf: OK"
|
||||
exit 0
|
||||
|
220
configure.ac
220
configure.ac
@@ -122,13 +122,13 @@ case $host in
|
||||
*-*-mingw*)
|
||||
AC_DEFINE(BUILDING_LIBCURL, 1, [when building libcurl itself])
|
||||
AC_MSG_RESULT(yes)
|
||||
<EFBFBD> <20>AC_MSG_CHECKING([if we need CURL_STATICLIB])
|
||||
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)
|
||||
<EFBFBD> <20>else
|
||||
<EFBFBD> <20> <20>AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
@@ -251,6 +251,21 @@ AC_HELP_STRING([--disable-telnet],[Disable TELNET support]),
|
||||
esac ],
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
AC_MSG_CHECKING([whether to support tftp])
|
||||
AC_ARG_ENABLE(tftp,
|
||||
AC_HELP_STRING([--enable-tftp],[Enable TFTP support])
|
||||
AC_HELP_STRING([--disable-tftp],[Disable TFTP support]),
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(CURL_DISABLE_TFTP, 1, [to disable TFTP])
|
||||
AC_SUBST(CURL_DISABLE_TFTP, [1])
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for built-in manual
|
||||
@@ -567,14 +582,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])
|
||||
@@ -643,10 +659,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
|
||||
|
||||
@@ -683,19 +702,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`
|
||||
@@ -705,7 +729,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"
|
||||
@@ -715,31 +780,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 **********************************************************************
|
||||
@@ -768,20 +812,24 @@ if test X"$OPT_SSL" != Xno; then
|
||||
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
|
||||
|
||||
@@ -803,6 +851,8 @@ if test X"$OPT_SSL" != Xno; then
|
||||
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"
|
||||
@@ -832,8 +882,8 @@ if test X"$OPT_SSL" != Xno; then
|
||||
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"], [
|
||||
@@ -918,11 +968,15 @@ if test X"$OPT_SSL" != Xno; then
|
||||
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
|
||||
@@ -964,7 +1018,7 @@ dnl FIX: only check for GnuTLS if OpenSSL is not enabled
|
||||
dnl ----------------------------------------------------
|
||||
|
||||
dnl Default to compiler & linker defaults for GnuTLS files & libraries.
|
||||
OPT_GNUTLS=off
|
||||
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/)])
|
||||
@@ -973,7 +1027,7 @@ AC_HELP_STRING([--without-gnutls], [disable GnuTLS detection]),
|
||||
|
||||
if test "$OPENSSL_ENABLED" != "1"; then
|
||||
|
||||
if test X"$OPT_GNUTLS" != Xoff; 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
|
||||
@@ -1023,6 +1077,7 @@ if test "$OPENSSL_ENABLED" != "1"; then
|
||||
|
||||
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
|
||||
@@ -1168,7 +1223,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"
|
||||
@@ -1254,7 +1308,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
|
||||
@@ -1290,7 +1344,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
|
||||
|
||||
|
||||
@@ -1340,6 +1434,8 @@ AC_CHECK_HEADERS(
|
||||
libgen.h \
|
||||
locale.h \
|
||||
errno.h \
|
||||
arpa/tftp.h \
|
||||
sys/filio.h \
|
||||
setjmp.h,
|
||||
dnl to do if not found
|
||||
[],
|
||||
@@ -1594,7 +1690,7 @@ AC_HELP_STRING([--disable-ares],[Disable ares for name lookups]),
|
||||
*) AC_MSG_RESULT(yes)
|
||||
|
||||
if test "x$IPV6_ENABLED" = "x1"; then
|
||||
AC_MSG_ERROR([ares doesn't work with ipv6, disable ipv6 to use ares])
|
||||
AC_MSG_NOTICE([ares may not work properly with ipv6])
|
||||
fi
|
||||
|
||||
AC_DEFINE(USE_ARES, 1, [Define if you want to enable ares support])
|
||||
@@ -1603,7 +1699,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
|
||||
|
@@ -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"
|
||||
@@ -114,6 +116,9 @@ while test $# -gt 0; do
|
||||
if test "@CURL_DISABLE_DICT@" != "1"; then
|
||||
echo "DICT"
|
||||
fi
|
||||
if test "@CURL_DISABLE_TFTP@" != "1"; then
|
||||
echo "TFTP"
|
||||
fi
|
||||
;;
|
||||
--version)
|
||||
echo libcurl @VERSION@
|
||||
|
@@ -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
|
||||
|
||||
@@ -150,6 +150,11 @@ Scheme
|
||||
Bigloo binding written by Kirill Lisovsky
|
||||
http://curl.haxx.se/libcurl/scheme/
|
||||
|
||||
S-Lang
|
||||
|
||||
S-Lang binding written by John E Davis
|
||||
http://www.jedsoft.org/slang/modules/curl.html
|
||||
|
||||
Tcl
|
||||
|
||||
Tclcurl is written by Andr<64>s Garc<72>a
|
||||
@@ -161,7 +166,7 @@ Visual Basic
|
||||
http://sourceforge.net/projects/libcurl-vb/
|
||||
|
||||
Q
|
||||
|
||||
The libcurl module is part of the default install
|
||||
http://q-lang.sourceforge.net/
|
||||
|
||||
wxWidgets
|
||||
|
205
docs/DISTRO-DILEMMA
Normal file
205
docs/DISTRO-DILEMMA
Normal file
@@ -0,0 +1,205 @@
|
||||
Date: September 30, 2005
|
||||
Author: Daniel Stenberg <daniel@haxx.se>
|
||||
URL: http://curl.haxx.se/legal/distro-dilemma.html
|
||||
|
||||
Condition
|
||||
|
||||
This document is written to describe the situation as it is right
|
||||
now. libcurl 7.14.1 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-licensed 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
|
||||
underlying 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 for example can be burdensome for
|
||||
embedded systems usage).
|
||||
|
||||
In Debian land, there seems to be a common opinion that LGPL is "maximally
|
||||
compatible" with apps while Original BSD is not. Like this:
|
||||
|
||||
http://lists.debian.org/debian-devel/2005/09/msg01417.html
|
||||
|
||||
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.
|
||||
|
||||
libcurl has different ABI when built with different SSL/TLS libraries due to
|
||||
two reasons:
|
||||
|
||||
1. No one has worked on fixing this. The mutex/lock callbacks should be set
|
||||
with a generic libcurl function that should use the proper underlying
|
||||
functions.
|
||||
|
||||
2. The CURLOPT_SSL_CTX_FUNCTION option is not possible to "emulate" on GnuTLS
|
||||
but simply requires OpenSSL.
|
||||
|
||||
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.
|
||||
|
||||
Update: Work on this has been initiated by Richard Atterer:
|
||||
|
||||
http://curl.haxx.se/mail/lib-2005-09/0066.html
|
||||
|
||||
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
|
68
docs/FAQ
68
docs/FAQ
@@ -1,4 +1,4 @@
|
||||
Updated: April 13, 2005 (http://curl.haxx.se/docs/faq.html)
|
||||
Updated: August 26, 2005 (http://curl.haxx.se/docs/faq.html)
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
@@ -64,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?
|
||||
@@ -132,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?
|
||||
|
||||
@@ -197,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.
|
||||
|
||||
@@ -220,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?
|
||||
|
||||
@@ -256,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
|
||||
|
||||
@@ -396,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
|
||||
@@ -734,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
|
||||
|
||||
@@ -754,7 +781,7 @@ FAQ
|
||||
need to provide locking function(s) for libgcrypt (which is used by GnuTLS
|
||||
for the crypto functions).
|
||||
|
||||
[informative link missing]
|
||||
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?
|
||||
|
||||
@@ -978,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
|
||||
|
@@ -145,3 +145,9 @@ August 2004:
|
||||
April 2005:
|
||||
|
||||
GnuTLS can now optionally be used for the secure layer when curl is built.
|
||||
|
||||
September 2005:
|
||||
|
||||
TFTP support was added.
|
||||
|
||||
More than 100,000 unique visitors of the curl web site. 25 mirrors.
|
||||
|
24
docs/INSTALL
24
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/
|
||||
@@ -588,7 +586,7 @@ PORTS
|
||||
- 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
|
||||
|
@@ -3,11 +3,31 @@ join in and help us correct one or more of these! Also be sure to check the
|
||||
changelog of the current development status, as one or more of these problems
|
||||
may have been fixed since this was written!
|
||||
|
||||
26. NTLM authentication using SSPI (on Windows) when (lib)curl is running in
|
||||
"system context" will make it use wrong(?) user name - at least when compared
|
||||
to what winhttp does. See http://curl.haxx.se/bug/view.cgi?id=1281867
|
||||
|
||||
25. When doing a CONNECT request with curl it doesn't properly handle if the
|
||||
proxy closes the connection within the authentication "negotiation phase".
|
||||
Like if you do HTTPS or similar over a proxy and you use perhaps
|
||||
--proxy-anyauth. There's work in progress on this problem, and a recent
|
||||
patch was posted here: http://curl.haxx.se/mail/lib-2005-08/0074.html
|
||||
|
||||
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
|
||||
possible fix would involve sending a "STRU VMS" command.
|
||||
http://sourceforge.net/support/tracker.php?aid=1156287
|
||||
http://curl.haxx.se/bug/view.cgi?id=1156287
|
||||
|
||||
21. FTP ASCII transfers do not follow RFC959. They don't convert the data
|
||||
accordingly (not for sending nor for receiving). RFC 959 section 3.1.1.1
|
||||
@@ -18,14 +38,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 +54,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
|
||||
@@ -65,11 +73,12 @@ may have been fixed since this was written!
|
||||
10. To get HTTP Negotiate authentication to work fine, you need to provide a
|
||||
(fake) user name (this concerns both curl and the lib) because the code
|
||||
wrongly only considers authentication if there's a user name provided.
|
||||
Bug report #1004841. How? http://curl.haxx.se/mail/lib-2004-08/0182.html
|
||||
http://curl.haxx.se/bug/view.cgi?id=1004841. How?
|
||||
http://curl.haxx.se/mail/lib-2004-08/0182.html
|
||||
|
||||
9. --limit-rate using -d or -F does not work. This is because the limit logic
|
||||
is provided by the curl app in its read/write callbacks, and when doing
|
||||
-d/-F the callbacks aren't used! Bug report #921395.
|
||||
-d/-F the callbacks aren't used! http://curl.haxx.se/bug/view.cgi?id=921395
|
||||
|
||||
8. Doing resumed upload over HTTP does not work with '-C -', because curl
|
||||
doesn't do a HEAD first to get the initial size. This needs to be done
|
||||
|
@@ -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,29 +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). If OpenSSL's licensing is a problem for you,
|
||||
consider using GnuTLS instead.
|
||||
(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/
|
||||
|
||||
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.
|
||||
(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
|
||||
|
||||
@@ -60,33 +60,43 @@ 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
|
||||
|
@@ -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 < $< >$@
|
||||
|
||||
|
539
docs/THANKS
539
docs/THANKS
@@ -4,91 +4,454 @@
|
||||
|
||||
If you have contributed but are missing here, please let us know!
|
||||
|
||||
Alan Pinstein, Albert Chin-A-Young, Albert Choy, Aleksandar Milivojevic, Alex
|
||||
aka WindEagle, Alex Neblett, Alex Suykov, Alexander Kourakos, Alexander
|
||||
Krasnostavsky, Alexander Zhuravlev, Alexis Carvalho, Andi Jahja, Andreas Damm,
|
||||
Andreas Olsson, Andreas Rieke, Andrew Francis, Andrew Fuller, Andr<64>s Garc<72>a,
|
||||
Andy Cedilnik, Andy Serpa, Angus Mackay, Antoine Calando, Anton Kalmykov,
|
||||
Arkadiusz Miskiewicz, Augustus Saunders, Avery Fay, Ben Greear, Benjamin
|
||||
Gerard, Bertrand Demiddelaer, Bjorn Reese, Bj<42>rn Stenberg, Bob Schader, Brad
|
||||
Burdick, Brent Beardsley, Brian Akins, Brian R Duffy, Bruce Mitchener, Bryan
|
||||
Henderson, Bryan Henderson , Bryan Kemp, Caolan McNamara, Casey O'Donnell,
|
||||
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 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, Gautam Mani, Gaz
|
||||
Iqbal, Georg Horn, Georg Huettenegger, 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,
|
||||
G<EFBFBD>tz Babin-Ebell, G<>nter Knauf, 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, 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, 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 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, J<>rg Mueller-Tolk, J<>rn Hartroth, 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, 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, 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 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. 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,
|
||||
S<EFBFBD>bastien Willemijns, T. Bharath, T. Yamada, Thomas Schwinge, Thomas Tonino,
|
||||
Tim Baker, Tim Bartley, Tim Costello, Tim Sneddon, Toby Peterson, 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, 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
|
||||
Adrian Schuur
|
||||
Alan Pinstein
|
||||
Albert Chin-A-Young
|
||||
Albert Choy
|
||||
Aleksandar Milivojevic
|
||||
Alex Neblett
|
||||
Alex Suykov
|
||||
Alex aka WindEagle
|
||||
Alexander Kourakos
|
||||
Alexander Krasnostavsky
|
||||
Alexander Zhuravlev
|
||||
Alexis Carvalho
|
||||
Andi Jahja
|
||||
Andreas Damm
|
||||
Andreas Olsson
|
||||
Andreas Rieke
|
||||
Andres Garcia
|
||||
Andrew Bushnell
|
||||
Andrew Francis
|
||||
Andrew Fuller
|
||||
Andr<EFBFBD>s Garc<72>a
|
||||
Andy Cedilnik
|
||||
Andy Serpa
|
||||
Angus Mackay
|
||||
Antoine Calando
|
||||
Anton Kalmykov
|
||||
Arkadiusz Miskiewicz
|
||||
Augustus Saunders
|
||||
Avery Fay
|
||||
Ben Greear
|
||||
Benjamin Gerard
|
||||
Bertrand Demiddelaer
|
||||
Bjorn Reese
|
||||
Bj<EFBFBD>rn Stenberg
|
||||
Bob Schader
|
||||
Brad Burdick
|
||||
Brent Beardsley
|
||||
Brian Akins
|
||||
Brian R Duffy
|
||||
Bruce Mitchener
|
||||
Bryan Henderson
|
||||
Bryan Henderson
|
||||
Bryan Kemp
|
||||
Caolan McNamara
|
||||
Casey O'Donnell
|
||||
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 Stenberg
|
||||
Daniel at touchtunes
|
||||
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
|
||||
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
|
||||
G<EFBFBD>tz Babin-Ebell
|
||||
G<EFBFBD>nter Knauf
|
||||
Hamish Mackenzie
|
||||
Hanno Kranzhoff
|
||||
Hans Steegers
|
||||
Hardeep Singh
|
||||
Harshal Pradhan
|
||||
Heikki Korpela
|
||||
Henrik Storner
|
||||
Hzhijun
|
||||
Ian Ford
|
||||
Ian Gulliver
|
||||
Ian Wilkes
|
||||
Ignacio Vazquez-Abrams
|
||||
Igor Polyakov
|
||||
Ilguiz Latypov
|
||||
Ingo Ralf Blum
|
||||
Ingo Wilken
|
||||
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
|
||||
J<EFBFBD>rg Mueller-Tolk
|
||||
J<EFBFBD>rn Hartroth
|
||||
Kai Sommerfeld
|
||||
Kai-Uwe Rommel
|
||||
Kang-Jin Lee
|
||||
Karol Pietrzak
|
||||
Keith MacDonald
|
||||
Keith McGuigan
|
||||
Ken Hirsch
|
||||
Ken Rastatter
|
||||
Kevin Fisk
|
||||
Kevin Lussier
|
||||
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
|
||||
Nodak Sodak
|
||||
Norbert Novotny
|
||||
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. 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 Josefsson
|
||||
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
|
||||
S<EFBFBD>bastien Willemijns
|
||||
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
|
||||
nk
|
||||
swalkaus at yahoo.com
|
||||
|
35
docs/TODO
35
docs/TODO
@@ -31,7 +31,7 @@ TODO
|
||||
* Introduce a new error code indicating authentication problems (for proxy
|
||||
CONNECT error 407 for example). This cannot be an error code, we must not
|
||||
return informational stuff as errors, consider a new info returned by
|
||||
curl_easy_getinfo() #845941
|
||||
curl_easy_getinfo() http://curl.haxx.se/bug/view.cgi?id=845941
|
||||
|
||||
* Use 'struct lifreq' and SIOCGLIFADDR instead of 'struct ifreq' and
|
||||
SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
|
||||
@@ -40,6 +40,9 @@ TODO
|
||||
* 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. this allows apps to avoid the
|
||||
@@ -58,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
|
||||
@@ -149,6 +163,25 @@ TODO
|
||||
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
|
||||
|
||||
* Look over the implementation. The looping will have to "go away" from the
|
||||
|
59
docs/curl.1
59
docs/curl.1
@@ -21,7 +21,7 @@
|
||||
.\" * $Id$
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl 1 "28 Apr 2005" "Curl 7.14.0" "Curl Manual"
|
||||
.TH curl 1 "4 Sep 2005" "Curl 7.14.2" "Curl Manual"
|
||||
.SH NAME
|
||||
curl \- transfer a URL
|
||||
.SH SYNOPSIS
|
||||
@@ -30,8 +30,8 @@ curl \- transfer a URL
|
||||
.SH DESCRIPTION
|
||||
.B curl
|
||||
is a tool to transfer data from or to a server, using one of the supported
|
||||
protocols (HTTP, HTTPS, FTP, FTPS, GOPHER, DICT, TELNET, LDAP or FILE). The
|
||||
command is designed to work without user interaction.
|
||||
protocols (HTTP, HTTPS, FTP, FTPS, TFTP, GOPHER, DICT, TELNET, LDAP or
|
||||
FILE). The command is designed to work without user interaction.
|
||||
|
||||
curl offers a busload of useful tricks like proxy support, user
|
||||
authentication, ftp upload, HTTP post, SSL (https:) connections, cookies, file
|
||||
@@ -64,6 +64,11 @@ several ones next to each other:
|
||||
You can specify any amount of URLs on the command line. They will be fetched
|
||||
in a sequential manner in the specified order.
|
||||
|
||||
If you specify URL without protocol:// prefix, curl will attempt to guess what
|
||||
protocol you might want. It will then default to HTTP but try other protocols
|
||||
based on often-used host name prefixes. For example, for host names starting
|
||||
with "ftp." curl will assume you want to speak FTP.
|
||||
|
||||
Curl will attempt to re-use connections for multiple file transfers, so that
|
||||
getting many files from the same server will not do multiple connects /
|
||||
handshakes. This improves speed. Of course this is only done on files
|
||||
@@ -347,6 +352,15 @@ If this option is used twice, the second will again disable silent failure.
|
||||
using this option can be used to override a previous --ftp-port option. (Added
|
||||
in 7.11.0)
|
||||
|
||||
If this option is used twice, the second will again disable silent failure.
|
||||
.IP "--ftp-skip-pasv-ip"
|
||||
(FTP) Tell curl to not use the IP address the server suggests in its response
|
||||
to curl's PASV command when curl connects the data connection. Instead curl
|
||||
will re-use the same IP address it already uses for the control
|
||||
connection. (Added in 7.14.2)
|
||||
|
||||
This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
|
||||
|
||||
If this option is used twice, the second will again disable silent failure.
|
||||
.IP "--ftp-ssl"
|
||||
(FTP) Make the FTP connection switch to use SSL/TLS. (Added in 7.11.0)
|
||||
@@ -421,9 +435,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
|
||||
@@ -569,8 +593,7 @@ this given limit. This concerns both FTP and HTTP transfers.
|
||||
.IP "-m/--max-time <seconds>"
|
||||
Maximum time in seconds that you allow the whole operation to take. This is
|
||||
useful for preventing your batch jobs from hanging for hours due to slow
|
||||
networks or links going down. This doesn't work fully in win32 systems. See
|
||||
also the \fI--connect-timeout\fP option.
|
||||
networks or links going down. See also the \fI--connect-timeout\fP option.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-M/--manual"
|
||||
@@ -589,7 +612,7 @@ directory.
|
||||
|
||||
A quick and very simple example of how to setup a \fI.netrc\fP to allow curl
|
||||
to ftp to the machine host.domain.com with user name \&'myself' and password
|
||||
'secret' should look similar to:
|
||||
\&'secret' should look similar to:
|
||||
|
||||
.B "machine host.domain.com login myself password secret"
|
||||
|
||||
@@ -958,11 +981,11 @@ 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
|
||||
@@ -1058,12 +1081,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
|
||||
@@ -1157,7 +1184,7 @@ Sets proxy server to use for GOPHER.
|
||||
Sets proxy server to use if no protocol-specific proxy is set.
|
||||
.IP "NO_PROXY <comma-separated list of hosts>"
|
||||
list of host names that shouldn't go through any proxy. If set to a asterisk
|
||||
'*' only, it matches all hosts.
|
||||
\&'*' only, it matches all hosts.
|
||||
.SH EXIT CODES
|
||||
There exists a bunch of different error codes and their corresponding error
|
||||
messages that may appear during bad conditions. At the time of this writing,
|
||||
|
@@ -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 opensslthreadlock.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;
|
||||
}
|
@@ -14,6 +14,8 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
@@ -93,5 +95,8 @@ int main(int argc, char **argv)
|
||||
* you're done with it, you should free() it as a nice application.
|
||||
*/
|
||||
|
||||
if(chunk.memory)
|
||||
free(chunk.memory);
|
||||
|
||||
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)
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_easy_getinfo 3 "22 Dec 2004" "libcurl 7.12.3" "libcurl Manual"
|
||||
.TH curl_easy_getinfo 3 "6 Oct 2005" "libcurl 7.12.3" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_getinfo - extract information from a curl handle
|
||||
.SH SYNOPSIS
|
||||
@@ -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,47 @@ 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 TIMES
|
||||
.NF
|
||||
An overview of the six time values available from curl_easy_getinfo()
|
||||
|
||||
curk_easy_perform()
|
||||
|
|
||||
|--NT
|
||||
|--|--CT
|
||||
|--|--|--PT
|
||||
|--|--|--|--ST
|
||||
|--|--|--TT
|
||||
|--|--|--|--|--RT
|
||||
.FI
|
||||
.IP NT
|
||||
\fICURLINFO_NAMELOOKUP_TIME\fP. The time it took from the start until the name
|
||||
resolving was completed.
|
||||
.IP CT
|
||||
\fICURLINFO_CONNECT_TIME\fP. The time it took from the start until the connect
|
||||
to the remote host (or proxy) was completed.
|
||||
.IP PT
|
||||
\fICURLINFO_PRETRANSFER_TIME\fP. 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.
|
||||
.IP ST
|
||||
\fICURLINFO_STARTTRANSFER_TIME\fP. The time it took from the start until the
|
||||
first byte is just about to be transferred.
|
||||
.IP TT
|
||||
\fICURLINFO_TOTAL_TIME\fP. 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.
|
||||
.IP RT
|
||||
\fICURLINFO_REDIRECT_TIME\fP. 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.
|
||||
.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 "12 May 2005" "libcurl 7.14.0" "libcurl Manual"
|
||||
.TH curl_easy_setopt 3 "22 Sep 2005" "libcurl 7.14.2" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_setopt - set options for a curl easy handle
|
||||
.SH SYNOPSIS
|
||||
@@ -44,11 +44,11 @@ between transfers, so if you want subsequent transfers with different options,
|
||||
you must change them between the transfers. You can optionally reset all
|
||||
options back to internal default with \fIcurl_easy_reset(3)\fP.
|
||||
|
||||
\fBNOTE:\fP strings passed to libcurl as 'char *' arguments, will not be
|
||||
copied by the library. Instead you should keep them available until libcurl no
|
||||
longer needs them. Failing to do so will cause very odd behavior or even
|
||||
crashes. libcurl will need them until you call \fIcurl_easy_cleanup(3)\fP or
|
||||
you set the same option again to use a different pointer.
|
||||
Strings passed to libcurl as 'char *' arguments, will not be copied by the
|
||||
library. Instead you should keep them available until libcurl no longer needs
|
||||
them. Failing to do so will cause very odd behavior or even crashes. libcurl
|
||||
will need them until you call \fIcurl_easy_cleanup(3)\fP or you set the same
|
||||
option again to use a different pointer.
|
||||
|
||||
The \fIhandle\fP is the return code from a \fIcurl_easy_init(3)\fP or
|
||||
\fIcurl_easy_duphandle(3)\fP call.
|
||||
@@ -70,8 +70,8 @@ preceding the data (like HTTP).
|
||||
A non-zero parameter tells the library to shut off the built-in progress meter
|
||||
completely.
|
||||
|
||||
\fBNOTE:\fP future versions of libcurl is likely to not have any built-in
|
||||
progress meter at all.
|
||||
Future versions of libcurl is likely to not have any built-in progress meter
|
||||
at all.
|
||||
.IP CURLOPT_NOSIGNAL
|
||||
Pass a long. If it is non-zero, libcurl will not use any functions that
|
||||
install signal handlers or any functions that cause signals to be sent to the
|
||||
@@ -96,19 +96,26 @@ transfer and return \fICURLE_WRITE_ERROR\fP.
|
||||
This function may be called with zero bytes data if the transfered file is
|
||||
empty.
|
||||
|
||||
Set this option to NULL to get the internal default function. The internal
|
||||
default function will write the data to the FILE * given with
|
||||
\fICURLOPT_WRITEDATA\fP.
|
||||
|
||||
Set the \fIstream\fP argument with the \fICURLOPT_WRITEDATA\fP option.
|
||||
|
||||
\fBNOTE:\fP you will be passed as much data as possible in all invokes, but
|
||||
you cannot possibly make any assumptions. It may be one byte, it may be
|
||||
The callback function will be passed as much data as possible in all invokes,
|
||||
but you cannot possibly make any assumptions. It may be one byte, it may be
|
||||
thousands. The maximum amount of data that can be passed to the write callback
|
||||
is defined in the curl.h header file: CURL_MAX_WRITE_SIZE.
|
||||
.IP CURLOPT_WRITEDATA
|
||||
Data pointer to pass to the file write function. Note that if you specify the
|
||||
\fICURLOPT_WRITEFUNCTION\fP, this is the pointer you'll get as input. If you
|
||||
don't use a callback, you must pass a 'FILE *' as libcurl will pass this to
|
||||
fwrite() when writing data.
|
||||
Data pointer to pass to the file write function. If you use the
|
||||
\fICURLOPT_WRITEFUNCTION\fP option, this is the pointer you'll get as
|
||||
input. If you don't use a callback, you must pass a 'FILE *' as libcurl will
|
||||
pass this to fwrite() when writing data.
|
||||
|
||||
\fBNOTE:\fP If you're using libcurl as a win32 DLL, you MUST use the
|
||||
The internal \fICURLOPT_WRITEFUNCTION\fP will write the data to the FILE *
|
||||
given with this option, or to stdout if this option hasn't been set.
|
||||
|
||||
If you're using libcurl as a win32 DLL, you \fBMUST\fP use the
|
||||
\fICURLOPT_WRITEFUNCTION\fP if you set this option or you will experience
|
||||
crashes.
|
||||
|
||||
@@ -129,15 +136,20 @@ server expected it, like when you've told you will upload N bytes and you
|
||||
upload less than N bytes), you may experience that the server "hangs" waiting
|
||||
for the rest of the data that won't come.
|
||||
|
||||
In libcurl 7.12.1 and later, the read callback may return
|
||||
\fICURL_READFUNC_ABORT\fP to stop the current operation at once, with a
|
||||
\fICURLE_ABORTED_BY_CALLBACK\fP error code from the transfer.
|
||||
.IP CURLOPT_READDATA
|
||||
Data pointer to pass to the file read function. Note that if you specify the
|
||||
\fICURLOPT_READFUNCTION\fP, this is the pointer you'll get as input. If you
|
||||
don't specify a read callback, this must be a valid FILE *.
|
||||
The read callback may return \fICURL_READFUNC_ABORT\fP to stop the current
|
||||
operation immediately, resulting in a \fICURLE_ABORTED_BY_CALLBACK\fP error
|
||||
code from the transfer (Added in 7.12.1)
|
||||
|
||||
\fBNOTE:\fP If you're using libcurl as a win32 DLL, you MUST use a
|
||||
If you set the callback pointer to NULL, or doesn't set it at all, the default
|
||||
internal read function will be used. It is simply doing an fread() on the FILE
|
||||
* stream set with \fICURLOPT_READDATA\fP.
|
||||
.IP CURLOPT_READDATA
|
||||
Data pointer to pass to the file read function. If you use the
|
||||
\fICURLOPT_READFUNCTION\fP option, this is the pointer you'll get as input. If
|
||||
you don't specify a read callback but instead rely on the default internal
|
||||
read function, this data must be a valid readable FILE *.
|
||||
|
||||
If you're using libcurl as a win32 DLL, you MUST use a
|
||||
\fICURLOPT_READFUNCTION\fP if you set this option.
|
||||
|
||||
This option is also known with the older name \fICURLOPT_INFILE\fP, the name
|
||||
@@ -163,28 +175,38 @@ data, the upload size will remain 0). Returning a non-zero value from this
|
||||
callback will cause libcurl to abort the transfer and return
|
||||
\fICURLE_ABORTED_BY_CALLBACK\fP.
|
||||
|
||||
Also note that \fICURLOPT_NOPROGRESS\fP must be set to FALSE to make this
|
||||
function actually get called.
|
||||
\fICURLOPT_NOPROGRESS\fP must be set to FALSE to make this function actually
|
||||
get called.
|
||||
.IP CURLOPT_PROGRESSDATA
|
||||
Pass a pointer that will be untouched by libcurl and passed as the first
|
||||
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,10 +245,13 @@ 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.
|
||||
|
||||
\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
|
||||
to change the actual URI of an HTTPS request (example used in the lib509 test
|
||||
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.
|
||||
|
||||
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 to
|
||||
change the actual URI of an HTTPS request (example used in the lib509 test
|
||||
case). See also the example section for a replacement of the key, certificate
|
||||
and trust file settings.
|
||||
.IP CURLOPT_SSL_CTX_DATA
|
||||
@@ -236,14 +261,21 @@ parameter, otherwise \fBNULL\fP. (Added in 7.11.0)
|
||||
.SH ERROR OPTIONS
|
||||
.IP CURLOPT_ERRORBUFFER
|
||||
Pass a char * to a buffer that the libcurl may store human readable error
|
||||
messages in. This may be more helpful than just the return code from the
|
||||
library. The buffer must be at least CURL_ERROR_SIZE big.
|
||||
messages in. This may be more helpful than just the return code from
|
||||
\fIcurl_easy_perform\fP. The buffer must be at least CURL_ERROR_SIZE big.
|
||||
|
||||
Use \fICURLOPT_VERBOSE\fP and \fICURLOPT_DEBUGFUNCTION\fP to better
|
||||
debug/trace why errors happen.
|
||||
|
||||
\fBNote:\fP if the library does not return an error, the buffer may not have
|
||||
been touched. Do not rely on the contents in those cases.
|
||||
If the library does not return an error, the buffer may not have been
|
||||
touched. Do not rely on the contents in those cases.
|
||||
|
||||
In a few rare cases, there is no text string associated with the error in
|
||||
libcurl and then you may not get a string in the buffer even though it returns
|
||||
an error. This is considered a bug and we appreciate your reports about these
|
||||
cases. Anyway, you can avoid problems with these cases in your program by
|
||||
making sure to clear the first byte of the error buffer before you call
|
||||
curl_easy_perform().
|
||||
.IP CURLOPT_STDERR
|
||||
Pass a FILE * as parameter. Tell libcurl to use this stream instead of stderr
|
||||
when showing the progress meter and displaying \fICURLOPT_VERBOSE\fP data.
|
||||
@@ -264,7 +296,7 @@ given protocol of the set URL is not supported, libcurl will return on error
|
||||
\fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed info
|
||||
on which protocols that are supported.
|
||||
|
||||
\fBNOTE:\fP \fICURLOPT_URL\fP is the only option that must be set before
|
||||
\fICURLOPT_URL\fP is the only option that must be set before
|
||||
\fIcurl_easy_perform(3)\fP is called.
|
||||
.IP CURLOPT_PROXY
|
||||
Set HTTP proxy to use. The parameter should be a char * to a zero terminated
|
||||
@@ -274,15 +306,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.
|
||||
@@ -292,9 +329,9 @@ this are \fICURLPROXY_HTTP\fP and \fICURLPROXY_SOCKS5\fP, with the HTTP one
|
||||
being default. (Added in 7.10)
|
||||
.IP CURLOPT_HTTPPROXYTUNNEL
|
||||
Set the parameter to non-zero to get the library to tunnel all operations
|
||||
through a given HTTP proxy. Note that there is a big difference between using
|
||||
a proxy and to tunnel through it. If you don't know what this means, you
|
||||
probably don't want this tunneling option.
|
||||
through a given HTTP proxy. There is a big difference between using a proxy
|
||||
and to tunnel through it. If you don't know what this means, you probably
|
||||
don't want this tunneling option.
|
||||
.IP CURLOPT_INTERFACE
|
||||
Pass a char * as parameter. This set the interface name to use as outgoing
|
||||
network interface. The name can be an interface name, an IP address or a host
|
||||
@@ -313,10 +350,14 @@ thread-safe and this will use a global variable.
|
||||
to using the share interface instead! See \fICURLOPT_SHARE\fP and
|
||||
\fIcurl_share_init(3)\fP.
|
||||
.IP CURLOPT_BUFFERSIZE
|
||||
Pass a long specifying your preferred size for the receive buffer in libcurl.
|
||||
The main point of this would be that the write callback gets called more often
|
||||
and with smaller chunks. This is just treated as a request, not an order. You
|
||||
cannot be guaranteed to actually get the given size. (Added in 7.10)
|
||||
Pass a long specifying your preferred size (in bytes) for the receive buffer
|
||||
in libcurl. The main point of this would be that the write callback gets
|
||||
called more often and with smaller chunks. This is just treated as a request,
|
||||
not an order. You cannot be guaranteed to actually get the given size. (Added
|
||||
in 7.10)
|
||||
|
||||
This size is by default set as big as possible (CURL_MAX_WRITE_SIZE), so it
|
||||
only makse sense to use this option if you want it smaller.
|
||||
.IP CURLOPT_PORT
|
||||
Pass a long specifying what remote port number to connect to, instead of the
|
||||
one specified in the URL or the default port for the used protocol.
|
||||
@@ -342,9 +383,9 @@ This parameter controls the preference of libcurl between using user names and
|
||||
passwords from your \fI~/.netrc\fP file, relative to user names and passwords
|
||||
in the URL supplied with \fICURLOPT_URL\fP.
|
||||
|
||||
\fBNote:\fP libcurl uses a user name (and supplied or prompted password)
|
||||
supplied with \fICURLOPT_USERPWD\fP in preference to any of the options
|
||||
controlled by this parameter.
|
||||
libcurl uses a user name (and supplied or prompted password) supplied with
|
||||
\fICURLOPT_USERPWD\fP in preference to any of the options controlled by this
|
||||
parameter.
|
||||
|
||||
Pass a long, set to one of the values described below.
|
||||
.RS
|
||||
@@ -368,9 +409,8 @@ and to search the file with the host only.
|
||||
Only machine name, user name and password are taken into account
|
||||
(init macros and similar things aren't supported).
|
||||
|
||||
\fBNote:\fP libcurl does not verify that the file has the correct properties
|
||||
set (as the standard Unix ftp client does). It should only be readable by
|
||||
user.
|
||||
libcurl does not verify that the file has the correct properties set (as the
|
||||
standard Unix ftp client does). It should only be readable by user.
|
||||
.IP CURLOPT_NETRC_FILE
|
||||
Pass a char * as parameter, pointing to a zero terminated string containing
|
||||
the full path name to the file you want libcurl to use as .netrc file. If this
|
||||
@@ -395,9 +435,9 @@ Pass a long as parameter, which is set to a bitmask, to tell libcurl what
|
||||
authentication method(s) you want it to use. The available bits are listed
|
||||
below. If more than one bit is set, libcurl will first query the site to see
|
||||
what authentication methods it supports and then pick the best one you allow
|
||||
it to use. Note that for some methods, this will induce an extra network
|
||||
round-trip. Set the actual name and password with the \fICURLOPT_USERPWD\fP
|
||||
option. (Added in 7.10.6)
|
||||
it to use. For some methods, this will induce an extra network round-trip. Set
|
||||
the actual name and password with the \fICURLOPT_USERPWD\fP option. (Added in
|
||||
7.10.6)
|
||||
.RS
|
||||
.IP CURLAUTH_BASIC
|
||||
HTTP Basic authentication. This is the default choice, and the only method
|
||||
@@ -415,15 +455,14 @@ 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.
|
||||
|
||||
\fBNOTE\fP that you need to build libcurl with a suitable GSS-API library for
|
||||
this to work.
|
||||
You need to build libcurl with a suitable GSS-API library for this to work.
|
||||
.IP CURLAUTH_NTLM
|
||||
HTTP NTLM authentication. A proprietary protocol invented and used by
|
||||
Microsoft. It uses a challenge-response and hash concept similar to Digest, to
|
||||
prevent the password from being eavesdropped.
|
||||
|
||||
\fBNOTE\fP that you need to build libcurl with SSL support for this option to
|
||||
work.
|
||||
You need to build libcurl with OpenSSL support for this option to work, or
|
||||
build libcurl on Windows.
|
||||
.IP CURLAUTH_ANY
|
||||
This is a convenience macro that sets all bits and thus makes libcurl pick any
|
||||
it finds suitable. libcurl will automatically select the one it finds most
|
||||
@@ -438,11 +477,11 @@ Pass a long as parameter, which is set to a bitmask, to tell libcurl what
|
||||
authentication method(s) you want it to use for your proxy authentication. If
|
||||
more than one bit is set, libcurl will first query the site to see what
|
||||
authentication methods it supports and then pick the best one you allow it to
|
||||
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, Digest and NTLM work. (Added in 7.10.7)
|
||||
use. 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, 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
|
||||
@@ -465,14 +504,14 @@ lib/README.encoding for details.
|
||||
A non-zero parameter tells the library to follow any Location: header that the
|
||||
server sends as part of an HTTP header.
|
||||
|
||||
\fBNOTE:\fP this means that the library will re-send the same request on the
|
||||
new location and follow new Location: headers all the way until no more such
|
||||
headers are returned. \fICURLOPT_MAXREDIRS\fP can be used to limit the number
|
||||
of redirects libcurl will follow.
|
||||
This means that the library will re-send the same request on the new location
|
||||
and follow new Location: headers all the way until no more such headers are
|
||||
returned. \fICURLOPT_MAXREDIRS\fP can be used to limit the number of redirects
|
||||
libcurl will follow.
|
||||
.IP CURLOPT_UNRESTRICTED_AUTH
|
||||
A non-zero parameter tells the library it can continue to send authentication
|
||||
(user+password) when following locations, even when hostname changed. Note
|
||||
that this is meaningful only when setting \fICURLOPT_FOLLOWLOCATION\fP.
|
||||
(user+password) when following locations, even when hostname changed. This
|
||||
option is meaningful only when setting \fICURLOPT_FOLLOWLOCATION\fP.
|
||||
.IP CURLOPT_MAXREDIRS
|
||||
Pass a long. The set number will be the redirection limit. If that many
|
||||
redirections have been followed, the next redirect will cause an error
|
||||
@@ -511,8 +550,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
|
||||
@@ -528,8 +570,8 @@ commonly used one by HTML forms. See also the \fICURLOPT_POST\fP. Using
|
||||
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.
|
||||
|
||||
\fBNote:\fP to make multipart/formdata posts (aka rfc1867-posts), check out
|
||||
the \fICURLOPT_HTTPPOST\fP option.
|
||||
To make multipart/formdata posts (aka rfc1867-posts), check out the
|
||||
\fICURLOPT_HTTPPOST\fP option.
|
||||
.IP CURLOPT_POSTFIELDSIZE
|
||||
If you want to post data to the server without letting libcurl do a strlen()
|
||||
to measure the data size, this option must be used. When this option is used
|
||||
@@ -550,6 +592,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
|
||||
@@ -581,7 +626,7 @@ request-line are headers.
|
||||
|
||||
Pass a NULL to this to reset back to no custom headers.
|
||||
|
||||
\fBNOTE:\fP The most commonly replaced headers have "shortcuts" in the options
|
||||
The most commonly replaced headers have "shortcuts" in the options
|
||||
\fICURLOPT_COOKIE\fP, \fICURLOPT_USERAGENT\fP and \fICURLOPT_REFERER\fP.
|
||||
.IP CURLOPT_HTTP200ALIASES
|
||||
Pass a pointer to a linked list of aliases to be treated as valid HTTP 200
|
||||
@@ -594,9 +639,9 @@ The linked list should be a fully valid list of struct curl_slist structs, and
|
||||
be properly filled in. Use \fIcurl_slist_append(3)\fP to create the list and
|
||||
\fIcurl_slist_free_all(3)\fP to clean up an entire list.
|
||||
|
||||
\fBNOTE:\fP The alias itself is not parsed for any version strings. So if your
|
||||
alias is "MYHTTP/9.9", Libcurl will not treat the server as responding with
|
||||
HTTP version 9.9. Instead Libcurl will use the value set by option
|
||||
The alias itself is not parsed for any version strings. So if your alias is
|
||||
\&"MYHTTP/9.9", Libcurl will not treat the server as responding with HTTP
|
||||
version 9.9. Instead Libcurl will use the value set by option
|
||||
\fICURLOPT_HTTP_VERSION\fP.
|
||||
.IP CURLOPT_COOKIE
|
||||
Pass a pointer to a zero terminated string as parameter. It will be used to
|
||||
@@ -620,6 +665,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
|
||||
@@ -628,7 +676,7 @@ instead have the cookies written to stdout. Using this option also enables
|
||||
cookies for this session, so if you for example follow a location it will make
|
||||
matching cookies get sent accordingly.
|
||||
|
||||
\fBNOTE:\fP If the cookie jar file can't be created or written to (when the
|
||||
If the cookie jar file can't be created or written to (when the
|
||||
\fIcurl_easy_cleanup(3)\fP is called), libcurl will not and cannot report an
|
||||
error for this. Using \fICURLOPT_VERBOSE\fP or \fICURLOPT_DEBUGFUNCTION\fP
|
||||
will get a warning to display, but that is the only visible feedback you get
|
||||
@@ -640,10 +688,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 +712,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
|
||||
@@ -721,11 +783,19 @@ directory. (Added in 7.10.7)
|
||||
.IP CURLOPT_FTP_RESPONSE_TIMEOUT
|
||||
Pass a long. Causes curl to set a timeout period (in seconds) on the amount
|
||||
of time that the server is allowed to take in order to generate a response
|
||||
message for a command before the session is considered hung. Note that while
|
||||
curl is waiting for a response, this value overrides \fICURLOPT_TIMEOUT\fP. It
|
||||
is recommended that if used in conjunction with \fICURLOPT_TIMEOUT\fP, you set
|
||||
message for a command before the session is considered hung. While curl is
|
||||
waiting for a response, this value overrides \fICURLOPT_TIMEOUT\fP. It is
|
||||
recommended that if used in conjunction with \fICURLOPT_TIMEOUT\fP, you set
|
||||
\fICURLOPT_FTP_RESPONSE_TIMEOUT\fP to a value smaller than
|
||||
\fICURLOPT_TIMEOUT\fP. (Added in 7.10.8)
|
||||
.IP CURLOPT_FTP_SKIP_PASV_IP
|
||||
Pass a long. If set to a non-zero value, it instructs libcurl to not use the
|
||||
IP address the server suggests in its 227-response to libcurl's PASV command
|
||||
when libcurl connects the data connection. Instead libcurl will re-use the
|
||||
same IP address it already uses for the control connection. But it will use
|
||||
the port number from the 227-response. (Added in 7.14.2)
|
||||
|
||||
This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
|
||||
.IP CURLOPT_FTP_SSL
|
||||
Pass a long using one of the values from below, to make libcurl use your
|
||||
desired level of SSL for the ftp transfer. (Added in 7.11.0)
|
||||
@@ -770,11 +840,14 @@ 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.
|
||||
|
||||
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
|
||||
@@ -800,11 +873,11 @@ server supports the command first.
|
||||
|
||||
Restore to the internal default by setting this to NULL.
|
||||
|
||||
\fBNOTE:\fP Many people have wrongly used this option to replace the entire
|
||||
request with their own, including multiple headers and POST contents. While
|
||||
that might work in many cases, it will cause libcurl to send invalid requests
|
||||
and it could possibly confuse the remote server badly. Use \fICURLOPT_POST\fP
|
||||
and \fICURLOPT_POSTFIELDS\fP to set POST data. Use \fICURLOPT_HTTPHEADER\fP to
|
||||
Many people have wrongly used this option to replace the entire request with
|
||||
their own, including multiple headers and POST contents. While that might work
|
||||
in many cases, it will cause libcurl to send invalid requests and it could
|
||||
possibly confuse the remote server badly. Use \fICURLOPT_POST\fP and
|
||||
\fICURLOPT_POSTFIELDS\fP to set POST data. Use \fICURLOPT_HTTPHEADER\fP to
|
||||
replace or extend the set of headers sent by libcurl. Use
|
||||
\fICURLOPT_HTTP_VERSION\fP to change HTTP version.
|
||||
.IP CURLOPT_FILETIME
|
||||
@@ -818,9 +891,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
|
||||
@@ -849,26 +921,26 @@ Pass a long as parameter. This allows you to specify the maximum size (in
|
||||
bytes) of a file to download. If the file requested is larger than this value,
|
||||
the transfer will not start and CURLE_FILESIZE_EXCEEDED will be returned.
|
||||
|
||||
\fBNOTE:\fP The file size is not always known prior to download, and for such
|
||||
files this option has no effect even if the file transfer ends up being larger
|
||||
than this given limit. This concerns both FTP and HTTP transfers.
|
||||
The file size is not always known prior to download, and for such files this
|
||||
option has no effect even if the file transfer ends up being larger than this
|
||||
given limit. This concerns both FTP and HTTP transfers.
|
||||
.IP CURLOPT_MAXFILESIZE_LARGE
|
||||
Pass a curl_off_t as parameter. This allows you to specify the maximum size
|
||||
(in bytes) of a file to download. If the file requested is larger than this
|
||||
value, the transfer will not start and \fICURLE_FILESIZE_EXCEEDED\fP will be
|
||||
returned. (Added in 7.11.0)
|
||||
|
||||
\fBNOTE:\fP The file size is not always known prior to download, and for such
|
||||
files this option has no effect even if the file transfer ends up being larger
|
||||
than this given limit. This concerns both FTP and HTTP transfers.
|
||||
The file size is not always known prior to download, and for such files this
|
||||
option has no effect even if the file transfer ends up being larger than this
|
||||
given limit. This concerns both FTP and HTTP transfers.
|
||||
.IP CURLOPT_TIMECONDITION
|
||||
Pass a long as parameter. This defines how the \fICURLOPT_TIMEVALUE\fP time
|
||||
value is treated. You can set this parameter to \fICURL_TIMECOND_IFMODSINCE\fP
|
||||
or \fICURL_TIMECOND_IFUNMODSINCE\fP. This feature applies to HTTP and FTP.
|
||||
|
||||
\fBNOTE:\fP The last modification time of a file is not always known and in such
|
||||
instances this feature will have no effect even if the given time condition
|
||||
would have not been met.
|
||||
The last modification time of a file is not always known and in such instances
|
||||
this feature will have no effect even if the given time condition would have
|
||||
not been met.
|
||||
.IP CURLOPT_TIMEVALUE
|
||||
Pass a long as parameter. This should be the time in seconds since 1 jan 1970,
|
||||
and the time will be used in a condition as specified with
|
||||
@@ -881,8 +953,8 @@ considerable time and limiting operations to less than a few minutes risk
|
||||
aborting perfectly normal operations. This option will cause curl to use the
|
||||
SIGALRM to enable time-outing system calls.
|
||||
|
||||
\fBNOTE:\fP this is not recommended to use in unix multi-threaded programs, as
|
||||
it uses signals unless \fICURLOPT_NOSIGNAL\fP (see above) is set.
|
||||
In unix-like systems, this might cause signals to be used unless
|
||||
\fICURLOPT_NOSIGNAL\fP is set.
|
||||
.IP CURLOPT_LOW_SPEED_LIMIT
|
||||
Pass a long as parameter. It contains the transfer speed in bytes per second
|
||||
that the transfer should be below during \fICURLOPT_LOW_SPEED_TIME\fP seconds
|
||||
@@ -903,9 +975,9 @@ When reaching the maximum limit, curl uses the \fICURLOPT_CLOSEPOLICY\fP to
|
||||
figure out which of the existing connections to close to prevent the number of
|
||||
open connections to increase.
|
||||
|
||||
\fBNOTE:\fP if you already have performed transfers with this curl handle,
|
||||
setting a smaller MAXCONNECTS than before may cause open connections to get
|
||||
closed unnecessarily.
|
||||
If you already have performed transfers with this curl handle, setting a
|
||||
smaller MAXCONNECTS than before may cause open connections to get closed
|
||||
unnecessarily.
|
||||
.IP CURLOPT_CLOSEPOLICY
|
||||
Pass a long. This option sets what policy libcurl should use when the
|
||||
connection cache is filled and one of the open connections has to be closed to
|
||||
@@ -937,8 +1009,8 @@ it has connected, this option is of no more use. Set to zero to disable
|
||||
connection timeout (it will then only timeout on the system's internal
|
||||
timeouts). See also the \fICURLOPT_TIMEOUT\fP option.
|
||||
|
||||
\fBNOTE:\fP this is not recommended to use in unix multi-threaded programs, as
|
||||
it uses signals unless \fICURLOPT_NOSIGNAL\fP (see above) is set.
|
||||
In unix-like systems, this might cause signals to be used unless
|
||||
\fICURLOPT_NOSIGNAL\fP is set.
|
||||
.IP CURLOPT_IPRESOLVE
|
||||
Allows an application to select what kind of IP addresses to use when
|
||||
resolving host names. This is only interesting when using host names that
|
||||
@@ -975,9 +1047,9 @@ changed with \fICURLOPT_SSLKEYTYPE\fP.
|
||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||
the format of your private key. Supported formats are "PEM", "DER" and "ENG".
|
||||
|
||||
\fBNOTE:\fP The format "ENG" enables you to load the private key from a crypto
|
||||
engine. In this case \fICURLOPT_SSLKEY\fP is used as an identifier passed to
|
||||
the engine. You have to set the crypto engine with \fICURLOPT_SSLENGINE\fP.
|
||||
The format "ENG" enables you to load the private key from a crypto engine. In
|
||||
this case \fICURLOPT_SSLKEY\fP is used as an identifier passed to the
|
||||
engine. You have to set the crypto engine with \fICURLOPT_SSLENGINE\fP.
|
||||
\&"DER" format key file currently does not work because of a bug in OpenSSL.
|
||||
.IP CURLOPT_SSLKEYPASSWD
|
||||
Pass a pointer to a zero terminated string as parameter. It will be used as
|
||||
@@ -987,14 +1059,14 @@ Pass a pointer to a zero terminated string as parameter. It will be used as
|
||||
the identifier for the crypto engine you want to use for your private
|
||||
key.
|
||||
|
||||
\fBNOTE:\fP If the crypto device cannot be loaded,
|
||||
\fICURLE_SSL_ENGINE_NOTFOUND\fP is returned.
|
||||
If the crypto device cannot be loaded, \fICURLE_SSL_ENGINE_NOTFOUND\fP is
|
||||
returned.
|
||||
.IP CURLOPT_SSLENGINE_DEFAULT
|
||||
Sets the actual crypto engine as the default for (asymmetric) crypto
|
||||
operations.
|
||||
|
||||
\fBNOTE:\fP If the crypto device cannot be set,
|
||||
\fICURLE_SSL_ENGINE_SETFAILED\fP is returned.
|
||||
If the crypto device cannot be set, \fICURLE_SSL_ENGINE_SETFAILED\fP is
|
||||
returned.
|
||||
.IP CURLOPT_SSLVERSION
|
||||
Pass a long as parameter to control what version of SSL/TLS to attempt to use.
|
||||
The available options are:
|
||||
|
@@ -23,4 +23,4 @@ You must curl_free() the returned string when you're done with it.
|
||||
.SH RETURN VALUE
|
||||
A pointer to a zero terminated string or NULL if it failed.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_unescape(3), curl_free(3), RFC 2396
|
||||
.BR curl_unescape "(3), " curl_free "(3), " RFC 2396
|
||||
|
@@ -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.
|
||||
|
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)"
|
||||
|
@@ -243,7 +243,7 @@ where it'll store a human readable error message as well.
|
||||
If you then want to transfer another file, the handle is ready to be used
|
||||
again. Mind you, it is even preferred that you re-use an existing handle if
|
||||
you intend to make another transfer. libcurl will then attempt to re-use the
|
||||
previous
|
||||
previous connection.
|
||||
|
||||
.SH "Multi-threading Issues"
|
||||
The first basic rule is that you must \fBnever\fP share a libcurl handle (be
|
||||
|
@@ -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)
|
||||
|
@@ -309,6 +309,13 @@ typedef enum {
|
||||
CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */
|
||||
CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not
|
||||
accepted and we failed to login */
|
||||
CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */
|
||||
CURLE_TFTP_PERM, /* 69 - permission problem on server */
|
||||
CURLE_TFTP_DISKFULL, /* 70 - out of disk space on server */
|
||||
CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */
|
||||
CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
|
||||
CURLE_TFTP_EXISTS, /* 73 - File already exists */
|
||||
CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
|
||||
CURL_LAST /* never use! */
|
||||
} CURLcode;
|
||||
|
||||
@@ -890,6 +897,18 @@ 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),
|
||||
|
||||
/* Set to non-zero to skip the IP address received in a 227 PASV FTP server
|
||||
response. Typically used for FTP-SSL purposes but is not restricted to
|
||||
that. libcurl will then instead use the same IP address it used for the
|
||||
control connection. */
|
||||
CINIT(FTP_SKIP_PASV_IP, LONG, 137),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -1202,11 +1221,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 +1262,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
|
||||
|
@@ -28,7 +28,13 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.14.0-CVS"
|
||||
#define LIBCURL_VERSION "7.15.0-CVS"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 15
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -37,19 +43,16 @@
|
||||
0xXXYYZZ
|
||||
|
||||
Where XX, YY and ZZ are the main version, release and patch numbers in
|
||||
hexadecimal. All three numbers are always represented using two digits. 1.2
|
||||
would appear as "0x010200" while version 9.11.7 appears as "0x090b07".
|
||||
hexadecimal (using 8 bits each). All three numbers are always represented
|
||||
using two digits. 1.2 would appear as "0x010200" while version 9.11.7
|
||||
appears as "0x090b07".
|
||||
|
||||
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 6-digit (24 bits) 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.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x070e00
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 14
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
#define LIBCURL_VERSION_NUM ((LIBCURL_VERSION_MAJOR << 16) | \
|
||||
(LIBCURL_VERSION_MINOR << 8) | \
|
||||
LIBCURL_VERSION_PATCH)
|
||||
|
||||
#endif /* __CURL_CURLVER_H */
|
||||
|
@@ -44,7 +44,7 @@ OBJS = $(OBJ_DIR)\transfer.obj $(OBJ_DIR)\file.obj &
|
||||
$(OBJ_DIR)\hostip6.obj $(OBJ_DIR)\inet_ntop.obj &
|
||||
$(OBJ_DIR)\hostsyn.obj $(OBJ_DIR)\parsedate.obj &
|
||||
$(OBJ_DIR)\select.obj $(OBJ_DIR)\sslgen.obj &
|
||||
$(OBJ_DIR)\gtls.obj
|
||||
$(OBJ_DIR)\gtls.obj $(OBJ_DIR)\tftp.obj
|
||||
|
||||
RESOURCE = $(OBJ_DIR)\libcurl.res
|
||||
|
||||
@@ -362,3 +362,9 @@ $(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
|
||||
|
||||
$(OBJ_DIR)\tftp.obj: tftp.c setup.h config-win32.h urldata.h cookie.h &
|
||||
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
|
||||
..\include\curl\multi.h formdata.h http_chunks.h hostip.h hash.h llist.h &
|
||||
transfer.h sendf.h tftp.h progress.h ..\include\curl\mprintf.h memory.h &
|
||||
select.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 gtls.c sslgen.c
|
||||
select.c gtls.c sslgen.c tftp.c
|
||||
|
||||
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
||||
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
||||
@@ -18,5 +18,5 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
||||
share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \
|
||||
inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h \
|
||||
setup.h transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h \
|
||||
gtls.h
|
||||
gtls.h tftp.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.2
|
||||
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.7g
|
||||
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) >> $@
|
||||
@@ -293,7 +301,7 @@ config.h: Makefile.netware
|
||||
@echo $(DL)*/$(DL) >> $@
|
||||
@echo $(DL)#define OS "i586-pc-NetWare"$(DL) >> $@
|
||||
@echo $(DL)#define VERSION "$(LIBCURL_VERSION_STR)"$(DL) >> $@
|
||||
@echo $(DL)#define PACKAGE_BUGREPORT "curl-bug@haxx.se"$(DL) >> $@
|
||||
@echo $(DL)#define PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/"$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_DLFCN_H 1$(DL) >> $@
|
||||
@@ -336,6 +344,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_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
|
||||
@@ -355,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) >> $@
|
||||
|
@@ -469,6 +469,7 @@ X_OBJS= \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\select.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
all : $(TARGET)
|
||||
|
@@ -1,17 +0,0 @@
|
||||
Things to fix for the GnuTLS support
|
||||
====================================
|
||||
|
||||
* make the configure --with-ssl option first check for OpenSSL and then for
|
||||
GnuTLS if OpenSSL wasn't detected.
|
||||
|
||||
* 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?
|
||||
|
||||
SRP for TLS
|
||||
|
||||
* Work out a common method with Peter Sylvester's OpenSSL-patch for SRP
|
||||
on the TLS to provide name and password
|
@@ -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
|
||||
|
@@ -359,13 +359,13 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
|
||||
} /* 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;
|
||||
}
|
||||
|
||||
@@ -631,8 +631,9 @@ singleipconnect(struct connectdata *conn,
|
||||
int error;
|
||||
bool conected;
|
||||
struct SessionHandle *data = conn->data;
|
||||
curl_socket_t sockfd = socket(ai->ai_family, ai->ai_socktype,
|
||||
ai->ai_protocol);
|
||||
curl_socket_t sockfd;
|
||||
|
||||
sockfd = socket(ai->ai_family, conn->socktype, ai->ai_protocol);
|
||||
if (sockfd == CURL_SOCKET_BAD)
|
||||
return CURL_SOCKET_BAD;
|
||||
|
||||
@@ -660,7 +661,11 @@ singleipconnect(struct connectdata *conn,
|
||||
/* set socket non-blocking */
|
||||
Curl_nonblock(sockfd, TRUE);
|
||||
|
||||
rc = connect(sockfd, ai->ai_addr, (socklen_t)ai->ai_addrlen);
|
||||
/* Connect TCP sockets, bind UDP */
|
||||
if(conn->socktype == SOCK_STREAM)
|
||||
rc = connect(sockfd, ai->ai_addr, (socklen_t)ai->ai_addrlen);
|
||||
else
|
||||
rc = 0;
|
||||
|
||||
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()
|
||||
@@ -317,7 +343,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
co->expires = (long)curl_getdate(what, &now);
|
||||
co->expires = curl_getdate(what, &now);
|
||||
}
|
||||
else if(!co->name) {
|
||||
co->name = strdup(name);
|
||||
@@ -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
|
||||
|
36
lib/easy.c
36
lib/easy.c
@@ -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;
|
||||
|
51
lib/ftp.c
51
lib/ftp.c
@@ -209,12 +209,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 */
|
||||
|
||||
@@ -843,7 +843,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
* Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype):
|
||||
*/
|
||||
if (ai->ai_socktype == 0)
|
||||
ai->ai_socktype = SOCK_STREAM;
|
||||
ai->ai_socktype = conn->socktype;
|
||||
|
||||
portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (portsock == CURL_SOCKET_BAD) {
|
||||
@@ -1110,7 +1110,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;
|
||||
}
|
||||
|
||||
@@ -1586,8 +1586,18 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
return CURLE_FTP_WEIRD_227_FORMAT;
|
||||
}
|
||||
|
||||
snprintf(newhost, sizeof(newhost),
|
||||
"%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
/* we got OK from server */
|
||||
if(data->set.ftp_skip_ip) {
|
||||
/* told to ignore the remotely given IP but instead use the one we used
|
||||
for the control connection */
|
||||
infof(data, "Skips %d.%d.%d.%d for data connection, uses %s instead\n",
|
||||
ip[0], ip[1], ip[2], ip[3],
|
||||
conn->ip_addr_str);
|
||||
snprintf(newhost, sizeof(newhost), "%s", conn->ip_addr_str);
|
||||
}
|
||||
else
|
||||
snprintf(newhost, sizeof(newhost),
|
||||
"%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
newport = (port[0]<<8) + port[1];
|
||||
}
|
||||
else if(ftp->count1 == 0) {
|
||||
@@ -1607,8 +1617,6 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
return CURLE_FTP_WEIRD_PASV_REPLY;
|
||||
}
|
||||
|
||||
/* we got OK from server */
|
||||
|
||||
if(data->change.proxy && *data->change.proxy) {
|
||||
/*
|
||||
* This is a tunnel through a http proxy and we need to connect to the
|
||||
@@ -1670,8 +1678,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;
|
||||
}
|
||||
@@ -1791,7 +1798,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||||
switch(data->set.timecondition) {
|
||||
case CURL_TIMECOND_IFMODSINCE:
|
||||
default:
|
||||
if(data->info.filetime < data->set.timevalue) {
|
||||
if(data->info.filetime <= data->set.timevalue) {
|
||||
infof(data, "The requested document is not new enough\n");
|
||||
ftp->no_transfer = TRUE; /* mark this to not transfer data */
|
||||
state(conn, FTP_STOP);
|
||||
@@ -1826,10 +1833,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)
|
||||
@@ -2738,8 +2752,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;
|
||||
}
|
||||
@@ -3164,7 +3178,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
||||
*connected = conn->bits.tcpconnect;
|
||||
|
||||
if(*dophase_done)
|
||||
DEBUGF(infof(conn->data, "DO phase is comlete\n"));
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -3797,6 +3811,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
|
||||
/* Failure detected, close the second socket if it was created already */
|
||||
sclose(conn->sock[SECONDARYSOCKET]);
|
||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||
return result;
|
||||
}
|
||||
|
||||
if(ftp->no_transfer)
|
||||
@@ -3821,7 +3836,7 @@ CURLcode Curl_ftp_doing(struct connectdata *conn,
|
||||
if(*dophase_done) {
|
||||
result = ftp_dophase_done(conn, FALSE /* not connected */);
|
||||
|
||||
DEBUGF(infof(conn->data, "DO phase is comlete\n"));
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@@ -184,6 +184,9 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
||||
case CURLINFO_SSL_ENGINES:
|
||||
*param_slistp = Curl_ssl_engines_list(data);
|
||||
break;
|
||||
case CURLINFO_COOKIELIST:
|
||||
*param_slistp = Curl_cookie_list(data);
|
||||
break;
|
||||
default:
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
|
@@ -151,13 +151,18 @@ Curl_gtls_connect(struct connectdata *conn,
|
||||
|
||||
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) {
|
||||
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 */
|
||||
|
@@ -172,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
|
||||
@@ -424,7 +423,11 @@ Curl_addrinfo *Curl_he2ai(struct hostent *he, int port)
|
||||
prevai->ai_next = ai;
|
||||
|
||||
ai->ai_family = AF_INET; /* we only support this */
|
||||
ai->ai_socktype = SOCK_STREAM; /* we only support this */
|
||||
|
||||
/* we return all names as STREAM, so when using this address for TFTP
|
||||
the type must be ignored and conn->socktype be used instead! */
|
||||
ai->ai_socktype = SOCK_STREAM;
|
||||
|
||||
ai->ai_addrlen = sizeof(struct sockaddr_in);
|
||||
/* make the ai_addr point to the address immediately following this struct
|
||||
and use that area to store the address */
|
||||
|
@@ -202,6 +202,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
struct addrinfo hints, *res;
|
||||
int error;
|
||||
char sbuf[NI_MAXSERV];
|
||||
char *sbufptr = NULL;
|
||||
char addrbuf[128];
|
||||
curl_socket_t s;
|
||||
int pf;
|
||||
@@ -251,10 +252,15 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = pf;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
hints.ai_socktype = conn->socktype;
|
||||
|
||||
hints.ai_flags = ai_flags;
|
||||
snprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
error = getaddrinfo(hostname, sbuf, &hints, &res);
|
||||
if(port) {
|
||||
snprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
sbufptr=sbuf;
|
||||
}
|
||||
error = getaddrinfo(hostname, sbufptr, &hints, &res);
|
||||
if (error) {
|
||||
infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
|
||||
return NULL;
|
||||
|
238
lib/hostthre.c
238
lib/hostthre.c
@@ -88,6 +88,10 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#if defined(_MSC_VER) && defined(CURL_NO__BEGINTHREADEX)
|
||||
#pragma message ("No _beginthreadex() available in this RTL")
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* Only for Windows threaded name resolves builds
|
||||
**********************************************************************/
|
||||
@@ -157,11 +161,119 @@ struct thread_data {
|
||||
FILE *stderr_file;
|
||||
HANDLE mutex_waiting; /* marks that we are still waiting for a resolve */
|
||||
HANDLE event_resolved; /* marks that the thread obtained the information */
|
||||
HANDLE event_thread_started; /* marks that the thread has initialized and
|
||||
started */
|
||||
HANDLE mutex_terminate; /* serializes access to flag_terminate */
|
||||
HANDLE event_terminate; /* flag for thread to terminate instead of calling
|
||||
callbacks */
|
||||
#ifdef CURLRES_IPV6
|
||||
struct addrinfo hints;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Data for synchronization between resolver thread and its parent */
|
||||
struct thread_sync_data {
|
||||
HANDLE mutex_waiting; /* thread_data.mutex_waiting duplicate */
|
||||
HANDLE mutex_terminate; /* thread_data.mutex_terminate duplicate */
|
||||
HANDLE event_terminate; /* thread_data.event_terminate duplicate */
|
||||
char * hostname; /* hostname to resolve, Curl_async.hostname
|
||||
duplicate */
|
||||
};
|
||||
|
||||
/* Destroy resolver thread synchronization data */
|
||||
void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
||||
{
|
||||
if (tsd->hostname) {
|
||||
free(tsd->hostname);
|
||||
tsd->hostname = NULL;
|
||||
}
|
||||
if (tsd->event_terminate) {
|
||||
CloseHandle(tsd->event_terminate);
|
||||
tsd->event_terminate = NULL;
|
||||
}
|
||||
if (tsd->mutex_terminate) {
|
||||
CloseHandle(tsd->mutex_terminate);
|
||||
tsd->mutex_terminate = NULL;
|
||||
}
|
||||
if (tsd->mutex_waiting) {
|
||||
CloseHandle(tsd->mutex_waiting);
|
||||
tsd->mutex_waiting = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize resolver thread synchronization data */
|
||||
BOOL init_thread_sync_data(struct thread_data * td,
|
||||
char * hostname,
|
||||
struct thread_sync_data * tsd)
|
||||
{
|
||||
HANDLE curr_proc = GetCurrentProcess();
|
||||
|
||||
memset(tsd, 0, sizeof(tsd));
|
||||
if (!DuplicateHandle(curr_proc, td->mutex_waiting,
|
||||
curr_proc, &tsd->mutex_waiting, 0, FALSE,
|
||||
DUPLICATE_SAME_ACCESS)) {
|
||||
/* failed to duplicate the mutex, no point in continuing */
|
||||
destroy_thread_sync_data(tsd);
|
||||
return FALSE;
|
||||
}
|
||||
if (!DuplicateHandle(curr_proc, td->mutex_terminate,
|
||||
curr_proc, &tsd->mutex_terminate, 0, FALSE,
|
||||
DUPLICATE_SAME_ACCESS)) {
|
||||
/* failed to duplicate the mutex, no point in continuing */
|
||||
destroy_thread_sync_data(tsd);
|
||||
return FALSE;
|
||||
}
|
||||
if (!DuplicateHandle(curr_proc, td->event_terminate,
|
||||
curr_proc, &tsd->event_terminate, 0, FALSE,
|
||||
DUPLICATE_SAME_ACCESS)) {
|
||||
/* failed to duplicate the event, no point in continuing */
|
||||
destroy_thread_sync_data(tsd);
|
||||
return FALSE;
|
||||
}
|
||||
/* Copying hostname string because original can be destroyed by parent
|
||||
* thread during gethostbyname execution.
|
||||
*/
|
||||
tsd->hostname = strdup(hostname);
|
||||
if (!tsd->hostname) {
|
||||
/* Memory allocation failed */
|
||||
destroy_thread_sync_data(tsd);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* acquire resolver thread synchronization */
|
||||
BOOL acquire_thread_sync(struct thread_sync_data * tsd)
|
||||
{
|
||||
/* is the thread initiator still waiting for us ? */
|
||||
if (WaitForSingleObject(tsd->mutex_waiting, 0) == WAIT_TIMEOUT) {
|
||||
/* yes, it is */
|
||||
|
||||
/* Waiting access to event_terminate */
|
||||
if (WaitForSingleObject(tsd->mutex_terminate, INFINITE) != WAIT_OBJECT_0) {
|
||||
/* Something went wrong - now just ignoring */
|
||||
}
|
||||
else {
|
||||
if (WaitForSingleObject(tsd->event_terminate, 0) != WAIT_TIMEOUT) {
|
||||
/* Parent thread signaled us to terminate.
|
||||
* This means that all data in conn->async is now destroyed
|
||||
* and we cannot use it.
|
||||
*/
|
||||
}
|
||||
else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* release resolver thread synchronization */
|
||||
void release_thread_sync(struct thread_sync_data * tsd)
|
||||
{
|
||||
ReleaseMutex(tsd->mutex_terminate);
|
||||
}
|
||||
|
||||
#if defined(CURLRES_IPV4)
|
||||
/*
|
||||
* gethostbyname_thread() resolves a name, calls the Curl_addrinfo4_callback
|
||||
@@ -177,17 +289,13 @@ static unsigned __stdcall gethostbyname_thread (void *arg)
|
||||
struct hostent *he;
|
||||
int rc = 0;
|
||||
|
||||
/* Duplicate the passed mutex handle.
|
||||
/* Duplicate the passed mutex and event handles.
|
||||
* This allows us to use it even after the container gets destroyed
|
||||
* due to a resolver timeout.
|
||||
*/
|
||||
HANDLE mutex_waiting = NULL;
|
||||
HANDLE curr_proc = GetCurrentProcess();
|
||||
|
||||
if (!DuplicateHandle(curr_proc, td->mutex_waiting,
|
||||
curr_proc, &mutex_waiting, 0, FALSE,
|
||||
DUPLICATE_SAME_ACCESS)) {
|
||||
/* failed to duplicate the mutex, no point in continuing */
|
||||
struct thread_sync_data tsd = { 0,0,0,NULL };
|
||||
if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) {
|
||||
/* thread synchronization data initialization failed */
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -200,17 +308,18 @@ static unsigned __stdcall gethostbyname_thread (void *arg)
|
||||
#endif
|
||||
|
||||
WSASetLastError (conn->async.status = NO_DATA); /* pending status */
|
||||
he = gethostbyname (conn->async.hostname);
|
||||
|
||||
/* is the thread initiator still waiting for us ? */
|
||||
if (WaitForSingleObject(mutex_waiting, 0) == WAIT_TIMEOUT) {
|
||||
/* yes, it is */
|
||||
/* Signaling that we have initialized all copies of data and handles we
|
||||
need */
|
||||
SetEvent(td->event_thread_started);
|
||||
|
||||
/* Mark that we have obtained the information, and that we are
|
||||
* calling back with it.
|
||||
*/
|
||||
he = gethostbyname (tsd.hostname);
|
||||
|
||||
/* is parent thread waiting for us and are we able to access conn members? */
|
||||
if (acquire_thread_sync(&tsd)) {
|
||||
/* Mark that we have obtained the information, and that we are calling
|
||||
* back with it. */
|
||||
SetEvent(td->event_resolved);
|
||||
|
||||
if (he) {
|
||||
rc = Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he);
|
||||
}
|
||||
@@ -219,10 +328,11 @@ static unsigned __stdcall gethostbyname_thread (void *arg)
|
||||
}
|
||||
TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
|
||||
he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
|
||||
release_thread_sync(&tsd);
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
CloseHandle(mutex_waiting);
|
||||
destroy_thread_sync_data(&tsd);
|
||||
|
||||
return (rc);
|
||||
/* An implicit _endthreadex() here */
|
||||
@@ -244,18 +354,15 @@ static unsigned __stdcall getaddrinfo_thread (void *arg)
|
||||
struct addrinfo *res;
|
||||
char service [NI_MAXSERV];
|
||||
int rc;
|
||||
struct addrinfo hints = td->hints;
|
||||
|
||||
/* Duplicate the passed mutex handle.
|
||||
* This allows us to use it even after the container gets destroyed
|
||||
* due to a resolver timeout.
|
||||
*/
|
||||
HANDLE mutex_waiting = NULL;
|
||||
HANDLE curr_proc = GetCurrentProcess();
|
||||
|
||||
if (!DuplicateHandle(curr_proc, td->mutex_waiting,
|
||||
curr_proc, &mutex_waiting, 0, FALSE,
|
||||
DUPLICATE_SAME_ACCESS)) {
|
||||
/* failed to duplicate the mutex, no point in continuing */
|
||||
struct thread_sync_data tsd = { 0,0,0,NULL };
|
||||
if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) {
|
||||
/* thread synchronization data initialization failed */
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -267,15 +374,16 @@ static unsigned __stdcall getaddrinfo_thread (void *arg)
|
||||
|
||||
WSASetLastError(conn->async.status = NO_DATA); /* pending status */
|
||||
|
||||
rc = getaddrinfo(conn->async.hostname, service, &td->hints, &res);
|
||||
/* Signaling that we have initialized all copies of data and handles we
|
||||
need */
|
||||
SetEvent(td->event_thread_started);
|
||||
|
||||
/* is the thread initiator still waiting for us ? */
|
||||
if (WaitForSingleObject(mutex_waiting, 0) == WAIT_TIMEOUT) {
|
||||
/* yes, it is */
|
||||
rc = getaddrinfo(tsd.hostname, service, &hints, &res);
|
||||
|
||||
/* Mark that we have obtained the information, and that we are
|
||||
* calling back with it.
|
||||
*/
|
||||
/* is parent thread waiting for us and are we able to access conn members? */
|
||||
if (acquire_thread_sync(&tsd)) {
|
||||
/* Mark that we have obtained the information, and that we are calling
|
||||
back with it. */
|
||||
SetEvent(td->event_resolved);
|
||||
|
||||
if (rc == 0) {
|
||||
@@ -288,10 +396,11 @@ static unsigned __stdcall getaddrinfo_thread (void *arg)
|
||||
rc = Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL);
|
||||
TRACE(("Winsock-error %d, no address\n", conn->async.status));
|
||||
}
|
||||
release_thread_sync(&tsd);
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
CloseHandle(mutex_waiting);
|
||||
destroy_thread_sync_data(&tsd);
|
||||
|
||||
return (rc);
|
||||
/* An implicit _endthreadex() here */
|
||||
@@ -299,7 +408,7 @@ static unsigned __stdcall getaddrinfo_thread (void *arg)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_destroy_thread_data() cleans up async resolver data.
|
||||
* Curl_destroy_thread_data() cleans up async resolver data and thread handle.
|
||||
* Complementary of ares_destroy.
|
||||
*/
|
||||
void Curl_destroy_thread_data (struct Curl_async *async)
|
||||
@@ -311,6 +420,24 @@ void Curl_destroy_thread_data (struct Curl_async *async)
|
||||
struct thread_data *td = (struct thread_data*) async->os_specific;
|
||||
curl_socket_t sock = td->dummy_sock;
|
||||
|
||||
if (td->mutex_terminate && td->event_terminate) {
|
||||
/* Signaling resolver thread to terminate */
|
||||
if (WaitForSingleObject(td->mutex_terminate, INFINITE) == WAIT_OBJECT_0) {
|
||||
SetEvent(td->event_terminate);
|
||||
ReleaseMutex(td->mutex_terminate);
|
||||
}
|
||||
else {
|
||||
/* Something went wrong - just ignoring it */
|
||||
}
|
||||
}
|
||||
|
||||
if (td->mutex_terminate)
|
||||
CloseHandle(td->mutex_terminate);
|
||||
if (td->event_terminate)
|
||||
CloseHandle(td->event_terminate);
|
||||
if (td->event_thread_started)
|
||||
CloseHandle(td->event_thread_started);
|
||||
|
||||
if (sock != CURL_SOCKET_BAD)
|
||||
sclose(sock);
|
||||
|
||||
@@ -321,6 +448,9 @@ void Curl_destroy_thread_data (struct Curl_async *async)
|
||||
if (td->event_resolved)
|
||||
CloseHandle(td->event_resolved);
|
||||
|
||||
if (td->thread_hnd)
|
||||
CloseHandle(td->thread_hnd);
|
||||
|
||||
free(async->os_specific);
|
||||
}
|
||||
async->hostname = NULL;
|
||||
@@ -338,6 +468,7 @@ static bool init_resolve_thread (struct connectdata *conn,
|
||||
const Curl_addrinfo *hints)
|
||||
{
|
||||
struct thread_data *td = calloc(sizeof(*td), 1);
|
||||
HANDLE thread_and_event[2] = {0};
|
||||
|
||||
if (!td) {
|
||||
SetLastError(ENOMEM);
|
||||
@@ -378,6 +509,31 @@ static bool init_resolve_thread (struct connectdata *conn,
|
||||
SetLastError(EAGAIN);
|
||||
return FALSE;
|
||||
}
|
||||
/* Create the mutex used to serialize access to event_terminated
|
||||
* between us and resolver thread.
|
||||
*/
|
||||
td->mutex_terminate = CreateMutex(NULL, FALSE, NULL);
|
||||
if (td->mutex_terminate == NULL) {
|
||||
Curl_destroy_thread_data(&conn->async);
|
||||
SetLastError(EAGAIN);
|
||||
return FALSE;
|
||||
}
|
||||
/* Create the event used to signal thread that it should terminate.
|
||||
*/
|
||||
td->event_terminate = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (td->event_terminate == NULL) {
|
||||
Curl_destroy_thread_data(&conn->async);
|
||||
SetLastError(EAGAIN);
|
||||
return FALSE;
|
||||
}
|
||||
/* Create the event used by thread to inform it has initialized its own data.
|
||||
*/
|
||||
td->event_thread_started = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (td->event_thread_started == NULL) {
|
||||
Curl_destroy_thread_data(&conn->async);
|
||||
SetLastError(EAGAIN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
td->stderr_file = stderr;
|
||||
|
||||
@@ -403,6 +559,18 @@ static bool init_resolve_thread (struct connectdata *conn,
|
||||
Curl_destroy_thread_data(&conn->async);
|
||||
return FALSE;
|
||||
}
|
||||
/* Waiting until the thread will initialize its data or it will exit due errors.
|
||||
*/
|
||||
thread_and_event[0] = td->thread_hnd;
|
||||
thread_and_event[1] = td->event_thread_started;
|
||||
if (WaitForMultipleObjects(sizeof(thread_and_event) /
|
||||
sizeof(thread_and_event[0]),
|
||||
thread_and_event, FALSE,
|
||||
INFINITE) == WAIT_FAILED) {
|
||||
/* The resolver thread has been created,
|
||||
* most probably it works now - ignoring this "minor" error
|
||||
*/
|
||||
}
|
||||
/* This socket is only to keep Curl_resolv_fdset() and select() happy;
|
||||
* should never become signalled for read/write since it's unbound but
|
||||
* Windows needs atleast 1 socket in select().
|
||||
@@ -481,8 +649,6 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
|
||||
TRACE(("elapsed %lu ms\n", GetTickCount()-ticks));
|
||||
|
||||
CloseHandle(td->thread_hnd);
|
||||
|
||||
if(entry)
|
||||
*entry = conn->async.dns;
|
||||
|
||||
@@ -645,7 +811,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = pf;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_socktype = conn->socktype;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
itoa(port, sbuf, 10);
|
||||
|
||||
|
57
lib/http.c
57
lib/http.c
@@ -96,6 +96,7 @@
|
||||
#include "memory.h"
|
||||
#include "select.h"
|
||||
#include "parsedate.h" /* for the week day and month names */
|
||||
#include "strtoofft.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -1053,10 +1054,9 @@ Curl_compareheader(char *headerline, /* line to check */
|
||||
}
|
||||
|
||||
/*
|
||||
* ConnectHTTPProxyTunnel() requires that we're connected to a HTTP
|
||||
* proxy. This function will issue the necessary commands to get a seamless
|
||||
* tunnel through this proxy. After that, the socket can be used just as a
|
||||
* normal socket.
|
||||
* Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This
|
||||
* function will issue the necessary commands to get a seamless tunnel through
|
||||
* this proxy. After that, the socket can be used just as a normal socket.
|
||||
*
|
||||
* This badly needs to be rewritten. CONNECT should be sent and dealt with
|
||||
* like any ordinary HTTP request, and not specially crafted like this. This
|
||||
@@ -1064,10 +1064,10 @@ Curl_compareheader(char *headerline, /* line to check */
|
||||
* much work to do at the moment.
|
||||
*/
|
||||
|
||||
CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
int sockindex,
|
||||
char *hostname,
|
||||
int remote_port)
|
||||
CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
int sockindex,
|
||||
char *hostname,
|
||||
int remote_port)
|
||||
{
|
||||
int subversion=0;
|
||||
struct SessionHandle *data=conn->data;
|
||||
@@ -1076,7 +1076,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
int res;
|
||||
size_t nread; /* total size read */
|
||||
int perline; /* count bytes per line */
|
||||
bool keepon=TRUE;
|
||||
int keepon=TRUE;
|
||||
ssize_t gotbytes;
|
||||
char *ptr;
|
||||
long timeout =
|
||||
@@ -1085,6 +1085,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
char *host_port;
|
||||
curl_socket_t tunnelsocket = conn->sock[sockindex];
|
||||
send_buffer *req_buffer;
|
||||
curl_off_t cl=0;
|
||||
|
||||
#define SELECT_OK 0
|
||||
#define SELECT_ERROR 1
|
||||
@@ -1215,6 +1216,18 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
int i;
|
||||
|
||||
nread += gotbytes;
|
||||
|
||||
if(keepon > TRUE) {
|
||||
/* This means we are currently ignoring a response-body, so we
|
||||
simply count down our counter and make sure to break out of the
|
||||
loop when we're done! */
|
||||
cl -= gotbytes;
|
||||
if(cl<=0) {
|
||||
keepon = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
for(i = 0; i < gotbytes; ptr++, i++) {
|
||||
perline++; /* amount of bytes in this line so far */
|
||||
if(*ptr=='\n') {
|
||||
@@ -1242,7 +1255,21 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
if(('\r' == line_start[0]) ||
|
||||
('\n' == line_start[0])) {
|
||||
/* end of response-headers from the proxy */
|
||||
keepon=FALSE;
|
||||
if(cl && (407 == k->httpcode) && !data->state.authproblem) {
|
||||
/* If we get a 407 response code with content length when we
|
||||
* have no auth problem, we must ignore the whole
|
||||
* response-body */
|
||||
keepon = 2;
|
||||
infof(data, "Ignore %" FORMAT_OFF_T
|
||||
" bytes of response-body\n", cl);
|
||||
cl -= (gotbytes - i);/* remove the remaining chunk of what
|
||||
we already read */
|
||||
if(cl<=0)
|
||||
/* if the whole thing was already read, we are done! */
|
||||
keepon=FALSE;
|
||||
}
|
||||
else
|
||||
keepon = FALSE;
|
||||
break; /* breaks out of for-loop, not switch() */
|
||||
}
|
||||
|
||||
@@ -1257,6 +1284,10 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else if(checkprefix("Content-Length:", line_start)) {
|
||||
cl = curlx_strtoofft(line_start + strlen("Content-Length:"),
|
||||
NULL, 10);
|
||||
}
|
||||
else if(2 == sscanf(line_start, "HTTP/1.%d %d",
|
||||
&subversion,
|
||||
&k->httpcode)) {
|
||||
@@ -1323,9 +1354,9 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
||||
if(conn->bits.tunnel_proxy) {
|
||||
|
||||
/* either SSL over proxy, or explicitly asked for */
|
||||
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;
|
||||
}
|
||||
|
@@ -29,9 +29,9 @@ bool Curl_compareheader(char *headerline, /* line to check */
|
||||
const char *content); /* content string to find */
|
||||
|
||||
/* ftp can use this as well */
|
||||
CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
int tunnelsocket,
|
||||
char *hostname, int remote_port);
|
||||
CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
int tunnelsocket,
|
||||
char *hostname, int remote_port);
|
||||
|
||||
/* protocol-specific functions set up to be called by the main engine */
|
||||
CURLcode Curl_http(struct connectdata *conn, bool *done);
|
||||
|
@@ -153,10 +153,17 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
if(*datap == '\n') {
|
||||
/* we're now expecting data to come, unless size was zero! */
|
||||
if(0 == ch->datasize) {
|
||||
ch->state = CHUNK_STOP; /* stop reading! */
|
||||
if(1 == length) {
|
||||
/* This was the final byte, return right now */
|
||||
return CHUNKE_STOP;
|
||||
if (conn->bits.trailerHdrPresent!=TRUE) {
|
||||
/* No Trailer: header found - revert to original Curl processing */
|
||||
ch->state = CHUNK_STOP;
|
||||
if (1 == length) {
|
||||
/* This is the final byte, return right now */
|
||||
return CHUNKE_STOP;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ch->state = CHUNK_TRAILER; /* attempt to read trailers */
|
||||
conn->trlPos=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -250,6 +257,64 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
return CHUNKE_BAD_CHUNK;
|
||||
break;
|
||||
|
||||
case CHUNK_TRAILER:
|
||||
/* conn->trailer is assumed to be freed in url.c on a
|
||||
connection basis */
|
||||
if (conn->trlPos >= conn->trlMax) {
|
||||
char *ptr;
|
||||
if(conn->trlMax) {
|
||||
conn->trlMax *= 2;
|
||||
ptr = (char*)realloc(conn->trailer,conn->trlMax);
|
||||
}
|
||||
else {
|
||||
conn->trlMax=128;
|
||||
ptr = (char*)malloc(conn->trlMax);
|
||||
}
|
||||
if(!ptr)
|
||||
return CHUNKE_OUT_OF_MEMORY;
|
||||
conn->trailer = ptr;
|
||||
}
|
||||
conn->trailer[conn->trlPos++]=*datap;
|
||||
|
||||
if(*datap == '\r')
|
||||
ch->state = CHUNK_TRAILER_CR;
|
||||
else {
|
||||
datap++;
|
||||
length--;
|
||||
}
|
||||
break;
|
||||
|
||||
case CHUNK_TRAILER_CR:
|
||||
if(*datap == '\r') {
|
||||
ch->state = CHUNK_TRAILER_POSTCR;
|
||||
datap++;
|
||||
length--;
|
||||
}
|
||||
else
|
||||
return CHUNKE_BAD_CHUNK;
|
||||
break;
|
||||
|
||||
case CHUNK_TRAILER_POSTCR:
|
||||
if (*datap == '\n') {
|
||||
conn->trailer[conn->trlPos++]='\n';
|
||||
conn->trailer[conn->trlPos]=0;
|
||||
if (conn->trlPos==2) {
|
||||
ch->state = CHUNK_STOP;
|
||||
return CHUNKE_STOP;
|
||||
}
|
||||
else {
|
||||
Curl_client_write(conn->data, CLIENTWRITE_HEADER,
|
||||
conn->trailer, conn->trlPos);
|
||||
}
|
||||
ch->state = CHUNK_TRAILER;
|
||||
conn->trlPos=0;
|
||||
datap++;
|
||||
length--;
|
||||
}
|
||||
else
|
||||
return CHUNKE_BAD_CHUNK;
|
||||
break;
|
||||
|
||||
case CHUNK_STOP:
|
||||
/* If we arrive here, there is data left in the end of the buffer
|
||||
even if there's no more chunks to read */
|
||||
|
@@ -52,8 +52,8 @@ typedef enum {
|
||||
/* POSTCR should get a CR and nothing else, then move to POSTLF */
|
||||
CHUNK_POSTCR,
|
||||
|
||||
/* POSTLF should get a LF and nothing else, then move back to HEX as
|
||||
the CRLF combination marks the end of a chunk */
|
||||
/* POSTLF should get a LF and nothing else, then move back to HEX as the
|
||||
CRLF combination marks the end of a chunk */
|
||||
CHUNK_POSTLF,
|
||||
|
||||
/* This is mainly used to really mark that we're out of the game.
|
||||
@@ -62,7 +62,22 @@ typedef enum {
|
||||
buffer! */
|
||||
CHUNK_STOP,
|
||||
|
||||
/* At this point optional trailer headers can be found, unless the next line
|
||||
is CRLF */
|
||||
CHUNK_TRAILER,
|
||||
|
||||
/* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR.
|
||||
Next char must be a LF */
|
||||
CHUNK_TRAILER_CR,
|
||||
|
||||
/* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be
|
||||
signalled If this is an empty trailer CHUNKE_STOP will be signalled.
|
||||
Otherwise the trailer will be broadcasted via Curl_client_write() and the
|
||||
next state will be CHUNK_TRAILER */
|
||||
CHUNK_TRAILER_POSTCR,
|
||||
|
||||
CHUNK_LAST /* never use */
|
||||
|
||||
} ChunkyState;
|
||||
|
||||
typedef enum {
|
||||
@@ -74,6 +89,7 @@ typedef enum {
|
||||
CHUNKE_WRITE_ERROR,
|
||||
CHUNKE_STATE_ERROR,
|
||||
CHUNKE_BAD_ENCODING,
|
||||
CHUNKE_OUT_OF_MEMORY,
|
||||
CHUNKE_LAST
|
||||
} CHUNKcode;
|
||||
|
||||
|
@@ -387,6 +387,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
ULONG attrs;
|
||||
const char *user;
|
||||
int domlen;
|
||||
TimeStamp tsDummy; /* For Windows 9x compatibility of SPPI calls */
|
||||
|
||||
ntlm_sspi_cleanup(ntlm);
|
||||
|
||||
@@ -430,8 +431,8 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
|
||||
if (AcquireCredentialsHandle(
|
||||
NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND, NULL, ntlm->p_identity,
|
||||
NULL, NULL, &ntlm->handle, NULL
|
||||
) != SEC_E_OK) {
|
||||
NULL, NULL, &ntlm->handle, &tsDummy
|
||||
) != SEC_E_OK) {
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -447,12 +448,23 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONNECTION,
|
||||
0, SECURITY_NETWORK_DREP, NULL, 0,
|
||||
&ntlm->c_handle, &desc, &attrs, NULL
|
||||
);
|
||||
&ntlm->c_handle, &desc, &attrs, &tsDummy
|
||||
);
|
||||
|
||||
if (status == SEC_I_COMPLETE_AND_CONTINUE ||
|
||||
status == SEC_I_CONTINUE_NEEDED) {
|
||||
CompleteAuthToken(&ntlm->c_handle, &desc);
|
||||
/* CompleteAuthToken() is not present in Win9x, so load it dynamically */
|
||||
SECURITY_STATUS (__stdcall * pCompleteAuthToken)
|
||||
(PCtxtHandle,PSecBufferDesc);
|
||||
HMODULE hSecur32 = GetModuleHandle("secur32.dll");
|
||||
if (hSecur32 != NULL) {
|
||||
pCompleteAuthToken =
|
||||
(SECURITY_STATUS (__stdcall *)(PCtxtHandle,PSecBufferDesc))
|
||||
GetProcAddress(hSecur32, "CompleteAuthToken");
|
||||
if( pCompleteAuthToken != NULL ) {
|
||||
pCompleteAuthToken(&ntlm->c_handle, &desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (status != SEC_E_OK) {
|
||||
FreeCredentialsHandle(&ntlm->handle);
|
||||
@@ -553,6 +565,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
SecBufferDesc type_2_desc, type_3_desc;
|
||||
SECURITY_STATUS status;
|
||||
ULONG attrs;
|
||||
TimeStamp tsDummy; /* For Windows 9x compatibility of SPPI calls */
|
||||
|
||||
type_2_desc.ulVersion = type_3_desc.ulVersion = SECBUFFER_VERSION;
|
||||
type_2_desc.cBuffers = type_3_desc.cBuffers = 1;
|
||||
@@ -573,7 +586,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
ISC_REQ_CONNECTION,
|
||||
0, SECURITY_NETWORK_DREP, &type_2_desc,
|
||||
0, &ntlm->c_handle, &type_3_desc,
|
||||
&attrs, NULL);
|
||||
&attrs, &tsDummy);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
return CURLE_RECV_ERROR;
|
||||
@@ -700,6 +713,13 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
size=64;
|
||||
ntlmbuf[62]=ntlmbuf[63]=0;
|
||||
|
||||
/* Make sure that the user and domain strings fit in the target buffer
|
||||
before we copy them there. */
|
||||
if(size + userlen + domlen >= sizeof(ntlmbuf)) {
|
||||
failf(conn->data, "user + domain name too big");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(&ntlmbuf[size], domain, domlen);
|
||||
size += domlen;
|
||||
|
||||
|
@@ -39,7 +39,8 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
|
||||
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_ntlm_cleanup(struct connectdata *conn);
|
||||
#if !defined(USE_SSLEAY) && !defined(USE_WINDOWS_SSPI)
|
||||
#if (!defined(USE_SSLEAY) && !defined(USE_WINDOWS_SSPI)) || \
|
||||
defined(CURL_DISABLE_HTTP)
|
||||
#define Curl_ntlm_cleanup(x)
|
||||
#endif
|
||||
|
||||
|
@@ -34,7 +34,8 @@
|
||||
#include "if2ip.h"
|
||||
|
||||
#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN32__) && \
|
||||
!defined(__riscos__) && !defined(__INTERIX) && !defined(NETWARE)
|
||||
!defined(__riscos__) && !defined(__INTERIX) && !defined(NETWARE) && \
|
||||
!defined(_AMIGASF)
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
|
@@ -1,5 +1,27 @@
|
||||
#ifndef __INET_NTOA_R_H
|
||||
#define __INET_NTOA_R_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$
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
|
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 1996-2001 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.
|
||||
*/
|
||||
/*
|
||||
* Original code by Paul Vixie. "curlified" by Gisle Vanem.
|
||||
*/
|
||||
|
@@ -49,4 +49,5 @@ EXPORTS
|
||||
curl_multi_strerror @ 41;
|
||||
curl_share_strerror @ 42;
|
||||
curl_easy_reset @ 43;
|
||||
curl_mvsnprintf @ 44 ;
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
curl_msprintf,
|
||||
curl_msnprintf,
|
||||
curl_mvfprintf,
|
||||
curl_mvsnprintf,
|
||||
curl_strequal,
|
||||
curl_strnequal,
|
||||
curl_easy_duphandle,
|
||||
|
@@ -30,7 +30,7 @@ BEGIN
|
||||
VALUE "OriginalFilename", "libcurl.dll\0"
|
||||
VALUE "ProductName", "The cURL library\0"
|
||||
VALUE "ProductVersion", LIBCURL_VERSION "\0"
|
||||
VALUE "LegalCopyright", "Copyright 1996-2004 by Daniel Stenberg. http://curl.haxx.se/docs/copyright.html\0"
|
||||
VALUE "LegalCopyright", "Copyright 1996-2005 by Daniel Stenberg. http://curl.haxx.se/docs/copyright.html\0"
|
||||
END
|
||||
END
|
||||
|
||||
|
@@ -7,8 +7,8 @@
|
||||
ATCPSDKI= /GG/netinclude
|
||||
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -I$(ATCPSDKI) -m68020-60 -noixemul -I. -I../include -W -Wall
|
||||
CC = m68k-amigaos-gcc
|
||||
CFLAGS = -I$(ATCPSDKI) -m68020-60 -O2 -msoft-float -noixemul -g -I. -I../include -W -Wall
|
||||
|
||||
OBJS = amigaos.c base64.c connect.c content_encoding.c cookie.c dict.c easy.c \
|
||||
escape.c file.c formdata.c ftp.c getenv.c getinfo.c hash.c hostip.c \
|
||||
@@ -17,7 +17,7 @@ OBJS = amigaos.c base64.c connect.c content_encoding.c cookie.c dict.c easy.c \
|
||||
ldap.c llist.c md5.c memdebug.c mprintf.c multi.c netrc.c parsedate.c \
|
||||
progress.c security.c select.c sendf.c share.c speedcheck.c ssluse.c \
|
||||
strequal.c strtok.c telnet.c timeval.c transfer.c url.c version.c \
|
||||
sslgen.c gtls.c
|
||||
sslgen.c gtls.c strerror.c
|
||||
|
||||
all: $(OBJS:.c=.o)
|
||||
ar cru libcurl.a $(OBJS:.c=.o)
|
||||
|
@@ -201,7 +201,7 @@ void *curl_dorealloc(void *ptr, size_t wantedsize,
|
||||
|
||||
mem=(struct memdebug *)(Curl_crealloc)(mem, size);
|
||||
if(logfile)
|
||||
fprintf(logfile, "MEM %s:%d realloc(0x%x, %zd) = %p\n",
|
||||
fprintf(logfile, "MEM %s:%d realloc(%p, %zd) = %p\n",
|
||||
source, line, ptr, wantedsize, mem?mem->mem:NULL);
|
||||
|
||||
if(mem) {
|
||||
|
@@ -85,8 +85,16 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
|
||||
#define accept(sock,addr,len)\
|
||||
curl_accept(sock,addr,len,__LINE__,__FILE__)
|
||||
|
||||
#if defined(getaddrinfo) && defined(__osf__)
|
||||
/* OSF/1 and Tru64 have getaddrinfo as a define already, so we cannot define
|
||||
our macro as for other platforms. Instead, we redefine the new name they
|
||||
define getaddrinfo to become! */
|
||||
#define ogetaddrinfo(host,serv,hint,res) \
|
||||
curl_dogetaddrinfo(host,serv,hint,res,__LINE__,__FILE__)
|
||||
#else
|
||||
#define getaddrinfo(host,serv,hint,res) \
|
||||
curl_dogetaddrinfo(host,serv,hint,res,__LINE__,__FILE__)
|
||||
#endif
|
||||
#define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \
|
||||
curl_dogetnameinfo(sa,salen,host,hostlen,serv,servlen,flags, __LINE__, \
|
||||
__FILE__)
|
||||
|
@@ -75,6 +75,9 @@
|
||||
# define BOOL char
|
||||
#endif
|
||||
|
||||
#ifdef _AMIGASF
|
||||
# undef FORMAT_INT
|
||||
#endif
|
||||
|
||||
/* Lower-case digits. */
|
||||
static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
@@ -42,8 +42,8 @@ RSC=rc.exe
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "." /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /D "_WINDLL" /FR /FD /c
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BUILDING_LIBCURL" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "." /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BUILDING_LIBCURL" /D "_WINDLL" /FR /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
@@ -69,8 +69,8 @@ LINK32=link.exe
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /FR /FD /GZ /c
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BUILDING_LIBCURL" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BUILDING_LIBCURL" /FR /FD /GZ /c
|
||||
# SUBTRACT CPP /WX /YX
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
|
100
lib/parsedate.c
100
lib/parsedate.c
@@ -102,50 +102,51 @@ struct tzinfo {
|
||||
|
||||
/* Here's a bunch of frequently used time zone names. These were supported
|
||||
by the old getdate parser. */
|
||||
#define tDAYZONE -60 /* offset for daylight savings time */
|
||||
static const struct tzinfo tz[]= {
|
||||
{"GMT", 0}, /* Greenwich Mean */
|
||||
{"UTC", 0}, /* Universal (Coordinated) */
|
||||
{"WET", 0}, /* Western European */
|
||||
{"BST", 0}, /* British Summer */
|
||||
{"WAT", 60}, /* West Africa */
|
||||
{"AST", 240}, /* Atlantic Standard */
|
||||
{"ADT", 240}, /* Atlantic Daylight */
|
||||
{"EST", 300}, /* Eastern Standard */
|
||||
{"EDT", 300}, /* Eastern Daylight */
|
||||
{"CST", 360}, /* Central Standard */
|
||||
{"CDT", 360}, /* Central Daylight */
|
||||
{"MST", 420}, /* Mountain Standard */
|
||||
{"MDT", 420}, /* Mountain Daylight */
|
||||
{"PST", 480}, /* Pacific Standard */
|
||||
{"PDT", 480}, /* Pacific Daylight */
|
||||
{"YST", 540}, /* Yukon Standard */
|
||||
{"YDT", 540}, /* Yukon Daylight */
|
||||
{"HST", 600}, /* Hawaii Standard */
|
||||
{"HDT", 600}, /* Hawaii Daylight */
|
||||
{"CAT", 600}, /* Central Alaska */
|
||||
{"AHST", 600}, /* Alaska-Hawaii Standard */
|
||||
{"NT", 660}, /* Nome */
|
||||
{"IDLW", 720}, /* International Date Line West */
|
||||
{"CET", -60}, /* Central European */
|
||||
{"MET", -60}, /* Middle European */
|
||||
{"MEWT", -60}, /* Middle European Winter */
|
||||
{"MEST", -120}, /* Middle European Summer */
|
||||
{"CEST", -120}, /* Central European Summer */
|
||||
{"MESZ", -60}, /* Middle European Summer */
|
||||
{"FWT", -60}, /* French Winter */
|
||||
{"FST", -60}, /* French Summer */
|
||||
{"EET", -120}, /* Eastern Europe, USSR Zone 1 */
|
||||
{"WAST", -420}, /* West Australian Standard */
|
||||
{"WADT", -420}, /* West Australian Daylight */
|
||||
{"CCT", -480}, /* China Coast, USSR Zone 7 */
|
||||
{"JST", -540}, /* Japan Standard, USSR Zone 8 */
|
||||
{"EAST", -600}, /* Eastern Australian Standard */
|
||||
{"EADT", -600}, /* Eastern Australian Daylight */
|
||||
{"GST", -600}, /* Guam Standard, USSR Zone 9 */
|
||||
{"NZT", -720}, /* New Zealand */
|
||||
{"NZST", -720}, /* New Zealand Standard */
|
||||
{"NZDT", -720}, /* New Zealand Daylight */
|
||||
{"IDLE", -720}, /* International Date Line East */
|
||||
{"GMT", 0}, /* Greenwich Mean */
|
||||
{"UTC", 0}, /* Universal (Coordinated) */
|
||||
{"WET", 0}, /* Western European */
|
||||
{"BST", 0 tDAYZONE}, /* British Summer */
|
||||
{"WAT", 60}, /* West Africa */
|
||||
{"AST", 240}, /* Atlantic Standard */
|
||||
{"ADT", 240 tDAYZONE}, /* Atlantic Daylight */
|
||||
{"EST", 300}, /* Eastern Standard */
|
||||
{"EDT", 300 tDAYZONE}, /* Eastern Daylight */
|
||||
{"CST", 360}, /* Central Standard */
|
||||
{"CDT", 360 tDAYZONE}, /* Central Daylight */
|
||||
{"MST", 420}, /* Mountain Standard */
|
||||
{"MDT", 420 tDAYZONE}, /* Mountain Daylight */
|
||||
{"PST", 480}, /* Pacific Standard */
|
||||
{"PDT", 480 tDAYZONE}, /* Pacific Daylight */
|
||||
{"YST", 540}, /* Yukon Standard */
|
||||
{"YDT", 540 tDAYZONE}, /* Yukon Daylight */
|
||||
{"HST", 600}, /* Hawaii Standard */
|
||||
{"HDT", 600 tDAYZONE}, /* Hawaii Daylight */
|
||||
{"CAT", 600}, /* Central Alaska */
|
||||
{"AHST", 600}, /* Alaska-Hawaii Standard */
|
||||
{"NT", 660}, /* Nome */
|
||||
{"IDLW", 720}, /* International Date Line West */
|
||||
{"CET", -60}, /* Central European */
|
||||
{"MET", -60}, /* Middle European */
|
||||
{"MEWT", -60}, /* Middle European Winter */
|
||||
{"MEST", -60 tDAYZONE}, /* Middle European Summer */
|
||||
{"CEST", -60 tDAYZONE}, /* Central European Summer */
|
||||
{"MESZ", -60 tDAYZONE}, /* Middle European Summer */
|
||||
{"FWT", -60}, /* French Winter */
|
||||
{"FST", -60 tDAYZONE}, /* French Summer */
|
||||
{"EET", -120}, /* Eastern Europe, USSR Zone 1 */
|
||||
{"WAST", -420}, /* West Australian Standard */
|
||||
{"WADT", -420 tDAYZONE}, /* West Australian Daylight */
|
||||
{"CCT", -480}, /* China Coast, USSR Zone 7 */
|
||||
{"JST", -540}, /* Japan Standard, USSR Zone 8 */
|
||||
{"EAST", -600}, /* Eastern Australian Standard */
|
||||
{"EADT", -600 tDAYZONE}, /* Eastern Australian Daylight */
|
||||
{"GST", -600}, /* Guam Standard, USSR Zone 9 */
|
||||
{"NZT", -720}, /* New Zealand */
|
||||
{"NZST", -720}, /* New Zealand Standard */
|
||||
{"NZDT", -720 tDAYZONE}, /* New Zealand Daylight */
|
||||
{"IDLE", -720}, /* International Date Line East */
|
||||
};
|
||||
|
||||
/* returns:
|
||||
@@ -236,9 +237,20 @@ static time_t Curl_parsedate(const char *date)
|
||||
struct tm tm;
|
||||
enum assume dignext = DATE_MDAY;
|
||||
const char *indate = date; /* save the original pointer */
|
||||
|
||||
int part = 0; /* max 6 parts */
|
||||
|
||||
#ifdef WIN32
|
||||
/*
|
||||
* On Windows, we need an odd work-around for the case when no TZ variable
|
||||
* is set. If it isn't set and "automatic DST adjustment" is enabled, the
|
||||
* time functions below will return values one hour off! As reported and
|
||||
* investigated in bug report #1230118.
|
||||
*/
|
||||
const char *env = getenv("TZ");
|
||||
if(!env)
|
||||
putenv("TZ=GMT");
|
||||
#endif
|
||||
|
||||
while(*date && (part < 6)) {
|
||||
bool found=FALSE;
|
||||
|
||||
|
@@ -262,6 +262,14 @@ typedef int curl_socket_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* "cl -ML" or "cl -MLd" implies a single-threaded runtime library where
|
||||
_beginthreadex() is not available */
|
||||
#if defined(_MSC_VER) && !defined(_MT) && !defined(USE_ARES)
|
||||
#undef USE_THREADING_GETADDRINFO
|
||||
#undef USE_THREADING_GETHOSTBYNAME
|
||||
#define CURL_NO__BEGINTHREADEX
|
||||
#endif
|
||||
|
||||
#ifdef mpeix
|
||||
#define IOCTL_3_ARGS
|
||||
#endif
|
||||
|
@@ -473,8 +473,6 @@ int Curl_ssl_recv(struct connectdata *conn, /* connection data */
|
||||
#endif /* USE_GNUTLS */
|
||||
#endif /* USE_SSLEAY */
|
||||
if(nread == -1) {
|
||||
infof(conn->data, "Curl_xxx_rcvs returned -1, block = %s\n",
|
||||
block?"TRUE":"FALSE");
|
||||
if(!block)
|
||||
return 0; /* this is a true error, not EWOULDBLOCK */
|
||||
else
|
||||
|
@@ -1098,8 +1098,8 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
|
||||
msg_type = *(char*)buf;
|
||||
msg_name = ssl_msg_type(ssl_ver, msg_type);
|
||||
|
||||
txt_len = 1 + snprintf(ssl_buf, sizeof(ssl_buf), "SSLv%c, %s%s (%d):\n",
|
||||
ver, tls_rt_name, msg_name, msg_type);
|
||||
txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "SSLv%c, %s%s (%d):\n",
|
||||
ver, tls_rt_name, msg_name, msg_type);
|
||||
Curl_debug(data, CURLINFO_TEXT, ssl_buf, txt_len, NULL);
|
||||
|
||||
Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
|
||||
|
@@ -22,6 +22,12 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef HAVE_STRERROR_R
|
||||
#if !defined(HAVE_POSIX_STRERROR_R) && !defined(HAVE_GLIBC_STRERROR_R)
|
||||
#error "you MUST have either POSIX or glibc strerror_r if strerror_r is found"
|
||||
#endif /* !POSIX && !glibc */
|
||||
#endif /* HAVE_STRERROR_R */
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -63,10 +69,10 @@ curl_easy_strerror(CURLcode error)
|
||||
return "URL using bad/illegal format or missing URL";
|
||||
|
||||
case CURLE_COULDNT_RESOLVE_PROXY:
|
||||
return "couldnt resolve proxy name";
|
||||
return "couldn't resolve proxy name";
|
||||
|
||||
case CURLE_COULDNT_RESOLVE_HOST:
|
||||
return "couldnt resolve host name";
|
||||
return "couldn't resolve host name";
|
||||
|
||||
case CURLE_COULDNT_CONNECT:
|
||||
return "couldn't connect to server";
|
||||
@@ -239,6 +245,27 @@ curl_easy_strerror(CURLcode error)
|
||||
case CURLE_LOGIN_DENIED:
|
||||
return "FTP: login denied";;
|
||||
|
||||
case CURLE_TFTP_NOTFOUND:
|
||||
return "TFTP: File Not Found";;
|
||||
|
||||
case CURLE_TFTP_PERM:
|
||||
return "TFTP: Access Violation";;
|
||||
|
||||
case CURLE_TFTP_DISKFULL:
|
||||
return "TFTP: Disk full or allocation exceeded";;
|
||||
|
||||
case CURLE_TFTP_ILLEGAL:
|
||||
return "TFTP: Illegal operation";;
|
||||
|
||||
case CURLE_TFTP_UNKNOWNID:
|
||||
return "TFTP: Unknown transfer ID";;
|
||||
|
||||
case CURLE_TFTP_EXISTS:
|
||||
return "TFTP: File already exists";;
|
||||
|
||||
case CURLE_TFTP_NOSUCHUSER:
|
||||
return "TFTP: No such user";;
|
||||
|
||||
case CURLE_URL_MALFORMAT_USER: /* not used by current libcurl */
|
||||
case CURLE_MALFORMAT_USER: /* not used by current libcurl */
|
||||
case CURLE_BAD_CALLING_ORDER: /* not used by current libcurl */
|
||||
@@ -486,7 +513,7 @@ get_winsock_error (int err, char *buf, size_t len)
|
||||
p = "Winsock library is not ready";
|
||||
break;
|
||||
case WSANOTINITIALISED:
|
||||
p = "Winsock library not initalised";
|
||||
p = "Winsock library not initialised";
|
||||
break;
|
||||
case WSAVERNOTSUPPORTED:
|
||||
p = "Winsock version not supported.";
|
||||
|
@@ -24,6 +24,14 @@
|
||||
#include "setup.h"
|
||||
#include "strtoofft.h"
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
*
|
||||
* In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we
|
||||
* could use in case strtoll() doesn't exist... See
|
||||
* http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
|
||||
*/
|
||||
|
||||
#ifdef NEED_CURL_STRTOLL
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
719
lib/tftp.c
Normal file
719
lib/tftp.c
Normal file
@@ -0,0 +1,719 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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$
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_TFTP
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <netdb.h>
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
#include "sendf.h"
|
||||
#include "tftp.h"
|
||||
#include "progress.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "select.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
TFTP_MODE_NETASCII=0,
|
||||
TFTP_MODE_OCTET
|
||||
} tftp_mode_t;
|
||||
|
||||
typedef enum {
|
||||
TFTP_STATE_START=0,
|
||||
TFTP_STATE_RX,
|
||||
TFTP_STATE_TX,
|
||||
TFTP_STATE_FIN
|
||||
} tftp_state_t;
|
||||
|
||||
typedef enum {
|
||||
TFTP_EVENT_INIT=0,
|
||||
TFTP_EVENT_RRQ = 1,
|
||||
TFTP_EVENT_WRQ = 2,
|
||||
TFTP_EVENT_DATA = 3,
|
||||
TFTP_EVENT_ACK = 4,
|
||||
TFTP_EVENT_ERROR = 5,
|
||||
TFTP_EVENT_TIMEOUT
|
||||
} tftp_event_t;
|
||||
|
||||
typedef enum {
|
||||
TFTP_ERR_UNDEF=0,
|
||||
TFTP_ERR_NOTFOUND,
|
||||
TFTP_ERR_PERM,
|
||||
TFTP_ERR_DISKFULL,
|
||||
TFTP_ERR_ILLEGAL,
|
||||
TFTP_ERR_UNKNOWNID,
|
||||
TFTP_ERR_EXISTS,
|
||||
TFTP_ERR_NOSUCHUSER,
|
||||
TFTP_ERR_TIMEOUT,
|
||||
TFTP_ERR_NORESPONSE
|
||||
} tftp_error_t;
|
||||
|
||||
typedef struct tftp_packet {
|
||||
unsigned short event;
|
||||
union {
|
||||
struct {
|
||||
unsigned char data[512];
|
||||
} request;
|
||||
struct {
|
||||
unsigned short block;
|
||||
unsigned char data[512];
|
||||
} data;
|
||||
struct {
|
||||
unsigned short block;
|
||||
} ack;
|
||||
struct {
|
||||
unsigned short code;
|
||||
unsigned char data[512];
|
||||
} error;
|
||||
} u;
|
||||
} tftp_packet_t;
|
||||
|
||||
typedef struct tftp_state_data {
|
||||
tftp_state_t state;
|
||||
tftp_mode_t mode;
|
||||
tftp_error_t error;
|
||||
struct connectdata *conn;
|
||||
curl_socket_t sockfd;
|
||||
int retries;
|
||||
int retry_time;
|
||||
int retry_max;
|
||||
time_t start_time;
|
||||
time_t max_time;
|
||||
unsigned short block;
|
||||
struct sockaddr local_addr;
|
||||
socklen_t local_addrlen;
|
||||
struct sockaddr remote_addr;
|
||||
socklen_t remote_addrlen;
|
||||
int rbytes;
|
||||
int sbytes;
|
||||
tftp_packet_t rpacket;
|
||||
tftp_packet_t spacket;
|
||||
} tftp_state_data_t;
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
static void tftp_rx(tftp_state_data_t *state, tftp_event_t event) ;
|
||||
static void tftp_tx(tftp_state_data_t *state, tftp_event_t event) ;
|
||||
void tftp_set_timeouts(tftp_state_data_t *state) ;
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* tftp_set_timeouts -
|
||||
*
|
||||
* Set timeouts based on state machine state.
|
||||
* Use user provided connect timeouts until DATA or ACK
|
||||
* packet is received, then use user-provided transfer timeouts
|
||||
*
|
||||
*
|
||||
**********************************************************/
|
||||
void tftp_set_timeouts(tftp_state_data_t *state)
|
||||
{
|
||||
|
||||
struct SessionHandle *data = state->conn->data;
|
||||
time_t maxtime, timeout;
|
||||
|
||||
time(&state->start_time);
|
||||
if(state->state == TFTP_STATE_START) {
|
||||
/* Compute drop-dead time */
|
||||
maxtime = (time_t)(data->set.connecttimeout?data->set.connecttimeout:30);
|
||||
state->max_time = state->start_time+maxtime;
|
||||
|
||||
/* Set per-block timeout to total */
|
||||
timeout = maxtime ;
|
||||
|
||||
/* Average restart after 5 seconds */
|
||||
state->retry_max = timeout/5;
|
||||
|
||||
/* Compute the re-start interval to suit the timeout */
|
||||
state->retry_time = timeout/state->retry_max;
|
||||
if(state->retry_time<1) state->retry_time=1;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
/* Compute drop-dead time */
|
||||
maxtime = data->set.timeout?data->set.timeout:3600;
|
||||
state->max_time = state->start_time+maxtime;
|
||||
|
||||
/* Set per-block timeout to 10% of total */
|
||||
timeout = maxtime/10 ;
|
||||
|
||||
/* Average reposting an ACK after 15 seconds */
|
||||
state->retry_max = timeout/15;
|
||||
}
|
||||
/* But bound the total number */
|
||||
if(state->retry_max<3) state->retry_max=3;
|
||||
if(state->retry_max>50) state->retry_max=50;
|
||||
|
||||
/* Compute the re-ACK interval to suit the timeout */
|
||||
state->retry_time = timeout/state->retry_max;
|
||||
if(state->retry_time<1) state->retry_time=1;
|
||||
|
||||
infof(data, "set timeouts for state %d; Total %d, retry %d maxtry %d\n",
|
||||
state->state, (state->max_time-state->start_time),
|
||||
state->retry_time, state->retry_max);
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* tftp_set_send_first
|
||||
*
|
||||
* Event handler for the START state
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
static void tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
|
||||
{
|
||||
int sbytes;
|
||||
const char *mode = "octet";
|
||||
char *filename = state->conn->path;
|
||||
struct SessionHandle *data = state->conn->data;
|
||||
|
||||
/* Set ascii mode if -B flag was used */
|
||||
if(data->set.ftp_ascii)
|
||||
mode = "netascii";
|
||||
|
||||
switch(event) {
|
||||
|
||||
case TFTP_EVENT_INIT: /* Send the first packet out */
|
||||
case TFTP_EVENT_TIMEOUT: /* Resend the first packet out */
|
||||
/* Increment the retry counter, quit if over the limit */
|
||||
state->retries++;
|
||||
if(state->retries>state->retry_max) {
|
||||
state->error = TFTP_ERR_NORESPONSE;
|
||||
state->state = TFTP_STATE_FIN;
|
||||
return;
|
||||
}
|
||||
|
||||
if(data->set.upload) {
|
||||
/* If we are uploading, send an WRQ */
|
||||
state->spacket.event = htons(TFTP_EVENT_WRQ);
|
||||
filename = curl_unescape(filename, strlen(filename));
|
||||
state->conn->upload_fromhere = (char *)state->spacket.u.data.data;
|
||||
if(data->set.infilesize != -1) {
|
||||
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* If we are downloading, send an RRQ */
|
||||
state->spacket.event = htons(TFTP_EVENT_RRQ);
|
||||
}
|
||||
sprintf((char *)state->spacket.u.request.data, "%s%c%s%c",
|
||||
filename, '\0', mode, '\0');
|
||||
sbytes = 4 + strlen(filename) + strlen(mode);
|
||||
sbytes = sendto(state->sockfd, &state->spacket, sbytes, 0,
|
||||
state->conn->ip_addr->ai_addr,
|
||||
state->conn->ip_addr->ai_addrlen);
|
||||
if(sbytes < 0) {
|
||||
failf(data, "%s\n", strerror(errno));
|
||||
}
|
||||
break;
|
||||
|
||||
case TFTP_EVENT_ACK: /* Connected for transmit */
|
||||
infof(data, "%s\n", "Connected for transmit");
|
||||
state->state = TFTP_STATE_TX;
|
||||
tftp_set_timeouts(state);
|
||||
tftp_tx(state, event);
|
||||
break;
|
||||
|
||||
case TFTP_EVENT_DATA: /* connected for receive */
|
||||
infof(data, "%s\n", "Connected for receive");
|
||||
state->state = TFTP_STATE_RX;
|
||||
tftp_set_timeouts(state);
|
||||
tftp_rx(state, event);
|
||||
break;
|
||||
|
||||
case TFTP_EVENT_ERROR:
|
||||
state->state = TFTP_STATE_FIN;
|
||||
break;
|
||||
|
||||
default:
|
||||
failf(state->conn->data, "tftp_send_first: internal error\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* tftp_rx
|
||||
*
|
||||
* Event handler for the RX state
|
||||
*
|
||||
**********************************************************/
|
||||
static void tftp_rx(tftp_state_data_t *state, tftp_event_t event)
|
||||
{
|
||||
int sbytes;
|
||||
int rblock;
|
||||
struct SessionHandle *data = state->conn->data;
|
||||
|
||||
switch(event) {
|
||||
|
||||
case TFTP_EVENT_DATA:
|
||||
|
||||
/* Is this the block we expect? */
|
||||
rblock = ntohs(state->rpacket.u.data.block);
|
||||
if ((state->block+1) != rblock) {
|
||||
/* No, log it, up the retry count and fail if over the limit */
|
||||
infof(data,
|
||||
"Received unexpected DATA packet block %d\n", rblock);
|
||||
state->retries++;
|
||||
if (state->retries>state->retry_max) {
|
||||
failf(data, "tftp_rx: giving up waiting for block %d\n",
|
||||
state->block+1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* This is the expected block. Reset counters and ACK it. */
|
||||
state->block = rblock;
|
||||
state->retries = 0;
|
||||
state->spacket.event = htons(TFTP_EVENT_ACK);
|
||||
state->spacket.u.ack.block = htons(state->block);
|
||||
sbytes = sendto(state->sockfd, &state->spacket, 4, MSG_NOSIGNAL,
|
||||
&state->remote_addr, state->remote_addrlen);
|
||||
if(sbytes < 0) {
|
||||
failf(data, "%s\n", strerror(errno));
|
||||
}
|
||||
|
||||
/* Check if completed (That is, a less than full packet is recieved) */
|
||||
if (state->rbytes < (int)sizeof(state->spacket)){
|
||||
state->state = TFTP_STATE_FIN;
|
||||
}
|
||||
else {
|
||||
state->state = TFTP_STATE_RX;
|
||||
}
|
||||
break;
|
||||
|
||||
case TFTP_EVENT_TIMEOUT:
|
||||
/* Increment the retry count and fail if over the limit */
|
||||
state->retries++;
|
||||
infof(data,
|
||||
"Timeout waiting for block %d ACK. Retries = %d\n", state->retries);
|
||||
if(state->retries > state->retry_max) {
|
||||
state->error = TFTP_ERR_TIMEOUT;
|
||||
state->state = TFTP_STATE_FIN;
|
||||
} else {
|
||||
/* Resend the previous ACK */
|
||||
sbytes = sendto(state->sockfd, &state->spacket,
|
||||
4, MSG_NOSIGNAL,
|
||||
&state->remote_addr, state->remote_addrlen);
|
||||
/* Check all sbytes were sent */
|
||||
if(sbytes<0) {
|
||||
failf(data, "%s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TFTP_EVENT_ERROR:
|
||||
state->state = TFTP_STATE_FIN;
|
||||
break;
|
||||
|
||||
default:
|
||||
failf(data, "%s\n", "tftp_rx: internal error");
|
||||
break;
|
||||
}
|
||||
Curl_pgrsSetDownloadCounter(data,
|
||||
(curl_off_t) state->block*512);
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* tftp_tx
|
||||
*
|
||||
* Event handler for the TX state
|
||||
*
|
||||
**********************************************************/
|
||||
static void tftp_tx(tftp_state_data_t *state, tftp_event_t event)
|
||||
{
|
||||
struct SessionHandle *data = state->conn->data;
|
||||
int sbytes;
|
||||
int rblock;
|
||||
|
||||
switch(event) {
|
||||
|
||||
case TFTP_EVENT_ACK:
|
||||
/* Ack the packet */
|
||||
rblock = ntohs(state->rpacket.u.data.block);
|
||||
|
||||
if(rblock != state->block) {
|
||||
/* This isn't the expected block. Log it and up the retry counter */
|
||||
infof(data, "Received ACK for block %d, expecting %d\n",
|
||||
rblock, state->block);
|
||||
state->retries++;
|
||||
/* Bail out if over the maximum */
|
||||
if(state->retries>state->retry_max) {
|
||||
failf(data, "%s\n",
|
||||
"tftp_tx: giving up waiting for block %d ack",
|
||||
state->block);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* This is the expected packet. Reset the counters and send the next
|
||||
block */
|
||||
state->block++;
|
||||
state->retries = 0;
|
||||
state->spacket.event = htons(TFTP_EVENT_DATA);
|
||||
state->spacket.u.ack.block = htons(state->block);
|
||||
if(state->block > 1 && state->sbytes < 512) {
|
||||
state->state = TFTP_STATE_FIN;
|
||||
return;
|
||||
}
|
||||
Curl_fillreadbuffer(state->conn, 512, &state->sbytes);
|
||||
sbytes = sendto(state->sockfd, &state->spacket,
|
||||
4+state->sbytes, MSG_NOSIGNAL,
|
||||
&state->remote_addr, state->remote_addrlen);
|
||||
/* Check all sbytes were sent */
|
||||
if(sbytes<0) {
|
||||
failf(data, "%s\n", strerror(errno));
|
||||
}
|
||||
break;
|
||||
|
||||
case TFTP_EVENT_TIMEOUT:
|
||||
/* Increment the retry counter and log the timeout */
|
||||
state->retries++;
|
||||
infof(data, "Timeout waiting for block %d ACK. "
|
||||
" Retries = %d\n", state->retries);
|
||||
/* Decide if we've had enough */
|
||||
if(state->retries > state->retry_max) {
|
||||
state->error = TFTP_ERR_TIMEOUT;
|
||||
state->state = TFTP_STATE_FIN;
|
||||
} else {
|
||||
/* Re-send the data packet */
|
||||
sbytes = sendto(state->sockfd, &state->spacket,
|
||||
4+state->sbytes, MSG_NOSIGNAL,
|
||||
&state->remote_addr, state->remote_addrlen);
|
||||
/* Check all sbytes were sent */
|
||||
if(sbytes<0) {
|
||||
failf(data, "%s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TFTP_EVENT_ERROR:
|
||||
state->state = TFTP_STATE_FIN;
|
||||
break;
|
||||
|
||||
default:
|
||||
failf(data, "%s\n", "tftp_tx: internal error");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update the progress meter */
|
||||
Curl_pgrsSetUploadCounter(data, (curl_off_t) state->block*512);
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* tftp_state_machine
|
||||
*
|
||||
* The tftp state machine event dispatcher
|
||||
*
|
||||
**********************************************************/
|
||||
static CURLcode tftp_state_machine(tftp_state_data_t *state,
|
||||
tftp_event_t event)
|
||||
{
|
||||
struct SessionHandle *data = state->conn->data;
|
||||
switch(state->state) {
|
||||
case TFTP_STATE_START:
|
||||
DEBUGF(infof(data, "TFTP_STATE_START\n"));
|
||||
tftp_send_first(state, event);
|
||||
break;
|
||||
case TFTP_STATE_RX:
|
||||
DEBUGF(infof(data, "TFTP_STATE_RX\n"));
|
||||
tftp_rx(state, event);
|
||||
break;
|
||||
case TFTP_STATE_TX:
|
||||
DEBUGF(infof(data, "TFTP_STATE_TX\n"));
|
||||
tftp_tx(state, event);
|
||||
break;
|
||||
case TFTP_STATE_FIN:
|
||||
infof(data, "%s\n", "TFTP finished");
|
||||
break;
|
||||
default:
|
||||
DEBUGF(infof(data, "STATE: %d\n", state->state));
|
||||
failf(data, "%s\n", "Internal state machine error");
|
||||
break;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* Curl_tftp_connect
|
||||
*
|
||||
* The connect callback
|
||||
*
|
||||
**********************************************************/
|
||||
CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode code;
|
||||
tftp_state_data_t *state;
|
||||
int rc;
|
||||
|
||||
if((state = conn->proto.tftp = calloc(sizeof(tftp_state_data_t), 1))==NULL) {
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
state->conn = conn;
|
||||
state->sockfd = state->conn->sock[FIRSTSOCKET];
|
||||
state->state = TFTP_STATE_START;
|
||||
|
||||
#ifdef WIN32
|
||||
/* AF_UNSPEC == 0 (from above calloc) doesn't work on Winsock */
|
||||
state->local_addr.sa_family = conn->ip_addr->ai_family;
|
||||
#endif
|
||||
|
||||
tftp_set_timeouts(state);
|
||||
|
||||
/* Bind to any interface, random UDP port */
|
||||
rc = bind(state->sockfd, &state->local_addr, sizeof(state->local_addr));
|
||||
if(rc) {
|
||||
failf(conn->data, "bind() failed; %s\n",
|
||||
Curl_strerror(conn,Curl_ourerrno()));
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
Curl_pgrsStartNow(conn->data);
|
||||
|
||||
*done = TRUE;
|
||||
code = CURLE_OK;
|
||||
return(code);
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* Curl_tftp_done
|
||||
*
|
||||
* The done callback
|
||||
*
|
||||
**********************************************************/
|
||||
CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status)
|
||||
{
|
||||
(void)status; /* unused */
|
||||
|
||||
free(conn->proto.tftp);
|
||||
conn->proto.tftp = NULL;
|
||||
Curl_pgrsDone(conn);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* Curl_tftp
|
||||
*
|
||||
* The do callback
|
||||
*
|
||||
* This callback handles the entire TFTP transfer
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
CURLcode Curl_tftp(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
tftp_state_data_t *state = (tftp_state_data_t *)(conn->proto.tftp);
|
||||
tftp_event_t event;
|
||||
CURLcode code;
|
||||
int rc;
|
||||
struct sockaddr fromaddr;
|
||||
socklen_t fromlen;
|
||||
int check_time = 0;
|
||||
|
||||
(void)done; /* prevent compiler warning */
|
||||
|
||||
/* Run the TFTP State Machine */
|
||||
for(tftp_state_machine(state, TFTP_EVENT_INIT);
|
||||
state->state != TFTP_STATE_FIN;
|
||||
tftp_state_machine(state, event) ) {
|
||||
|
||||
/* Wait until ready to read or timeout occurs */
|
||||
rc=Curl_select(state->sockfd, CURL_SOCKET_BAD, state->retry_time * 1000);
|
||||
|
||||
if(rc == -1) {
|
||||
/* bail out */
|
||||
int error = Curl_ourerrno();
|
||||
failf(data, "%s\n", Curl_strerror(conn, error));
|
||||
event = TFTP_EVENT_ERROR;
|
||||
}
|
||||
else if (rc==0) {
|
||||
/* A timeout occured */
|
||||
event = TFTP_EVENT_TIMEOUT;
|
||||
|
||||
/* Force a look at transfer timeouts */
|
||||
check_time = 0;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
/* Receive the packet */
|
||||
fromlen=sizeof(fromaddr);
|
||||
state->rbytes = recvfrom(state->sockfd,
|
||||
(void *)&state->rpacket, sizeof(state->rpacket),
|
||||
0, &fromaddr, &fromlen);
|
||||
if(state->remote_addrlen==0) {
|
||||
memcpy(&state->remote_addr, &fromaddr, fromlen);
|
||||
state->remote_addrlen = fromlen;
|
||||
}
|
||||
|
||||
/* The event is given by the TFTP packet time */
|
||||
event = (tftp_event_t)ntohs(state->rpacket.event);
|
||||
|
||||
switch(event) {
|
||||
case TFTP_EVENT_DATA:
|
||||
Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
(char *)state->rpacket.u.data.data, state->rbytes-4);
|
||||
break;
|
||||
case TFTP_EVENT_ERROR:
|
||||
state->error = (tftp_error_t)ntohs(state->rpacket.u.error.code);
|
||||
infof(conn->data, "%s\n", (char *)state->rpacket.u.error.data);
|
||||
break;
|
||||
case TFTP_EVENT_ACK:
|
||||
break;
|
||||
case TFTP_EVENT_RRQ:
|
||||
case TFTP_EVENT_WRQ:
|
||||
default:
|
||||
failf(conn->data, "%s\n", "Internal error: Unexpected packet");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update the progress meter */
|
||||
Curl_pgrsUpdate(conn);
|
||||
|
||||
}
|
||||
|
||||
/* Check for transfer timeout every 10 blocks, or after timeout */
|
||||
if(check_time%10==0) {
|
||||
time_t current;
|
||||
time(¤t);
|
||||
if(current>state->max_time) {
|
||||
DEBUGF(infof(data, "timeout: %d > %d\n",
|
||||
current, state->max_time));
|
||||
state->error = TFTP_ERR_TIMEOUT;
|
||||
state->state = TFTP_STATE_FIN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Tell curl we're done */
|
||||
Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
|
||||
/* If we have encountered an error */
|
||||
if(state->error) {
|
||||
|
||||
/* Translate internal error codes to curl error codes */
|
||||
switch(state->error) {
|
||||
case TFTP_ERR_NOTFOUND:
|
||||
code = CURLE_TFTP_NOTFOUND;
|
||||
break;
|
||||
case TFTP_ERR_PERM:
|
||||
code = CURLE_TFTP_PERM;
|
||||
break;
|
||||
case TFTP_ERR_DISKFULL:
|
||||
code = CURLE_TFTP_DISKFULL;
|
||||
break;
|
||||
case TFTP_ERR_ILLEGAL:
|
||||
code = CURLE_TFTP_ILLEGAL;
|
||||
break;
|
||||
case TFTP_ERR_UNKNOWNID:
|
||||
code = CURLE_TFTP_UNKNOWNID;
|
||||
break;
|
||||
case TFTP_ERR_EXISTS:
|
||||
code = CURLE_TFTP_EXISTS;
|
||||
break;
|
||||
case TFTP_ERR_NOSUCHUSER:
|
||||
code = CURLE_TFTP_NOSUCHUSER;
|
||||
break;
|
||||
case TFTP_ERR_TIMEOUT:
|
||||
code = CURLE_OPERATION_TIMEOUTED;
|
||||
break;
|
||||
case TFTP_ERR_NORESPONSE:
|
||||
code = CURLE_COULDNT_CONNECT;
|
||||
break;
|
||||
default:
|
||||
code= CURLE_ABORTED_BY_CALLBACK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
code = CURLE_OK;
|
||||
return code;
|
||||
}
|
||||
#endif
|
31
lib/tftp.h
Normal file
31
lib/tftp.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef __TFTP_H
|
||||
#define __TFTP_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$
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_TFTP
|
||||
CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_tftp(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode);
|
||||
#endif
|
||||
#endif
|
@@ -360,7 +360,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
/* str_start is start of line within buf */
|
||||
k->str_start = k->str;
|
||||
|
||||
k->end_ptr = strchr (k->str_start, '\n');
|
||||
k->end_ptr = memchr(k->str_start, '\n', nread);
|
||||
|
||||
if (!k->end_ptr) {
|
||||
/* Not a complete header line within buffer, append the data to
|
||||
@@ -428,7 +428,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* copy to end of line */
|
||||
strncpy (k->hbufp, k->str_start, full_length);
|
||||
memcpy(k->hbufp, k->str_start, full_length);
|
||||
k->hbufp += full_length;
|
||||
k->hbuflen += full_length;
|
||||
*k->hbufp = 0;
|
||||
@@ -718,7 +718,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
the header completely if we get a 416 response as then we're
|
||||
resuming a document that we don't get, and this header contains
|
||||
info about the true size of the document we didn't get now. */
|
||||
if (!k->ignorecl &&
|
||||
if (!k->ignorecl && !data->set.ignorecl &&
|
||||
checkprefix("Content-Length:", k->p)) {
|
||||
contentlength = curlx_strtoofft(k->p+15, NULL, 10);
|
||||
if (data->set.max_filesize &&
|
||||
@@ -833,6 +833,20 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
/* init our chunky engine */
|
||||
Curl_httpchunk_init(conn);
|
||||
}
|
||||
|
||||
else if (checkprefix("Trailer:", k->p) ||
|
||||
checkprefix("Trailers:", k->p)) {
|
||||
/*
|
||||
* This test helps Curl_httpchunk_read() to determine to look
|
||||
* for well formed trailers after the zero chunksize record. In
|
||||
* this case a CRLF is required after the zero chunksize record
|
||||
* when no trailers are sent, or after the last trailer record.
|
||||
*
|
||||
* It seems both Trailer: and Trailers: occur in the wild.
|
||||
*/
|
||||
conn->bits.trailerHdrPresent = TRUE;
|
||||
}
|
||||
|
||||
else if (checkprefix("Content-Encoding:", k->p) &&
|
||||
data->set.encoding) {
|
||||
/*
|
||||
@@ -866,11 +880,11 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
/* Content-Range: bytes [num]-
|
||||
Content-Range: bytes: [num]-
|
||||
|
||||
The second format was added August 1st 2000 by Igor
|
||||
Khristophorov since Sun's webserver JavaWebServer/1.1.1
|
||||
obviously sends the header this way! :-( */
|
||||
The second format was added since Sun's webserver
|
||||
JavaWebServer/1.1.1 obviously sends the header this way!
|
||||
*/
|
||||
|
||||
char *ptr = strstr(k->p, "bytes");
|
||||
char *ptr = Curl_strcasestr(k->p, "bytes");
|
||||
ptr+=5;
|
||||
|
||||
if(*ptr == ':')
|
||||
@@ -1074,6 +1088,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
* the name says read, this function both reads and writes away
|
||||
* the data. The returned 'nread' holds the number of actual
|
||||
* data it wrote to the client. */
|
||||
|
||||
CHUNKcode res =
|
||||
Curl_httpchunk_read(conn, k->str, nread, &nread);
|
||||
|
||||
@@ -1119,6 +1134,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
data->state.headerbuff,
|
||||
k->hbuflen);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
if(k->badheader < HEADER_ALLBAD) {
|
||||
/* This switch handles various content encodings. If there's an
|
||||
@@ -1605,9 +1622,11 @@ Transfer(struct connectdata *conn)
|
||||
CURLcode Curl_pretransfer(struct SessionHandle *data)
|
||||
{
|
||||
CURLcode res;
|
||||
if(!data->change.url)
|
||||
if(!data->change.url) {
|
||||
/* we can't do anything wihout URL */
|
||||
failf(data, "No URL set!\n");
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
/* Init the SSL session ID cache here. We do it here since we want to do it
|
||||
after the *_setopt() calls (that could change the size of the cache) but
|
||||
@@ -1624,25 +1643,9 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
|
||||
data->state.authhost.want = data->set.httpauth;
|
||||
data->state.authproxy.want = data->set.proxyauth;
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
/* If there was a list of cookie files to read and we haven't done it before,
|
||||
do it now! */
|
||||
if(data->change.cookielist) {
|
||||
struct curl_slist *list = data->change.cookielist;
|
||||
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! */
|
||||
}
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
|
||||
/* If there is a list of cookie files to read, do it now! */
|
||||
if(data->change.cookielist)
|
||||
Curl_cookie_loadfiles(data);
|
||||
|
||||
/* Allow data->set.use_port to set which port to use. This needs to be
|
||||
* disabled for example when we follow Location: headers to URLs using
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user