Compare commits
180 Commits
curl-7_15_
...
curl-7_15_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1d3969b215 | ||
![]() |
94116d9ebc | ||
![]() |
cc5174a89a | ||
![]() |
31552100c5 | ||
![]() |
8df5dcb193 | ||
![]() |
7929600798 | ||
![]() |
a05ea124b9 | ||
![]() |
6a03ab3ad4 | ||
![]() |
6a151c1312 | ||
![]() |
990e56fb13 | ||
![]() |
2bd3033f68 | ||
![]() |
fe105a07e3 | ||
![]() |
a5782defd3 | ||
![]() |
bcccd2fe74 | ||
![]() |
404e23734b | ||
![]() |
973d63f4f2 | ||
![]() |
405d98ee63 | ||
![]() |
f81724969d | ||
![]() |
edb5444fa3 | ||
![]() |
e877cb7bd7 | ||
![]() |
482b3ba702 | ||
![]() |
752acedc0b | ||
![]() |
fb88723afc | ||
![]() |
3718737091 | ||
![]() |
3d3f056f7e | ||
![]() |
c60621c367 | ||
![]() |
606562aa7e | ||
![]() |
f689d06ca9 | ||
![]() |
7cfd7f3fb1 | ||
![]() |
4a8dfb3461 | ||
![]() |
3752b3aead | ||
![]() |
b81d41df22 | ||
![]() |
dadf3f06ee | ||
![]() |
8ed0d5675f | ||
![]() |
d5e9041344 | ||
![]() |
d99c20f628 | ||
![]() |
973ed24dc8 | ||
![]() |
5d5f5e3be8 | ||
![]() |
d9e14408f0 | ||
![]() |
c9c5ce2365 | ||
![]() |
975534370f | ||
![]() |
28605f6bd3 | ||
![]() |
3c6d3b69c2 | ||
![]() |
00312e95fe | ||
![]() |
4223130bb0 | ||
![]() |
c811e1ce70 | ||
![]() |
77475f2ad0 | ||
![]() |
3680a2f6f5 | ||
![]() |
1946058e7b | ||
![]() |
73daf8ce33 | ||
![]() |
094ceeba14 | ||
![]() |
3b7359a27a | ||
![]() |
df9108e19b | ||
![]() |
6307e783d8 | ||
![]() |
b9cd73c76d | ||
![]() |
b62c230ca2 | ||
![]() |
800193da9b | ||
![]() |
577ba5783c | ||
![]() |
9bece2b313 | ||
![]() |
e85e30546c | ||
![]() |
758f6eed51 | ||
![]() |
80ee5d3bd8 | ||
![]() |
dd06c60ada | ||
![]() |
6ca627ae74 | ||
![]() |
80a0b81c2a | ||
![]() |
06a7b0561b | ||
![]() |
12db20be4e | ||
![]() |
3cbb1b2b64 | ||
![]() |
d75e587613 | ||
![]() |
414c57d138 | ||
![]() |
c14a84e6f2 | ||
![]() |
def0db30e7 | ||
![]() |
6ef7a81a3b | ||
![]() |
95152aec68 | ||
![]() |
8ed6762363 | ||
![]() |
87c5ed8bec | ||
![]() |
ecc6c1f501 | ||
![]() |
3d8338b0d4 | ||
![]() |
c91e25518f | ||
![]() |
a8dddeab61 | ||
![]() |
8f0a5ab660 | ||
![]() |
db03d4bdd0 | ||
![]() |
0ec96e4279 | ||
![]() |
6e520c4cdc | ||
![]() |
1e8683d72d | ||
![]() |
2df622fd14 | ||
![]() |
fede784fa2 | ||
![]() |
f191b143e9 | ||
![]() |
59212553b5 | ||
![]() |
e532b196cc | ||
![]() |
0f5232280c | ||
![]() |
38898ba4af | ||
![]() |
48f56d9600 | ||
![]() |
17bf5ac2fc | ||
![]() |
343b882d80 | ||
![]() |
db06d21339 | ||
![]() |
19240f08bb | ||
![]() |
d774730f83 | ||
![]() |
c2edf42567 | ||
![]() |
08f0e55b4f | ||
![]() |
deeb74b7e4 | ||
![]() |
0542002d7a | ||
![]() |
c1e307f585 | ||
![]() |
7b4ba43dcf | ||
![]() |
b0e4debaab | ||
![]() |
676597e961 | ||
![]() |
686d90745b | ||
![]() |
5dc02d53c3 | ||
![]() |
0598547b58 | ||
![]() |
67c7745f5d | ||
![]() |
a2c289646d | ||
![]() |
e6efecd054 | ||
![]() |
778b6a86c0 | ||
![]() |
e5babd086d | ||
![]() |
c212ebbdda | ||
![]() |
83b8de3d43 | ||
![]() |
e174d374f2 | ||
![]() |
4edb93508d | ||
![]() |
38c994b83b | ||
![]() |
1b8643d4c9 | ||
![]() |
d3c796f5b0 | ||
![]() |
83d8a6a450 | ||
![]() |
a21a77d230 | ||
![]() |
260b88c197 | ||
![]() |
655331a91b | ||
![]() |
09e569f83d | ||
![]() |
e4a4b562c4 | ||
![]() |
35b4a755f9 | ||
![]() |
5a4b43848a | ||
![]() |
d98869a088 | ||
![]() |
4d33cf739d | ||
![]() |
34e7daf989 | ||
![]() |
b0adcd6a46 | ||
![]() |
be285cde3f | ||
![]() |
0ff1faf7f2 | ||
![]() |
bcc62cc9e3 | ||
![]() |
97b466d409 | ||
![]() |
f17d9bba14 | ||
![]() |
d74725ce67 | ||
![]() |
3dad55d7a8 | ||
![]() |
598ffeea89 | ||
![]() |
83367f67de | ||
![]() |
15f2647d71 | ||
![]() |
6421d69bff | ||
![]() |
18081e30e1 | ||
![]() |
97181b5c0d | ||
![]() |
a63f9887b9 | ||
![]() |
1282aad4a5 | ||
![]() |
b8fad99f09 | ||
![]() |
c7e9e60b05 | ||
![]() |
47f2e1da73 | ||
![]() |
5975229919 | ||
![]() |
38295e8a75 | ||
![]() |
f9612b5eaf | ||
![]() |
5cf2ef2ef7 | ||
![]() |
938b5c886e | ||
![]() |
0618e68200 | ||
![]() |
bac52f3969 | ||
![]() |
d494d62953 | ||
![]() |
7206181385 | ||
![]() |
3f22901a43 | ||
![]() |
f70f11fc70 | ||
![]() |
cffebd7fd6 | ||
![]() |
b8c8e7349f | ||
![]() |
8bba99ae56 | ||
![]() |
b5c5f57613 | ||
![]() |
33df856925 | ||
![]() |
ce09cedd2e | ||
![]() |
7d68101f83 | ||
![]() |
aa50a00898 | ||
![]() |
26f112ba55 | ||
![]() |
159b9162f8 | ||
![]() |
d7999f9fcb | ||
![]() |
f13eba4c78 | ||
![]() |
050e82e088 | ||
![]() |
88377e5b61 | ||
![]() |
241af465fd | ||
![]() |
59510a554d | ||
![]() |
b10aa95d28 | ||
![]() |
097bee681a |
1183
CHANGES.2005
Normal file
1183
CHANGES.2005
Normal file
File diff suppressed because it is too large
Load Diff
6
CVS-INFO
6
CVS-INFO
@@ -53,12 +53,6 @@ installed:
|
|||||||
give you an older version of the file that isn't up-to-date. That file was
|
give you an older version of the file that isn't up-to-date. That file was
|
||||||
checked in once and won't be updated very regularly.
|
checked in once and won't be updated very regularly.
|
||||||
|
|
||||||
o yacc/bison
|
|
||||||
|
|
||||||
If you don't have yacc or bison, you must rename the lib/getdate.c.cvs file
|
|
||||||
to lib/getdate.c to be able to build libcurl. yacc/bison is normally used
|
|
||||||
to generate the lib/getdate.c file from the lib/getdate.y source file.
|
|
||||||
|
|
||||||
MAC OS X
|
MAC OS X
|
||||||
|
|
||||||
With Mac OS X 10.2 and the associated Developer Tools, the installed versions
|
With Mac OS X 10.2 and the associated Developer Tools, the installed versions
|
||||||
|
29
README
29
README
@@ -33,34 +33,7 @@ WEB SITE
|
|||||||
Visit the curl web site or mirrors for the latest news and downloads:
|
Visit the curl web site or mirrors for the latest news and downloads:
|
||||||
|
|
||||||
Sweden http://curl.haxx.se/
|
Sweden http://curl.haxx.se/
|
||||||
Australia http://curl.planetmirror.com/
|
Mirrors http://curlm.haxx.se/
|
||||||
Austria http://curl.gds.tuwien.ac.at/
|
|
||||||
Denmark http://curl.cofman.dk/
|
|
||||||
France http://curl.fastmirror.net/
|
|
||||||
Germany http://curl.freemirror.de/
|
|
||||||
Germany http://curl.mirror-server.net/
|
|
||||||
Germany http://curl.mirror.at.stealer.net/
|
|
||||||
Germany http://curl.mirroring.de/
|
|
||||||
Germany http://curl.miscellaneousmirror.org/
|
|
||||||
Germany http://curl.mons-new-media.de/
|
|
||||||
Germany http://curl.storemypix.com/
|
|
||||||
Germany http://curl.triplemind.com/
|
|
||||||
Hong Kong http://curl.hkmirror.org/
|
|
||||||
Japan http://curl.s-lines.net/
|
|
||||||
Netherlands http://curl.nedmirror.nl/
|
|
||||||
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.meulie.net/
|
|
||||||
US (CA) http://curl.mirror.redwire.net/
|
|
||||||
US (CA) http://curl.mirrormonster.com/
|
|
||||||
US (CA) http://curl.signal42.com/
|
|
||||||
US (FL) http://curl.hoxt.com/
|
|
||||||
US (TX) http://curl.109k.com/
|
|
||||||
US (TX) http://curl.hostingzero.com/
|
|
||||||
US (TX) http://curl.mirrors.cyberservers.net/
|
|
||||||
US (TX) http://curl.seekmeup.com/
|
|
||||||
|
|
||||||
CVS
|
CVS
|
||||||
|
|
||||||
|
109
RELEASE-NOTES
109
RELEASE-NOTES
@@ -1,73 +1,72 @@
|
|||||||
Curl and libcurl 7.15.2
|
Curl and libcurl 7.15.4
|
||||||
|
|
||||||
Public curl release number: 92
|
Public curl release number: 94
|
||||||
Releases counted from the very beginning: 119
|
Releases counted from the very beginning: 121
|
||||||
Available command line options: 112
|
Available command line options: 112
|
||||||
Available curl_easy_setopt() options: 129
|
Available curl_easy_setopt() options: 132
|
||||||
Number of public functions in libcurl: 46
|
Number of public functions in libcurl: 49
|
||||||
Amount of public web site mirrors: 31
|
Amount of public web site mirrors: 33
|
||||||
Number of known libcurl bindings: 32
|
Number of known libcurl bindings: 32
|
||||||
Number of contributors: 474
|
Number of contributors: 492
|
||||||
|
|
||||||
This release includes the following changes:
|
This release includes the following changes:
|
||||||
|
|
||||||
o Support for SOCKS4 proxies (added --socks4)
|
o NTLM2 session response support
|
||||||
o CURLOPT_CONNECT_ONLY and CURLINFO_LASTSOCKET added
|
o CURLOPT_COOKIELIST set to "SESS" clears all session cookies
|
||||||
o CURLOPT_LOCALPORT and CURLOPT_LOCALPORTRANGE (--local-port) added
|
o CURLINFO_LASTSOCKET returned sockets are now checked more before returned
|
||||||
o Dropped support for the LPRT ftp command
|
o curl-config got a --checkfor option to compare version numbers
|
||||||
o Gopher is now officially abandoned as a protocol (lib)curl tries to support
|
o line end conversions for FTP ASCII transfers
|
||||||
o curl_global_init() and curl_global_cleanup() are now using a refcount so
|
o curl_multi_socket() API added (still mostly untested)
|
||||||
that it is now legal to call them multiple times. See updated info for
|
o conversion callback options for EBCDIC <=> ASCII conversions
|
||||||
details
|
o added CURLINFO_FTP_ENTRY_PATH
|
||||||
|
o less blocking for the multi interface during (Open)SSL connect negotiation
|
||||||
|
|
||||||
This release includes the following bugfixes:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
o two bugs concerning using curl_multi_remove_handle() before the transfer
|
o builds fine on cygwin
|
||||||
was complete
|
o md5-sess with Digest authentication
|
||||||
o multi-pass authentication and compressed content
|
o dict with letters such as space in a word
|
||||||
o minor format string mistake in the GSS/Negotiate code
|
o dict with url-encoded words in the URL
|
||||||
o cached DNS entries could remain in the cache too long
|
o libcurl.m4 when default=yes but no libcurl was found
|
||||||
o improved GnuTLS check in configure
|
o numerous bugs fixed in the TFTP code
|
||||||
o re-used FTP connections when the second request didn't do a transfer
|
o possible memory leak when adding easy handles to multi stack
|
||||||
o plain --limit-rate [num] means bytes
|
o TFTP works in a more portable fashion (== on more platforms)
|
||||||
o re-creating a dead connection is no longer counted internally as a followed
|
o WSAGetLastError() is now used (better) on Windows
|
||||||
redirect and thus prevents a weird error that would occur if a FTP
|
o GnuTLS non-block case that could cause data trashing
|
||||||
connection died on an attempted re-use
|
o deflate code survives lack of zlib header
|
||||||
o Try PASV after failing to connect to the port the EPSV response contained
|
o CURLOPT_INTERFACE works with hostname
|
||||||
o -P [IP] with non-local address with ipv6-enabled curl
|
o configure runs fine with ICC
|
||||||
o -P [hostname] with ipv6-disabled curl
|
o closed control connection with FTP when easy handle was removed from multi
|
||||||
o libcurl.m4 was updated
|
o curl --trace crash when built with VS2005
|
||||||
o configure no longer warns if the current path contains a space
|
o SSL connect time-out
|
||||||
o test suite kill race condition
|
o improved NTLM functionality
|
||||||
o FTP_SKIP_PASV_IP and FTP_USE_EPSV when doing FTP over HTTP proxy
|
o following redirects with more than one question mark in source URL
|
||||||
o Doing a second request with FTP on the same bath path, would make libcurl
|
o fixed debug build crash with -d
|
||||||
confuse what current working directory it had
|
o generates a fine AIX Toolbox RPM spec
|
||||||
o FTP over HTTP proxy now sends the second CONNECT properly
|
o treat FTP AUTH failures properly
|
||||||
o numerous compiler warnings and build quirks for various compilers have
|
o TFTP transfers could trash data
|
||||||
been addressed
|
o -d + -G combo crash
|
||||||
o supports name and passwords up to 255 bytes long, embedded in URLs
|
|
||||||
o the HTTP_ONLY define disables the TFTP support
|
|
||||||
|
|
||||||
Other curl-related news since the previous public release:
|
Other curl-related news:
|
||||||
|
|
||||||
o http://curlm.haxx.se/ is new service that automatically redirects you to a
|
o tclcurl 0.15.3 was released:
|
||||||
curl web mirror that is close to you!
|
|
||||||
|
|
||||||
o http://curl.hkmirror.org/ is a new curl web mirror in Hong Kong
|
|
||||||
o http://curl.storemypix.com/ is a new curl web mirror in Germany
|
|
||||||
o http://curl.s-lines.net/ is a new curl web mirror in Japan
|
|
||||||
o http://curl.oss-mirror.org/ is a new curl web mirror in Ireland
|
|
||||||
o http://curl.linux-mirror.org/ is a new curl web mirror in Germany
|
|
||||||
o pycurl 7.15.1 was released: http://pycurl.sf.net/
|
|
||||||
o TclCurl 0.15.1 was released:
|
|
||||||
http://personal1.iddeo.es/andresgarci/tclcurl/english/
|
http://personal1.iddeo.es/andresgarci/tclcurl/english/
|
||||||
|
|
||||||
|
New curl mirrors:
|
||||||
|
|
||||||
|
o http://curl.webdesign-zdg.de/ in Frankfurt, Germany
|
||||||
|
o http://curl.de-mirror.de/ in Aachen, Germany
|
||||||
|
o http://curl.osmirror.nl/ in Amsterdam, the Netherlands
|
||||||
|
o http://curl.usphp.com/ in Florida, US
|
||||||
|
o http://curl.oslevel.de/ in Karlsruhe, Germany
|
||||||
|
|
||||||
This release would not have looked like this without help, code, reports and
|
This release would not have looked like this without help, code, reports and
|
||||||
advice from friends like these:
|
advice from friends like these:
|
||||||
|
|
||||||
Dov Murik, Jean Jacques Drouin, Andres Garcia, Yang Tse, Gisle Vanem, Dan
|
Dan Fandrich, Ilja van Sprundel, David McCreedy, Tor Arntsen, Xavier Bouchoux,
|
||||||
Fandrich, Alexander Lazic, Michael Jahn, Andrew Benham, Bryan Henderson,
|
David Byron, Michele Bini, Ates Goral, Katie Wang, Robson Braga Araujo,
|
||||||
David Shaw, Jon Turner, Duane Cathey, Michal Marek, Philippe Vaucher, Kent
|
Ale Vesely, Paul Querna, Gisle Vanem, Mark Eichin, Roland Blom, Andreas
|
||||||
Boortz, Karl Moerder, Shmulik Regev, Ulf H<>rnhammar, Peter Su
|
Ntaflos, David Shaw, Michael Wallner, Olaf St<53>ben, Mikael Sennerholm,
|
||||||
|
Brian Dessent
|
||||||
|
|
||||||
Thanks! (and sorry if I forgot to mention someone)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
To get fixed in 7.15.2 (planned release: Febrary 2006)
|
To get fixed in 7.15.4 (planned release: June 2006)
|
||||||
======================
|
======================
|
||||||
|
|
||||||
65 -
|
66 -
|
||||||
|
|
||||||
|
45
acinclude.m4
45
acinclude.m4
@@ -5,7 +5,7 @@
|
|||||||
# | (__| |_| | _ <| |___
|
# | (__| |_| | _ <| |___
|
||||||
# \___|\___/|_| \_\_____|
|
# \___|\___/|_| \_\_____|
|
||||||
#
|
#
|
||||||
# Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
# Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
#
|
#
|
||||||
# This software is licensed as described in the file COPYING, which
|
# This software is licensed as described in the file COPYING, which
|
||||||
# you should have received as part of this distribution. The terms
|
# you should have received as part of this distribution. The terms
|
||||||
@@ -1105,12 +1105,44 @@ fi
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl **********************************************************************
|
||||||
|
dnl CURL_DETECT_ICC ([ACTION-IF-YES])
|
||||||
|
dnl
|
||||||
|
dnl check if this is the Intel ICC compiler, and if so run the ACTION-IF-YES
|
||||||
|
dnl sets the $ICC variable to "yes" or "no"
|
||||||
|
dnl **********************************************************************
|
||||||
|
AC_DEFUN([CURL_DETECT_ICC],
|
||||||
|
[
|
||||||
|
ICC="no"
|
||||||
|
AC_MSG_CHECKING([for icc in use])
|
||||||
|
if test "$GCC" = "yes"; then
|
||||||
|
dnl check if this is icc acting as gcc in disguise
|
||||||
|
AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER],
|
||||||
|
dnl action if the text is found, this it has not been replaced by the
|
||||||
|
dnl cpp
|
||||||
|
ICC="no",
|
||||||
|
dnl the text was not found, it was replaced by the cpp
|
||||||
|
ICC="yes"
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
[$1]
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
if test "$ICC" = "no"; then
|
||||||
|
# this is not ICC
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
dnl We create a function for detecting which compiler we use and then set as
|
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
|
dnl pendantic compiler options as possible for that particular compiler. The
|
||||||
dnl options are only used for debug-builds.
|
dnl options are only used for debug-builds.
|
||||||
|
|
||||||
AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
||||||
[
|
[
|
||||||
|
if test "z$ICC" = "z"; then
|
||||||
|
CURL_DETECT_ICC
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$GCC" = "yes"; then
|
if test "$GCC" = "yes"; then
|
||||||
|
|
||||||
dnl figure out gcc version!
|
dnl figure out gcc version!
|
||||||
@@ -1121,17 +1153,6 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
|||||||
gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null`
|
gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null`
|
||||||
AC_MSG_RESULT($gccver)
|
AC_MSG_RESULT($gccver)
|
||||||
|
|
||||||
AC_MSG_CHECKING([if this is icc in disguise])
|
|
||||||
AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER],
|
|
||||||
dnl action if the text is found, this it has not been replaced by the
|
|
||||||
dnl cpp
|
|
||||||
ICC="no"
|
|
||||||
AC_MSG_RESULT([no]),
|
|
||||||
dnl the text was not found, it was replaced by the cpp
|
|
||||||
ICC="yes"
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
)
|
|
||||||
|
|
||||||
if test "$ICC" = "yes"; then
|
if test "$ICC" = "yes"; then
|
||||||
dnl this is icc, not gcc.
|
dnl this is icc, not gcc.
|
||||||
|
|
||||||
|
@@ -12,3 +12,5 @@ Gisle Vanem
|
|||||||
Gunter Knauf
|
Gunter Knauf
|
||||||
Henrik Stoerner
|
Henrik Stoerner
|
||||||
Yang Tse
|
Yang Tse
|
||||||
|
Nick Mathewson
|
||||||
|
Alexander Lazic
|
||||||
|
17
ares/CHANGES
17
ares/CHANGES
@@ -1,5 +1,18 @@
|
|||||||
Changelog for the c-ares project
|
Changelog for the c-ares project
|
||||||
|
|
||||||
|
* May 10, 2006
|
||||||
|
|
||||||
|
- Bram Matthys brought my attention to a libtool peculiarity where detecting
|
||||||
|
things such as C++ compiler actually is a bad thing and since we don't need
|
||||||
|
that detection I added a work-around, much inspired by a previous patch by
|
||||||
|
Paolo Bonzini. This also shortens the configure script quite a lot.
|
||||||
|
|
||||||
|
* May 3, 2006
|
||||||
|
|
||||||
|
- Nick Mathewson added the ARES_OPT_SOCK_STATE_CB option that when set makes
|
||||||
|
c-ares call a callback on socket state changes. A better way than the
|
||||||
|
ares_getsock() to get full control over the socket state.
|
||||||
|
|
||||||
* January 9, 2006
|
* January 9, 2006
|
||||||
|
|
||||||
- Alexander Lazic improved the getservbyport_r() configure check.
|
- Alexander Lazic improved the getservbyport_r() configure check.
|
||||||
@@ -28,8 +41,8 @@
|
|||||||
|
|
||||||
- Added constants that will be used by ares_getaddrinfo
|
- Added constants that will be used by ares_getaddrinfo
|
||||||
|
|
||||||
- Made ares_getnameinfo use the reentrant getservbyport (getservbyport_r) if it is
|
- Made ares_getnameinfo use the reentrant getservbyport (getservbyport_r) if it
|
||||||
available to ensure it works properly in a threaded environment.
|
is available to ensure it works properly in a threaded environment.
|
||||||
|
|
||||||
* September 10
|
* September 10
|
||||||
|
|
||||||
|
@@ -43,7 +43,13 @@ VER=-version-info 1:0:0
|
|||||||
# set age to 0. (c:r:a=0)
|
# set age to 0. (c:r:a=0)
|
||||||
#
|
#
|
||||||
|
|
||||||
libcares_la_LDFLAGS = $(VER)
|
if NO_UNDEFINED
|
||||||
|
# The -no-undefined flag is crucial for this to build fine on some platforms
|
||||||
|
UNDEF = -no-undefined
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
libcares_la_LDFLAGS = $(UNDEF) $(VER)
|
||||||
|
|
||||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||||
include Makefile.inc
|
include Makefile.inc
|
||||||
|
@@ -20,7 +20,7 @@ endif
|
|||||||
TARGETS = adig.nlm ahost.nlm
|
TARGETS = adig.nlm ahost.nlm
|
||||||
LTARGET = libcares.lib
|
LTARGET = libcares.lib
|
||||||
VERSION = $(LIBCARES_VERSION)
|
VERSION = $(LIBCARES_VERSION)
|
||||||
COPYR = Copyright (C) 1996 - 2005, Daniel Stenberg, <daniel@haxx.se>
|
COPYR = Copyright (C) 1996 - 2006, Daniel Stenberg, <daniel@haxx.se>
|
||||||
DESCR = cURL $(subst .def,,$(notdir $@)) $(LIBCARES_VERSION_STR) - http://curl.haxx.se
|
DESCR = cURL $(subst .def,,$(notdir $@)) $(LIBCARES_VERSION_STR) - http://curl.haxx.se
|
||||||
MTSAFE = YES
|
MTSAFE = YES
|
||||||
STACK = 64000
|
STACK = 64000
|
||||||
@@ -88,7 +88,7 @@ LD = nlmconv
|
|||||||
LDFLAGS = -T
|
LDFLAGS = -T
|
||||||
AR = ar
|
AR = ar
|
||||||
ARFLAGS = -cq
|
ARFLAGS = -cq
|
||||||
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return -fno-strict-aliasing
|
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
|
||||||
CFLAGS += -Wall -Wno-format -Wno-uninitialized # -pedantic
|
CFLAGS += -Wall -Wno-format -Wno-uninitialized # -pedantic
|
||||||
ifeq ($(LIBARCH),LIBC)
|
ifeq ($(LIBARCH),LIBC)
|
||||||
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
||||||
@@ -256,8 +256,8 @@ config.h: Makefile.netware
|
|||||||
@echo $(DL)** All your changes will be lost!!$(DL) >> $@
|
@echo $(DL)** All your changes will be lost!!$(DL) >> $@
|
||||||
@echo $(DL)*/$(DL) >> $@
|
@echo $(DL)*/$(DL) >> $@
|
||||||
@echo $(DL)#define OS "i586-pc-NetWare"$(DL) >> $@
|
@echo $(DL)#define OS "i586-pc-NetWare"$(DL) >> $@
|
||||||
@echo $(DL)#define VERSION "$(LIBCURL_VERSION_STR)"$(DL) >> $@
|
@echo $(DL)#define VERSION "$(LIBCARES_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_ARPA_INET_H 1$(DL) >> $@
|
||||||
@echo $(DL)#define HAVE_ARPA_NAMESER_H 1$(DL) >> $@
|
@echo $(DL)#define HAVE_ARPA_NAMESER_H 1$(DL) >> $@
|
||||||
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
||||||
|
@@ -826,3 +826,39 @@ else
|
|||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
# Prevent libtool for checking how to run C++ compiler and check for other
|
||||||
|
# tools we don't want to use. We do this by m4-defining the _LT_AC_TAGCONFIG
|
||||||
|
# variable to the code to run, as by default it uses a much more complicated
|
||||||
|
# approach. The code below that is actually added seems to be used for cases
|
||||||
|
# where configure has trouble figuring out what C compiler to use but where
|
||||||
|
# the installed libtool has an idea.
|
||||||
|
#
|
||||||
|
# This function is a re-implemented version of the Paolo Bonzini fix posted to
|
||||||
|
# the c-ares mailing list by Bram Matthys on May 6 2006. My version removes
|
||||||
|
# redundant code but also adds the LTCFLAGS check that wasn't in that patch.
|
||||||
|
#
|
||||||
|
# Some code in this function was extracted from the generated configure script.
|
||||||
|
#
|
||||||
|
# CARES_CLEAR_LIBTOOL_TAGS
|
||||||
|
AC_DEFUN([CARES_CLEAR_LIBTOOL_TAGS],
|
||||||
|
[m4_define([_LT_AC_TAGCONFIG], [
|
||||||
|
if test -f "$ltmain"; then
|
||||||
|
if test ! -f "${ofile}"; then
|
||||||
|
AC_MSG_WARN([output file `$ofile' does not exist])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$LTCC"; then
|
||||||
|
eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
|
||||||
|
if test -z "$LTCC"; then
|
||||||
|
AC_MSG_WARN([output file `$ofile' does not look like a libtool
|
||||||
|
script])
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test -z "$LTCFLAGS"; then
|
||||||
|
eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
])]
|
||||||
|
)
|
||||||
|
15
ares/ares.h
15
ares/ares.h
@@ -93,6 +93,7 @@ extern "C" {
|
|||||||
#define ARES_OPT_SERVERS (1 << 6)
|
#define ARES_OPT_SERVERS (1 << 6)
|
||||||
#define ARES_OPT_DOMAINS (1 << 7)
|
#define ARES_OPT_DOMAINS (1 << 7)
|
||||||
#define ARES_OPT_LOOKUPS (1 << 8)
|
#define ARES_OPT_LOOKUPS (1 << 8)
|
||||||
|
#define ARES_OPT_SOCK_STATE_CB (1 << 9)
|
||||||
|
|
||||||
/* Nameinfo flag values */
|
/* Nameinfo flag values */
|
||||||
#define ARES_NI_NOFQDN (1 << 0)
|
#define ARES_NI_NOFQDN (1 << 0)
|
||||||
@@ -135,6 +136,18 @@ extern "C" {
|
|||||||
#define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \
|
#define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \
|
||||||
ARES_GETSOCK_MAXNUM)))
|
ARES_GETSOCK_MAXNUM)))
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
typedef void (*ares_sock_state_cb)(void *data,
|
||||||
|
SOCKET socket,
|
||||||
|
int readable,
|
||||||
|
int writable);
|
||||||
|
#else
|
||||||
|
typedef void (*ares_sock_state_cb)(void *data,
|
||||||
|
int socket,
|
||||||
|
int readable,
|
||||||
|
int writable);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct ares_options {
|
struct ares_options {
|
||||||
int flags;
|
int flags;
|
||||||
int timeout;
|
int timeout;
|
||||||
@@ -147,6 +160,8 @@ struct ares_options {
|
|||||||
char **domains;
|
char **domains;
|
||||||
int ndomains;
|
int ndomains;
|
||||||
char *lookups;
|
char *lookups;
|
||||||
|
ares_sock_state_cb sock_state_cb;
|
||||||
|
void *sock_state_cb_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hostent;
|
struct hostent;
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
|
||||||
void ares__close_sockets(struct server_state *server)
|
void ares__close_sockets(ares_channel channel, struct server_state *server)
|
||||||
{
|
{
|
||||||
struct send_request *sendreq;
|
struct send_request *sendreq;
|
||||||
|
|
||||||
@@ -46,11 +46,13 @@ void ares__close_sockets(struct server_state *server)
|
|||||||
/* Close the TCP and UDP sockets. */
|
/* Close the TCP and UDP sockets. */
|
||||||
if (server->tcp_socket != ARES_SOCKET_BAD)
|
if (server->tcp_socket != ARES_SOCKET_BAD)
|
||||||
{
|
{
|
||||||
|
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 0, 0);
|
||||||
closesocket(server->tcp_socket);
|
closesocket(server->tcp_socket);
|
||||||
server->tcp_socket = ARES_SOCKET_BAD;
|
server->tcp_socket = ARES_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
if (server->udp_socket != ARES_SOCKET_BAD)
|
if (server->udp_socket != ARES_SOCKET_BAD)
|
||||||
{
|
{
|
||||||
|
SOCK_STATE_CALLBACK(channel, server->udp_socket, 0, 0);
|
||||||
closesocket(server->udp_socket);
|
closesocket(server->udp_socket);
|
||||||
server->udp_socket = ARES_SOCKET_BAD;
|
server->udp_socket = ARES_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
|
@@ -38,6 +38,6 @@ void ares_cancel(ares_channel channel)
|
|||||||
if (!(channel->flags & ARES_FLAG_STAYOPEN))
|
if (!(channel->flags & ARES_FLAG_STAYOPEN))
|
||||||
{
|
{
|
||||||
for (i = 0; i < channel->nservers; i++)
|
for (i = 0; i < channel->nservers; i++)
|
||||||
ares__close_sockets(&channel->servers[i]);
|
ares__close_sockets(channel, &channel->servers[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,7 @@ void ares_destroy(ares_channel channel)
|
|||||||
struct query *query;
|
struct query *query;
|
||||||
|
|
||||||
for (i = 0; i < channel->nservers; i++)
|
for (i = 0; i < channel->nservers; i++)
|
||||||
ares__close_sockets(&channel->servers[i]);
|
ares__close_sockets(channel, &channel->servers[i]);
|
||||||
free(channel->servers);
|
free(channel->servers);
|
||||||
for (i = 0; i < channel->ndomains; i++)
|
for (i = 0; i < channel->ndomains; i++)
|
||||||
free(channel->domains[i]);
|
free(channel->domains[i]);
|
||||||
|
@@ -98,6 +98,24 @@ The lookups to perform for host queries.
|
|||||||
.I lookups
|
.I lookups
|
||||||
should be set to a string of the characters "b" or "f", where "b"
|
should be set to a string of the characters "b" or "f", where "b"
|
||||||
indicates a DNS lookup and "f" indicates a lookup in the hosts file.
|
indicates a DNS lookup and "f" indicates a lookup in the hosts file.
|
||||||
|
.TP 18
|
||||||
|
.B ARES_OPT_SOCK_STATE_CB
|
||||||
|
.B void (*\fIsock_state_cb\fP)(void *data, int s, int read, int write);
|
||||||
|
.br
|
||||||
|
.B void *\fIsock_state_cb_data\fP;
|
||||||
|
.br
|
||||||
|
A callback function to be invoked when a socket changes state.
|
||||||
|
.I s
|
||||||
|
will be passed the socket whose state has changed;
|
||||||
|
.I read
|
||||||
|
will be set to true if the socket should listen for read events, and
|
||||||
|
.I write
|
||||||
|
will be set to true if the socket should listen for write events.
|
||||||
|
The value of
|
||||||
|
.I sock_state_cb_data
|
||||||
|
will be passed as the
|
||||||
|
.I data
|
||||||
|
argument.
|
||||||
.PP
|
.PP
|
||||||
The
|
The
|
||||||
.I flags
|
.I flags
|
||||||
|
@@ -113,6 +113,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
|||||||
channel->queries = NULL;
|
channel->queries = NULL;
|
||||||
channel->domains = NULL;
|
channel->domains = NULL;
|
||||||
channel->sortlist = NULL;
|
channel->sortlist = NULL;
|
||||||
|
channel->sock_state_cb = NULL;
|
||||||
|
|
||||||
/* Initialize configuration by each of the four sources, from highest
|
/* Initialize configuration by each of the four sources, from highest
|
||||||
* precedence to lowest.
|
* precedence to lowest.
|
||||||
@@ -192,6 +193,11 @@ static int init_by_options(ares_channel channel, struct ares_options *options,
|
|||||||
channel->udp_port = options->udp_port;
|
channel->udp_port = options->udp_port;
|
||||||
if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
|
if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
|
||||||
channel->tcp_port = options->tcp_port;
|
channel->tcp_port = options->tcp_port;
|
||||||
|
if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
|
||||||
|
{
|
||||||
|
channel->sock_state_cb = options->sock_state_cb;
|
||||||
|
channel->sock_state_cb_data = options->sock_state_cb_data;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy the servers, if given. */
|
/* Copy the servers, if given. */
|
||||||
if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
|
if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
|
||||||
|
@@ -176,13 +176,22 @@ struct ares_channeldata {
|
|||||||
|
|
||||||
/* Active queries */
|
/* Active queries */
|
||||||
struct query *queries;
|
struct query *queries;
|
||||||
|
|
||||||
|
ares_sock_state_cb sock_state_cb;
|
||||||
|
void *sock_state_cb_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ares__send_query(ares_channel channel, struct query *query, time_t now);
|
void ares__send_query(ares_channel channel, struct query *query, time_t now);
|
||||||
void ares__close_sockets(struct server_state *server);
|
void ares__close_sockets(ares_channel channel, struct server_state *server);
|
||||||
int ares__get_hostent(FILE *fp, int family, struct hostent **host);
|
int ares__get_hostent(FILE *fp, int family, struct hostent **host);
|
||||||
int ares__read_line(FILE *fp, char **buf, int *bufsize);
|
int ares__read_line(FILE *fp, char **buf, int *bufsize);
|
||||||
|
|
||||||
|
#define SOCK_STATE_CALLBACK(c, s, r, w) \
|
||||||
|
do { \
|
||||||
|
if ((c)->sock_state_cb) \
|
||||||
|
(c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#ifdef CURLDEBUG
|
#ifdef CURLDEBUG
|
||||||
/* This is low-level hard-hacking memory leak tracking and similar. Using the
|
/* This is low-level hard-hacking memory leak tracking and similar. Using the
|
||||||
libcurl lowlevel code from within library is ugly and only works when
|
libcurl lowlevel code from within library is ugly and only works when
|
||||||
|
@@ -149,7 +149,10 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now)
|
|||||||
wcount -= sendreq->len;
|
wcount -= sendreq->len;
|
||||||
server->qhead = sendreq->next;
|
server->qhead = sendreq->next;
|
||||||
if (server->qhead == NULL)
|
if (server->qhead == NULL)
|
||||||
server->qtail = NULL;
|
{
|
||||||
|
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
|
||||||
|
server->qtail = NULL;
|
||||||
|
}
|
||||||
free(sendreq);
|
free(sendreq);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -179,7 +182,10 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now)
|
|||||||
{
|
{
|
||||||
server->qhead = sendreq->next;
|
server->qhead = sendreq->next;
|
||||||
if (server->qhead == NULL)
|
if (server->qhead == NULL)
|
||||||
server->qtail = NULL;
|
{
|
||||||
|
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
|
||||||
|
server->qtail = NULL;
|
||||||
|
}
|
||||||
free(sendreq);
|
free(sendreq);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -380,7 +386,7 @@ static void handle_error(ares_channel channel, int whichserver, time_t now)
|
|||||||
struct query *query, *next;
|
struct query *query, *next;
|
||||||
|
|
||||||
/* Reset communications with this server. */
|
/* Reset communications with this server. */
|
||||||
ares__close_sockets(&channel->servers[whichserver]);
|
ares__close_sockets(channel, &channel->servers[whichserver]);
|
||||||
|
|
||||||
/* Tell all queries talking to this server to move on and not try
|
/* Tell all queries talking to this server to move on and not try
|
||||||
* this server again.
|
* this server again.
|
||||||
@@ -452,7 +458,10 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now)
|
|||||||
if (server->qtail)
|
if (server->qtail)
|
||||||
server->qtail->next = sendreq;
|
server->qtail->next = sendreq;
|
||||||
else
|
else
|
||||||
server->qhead = sendreq;
|
{
|
||||||
|
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 1);
|
||||||
|
server->qhead = sendreq;
|
||||||
|
}
|
||||||
server->qtail = sendreq;
|
server->qtail = sendreq;
|
||||||
query->timeout = 0;
|
query->timeout = 0;
|
||||||
}
|
}
|
||||||
@@ -575,6 +584,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SOCK_STATE_CALLBACK(channel, s, 1, 0);
|
||||||
server->tcp_buffer_pos = 0;
|
server->tcp_buffer_pos = 0;
|
||||||
server->tcp_socket = s;
|
server->tcp_socket = s;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -604,6 +614,8 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SOCK_STATE_CALLBACK(channel, s, 1, 0);
|
||||||
|
|
||||||
server->udp_socket = s;
|
server->udp_socket = s;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -714,7 +726,7 @@ static struct query *end_query (ares_channel channel, struct query *query, int s
|
|||||||
if (!channel->queries && !(channel->flags & ARES_FLAG_STAYOPEN))
|
if (!channel->queries && !(channel->flags & ARES_FLAG_STAYOPEN))
|
||||||
{
|
{
|
||||||
for (i = 0; i < channel->nservers; i++)
|
for (i = 0; i < channel->nservers; i++)
|
||||||
ares__close_sockets(&channel->servers[i]);
|
ares__close_sockets(channel, &channel->servers[i]);
|
||||||
}
|
}
|
||||||
return (next);
|
return (next);
|
||||||
}
|
}
|
||||||
|
@@ -47,6 +47,15 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
|||||||
CPPFLAGS="$CPPFLAGS -DCURLDEBUG -I$srcdir/../include"
|
CPPFLAGS="$CPPFLAGS -DCURLDEBUG -I$srcdir/../include"
|
||||||
CFLAGS="$CFLAGS -g"
|
CFLAGS="$CFLAGS -g"
|
||||||
|
|
||||||
|
dnl check for how to do large files, needed to get the curl_off_t check
|
||||||
|
dnl done right
|
||||||
|
AC_SYS_LARGEFILE
|
||||||
|
|
||||||
|
AC_CHECK_SIZEOF(curl_off_t, ,[
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "$srcdir/../include/curl/curl.h"
|
||||||
|
])
|
||||||
|
|
||||||
dnl set compiler "debug" options to become more picky, and remove
|
dnl set compiler "debug" options to become more picky, and remove
|
||||||
dnl optimize options from CFLAGS
|
dnl optimize options from CFLAGS
|
||||||
CURL_CC_DEBUG_OPTS
|
CURL_CC_DEBUG_OPTS
|
||||||
@@ -57,8 +66,21 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
|||||||
)
|
)
|
||||||
|
|
||||||
dnl libtool setup
|
dnl libtool setup
|
||||||
|
CARES_CLEAR_LIBTOOL_TAGS
|
||||||
AC_PROG_LIBTOOL
|
AC_PROG_LIBTOOL
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if we need -no-undefined])
|
||||||
|
case $host in
|
||||||
|
*-*-cygwin | *-*-mingw* | *-*-pw32*)
|
||||||
|
need_no_undefined=yes
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
need_no_undefined=no
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_MSG_RESULT($need_no_undefined)
|
||||||
|
AM_CONDITIONAL(NO_UNDEFINED, test x$need_no_undefined = xyes)
|
||||||
|
|
||||||
dnl Checks for header files.
|
dnl Checks for header files.
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
|
|
||||||
@@ -121,10 +143,6 @@ AC_C_CONST
|
|||||||
AC_TYPE_SIZE_T
|
AC_TYPE_SIZE_T
|
||||||
AC_HEADER_TIME
|
AC_HEADER_TIME
|
||||||
|
|
||||||
AC_CHECK_SIZEOF(curl_off_t, ,[
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "$srcdir/include/curl/curl.h"
|
|
||||||
])
|
|
||||||
AC_CHECK_SIZEOF(size_t)
|
AC_CHECK_SIZEOF(size_t)
|
||||||
AC_CHECK_SIZEOF(long)
|
AC_CHECK_SIZEOF(long)
|
||||||
AC_CHECK_SIZEOF(time_t)
|
AC_CHECK_SIZEOF(time_t)
|
||||||
@@ -428,7 +446,8 @@ int main()
|
|||||||
}
|
}
|
||||||
], [
|
], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6,1,[Define to 1 if inet_ntop supports IPv6.])
|
AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6,1,
|
||||||
|
[Define to 1 if inet_ntop supports IPv6.])
|
||||||
], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
|
], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -494,13 +513,15 @@ dnl and get the types of five of its arguments.
|
|||||||
CURL_CHECK_FUNC_GETNAMEINFO
|
CURL_CHECK_FUNC_GETNAMEINFO
|
||||||
|
|
||||||
|
|
||||||
dnl God bless non-standardized functions! We need to see which getservbyport_r variant is available
|
dnl God bless non-standardized functions! We need to see which getservbyport_r
|
||||||
|
dnl variant is available
|
||||||
CARES_CHECK_GETSERVBYPORT_R
|
CARES_CHECK_GETSERVBYPORT_R
|
||||||
|
|
||||||
CURL_CHECK_NONBLOCKING_SOCKET
|
CURL_CHECK_NONBLOCKING_SOCKET
|
||||||
|
|
||||||
AC_C_BIGENDIAN(
|
AC_C_BIGENDIAN(
|
||||||
[AC_DEFINE(ARES_BIG_ENDIAN, 1, [define this if ares is built for a big endian system])],
|
[AC_DEFINE(ARES_BIG_ENDIAN, 1,
|
||||||
|
[define this if ares is built for a big endian system])],
|
||||||
,
|
,
|
||||||
[AC_MSG_WARN([couldn't figure out endianess, assuming little endian!])]
|
[AC_MSG_WARN([couldn't figure out endianess, assuming little endian!])]
|
||||||
)
|
)
|
||||||
|
103
configure.ac
103
configure.ac
@@ -5,7 +5,7 @@
|
|||||||
# | (__| |_| | _ <| |___
|
# | (__| |_| | _ <| |___
|
||||||
# \___|\___/|_| \_\_____|
|
# \___|\___/|_| \_\_____|
|
||||||
#
|
#
|
||||||
# Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
# Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
#
|
#
|
||||||
# This software is licensed as described in the file COPYING, which
|
# This software is licensed as described in the file COPYING, which
|
||||||
# you should have received as part of this distribution. The terms
|
# you should have received as part of this distribution. The terms
|
||||||
@@ -306,6 +306,13 @@ AC_HELP_STRING([--disable-manual],[Disable built-in manual]),
|
|||||||
dnl The actual use of the USE_MANUAL variable is done much later in this
|
dnl The actual use of the USE_MANUAL variable is done much later in this
|
||||||
dnl script to allow other actions to disable it as well.
|
dnl script to allow other actions to disable it as well.
|
||||||
|
|
||||||
|
dnl **********************************************************************
|
||||||
|
dnl check if this is the Intel ICC compiler, and if so make it stricter
|
||||||
|
dnl (convert warning 147 into an error) so that it properly can detect the
|
||||||
|
dnl gethostbyname_r() version
|
||||||
|
dnl **********************************************************************
|
||||||
|
CURL_DETECT_ICC([CFLAGS="$CFLAGS -we 147"])
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
dnl Checks for libraries.
|
dnl Checks for libraries.
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
@@ -465,20 +472,31 @@ dnl **********************************************************************
|
|||||||
dnl Check for the presence of the winmm library.
|
dnl Check for the presence of the winmm library.
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
|
|
||||||
AC_MSG_CHECKING([for timeGetTime in winmm])
|
case $host in
|
||||||
my_ac_save_LIBS=$LIBS
|
*-*-cygwin*)
|
||||||
LIBS="-lwinmm $LIBS"
|
dnl Under Cygwin, winmm exists but is not needed as WIN32 is not #defined
|
||||||
AC_TRY_LINK([#include <windef.h>
|
dnl and gettimeofday() will be used regardless of the outcome of this test.
|
||||||
#include <mmsystem.h>
|
dnl Skip this test, otherwise -lwinmm will be needlessly added to LIBS
|
||||||
],
|
dnl (and recorded as such in the .la file, potentially affecting downstream
|
||||||
[timeGetTime();],
|
dnl clients of the library.)
|
||||||
[ dnl worked!
|
;;
|
||||||
AC_MSG_RESULT([yes])
|
*)
|
||||||
],
|
AC_MSG_CHECKING([for timeGetTime in winmm])
|
||||||
[ dnl failed, restore LIBS
|
my_ac_save_LIBS=$LIBS
|
||||||
LIBS=$my_ac_save_LIBS
|
LIBS="-lwinmm $LIBS"
|
||||||
AC_MSG_RESULT(no)]
|
AC_TRY_LINK([#include <windef.h>
|
||||||
)
|
#include <mmsystem.h>
|
||||||
|
],
|
||||||
|
[timeGetTime();],
|
||||||
|
[ dnl worked!
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
],
|
||||||
|
[ dnl failed, restore LIBS
|
||||||
|
LIBS=$my_ac_save_LIBS
|
||||||
|
AC_MSG_RESULT(no)]
|
||||||
|
)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
dnl Checks for IPv6
|
dnl Checks for IPv6
|
||||||
@@ -881,18 +899,26 @@ if test X"$OPT_SSL" != Xno; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
dnl This is for Msys/Mingw
|
dnl This is for Msys/Mingw
|
||||||
AC_MSG_CHECKING([for gdi32])
|
case $host in
|
||||||
my_ac_save_LIBS=$LIBS
|
*-*-cygwin*)
|
||||||
LIBS="-lgdi32 $LIBS"
|
dnl Under Cygwin this is extraneous and causes an unnecessary -lgdi32
|
||||||
AC_TRY_LINK([#include <windef.h>
|
dnl to be added to LIBS and recorded in the .la file.
|
||||||
#include <wingdi.h>],
|
;;
|
||||||
[GdiFlush();],
|
*)
|
||||||
[ dnl worked!
|
AC_MSG_CHECKING([for gdi32])
|
||||||
AC_MSG_RESULT([yes])],
|
my_ac_save_LIBS=$LIBS
|
||||||
[ dnl failed, restore LIBS
|
LIBS="-lgdi32 $LIBS"
|
||||||
LIBS=$my_ac_save_LIBS
|
AC_TRY_LINK([#include <windef.h>
|
||||||
AC_MSG_RESULT(no)]
|
#include <wingdi.h>],
|
||||||
)
|
[GdiFlush();],
|
||||||
|
[ dnl worked!
|
||||||
|
AC_MSG_RESULT([yes])],
|
||||||
|
[ dnl failed, restore LIBS
|
||||||
|
LIBS=$my_ac_save_LIBS
|
||||||
|
AC_MSG_RESULT(no)]
|
||||||
|
)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
AC_CHECK_LIB(crypto, CRYPTO_lock,[
|
AC_CHECK_LIB(crypto, CRYPTO_lock,[
|
||||||
HAVECRYPTO="yes"
|
HAVECRYPTO="yes"
|
||||||
@@ -940,9 +966,18 @@ if test X"$OPT_SSL" != Xno; then
|
|||||||
AC_DEFINE(USE_OPENSSL, 1, [if OpenSSL is in use]))
|
AC_DEFINE(USE_OPENSSL, 1, [if OpenSSL is in use]))
|
||||||
|
|
||||||
if test $ac_cv_header_openssl_x509_h = no; then
|
if test $ac_cv_header_openssl_x509_h = no; then
|
||||||
AC_CHECK_HEADERS(x509.h rsa.h crypto.h pem.h ssl.h err.h,
|
dnl we don't use the "action" part of the AC_CHECK_HEADERS macro
|
||||||
|
dnl since 'err.h' might in fact find a krb4 header with the same
|
||||||
|
dnl name
|
||||||
|
AC_CHECK_HEADERS(x509.h rsa.h crypto.h pem.h ssl.h err.h)
|
||||||
|
|
||||||
|
if test $ac_cv_header_x509_h = yes &&
|
||||||
|
test $ac_cv_header_crypto_h = yes &&
|
||||||
|
test $ac_cv_header_ssl_h = yes; then
|
||||||
|
dnl three matches
|
||||||
curl_ssl_msg="enabled (OpenSSL)"
|
curl_ssl_msg="enabled (OpenSSL)"
|
||||||
OPENSSL_ENABLED=1)
|
OPENSSL_ENABLED=1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -1396,7 +1431,8 @@ if test x$cross_compiling != xyes; then
|
|||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
,
|
,
|
||||||
dnl not invoked when crosscompiling)
|
dnl not invoked when crosscompiling)
|
||||||
])
|
echo "hej"
|
||||||
|
)
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
dnl and for crosscompilings
|
dnl and for crosscompilings
|
||||||
@@ -1560,8 +1596,10 @@ AC_CHECK_FUNCS( strtoll \
|
|||||||
ftruncate \
|
ftruncate \
|
||||||
pipe \
|
pipe \
|
||||||
poll \
|
poll \
|
||||||
|
getprotobyname \
|
||||||
getrlimit \
|
getrlimit \
|
||||||
setrlimit,
|
setrlimit \
|
||||||
|
fork,
|
||||||
dnl if found
|
dnl if found
|
||||||
[],
|
[],
|
||||||
dnl if not found, $ac_func is the name we check for
|
dnl if not found, $ac_func is the name we check for
|
||||||
@@ -1953,6 +1991,9 @@ AC_CONFIG_FILES([Makefile \
|
|||||||
packages/EPM/curl.list \
|
packages/EPM/curl.list \
|
||||||
packages/EPM/Makefile \
|
packages/EPM/Makefile \
|
||||||
packages/vms/Makefile \
|
packages/vms/Makefile \
|
||||||
|
packages/AIX/Makefile \
|
||||||
|
packages/AIX/RPM/Makefile \
|
||||||
|
packages/AIX/RPM/curl.spec \
|
||||||
curl-config \
|
curl-config \
|
||||||
libcurl.pc
|
libcurl.pc
|
||||||
])
|
])
|
||||||
|
@@ -1,10 +1,30 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
#***************************************************************************
|
||||||
|
# _ _ ____ _
|
||||||
|
# Project ___| | | | _ \| |
|
||||||
|
# / __| | | | |_) | |
|
||||||
|
# | (__| |_| | _ <| |___
|
||||||
|
# \___|\___/|_| \_\_____|
|
||||||
|
#
|
||||||
|
# Copyright (C) 2001 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
#
|
||||||
|
# This software is licensed as described in the file COPYING, which
|
||||||
|
# you should have received as part of this distribution. The terms
|
||||||
|
# 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$
|
||||||
|
###########################################################################
|
||||||
#
|
#
|
||||||
# The idea to this kind of setup info script was stolen from numerous
|
# The idea to this kind of setup info script was stolen from numerous
|
||||||
# other packages, such as neon, libxml and gnome.
|
# other packages, such as neon, libxml and gnome.
|
||||||
#
|
#
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
prefix=@prefix@
|
prefix=@prefix@
|
||||||
exec_prefix=@exec_prefix@
|
exec_prefix=@exec_prefix@
|
||||||
includedir=@includedir@
|
includedir=@includedir@
|
||||||
@@ -19,6 +39,7 @@ Available values for OPTION include:
|
|||||||
--ca ca bundle install path
|
--ca ca bundle install path
|
||||||
--cc compiler
|
--cc compiler
|
||||||
--cflags pre-processor and compiler flags
|
--cflags pre-processor and compiler flags
|
||||||
|
--checkfor [version] check for (lib)curl of the specified version
|
||||||
--features newline separated list of enabled features
|
--features newline separated list of enabled features
|
||||||
--protocols newline separated list of enabled protocols
|
--protocols newline separated list of enabled protocols
|
||||||
--help display this help and exit
|
--help display this help and exit
|
||||||
@@ -122,6 +143,26 @@ while test $# -gt 0; do
|
|||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
--checkfor)
|
||||||
|
checkfor=$2
|
||||||
|
cmajor=`echo $checkfor | cut -d. -f1`
|
||||||
|
cminor=`echo $checkfor | cut -d. -f2`
|
||||||
|
# when extracting the patch part we strip off everything after a
|
||||||
|
# dash as that's used for things like version 1.2.3-CVS
|
||||||
|
cpatch=`echo $checkfor | cut -d. -f3 | cut -d- -f1`
|
||||||
|
checknum=`echo "$cmajor*256*256 + $cminor*256 + ${cpatch:-0}" | bc`
|
||||||
|
numuppercase=`echo @VERSIONNUM@ | tr 'a-f' 'A-F'`
|
||||||
|
nownum=`echo "obase=10; ibase=16; $numuppercase" | bc`
|
||||||
|
|
||||||
|
if test "$nownum" -ge "$checknum"; then
|
||||||
|
# silent success
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "requested version $checkfor is newer than existing @VERSION@"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
--vernum)
|
--vernum)
|
||||||
echo @VERSIONNUM@
|
echo @VERSIONNUM@
|
||||||
exit 0
|
exit 0
|
||||||
|
@@ -155,6 +155,11 @@ S-Lang
|
|||||||
S-Lang binding written by John E Davis
|
S-Lang binding written by John E Davis
|
||||||
http://www.jedsoft.org/slang/modules/curl.html
|
http://www.jedsoft.org/slang/modules/curl.html
|
||||||
|
|
||||||
|
SPL
|
||||||
|
|
||||||
|
SPL binding written by Clifford Wolf
|
||||||
|
http://www.clifford.at/spl/
|
||||||
|
|
||||||
Tcl
|
Tcl
|
||||||
|
|
||||||
Tclcurl is written by Andr<64>s Garc<72>a
|
Tclcurl is written by Andr<64>s Garc<72>a
|
||||||
@@ -173,3 +178,8 @@ wxWidgets
|
|||||||
|
|
||||||
Written by Casey O'Donnell
|
Written by Casey O'Donnell
|
||||||
http://homepage.mac.com/codonnell/wxcurldav/
|
http://homepage.mac.com/codonnell/wxcurldav/
|
||||||
|
|
||||||
|
XBLite
|
||||||
|
|
||||||
|
Written by David Szafranski
|
||||||
|
http://perso.wanadoo.fr/xblite/libraries.html
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
Date: October 27, 2005
|
Date: May 15, 2006
|
||||||
Author: Daniel Stenberg <daniel@haxx.se>
|
Author: Daniel Stenberg <daniel@haxx.se>
|
||||||
URL: http://curl.haxx.se/legal/distro-dilemma.html
|
URL: http://curl.haxx.se/legal/distro-dilemma.html
|
||||||
|
|
||||||
Condition
|
Condition
|
||||||
|
|
||||||
This document is written to describe the situation as it is right
|
This document is written to describe the situation as it is right
|
||||||
now. libcurl 7.15.0 is currently the latest version available. Things may (or
|
now. libcurl 7.15.3 is currently the latest version available. Things may of
|
||||||
perhaps will) of course change in the future.
|
course change in the future.
|
||||||
|
|
||||||
This document reflects my view and understanding of these things. Please tell
|
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.
|
me where and how you think I'm wrong, and I'll try to correct my mistakes.
|
||||||
@@ -16,11 +16,10 @@ Background
|
|||||||
The Free Software Foundation has deemed the Original BSD license[1] to be
|
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
|
"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,
|
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
|
it MUST NOT be linked with any Original BSD-licensed parts or libraries.
|
||||||
libraries. Doing so will violate the GPL license. For a long time, very many
|
Doing so will violate the GPL license. For a long time, very many GPL
|
||||||
GPL licensed programs have avoided this license mess by adding an
|
licensed programs have avoided this license mess by adding an exception[8] to
|
||||||
exception[8] to their license. And many others have just closed their eyes
|
their license. And many others have just closed their eyes for this problem.
|
||||||
for this problem.
|
|
||||||
|
|
||||||
libcurl is MIT-style[4] licensed - how on earth did this dilemma fall onto
|
libcurl is MIT-style[4] licensed - how on earth did this dilemma fall onto
|
||||||
our plates?
|
our plates?
|
||||||
@@ -49,25 +48,13 @@ Part of the Operating System
|
|||||||
Debian does however not take this stance and has officially(?) claimed that
|
Debian does however not take this stance and has officially(?) claimed that
|
||||||
OpenSSL is not a required part of the Debian operating system
|
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
|
GnuTLS
|
||||||
|
|
||||||
With the release of libcurl 7.14.0 (May 2005), it can now get built to use
|
With the release of libcurl 7.14.0 (May 2005), libcurl can now get built to
|
||||||
GnuTLS instead of OpenSSL. GnuTLS is a LGPL[7] licensed library that offers a
|
use GnuTLS instead of OpenSSL. GnuTLS is an LGPL[7] licensed library that
|
||||||
matching set of features as OpenSSL does. Now, you can build and distribute
|
offers a matching set of features as OpenSSL does. Now, you can build and
|
||||||
an SSL capable libcurl without including any Original BSD licensed code.
|
distribute an TLS/SSL capable libcurl without including any Original BSD
|
||||||
|
licensed code.
|
||||||
|
|
||||||
I believe Debian is the first distro to provide libcurl/GnutTLS packages.
|
I believe Debian is the first distro to provide libcurl/GnutTLS packages.
|
||||||
|
|
||||||
@@ -80,23 +67,20 @@ GnuTLS vs OpenSSL
|
|||||||
and it has not been tested nor used very extensively, while the OpenSSL
|
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.
|
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.
|
|
||||||
|
|
||||||
GnuTLS
|
GnuTLS
|
||||||
- LGPL licensened
|
- LGPL licensened
|
||||||
- supports SRP
|
- supports SRP
|
||||||
- lacks SSLv2 support
|
- lacks SSLv2 support
|
||||||
- lacks MD2 support (used by at least some CA certs)
|
- lacks MD2 support (used by at least some CA certs)
|
||||||
|
- lacks the crypto functions libcurl uses for NTLM
|
||||||
|
|
||||||
OpenSSL
|
OpenSSL
|
||||||
- Original BSD licensened
|
- Original BSD licensened
|
||||||
- lacks SRP
|
- lacks SRP
|
||||||
- supports SSLv2
|
- supports SSLv2
|
||||||
- older and more widely used
|
- older and more widely used
|
||||||
|
- provides crypto functions libcurl uses for NTLM
|
||||||
|
- libcurl can do non-blocking connects with it in 7.15.4 and later
|
||||||
|
|
||||||
The Better License, Original BSD or LGPL?
|
The Better License, Original BSD or LGPL?
|
||||||
|
|
||||||
@@ -124,20 +108,21 @@ More SSL Libraries
|
|||||||
Application Angle of this Problem
|
Application Angle of this Problem
|
||||||
|
|
||||||
libcurl is built to use one SSL/TLS library. It uses a single fixed name (by
|
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
|
default) on the built/created lib file, and applications are built/linked to
|
||||||
one libcurl instance with another one that uses the other SSL/TLS library
|
use that single lib. Replacing one libcurl instance with another one that
|
||||||
might break one or more applications (due to ABI differences and/or different
|
uses the other SSL/TLS library might break one or more applications (due to
|
||||||
feature set). You want your application to use the libcurl it was built for.
|
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
|
Project cURL Angle of this Problem
|
||||||
|
|
||||||
We distribute libcurl and everyone may build libcurl with either library. At
|
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
|
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
|
affects users - GPL application authors only - of our lib as it comes
|
||||||
included and delivered on some distros.
|
included and delivered on some distros.
|
||||||
|
|
||||||
libcurl has different ABI when built with different SSL/TLS libraries due to
|
libcurl has different ABI when built with different SSL/TLS libraries due to
|
||||||
two reasons:
|
these reasons:
|
||||||
|
|
||||||
1. No one has worked on fixing this. The mutex/lock callbacks should be set
|
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
|
with a generic libcurl function that should use the proper underlying
|
||||||
@@ -146,25 +131,25 @@ Project cURL Angle of this Problem
|
|||||||
2. The CURLOPT_SSL_CTX_FUNCTION option is not possible to "emulate" on GnuTLS
|
2. The CURLOPT_SSL_CTX_FUNCTION option is not possible to "emulate" on GnuTLS
|
||||||
but simply requires OpenSSL.
|
but simply requires OpenSSL.
|
||||||
|
|
||||||
|
3. There might be some other subtle differences just because nobody has yet
|
||||||
|
tried to make a fixed ABI like this.
|
||||||
|
|
||||||
Distro Angle of this Problem
|
Distro Angle of this Problem
|
||||||
|
|
||||||
A distro can provide separate libcurls built with different SSL/TLS libraries
|
To my knowledge there is only one distro that ships libcurl built with either
|
||||||
to work around this, but at least Debian seems to be very hostile against
|
one of the SSL libs supported.
|
||||||
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
|
Debian Linux is now (since mid September 2005) providing two different
|
||||||
man pages etc.
|
libcurl packages, one for libcurl built with OpenSSL and one built with
|
||||||
|
GnuTLS. They use different .so names and can this both be installed in a
|
||||||
|
single system simultaneously. This has been said to be a transitional system
|
||||||
|
not desired to keep in the long run.
|
||||||
|
|
||||||
Fixing the Only Problem
|
Fixing the Only Problem
|
||||||
|
|
||||||
The only problem is thus for distributions that want to offer libcurl
|
The only problem is thus for distributions that want to offer libcurl
|
||||||
versions built with more than one SSL/TLS library.
|
versions built with more than one SSL/TLS library.
|
||||||
|
|
||||||
Debian is now (since mid September 2005) providing two different devel
|
|
||||||
packages, one for libcurl built with OpenSSL and one built with GnuTLS. They
|
|
||||||
use different .so names and can this both be installed in a single system
|
|
||||||
simultaneously. This has previously been said as a transitional system not
|
|
||||||
desired to keep in the long run.
|
|
||||||
|
|
||||||
Since multiple libcurl binaries using different names are ruled out, we need
|
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
|
to come up with a way to have one single libcurl that someone uses different
|
||||||
underlying libraries. The best(?) approach currently suggested involves this:
|
underlying libraries. The best(?) approach currently suggested involves this:
|
||||||
@@ -194,9 +179,9 @@ Fixing the Only Problem
|
|||||||
|
|
||||||
When Will This Happen
|
When Will This Happen
|
||||||
|
|
||||||
Note again that this is not a problem in curl, it doesn't solve any actual
|
This is not a problem in curl, it doesn't solve any actual technical problems
|
||||||
technical problems in our project. Don't hold your breath for this to happen
|
in our project. Don't hold your breath for this to happen very soon (if at
|
||||||
very soon (if at all) unless you step forward and contribute.
|
all) unless you step forward and contribute.
|
||||||
|
|
||||||
The suggestion that is outlined above is still only a suggestion. Feel free
|
The suggestion that is outlined above is still only a suggestion. Feel free
|
||||||
to bring a better idea!
|
to bring a better idea!
|
||||||
@@ -206,7 +191,7 @@ When Will This Happen
|
|||||||
code like today (without the use of lib2), should you decide to ignore the
|
code like today (without the use of lib2), should you decide to ignore the
|
||||||
problems outlined in this document.
|
problems outlined in this document.
|
||||||
|
|
||||||
Update: Work on this has been initiated by Richard Atterer:
|
Work on this was suggested by Richard Atterer:
|
||||||
|
|
||||||
http://curl.haxx.se/mail/lib-2005-09/0066.html
|
http://curl.haxx.se/mail/lib-2005-09/0066.html
|
||||||
|
|
||||||
|
@@ -91,8 +91,8 @@ FTP
|
|||||||
- no dir depth limit
|
- no dir depth limit
|
||||||
|
|
||||||
FTPS (*1)
|
FTPS (*1)
|
||||||
- explicit ftps:// support that use SSL on both connections
|
- implicit ftps:// support that use SSL on both connections
|
||||||
- implicit "AUTH TSL" and "AUTH SSL" usage to "upgrade" plain ftp://
|
- explicit "AUTH TSL" and "AUTH SSL" usage to "upgrade" plain ftp://
|
||||||
connection to use SSL for both or one of the connections
|
connection to use SSL for both or one of the connections
|
||||||
|
|
||||||
TFTP
|
TFTP
|
||||||
|
@@ -3,9 +3,14 @@ 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
|
changelog of the current development status, as one or more of these problems
|
||||||
may have been fixed since this was written!
|
may have been fixed since this was written!
|
||||||
|
|
||||||
33. Doing FTP upload and specifying a URL that ends with a slash will cause
|
34. The SOCKS connection codes don't properly acknowledge (connect) timeouts.
|
||||||
a filed named "(nil)" get created. The proper fix should most likely be to
|
|
||||||
reject the upload early since there's no target file name specified.
|
33. Doing multi-pass HTTP authentication on a non-default port does not work.
|
||||||
|
This happens because the multi-pass code abuses the redirect following code
|
||||||
|
for doing multiple requests, and when we following redirects to an absolute
|
||||||
|
URL we must use the newly specified port and not the one specified in the
|
||||||
|
original URL. A proper fix to this would need to separate the negotiation
|
||||||
|
"redirect" from an actual redirect.
|
||||||
|
|
||||||
32. (At least on Windows) If libcurl is built with c-ares and there's no DNS
|
32. (At least on Windows) If libcurl is built with c-ares and there's no DNS
|
||||||
server configured in the system, the ares_init() call fails and thus
|
server configured in the system, the ares_init() call fails and thus
|
||||||
@@ -30,8 +35,6 @@ may have been fixed since this was written!
|
|||||||
|
|
||||||
See http://curl.haxx.se/bug/view.cgi?id=1371118
|
See http://curl.haxx.se/bug/view.cgi?id=1371118
|
||||||
|
|
||||||
28. The TFTP code is not portable and will fail on some architectures.
|
|
||||||
|
|
||||||
26. NTLM authentication using SSPI (on Windows) when (lib)curl is running in
|
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
|
"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
|
to what winhttp does. See http://curl.haxx.se/bug/view.cgi?id=1281867
|
||||||
@@ -42,12 +45,6 @@ may have been fixed since this was written!
|
|||||||
--proxy-anyauth. There's work in progress on this problem, and a recent
|
--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
|
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.
|
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
|
We don't have any test cases for SOCKS proxy. We probably have even more
|
||||||
bugs and lack of features when a SOCKS proxy is used. And there seem to be a
|
bugs and lack of features when a SOCKS proxy is used. And there seem to be a
|
||||||
@@ -69,6 +66,8 @@ may have been fixed since this was written!
|
|||||||
specification). The receiver will convert the data from the standard
|
specification). The receiver will convert the data from the standard
|
||||||
form to his own internal form.
|
form to his own internal form.
|
||||||
|
|
||||||
|
Since 7.15.4 at least line endings are converted.
|
||||||
|
|
||||||
19. FTP 3rd party transfers with the multi interface doesn't work. Test:
|
19. FTP 3rd party transfers with the multi interface doesn't work. Test:
|
||||||
define CURL_MULTIEASY, rebuild curl, run test case 230 - 232.
|
define CURL_MULTIEASY, rebuild curl, run test case 230 - 232.
|
||||||
|
|
||||||
|
@@ -726,7 +726,7 @@ LDAP
|
|||||||
Working with LDAP URLs":
|
Working with LDAP URLs":
|
||||||
http://developer.netscape.com/docs/manuals/dirsdk/csdk30/url.htm
|
http://developer.netscape.com/docs/manuals/dirsdk/csdk30/url.htm
|
||||||
|
|
||||||
RFC 2255, "The LDAP URL Format" http://www.rfc-editor.org/rfc/rfc2255.txt
|
RFC 2255, "The LDAP URL Format" http://curl.haxx.se/rfc/rfc2255.txt
|
||||||
|
|
||||||
To show you an example, this is now I can get all people from my local LDAP
|
To show you an example, this is now I can get all people from my local LDAP
|
||||||
server that has a certain sub-domain in their email address:
|
server that has a certain sub-domain in their email address:
|
||||||
|
18
docs/THANKS
18
docs/THANKS
@@ -14,6 +14,7 @@ Alex Suykov
|
|||||||
Alex aka WindEagle
|
Alex aka WindEagle
|
||||||
Alexander Kourakos
|
Alexander Kourakos
|
||||||
Alexander Krasnostavsky
|
Alexander Krasnostavsky
|
||||||
|
Alexander Lazic
|
||||||
Alexander Zhuravlev
|
Alexander Zhuravlev
|
||||||
Alexis Carvalho
|
Alexis Carvalho
|
||||||
Amol Pattekar
|
Amol Pattekar
|
||||||
@@ -22,6 +23,7 @@ Andreas Damm
|
|||||||
Andreas Olsson
|
Andreas Olsson
|
||||||
Andreas Rieke
|
Andreas Rieke
|
||||||
Andres Garcia
|
Andres Garcia
|
||||||
|
Andrew Benham
|
||||||
Andrew Bushnell
|
Andrew Bushnell
|
||||||
Andrew Francis
|
Andrew Francis
|
||||||
Andrew Fuller
|
Andrew Fuller
|
||||||
@@ -94,6 +96,7 @@ David James
|
|||||||
David Kimdon
|
David Kimdon
|
||||||
David Lang
|
David Lang
|
||||||
David LeBlanc
|
David LeBlanc
|
||||||
|
David McCreedy
|
||||||
David Odin
|
David Odin
|
||||||
David Phillips
|
David Phillips
|
||||||
David Shaw
|
David Shaw
|
||||||
@@ -115,6 +118,8 @@ Doug Kaufman
|
|||||||
Doug Porter
|
Doug Porter
|
||||||
Douglas E. Wegscheid
|
Douglas E. Wegscheid
|
||||||
Douglas R. Horner
|
Douglas R. Horner
|
||||||
|
Dov Murik
|
||||||
|
Duane Cathey
|
||||||
Dustin Boswell
|
Dustin Boswell
|
||||||
Dylan Ellicott
|
Dylan Ellicott
|
||||||
Dylan Salisbury
|
Dylan Salisbury
|
||||||
@@ -200,6 +205,7 @@ Jamie Wilkinson
|
|||||||
Jan Kunder
|
Jan Kunder
|
||||||
Jason S. Priebe
|
Jason S. Priebe
|
||||||
Jaz Fresh
|
Jaz Fresh
|
||||||
|
Jean Jacques Drouin
|
||||||
Jean-Claude Chauve
|
Jean-Claude Chauve
|
||||||
Jean-Louis Lemaire
|
Jean-Louis Lemaire
|
||||||
Jean-Marc Ranger
|
Jean-Marc Ranger
|
||||||
@@ -241,11 +247,13 @@ J
|
|||||||
Kai Sommerfeld
|
Kai Sommerfeld
|
||||||
Kai-Uwe Rommel
|
Kai-Uwe Rommel
|
||||||
Kang-Jin Lee
|
Kang-Jin Lee
|
||||||
|
Karl Moerder
|
||||||
Karol Pietrzak
|
Karol Pietrzak
|
||||||
Keith MacDonald
|
Keith MacDonald
|
||||||
Keith McGuigan
|
Keith McGuigan
|
||||||
Ken Hirsch
|
Ken Hirsch
|
||||||
Ken Rastatter
|
Ken Rastatter
|
||||||
|
Kent Boortz
|
||||||
Kevin Fisk
|
Kevin Fisk
|
||||||
Kevin Lussier
|
Kevin Lussier
|
||||||
Kevin Roth
|
Kevin Roth
|
||||||
@@ -286,6 +294,7 @@ Marco G. Salvagno
|
|||||||
Marcus Webster
|
Marcus Webster
|
||||||
Mario Schroeder
|
Mario Schroeder
|
||||||
Mark Butler
|
Mark Butler
|
||||||
|
Markus Koetter
|
||||||
Markus Moeller
|
Markus Moeller
|
||||||
Markus Oberhumer
|
Markus Oberhumer
|
||||||
Martijn Koster
|
Martijn Koster
|
||||||
@@ -304,9 +313,11 @@ Mekonikum
|
|||||||
Mettgut Jamalla
|
Mettgut Jamalla
|
||||||
Michael Benedict
|
Michael Benedict
|
||||||
Michael Curtis
|
Michael Curtis
|
||||||
|
Michael Jahn
|
||||||
Michael Mealling
|
Michael Mealling
|
||||||
Michael Wallner
|
Michael Wallner
|
||||||
Michal Bonino
|
Michal Bonino
|
||||||
|
Michal Marek
|
||||||
Mihai Ionescu
|
Mihai Ionescu
|
||||||
Mike Bytnar
|
Mike Bytnar
|
||||||
Mike Dobbs
|
Mike Dobbs
|
||||||
@@ -347,7 +358,9 @@ Pedro Neves
|
|||||||
Pete Su
|
Pete Su
|
||||||
Peter Bray
|
Peter Bray
|
||||||
Peter Forret
|
Peter Forret
|
||||||
|
Peter Heuchert
|
||||||
Peter Pentchev
|
Peter Pentchev
|
||||||
|
Peter Su
|
||||||
Peter Sylvester
|
Peter Sylvester
|
||||||
Peter Todd
|
Peter Todd
|
||||||
Peter Verhas
|
Peter Verhas
|
||||||
@@ -357,6 +370,7 @@ Phil Karn
|
|||||||
Philip Gladstone
|
Philip Gladstone
|
||||||
Philippe Hameau
|
Philippe Hameau
|
||||||
Philippe Raoult
|
Philippe Raoult
|
||||||
|
Philippe Vaucher
|
||||||
Pierre
|
Pierre
|
||||||
Puneet Pawaia
|
Puneet Pawaia
|
||||||
Quagmire
|
Quagmire
|
||||||
@@ -409,6 +423,7 @@ Sergio Ballestrero
|
|||||||
Seshubabu Pasam
|
Seshubabu Pasam
|
||||||
Shard
|
Shard
|
||||||
Shawn Poulson
|
Shawn Poulson
|
||||||
|
Shmulik Regev
|
||||||
Siddhartha Prakash Jain
|
Siddhartha Prakash Jain
|
||||||
Simon Dick
|
Simon Dick
|
||||||
Simon Josefsson
|
Simon Josefsson
|
||||||
@@ -433,6 +448,7 @@ S
|
|||||||
T. Bharath
|
T. Bharath
|
||||||
T. Yamada
|
T. Yamada
|
||||||
Temprimus
|
Temprimus
|
||||||
|
Thomas Klausner
|
||||||
Thomas Schwinge
|
Thomas Schwinge
|
||||||
Thomas Tonino
|
Thomas Tonino
|
||||||
Tim Baker
|
Tim Baker
|
||||||
@@ -441,6 +457,7 @@ Tim Costello
|
|||||||
Tim Sneddon
|
Tim Sneddon
|
||||||
Toby Peterson
|
Toby Peterson
|
||||||
Todd Kulesza
|
Todd Kulesza
|
||||||
|
Todd Vierling
|
||||||
Tom Benoist
|
Tom Benoist
|
||||||
Tom Lee
|
Tom Lee
|
||||||
Tom Mattison
|
Tom Mattison
|
||||||
@@ -458,6 +475,7 @@ Traian Nicolescu
|
|||||||
Troels Walsted Hansen
|
Troels Walsted Hansen
|
||||||
Troy Engel
|
Troy Engel
|
||||||
Tupone Alfredo
|
Tupone Alfredo
|
||||||
|
Ulf H<>rnhammar
|
||||||
Ulrich Zadow
|
Ulrich Zadow
|
||||||
Vilmos Nebehaj
|
Vilmos Nebehaj
|
||||||
Vincent Bronner
|
Vincent Bronner
|
||||||
|
25
docs/TODO
25
docs/TODO
@@ -14,12 +14,6 @@ TODO
|
|||||||
|
|
||||||
LIBCURL
|
LIBCURL
|
||||||
|
|
||||||
* Introduce an interface to libcurl that allows applications to easier get to
|
|
||||||
know what cookies that are received. CURLINFO_COOKIELIST to get a
|
|
||||||
curl_slist with cookies (netscape/mozilla cookie file formatted), and
|
|
||||||
CURLOPT_COOKIELIST to set a list of cookies (using the same format).
|
|
||||||
http://curl.haxx.se/mail/lib-2004-12/0195.html
|
|
||||||
|
|
||||||
* Introduce another callback interface for upload/download that makes one
|
* Introduce another callback interface for upload/download that makes one
|
||||||
less copy of data and thus a faster operation.
|
less copy of data and thus a faster operation.
|
||||||
[http://curl.haxx.se/dev/no_copy_callbacks.txt]
|
[http://curl.haxx.se/dev/no_copy_callbacks.txt]
|
||||||
@@ -64,13 +58,8 @@ TODO
|
|||||||
|
|
||||||
LIBCURL - multi interface
|
LIBCURL - multi interface
|
||||||
|
|
||||||
* Add a curl_multi_fdset() alternative. this allows apps to avoid the
|
|
||||||
FD_SETSIZE problem with select().
|
|
||||||
|
|
||||||
* Add curl_multi_timeout() to make libcurl's ares-functionality better.
|
|
||||||
|
|
||||||
* Make sure we don't ever loop because of non-blocking sockets return
|
* Make sure we don't ever loop because of non-blocking sockets return
|
||||||
EWOULDBLOCK or similar. This FTP command sending, the SSL connection etc.
|
EWOULDBLOCK or similar. The GnuTLS connection etc.
|
||||||
|
|
||||||
* Make transfers treated more carefully. We need a way to tell libcurl we
|
* Make transfers treated more carefully. We need a way to tell libcurl we
|
||||||
have data to write, as the current system expects us to upload data each
|
have data to write, as the current system expects us to upload data each
|
||||||
@@ -80,10 +69,6 @@ TODO
|
|||||||
ready to accept read data. Today libcurl feeds the data as soon as it is
|
ready to accept read data. Today libcurl feeds the data as soon as it is
|
||||||
available for reading, no matter what.
|
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
|
* 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
|
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
|
transfer is done, then detach the easy handle, destroy the multi handle and
|
||||||
@@ -201,6 +186,11 @@ TODO
|
|||||||
* Work out a common method with Peter Sylvester's OpenSSL-patch for SRP
|
* Work out a common method with Peter Sylvester's OpenSSL-patch for SRP
|
||||||
on the TLS to provide name and password
|
on the TLS to provide name and password
|
||||||
|
|
||||||
|
* Fix the connection phase to be non-blocking when multi interface is used
|
||||||
|
|
||||||
|
* Add a way to check if the connection seems to be alive, to corrspond to the
|
||||||
|
SSL_peak() way we use with OpenSSL.
|
||||||
|
|
||||||
LDAP
|
LDAP
|
||||||
|
|
||||||
* Look over the implementation. The looping will have to "go away" from the
|
* Look over the implementation. The looping will have to "go away" from the
|
||||||
@@ -212,7 +202,8 @@ TODO
|
|||||||
* RTSP - RFC2326 (protocol - very HTTP-like, also contains URL description)
|
* RTSP - RFC2326 (protocol - very HTTP-like, also contains URL description)
|
||||||
|
|
||||||
* SFTP/SCP/SSH (no RFCs for protocol nor URI/URL format). An implementation
|
* SFTP/SCP/SSH (no RFCs for protocol nor URI/URL format). An implementation
|
||||||
should most probably use an existing ssh library, such as OpenSSH.
|
should most probably use an existing ssh library, such as OpenSSH. or
|
||||||
|
libssh2.org
|
||||||
|
|
||||||
* RSYNC (no RFCs for protocol nor URI/URL format). An implementation should
|
* RSYNC (no RFCs for protocol nor URI/URL format). An implementation should
|
||||||
most probably use an existing rsync library, such as librsync.
|
most probably use an existing rsync library, such as librsync.
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
.\" *
|
.\" *
|
||||||
.\" * This software is licensed as described in the file COPYING, which
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * you should have received as part of this distribution. The terms
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
.\" * $Id$
|
.\" * $Id$
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl-config 1 "25 Jan 2004" "Curl 7.13.0" "curl-config manual"
|
.TH curl-config 1 "25 Jan 2004" "Curl 7.15.4" "curl-config manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl-config \- Get information about a libcurl installation
|
curl-config \- Get information about a libcurl installation
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -37,6 +37,11 @@ Displays the compiler used to build libcurl.
|
|||||||
.IP "--cflags"
|
.IP "--cflags"
|
||||||
Set of compiler options (CFLAGS) to use when compiling files that use
|
Set of compiler options (CFLAGS) to use when compiling files that use
|
||||||
libcurl. Currently that is only thw include path to the curl include files.
|
libcurl. Currently that is only thw include path to the curl include files.
|
||||||
|
.IP "--checkfor [version]"
|
||||||
|
Specify the oldest possible libcurl version string you want, and this
|
||||||
|
script will return 0 if the current installation is new enough or it
|
||||||
|
returns 1 and outputs a text saying that the current version is not new
|
||||||
|
enough. (Added in 7.15.4)
|
||||||
.IP "--feature"
|
.IP "--feature"
|
||||||
Lists what particular main features the installed libcurl was built with. At
|
Lists what particular main features the installed libcurl was built with. At
|
||||||
the time of writing, this list may include SSL, KRB4 or IPv6. Do not assume
|
the time of writing, this list may include SSL, KRB4 or IPv6. Do not assume
|
||||||
|
74
docs/curl.1
74
docs/curl.1
@@ -21,7 +21,7 @@
|
|||||||
.\" * $Id$
|
.\" * $Id$
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl 1 "21 Feb 2006" "Curl 7.15.2" "Curl Manual"
|
.TH curl 1 "21 Mar 2006" "Curl 7.15.4" "Curl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl \- transfer a URL
|
curl \- transfer a URL
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -43,7 +43,7 @@ curl is powered by libcurl for all transfer-related features. See
|
|||||||
for details.
|
for details.
|
||||||
.SH URL
|
.SH URL
|
||||||
The URL syntax is protocol dependent. You'll find a detailed description in
|
The URL syntax is protocol dependent. You'll find a detailed description in
|
||||||
RFC 2396.
|
RFC 3986.
|
||||||
|
|
||||||
You can specify multiple URLs or parts of URLs by writing part sets within
|
You can specify multiple URLs or parts of URLs by writing part sets within
|
||||||
braces as in:
|
braces as in:
|
||||||
@@ -80,6 +80,24 @@ getting many files from the same server will not do multiple connects /
|
|||||||
handshakes. This improves speed. Of course this is only done on files
|
handshakes. This improves speed. Of course this is only done on files
|
||||||
specified on a single command line and cannot be used between separate curl
|
specified on a single command line and cannot be used between separate curl
|
||||||
invokes.
|
invokes.
|
||||||
|
.SH "PROGRESS METER"
|
||||||
|
curl normally displays a progress meter during operations, indicating amount
|
||||||
|
of transfered data, transfer speeds and estimated time left etc.
|
||||||
|
|
||||||
|
However, since curl displays data to the terminal by default, if you invoke
|
||||||
|
curl to do an operation and it is about to write data to the terminal, it
|
||||||
|
\fIdisables\fP the progress meter as otherwise it would mess up the output
|
||||||
|
mixing progress meter and response data.
|
||||||
|
|
||||||
|
If you want a progress meter for HTTP POST or PUT requests, you need to
|
||||||
|
redirect the response output to a file, using shell redirect (>), -o [file] or
|
||||||
|
similar.
|
||||||
|
|
||||||
|
It is not the same case for FTP upload as that operation is not spitting out
|
||||||
|
any response data to the terminal.
|
||||||
|
|
||||||
|
If you prefer a progress "bar" instead of the regular meter, \fI-#\fP is your
|
||||||
|
friend.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.IP "-a/--append"
|
.IP "-a/--append"
|
||||||
(FTP) When used in an FTP upload, this will tell curl to append to the target
|
(FTP) When used in an FTP upload, this will tell curl to append to the target
|
||||||
@@ -337,9 +355,9 @@ If this option is used several times, the last one will be used.
|
|||||||
.IP "-f/--fail"
|
.IP "-f/--fail"
|
||||||
(HTTP) Fail silently (no output at all) on server errors. This is mostly done
|
(HTTP) Fail silently (no output at all) on server errors. This is mostly done
|
||||||
like this to better enable scripts etc to better deal with failed attempts. In
|
like this to better enable scripts etc to better deal with failed attempts. In
|
||||||
normal cases when a HTTP server fails to deliver a document, it returns a HTML
|
normal cases when a HTTP server fails to deliver a document, it returns an
|
||||||
document stating so (which often also describes why and more). This flag will
|
HTML document stating so (which often also describes why and more). This flag
|
||||||
prevent curl from outputting that and fail silently instead.
|
will prevent curl from outputting that and return error 22.
|
||||||
|
|
||||||
If this option is used twice, the second will again disable silent failure.
|
If this option is used twice, the second will again disable silent failure.
|
||||||
.IP "--ftp-account [data]"
|
.IP "--ftp-account [data]"
|
||||||
@@ -354,6 +372,22 @@ the server, the standard behavior of curl is to fail. Using this option, curl
|
|||||||
will instead attempt to create missing directories.
|
will instead attempt to create missing directories.
|
||||||
|
|
||||||
If this option is used twice, the second will again disable directory creation.
|
If this option is used twice, the second will again disable directory creation.
|
||||||
|
.IP "--ftp-method [method]"
|
||||||
|
(FTP) Control what method curl should use to reach a file on a FTP(S)
|
||||||
|
server. The method argument should be one of the following alternatives:
|
||||||
|
.RS
|
||||||
|
.IP multicwd
|
||||||
|
curl does a single CWD operation for each path part in the given URL. For deep
|
||||||
|
hierarchies this means very many commands. This is how RFC1738 says it should
|
||||||
|
be done. This is the default but the slowest behavior.
|
||||||
|
.IP nocwd
|
||||||
|
curl does no CWD at all. curl will do SIZE, RETR, STOR etc and give a full
|
||||||
|
path to the server for all these commands. This is the fastest behavior.
|
||||||
|
.IP singlecwd
|
||||||
|
curl does one CWD with the full target directory and then operates on the file
|
||||||
|
\&"normally" (like in the multicwd case). This is somewhat more standards
|
||||||
|
compliant than 'nocwd' but without the full penalty of 'multicwd'.
|
||||||
|
.RE
|
||||||
.IP "--ftp-pasv"
|
.IP "--ftp-pasv"
|
||||||
(FTP) Use PASV when transferring. PASV is the internal default behavior, but
|
(FTP) Use PASV when transferring. PASV is the internal default behavior, but
|
||||||
using this option can be used to override a previous --ftp-port option. (Added
|
using this option can be used to override a previous --ftp-port option. (Added
|
||||||
@@ -1097,6 +1131,10 @@ Number of new connects made in the recent transfer. (Added in 7.12.3)
|
|||||||
.TP
|
.TP
|
||||||
.B num_redirects
|
.B num_redirects
|
||||||
Number of redirects that were followed in the request. (Added in 7.12.3)
|
Number of redirects that were followed in the request. (Added in 7.12.3)
|
||||||
|
.TP
|
||||||
|
.B ftp_entry_path
|
||||||
|
The initial path libcurl ended up in when logging on to the remote FTP
|
||||||
|
server. (Added in 7.15.4)
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
@@ -1355,6 +1393,32 @@ Unrecognized transfer encoding
|
|||||||
Invalid LDAP URL
|
Invalid LDAP URL
|
||||||
.IP 63
|
.IP 63
|
||||||
Maximum file size exceeded
|
Maximum file size exceeded
|
||||||
|
.IP 64
|
||||||
|
Requested FTP SSL level failed
|
||||||
|
.IP 65
|
||||||
|
Sending the data requires a rewind that failed
|
||||||
|
.IP 66
|
||||||
|
Failed to initialise SSL Engine
|
||||||
|
.IP 67
|
||||||
|
User, password or similar was not accepted and curl failed to login
|
||||||
|
.IP 68
|
||||||
|
File not found on TFTP server
|
||||||
|
.IP 69
|
||||||
|
Permission problem on TFTP server
|
||||||
|
.IP 70
|
||||||
|
Out of disk space on TFTP server
|
||||||
|
.IP 71
|
||||||
|
Illegal TFTP operation
|
||||||
|
.IP 72
|
||||||
|
Unknown TFTP transfer ID
|
||||||
|
.IP 73
|
||||||
|
File already exists (TFTP)
|
||||||
|
.IP 74
|
||||||
|
No such user (TFTP)
|
||||||
|
.IP 75
|
||||||
|
Character conversion failed
|
||||||
|
.IP 76
|
||||||
|
Character conversion functions required
|
||||||
.IP XX
|
.IP XX
|
||||||
There will appear more error codes here in future releases. The existing ones
|
There will appear more error codes here in future releases. The existing ones
|
||||||
are meant to never change.
|
are meant to never change.
|
||||||
|
@@ -11,7 +11,7 @@ EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \
|
|||||||
multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \
|
multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \
|
||||||
multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c debug.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 synctime.c
|
cookie_interface.c cacertinmem.c synctime.c sampleconv.c ftpuploadresume.c
|
||||||
|
|
||||||
all:
|
all:
|
||||||
@echo "done"
|
@echo "done"
|
||||||
|
154
docs/examples/ftpuploadresume.c
Normal file
154
docs/examples/ftpuploadresume.c
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Upload to FTP, resuming failed transfers
|
||||||
|
*
|
||||||
|
* Compile for MinGW like this:
|
||||||
|
* gcc -Wall -pedantic -std=c99 ftpuploadwithresume.c -o ftpuploadresume.exe
|
||||||
|
* -lcurl -lmsvcr70
|
||||||
|
*
|
||||||
|
* Written by Philip Bock
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* The MinGW headers are missing a few Win32 function definitions,
|
||||||
|
you shouldn't need this if you use VC++ */
|
||||||
|
int __cdecl _snscanf(const char * input, size_t length, const char * format, ...);
|
||||||
|
|
||||||
|
|
||||||
|
/* parse headers for Content-Length */
|
||||||
|
size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb, void *stream) {
|
||||||
|
int r;
|
||||||
|
long len = 0;
|
||||||
|
|
||||||
|
/* _snscanf() is Win32 specific */
|
||||||
|
r = _snscanf(ptr, size * nmemb, "Content-Length: %ld\n", &len);
|
||||||
|
|
||||||
|
if (r) /* Microsoft: we don't read the specs */
|
||||||
|
*((long *) stream) = len;
|
||||||
|
|
||||||
|
return size * nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* discard downloaded data */
|
||||||
|
size_t discardfunc(void *ptr, size_t size, size_t nmemb, void *stream) {
|
||||||
|
return size * nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read data to upload */
|
||||||
|
size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||||
|
{
|
||||||
|
FILE *f = stream;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if (ferror(f))
|
||||||
|
return CURL_READFUNC_ABORT;
|
||||||
|
|
||||||
|
n = fread(ptr, size, nmemb, f) * size;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
|
||||||
|
long timeout, long tries)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
long uploaded_len = 0;
|
||||||
|
CURLcode r = CURLE_GOT_NOTHING;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
f = fopen(localpath, "rb");
|
||||||
|
if (f == NULL) {
|
||||||
|
perror(NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_UPLOAD, TRUE);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);
|
||||||
|
|
||||||
|
if (timeout)
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_FTP_RESPONSE_TIMEOUT, timeout);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &uploaded_len);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, discardfunc);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc);
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_READDATA, f);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_FTPPORT, "-"); /* disable passive mode */
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, TRUE);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, TRUE);
|
||||||
|
|
||||||
|
for (c = 0; (r != CURLE_OK) && (c < tries); c++) {
|
||||||
|
/* are we resuming? */
|
||||||
|
if (c) { /* yes */
|
||||||
|
/* determine the length of the file already written */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* With NOBODY and NOHEADER, libcurl will issue a SIZE
|
||||||
|
* command, but the only way to retrieve the result is
|
||||||
|
* to parse the returned Content-Length header. Thus,
|
||||||
|
* getcontentlengthfunc(). We need discardfunc() above
|
||||||
|
* because HEADER will dump the headers to stdout
|
||||||
|
* without it.
|
||||||
|
*/
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, TRUE);
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_HEADER, TRUE);
|
||||||
|
|
||||||
|
r = curl_easy_perform(curlhandle);
|
||||||
|
if (r != CURLE_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, FALSE);
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_HEADER, FALSE);
|
||||||
|
|
||||||
|
fseek(f, uploaded_len, SEEK_SET);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_FTPAPPEND, TRUE);
|
||||||
|
}
|
||||||
|
else { /* no */
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_FTPAPPEND, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = curl_easy_perform(curlhandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
if (r == CURLE_OK)
|
||||||
|
return 1;
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "%s\n", curl_easy_strerror(r));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int c, char **argv) {
|
||||||
|
CURL *curlhandle = NULL;
|
||||||
|
|
||||||
|
curl_global_init(CURL_GLOBAL_ALL);
|
||||||
|
curlhandle = curl_easy_init();
|
||||||
|
|
||||||
|
upload(curlhandle, "ftp://user:pass@host/path/file", "C:\\file", 0, 3);
|
||||||
|
|
||||||
|
curl_easy_cleanup(curlhandle);
|
||||||
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -24,12 +24,13 @@ int main(int argc, char *argv[])
|
|||||||
CURLM *multi_handle;
|
CURLM *multi_handle;
|
||||||
int still_running;
|
int still_running;
|
||||||
|
|
||||||
struct HttpPost *formpost=NULL;
|
struct curl_httppost *formpost=NULL;
|
||||||
struct HttpPost *lastptr=NULL;
|
struct curl_httppost *lastptr=NULL;
|
||||||
struct curl_slist *headerlist=NULL;
|
struct curl_slist *headerlist=NULL;
|
||||||
char buf[] = "Expect:";
|
char buf[] = "Expect:";
|
||||||
|
|
||||||
/* Fill in the file upload field */
|
/* Fill in the file upload field. This makes libcurl load data from
|
||||||
|
the given file name when curl_easy_perform() is called. */
|
||||||
curl_formadd(&formpost,
|
curl_formadd(&formpost,
|
||||||
&lastptr,
|
&lastptr,
|
||||||
CURLFORM_COPYNAME, "sendfile",
|
CURLFORM_COPYNAME, "sendfile",
|
||||||
@@ -43,7 +44,6 @@ int main(int argc, char *argv[])
|
|||||||
CURLFORM_COPYCONTENTS, "postit2.c",
|
CURLFORM_COPYCONTENTS, "postit2.c",
|
||||||
CURLFORM_END);
|
CURLFORM_END);
|
||||||
|
|
||||||
|
|
||||||
/* Fill in the submit field too, even if this is rarely needed */
|
/* Fill in the submit field too, even if this is rarely needed */
|
||||||
curl_formadd(&formpost,
|
curl_formadd(&formpost,
|
||||||
&lastptr,
|
&lastptr,
|
||||||
|
95
docs/examples/sampleconv.c
Normal file
95
docs/examples/sampleconv.c
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
This is a simple example showing how a program on a non-ASCII platform
|
||||||
|
would invoke callbacks to do its own codeset conversions instead of
|
||||||
|
using the built-in iconv functions in libcurl.
|
||||||
|
|
||||||
|
The IBM-1047 EBCDIC codeset is used for this example but the code
|
||||||
|
would be similar for other non-ASCII codesets.
|
||||||
|
|
||||||
|
Three callback functions are created below:
|
||||||
|
my_conv_from_ascii_to_ebcdic,
|
||||||
|
my_conv_from_ebcdic_to_ascii, and
|
||||||
|
my_conv_from_utf8_to_ebcdic
|
||||||
|
|
||||||
|
The "platform_xxx" calls represent platform-specific conversion routines.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
CURLcode my_conv_from_ascii_to_ebcdic(char *buffer, size_t length)
|
||||||
|
{
|
||||||
|
char *tempptrin, *tempptrout;
|
||||||
|
size_t bytes = length;
|
||||||
|
int rc;
|
||||||
|
tempptrin = tempptrout = buffer;
|
||||||
|
rc = platform_a2e(&tempptrin, &bytes, &tempptrout, &bytes);
|
||||||
|
if (rc == PLATFORM_CONV_OK) {
|
||||||
|
return(CURLE_OK);
|
||||||
|
} else {
|
||||||
|
return(CURLE_CONV_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode my_conv_from_ebcdic_to_ascii(char *buffer, size_t length)
|
||||||
|
{
|
||||||
|
char *tempptrin, *tempptrout;
|
||||||
|
size_t bytes = length;
|
||||||
|
int rc;
|
||||||
|
tempptrin = tempptrout = buffer;
|
||||||
|
rc = platform_e2a(&tempptrin, &bytes, &tempptrout, &bytes);
|
||||||
|
if (rc == PLATFORM_CONV_OK) {
|
||||||
|
return(CURLE_OK);
|
||||||
|
} else {
|
||||||
|
return(CURLE_CONV_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode my_conv_from_utf8_to_ebcdic(char *buffer, size_t length)
|
||||||
|
{
|
||||||
|
char *tempptrin, *tempptrout;
|
||||||
|
size_t bytes = length;
|
||||||
|
int rc;
|
||||||
|
tempptrin = tempptrout = buffer;
|
||||||
|
rc = platform_u2e(&tempptrin, &bytes, &tempptrout, &bytes);
|
||||||
|
if (rc == PLATFORM_CONV_OK) {
|
||||||
|
return(CURLE_OK);
|
||||||
|
} else {
|
||||||
|
return(CURLE_CONV_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
CURL *curl;
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
|
curl = curl_easy_init();
|
||||||
|
if(curl) {
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se");
|
||||||
|
|
||||||
|
/* use platform-specific functions for codeset conversions */
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONV_FROM_NETWORK_FUNCTION,
|
||||||
|
my_conv_from_ascii_to_ebcdic);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONV_TO_NETWORK_FUNCTION,
|
||||||
|
my_conv_from_ebcdic_to_ascii);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONV_FROM_UTF8_FUNCTION,
|
||||||
|
my_conv_from_utf8_to_ebcdic);
|
||||||
|
|
||||||
|
res = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
/* always cleanup */
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -4,51 +4,54 @@
|
|||||||
|
|
||||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||||
|
|
||||||
man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \
|
man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \
|
||||||
curl_easy_perform.3 curl_easy_setopt.3 curl_easy_duphandle.3 \
|
curl_easy_perform.3 curl_easy_setopt.3 curl_easy_duphandle.3 \
|
||||||
curl_formadd.3 curl_formfree.3 curl_getdate.3 curl_getenv.3 \
|
curl_formadd.3 curl_formfree.3 curl_getdate.3 curl_getenv.3 \
|
||||||
curl_slist_append.3 curl_slist_free_all.3 curl_version.3 \
|
curl_slist_append.3 curl_slist_free_all.3 curl_version.3 \
|
||||||
curl_version_info.3 curl_escape.3 curl_unescape.3 curl_free.3 \
|
curl_version_info.3 curl_escape.3 curl_unescape.3 curl_free.3 \
|
||||||
curl_strequal.3 curl_mprintf.3 curl_global_init.3 \
|
curl_strequal.3 curl_mprintf.3 curl_global_init.3 curl_global_cleanup.3 \
|
||||||
curl_global_cleanup.3 curl_multi_add_handle.3 curl_multi_cleanup.3 \
|
curl_multi_add_handle.3 curl_multi_cleanup.3 curl_multi_fdset.3 \
|
||||||
curl_multi_fdset.3 curl_multi_info_read.3 curl_multi_init.3 \
|
curl_multi_info_read.3 curl_multi_init.3 curl_multi_perform.3 \
|
||||||
curl_multi_perform.3 curl_multi_remove_handle.3 curl_share_cleanup.3 \
|
curl_multi_remove_handle.3 curl_share_cleanup.3 curl_share_init.3 \
|
||||||
curl_share_init.3 curl_share_setopt.3 libcurl.3 libcurl-easy.3 \
|
curl_share_setopt.3 libcurl.3 libcurl-easy.3 libcurl-multi.3 \
|
||||||
libcurl-multi.3 libcurl-share.3 libcurl-errors.3 curl_easy_strerror.3 \
|
libcurl-share.3 libcurl-errors.3 curl_easy_strerror.3 \
|
||||||
curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3 \
|
curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3 \
|
||||||
libcurl-tutorial.3 curl_easy_reset.3
|
libcurl-tutorial.3 curl_easy_reset.3 curl_easy_escape.3 \
|
||||||
|
curl_easy_unescape.3 curl_multi_setopt.3 curl_multi_socket.3 \
|
||||||
|
curl_multi_timeout.3
|
||||||
|
|
||||||
HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
||||||
curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \
|
curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \
|
||||||
curl_easy_duphandle.html curl_formadd.html curl_formfree.html \
|
curl_easy_duphandle.html curl_formadd.html curl_formfree.html \
|
||||||
curl_getdate.html curl_getenv.html curl_slist_append.html \
|
curl_getdate.html curl_getenv.html curl_slist_append.html \
|
||||||
curl_slist_free_all.html curl_version.html curl_version_info.html \
|
curl_slist_free_all.html curl_version.html curl_version_info.html \
|
||||||
curl_escape.html curl_unescape.html curl_free.html curl_strequal.html \
|
curl_escape.html curl_unescape.html curl_free.html curl_strequal.html \
|
||||||
curl_mprintf.html curl_global_init.html curl_global_cleanup.html \
|
curl_mprintf.html curl_global_init.html curl_global_cleanup.html \
|
||||||
curl_multi_add_handle.html curl_multi_cleanup.html \
|
curl_multi_add_handle.html curl_multi_cleanup.html curl_multi_fdset.html \
|
||||||
curl_multi_fdset.html curl_multi_info_read.html curl_multi_init.html \
|
curl_multi_info_read.html curl_multi_init.html curl_multi_perform.html \
|
||||||
curl_multi_perform.html curl_multi_remove_handle.html \
|
curl_multi_remove_handle.html curl_share_cleanup.html \
|
||||||
curl_share_cleanup.html curl_share_init.html curl_share_setopt.html \
|
curl_share_init.html curl_share_setopt.html libcurl.html \
|
||||||
libcurl.html libcurl-multi.html libcurl-easy.html libcurl-share.html \
|
libcurl-multi.html libcurl-easy.html libcurl-share.html \
|
||||||
libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html \
|
libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html \
|
||||||
curl_share_strerror.html curl_global_init_mem.html \
|
curl_share_strerror.html curl_global_init_mem.html libcurl-tutorial.html \
|
||||||
libcurl-tutorial.html curl_easy_reset.html
|
curl_easy_reset.html curl_easy_escape.html curl_easy_unescape.html \
|
||||||
|
curl_multi_setopt.html curl_multi_socket.html curl_multi_timeout.html
|
||||||
|
|
||||||
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
|
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf curl_easy_init.pdf \
|
||||||
curl_easy_init.pdf curl_easy_perform.pdf curl_easy_setopt.pdf \
|
curl_easy_perform.pdf curl_easy_setopt.pdf curl_easy_duphandle.pdf \
|
||||||
curl_easy_duphandle.pdf curl_formadd.pdf curl_formfree.pdf \
|
curl_formadd.pdf curl_formfree.pdf curl_getdate.pdf curl_getenv.pdf \
|
||||||
curl_getdate.pdf curl_getenv.pdf curl_slist_append.pdf \
|
curl_slist_append.pdf curl_slist_free_all.pdf curl_version.pdf \
|
||||||
curl_slist_free_all.pdf curl_version.pdf curl_version_info.pdf \
|
curl_version_info.pdf curl_escape.pdf curl_unescape.pdf curl_free.pdf \
|
||||||
curl_escape.pdf curl_unescape.pdf curl_free.pdf curl_strequal.pdf \
|
curl_strequal.pdf curl_mprintf.pdf curl_global_init.pdf \
|
||||||
curl_mprintf.pdf curl_global_init.pdf curl_global_cleanup.pdf \
|
curl_global_cleanup.pdf curl_multi_add_handle.pdf curl_multi_cleanup.pdf \
|
||||||
curl_multi_add_handle.pdf curl_multi_cleanup.pdf curl_multi_fdset.pdf \
|
curl_multi_fdset.pdf curl_multi_info_read.pdf curl_multi_init.pdf \
|
||||||
curl_multi_info_read.pdf curl_multi_init.pdf curl_multi_perform.pdf \
|
curl_multi_perform.pdf curl_multi_remove_handle.pdf \
|
||||||
curl_multi_remove_handle.pdf curl_share_cleanup.pdf \
|
curl_share_cleanup.pdf curl_share_init.pdf curl_share_setopt.pdf \
|
||||||
curl_share_init.pdf curl_share_setopt.pdf libcurl.pdf \
|
libcurl.pdf libcurl-multi.pdf libcurl-easy.pdf libcurl-share.pdf \
|
||||||
libcurl-multi.pdf libcurl-easy.pdf libcurl-share.pdf \
|
libcurl-errors.pdf curl_easy_strerror.pdf curl_multi_strerror.pdf \
|
||||||
libcurl-errors.pdf curl_easy_strerror.pdf curl_multi_strerror.pdf \
|
curl_share_strerror.pdf curl_global_init_mem.pdf libcurl-tutorial.pdf \
|
||||||
curl_share_strerror.pdf curl_global_init_mem.pdf libcurl-tutorial.pdf \
|
curl_easy_reset.pdf curl_easy_escape.pdf curl_easy_unescape.pdf \
|
||||||
curl_easy_reset.pdf
|
curl_multi_setopt.pdf curl_multi_socket.pdf curl_multi_timeout.pdf
|
||||||
|
|
||||||
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
||||||
|
|
||||||
|
47
docs/libcurl/curl_easy_escape.3
Normal file
47
docs/libcurl/curl_easy_escape.3
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
.\" **************************************************************************
|
||||||
|
.\" * _ _ ____ _
|
||||||
|
.\" * Project ___| | | | _ \| |
|
||||||
|
.\" * / __| | | | |_) | |
|
||||||
|
.\" * | (__| |_| | _ <| |___
|
||||||
|
.\" * \___|\___/|_| \_\_____|
|
||||||
|
.\" *
|
||||||
|
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
|
.\" * you should have received as part of this distribution. The terms
|
||||||
|
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
.\" *
|
||||||
|
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
.\" * copies of the Software, and permit persons to whom the Software is
|
||||||
|
.\" * furnished to do so, under the terms of the COPYING file.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
.\" * KIND, either express or implied.
|
||||||
|
.\" *
|
||||||
|
.\" * $Id$
|
||||||
|
.\" **************************************************************************
|
||||||
|
.\"
|
||||||
|
.TH curl_easy_escape 3 "7 April 2006" "libcurl 7.15.4" "libcurl Manual"
|
||||||
|
.SH NAME
|
||||||
|
curl_easy_escape - URL encodes the given string
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B #include <curl/curl.h>
|
||||||
|
.sp
|
||||||
|
.BI "char *curl_easy_escape( CURL *" curl ", char *" url ", int "length " );"
|
||||||
|
.ad
|
||||||
|
.SH DESCRIPTION
|
||||||
|
This function converts the given input string to an URL encoded string and
|
||||||
|
returns that as a new allocated string. All input characters that are not a-z,
|
||||||
|
A-Z or 0-9 are converted to their "URL escaped" version (%NN where NN is a
|
||||||
|
two-digit hexadecimal number).
|
||||||
|
|
||||||
|
If the \fBlength\fP argument is set to 0 (zero), curl_easy_escape() uses
|
||||||
|
strlen() on the input \fBurl\fP to find out the size.
|
||||||
|
|
||||||
|
You must \fIcurl_free(3)\fP the returned string when you're done with it.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
Added in 7.15.4 and replaces the old curl_escape() function.
|
||||||
|
.SH RETURN VALUE
|
||||||
|
A pointer to a zero terminated string or NULL if it failed.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR curl_easy_unescape "(3), " curl_free "(3), " RFC 2396
|
@@ -1,8 +1,27 @@
|
|||||||
.\" You can view this file with:
|
.\" **************************************************************************
|
||||||
.\" nroff -man [file]
|
.\" * _ _ ____ _
|
||||||
.\" $Id$
|
.\" * Project ___| | | | _ \| |
|
||||||
|
.\" * / __| | | | |_) | |
|
||||||
|
.\" * | (__| |_| | _ <| |___
|
||||||
|
.\" * \___|\___/|_| \_\_____|
|
||||||
|
.\" *
|
||||||
|
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
|
.\" * you should have received as part of this distribution. The terms
|
||||||
|
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
.\" *
|
||||||
|
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
.\" * copies of the Software, and permit persons to whom the Software is
|
||||||
|
.\" * furnished to do so, under the terms of the COPYING file.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
.\" * KIND, either express or implied.
|
||||||
|
.\" *
|
||||||
|
.\" * $Id$
|
||||||
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl_easy_getinfo 3 "6 Oct 2005" "libcurl 7.12.3" "libcurl Manual"
|
.TH curl_easy_getinfo 3 "21 Mar 2006" "libcurl 7.15.4" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_easy_getinfo - extract information from a curl handle
|
curl_easy_getinfo - extract information from a curl handle
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -44,10 +63,8 @@ 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
|
to \fIcurl_easy_setopt(3)\fP or you will unconditionally get a -1 back. (Added
|
||||||
in 7.5)
|
in 7.5)
|
||||||
.IP CURLINFO_TOTAL_TIME
|
.IP CURLINFO_TOTAL_TIME
|
||||||
Pass a pointer to a double to receive the total transaction time in seconds
|
Pass a pointer to a double to receive the total time in seconds for the
|
||||||
for the previous transfer. This time does not include the connect time, so if
|
previous transfer, including name resolving, TCP connect etc.
|
||||||
you want the complete operation time, you should add the
|
|
||||||
CURLINFO_CONNECT_TIME.
|
|
||||||
.IP CURLINFO_NAMELOOKUP_TIME
|
.IP CURLINFO_NAMELOOKUP_TIME
|
||||||
Pass a pointer to a double to receive the time, in seconds, it took from the
|
Pass a pointer to a double to receive the time, in seconds, it took from the
|
||||||
start until the name resolving was completed.
|
start until the name resolving was completed.
|
||||||
@@ -148,17 +165,22 @@ working with the socket, you must call curl_easy_cleanup() as usual and let
|
|||||||
libcurl close the socket and cleanup other resources associated with the
|
libcurl close the socket and cleanup other resources associated with the
|
||||||
handle. This is typically used in combination with \fICURLOPT_CONNECT_ONLY\fP.
|
handle. This is typically used in combination with \fICURLOPT_CONNECT_ONLY\fP.
|
||||||
(Added in 7.15.2)
|
(Added in 7.15.2)
|
||||||
|
.IP CURLINFO_FTP_ENTRY_PATH
|
||||||
|
Pass a pointer to a 'char *' to receive a pointer to a string holding the path
|
||||||
|
of the entry path. That is the initial path libcurl ended up in when logging
|
||||||
|
on to the remote FTP server. This stores a NULL as pointer if something is
|
||||||
|
wrong. (Added in 7.15.4)
|
||||||
.SH TIMES
|
.SH TIMES
|
||||||
.NF
|
.NF
|
||||||
An overview of the six time values available from curl_easy_getinfo()
|
An overview of the six time values available from curl_easy_getinfo()
|
||||||
|
|
||||||
curk_easy_perform()
|
curl_easy_perform()
|
||||||
|
|
|
|
||||||
|--NT
|
|--NT
|
||||||
|--|--CT
|
|--|--CT
|
||||||
|--|--|--PT
|
|--|--|--PT
|
||||||
|--|--|--|--ST
|
|--|--|--|--ST
|
||||||
|--|--|--TT
|
|--|--|--|--|--TT
|
||||||
|--|--|--|--|--RT
|
|--|--|--|--|--RT
|
||||||
.FI
|
.FI
|
||||||
.IP NT
|
.IP NT
|
||||||
@@ -175,9 +197,7 @@ and negotiations that are specific to the particular protocol(s) involved.
|
|||||||
\fICURLINFO_STARTTRANSFER_TIME\fP. The time it took from the start until the
|
\fICURLINFO_STARTTRANSFER_TIME\fP. The time it took from the start until the
|
||||||
first byte is just about to be transferred.
|
first byte is just about to be transferred.
|
||||||
.IP TT
|
.IP TT
|
||||||
\fICURLINFO_TOTAL_TIME\fP. Time of the previous transfer. This time does not
|
\fICURLINFO_TOTAL_TIME\fP. Total time of the previous request.
|
||||||
include the connect time (CT), so if you want the complete operation time, you
|
|
||||||
should add that.
|
|
||||||
.IP RT
|
.IP RT
|
||||||
\fICURLINFO_REDIRECT_TIME\fP. The time it took for all redirection steps
|
\fICURLINFO_REDIRECT_TIME\fP. The time it took for all redirection steps
|
||||||
include name lookup, connect, pretransfer and transfer before final
|
include name lookup, connect, pretransfer and transfer before final
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
.\" * $Id$
|
.\" * $Id$
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl_easy_setopt 3 "21 Feb 2006" "libcurl 7.15.2" "libcurl Manual"
|
.TH curl_easy_setopt 3 "19 Apr 2006" "libcurl 7.15.4" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_easy_setopt \- set options for a curl easy handle
|
curl_easy_setopt \- set options for a curl easy handle
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -263,6 +263,51 @@ and trust file settings.
|
|||||||
Data pointer to pass to the ssl context callback set by the option
|
Data pointer to pass to the ssl context callback set by the option
|
||||||
\fICURLOPT_SSL_CTX_FUNCTION\fP, this is the pointer you'll get as third
|
\fICURLOPT_SSL_CTX_FUNCTION\fP, this is the pointer you'll get as third
|
||||||
parameter, otherwise \fBNULL\fP. (Added in 7.11.0)
|
parameter, otherwise \fBNULL\fP. (Added in 7.11.0)
|
||||||
|
.IP CURLOPT_CONV_TO_NETWORK_FUNCTION
|
||||||
|
.IP CURLOPT_CONV_FROM_NETWORK_FUNCTION
|
||||||
|
.IP CURLOPT_CONV_FROM_UTF8_FUNCTION
|
||||||
|
Function pointers that should match the following prototype: CURLcode
|
||||||
|
function(char *ptr, size_t length);
|
||||||
|
|
||||||
|
These three options apply to non-ASCII platforms only. They are available
|
||||||
|
only if \fBCURL_DOES_CONVERSIONS\fP was defined when libcurl was built. When
|
||||||
|
this is the case, \fIcurl_version_info(3)\fP will return the CURL_VERSION_CONV
|
||||||
|
feature bit set.
|
||||||
|
|
||||||
|
The data to be converted is in a buffer pointed to by the ptr parameter. The
|
||||||
|
amount of data to convert is indicated by the length parameter. The converted
|
||||||
|
data overlays the input data in the buffer pointed to by the ptr parameter.
|
||||||
|
CURLE_OK should be returned upon successful conversion. A CURLcode return
|
||||||
|
value defined by curl.h, such as CURLE_CONV_FAILED, should be returned if an
|
||||||
|
error was encountered.
|
||||||
|
|
||||||
|
\fBCURLOPT_CONV_TO_NETWORK_FUNCTION\fP and
|
||||||
|
\fBCURLOPT_CONV_FROM_NETWORK_FUNCTION\fP convert between the host encoding and
|
||||||
|
the network encoding. They are used when commands or ASCII data are
|
||||||
|
sent/received over the network.
|
||||||
|
|
||||||
|
\fBCURLOPT_CONV_FROM_UTF8_FUNCTION\fP is called to convert from UTF8 into the
|
||||||
|
host encoding. It is required only for SSL processing.
|
||||||
|
|
||||||
|
If you set a callback pointer to NULL, or don't set it at all, the built-in
|
||||||
|
libcurl iconv functions will be used. If HAVE_ICONV was not defined when
|
||||||
|
libcurl was built, and no callback has been established, conversion will
|
||||||
|
return the CURLE_CONV_REQD error code.
|
||||||
|
|
||||||
|
If HAVE_ICONV is defined, CURL_ICONV_CODESET_OF_HOST must also be defined.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
\&#define CURL_ICONV_CODESET_OF_HOST "IBM-1047"
|
||||||
|
|
||||||
|
The iconv code in libcurl will default the network and UTF8 codeset names as
|
||||||
|
follows:
|
||||||
|
|
||||||
|
\&#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
|
||||||
|
|
||||||
|
\&#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
|
||||||
|
|
||||||
|
You will need to override these definitions if they are different on your
|
||||||
|
system.
|
||||||
.SH ERROR OPTIONS
|
.SH ERROR OPTIONS
|
||||||
.IP CURLOPT_ERRORBUFFER
|
.IP CURLOPT_ERRORBUFFER
|
||||||
Pass a char * to a buffer that the libcurl may store human readable error
|
Pass a char * to a buffer that the libcurl may store human readable error
|
||||||
@@ -295,7 +340,10 @@ 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
|
\fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed info
|
||||||
on which protocols that are supported.
|
on which protocols that are supported.
|
||||||
|
|
||||||
\fICURLOPT_URL\fP is the only option that must be set before
|
The string given to CURLOPT_URL must be url-encoded and following the RFC 2396
|
||||||
|
(http://curl.haxx.se/rfc/rfc2396.txt).
|
||||||
|
|
||||||
|
\fICURLOPT_URL\fP is the only option that \fBmust\fP be set before
|
||||||
\fIcurl_easy_perform(3)\fP is called.
|
\fIcurl_easy_perform(3)\fP is called.
|
||||||
.IP CURLOPT_PROXY
|
.IP CURLOPT_PROXY
|
||||||
Set HTTP proxy to use. The parameter should be a char * to a zero terminated
|
Set HTTP proxy to use. The parameter should be a char * to a zero terminated
|
||||||
@@ -714,6 +762,8 @@ 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
|
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
|
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)
|
magic string \&"ALL" will erase all cookies known by cURL. (Added in 7.14.1)
|
||||||
|
Passing the special string \&"SESS" will only erase all session cookies known
|
||||||
|
by cURL. (Added in 7.15.4)
|
||||||
.IP CURLOPT_HTTPGET
|
.IP CURLOPT_HTTPGET
|
||||||
Pass a long. If the long is non-zero, this forces the HTTP request to get back
|
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
|
to GET. usable if a POST, HEAD, PUT or a custom request have been used
|
||||||
@@ -858,6 +908,23 @@ Exactly like \fICURLOPT_POSTQUOTE\fP, but for the source host.
|
|||||||
Pass a pointer to a zero-terminated string (or NULL to disable). When an FTP
|
Pass a pointer to a zero-terminated string (or NULL to disable). When an FTP
|
||||||
server asks for "account data" after user name and password has been provided,
|
server asks for "account data" after user name and password has been provided,
|
||||||
this data is sent off using the ACCT command. (Added in 7.13.0)
|
this data is sent off using the ACCT command. (Added in 7.13.0)
|
||||||
|
.IP CURLOPT_FTP_FILEMETHOD
|
||||||
|
Pass a long that should have one of the following values. This option controls
|
||||||
|
what method libcurl should use to reach a file on a FTP(S) server. The
|
||||||
|
argument should be one of the following alternatives:
|
||||||
|
.RS
|
||||||
|
.IP CURLFTPMETHOD_MULTICWD
|
||||||
|
libcurl does a single CWD operation for each path part in the given URL. For
|
||||||
|
deep hierarchies this means very many commands. This is how RFC1738 says it
|
||||||
|
should be done. This is the default but the slowest behavior.
|
||||||
|
.IP CURLFTPMETHOD_NOCWD
|
||||||
|
libcurl does no CWD at all. libcurl will do SIZE, RETR, STOR etc and give a
|
||||||
|
full path to the server for all these commands. This is the fastest behavior.
|
||||||
|
.IP CURLFTPMETHOD_SINGLECWD
|
||||||
|
libcurl does one CWD with the full target directory and then operates on the
|
||||||
|
file \&"normally" (like in the multicwd case). This is somewhat more standards
|
||||||
|
compliant than 'nocwd' but without the full penalty of 'multicwd'.
|
||||||
|
.RE
|
||||||
.SH PROTOCOL OPTIONS
|
.SH PROTOCOL OPTIONS
|
||||||
.IP CURLOPT_TRANSFERTEXT
|
.IP CURLOPT_TRANSFERTEXT
|
||||||
A non-zero parameter tells the library to use ASCII mode for ftp transfers,
|
A non-zero parameter tells the library to use ASCII mode for ftp transfers,
|
||||||
@@ -1142,6 +1209,9 @@ certificates to verify the peer with. This makes sense only when used in
|
|||||||
combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If
|
combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If
|
||||||
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAINFO\fP need not
|
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAINFO\fP need not
|
||||||
even indicate an accessible file.
|
even indicate an accessible file.
|
||||||
|
|
||||||
|
Note that option is by default set to the system path where libcurl's cacert
|
||||||
|
bundle is assumed to be stored, as established at build time.
|
||||||
.IP CURLOPT_CAPATH
|
.IP CURLOPT_CAPATH
|
||||||
Pass a char * to a zero terminated string naming a directory holding
|
Pass a char * to a zero terminated string naming a directory holding
|
||||||
multiple CA certificates to verify the peer with. The certificate
|
multiple CA certificates to verify the peer with. The certificate
|
||||||
|
52
docs/libcurl/curl_easy_unescape.3
Normal file
52
docs/libcurl/curl_easy_unescape.3
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
.\" **************************************************************************
|
||||||
|
.\" * _ _ ____ _
|
||||||
|
.\" * Project ___| | | | _ \| |
|
||||||
|
.\" * / __| | | | |_) | |
|
||||||
|
.\" * | (__| |_| | _ <| |___
|
||||||
|
.\" * \___|\___/|_| \_\_____|
|
||||||
|
.\" *
|
||||||
|
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
|
.\" * you should have received as part of this distribution. The terms
|
||||||
|
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
.\" *
|
||||||
|
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
.\" * copies of the Software, and permit persons to whom the Software is
|
||||||
|
.\" * furnished to do so, under the terms of the COPYING file.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
.\" * KIND, either express or implied.
|
||||||
|
.\" *
|
||||||
|
.\" * $Id$
|
||||||
|
.\" **************************************************************************
|
||||||
|
.\"
|
||||||
|
.TH curl_easy_unescape 3 "7 April 2006" "libcurl 7.15.4" "libcurl Manual"
|
||||||
|
.SH NAME
|
||||||
|
curl_easy_unescape - URL decodes the given string
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B #include <curl/curl.h>
|
||||||
|
.sp
|
||||||
|
.BI "char *curl_easy_unescape( CURL *" curl ", char *" url ", int "inlength
|
||||||
|
.BI ", int *" outlength " );"
|
||||||
|
.ad
|
||||||
|
.SH DESCRIPTION
|
||||||
|
This function converts the given URL encoded input string to a "plain string"
|
||||||
|
and returns that in an allocated memory area. All input characters that are
|
||||||
|
URL encoded (%XX where XX is a two-digit hexadecimal number) are converted to
|
||||||
|
their binary versions.
|
||||||
|
|
||||||
|
If the \fBlength\fP argument is set to 0 (zero), curl_easy_unescape() will use
|
||||||
|
strlen() on the input \fIurl\fP string to find out the size.
|
||||||
|
|
||||||
|
If \fBoutlength\fP is non-NULL, the function will write the length of the
|
||||||
|
returned string in the integer it points to. This allows an escaped string
|
||||||
|
containing %00 to still get used properly after unescaping.
|
||||||
|
|
||||||
|
You must \fIcurl_free(3)\fP the returned string when you're done with it.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
Added in 7.15.4 and replaces the old curl_unescape() function.
|
||||||
|
.SH RETURN VALUE
|
||||||
|
A pointer to a zero terminated string or NULL if it failed.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.I curl_easy_escape(3), curl_free(3), RFC 2396
|
@@ -11,6 +11,8 @@ curl_escape - URL encodes the given string
|
|||||||
.BI "char *curl_escape( char *" url ", int "length " );"
|
.BI "char *curl_escape( char *" url ", int "length " );"
|
||||||
.ad
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
Obsolete function. Use \fIcurl_easy_escape(3)\fP instead!
|
||||||
|
|
||||||
This function will convert the given input string to an URL encoded string and
|
This function will convert the given input string to an URL encoded string and
|
||||||
return that as a new allocated string. All input characters that are not a-z,
|
return that as a new allocated string. All input characters that are not a-z,
|
||||||
A-Z or 0-9 will be converted to their "URL escaped" version (%NN where NN is a
|
A-Z or 0-9 will be converted to their "URL escaped" version (%NN where NN is a
|
||||||
@@ -20,6 +22,9 @@ If the 'length' argument is set to 0, curl_escape() will use strlen() on the
|
|||||||
input 'url' string to find out the size.
|
input 'url' string to find out the size.
|
||||||
|
|
||||||
You must curl_free() the returned string when you're done with it.
|
You must curl_free() the returned string when you're done with it.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
Since 7.15.4, \fIcurl_easy_escape(3)\fP should be used. This function will
|
||||||
|
be removed in a future release.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to a zero terminated string or NULL if it failed.
|
A pointer to a zero terminated string or NULL if it failed.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
|
@@ -18,10 +18,9 @@ will instead be made "available" by source code access only, and then as
|
|||||||
curlx_getenv().
|
curlx_getenv().
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
If successful, curl_getenv() returns a pointer to the value of the specified
|
If successful, curl_getenv() returns a pointer to the value of the specified
|
||||||
environment. The memory it refers to is malloc()ed why the application must
|
environment. The memory it refers to is malloc()ed so the application must
|
||||||
free() this when the data has completed to serve its purpose. When
|
free() this when the data is no longer needed. When \fIcurl_getenv(3)\fP fails
|
||||||
.I curl_getenv(3)
|
to find the specified name, it returns a null pointer.
|
||||||
fails to find the specified name, it returns a null pointer.
|
|
||||||
.SH NOTE
|
.SH NOTE
|
||||||
Under unix operating systems, there isn't any point in returning an allocated
|
Under unix operating systems, there isn't any point in returning an allocated
|
||||||
memory, although other systems won't work properly if this isn't done. The
|
memory, although other systems won't work properly if this isn't done. The
|
||||||
|
@@ -11,6 +11,8 @@ curl_unescape - URL decodes the given string
|
|||||||
.BI "char *curl_unescape( char *" url ", int "length " );"
|
.BI "char *curl_unescape( char *" url ", int "length " );"
|
||||||
.ad
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
Obsolete function. Use \fIcurl_easy_unescape(3)\fP instead!
|
||||||
|
|
||||||
This function will convert the given URL encoded input string to a "plain
|
This function will convert the given URL encoded input string to a "plain
|
||||||
string" and return that as a new allocated string. All input characters that
|
string" and return that as a new allocated string. All input characters that
|
||||||
are URL encoded (%XX where XX is a two-digit hexadecimal number) will be
|
are URL encoded (%XX where XX is a two-digit hexadecimal number) will be
|
||||||
@@ -20,7 +22,10 @@ If the 'length' argument is set to 0, curl_unescape() will use strlen() on the
|
|||||||
input 'url' string to find out the size.
|
input 'url' string to find out the size.
|
||||||
|
|
||||||
You must curl_free() the returned string when you're done with it.
|
You must curl_free() the returned string when you're done with it.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
Since 7.15.4, \fIcurl_easy_unescape(3)\fP should be used. This function will
|
||||||
|
be removed in a future release.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to a zero terminated string or NULL if it failed.
|
A pointer to a zero terminated string or NULL if it failed.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.I curl_escape(3), curl_free(3), RFC 2396
|
.I curl_easy_escape(3), curl_easy_unescape(3), curl_free(3), RFC 2396
|
||||||
|
@@ -1,6 +1,27 @@
|
|||||||
.\" $Id$
|
.\" **************************************************************************
|
||||||
|
.\" * _ _ ____ _
|
||||||
|
.\" * Project ___| | | | _ \| |
|
||||||
|
.\" * / __| | | | |_) | |
|
||||||
|
.\" * | (__| |_| | _ <| |___
|
||||||
|
.\" * \___|\___/|_| \_\_____|
|
||||||
|
.\" *
|
||||||
|
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
|
.\" * you should have received as part of this distribution. The terms
|
||||||
|
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
.\" *
|
||||||
|
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
.\" * copies of the Software, and permit persons to whom the Software is
|
||||||
|
.\" * furnished to do so, under the terms of the COPYING file.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
.\" * KIND, either express or implied.
|
||||||
|
.\" *
|
||||||
|
.\" * $Id$
|
||||||
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl_version_info 3 "11 Mar 2005" "libcurl 7.13.2" "libcurl Manual"
|
.TH curl_version_info 3 "19 Apr 2006" "libcurl 7.15.4" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_version_info - returns run-time libcurl version info
|
curl_version_info - returns run-time libcurl version info
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -98,6 +119,9 @@ libcurl was built with support for SSPI. This is only available on Windows and
|
|||||||
makes libcurl use Windows-provided functions for NTLM authentication. It also
|
makes libcurl use Windows-provided functions for NTLM authentication. It also
|
||||||
allows libcurl to use the current user and the current user's password without
|
allows libcurl to use the current user and the current user's password without
|
||||||
the app having to pass them on. (Added in 7.13.2)
|
the app having to pass them on. (Added in 7.13.2)
|
||||||
|
.IP CURL_VERSION_CONV
|
||||||
|
libcurl was built with support for character conversions, as provided by the
|
||||||
|
CUURLOPT_CONV_* callbacks. (Added in 7.15.4)
|
||||||
.RE
|
.RE
|
||||||
\fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
|
\fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
|
||||||
has no SSL support, this is NULL.
|
has no SSL support, this is NULL.
|
||||||
|
@@ -30,7 +30,7 @@ or problem.
|
|||||||
.IP "CURLE_URL_MALFORMAT (3)"
|
.IP "CURLE_URL_MALFORMAT (3)"
|
||||||
The URL was not properly formatted.
|
The URL was not properly formatted.
|
||||||
.IP "CURLE_URL_MALFORMAT_USER (4)"
|
.IP "CURLE_URL_MALFORMAT_USER (4)"
|
||||||
URL user malformatted. The user-part of the URL syntax was not correct.
|
This is never returned by current libcurl.
|
||||||
.IP "CURLE_COULDNT_RESOLVE_PROXY (5)"
|
.IP "CURLE_COULDNT_RESOLVE_PROXY (5)"
|
||||||
Couldn't resolve proxy. The given proxy host could not be resolved.
|
Couldn't resolve proxy. The given proxy host could not be resolved.
|
||||||
.IP "CURLE_COULDNT_RESOLVE_HOST (6)"
|
.IP "CURLE_COULDNT_RESOLVE_HOST (6)"
|
||||||
@@ -45,9 +45,7 @@ remote server is probably not an OK FTP server.
|
|||||||
We were denied access when trying to login to an FTP server or when trying to
|
We were denied access when trying to login to an FTP server or when trying to
|
||||||
change working directory to the one given in the URL.
|
change working directory to the one given in the URL.
|
||||||
.IP "CURLE_FTP_USER_PASSWORD_INCORRECT (10)"
|
.IP "CURLE_FTP_USER_PASSWORD_INCORRECT (10)"
|
||||||
The FTP server rejected access to the server after the password was sent to
|
This is never returned by current libcurl.
|
||||||
it. It might be because the username and/or the password were incorrect or
|
|
||||||
just that the server is not allowing you access for the moment etc.
|
|
||||||
.IP "CURLE_FTP_WEIRD_PASS_REPLY (11)"
|
.IP "CURLE_FTP_WEIRD_PASS_REPLY (11)"
|
||||||
After having sent the FTP password to the server, libcurl expects a proper
|
After having sent the FTP password to the server, libcurl expects a proper
|
||||||
reply. This error code indicates that an unexpected code was returned.
|
reply. This error code indicates that an unexpected code was returned.
|
||||||
@@ -87,7 +85,7 @@ returns an error code that is >= 400.
|
|||||||
An error occurred when writing received data to a local file, or an error was
|
An error occurred when writing received data to a local file, or an error was
|
||||||
returned to libcurl from a write callback.
|
returned to libcurl from a write callback.
|
||||||
.IP "CURLE_MALFORMAT_USER (24)"
|
.IP "CURLE_MALFORMAT_USER (24)"
|
||||||
Malformat user. User name badly specified. *Not currently used*
|
This is never returned by current libcurl.
|
||||||
.IP "CURLE_FTP_COULDNT_STOR_FILE (25)"
|
.IP "CURLE_FTP_COULDNT_STOR_FILE (25)"
|
||||||
FTP couldn't STOR file. The server denied the STOR operation. The error buffer
|
FTP couldn't STOR file. The server denied the STOR operation. The error buffer
|
||||||
usually contains the server's explanation to this.
|
usually contains the server's explanation to this.
|
||||||
@@ -138,15 +136,13 @@ Aborted by callback. A callback returned "abort" to libcurl.
|
|||||||
.IP "CURLE_BAD_FUNCTION_ARGUMENT (43)"
|
.IP "CURLE_BAD_FUNCTION_ARGUMENT (43)"
|
||||||
Internal error. A function was called with a bad parameter.
|
Internal error. A function was called with a bad parameter.
|
||||||
.IP "CURLE_BAD_CALLING_ORDER (44)"
|
.IP "CURLE_BAD_CALLING_ORDER (44)"
|
||||||
Internal error. A function was called in a bad order.
|
This is never returned by current libcurl.
|
||||||
.IP "CURLE_HTTP_PORT_FAILED (45)"
|
.IP "CURLE_HTTP_PORT_FAILED (45)"
|
||||||
Interface error. A specified outgoing interface could not be used. Set which
|
Interface error. A specified outgoing interface could not be used. Set which
|
||||||
interface to use for outgoing connections' source IP address with
|
interface to use for outgoing connections' source IP address with
|
||||||
CURLOPT_INTERFACE.
|
CURLOPT_INTERFACE.
|
||||||
.IP "CURLE_BAD_PASSWORD_ENTERED (46)"
|
.IP "CURLE_BAD_PASSWORD_ENTERED (46)"
|
||||||
Bad password entered. An error was signaled when the password was
|
This is never returned by current libcurl.
|
||||||
entered. This can also be the result of a "bad password" returned from a
|
|
||||||
specified password callback.
|
|
||||||
.IP "CURLE_TOO_MANY_REDIRECTS (47)"
|
.IP "CURLE_TOO_MANY_REDIRECTS (47)"
|
||||||
Too many redirects. When following redirects, libcurl hit the maximum amount.
|
Too many redirects. When following redirects, libcurl hit the maximum amount.
|
||||||
Set your limit with CURLOPT_MAXREDIRS.
|
Set your limit with CURLOPT_MAXREDIRS.
|
||||||
@@ -194,6 +190,24 @@ rewinding operation failed
|
|||||||
Initiating the SSL Engine failed
|
Initiating the SSL Engine failed
|
||||||
.IP "CURLE_LOGIN_DENIED (67)"
|
.IP "CURLE_LOGIN_DENIED (67)"
|
||||||
The remote server denied curl to login (Added in 7.13.1)
|
The remote server denied curl to login (Added in 7.13.1)
|
||||||
|
.IP "CURLE_TFTP_NOTFOUND (68)"
|
||||||
|
File not found on TFTP server
|
||||||
|
.IP "CURLE_TFTP_PERM (69"
|
||||||
|
Permission problem on TFTP server
|
||||||
|
.IP "CURLE_TFTP_DISKFULL (70)"
|
||||||
|
Out of disk space on TFTP server
|
||||||
|
.IP "CURLE_TFTP_ILLEGAL (71)"
|
||||||
|
Illegal TFTP operation
|
||||||
|
.IP "CURLE_TFTP_UNKNOWNID (72)"
|
||||||
|
Unknown TFTP transfer ID
|
||||||
|
.IP "CURLE_TFTP_EXISTS (73)"
|
||||||
|
TFTP File already exists
|
||||||
|
.IP "CURLE_TFTP_NOSUCHUSER (74)"
|
||||||
|
No such TFTP user
|
||||||
|
.IP "CURLE_CONV_FAILED (75)"
|
||||||
|
Character conversion failed
|
||||||
|
.IP "CURLE_CONV_REQD (76)"
|
||||||
|
Caller must register conversion callbacks
|
||||||
.SH "CURLMcode"
|
.SH "CURLMcode"
|
||||||
This is the generic return code used by functions in the libcurl multi
|
This is the generic return code used by functions in the libcurl multi
|
||||||
interface. Also consider \fIcurl_multi_strerror(3)\fP.
|
interface. Also consider \fIcurl_multi_strerror(3)\fP.
|
||||||
|
@@ -133,10 +133,11 @@ Repeated calls to \fIcurl_global_init(3)\fP and \fIcurl_global_cleanup(3)\fP
|
|||||||
should be avoided. They should only be called once each.
|
should be avoided. They should only be called once each.
|
||||||
|
|
||||||
.SH "Features libcurl Provides"
|
.SH "Features libcurl Provides"
|
||||||
It is considered best-practice to determine libcurl features run-time rather
|
It is considered best-practice to determine libcurl features at run-time
|
||||||
than build-time (if possible of course). By calling curl_version_info() and
|
rather than at build-time (if possible of course). By calling
|
||||||
checking tout he details of the returned struct, your program can figure out
|
\fIcurl_version_info(3)\fP and checking out the details of the returned
|
||||||
exactly what the currently running libcurl supports.
|
struct, your program can figure out exactly what the currently running libcurl
|
||||||
|
supports.
|
||||||
|
|
||||||
.SH "Handle the Easy libcurl"
|
.SH "Handle the Easy libcurl"
|
||||||
libcurl first introduced the so called easy interface. All operations in the
|
libcurl first introduced the so called easy interface. All operations in the
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
|
# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
|
||||||
# [ACTION-IF-YES], [ACTION-IF-NO])
|
# [ACTION-IF-YES], [ACTION-IF-NO])
|
||||||
# ----------------------------------------------------------
|
# ----------------------------------------------------------
|
||||||
# David Shaw <dshaw@jabberwocky.com> Jan-17-2006
|
# David Shaw <dshaw@jabberwocky.com> May-09-2006
|
||||||
#
|
#
|
||||||
# Checks for libcurl. DEFAULT-ACTION is the string yes or no to
|
# Checks for libcurl. DEFAULT-ACTION is the string yes or no to
|
||||||
# specify whether to default to --with-libcurl or --without-libcurl.
|
# specify whether to default to --with-libcurl or --without-libcurl.
|
||||||
@@ -210,6 +210,9 @@ x=CURLOPT_VERBOSE;
|
|||||||
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1])
|
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1])
|
||||||
eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes
|
eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes
|
||||||
done
|
done
|
||||||
|
else
|
||||||
|
unset LIBCURL
|
||||||
|
unset LIBCURL_CPPFLAGS
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@@ -1,13 +1,14 @@
|
|||||||
#
|
#
|
||||||
# Build a little app for the Hiper project
|
# Build test apps for the Hiper project
|
||||||
# During dev at least, we use a static libcurl.
|
# During dev at least, we use a static libcurl.
|
||||||
#
|
#
|
||||||
|
|
||||||
LDFLAGS = -lcrypt -lidn -lssl -lcrypto -ldl -lz -lresolv -L../ares/.libs -lcares
|
LDFLAGS = -lcrypt -lidn -lssl -lcrypto -ldl -lz -lresolv -L../ares/.libs \
|
||||||
|
-lcares
|
||||||
LIBCURL = -L../lib/.libs/ -lcurl
|
LIBCURL = -L../lib/.libs/ -lcurl
|
||||||
CFLAGS = -I../include -g -DHAVE_CURL_MULTI_SOCKET
|
CFLAGS = -I../include -g
|
||||||
|
|
||||||
all: shiper hiper ulimiter
|
all: shiper hiper hipev ulimiter
|
||||||
|
|
||||||
hiper: hiper.o $(LIBCURL)
|
hiper: hiper.o $(LIBCURL)
|
||||||
$(CC) -o $@ $< $(LIBCURL) $(LDFLAGS)
|
$(CC) -o $@ $< $(LIBCURL) $(LDFLAGS)
|
||||||
@@ -15,6 +16,12 @@ hiper: hiper.o $(LIBCURL)
|
|||||||
hiper.o: hiper.c
|
hiper.o: hiper.c
|
||||||
$(CC) $(CFLAGS) -c $<
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
hipev: hipev.o $(LIBCURL)
|
||||||
|
$(CC) -o $@ $< $(LIBCURL) $(LDFLAGS) -levent
|
||||||
|
|
||||||
|
hipev.o: hipev.c
|
||||||
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
shiper: shiper.o $(LIBCURL)
|
shiper: shiper.o $(LIBCURL)
|
||||||
$(CC) -o $@ $< $(LIBCURL) $(LDFLAGS)
|
$(CC) -o $@ $< $(LIBCURL) $(LDFLAGS)
|
||||||
|
|
||||||
|
29
hiper/STATUS
29
hiper/STATUS
@@ -238,3 +238,32 @@ Roadmap Ahead
|
|||||||
I plan and hope to return to full-time hiper work later on this spring or
|
I plan and hope to return to full-time hiper work later on this spring or
|
||||||
possibly summer to continue where I pause now. Of course some spare time
|
possibly summer to continue where I pause now. Of course some spare time
|
||||||
might also be spent until then to get us moving forward.
|
might also be spent until then to get us moving forward.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
April 11, 2006
|
||||||
|
|
||||||
|
While sitting staring on my screen trying to write up a *nice* sample script
|
||||||
|
using libevent, it strikes me that since libevent is pretty much based around
|
||||||
|
its structs that you setup for each event/file descriptor, my application
|
||||||
|
wants to figure out the correct struct that is associted with the file
|
||||||
|
descriptor that libcurl provides in the socket callback.
|
||||||
|
|
||||||
|
This feels like an operation most applications will need when using the
|
||||||
|
multi_socket API, so it feels like I should better try to figure out a decent
|
||||||
|
way to offer this basic functionality already in libcurl - and the fact that
|
||||||
|
we already have the file descriptors in a hash we can probably just as well
|
||||||
|
extend it somewhat and store some custom pointers as well.
|
||||||
|
|
||||||
|
We need to offer the app a way to set a private pointer to be associated with
|
||||||
|
the particular file descriptor, and then be able to provide that pointer on
|
||||||
|
subsequent callback calls.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
April 20, 2006
|
||||||
|
|
||||||
|
I was wrong when I previously claimed we could have more than one easy handle
|
||||||
|
using the same socket. I've cleaned up and simplified code now to adjust to
|
||||||
|
this.
|
||||||
|
|
||||||
|
550
hiper/hipev.c
Normal file
550
hiper/hipev.c
Normal file
@@ -0,0 +1,550 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Connect N connections. Z are idle, and X are active. Transfer as fast as
|
||||||
|
* possible.
|
||||||
|
*
|
||||||
|
* Run for a specific amount of time (10 secs for now). Output detailed timing
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* Uses libevent.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The maximum number of simultanoues connections/transfers we support */
|
||||||
|
#define NCONNECTIONS 50000
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#include <event.h> /* for libevent */
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MICROSEC 1000000 /* number of microseconds in one second */
|
||||||
|
|
||||||
|
/* The maximum time (in microseconds) we run the test */
|
||||||
|
#define RUN_FOR_THIS_LONG (5*MICROSEC)
|
||||||
|
|
||||||
|
/* Number of loops (seconds) we allow the total download amount and alive
|
||||||
|
connections to remain the same until we bail out. Set this slightly higher
|
||||||
|
when using asynch supported libcurl. */
|
||||||
|
#define IDLE_TIME 10
|
||||||
|
|
||||||
|
struct ourfdset {
|
||||||
|
/* __fds_bits is what the Linux glibc headers use when they declare the
|
||||||
|
fd_set struct so by using this we can actually avoid the typecase for the
|
||||||
|
FD_SET() macro usage but it would hardly be portable */
|
||||||
|
char __fds_bits[NCONNECTIONS/8];
|
||||||
|
};
|
||||||
|
#define FD2_ZERO(x) memset(x, 0, sizeof(struct ourfdset))
|
||||||
|
|
||||||
|
typedef struct ourfdset fd2_set;
|
||||||
|
|
||||||
|
struct globalinfo {
|
||||||
|
size_t dlcounter;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct connection {
|
||||||
|
CURL *e;
|
||||||
|
int id; /* just a counter for easy browsing */
|
||||||
|
char *url;
|
||||||
|
size_t dlcounter;
|
||||||
|
struct globalinfo *global;
|
||||||
|
char error[CURL_ERROR_SIZE];
|
||||||
|
struct event ev[3]; /* maximum 3 events per handle NOTE: should this rather
|
||||||
|
be a define in a public curl header file or possibly
|
||||||
|
just documented somewhere or... ? */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fdinfo {
|
||||||
|
/* create a link list of fdinfo structs */
|
||||||
|
struct fdinfo *next;
|
||||||
|
struct fdinfo *prev;
|
||||||
|
curl_socket_t sockfd;
|
||||||
|
CURL *easy;
|
||||||
|
int action; /* as set by libcurl */
|
||||||
|
long timeout; /* as set by libcurl */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct fdinfo *allsocks;
|
||||||
|
|
||||||
|
static struct fdinfo *findsock(curl_socket_t s)
|
||||||
|
{
|
||||||
|
/* return the struct for the given socket */
|
||||||
|
struct fdinfo *fdp = allsocks;
|
||||||
|
|
||||||
|
while(fdp) {
|
||||||
|
if(fdp->sockfd == s)
|
||||||
|
break;
|
||||||
|
fdp = fdp->next;
|
||||||
|
}
|
||||||
|
return fdp; /* a struct pointer or NULL */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remsock(curl_socket_t s)
|
||||||
|
{
|
||||||
|
struct fdinfo *fdp = allsocks;
|
||||||
|
|
||||||
|
while(fdp) {
|
||||||
|
if(fdp->sockfd == s)
|
||||||
|
break;
|
||||||
|
fdp = fdp->next;
|
||||||
|
}
|
||||||
|
if(!fdp)
|
||||||
|
/* did not find socket to remove! */
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(fdp->prev)
|
||||||
|
fdp->prev->next = fdp->next;
|
||||||
|
if(fdp->next)
|
||||||
|
fdp->next->prev = fdp->prev;
|
||||||
|
else
|
||||||
|
/* this was the last entry */
|
||||||
|
allsocks = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setsock(struct fdinfo *fdp, curl_socket_t s, CURL *easy,
|
||||||
|
int action)
|
||||||
|
{
|
||||||
|
fdp->sockfd = s;
|
||||||
|
fdp->action = action;
|
||||||
|
fdp->easy = easy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addsock(curl_socket_t s, CURL *easy, int action)
|
||||||
|
{
|
||||||
|
struct fdinfo *fdp = calloc(sizeof(struct fdinfo), 1);
|
||||||
|
|
||||||
|
setsock(fdp, s, easy, action);
|
||||||
|
|
||||||
|
if(allsocks) {
|
||||||
|
fdp->next = allsocks;
|
||||||
|
allsocks->prev = fdp;
|
||||||
|
|
||||||
|
/* now set allsocks to point to the new struct */
|
||||||
|
allsocks = fdp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
allsocks = fdp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fdinfo2fdset(fd2_set *fdread, fd2_set *fdwrite, int *maxfd)
|
||||||
|
{
|
||||||
|
struct fdinfo *fdp = allsocks;
|
||||||
|
int writable=0;
|
||||||
|
|
||||||
|
FD2_ZERO(fdread);
|
||||||
|
FD2_ZERO(fdwrite);
|
||||||
|
|
||||||
|
*maxfd = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("Wait for: ");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while(fdp) {
|
||||||
|
if(fdp->action & CURL_POLL_IN) {
|
||||||
|
FD_SET(fdp->sockfd, (fd_set *)fdread);
|
||||||
|
}
|
||||||
|
if(fdp->action & CURL_POLL_OUT) {
|
||||||
|
FD_SET(fdp->sockfd, (fd_set *)fdwrite);
|
||||||
|
writable++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("%d (%s%s) ",
|
||||||
|
fdp->sockfd,
|
||||||
|
(fdp->action & CURL_POLL_IN)?"r":"",
|
||||||
|
(fdp->action & CURL_POLL_OUT)?"w":"");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(fdp->sockfd > *maxfd)
|
||||||
|
*maxfd = fdp->sockfd;
|
||||||
|
|
||||||
|
fdp = fdp->next;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
if(writable)
|
||||||
|
printf("Check for %d writable sockets\n", writable);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* on port 8999 we run a fork enabled sws that supports 'idle' and 'stream' */
|
||||||
|
#define PORT "8999"
|
||||||
|
|
||||||
|
#define HOST "192.168.1.13"
|
||||||
|
|
||||||
|
#define URL_IDLE "http://" HOST ":" PORT "/1000"
|
||||||
|
#define URL_ACTIVE "http://" HOST ":" PORT "/1001"
|
||||||
|
|
||||||
|
|
||||||
|
static int socket_callback(CURL *easy, /* easy handle */
|
||||||
|
curl_socket_t s, /* socket */
|
||||||
|
int what, /* see above */
|
||||||
|
void *userp) /* "private" pointer */
|
||||||
|
{
|
||||||
|
struct fdinfo *fdp;
|
||||||
|
printf("socket %d easy %p what %d\n", s, easy, what);
|
||||||
|
|
||||||
|
if(what == CURL_POLL_REMOVE)
|
||||||
|
remsock(s);
|
||||||
|
else {
|
||||||
|
fdp = findsock(s);
|
||||||
|
|
||||||
|
if(!fdp) {
|
||||||
|
addsock(s, easy, what);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* we already know about it, just change action/timeout */
|
||||||
|
printf("Changing info for socket %d from %d to %d\n",
|
||||||
|
s, fdp->action, what);
|
||||||
|
setsock(fdp, s, easy, what);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; /* return code meaning? */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
writecallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||||
|
{
|
||||||
|
size_t realsize = size * nmemb;
|
||||||
|
struct connection *c = (struct connection *)data;
|
||||||
|
|
||||||
|
c->dlcounter += realsize;
|
||||||
|
c->global->dlcounter += realsize;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("%02d: %d, total %d\n",
|
||||||
|
c->id, c->dlcounter, c->global->dlcounter);
|
||||||
|
#endif
|
||||||
|
return realsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the diff between two timevals, in us */
|
||||||
|
static long tvdiff(struct timeval *newer, struct timeval *older)
|
||||||
|
{
|
||||||
|
return (newer->tv_sec-older->tv_sec)*1000000+
|
||||||
|
(newer->tv_usec-older->tv_usec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* store the start time of the program in this variable */
|
||||||
|
static struct timeval timer;
|
||||||
|
|
||||||
|
static void timer_start(void)
|
||||||
|
{
|
||||||
|
/* capture the time of the start moment */
|
||||||
|
gettimeofday(&timer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct timeval cont; /* at this moment we continued */
|
||||||
|
|
||||||
|
int still_running; /* keep number of running handles */
|
||||||
|
|
||||||
|
struct conncount {
|
||||||
|
long time_us;
|
||||||
|
long laps;
|
||||||
|
long maxtime;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct timeval timerpause;
|
||||||
|
static void timer_pause(void)
|
||||||
|
{
|
||||||
|
/* capture the time of the pause moment */
|
||||||
|
gettimeofday(&timerpause, NULL);
|
||||||
|
|
||||||
|
/* If we have a previous continue (all times except the first), we can now
|
||||||
|
store the time for a whole "lap" */
|
||||||
|
if(cont.tv_sec) {
|
||||||
|
long lap;
|
||||||
|
|
||||||
|
lap = tvdiff(&timerpause, &cont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static long paused; /* amount of us we have been pausing */
|
||||||
|
|
||||||
|
static void timer_continue(void)
|
||||||
|
{
|
||||||
|
/* Capture the time of the restored operation moment, now calculate how long
|
||||||
|
time we were paused and added that to the 'paused' variable.
|
||||||
|
*/
|
||||||
|
gettimeofday(&cont, NULL);
|
||||||
|
|
||||||
|
paused += tvdiff(&cont, &timerpause);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long total; /* amount of us from start to stop */
|
||||||
|
static void timer_total(void)
|
||||||
|
{
|
||||||
|
struct timeval stop;
|
||||||
|
/* Capture the time of the operation stopped moment, now calculate how long
|
||||||
|
time we were running and how much of that pausing.
|
||||||
|
*/
|
||||||
|
gettimeofday(&stop, NULL);
|
||||||
|
|
||||||
|
total = tvdiff(&stop, &timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct globalinfo info;
|
||||||
|
struct connection *conns;
|
||||||
|
|
||||||
|
long selects;
|
||||||
|
long timeouts;
|
||||||
|
|
||||||
|
long multi_socket;
|
||||||
|
long performalive;
|
||||||
|
long performselect;
|
||||||
|
long topselect;
|
||||||
|
|
||||||
|
int num_total;
|
||||||
|
int num_idle;
|
||||||
|
int num_active;
|
||||||
|
|
||||||
|
static void report(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
long active = total - paused;
|
||||||
|
long numdl = 0;
|
||||||
|
|
||||||
|
for(i=0; i < num_total; i++) {
|
||||||
|
if(conns[i].dlcounter)
|
||||||
|
numdl++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Summary from %d simultanoues transfers (%d active)\n",
|
||||||
|
num_total, num_active);
|
||||||
|
printf("%d out of %d connections provided data\n", numdl, num_total);
|
||||||
|
|
||||||
|
printf("Total time: %ldus paused: %ldus curl_multi_socket(): %ldus\n",
|
||||||
|
total, paused, active);
|
||||||
|
|
||||||
|
printf("%d calls to select() "
|
||||||
|
"Average time: %dus\n",
|
||||||
|
selects, paused/selects);
|
||||||
|
printf(" Average number of readable connections per select() return: %d\n",
|
||||||
|
performselect/selects);
|
||||||
|
|
||||||
|
printf(" Max number of readable connections for a single select() "
|
||||||
|
"return: %d\n",
|
||||||
|
topselect);
|
||||||
|
|
||||||
|
printf("%ld calls to multi_socket(), "
|
||||||
|
"Average time: %ldus\n",
|
||||||
|
multi_socket, active/multi_socket);
|
||||||
|
|
||||||
|
printf("%ld select() timeouts\n", timeouts);
|
||||||
|
|
||||||
|
printf("Downloaded %ld bytes in %ld bytes/sec, %ld usec/byte\n",
|
||||||
|
info.dlcounter,
|
||||||
|
info.dlcounter/(total/1000000),
|
||||||
|
total/info.dlcounter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
CURLM *multi_handle;
|
||||||
|
CURLMsg *msg;
|
||||||
|
CURLcode code = CURLE_OK;
|
||||||
|
CURLMcode mcode = CURLM_OK;
|
||||||
|
int rc;
|
||||||
|
int i;
|
||||||
|
fd2_set fdsizecheck;
|
||||||
|
int selectmaxamount;
|
||||||
|
struct fdinfo *fdp;
|
||||||
|
char act;
|
||||||
|
|
||||||
|
memset(&info, 0, sizeof(struct globalinfo));
|
||||||
|
|
||||||
|
if(argc < 3) {
|
||||||
|
printf("Usage: hiper-event [num idle] [num active]\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_idle = atoi(argv[1]);
|
||||||
|
num_active = atoi(argv[2]);
|
||||||
|
|
||||||
|
num_total = num_idle + num_active;
|
||||||
|
|
||||||
|
conns = calloc(num_total, sizeof(struct connection));
|
||||||
|
if(!conns) {
|
||||||
|
printf("Out of memory\n");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(num_total >= NCONNECTIONS) {
|
||||||
|
printf("Too many connections requested, increase NCONNECTIONS!\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_init(); /* Initalize the event library */
|
||||||
|
|
||||||
|
printf("About to do %d connections\n", num_total);
|
||||||
|
|
||||||
|
/* init the multi stack */
|
||||||
|
multi_handle = curl_multi_init();
|
||||||
|
|
||||||
|
for(i=0; i< num_total; i++) {
|
||||||
|
CURL *e;
|
||||||
|
char *nl;
|
||||||
|
|
||||||
|
memset(&conns[i], 0, sizeof(struct connection));
|
||||||
|
|
||||||
|
if(i < num_idle)
|
||||||
|
conns[i].url = URL_IDLE;
|
||||||
|
else
|
||||||
|
conns[i].url = URL_ACTIVE;
|
||||||
|
|
||||||
|
e = curl_easy_init();
|
||||||
|
|
||||||
|
if(!e) {
|
||||||
|
printf("curl_easy_init() for handle %d failed, exiting!\n", i);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
conns[i].e = e;
|
||||||
|
conns[i].id = i;
|
||||||
|
conns[i].global = &info;
|
||||||
|
|
||||||
|
curl_easy_setopt(e, CURLOPT_URL, conns[i].url);
|
||||||
|
curl_easy_setopt(e, CURLOPT_WRITEFUNCTION, writecallback);
|
||||||
|
curl_easy_setopt(e, CURLOPT_WRITEDATA, &conns[i]);
|
||||||
|
curl_easy_setopt(e, CURLOPT_VERBOSE, 0);
|
||||||
|
curl_easy_setopt(e, CURLOPT_ERRORBUFFER, conns[i].error);
|
||||||
|
curl_easy_setopt(e, CURLOPT_PRIVATE, &conns[i]);
|
||||||
|
|
||||||
|
/* add the easy to the multi */
|
||||||
|
if(CURLM_OK != curl_multi_add_handle(multi_handle, e)) {
|
||||||
|
printf("curl_multi_add_handle() returned error for %d\n", i);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_multi_setopt(multi_handle, CURLMOPT_SOCKETFUNCTION, socket_callback);
|
||||||
|
curl_multi_setopt(multi_handle, CURLMOPT_SOCKETDATA, NULL);
|
||||||
|
|
||||||
|
/* we start the action by calling *socket() right away */
|
||||||
|
while(CURLM_CALL_MULTI_PERFORM == curl_multi_socket_all(multi_handle));
|
||||||
|
|
||||||
|
printf("Starting timer, expects to run for %ldus\n", RUN_FOR_THIS_LONG);
|
||||||
|
timer_start();
|
||||||
|
timer_pause();
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
struct timeval timeout;
|
||||||
|
int rc; /* select() return code */
|
||||||
|
long timeout_ms;
|
||||||
|
|
||||||
|
fd2_set fdread;
|
||||||
|
fd2_set fdwrite;
|
||||||
|
int maxfd;
|
||||||
|
|
||||||
|
curl_multi_timeout(multi_handle, &timeout_ms);
|
||||||
|
|
||||||
|
/* set timeout to wait */
|
||||||
|
timeout.tv_sec = timeout_ms/1000;
|
||||||
|
timeout.tv_usec = (timeout_ms%1000)*1000;
|
||||||
|
|
||||||
|
/* convert file descriptors from the transfers to fd_sets */
|
||||||
|
fdinfo2fdset(&fdread, &fdwrite, &maxfd);
|
||||||
|
|
||||||
|
selects++;
|
||||||
|
rc = select(maxfd+1,
|
||||||
|
(fd_set *)&fdread,
|
||||||
|
(fd_set *)&fdwrite,
|
||||||
|
NULL, &timeout);
|
||||||
|
switch(rc) {
|
||||||
|
case -1:
|
||||||
|
/* select error */
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
timeouts++;
|
||||||
|
curl_multi_socket(multi_handle, CURL_SOCKET_TIMEOUT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* timeout or readable/writable sockets */
|
||||||
|
|
||||||
|
for(i=0, fdp = allsocks; fdp; fdp = fdp->next) {
|
||||||
|
act = 0;
|
||||||
|
if((fdp->action & CURL_POLL_IN) &&
|
||||||
|
FD_ISSET(fdp->sockfd, &fdread)) {
|
||||||
|
act |= CURL_POLL_IN;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if((fdp->action & CURL_POLL_OUT) &&
|
||||||
|
FD_ISSET(fdp->sockfd, &fdwrite)) {
|
||||||
|
act |= CURL_POLL_OUT;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(act) {
|
||||||
|
multi_socket++;
|
||||||
|
timer_continue();
|
||||||
|
if(act & CURL_POLL_OUT)
|
||||||
|
act--;
|
||||||
|
curl_multi_socket(multi_handle, fdp->sockfd);
|
||||||
|
timer_pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
performselect += rc;
|
||||||
|
if(rc > topselect)
|
||||||
|
topselect = rc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_total(); /* calculate the total time spent so far */
|
||||||
|
|
||||||
|
if(total > RUN_FOR_THIS_LONG) {
|
||||||
|
printf("Stopped after %ldus\n", total);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(still_running != num_total) {
|
||||||
|
/* something made connections fail, extract the reason and tell */
|
||||||
|
int msgs_left;
|
||||||
|
struct connection *cptr;
|
||||||
|
while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
|
||||||
|
if (msg->msg == CURLMSG_DONE) {
|
||||||
|
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &cptr);
|
||||||
|
|
||||||
|
printf("%d => (%d) %s", cptr->id, msg->data.result, cptr->error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_multi_cleanup(multi_handle);
|
||||||
|
|
||||||
|
/* cleanup all the easy handles */
|
||||||
|
for(i=0; i< num_total; i++)
|
||||||
|
curl_easy_cleanup(conns[i].e);
|
||||||
|
|
||||||
|
report();
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
@@ -16,7 +16,8 @@
|
|||||||
* The same is hiper.c but instead using the new *socket() API instead of the
|
* The same is hiper.c but instead using the new *socket() API instead of the
|
||||||
* "old" *perform() call.
|
* "old" *perform() call.
|
||||||
*
|
*
|
||||||
* Uses libevent.
|
* Uses a select() approach but only for keeping the code simple and
|
||||||
|
* stand-alone. See hipev.c for a libevent-based example.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -33,8 +34,6 @@
|
|||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
#include <event.h> /* for libevent */
|
|
||||||
|
|
||||||
#ifndef FALSE
|
#ifndef FALSE
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
#endif
|
#endif
|
||||||
@@ -84,7 +83,6 @@ struct fdinfo {
|
|||||||
CURL *easy;
|
CURL *easy;
|
||||||
int action; /* as set by libcurl */
|
int action; /* as set by libcurl */
|
||||||
long timeout; /* as set by libcurl */
|
long timeout; /* as set by libcurl */
|
||||||
struct event ev;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct fdinfo *allsocks;
|
static struct fdinfo *allsocks;
|
||||||
|
@@ -242,7 +242,7 @@ typedef enum {
|
|||||||
CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
|
CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
|
||||||
CURLE_FAILED_INIT, /* 2 */
|
CURLE_FAILED_INIT, /* 2 */
|
||||||
CURLE_URL_MALFORMAT, /* 3 */
|
CURLE_URL_MALFORMAT, /* 3 */
|
||||||
CURLE_URL_MALFORMAT_USER, /* 4 (NOT USED) */
|
CURLE_URL_MALFORMAT_USER, /* 4 - NOT USED */
|
||||||
CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
|
CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
|
||||||
CURLE_COULDNT_RESOLVE_HOST, /* 6 */
|
CURLE_COULDNT_RESOLVE_HOST, /* 6 */
|
||||||
CURLE_COULDNT_CONNECT, /* 7 */
|
CURLE_COULDNT_CONNECT, /* 7 */
|
||||||
@@ -250,7 +250,7 @@ typedef enum {
|
|||||||
CURLE_FTP_ACCESS_DENIED, /* 9 a service was denied by the FTP server
|
CURLE_FTP_ACCESS_DENIED, /* 9 a service was denied by the FTP server
|
||||||
due to lack of access - when login fails
|
due to lack of access - when login fails
|
||||||
this is not returned. */
|
this is not returned. */
|
||||||
CURLE_FTP_USER_PASSWORD_INCORRECT, /* 10 */
|
CURLE_FTP_USER_PASSWORD_INCORRECT, /* 10 - NOT USED */
|
||||||
CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
|
CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
|
||||||
CURLE_FTP_WEIRD_USER_REPLY, /* 12 */
|
CURLE_FTP_WEIRD_USER_REPLY, /* 12 */
|
||||||
CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
|
CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
|
||||||
@@ -268,6 +268,10 @@ typedef enum {
|
|||||||
CURLE_FTP_COULDNT_STOR_FILE, /* 25 - failed FTP upload */
|
CURLE_FTP_COULDNT_STOR_FILE, /* 25 - failed FTP upload */
|
||||||
CURLE_READ_ERROR, /* 26 - could open/read from file */
|
CURLE_READ_ERROR, /* 26 - could open/read from file */
|
||||||
CURLE_OUT_OF_MEMORY, /* 27 */
|
CURLE_OUT_OF_MEMORY, /* 27 */
|
||||||
|
/* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
|
||||||
|
instead of a memory allocation error if CURL_DOES_CONVERSIONS
|
||||||
|
is defined
|
||||||
|
*/
|
||||||
CURLE_OPERATION_TIMEOUTED, /* 28 - the timeout time was reached */
|
CURLE_OPERATION_TIMEOUTED, /* 28 - the timeout time was reached */
|
||||||
CURLE_FTP_COULDNT_SET_ASCII, /* 29 - TYPE A failed */
|
CURLE_FTP_COULDNT_SET_ASCII, /* 29 - TYPE A failed */
|
||||||
CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
|
CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
|
||||||
@@ -318,9 +322,18 @@ typedef enum {
|
|||||||
CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
|
CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
|
||||||
CURLE_TFTP_EXISTS, /* 73 - File already exists */
|
CURLE_TFTP_EXISTS, /* 73 - File already exists */
|
||||||
CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
|
CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
|
||||||
|
CURLE_CONV_FAILED, /* 75 - conversion failed */
|
||||||
|
CURLE_CONV_REQD, /* 76 - caller must register conversion
|
||||||
|
callbacks using curl_easy_setopt options
|
||||||
|
CURLOPT_CONV_FROM_NETWORK_FUNCTION,
|
||||||
|
CURLOPT_CONV_TO_NETWORK_FUNCTION, and
|
||||||
|
CURLOPT_CONV_FROM_UTF8_FUNCTION */
|
||||||
CURL_LAST /* never use! */
|
CURL_LAST /* never use! */
|
||||||
} CURLcode;
|
} CURLcode;
|
||||||
|
|
||||||
|
/* This prototype applies to all conversion callbacks */
|
||||||
|
typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
|
||||||
|
|
||||||
typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
|
typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
|
||||||
void *ssl_ctx, /* actually an
|
void *ssl_ctx, /* actually an
|
||||||
OpenSSL SSL_CTX */
|
OpenSSL SSL_CTX */
|
||||||
@@ -381,6 +394,15 @@ typedef enum {
|
|||||||
CURLFTPAUTH_LAST /* not an option, never use */
|
CURLFTPAUTH_LAST /* not an option, never use */
|
||||||
} curl_ftpauth;
|
} curl_ftpauth;
|
||||||
|
|
||||||
|
/* parameter for the CURLOPT_FTP_FILEMETHOD option */
|
||||||
|
typedef enum {
|
||||||
|
CURLFTPMETHOD_DEFAULT, /* let libcurl pick */
|
||||||
|
CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */
|
||||||
|
CURLFTPMETHOD_NOCWD, /* no CWD at all */
|
||||||
|
CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
|
||||||
|
CURLFTPMETHOD_LAST /* not an option, never use */
|
||||||
|
} curl_ftpmethod;
|
||||||
|
|
||||||
/* long may be 32 or 64 bits, but we should never depend on anything else
|
/* long may be 32 or 64 bits, but we should never depend on anything else
|
||||||
but 32 */
|
but 32 */
|
||||||
#define CURLOPTTYPE_LONG 0
|
#define CURLOPTTYPE_LONG 0
|
||||||
@@ -403,7 +425,7 @@ typedef enum {
|
|||||||
*/
|
*/
|
||||||
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
|
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
|
||||||
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
|
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
|
||||||
defined(__POCC__)
|
defined(__POCC__) || defined(__SALFORDC__)
|
||||||
/* This compiler is believed to have an ISO compatible preprocessor */
|
/* This compiler is believed to have an ISO compatible preprocessor */
|
||||||
#define CURL_ISOCPP
|
#define CURL_ISOCPP
|
||||||
#else
|
#else
|
||||||
@@ -912,7 +934,8 @@ typedef enum {
|
|||||||
control connection. */
|
control connection. */
|
||||||
CINIT(FTP_SKIP_PASV_IP, LONG, 137),
|
CINIT(FTP_SKIP_PASV_IP, LONG, 137),
|
||||||
|
|
||||||
/* Select "file method" to use when doing FTP */
|
/* Select "file method" to use when doing FTP, see the curl_ftpmethod
|
||||||
|
above. */
|
||||||
CINIT(FTP_FILEMETHOD, LONG, 138),
|
CINIT(FTP_FILEMETHOD, LONG, 138),
|
||||||
|
|
||||||
/* Local port number to bind the socket to */
|
/* Local port number to bind the socket to */
|
||||||
@@ -927,6 +950,19 @@ typedef enum {
|
|||||||
extracting it with CURLINFO_LASTSOCKET */
|
extracting it with CURLINFO_LASTSOCKET */
|
||||||
CINIT(CONNECT_ONLY, LONG, 141),
|
CINIT(CONNECT_ONLY, LONG, 141),
|
||||||
|
|
||||||
|
/* Function that will be called to convert from the
|
||||||
|
network encoding (instead of using the iconv calls in libcurl) */
|
||||||
|
CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),
|
||||||
|
|
||||||
|
/* Function that will be called to convert to the
|
||||||
|
network encoding (instead of using the iconv calls in libcurl) */
|
||||||
|
CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),
|
||||||
|
|
||||||
|
/* Function that will be called to convert from UTF8
|
||||||
|
(instead of using the iconv calls in libcurl)
|
||||||
|
Note that this is used only for SSL certificate processing */
|
||||||
|
CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),
|
||||||
|
|
||||||
CURLOPT_LASTENTRY /* the last unused */
|
CURLOPT_LASTENTRY /* the last unused */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
@@ -1136,7 +1172,7 @@ CURL_EXTERN char *curl_getenv(const char *variable);
|
|||||||
CURL_EXTERN char *curl_version(void);
|
CURL_EXTERN char *curl_version(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NAME curl_escape()
|
* NAME curl_easy_escape()
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
*
|
*
|
||||||
@@ -1144,18 +1180,34 @@ CURL_EXTERN char *curl_version(void);
|
|||||||
* %XX versions). This function returns a new allocated string or NULL if an
|
* %XX versions). This function returns a new allocated string or NULL if an
|
||||||
* error occurred.
|
* error occurred.
|
||||||
*/
|
*/
|
||||||
CURL_EXTERN char *curl_escape(const char *string, int length);
|
CURL_EXTERN char *curl_easy_escape(CURL *handle,
|
||||||
|
const char *string,
|
||||||
|
int length);
|
||||||
|
|
||||||
|
/* the previous version: */
|
||||||
|
CURL_EXTERN char *curl_escape(const char *string,
|
||||||
|
int length);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NAME curl_unescape()
|
* NAME curl_easy_unescape()
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
*
|
*
|
||||||
* Unescapes URL encoding in strings (converts all %XX codes to their 8bit
|
* Unescapes URL encoding in strings (converts all %XX codes to their 8bit
|
||||||
* versions). This function returns a new allocated string or NULL if an error
|
* versions). This function returns a new allocated string or NULL if an error
|
||||||
* occurred.
|
* occurred.
|
||||||
|
* Conversion Note: On non-ASCII platforms the ASCII %XX codes are
|
||||||
|
* converted into the host encoding.
|
||||||
*/
|
*/
|
||||||
CURL_EXTERN char *curl_unescape(const char *string, int length);
|
CURL_EXTERN char *curl_easy_unescape(CURL *handle,
|
||||||
|
const char *string,
|
||||||
|
int length,
|
||||||
|
int *outlength);
|
||||||
|
|
||||||
|
/* the previous version */
|
||||||
|
CURL_EXTERN char *curl_unescape(const char *string,
|
||||||
|
int length);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NAME curl_free()
|
* NAME curl_free()
|
||||||
@@ -1282,9 +1334,10 @@ typedef enum {
|
|||||||
CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
|
CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
|
||||||
CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
|
CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
|
||||||
CURLINFO_LASTSOCKET = CURLINFO_LONG + 29,
|
CURLINFO_LASTSOCKET = CURLINFO_LONG + 29,
|
||||||
|
CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30,
|
||||||
/* Fill in new entries below here! */
|
/* Fill in new entries below here! */
|
||||||
|
|
||||||
CURLINFO_LASTONE = 29
|
CURLINFO_LASTONE = 30
|
||||||
} CURLINFO;
|
} CURLINFO;
|
||||||
|
|
||||||
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
||||||
@@ -1421,6 +1474,8 @@ typedef struct {
|
|||||||
#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */
|
#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */
|
||||||
#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */
|
#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */
|
||||||
#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */
|
#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */
|
||||||
|
#define CURL_VERSION_CONV (1<<12) /* character conversions are
|
||||||
|
supported */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NAME curl_version_info()
|
* NAME curl_version_info()
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -28,13 +28,13 @@
|
|||||||
|
|
||||||
/* This is the version number of the libcurl package from which this header
|
/* This is the version number of the libcurl package from which this header
|
||||||
file origins: */
|
file origins: */
|
||||||
#define LIBCURL_VERSION "7.15.2-CVS"
|
#define LIBCURL_VERSION "7.15.4-CVS"
|
||||||
|
|
||||||
/* The numeric version number is also available "in parts" by using these
|
/* The numeric version number is also available "in parts" by using these
|
||||||
defines: */
|
defines: */
|
||||||
#define LIBCURL_VERSION_MAJOR 7
|
#define LIBCURL_VERSION_MAJOR 7
|
||||||
#define LIBCURL_VERSION_MINOR 15
|
#define LIBCURL_VERSION_MINOR 15
|
||||||
#define LIBCURL_VERSION_PATCH 2
|
#define LIBCURL_VERSION_PATCH 4
|
||||||
|
|
||||||
/* This is the numeric version of the libcurl version number, meant for easier
|
/* This is the numeric version of the libcurl version number, meant for easier
|
||||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||||
@@ -51,6 +51,6 @@
|
|||||||
and it is always a greater number in a more recent release. It makes
|
and it is always a greater number in a more recent release. It makes
|
||||||
comparisons with greater than and less than work.
|
comparisons with greater than and less than work.
|
||||||
*/
|
*/
|
||||||
#define LIBCURL_VERSION_NUM 0x070f02
|
#define LIBCURL_VERSION_NUM 0x070f04
|
||||||
|
|
||||||
#endif /* __CURL_CURLVER_H */
|
#endif /* __CURL_CURLVER_H */
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -42,11 +42,18 @@ CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
|
|||||||
#ifdef _MPRINTF_REPLACE
|
#ifdef _MPRINTF_REPLACE
|
||||||
# define printf curl_mprintf
|
# define printf curl_mprintf
|
||||||
# define fprintf curl_mfprintf
|
# define fprintf curl_mfprintf
|
||||||
|
#ifdef CURLDEBUG
|
||||||
|
/* When built with CURLDEBUG we define away the sprintf() functions since we
|
||||||
|
don't want internal code to be using them */
|
||||||
|
# define sprintf sprintf_was_used
|
||||||
|
# define vsprintf vsprintf_was_used
|
||||||
|
#else
|
||||||
# define sprintf curl_msprintf
|
# define sprintf curl_msprintf
|
||||||
|
# define vsprintf curl_mvsprintf
|
||||||
|
#endif
|
||||||
# define snprintf curl_msnprintf
|
# define snprintf curl_msnprintf
|
||||||
# define vprintf curl_mvprintf
|
# define vprintf curl_mvprintf
|
||||||
# define vfprintf curl_mvfprintf
|
# define vfprintf curl_mvfprintf
|
||||||
# define vsprintf curl_mvsprintf
|
|
||||||
# define vsnprintf curl_mvsnprintf
|
# define vsnprintf curl_mvsnprintf
|
||||||
# define aprintf curl_maprintf
|
# define aprintf curl_maprintf
|
||||||
# define vaprintf curl_mvaprintf
|
# define vaprintf curl_mvaprintf
|
||||||
|
@@ -83,8 +83,6 @@ extern "C" {
|
|||||||
|
|
||||||
typedef void CURLM;
|
typedef void CURLM;
|
||||||
|
|
||||||
#ifdef HAVE_CURL_MULTI_SOCKET /* this is not set by anything yet */
|
|
||||||
|
|
||||||
#ifndef curl_socket_typedef
|
#ifndef curl_socket_typedef
|
||||||
/* Public socket typedef */
|
/* Public socket typedef */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -97,8 +95,6 @@ typedef int curl_socket_t;
|
|||||||
#define curl_socket_typedef
|
#define curl_socket_typedef
|
||||||
#endif /* curl_socket_typedef */
|
#endif /* curl_socket_typedef */
|
||||||
|
|
||||||
#endif /* HAVE_CURL_MULTI_SOCKET */
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() soon */
|
CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() soon */
|
||||||
CURLM_OK,
|
CURLM_OK,
|
||||||
@@ -106,6 +102,8 @@ typedef enum {
|
|||||||
CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
|
CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
|
||||||
CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
|
CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
|
||||||
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
|
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
|
||||||
|
CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
|
||||||
|
CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
|
||||||
CURLM_LAST
|
CURLM_LAST
|
||||||
} CURLMcode;
|
} CURLMcode;
|
||||||
|
|
||||||
@@ -243,7 +241,6 @@ CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
|
|||||||
*/
|
*/
|
||||||
CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
||||||
|
|
||||||
#ifdef HAVE_CURL_MULTI_SOCKET
|
|
||||||
/*
|
/*
|
||||||
* Name: curl_multi_socket() and
|
* Name: curl_multi_socket() and
|
||||||
* curl_multi_socket_all()
|
* curl_multi_socket_all()
|
||||||
@@ -259,8 +256,6 @@ CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
|||||||
#define CURL_POLL_INOUT 3
|
#define CURL_POLL_INOUT 3
|
||||||
#define CURL_POLL_REMOVE 4
|
#define CURL_POLL_REMOVE 4
|
||||||
|
|
||||||
#define CURL_EASY_NONE (CURL *)0
|
|
||||||
#define CURL_EASY_TIMEOUT (CURL *)0
|
|
||||||
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
|
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
|
||||||
|
|
||||||
typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
|
typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
|
||||||
@@ -268,15 +263,9 @@ typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
|
|||||||
int what, /* see above */
|
int what, /* see above */
|
||||||
void *userp); /* "private" pointer */
|
void *userp); /* "private" pointer */
|
||||||
|
|
||||||
CURLMcode curl_multi_socket(CURLM *multi_handle,
|
CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s);
|
||||||
curl_socket_t s,
|
|
||||||
CURL *easy,
|
|
||||||
curl_socket_callback callback,
|
|
||||||
void *userp); /* passed to callback */
|
|
||||||
|
|
||||||
CURLMcode curl_multi_socket_all(CURLM *multi_handle,
|
CURLMcode curl_multi_socket_all(CURLM *multi_handle);
|
||||||
curl_socket_callback callback,
|
|
||||||
void *userp); /* passed to callback */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Name: curl_multi_timeout()
|
* Name: curl_multi_timeout()
|
||||||
@@ -289,7 +278,39 @@ CURLMcode curl_multi_socket_all(CURLM *multi_handle,
|
|||||||
*/
|
*/
|
||||||
CURLMcode curl_multi_timeout(CURLM *multi_handle, long *milliseconds);
|
CURLMcode curl_multi_timeout(CURLM *multi_handle, long *milliseconds);
|
||||||
|
|
||||||
#endif /* HAVE_CURL_MULTI_SOCKET */
|
#undef CINIT /* re-using the same name as in curl.h */
|
||||||
|
|
||||||
|
#ifdef CURL_ISOCPP
|
||||||
|
#define CINIT(name,type,number) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + number
|
||||||
|
#else
|
||||||
|
/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
|
||||||
|
#define LONG CURLOPTTYPE_LONG
|
||||||
|
#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
|
||||||
|
#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
|
||||||
|
#define OFF_T CURLOPTTYPE_OFF_T
|
||||||
|
#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* This is the socket callback function pointer */
|
||||||
|
CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
|
||||||
|
|
||||||
|
/* This is the argument passed to the socket callback */
|
||||||
|
CINIT(SOCKETDATA, OBJECTPOINT, 2),
|
||||||
|
|
||||||
|
CURLMOPT_LASTENTRY /* the last unused */
|
||||||
|
} CURLMoption;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name: curl_multi_setopt()
|
||||||
|
*
|
||||||
|
* Desc: Sets options for the multi handle.
|
||||||
|
*
|
||||||
|
* Returns: CURLM error code.
|
||||||
|
*/
|
||||||
|
CURLMcode curl_multi_setopt(CURLM *multi_handle,
|
||||||
|
CURLMoption option, ...);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* end of extern "C" */
|
} /* end of extern "C" */
|
||||||
|
@@ -45,7 +45,8 @@ OBJS = $(OBJ_DIR)\transfer.obj $(OBJ_DIR)\file.obj &
|
|||||||
$(OBJ_DIR)\hostip6.obj $(OBJ_DIR)\inet_ntop.obj &
|
$(OBJ_DIR)\hostip6.obj $(OBJ_DIR)\inet_ntop.obj &
|
||||||
$(OBJ_DIR)\hostsyn.obj $(OBJ_DIR)\parsedate.obj &
|
$(OBJ_DIR)\hostsyn.obj $(OBJ_DIR)\parsedate.obj &
|
||||||
$(OBJ_DIR)\select.obj $(OBJ_DIR)\sslgen.obj &
|
$(OBJ_DIR)\select.obj $(OBJ_DIR)\sslgen.obj &
|
||||||
$(OBJ_DIR)\gtls.obj $(OBJ_DIR)\tftp.obj
|
$(OBJ_DIR)\gtls.obj $(OBJ_DIR)\tftp.obj &
|
||||||
|
$(OBJ_DIR)\splay.obj
|
||||||
|
|
||||||
RESOURCE = $(OBJ_DIR)\libcurl.res
|
RESOURCE = $(OBJ_DIR)\libcurl.res
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
# | (__| |_| | _ <| |___
|
# | (__| |_| | _ <| |___
|
||||||
# \___|\___/|_| \_\_____|
|
# \___|\___/|_| \_\_____|
|
||||||
#
|
#
|
||||||
# Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
# Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
#
|
#
|
||||||
# This software is licensed as described in the file COPYING, which
|
# This software is licensed as described in the file COPYING, which
|
||||||
# you should have received as part of this distribution. The terms
|
# you should have received as part of this distribution. The terms
|
||||||
@@ -25,12 +25,13 @@ AUTOMAKE_OPTIONS = foreign nostdinc
|
|||||||
DSP = curllib.dsp
|
DSP = curllib.dsp
|
||||||
|
|
||||||
EXTRA_DIST = Makefile.b32 Makefile.m32 Makefile.vc6 Makefile.riscos $(DSP) \
|
EXTRA_DIST = Makefile.b32 Makefile.m32 Makefile.vc6 Makefile.riscos $(DSP) \
|
||||||
curllib.dsw config-win32.h config-win32ce.h config-riscos.h \
|
curllib.dsw config-win32.h config-win32ce.h config-riscos.h \
|
||||||
config-mac.h config.h.in ca-bundle.crt README.encoding README.memoryleak \
|
config-mac.h config.h.in ca-bundle.crt README.encoding README.memoryleak \
|
||||||
README.ares README.curlx makefile.dj config.dj libcurl.framework.make \
|
README.ares README.curlx makefile.dj config.dj libcurl.framework.make \
|
||||||
libcurl.plist libcurl.rc config-amigaos.h amigaos.c amigaos.h makefile.amiga \
|
libcurl.plist libcurl.rc config-amigaos.h amigaos.c amigaos.h makefile.amiga \
|
||||||
Makefile.netware nwlib.c libcurl.imp msvcproj.head msvcproj.foot \
|
Makefile.netware nwlib.c libcurl.imp msvcproj.head msvcproj.foot \
|
||||||
config-win32ce.h README.httpauth Makefile.Watcom README.hostip
|
config-win32ce.h README.httpauth Makefile.Watcom README.hostip \
|
||||||
|
README.multi_socket config-tpf.h
|
||||||
|
|
||||||
CLEANFILES = $(DSP)
|
CLEANFILES = $(DSP)
|
||||||
|
|
||||||
|
@@ -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 \
|
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 \
|
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 \
|
hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c \
|
||||||
select.c gtls.c sslgen.c tftp.c
|
select.c gtls.c sslgen.c tftp.c splay.c
|
||||||
|
|
||||||
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
||||||
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
||||||
@@ -18,6 +18,6 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
|||||||
share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \
|
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 \
|
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 \
|
setup.h transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h \
|
||||||
gtls.h tftp.h sockaddr.h
|
gtls.h tftp.h sockaddr.h splay.h
|
||||||
|
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ endif
|
|||||||
|
|
||||||
# Edit the path below to point to the base of your OpenSSL package.
|
# Edit the path below to point to the base of your OpenSSL package.
|
||||||
ifndef OPENSSL_PATH
|
ifndef OPENSSL_PATH
|
||||||
OPENSSL_PATH = ../../openssl-0.9.8
|
OPENSSL_PATH = ../../openssl-0.9.8a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef INSTDIR
|
ifndef INSTDIR
|
||||||
@@ -29,7 +29,7 @@ endif
|
|||||||
# Edit the vars below to change NLM target settings.
|
# Edit the vars below to change NLM target settings.
|
||||||
TARGET = libcurl
|
TARGET = libcurl
|
||||||
VERSION = $(LIBCURL_VERSION)
|
VERSION = $(LIBCURL_VERSION)
|
||||||
COPYR = Copyright (C) 1996 - 2005, Daniel Stenberg, <daniel@haxx.se>
|
COPYR = Copyright (C) 1996 - 2006, Daniel Stenberg, <daniel@haxx.se>
|
||||||
DESCR = cURL libcurl $(LIBCURL_VERSION_STR) - http://curl.haxx.se
|
DESCR = cURL libcurl $(LIBCURL_VERSION_STR) - http://curl.haxx.se
|
||||||
MTSAFE = YES
|
MTSAFE = YES
|
||||||
STACK = 64000
|
STACK = 64000
|
||||||
@@ -95,7 +95,7 @@ LD = nlmconv
|
|||||||
LDFLAGS = -T
|
LDFLAGS = -T
|
||||||
AR = ar
|
AR = ar
|
||||||
ARFLAGS = -cq
|
ARFLAGS = -cq
|
||||||
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return -fno-strict-aliasing
|
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
|
||||||
CFLAGS += -Wall # -pedantic
|
CFLAGS += -Wall # -pedantic
|
||||||
ifeq ($(LIBARCH),LIBC)
|
ifeq ($(LIBARCH),LIBC)
|
||||||
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
||||||
|
@@ -480,6 +480,7 @@ X_OBJS= \
|
|||||||
$(DIROBJ)\select.obj \
|
$(DIROBJ)\select.obj \
|
||||||
$(DIROBJ)\content_encoding.obj \
|
$(DIROBJ)\content_encoding.obj \
|
||||||
$(DIROBJ)\tftp.obj \
|
$(DIROBJ)\tftp.obj \
|
||||||
|
$(DIROBJ)\splay.obj \
|
||||||
$(RESOURCE)
|
$(RESOURCE)
|
||||||
|
|
||||||
all : $(TARGET)
|
all : $(TARGET)
|
||||||
|
112
lib/README.multi_socket
Normal file
112
lib/README.multi_socket
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
Implementation of the curl_multi_socket API
|
||||||
|
|
||||||
|
Most of the design decisions and debates about this new API have already
|
||||||
|
been held on the curl-library mailing list a long time ago so I had a basic
|
||||||
|
idea on what approach to use. The main ideas of the new API are simply:
|
||||||
|
|
||||||
|
1 - The application can use whatever event system it likes as it gets info
|
||||||
|
from libcurl about what file descriptors libcurl waits for what action
|
||||||
|
on. (The previous API returns fd_sets which is very select()-centric).
|
||||||
|
|
||||||
|
2 - When the application discovers action on a single socket, it calls
|
||||||
|
libcurl and informs that there was action on this particular socket and
|
||||||
|
libcurl can then act on that socket/transfer only and not care about
|
||||||
|
any other transfers. (The previous API always had to scan through all
|
||||||
|
the existing transfers.)
|
||||||
|
|
||||||
|
The idea is that curl_multi_socket() calls a given callback with information
|
||||||
|
about what socket to wait for what action on, and the callback only gets
|
||||||
|
called if the status of that socket has changed.
|
||||||
|
|
||||||
|
In the API draft from before, we have a timeout argument on a per socket
|
||||||
|
basis and we also allowed curl_multi_socket() to pass in an 'easy handle'
|
||||||
|
instead of socket to allow libcurl to shortcut a lookup and work on the
|
||||||
|
affected easy handle right away. Both these turned out to be bad ideas.
|
||||||
|
|
||||||
|
The timeout argument was removed from the socket callback since after much
|
||||||
|
thinking I came to the conclusion that we really don't want to handle
|
||||||
|
timeouts on a per socket basis. We need it on a per transfer (easy handle)
|
||||||
|
basis and thus we can't provide it in the callbacks in a nice way. Instead,
|
||||||
|
we have to offer a curl_multi_timeout() that returns the largest amount of
|
||||||
|
time we should wait before we call the "timeout action" of libcurl, to
|
||||||
|
trigger the proper internal timeout action on the affected transfer. To get
|
||||||
|
this to work, I added a struct to each easy handle in which we store an
|
||||||
|
"expire time" (if any). The structs are then "splay sorted" so that we can
|
||||||
|
add and remove times from the linked list and yet somewhat swiftly figure
|
||||||
|
out 1 - how long time there is until the next timer expires and 2 - which
|
||||||
|
timer (handle) should we take care of now. Of course, the upside of all this
|
||||||
|
is that we get a curl_multi_timeout() that should also work with old-style
|
||||||
|
applications that use curl_multi_perform().
|
||||||
|
|
||||||
|
The easy handle argument was removed fom the curl_multi_socket() function
|
||||||
|
because having it there would require the application to do a socket to easy
|
||||||
|
handle conversion on its own. I find it very unlikely that applications
|
||||||
|
would want to do that and since libcurl would need such a lookup on its own
|
||||||
|
anyway since we didn't want to force applications to do that translation
|
||||||
|
code (it would be optional), it seemed like an unnecessary option.
|
||||||
|
|
||||||
|
Instead I created an internal "socket to easy handles" hash table that given
|
||||||
|
a socket (file descriptor) return the easy handle that waits for action on
|
||||||
|
that socket. This hash is made using the already existing hash code
|
||||||
|
(previously only used for the DNS cache).
|
||||||
|
|
||||||
|
To make libcurl be able to report plain sockets in the socket callback, I
|
||||||
|
had to re-organize the internals of the curl_multi_fdset() etc so that the
|
||||||
|
conversion from sockets to fd_sets for that function is only done in the
|
||||||
|
last step before the data is returned. I also had to extend c-ares to get a
|
||||||
|
function that can return plain sockets, as that library too returned only
|
||||||
|
fd_sets and that is no longer good enough. The changes done to c-ares have
|
||||||
|
been committed and are available in the c-ares CVS repository destined to be
|
||||||
|
included in the upcoming c-ares 1.3.1 release.
|
||||||
|
|
||||||
|
The 'shiper' tool is the test application I wrote that uses the new
|
||||||
|
curl_multi_socket() in its current state. It seems to be working and it uses
|
||||||
|
the API as it is documented and supposed to work. It is still using
|
||||||
|
select(), because I needed that during development (like until I had the
|
||||||
|
socket hash implemented etc) and because I haven't yet learned how to use
|
||||||
|
libevent or similar.
|
||||||
|
|
||||||
|
The hiper/shiper tools are very simple and initiates lots of connections and
|
||||||
|
have them running for the test period and then kills them all.
|
||||||
|
|
||||||
|
Since I wasn't done with the implementation until early January I haven't
|
||||||
|
had time to run very many measurements and checks, but I have done a few
|
||||||
|
runs with up to a few hundred connections (with a single active one). The
|
||||||
|
curl_multi_socket() invoke then takes 3-6 microseconds in average (using the
|
||||||
|
read-only-1-byte-at-a-time hack). If this number does increase a lot when we
|
||||||
|
add connections, it certainly matches my in my opinion very ambitious goal.
|
||||||
|
We are now below the 60 microseconds "per socket action" goal. It is
|
||||||
|
destined to be somewhat higher the more connections we have since the hash
|
||||||
|
table gets more populated and the splay tree will grow etc.
|
||||||
|
|
||||||
|
Some tests at 7000 and 9000 connections showed that the socket hash lookup
|
||||||
|
is somewhat of a bottle neck. Its current implementation may be a bit too
|
||||||
|
limiting. It simply has a fixed-size array, and on each entry in the array
|
||||||
|
it has a linked list with entries. So the hash only checks which list to
|
||||||
|
scan through. The code I had used so for used a list with merely 7 slots (as
|
||||||
|
that is what the DNS hash uses) but with 7000 connections that would make an
|
||||||
|
average of 1000 nodes in each list to run through. I upped that to 97 slots
|
||||||
|
(I believe a prime is suitable) and noticed a significant speed increase. I
|
||||||
|
need to reconsider the hash implementation or use a rather large default
|
||||||
|
value like this. At 9000 connections I was still below 10us per call.
|
||||||
|
|
||||||
|
Status Right Now
|
||||||
|
|
||||||
|
The curl_multi_socket() API is implemented according to how it is
|
||||||
|
documented.
|
||||||
|
|
||||||
|
http://curl.haxx.se/libcurl/c/curl_multi_socket.html
|
||||||
|
http://curl.haxx.se/libcurl/c/curl_multi_timeout.html
|
||||||
|
http://curl.haxx.se/libcurl/c/curl_multi_setopt.html
|
||||||
|
|
||||||
|
What is Left for the curl_multi_socket API
|
||||||
|
|
||||||
|
1 - More measuring with more extreme number of connections
|
||||||
|
|
||||||
|
2 - More testing with actual URLs and complete from start to end transfers.
|
||||||
|
|
||||||
|
I'm quite sure we don't set expire times all over in the code properly, so
|
||||||
|
there is bound to be some timeout bugs left.
|
||||||
|
|
||||||
|
What it really takes is for me to commit the code and to make an official
|
||||||
|
release with it so that we get people "out there" to help out testing it.
|
688
lib/config-tpf.h
Normal file
688
lib/config-tpf.h
Normal file
@@ -0,0 +1,688 @@
|
|||||||
|
#ifndef __LIBCONFIGTPF_H
|
||||||
|
#define __LIBCONFIGTPF_H
|
||||||
|
|
||||||
|
/* ================================================================ */
|
||||||
|
/* lib/config-tpf.h - Hand crafted config file for TPF */
|
||||||
|
/* ================================================================ */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
/* FEATURES, FUNCTIONS, and DEFINITIONS */
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* NOTE: Refer also to the .mak file for some of the flags below */
|
||||||
|
|
||||||
|
/* when building libcurl itself */
|
||||||
|
/* #undef BUILDING_LIBCURL */
|
||||||
|
|
||||||
|
/* to disable cookies support */
|
||||||
|
/* #undef CURL_DISABLE_COOKIES */
|
||||||
|
|
||||||
|
/* to disable cryptographic authentication */
|
||||||
|
/* #undef CURL_DISABLE_CRYPTO_AUTH */
|
||||||
|
|
||||||
|
/* to disable DICT */
|
||||||
|
/* #undef CURL_DISABLE_DICT */
|
||||||
|
|
||||||
|
/* to disable FILE */
|
||||||
|
/* #undef CURL_DISABLE_FILE */
|
||||||
|
|
||||||
|
/* to disable FTP */
|
||||||
|
/* #undef CURL_DISABLE_FTP */
|
||||||
|
|
||||||
|
/* to disable HTTP */
|
||||||
|
/* #undef CURL_DISABLE_HTTP */
|
||||||
|
|
||||||
|
/* to disable LDAP */
|
||||||
|
/* #undef CURL_DISABLE_LDAP */
|
||||||
|
|
||||||
|
/* to disable TELNET */
|
||||||
|
/* #undef CURL_DISABLE_TELNET */
|
||||||
|
|
||||||
|
/* to disable TFTP */
|
||||||
|
/* #undef CURL_DISABLE_TFTP */
|
||||||
|
|
||||||
|
/* to disable verbose strings */
|
||||||
|
/* #undef CURL_DISABLE_VERBOSE_STRINGS */
|
||||||
|
|
||||||
|
/* when not building a shared library */
|
||||||
|
/* #undef CURL_STATICLIB */
|
||||||
|
|
||||||
|
/* Set to explicitly specify we don't want to use thread-safe functions */
|
||||||
|
/* #undef DISABLED_THREADSAFE */
|
||||||
|
|
||||||
|
/* lber dynamic library file */
|
||||||
|
/* #undef DL_LBER_FILE */
|
||||||
|
|
||||||
|
/* ldap dynamic library file */
|
||||||
|
/* #undef DL_LDAP_FILE */
|
||||||
|
|
||||||
|
/* your Entropy Gathering Daemon socket pathname */
|
||||||
|
/* #undef EGD_SOCKET */
|
||||||
|
|
||||||
|
/* Define if you want to enable IPv6 support */
|
||||||
|
/* #undef ENABLE_IPV6 */
|
||||||
|
|
||||||
|
/* Define to the type of arg 1 for getnameinfo. */
|
||||||
|
/* #undef GETNAMEINFO_TYPE_ARG1 */
|
||||||
|
|
||||||
|
/* Define to the type of arg 2 for getnameinfo. */
|
||||||
|
/* #undef GETNAMEINFO_TYPE_ARG2 */
|
||||||
|
|
||||||
|
/* Define to the type of args 4 and 6 for getnameinfo. */
|
||||||
|
/* #undef GETNAMEINFO_TYPE_ARG46 */
|
||||||
|
|
||||||
|
/* Define to the type of arg 7 for getnameinfo. */
|
||||||
|
/* #undef GETNAMEINFO_TYPE_ARG7 */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <alloca.h> header file. */
|
||||||
|
#define HAVE_ALLOCA_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||||
|
#define HAVE_ARPA_INET_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <arpa/tftp.h> header file. */
|
||||||
|
/* #undef HAVE_ARPA_TFTP_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <assert.h> header file. */
|
||||||
|
#define HAVE_ASSERT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `basename' function. */
|
||||||
|
#define HAVE_BASENAME 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `closesocket' function. */
|
||||||
|
/* #undef HAVE_CLOSESOCKET */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
|
||||||
|
/* #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA */
|
||||||
|
#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <crypto.h> header file. */
|
||||||
|
/* #undef HAVE_CRYPTO_H */
|
||||||
|
#define HAVE_CRYPTO_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <des.h> header file. */
|
||||||
|
/* #undef HAVE_DES_H */
|
||||||
|
#define HAVE_DES_H 1
|
||||||
|
|
||||||
|
/* disabled non-blocking sockets */
|
||||||
|
/* #undef HAVE_DISABLED_NONBLOCKING */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
|
#define HAVE_DLFCN_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `dlopen' function. */
|
||||||
|
#define HAVE_DLOPEN 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
|
||||||
|
/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
|
||||||
|
#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <errno.h> header file. */
|
||||||
|
#define HAVE_ERRNO_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <err.h> header file. */
|
||||||
|
/* #undef HAVE_ERR_H */
|
||||||
|
#define HAVE_ERR_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||||
|
#define HAVE_FCNTL_H 1
|
||||||
|
|
||||||
|
/* use FIONBIO for non-blocking sockets */
|
||||||
|
/* #undef HAVE_FIONBIO */
|
||||||
|
#define HAVE_FIONBIO 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fork' function. */
|
||||||
|
/* #undef HAVE_FORK */
|
||||||
|
#define HAVE_FORK 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `ftruncate' function. */
|
||||||
|
#define HAVE_FTRUNCATE 1
|
||||||
|
|
||||||
|
/* Define if getaddrinfo exists and works */
|
||||||
|
/* #undef HAVE_GETADDRINFO */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `geteuid' function. */
|
||||||
|
#define HAVE_GETEUID 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `gethostbyaddr' function. */
|
||||||
|
#define HAVE_GETHOSTBYADDR 1
|
||||||
|
|
||||||
|
/* If you have gethostbyname */
|
||||||
|
#define HAVE_GETHOSTBYNAME 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `gethostbyname_r' function. */
|
||||||
|
/* #undef HAVE_GETHOSTBYNAME_R */
|
||||||
|
|
||||||
|
/* gethostbyname_r() takes 3 args */
|
||||||
|
/* #undef HAVE_GETHOSTBYNAME_R_3 */
|
||||||
|
|
||||||
|
/* gethostbyname_r() takes 5 args */
|
||||||
|
/* #undef HAVE_GETHOSTBYNAME_R_5 */
|
||||||
|
|
||||||
|
/* gethostbyname_r() takes 6 args */
|
||||||
|
/* #undef HAVE_GETHOSTBYNAME_R_6 1 */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the getnameinfo function. */
|
||||||
|
/* #undef HAVE_GETNAMEINFO */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getpass_r' function. */
|
||||||
|
/* #undef HAVE_GETPASS_R */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getprotobyname' function. */
|
||||||
|
/* #undef HAVE_GETPROTOBYNAME */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getpwuid' function. */
|
||||||
|
#define HAVE_GETPWUID 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getrlimit' function. */
|
||||||
|
/* #undef HAVE_GETRLIMIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `gettimeofday' function. */
|
||||||
|
#define HAVE_GETTIMEOFDAY 1
|
||||||
|
|
||||||
|
/* we have a glibc-style strerror_r() */
|
||||||
|
/* #undef HAVE_GLIBC_STRERROR_R */
|
||||||
|
#define HAVE_GLIBC_STRERROR_R 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `gmtime_r' function. */
|
||||||
|
#define HAVE_GMTIME_R 1
|
||||||
|
|
||||||
|
/* if you have the gssapi libraries */
|
||||||
|
/* #undef HAVE_GSSAPI */
|
||||||
|
|
||||||
|
/* if you have the GNU gssapi libraries */
|
||||||
|
/* #undef HAVE_GSSGNU */
|
||||||
|
|
||||||
|
/* if you have the Heimdal gssapi libraries */
|
||||||
|
/* #undef HAVE_GSSHEIMDAL */
|
||||||
|
|
||||||
|
/* if you have the MIT gssapi libraries */
|
||||||
|
/* #undef HAVE_GSSMIT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `iconv' functions. */
|
||||||
|
#define HAVE_ICONV 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `idna_strerror' function. */
|
||||||
|
/* #undef HAVE_IDNA_STRERROR */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `idn_free' function. */
|
||||||
|
/* #undef HAVE_IDN_FREE */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <idn-free.h> header file. */
|
||||||
|
/* #undef HAVE_IDN_FREE_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `inet_addr' function. */
|
||||||
|
#define HAVE_INET_ADDR 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `inet_ntoa' function. */
|
||||||
|
#define HAVE_INET_NTOA 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `inet_ntoa_r' function. */
|
||||||
|
/* #undef HAVE_INET_NTOA_R */
|
||||||
|
|
||||||
|
/* inet_ntoa_r() is declared */
|
||||||
|
/* #undef HAVE_INET_NTOA_R_DECL */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `inet_pton' function. */
|
||||||
|
/* #undef HAVE_INET_PTON */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#define HAVE_INTTYPES_H 1
|
||||||
|
|
||||||
|
/* use ioctlsocket() for non-blocking sockets */
|
||||||
|
/* #undef HAVE_IOCTLSOCKET */
|
||||||
|
|
||||||
|
/* use Ioctlsocket() for non-blocking sockets */
|
||||||
|
/* #undef HAVE_IOCTLSOCKET_CASE */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <io.h> header file. */
|
||||||
|
/* #undef HAVE_IO_H */
|
||||||
|
|
||||||
|
/* if you have the Kerberos4 libraries (including -ldes) */
|
||||||
|
/* #undef HAVE_KRB4 */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
|
||||||
|
/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <krb.h> header file. */
|
||||||
|
/* #undef HAVE_KRB_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `dl' library (-ldl). */
|
||||||
|
#define HAVE_LIBDL 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <libgen.h> header file. */
|
||||||
|
/* #undef HAVE_LIBGEN_H 1 */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `idn' library (-lidn). */
|
||||||
|
/* #undef HAVE_LIBIDN */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `resolv' library (-lresolv). */
|
||||||
|
/* #undef HAVE_LIBRESOLV */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `resolve' library (-lresolve). */
|
||||||
|
/* #undef HAVE_LIBRESOLVE */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `socket' library (-lsocket). */
|
||||||
|
/* #undef HAVE_LIBSOCKET */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `ssl' library (-lssl). */
|
||||||
|
/* #undef HAVE_LIBSSL */
|
||||||
|
#define HAVE_LIBSSL 1
|
||||||
|
|
||||||
|
/* if zlib is available */
|
||||||
|
/* #undef HAVE_LIBZ */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <limits.h> header file. */
|
||||||
|
#define HAVE_LIMITS_H 1
|
||||||
|
|
||||||
|
/* if your compiler supports LL */
|
||||||
|
#define HAVE_LL 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <locale.h> header file. */
|
||||||
|
#define HAVE_LOCALE_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `localtime_r' function. */
|
||||||
|
#define HAVE_LOCALTIME_R 1
|
||||||
|
|
||||||
|
/* if your compiler supports long long */
|
||||||
|
#define HAVE_LONGLONG 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <malloc.h> header file. */
|
||||||
|
/* #undef HAVE_MALLOC_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
|
#define HAVE_MEMORY_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <netdb.h> header file. */
|
||||||
|
#define HAVE_NETDB_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||||
|
#define HAVE_NETINET_IN_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
||||||
|
/* undef HAVE_NETINET_TCP_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <net/if.h> header file. */
|
||||||
|
#define HAVE_NET_IF_H 1
|
||||||
|
|
||||||
|
/* Define if NI_WITHSCOPEID exists and works */
|
||||||
|
/* #undef HAVE_NI_WITHSCOPEID */
|
||||||
|
|
||||||
|
/* Defined if no inet_pton() prototype available */
|
||||||
|
/* #undef HAVE_NO_INET_PTON_PROTO */
|
||||||
|
|
||||||
|
/* we have no strerror_r() proto */
|
||||||
|
/* #undef HAVE_NO_STRERROR_R_DECL */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <openssl/crypto.h> header file. */
|
||||||
|
/* #undef HAVE_OPENSSL_CRYPTO_H */
|
||||||
|
#define HAVE_OPENSSL_CRYPTO_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <openssl/engine.h> header file. */
|
||||||
|
/* #undef HAVE_OPENSSL_ENGINE_H */
|
||||||
|
#define HAVE_OPENSSL_ENGINE_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <openssl/err.h> header file. */
|
||||||
|
/* #undef HAVE_OPENSSL_ERR_H */
|
||||||
|
#define HAVE_OPENSSL_ERR_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <openssl/pem.h> header file. */
|
||||||
|
/* #undef HAVE_OPENSSL_PEM_H */
|
||||||
|
#define HAVE_OPENSSL_PEM_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
|
||||||
|
/* #undef HAVE_OPENSSL_PKCS12_H */
|
||||||
|
#define HAVE_OPENSSL_PKCS12_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <openssl/rsa.h> header file. */
|
||||||
|
/* #undef HAVE_OPENSSL_RSA_H */
|
||||||
|
#define HAVE_OPENSSL_RSA_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <openssl/ssl.h> header file. */
|
||||||
|
/* #undef HAVE_OPENSSL_SSL_H */
|
||||||
|
#define HAVE_OPENSSL_SSL_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <openssl/x509.h> header file. */
|
||||||
|
/* #undef HAVE_OPENSSL_X509_H */
|
||||||
|
#define HAVE_OPENSSL_X509_H 1
|
||||||
|
|
||||||
|
/* use O_NONBLOCK for non-blocking sockets */
|
||||||
|
/* #undef HAVE_O_NONBLOCK 1 */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <pem.h> header file. */
|
||||||
|
/* #undef HAVE_PEM_H */
|
||||||
|
#define HAVE_PEM_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `perror' function. */
|
||||||
|
#define HAVE_PERROR 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `pipe' function. */
|
||||||
|
#define HAVE_PIPE 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `poll' function. */
|
||||||
|
/* #undef HAVE_POLL */
|
||||||
|
|
||||||
|
/* If you have a fine poll */
|
||||||
|
/* #undef HAVE_POLL_FINE */
|
||||||
|
|
||||||
|
/* we have a POSIX-style strerror_r() */
|
||||||
|
/* #undef HAVE_POSIX_STRERROR_R */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <pwd.h> header file. */
|
||||||
|
#define HAVE_PWD_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `RAND_egd' function. */
|
||||||
|
/* #undef HAVE_RAND_EGD */
|
||||||
|
#define HAVE_RAND_EGD 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `RAND_screen' function. */
|
||||||
|
/* #undef HAVE_RAND_SCREEN */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `RAND_status' function. */
|
||||||
|
/* #undef HAVE_RAND_STATUS */
|
||||||
|
#define HAVE_RAND_STATUS 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <rsa.h> header file. */
|
||||||
|
/* #undef HAVE_RSA_H */
|
||||||
|
#define HAVE_RSA_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `select' function. */
|
||||||
|
#define HAVE_SELECT 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <setjmp.h> header file. */
|
||||||
|
#define HAVE_SETJMP_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setlocale' function. */
|
||||||
|
#define HAVE_SETLOCALE 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setrlimit' function. */
|
||||||
|
#define HAVE_SETRLIMIT 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sgtty.h> header file. */
|
||||||
|
/* #undef HAVE_SGTTY_H 1 */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `sigaction' function. */
|
||||||
|
#define HAVE_SIGACTION 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `siginterrupt' function. */
|
||||||
|
/* #undef HAVE_SIGINTERRUPT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `signal' function. */
|
||||||
|
#define HAVE_SIGNAL 1
|
||||||
|
|
||||||
|
/* If you have sigsetjmp */
|
||||||
|
/* #undef HAVE_SIGSETJMP */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `socket' function. */
|
||||||
|
#define HAVE_SOCKET 1
|
||||||
|
|
||||||
|
/* use SO_NONBLOCK for non-blocking sockets */
|
||||||
|
/* #undef HAVE_SO_NONBLOCK */
|
||||||
|
|
||||||
|
/* Define this if you have the SPNEGO library fbopenssl */
|
||||||
|
/* #undef HAVE_SPNEGO */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <ssl.h> header file. */
|
||||||
|
/* #undef HAVE_SSL_H */
|
||||||
|
#define HAVE_SSL_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#define HAVE_STDINT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#define HAVE_STDLIB_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strcasecmp' function. */
|
||||||
|
#define HAVE_STRCASECMP 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strcmpi' function. */
|
||||||
|
/* #undef HAVE_STRCMPI */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strdup' function. */
|
||||||
|
#define HAVE_STRDUP 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strerror_r' function. */
|
||||||
|
#define HAVE_STRERROR_R 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `stricmp' function. */
|
||||||
|
/* #undef HAVE_STRICMP */
|
||||||
|
#define HAVE_STRICMP 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#define HAVE_STRINGS_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#define HAVE_STRING_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strlcat' function. */
|
||||||
|
/* #undef HAVE_STRLCAT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strlcpy' function. */
|
||||||
|
/* #undef HAVE_STRLCPY */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strstr' function. */
|
||||||
|
#define HAVE_STRSTR 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strtok_r' function. */
|
||||||
|
#define HAVE_STRTOK_R 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strtoll' function. */
|
||||||
|
#define HAVE_STRTOLL 1
|
||||||
|
|
||||||
|
/* if struct sockaddr_storage is defined */
|
||||||
|
/* #undef HAVE_STRUCT_SOCKADDR_STORAGE */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/filio.h> header file. */
|
||||||
|
#define HAVE_SYS_FILIO_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||||
|
#define HAVE_SYS_IOCTL_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||||
|
#define HAVE_SYS_PARAM_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/poll.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_POLL_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||||
|
#define HAVE_SYS_RESOURCE_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||||
|
#define HAVE_SYS_SELECT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||||
|
#define HAVE_SYS_SOCKET_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_SOCKIO_H */
|
||||||
|
#define HAVE_SYS_SOCKIO_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#define HAVE_SYS_STAT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||||
|
#define HAVE_SYS_TIME_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#define HAVE_SYS_TYPES_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/utime.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_UTIME_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <termios.h> header file. */
|
||||||
|
/* #undef HAVE_TERMIOS_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <termio.h> header file. */
|
||||||
|
/* #undef HAVE_TERMIO_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <time.h> header file. */
|
||||||
|
#define HAVE_TIME_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <tld.h> header file. */
|
||||||
|
/* #undef HAVE_TLD_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `tld_strerror' function. */
|
||||||
|
/* #undef HAVE_TLD_STRERROR */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `uname' function. */
|
||||||
|
/* #undef HAVE_UNAME */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
|
#define HAVE_UNISTD_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `utime' function. */
|
||||||
|
#define HAVE_UTIME 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <utime.h> header file. */
|
||||||
|
#define HAVE_UTIME_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <winsock2.h> header file. */
|
||||||
|
/* #undef HAVE_WINSOCK2_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <winsock.h> header file. */
|
||||||
|
/* #undef HAVE_WINSOCK_H */
|
||||||
|
|
||||||
|
/* Define this symbol if your OS supports changing the contents of argv */
|
||||||
|
/* #undef HAVE_WRITABLE_ARGV */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ws2tcpip.h header file. */
|
||||||
|
/* #undef HAVE_WS2TCPIP_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <x509.h> header file. */
|
||||||
|
/* #undef HAVE_X509_H */
|
||||||
|
|
||||||
|
/* if you have the zlib.h header file */
|
||||||
|
/* #undef HAVE_ZLIB_H */
|
||||||
|
|
||||||
|
/* If you lack a fine basename() prototype */
|
||||||
|
/* #undef NEED_BASENAME_PROTO */
|
||||||
|
|
||||||
|
/* need REENTRANT defined */
|
||||||
|
/* #undef NEED_REENTRANT */
|
||||||
|
|
||||||
|
/* cpu-machine-OS */
|
||||||
|
#define OS "s390x-ibm-tpf"
|
||||||
|
|
||||||
|
/* Name of package */
|
||||||
|
#define PACKAGE "curl"
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#define PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/"
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#define PACKAGE_NAME "curl"
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#define PACKAGE_STRING "curl -"
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#define PACKAGE_TARNAME "curl"
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#define PACKAGE_VERSION "-"
|
||||||
|
|
||||||
|
/* a suitable file to read random data from */
|
||||||
|
/* #undef RANDOM_FILE */
|
||||||
|
|
||||||
|
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||||
|
#define RETSIGTYPE void
|
||||||
|
|
||||||
|
/* Define to the type of arg 1 for `select'. */
|
||||||
|
#define SELECT_TYPE_ARG1 int
|
||||||
|
|
||||||
|
/* Define to the type of args 2, 3 and 4 for `select'. */
|
||||||
|
#define SELECT_TYPE_ARG234 (fd_set *)
|
||||||
|
|
||||||
|
/* Define to the type of arg 5 for `select'. */
|
||||||
|
#define SELECT_TYPE_ARG5 (struct timeval *)
|
||||||
|
|
||||||
|
/* The size of a `curl_off_t', as computed by sizeof. */
|
||||||
|
#define SIZEOF_CURL_OFF_T 8
|
||||||
|
|
||||||
|
/* The size of a `long', as computed by sizeof. */
|
||||||
|
#define SIZEOF_LONG 8
|
||||||
|
|
||||||
|
/* The size of a `size_t', as computed by sizeof. */
|
||||||
|
#define SIZEOF_SIZE_T 8
|
||||||
|
|
||||||
|
/* The size of a `time_t', as computed by sizeof. */
|
||||||
|
#define SIZEOF_TIME_T 8
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
|
#define STDC_HEADERS 1
|
||||||
|
|
||||||
|
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||||
|
#define TIME_WITH_SYS_TIME 1
|
||||||
|
|
||||||
|
/* Define if you want to enable ares support */
|
||||||
|
/* #undef USE_ARES */
|
||||||
|
|
||||||
|
/* if GnuTLS is enabled */
|
||||||
|
/* #undef USE_GNUTLS */
|
||||||
|
|
||||||
|
/* If you want to build curl with the built-in manual */
|
||||||
|
/* #undef USE_MANUAL */
|
||||||
|
|
||||||
|
/* if OpenSSL is in use */
|
||||||
|
/* #undef USE_OPENSSL */
|
||||||
|
|
||||||
|
/* if SSL is enabled */
|
||||||
|
/* #undef USE_SSLEAY */
|
||||||
|
|
||||||
|
/* to enable SSPI support */
|
||||||
|
/* #undef USE_WINDOWS_SSPI */
|
||||||
|
|
||||||
|
/* Version number of package */
|
||||||
|
#define VERSION "not-used"
|
||||||
|
|
||||||
|
/* Define to avoid automatic inclusion of winsock.h */
|
||||||
|
/* #undef WIN32_LEAN_AND_MEAN */
|
||||||
|
|
||||||
|
/* Define to 1 if on AIX 3.
|
||||||
|
System headers sometimes define this.
|
||||||
|
We just want to avoid a redefinition error message. */
|
||||||
|
#ifndef _ALL_SOURCE
|
||||||
|
/* # undef _ALL_SOURCE */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||||
|
/* #undef _FILE_OFFSET_BITS */
|
||||||
|
|
||||||
|
/* Define for large files, on AIX-style hosts. */
|
||||||
|
/* #undef _LARGE_FILES */
|
||||||
|
|
||||||
|
/* define this if you need it to compile thread-safe code */
|
||||||
|
/* #undef _THREAD_SAFE */
|
||||||
|
|
||||||
|
/* Define to empty if `const' does not conform to ANSI C. */
|
||||||
|
/* #undef const */
|
||||||
|
|
||||||
|
/* type to use in place of in_addr_t if not defined */
|
||||||
|
/* #undef in_addr_t */
|
||||||
|
|
||||||
|
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||||
|
/* #undef size_t */
|
||||||
|
|
||||||
|
/* type to use in place of socklen_t if not defined */
|
||||||
|
/* #undef socklen_t */
|
||||||
|
|
||||||
|
/* the signed version of size_t */
|
||||||
|
/* #undef ssize_t */
|
||||||
|
|
||||||
|
#define CURL_DOES_CONVERSIONS
|
||||||
|
#ifndef CURL_ICONV_CODESET_OF_HOST
|
||||||
|
#define CURL_ICONV_CODESET_OF_HOST "IBM-1047"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
/* HEADER FILES */
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include <strings.h> /* for bzero, strcasecmp, and strncasecmp */
|
||||||
|
#include <string.h> /* for strcpy and strlen */
|
||||||
|
#include <stdlib.h> /* for rand and srand */
|
||||||
|
#include <sys/socket.h> /* for select and ioctl*/
|
||||||
|
#include <netdb.h> /* for in_addr_t definition */
|
||||||
|
#include <tpf/sysapi.h> /* for tpf_process_signals */
|
||||||
|
|
||||||
|
#endif /* __LIBCONFIGTPF_H */
|
@@ -37,7 +37,9 @@
|
|||||||
#define HAVE_IO_H 1
|
#define HAVE_IO_H 1
|
||||||
|
|
||||||
/* Define if you have the <malloc.h> header file. */
|
/* Define if you have the <malloc.h> header file. */
|
||||||
|
#ifndef __SALFORDC__
|
||||||
#define HAVE_MALLOC_H 1
|
#define HAVE_MALLOC_H 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define if you have the <netdb.h> header file. */
|
/* Define if you have the <netdb.h> header file. */
|
||||||
/* #define HAVE_NETDB_H 1 */
|
/* #define HAVE_NETDB_H 1 */
|
||||||
@@ -45,6 +47,11 @@
|
|||||||
/* Define if you have the <netinet/in.h> header file. */
|
/* Define if you have the <netinet/in.h> header file. */
|
||||||
/* #define HAVE_NETINET_IN_H 1 */
|
/* #define HAVE_NETINET_IN_H 1 */
|
||||||
|
|
||||||
|
/* Define if you have the <process.h> header file. */
|
||||||
|
#ifndef __SALFORDC__
|
||||||
|
#define HAVE_PROCESS_H 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define if you have the <sgtty.h> header file. */
|
/* Define if you have the <sgtty.h> header file. */
|
||||||
/* #define HAVE_SGTTY_H 1 */
|
/* #define HAVE_SGTTY_H 1 */
|
||||||
|
|
||||||
@@ -98,11 +105,13 @@
|
|||||||
/* Define if you have the <winsock.h> header file. */
|
/* Define if you have the <winsock.h> header file. */
|
||||||
#define HAVE_WINSOCK_H 1
|
#define HAVE_WINSOCK_H 1
|
||||||
|
|
||||||
|
#ifndef __SALFORDC__
|
||||||
/* Define if you have the <winsock2.h> header file. */
|
/* Define if you have the <winsock2.h> header file. */
|
||||||
#define HAVE_WINSOCK2_H 1
|
#define HAVE_WINSOCK2_H 1
|
||||||
|
|
||||||
/* Define if you have the <ws2tcpip.h> header file. */
|
/* Define if you have the <ws2tcpip.h> header file. */
|
||||||
#define HAVE_WS2TCPIP_H 1
|
#define HAVE_WS2TCPIP_H 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* OTHER HEADER INFO */
|
/* OTHER HEADER INFO */
|
||||||
@@ -246,8 +255,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Define SIZEOF_CURL_OFF_T as computed by sizeof(curl_off_t) */
|
/* Define SIZEOF_CURL_OFF_T as computed by sizeof(curl_off_t) */
|
||||||
/* Borland/PellesC lacks _lseeki64(), so we don't support >2GB files. */
|
/* Borland/PellesC/SalfordC lacks _lseeki64(), so we don't support
|
||||||
#if defined(__BORLANDC__) || defined(__POCC__)
|
* >2GB files.
|
||||||
|
*/
|
||||||
|
#if defined(__BORLANDC__) || defined(__POCC__) || defined(__SALFORDC__)
|
||||||
#define SIZEOF_CURL_OFF_T 4
|
#define SIZEOF_CURL_OFF_T 4
|
||||||
#else
|
#else
|
||||||
#define SIZEOF_CURL_OFF_T 8
|
#define SIZEOF_CURL_OFF_T 8
|
||||||
@@ -258,7 +269,9 @@
|
|||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
/* Define this if you have struct sockaddr_storage */
|
/* Define this if you have struct sockaddr_storage */
|
||||||
|
#ifndef __SALFORDC__
|
||||||
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
|
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* COMPILER SPECIFIC */
|
/* COMPILER SPECIFIC */
|
||||||
|
@@ -54,6 +54,9 @@
|
|||||||
/* Define if you have the <stdlib.h> header file. */
|
/* Define if you have the <stdlib.h> header file. */
|
||||||
#define HAVE_STDLIB_H 1
|
#define HAVE_STDLIB_H 1
|
||||||
|
|
||||||
|
/* Define if you have the <process.h> header file. */
|
||||||
|
#define HAVE_PROCESS_H 1
|
||||||
|
|
||||||
/* Define if you have the <sys/param.h> header file. */
|
/* Define if you have the <sys/param.h> header file. */
|
||||||
/* #define HAVE_SYS_PARAM_H 1 */
|
/* #define HAVE_SYS_PARAM_H 1 */
|
||||||
|
|
||||||
@@ -277,7 +280,7 @@
|
|||||||
#define PACKAGE "curl"
|
#define PACKAGE "curl"
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* WinCE */
|
/* WinCE */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
#define CURL_DISABLE_FILE 1
|
#define CURL_DISABLE_FILE 1
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#define HAVE_NETINET_IN_H 1
|
#define HAVE_NETINET_IN_H 1
|
||||||
#define HAVE_NETINET_TCP_H 1
|
#define HAVE_NETINET_TCP_H 1
|
||||||
#define HAVE_NET_IF_H 1
|
#define HAVE_NET_IF_H 1
|
||||||
|
#define HAVE_PROCESS_H 1
|
||||||
#define HAVE_PERROR 1
|
#define HAVE_PERROR 1
|
||||||
#define HAVE_SELECT 1
|
#define HAVE_SELECT 1
|
||||||
#define HAVE_SETJMP_H 1
|
#define HAVE_SETJMP_H 1
|
||||||
|
@@ -98,7 +98,9 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "select.h"
|
#include "select.h"
|
||||||
#include "url.h" /* for Curl_safefree() */
|
#include "url.h" /* for Curl_safefree() */
|
||||||
|
#include "multiif.h"
|
||||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||||
|
#include "inet_ntop.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
@@ -112,13 +114,13 @@ singleipconnect(struct connectdata *conn,
|
|||||||
bool *connected);
|
bool *connected);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_ourerrno() returns the errno (or equivalent) on this platform to
|
* Curl_sockerrno() returns the *socket-related* errno (or equivalent) on this
|
||||||
* hide platform specific for the function that calls this.
|
* platform to hide platform specific for the function that calls this.
|
||||||
*/
|
*/
|
||||||
int Curl_ourerrno(void)
|
int Curl_sockerrno(void)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
return (int)GetLastError();
|
return (int)WSAGetLastError();
|
||||||
#else
|
#else
|
||||||
return errno;
|
return errno;
|
||||||
#endif
|
#endif
|
||||||
@@ -287,8 +289,14 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
(void)Curl_wait_for_resolv(conn, &h);
|
(void)Curl_wait_for_resolv(conn, &h);
|
||||||
|
|
||||||
if(h) {
|
if(h) {
|
||||||
/* we know data->set.device is shorter than the myhost array */
|
if(in == CURL_INADDR_NONE)
|
||||||
strcpy(myhost, data->set.device);
|
/* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */
|
||||||
|
Curl_inet_ntop(h->addr->ai_addr->sa_family,
|
||||||
|
&((struct sockaddr_in*)h->addr->ai_addr)->sin_addr,
|
||||||
|
myhost, sizeof myhost);
|
||||||
|
else
|
||||||
|
/* we know data->set.device is shorter than the myhost array */
|
||||||
|
strcpy(myhost, data->set.device);
|
||||||
Curl_resolv_unlock(data, h);
|
Curl_resolv_unlock(data, h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -322,7 +330,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
|
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||||
data->set.device, strlen(data->set.device)+1) != 0) {
|
data->set.device, strlen(data->set.device)+1) != 0) {
|
||||||
/* printf("Failed to BINDTODEVICE, socket: %d device: %s error: %s\n",
|
/* printf("Failed to BINDTODEVICE, socket: %d device: %s error: %s\n",
|
||||||
sockfd, data->set.device, Curl_strerror(Curl_ourerrno())); */
|
sockfd, data->set.device, Curl_strerror(Curl_sockerrno())); */
|
||||||
infof(data, "SO_BINDTODEVICE %s failed\n",
|
infof(data, "SO_BINDTODEVICE %s failed\n",
|
||||||
data->set.device);
|
data->set.device);
|
||||||
/* This is typically "errno 1, error: Operation not permitted" if
|
/* This is typically "errno 1, error: Operation not permitted" if
|
||||||
@@ -374,7 +382,6 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
if( bind(sockfd, sock, socksize) >= 0) {
|
if( bind(sockfd, sock, socksize) >= 0) {
|
||||||
/* we succeeded to bind */
|
/* we succeeded to bind */
|
||||||
struct Curl_sockaddr_storage add;
|
struct Curl_sockaddr_storage add;
|
||||||
unsigned short port = 0;
|
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
size = sizeof(add);
|
size = sizeof(add);
|
||||||
@@ -383,6 +390,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
failf(data, "getsockname() failed");
|
failf(data, "getsockname() failed");
|
||||||
return CURLE_HTTP_PORT_FAILED;
|
return CURLE_HTTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
/* We re-use/clobber the port variable here below */
|
||||||
if(((struct sockaddr *)&add)->sa_family == AF_INET)
|
if(((struct sockaddr *)&add)->sa_family == AF_INET)
|
||||||
port = ntohs(((struct sockaddr_in *)&add)->sin_port);
|
port = ntohs(((struct sockaddr_in *)&add)->sin_port);
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
@@ -400,7 +408,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
break;
|
break;
|
||||||
} while(1);
|
} while(1);
|
||||||
|
|
||||||
data->state.os_errno = Curl_ourerrno();
|
data->state.os_errno = Curl_sockerrno();
|
||||||
failf(data, "bind failure: %s",
|
failf(data, "bind failure: %s",
|
||||||
Curl_strerror(conn, data->state.os_errno));
|
Curl_strerror(conn, data->state.os_errno));
|
||||||
return CURLE_HTTP_PORT_FAILED;
|
return CURLE_HTTP_PORT_FAILED;
|
||||||
@@ -444,7 +452,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
|
|||||||
|
|
||||||
if( -1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
|
if( -1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
|
||||||
(void *)&err, &errSize))
|
(void *)&err, &errSize))
|
||||||
err = Curl_ourerrno();
|
err = Curl_sockerrno();
|
||||||
|
|
||||||
#ifdef _WIN32_WCE
|
#ifdef _WIN32_WCE
|
||||||
/* Always returns this error, bug in CE? */
|
/* Always returns this error, bug in CE? */
|
||||||
@@ -463,7 +471,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
|
|||||||
#else
|
#else
|
||||||
(void)sockfd;
|
(void)sockfd;
|
||||||
if (error)
|
if (error)
|
||||||
*error = Curl_ourerrno();
|
*error = Curl_sockerrno();
|
||||||
#endif
|
#endif
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -534,6 +542,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
CURLcode code = CURLE_OK;
|
CURLcode code = CURLE_OK;
|
||||||
curl_socket_t sockfd = conn->sock[sockindex];
|
curl_socket_t sockfd = conn->sock[sockindex];
|
||||||
long allow = DEFAULT_CONNECT_TIMEOUT;
|
long allow = DEFAULT_CONNECT_TIMEOUT;
|
||||||
|
long allow_total = 0;
|
||||||
long has_passed;
|
long has_passed;
|
||||||
|
|
||||||
curlassert(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
|
curlassert(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
|
||||||
@@ -546,12 +555,12 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
/* subtract the most strict timeout of the ones */
|
/* subtract the most strict timeout of the ones */
|
||||||
if(data->set.timeout && data->set.connecttimeout) {
|
if(data->set.timeout && data->set.connecttimeout) {
|
||||||
if (data->set.timeout < data->set.connecttimeout)
|
if (data->set.timeout < data->set.connecttimeout)
|
||||||
allow = data->set.timeout*1000;
|
allow_total = allow = data->set.timeout*1000;
|
||||||
else
|
else
|
||||||
allow = data->set.connecttimeout*1000;
|
allow = data->set.connecttimeout*1000;
|
||||||
}
|
}
|
||||||
else if(data->set.timeout) {
|
else if(data->set.timeout) {
|
||||||
allow = data->set.timeout*1000;
|
allow_total = allow = data->set.timeout*1000;
|
||||||
}
|
}
|
||||||
else if(data->set.connecttimeout) {
|
else if(data->set.connecttimeout) {
|
||||||
allow = data->set.connecttimeout*1000;
|
allow = data->set.connecttimeout*1000;
|
||||||
@@ -564,10 +573,13 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
if(conn->bits.tcpconnect) {
|
if(conn->bits.tcpconnect) {
|
||||||
/* we are connected already! */
|
/* we are connected already! */
|
||||||
|
Curl_expire(data, allow_total);
|
||||||
*connected = TRUE;
|
*connected = TRUE;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_expire(data, allow);
|
||||||
|
|
||||||
/* check for connect without timeout as we want to return immediately */
|
/* check for connect without timeout as we want to return immediately */
|
||||||
rc = waitconnect(sockfd, 0);
|
rc = waitconnect(sockfd, 0);
|
||||||
|
|
||||||
@@ -598,7 +610,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
infof(data, "Connection failed\n");
|
infof(data, "Connection failed\n");
|
||||||
|
|
||||||
if(trynextip(conn, sockindex, connected)) {
|
if(trynextip(conn, sockindex, connected)) {
|
||||||
error = Curl_ourerrno();
|
error = Curl_sockerrno();
|
||||||
data->state.os_errno = error;
|
data->state.os_errno = error;
|
||||||
failf(data, "Failed connect to %s:%d; %s",
|
failf(data, "Failed connect to %s:%d; %s",
|
||||||
conn->host.name, conn->port, Curl_strerror(conn,error));
|
conn->host.name, conn->port, Curl_strerror(conn,error));
|
||||||
@@ -630,7 +642,7 @@ static void tcpnodelay(struct connectdata *conn,
|
|||||||
if(setsockopt(sockfd, proto, TCP_NODELAY, (void *)&onoff,
|
if(setsockopt(sockfd, proto, TCP_NODELAY, (void *)&onoff,
|
||||||
sizeof(onoff)) < 0)
|
sizeof(onoff)) < 0)
|
||||||
infof(data, "Could not set TCP_NODELAY: %s\n",
|
infof(data, "Could not set TCP_NODELAY: %s\n",
|
||||||
Curl_strerror(conn, Curl_ourerrno()));
|
Curl_strerror(conn, Curl_sockerrno()));
|
||||||
else
|
else
|
||||||
infof(data,"TCP_NODELAY set\n");
|
infof(data,"TCP_NODELAY set\n");
|
||||||
#else
|
#else
|
||||||
@@ -652,7 +664,7 @@ static void nosigpipe(struct connectdata *conn,
|
|||||||
if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
|
if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
|
||||||
sizeof(onoff)) < 0)
|
sizeof(onoff)) < 0)
|
||||||
infof(data, "Could not set SO_NOSIGPIPE: %s\n",
|
infof(data, "Could not set SO_NOSIGPIPE: %s\n",
|
||||||
Curl_strerror(conn, Curl_ourerrno()));
|
Curl_strerror(conn, Curl_sockerrno()));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define nosigpipe(x,y)
|
#define nosigpipe(x,y)
|
||||||
@@ -705,7 +717,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
if(-1 == rc) {
|
if(-1 == rc) {
|
||||||
error = Curl_ourerrno();
|
error = Curl_sockerrno();
|
||||||
|
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case EINPROGRESS:
|
case EINPROGRESS:
|
||||||
@@ -818,6 +830,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
return CURLE_OPERATION_TIMEOUTED;
|
return CURLE_OPERATION_TIMEOUTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Curl_expire(data, timeout_ms);
|
||||||
|
|
||||||
/* Max time for each address */
|
/* Max time for each address */
|
||||||
num_addr = Curl_num_addresses(remotehost->addr);
|
num_addr = Curl_num_addresses(remotehost->addr);
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -37,7 +37,7 @@ CURLcode Curl_connecthost(struct connectdata *conn,
|
|||||||
bool *connected /* truly connected? */
|
bool *connected /* truly connected? */
|
||||||
);
|
);
|
||||||
|
|
||||||
int Curl_ourerrno(void);
|
int Curl_sockerrno(void);
|
||||||
|
|
||||||
CURLcode Curl_store_ip_addr(struct connectdata *conn);
|
CURLcode Curl_store_ip_addr(struct connectdata *conn);
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -87,7 +87,10 @@ static CURLcode
|
|||||||
inflate_stream(struct SessionHandle *data,
|
inflate_stream(struct SessionHandle *data,
|
||||||
struct Curl_transfer_keeper *k)
|
struct Curl_transfer_keeper *k)
|
||||||
{
|
{
|
||||||
|
int allow_restart = 1;
|
||||||
z_stream *z = &k->z; /* zlib state structure */
|
z_stream *z = &k->z; /* zlib state structure */
|
||||||
|
uInt nread = z->avail_in;
|
||||||
|
Bytef *orig_in = z->next_in;
|
||||||
int status; /* zlib status */
|
int status; /* zlib status */
|
||||||
CURLcode result = CURLE_OK; /* Curl_client_write status */
|
CURLcode result = CURLE_OK; /* Curl_client_write status */
|
||||||
char *decomp; /* Put the decompressed data here. */
|
char *decomp; /* Put the decompressed data here. */
|
||||||
@@ -108,6 +111,7 @@ inflate_stream(struct SessionHandle *data,
|
|||||||
|
|
||||||
status = inflate(z, Z_SYNC_FLUSH);
|
status = inflate(z, Z_SYNC_FLUSH);
|
||||||
if (status == Z_OK || status == Z_STREAM_END) {
|
if (status == Z_OK || status == Z_STREAM_END) {
|
||||||
|
allow_restart = 0;
|
||||||
if(DSIZ - z->avail_out) {
|
if(DSIZ - z->avail_out) {
|
||||||
result = Curl_client_write(data, CLIENTWRITE_BODY, decomp,
|
result = Curl_client_write(data, CLIENTWRITE_BODY, decomp,
|
||||||
DSIZ - z->avail_out);
|
DSIZ - z->avail_out);
|
||||||
@@ -133,6 +137,19 @@ inflate_stream(struct SessionHandle *data,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (allow_restart && status == Z_DATA_ERROR) {
|
||||||
|
/* some servers seem to not generate zlib headers, so this is an attempt
|
||||||
|
to fix and continue anyway */
|
||||||
|
|
||||||
|
inflateReset(z);
|
||||||
|
if (inflateInit2(z, -MAX_WBITS) != Z_OK) {
|
||||||
|
return process_zlib_error(data, z);
|
||||||
|
}
|
||||||
|
z->next_in = orig_in;
|
||||||
|
z->avail_in = nread;
|
||||||
|
allow_restart = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else { /* Error; exit loop, handle below */
|
else { /* Error; exit loop, handle below */
|
||||||
free(decomp);
|
free(decomp);
|
||||||
return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
|
return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
|
||||||
|
230
lib/cookie.c
230
lib/cookie.c
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -733,68 +733,81 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
|||||||
struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||||
char *host, char *path, bool secure)
|
char *host, char *path, bool secure)
|
||||||
{
|
{
|
||||||
struct Cookie *newco;
|
struct Cookie *newco;
|
||||||
struct Cookie *co;
|
struct Cookie *co;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
struct Cookie *mainco=NULL;
|
struct Cookie *mainco=NULL;
|
||||||
|
|
||||||
if(!c || !c->cookies)
|
if(!c || !c->cookies)
|
||||||
return NULL; /* no cookie struct or no cookies in the struct */
|
return NULL; /* no cookie struct or no cookies in the struct */
|
||||||
|
|
||||||
co = c->cookies;
|
co = c->cookies;
|
||||||
|
|
||||||
while(co) {
|
while(co) {
|
||||||
/* only process this cookie if it is not expired or had no expire
|
/* only process this cookie if it is not expired or had no expire
|
||||||
date AND that if the cookie requires we're secure we must only
|
date AND that if the cookie requires we're secure we must only
|
||||||
continue if we are! */
|
continue if we are! */
|
||||||
if( (co->expires<=0 || (co->expires> now)) &&
|
if( (co->expires<=0 || (co->expires> now)) &&
|
||||||
(co->secure?secure:TRUE) ) {
|
(co->secure?secure:TRUE) ) {
|
||||||
|
|
||||||
/* now check if the domain is correct */
|
/* now check if the domain is correct */
|
||||||
if(!co->domain ||
|
if(!co->domain ||
|
||||||
(co->tailmatch && tailmatch(co->domain, host)) ||
|
(co->tailmatch && tailmatch(co->domain, host)) ||
|
||||||
(!co->tailmatch && strequal(host, co->domain)) ) {
|
(!co->tailmatch && strequal(host, co->domain)) ) {
|
||||||
/* the right part of the host matches the domain stuff in the
|
/* the right part of the host matches the domain stuff in the
|
||||||
cookie data */
|
cookie data */
|
||||||
|
|
||||||
/* now check the left part of the path with the cookies path
|
/* now check the left part of the path with the cookies path
|
||||||
requirement */
|
requirement */
|
||||||
if(!co->path ||
|
if(!co->path ||
|
||||||
checkprefix(co->path, path) ) {
|
checkprefix(co->path, path) ) {
|
||||||
|
|
||||||
/* and now, we know this is a match and we should create an
|
/* and now, we know this is a match and we should create an
|
||||||
entry for the return-linked-list */
|
entry for the return-linked-list */
|
||||||
|
|
||||||
newco = (struct Cookie *)malloc(sizeof(struct Cookie));
|
newco = (struct Cookie *)malloc(sizeof(struct Cookie));
|
||||||
if(newco) {
|
if(newco) {
|
||||||
/* first, copy the whole source cookie: */
|
/* first, copy the whole source cookie: */
|
||||||
memcpy(newco, co, sizeof(struct Cookie));
|
memcpy(newco, co, sizeof(struct Cookie));
|
||||||
|
|
||||||
/* then modify our next */
|
/* then modify our next */
|
||||||
newco->next = mainco;
|
newco->next = mainco;
|
||||||
|
|
||||||
/* point the main to us */
|
/* point the main to us */
|
||||||
mainco = newco;
|
mainco = newco;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* failure, clear up the allocated chain and return NULL */
|
/* failure, clear up the allocated chain and return NULL */
|
||||||
while(mainco) {
|
while(mainco) {
|
||||||
co = mainco->next;
|
co = mainco->next;
|
||||||
free(mainco);
|
free(mainco);
|
||||||
mainco = co;
|
mainco = co;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
co = co->next;
|
co = co->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mainco; /* return the new list */
|
return mainco; /* return the new list */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* Curl_cookie_clearall()
|
||||||
|
*
|
||||||
|
* Clear all existing cookies and reset the counter.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
void Curl_cookie_clearall(struct CookieInfo *cookies)
|
||||||
|
{
|
||||||
|
Curl_cookie_freelist(cookies->cookies);
|
||||||
|
cookies->cookies = NULL;
|
||||||
|
cookies->numcookies = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
@@ -806,17 +819,56 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
|||||||
|
|
||||||
void Curl_cookie_freelist(struct Cookie *co)
|
void Curl_cookie_freelist(struct Cookie *co)
|
||||||
{
|
{
|
||||||
struct Cookie *next;
|
struct Cookie *next;
|
||||||
if(co) {
|
if(co) {
|
||||||
while(co) {
|
while(co) {
|
||||||
next = co->next;
|
next = co->next;
|
||||||
free(co); /* we only free the struct since the "members" are all
|
free(co); /* we only free the struct since the "members" are all
|
||||||
just copied! */
|
just copied! */
|
||||||
co = next;
|
co = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* Curl_cookie_clearsess()
|
||||||
|
*
|
||||||
|
* Free all session cookies in the cookies list.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
void Curl_cookie_clearsess(struct CookieInfo *cookies)
|
||||||
|
{
|
||||||
|
struct Cookie *first, *curr, *next, *prev = NULL;
|
||||||
|
|
||||||
|
if(!cookies->cookies)
|
||||||
|
return;
|
||||||
|
|
||||||
|
first = curr = prev = cookies->cookies;
|
||||||
|
|
||||||
|
for(; curr; curr = next) {
|
||||||
|
next = curr->next;
|
||||||
|
if(!curr->expires) {
|
||||||
|
if(first == curr)
|
||||||
|
first = next;
|
||||||
|
|
||||||
|
if(prev == curr)
|
||||||
|
prev = next;
|
||||||
|
else
|
||||||
|
prev->next = next;
|
||||||
|
|
||||||
|
free(curr);
|
||||||
|
cookies->numcookies--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
prev = curr;
|
||||||
|
}
|
||||||
|
|
||||||
|
cookies->cookies = first;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* Curl_cookie_cleanup()
|
* Curl_cookie_cleanup()
|
||||||
@@ -826,20 +878,20 @@ void Curl_cookie_freelist(struct Cookie *co)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void Curl_cookie_cleanup(struct CookieInfo *c)
|
void Curl_cookie_cleanup(struct CookieInfo *c)
|
||||||
{
|
{
|
||||||
struct Cookie *co;
|
struct Cookie *co;
|
||||||
struct Cookie *next;
|
struct Cookie *next;
|
||||||
if(c) {
|
if(c) {
|
||||||
if(c->filename)
|
if(c->filename)
|
||||||
free(c->filename);
|
free(c->filename);
|
||||||
co = c->cookies;
|
co = c->cookies;
|
||||||
|
|
||||||
while(co) {
|
while(co) {
|
||||||
next = co->next;
|
next = co->next;
|
||||||
freecookie(co);
|
freecookie(co);
|
||||||
co = next;
|
co = next;
|
||||||
}
|
}
|
||||||
free(c); /* free the base struct as well */
|
free(c); /* free the base struct as well */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get_netscape_format()
|
/* get_netscape_format()
|
||||||
@@ -850,24 +902,24 @@ void Curl_cookie_cleanup(struct CookieInfo *c)
|
|||||||
*/
|
*/
|
||||||
static char *get_netscape_format(const struct Cookie *co)
|
static char *get_netscape_format(const struct Cookie *co)
|
||||||
{
|
{
|
||||||
return aprintf(
|
return aprintf(
|
||||||
"%s%s\t" /* domain */
|
"%s%s\t" /* domain */
|
||||||
"%s\t" /* tailmatch */
|
"%s\t" /* tailmatch */
|
||||||
"%s\t" /* path */
|
"%s\t" /* path */
|
||||||
"%s\t" /* secure */
|
"%s\t" /* secure */
|
||||||
"%" FORMAT_OFF_T "\t" /* expires */
|
"%" FORMAT_OFF_T "\t" /* expires */
|
||||||
"%s\t" /* name */
|
"%s\t" /* name */
|
||||||
"%s", /* value */
|
"%s", /* value */
|
||||||
/* Make sure all domains are prefixed with a dot if they allow
|
/* Make sure all domains are prefixed with a dot if they allow
|
||||||
tailmatching. This is Mozilla-style. */
|
tailmatching. This is Mozilla-style. */
|
||||||
(co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
|
(co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
|
||||||
co->domain?co->domain:"unknown",
|
co->domain?co->domain:"unknown",
|
||||||
co->tailmatch?"TRUE":"FALSE",
|
co->tailmatch?"TRUE":"FALSE",
|
||||||
co->path?co->path:"/",
|
co->path?co->path:"/",
|
||||||
co->secure?"TRUE":"FALSE",
|
co->secure?"TRUE":"FALSE",
|
||||||
co->expires,
|
co->expires,
|
||||||
co->name,
|
co->name,
|
||||||
co->value?co->value:"");
|
co->value?co->value:"");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -89,6 +89,8 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
|||||||
char *, struct CookieInfo *, bool);
|
char *, struct CookieInfo *, bool);
|
||||||
struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool);
|
struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool);
|
||||||
void Curl_cookie_freelist(struct Cookie *);
|
void Curl_cookie_freelist(struct Cookie *);
|
||||||
|
void Curl_cookie_clearall(struct CookieInfo *cookies);
|
||||||
|
void Curl_cookie_clearsess(struct CookieInfo *cookies);
|
||||||
void Curl_cookie_cleanup(struct CookieInfo *);
|
void Curl_cookie_cleanup(struct CookieInfo *);
|
||||||
int Curl_cookie_output(struct CookieInfo *, char *);
|
int Curl_cookie_output(struct CookieInfo *, char *);
|
||||||
|
|
||||||
|
59
lib/dict.c
59
lib/dict.c
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -38,8 +38,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
@@ -85,9 +83,46 @@
|
|||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
|
/* The last #include file should be: */
|
||||||
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
static char *unescape_word(struct SessionHandle *data, char *inp)
|
||||||
|
{
|
||||||
|
char *newp;
|
||||||
|
char *dictp;
|
||||||
|
char *ptr;
|
||||||
|
int len;
|
||||||
|
unsigned char byte;
|
||||||
|
int olen=0;
|
||||||
|
|
||||||
|
newp = curl_easy_unescape(data, inp, 0, &len);
|
||||||
|
if(!newp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dictp = malloc(len*2 + 1); /* add one for terminating zero */
|
||||||
|
if(dictp) {
|
||||||
|
/* According to RFC2229 section 2.2, these letters need to be escaped with
|
||||||
|
\[letter] */
|
||||||
|
for(ptr = newp;
|
||||||
|
(byte = (unsigned char)*ptr);
|
||||||
|
ptr++) {
|
||||||
|
if ((byte <= 32) || (byte == 127) ||
|
||||||
|
(byte == '\'') || (byte == '\"') || (byte == '\\')) {
|
||||||
|
dictp[olen++] = '\\';
|
||||||
|
}
|
||||||
|
dictp[olen++] = byte;
|
||||||
|
}
|
||||||
|
dictp[olen]=0;
|
||||||
|
|
||||||
|
free(newp);
|
||||||
|
}
|
||||||
|
return dictp;
|
||||||
|
}
|
||||||
|
|
||||||
CURLcode Curl_dict(struct connectdata *conn, bool *done)
|
CURLcode Curl_dict(struct connectdata *conn, bool *done)
|
||||||
{
|
{
|
||||||
char *word;
|
char *word;
|
||||||
|
char *eword;
|
||||||
char *ppath;
|
char *ppath;
|
||||||
char *database = NULL;
|
char *database = NULL;
|
||||||
char *strategy = NULL;
|
char *strategy = NULL;
|
||||||
@@ -137,6 +172,10 @@ CURLcode Curl_dict(struct connectdata *conn, bool *done)
|
|||||||
strategy = (char *)".";
|
strategy = (char *)".";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eword = unescape_word(data, word);
|
||||||
|
if(!eword)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
result = Curl_sendf(sockfd, conn,
|
result = Curl_sendf(sockfd, conn,
|
||||||
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
|
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
|
||||||
"MATCH "
|
"MATCH "
|
||||||
@@ -147,8 +186,11 @@ CURLcode Curl_dict(struct connectdata *conn, bool *done)
|
|||||||
|
|
||||||
database,
|
database,
|
||||||
strategy,
|
strategy,
|
||||||
word
|
eword
|
||||||
);
|
);
|
||||||
|
|
||||||
|
free(eword);
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
failf(data, "Failed sending DICT request");
|
failf(data, "Failed sending DICT request");
|
||||||
else
|
else
|
||||||
@@ -181,6 +223,10 @@ CURLcode Curl_dict(struct connectdata *conn, bool *done)
|
|||||||
database = (char *)"!";
|
database = (char *)"!";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eword = unescape_word(data, word);
|
||||||
|
if(!eword)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
result = Curl_sendf(sockfd, conn,
|
result = Curl_sendf(sockfd, conn,
|
||||||
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
|
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
|
||||||
"DEFINE "
|
"DEFINE "
|
||||||
@@ -188,7 +234,10 @@ CURLcode Curl_dict(struct connectdata *conn, bool *done)
|
|||||||
"%s\r\n" /* word */
|
"%s\r\n" /* word */
|
||||||
"QUIT\r\n",
|
"QUIT\r\n",
|
||||||
database,
|
database,
|
||||||
word);
|
eword);
|
||||||
|
|
||||||
|
free(eword);
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
failf(data, "Failed sending DICT request");
|
failf(data, "Failed sending DICT request");
|
||||||
else
|
else
|
||||||
|
189
lib/easy.c
189
lib/easy.c
@@ -83,10 +83,22 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "progress.h"
|
#include "progress.h"
|
||||||
#include "easyif.h"
|
#include "easyif.h"
|
||||||
|
#include "sendf.h" /* for failf function prototype */
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
|
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
|
||||||
|
#include <iconv.h>
|
||||||
|
/* set default codesets for iconv */
|
||||||
|
#ifndef CURL_ICONV_CODESET_OF_NETWORK
|
||||||
|
#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
|
||||||
|
#endif
|
||||||
|
#ifndef CURL_ICONV_CODESET_FOR_UTF8
|
||||||
|
#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
|
||||||
|
#endif
|
||||||
|
#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
@@ -656,3 +668,180 @@ void curl_easy_reset(CURL *curl)
|
|||||||
data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
|
data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CURL_DOES_CONVERSIONS
|
||||||
|
/*
|
||||||
|
* Curl_convert_to_network() is an internal function
|
||||||
|
* for performing ASCII conversions on non-ASCII platforms.
|
||||||
|
*/
|
||||||
|
CURLcode Curl_convert_to_network(struct SessionHandle *data,
|
||||||
|
char *buffer, size_t length)
|
||||||
|
{
|
||||||
|
CURLcode rc;
|
||||||
|
|
||||||
|
if(data->set.convtonetwork) {
|
||||||
|
/* use translation callback */
|
||||||
|
rc = data->set.convtonetwork(buffer, length);
|
||||||
|
if(rc != CURLE_OK) {
|
||||||
|
failf(data,
|
||||||
|
"CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %i: %s",
|
||||||
|
rc, curl_easy_strerror(rc));
|
||||||
|
}
|
||||||
|
return(rc);
|
||||||
|
} else {
|
||||||
|
#ifdef HAVE_ICONV
|
||||||
|
/* do the translation ourselves */
|
||||||
|
char *input_ptr, *output_ptr;
|
||||||
|
size_t in_bytes, out_bytes, rc;
|
||||||
|
|
||||||
|
/* open an iconv conversion descriptor if necessary */
|
||||||
|
if(data->outbound_cd == (iconv_t)-1) {
|
||||||
|
data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
|
||||||
|
CURL_ICONV_CODESET_OF_HOST);
|
||||||
|
if(data->outbound_cd == (iconv_t)-1) {
|
||||||
|
failf(data,
|
||||||
|
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||||
|
CURL_ICONV_CODESET_OF_NETWORK,
|
||||||
|
CURL_ICONV_CODESET_OF_HOST,
|
||||||
|
errno, strerror(errno));
|
||||||
|
return CURLE_CONV_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* call iconv */
|
||||||
|
input_ptr = output_ptr = buffer;
|
||||||
|
in_bytes = out_bytes = length;
|
||||||
|
rc = iconv(data->outbound_cd, &input_ptr, &in_bytes,
|
||||||
|
&output_ptr, &out_bytes);
|
||||||
|
if ((rc == -1) || (in_bytes != 0)) {
|
||||||
|
failf(data,
|
||||||
|
"The Curl_convert_to_network iconv call failed with errno %i: %s",
|
||||||
|
errno, strerror(errno));
|
||||||
|
return CURLE_CONV_FAILED;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
|
||||||
|
return CURLE_CONV_REQD;
|
||||||
|
#endif /* HAVE_ICONV */
|
||||||
|
}
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_convert_from_network() is an internal function
|
||||||
|
* for performing ASCII conversions on non-ASCII platforms.
|
||||||
|
*/
|
||||||
|
CURLcode Curl_convert_from_network(struct SessionHandle *data,
|
||||||
|
char *buffer, size_t length)
|
||||||
|
{
|
||||||
|
CURLcode rc;
|
||||||
|
|
||||||
|
if(data->set.convfromnetwork) {
|
||||||
|
/* use translation callback */
|
||||||
|
rc = data->set.convfromnetwork(buffer, length);
|
||||||
|
if(rc != CURLE_OK) {
|
||||||
|
failf(data,
|
||||||
|
"CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %i: %s",
|
||||||
|
rc, curl_easy_strerror(rc));
|
||||||
|
}
|
||||||
|
return(rc);
|
||||||
|
} else {
|
||||||
|
#ifdef HAVE_ICONV
|
||||||
|
/* do the translation ourselves */
|
||||||
|
char *input_ptr, *output_ptr;
|
||||||
|
size_t in_bytes, out_bytes, rc;
|
||||||
|
|
||||||
|
/* open an iconv conversion descriptor if necessary */
|
||||||
|
if(data->inbound_cd == (iconv_t)-1) {
|
||||||
|
data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||||
|
CURL_ICONV_CODESET_OF_NETWORK);
|
||||||
|
if(data->inbound_cd == (iconv_t)-1) {
|
||||||
|
failf(data,
|
||||||
|
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||||
|
CURL_ICONV_CODESET_OF_HOST,
|
||||||
|
CURL_ICONV_CODESET_OF_NETWORK,
|
||||||
|
errno, strerror(errno));
|
||||||
|
return CURLE_CONV_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* call iconv */
|
||||||
|
input_ptr = output_ptr = buffer;
|
||||||
|
in_bytes = out_bytes = length;
|
||||||
|
rc = iconv(data->inbound_cd, &input_ptr, &in_bytes,
|
||||||
|
&output_ptr, &out_bytes);
|
||||||
|
if ((rc == -1) || (in_bytes != 0)) {
|
||||||
|
failf(data,
|
||||||
|
"The Curl_convert_from_network iconv call failed with errno %i: %s",
|
||||||
|
errno, strerror(errno));
|
||||||
|
return CURLE_CONV_FAILED;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
|
||||||
|
return CURLE_CONV_REQD;
|
||||||
|
#endif /* HAVE_ICONV */
|
||||||
|
}
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_convert_from_utf8() is an internal function
|
||||||
|
* for performing UTF-8 conversions on non-ASCII platforms.
|
||||||
|
*/
|
||||||
|
CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
|
||||||
|
char *buffer, size_t length)
|
||||||
|
{
|
||||||
|
CURLcode rc;
|
||||||
|
|
||||||
|
if(data->set.convfromutf8) {
|
||||||
|
/* use translation callback */
|
||||||
|
rc = data->set.convfromutf8(buffer, length);
|
||||||
|
if(rc != CURLE_OK) {
|
||||||
|
failf(data,
|
||||||
|
"CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %i: %s",
|
||||||
|
rc, curl_easy_strerror(rc));
|
||||||
|
}
|
||||||
|
return(rc);
|
||||||
|
} else {
|
||||||
|
#ifdef HAVE_ICONV
|
||||||
|
/* do the translation ourselves */
|
||||||
|
char *input_ptr, *output_ptr;
|
||||||
|
size_t in_bytes, out_bytes, rc;
|
||||||
|
|
||||||
|
/* open an iconv conversion descriptor if necessary */
|
||||||
|
if(data->utf8_cd == (iconv_t)-1) {
|
||||||
|
data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
|
||||||
|
CURL_ICONV_CODESET_FOR_UTF8);
|
||||||
|
if(data->utf8_cd == (iconv_t)-1) {
|
||||||
|
failf(data,
|
||||||
|
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
|
||||||
|
CURL_ICONV_CODESET_OF_HOST,
|
||||||
|
CURL_ICONV_CODESET_FOR_UTF8,
|
||||||
|
errno, strerror(errno));
|
||||||
|
return CURLE_CONV_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* call iconv */
|
||||||
|
input_ptr = output_ptr = buffer;
|
||||||
|
in_bytes = out_bytes = length;
|
||||||
|
rc = iconv(data->utf8_cd, &input_ptr, &in_bytes, &output_ptr, &out_bytes);
|
||||||
|
if ((rc == -1) || (in_bytes != 0)) {
|
||||||
|
failf(data,
|
||||||
|
"The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
|
||||||
|
errno, strerror(errno));
|
||||||
|
return CURLE_CONV_FAILED;
|
||||||
|
}
|
||||||
|
if (output_ptr < input_ptr) {
|
||||||
|
/* null terminate the now shorter output string */
|
||||||
|
*output_ptr = 0x00;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
|
||||||
|
return CURLE_CONV_REQD;
|
||||||
|
#endif /* HAVE_ICONV */
|
||||||
|
}
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CURL_DOES_CONVERSIONS */
|
||||||
|
@@ -28,4 +28,11 @@
|
|||||||
*/
|
*/
|
||||||
void Curl_easy_addmulti(struct SessionHandle *data, void *multi);
|
void Curl_easy_addmulti(struct SessionHandle *data, void *multi);
|
||||||
|
|
||||||
|
CURLcode Curl_convert_to_network(struct SessionHandle *data,
|
||||||
|
char *buffer, size_t length);
|
||||||
|
CURLcode Curl_convert_from_network(struct SessionHandle *data,
|
||||||
|
char *buffer, size_t length);
|
||||||
|
CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
|
||||||
|
char *buffer, size_t length);
|
||||||
|
|
||||||
#endif /* __EASYIF_H */
|
#endif /* __EASYIF_H */
|
||||||
|
54
lib/escape.c
54
lib/escape.c
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -32,6 +32,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
/* urldata.h and easyif.h are included for Curl_convert_... prototypes */
|
||||||
|
#include "urldata.h"
|
||||||
|
#include "easyif.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -39,7 +42,19 @@
|
|||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
/* for ABI-compatibility with previous versions */
|
||||||
char *curl_escape(const char *string, int inlength)
|
char *curl_escape(const char *string, int inlength)
|
||||||
|
{
|
||||||
|
return curl_easy_escape(NULL, string, inlength);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for ABI-compatibility with previous versions */
|
||||||
|
char *curl_unescape(const char *string, int length)
|
||||||
|
{
|
||||||
|
return curl_easy_unescape(NULL, string, length, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
||||||
{
|
{
|
||||||
size_t alloc = (inlength?(size_t)inlength:strlen(string))+1;
|
size_t alloc = (inlength?(size_t)inlength:strlen(string))+1;
|
||||||
char *ns;
|
char *ns;
|
||||||
@@ -49,6 +64,10 @@ char *curl_escape(const char *string, int inlength)
|
|||||||
int strindex=0;
|
int strindex=0;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|
||||||
|
#ifndef CURL_DOES_CONVERSIONS
|
||||||
|
/* avoid compiler warnings */
|
||||||
|
(void)handle;
|
||||||
|
#endif
|
||||||
ns = malloc(alloc);
|
ns = malloc(alloc);
|
||||||
if(!ns)
|
if(!ns)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -72,6 +91,17 @@ char *curl_escape(const char *string, int inlength)
|
|||||||
ns = testing_ptr;
|
ns = testing_ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CURL_DOES_CONVERSIONS
|
||||||
|
/* escape sequences are always in ASCII so convert them on non-ASCII hosts */
|
||||||
|
if (!handle ||
|
||||||
|
(Curl_convert_to_network(handle, &in, 1) != CURLE_OK)) {
|
||||||
|
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||||
|
free(ns);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif /* CURL_DOES_CONVERSIONS */
|
||||||
|
|
||||||
snprintf(&ns[strindex], 4, "%%%02X", in);
|
snprintf(&ns[strindex], 4, "%%%02X", in);
|
||||||
|
|
||||||
strindex+=3;
|
strindex+=3;
|
||||||
@@ -90,7 +120,8 @@ char *curl_escape(const char *string, int inlength)
|
|||||||
(in >= 'A' && in <= 'F') || \
|
(in >= 'A' && in <= 'F') || \
|
||||||
(in >= '0' && in <= '9'))
|
(in >= '0' && in <= '9'))
|
||||||
|
|
||||||
char *curl_unescape(const char *string, int length)
|
char *curl_easy_unescape(CURL *handle, const char *string, int length,
|
||||||
|
int *olen)
|
||||||
{
|
{
|
||||||
int alloc = (length?length:(int)strlen(string))+1;
|
int alloc = (length?length:(int)strlen(string))+1;
|
||||||
char *ns = malloc(alloc);
|
char *ns = malloc(alloc);
|
||||||
@@ -98,6 +129,10 @@ char *curl_unescape(const char *string, int length)
|
|||||||
int strindex=0;
|
int strindex=0;
|
||||||
long hex;
|
long hex;
|
||||||
|
|
||||||
|
#ifndef CURL_DOES_CONVERSIONS
|
||||||
|
/* avoid compiler warnings */
|
||||||
|
(void)handle;
|
||||||
|
#endif
|
||||||
if( !ns )
|
if( !ns )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -114,6 +149,17 @@ char *curl_unescape(const char *string, int length)
|
|||||||
hex = strtol(hexstr, &ptr, 16);
|
hex = strtol(hexstr, &ptr, 16);
|
||||||
|
|
||||||
in = (unsigned char)hex; /* this long is never bigger than 255 anyway */
|
in = (unsigned char)hex; /* this long is never bigger than 255 anyway */
|
||||||
|
|
||||||
|
#ifdef CURL_DOES_CONVERSIONS
|
||||||
|
/* escape sequences are always in ASCII so convert them on non-ASCII hosts */
|
||||||
|
if (!handle ||
|
||||||
|
(Curl_convert_from_network(handle, &in, 1) != CURLE_OK)) {
|
||||||
|
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||||
|
free(ns);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif /* CURL_DOES_CONVERSIONS */
|
||||||
|
|
||||||
string+=2;
|
string+=2;
|
||||||
alloc-=2;
|
alloc-=2;
|
||||||
}
|
}
|
||||||
@@ -122,6 +168,10 @@ char *curl_unescape(const char *string, int length)
|
|||||||
string++;
|
string++;
|
||||||
}
|
}
|
||||||
ns[strindex]=0; /* terminate it */
|
ns[strindex]=0; /* terminate it */
|
||||||
|
|
||||||
|
if(olen)
|
||||||
|
/* store output size */
|
||||||
|
*olen = strindex;
|
||||||
return ns;
|
return ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -26,7 +26,5 @@
|
|||||||
/* Escape and unescape URL encoding in strings. The functions return a new
|
/* Escape and unescape URL encoding in strings. The functions return a new
|
||||||
* allocated string or NULL if an error occurred. */
|
* allocated string or NULL if an error occurred. */
|
||||||
|
|
||||||
char *curl_escape(const char *string, int length);
|
|
||||||
char *curl_unescape(const char *string, int length);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -37,8 +37,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
@@ -102,7 +100,7 @@
|
|||||||
*/
|
*/
|
||||||
CURLcode Curl_file_connect(struct connectdata *conn)
|
CURLcode Curl_file_connect(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
char *real_path = curl_unescape(conn->path, 0);
|
char *real_path = curl_easy_unescape(conn->data, conn->path, 0, NULL);
|
||||||
struct FILEPROTO *file;
|
struct FILEPROTO *file;
|
||||||
int fd;
|
int fd;
|
||||||
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
|
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
|
||||||
|
@@ -1279,7 +1279,7 @@ static size_t readfromfile(struct Form *form, char *buffer, size_t size)
|
|||||||
/* this file hasn't yet been opened */
|
/* this file hasn't yet been opened */
|
||||||
form->fp = fopen(form->data->line, "rb"); /* b is for binary */
|
form->fp = fopen(form->data->line, "rb"); /* b is for binary */
|
||||||
if(!form->fp)
|
if(!form->fp)
|
||||||
return -1; /* failure */
|
return (size_t)-1; /* failure */
|
||||||
}
|
}
|
||||||
nread = fread(buffer, 1, size, form->fp);
|
nread = fread(buffer, 1, size, form->fp);
|
||||||
|
|
||||||
|
227
lib/ftp.c
227
lib/ftp.c
@@ -29,7 +29,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -60,10 +59,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WIN32) && defined(__GNUC__) || defined(__MINGW32__)
|
|
||||||
#include <errno.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||||
#undef in_addr_t
|
#undef in_addr_t
|
||||||
#define in_addr_t unsigned long
|
#define in_addr_t unsigned long
|
||||||
@@ -72,6 +67,7 @@
|
|||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
|
#include "easyif.h" /* for Curl_convert_... prototypes */
|
||||||
|
|
||||||
#include "if2ip.h"
|
#include "if2ip.h"
|
||||||
#include "hostip.h"
|
#include "hostip.h"
|
||||||
@@ -95,6 +91,7 @@
|
|||||||
#include "select.h"
|
#include "select.h"
|
||||||
#include "parsedate.h" /* for the week day and month names */
|
#include "parsedate.h" /* for the week day and month names */
|
||||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||||
|
#include "multiif.h"
|
||||||
|
|
||||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||||
#include "inet_ntoa_r.h"
|
#include "inet_ntoa_r.h"
|
||||||
@@ -159,12 +156,15 @@ static void freedirs(struct FTP *ftp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns non-zero iff the given string contains CR (0x0D) or LF (0x0A), which
|
/* Returns non-zero if the given string contains CR (\r) or LF (\n),
|
||||||
are not allowed within RFC 959 <string>.
|
which are not allowed within RFC 959 <string>.
|
||||||
*/
|
Note: The input string is in the client's encoding which might
|
||||||
|
not be ASCII, so escape sequences \r & \n must be used instead
|
||||||
|
of hex values 0x0d & 0x0a.
|
||||||
|
*/
|
||||||
static bool isBadFtpString(const char *string)
|
static bool isBadFtpString(const char *string)
|
||||||
{
|
{
|
||||||
return strchr(string, 0x0D) != NULL || strchr(string, 0x0A) != NULL;
|
return strchr(string, '\r') != NULL || strchr(string, '\n') != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@@ -295,6 +295,14 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
|
|||||||
/* EWOULDBLOCK */
|
/* EWOULDBLOCK */
|
||||||
return CURLE_OK; /* return */
|
return CURLE_OK; /* return */
|
||||||
|
|
||||||
|
#ifdef CURL_DOES_CONVERSIONS
|
||||||
|
if((res == CURLE_OK) && (gotbytes > 0)) {
|
||||||
|
/* convert from the network encoding */
|
||||||
|
result = res = Curl_convert_from_network(data, ptr, gotbytes);
|
||||||
|
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||||
|
}
|
||||||
|
#endif /* CURL_DOES_CONVERSIONS */
|
||||||
|
|
||||||
if(CURLE_OK != res)
|
if(CURLE_OK != res)
|
||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
}
|
}
|
||||||
@@ -479,7 +487,8 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
|||||||
switch (Curl_select(sockfd, CURL_SOCKET_BAD, interval_ms)) {
|
switch (Curl_select(sockfd, CURL_SOCKET_BAD, interval_ms)) {
|
||||||
case -1: /* select() error, stop reading */
|
case -1: /* select() error, stop reading */
|
||||||
result = CURLE_RECV_ERROR;
|
result = CURLE_RECV_ERROR;
|
||||||
failf(data, "FTP response aborted due to select() error: %d", errno);
|
failf(data, "FTP response aborted due to select() error: %d",
|
||||||
|
Curl_sockerrno());
|
||||||
break;
|
break;
|
||||||
case 0: /* timeout */
|
case 0: /* timeout */
|
||||||
if(Curl_pgrsUpdate(conn))
|
if(Curl_pgrsUpdate(conn))
|
||||||
@@ -518,6 +527,14 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
|||||||
/* EWOULDBLOCK */
|
/* EWOULDBLOCK */
|
||||||
continue; /* go looping again */
|
continue; /* go looping again */
|
||||||
|
|
||||||
|
#ifdef CURL_DOES_CONVERSIONS
|
||||||
|
if((res == CURLE_OK) && (gotbytes > 0)) {
|
||||||
|
/* convert from the network encoding */
|
||||||
|
result = res = Curl_convert_from_network(data, ptr, gotbytes);
|
||||||
|
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||||
|
}
|
||||||
|
#endif /* CURL_DOES_CONVERSIONS */
|
||||||
|
|
||||||
if(CURLE_OK != res)
|
if(CURLE_OK != res)
|
||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
}
|
}
|
||||||
@@ -698,27 +715,24 @@ static CURLcode ftp_state_pwd(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* For the FTP "protocol connect" and "doing" phases only */
|
/* For the FTP "protocol connect" and "doing" phases only */
|
||||||
CURLcode Curl_ftp_fdset(struct connectdata *conn,
|
int Curl_ftp_getsock(struct connectdata *conn,
|
||||||
fd_set *read_fd_set,
|
curl_socket_t *socks,
|
||||||
fd_set *write_fd_set,
|
int numsocks)
|
||||||
int *max_fdp)
|
|
||||||
{
|
{
|
||||||
struct FTP *ftp = conn->proto.ftp;
|
struct FTP *ftp = conn->proto.ftp;
|
||||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
|
||||||
|
if(!numsocks)
|
||||||
|
return GETSOCK_BLANK;
|
||||||
|
|
||||||
|
socks[0] = conn->sock[FIRSTSOCKET];
|
||||||
|
|
||||||
if(ftp->sendleft) {
|
if(ftp->sendleft) {
|
||||||
/* write mode */
|
/* write mode */
|
||||||
FD_SET(sockfd, write_fd_set);
|
return GETSOCK_WRITESOCK(0);
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* read mode */
|
|
||||||
FD_SET(sockfd, read_fd_set);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if((int)sockfd > *max_fdp)
|
/* read mode */
|
||||||
*max_fdp = (int)sockfd;
|
return GETSOCK_READSOCK(0);
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is called after the FTP_QUOTE state is passed.
|
/* This is called after the FTP_QUOTE state is passed.
|
||||||
@@ -853,7 +867,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
|
|
||||||
portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||||
if (portsock == CURL_SOCKET_BAD) {
|
if (portsock == CURL_SOCKET_BAD) {
|
||||||
error = Curl_ourerrno();
|
error = Curl_sockerrno();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -885,7 +899,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
((struct sockaddr_in6 *)sa)->sin6_port =0;
|
((struct sockaddr_in6 *)sa)->sin6_port =0;
|
||||||
|
|
||||||
if(bind(portsock, (struct sockaddr *)sa, sslen) < 0) {
|
if(bind(portsock, (struct sockaddr *)sa, sslen) < 0) {
|
||||||
failf(data, "bind failed: %s", Curl_strerror(conn, Curl_ourerrno()));
|
failf(data, "bind failed: %s", Curl_strerror(conn, Curl_sockerrno()));
|
||||||
sclose(portsock);
|
sclose(portsock);
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
@@ -896,14 +910,14 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
sslen = sizeof(ss);
|
sslen = sizeof(ss);
|
||||||
if(getsockname(portsock, (struct sockaddr *)sa, &sslen)<0) {
|
if(getsockname(portsock, (struct sockaddr *)sa, &sslen)<0) {
|
||||||
failf(data, "getsockname() failed: %s",
|
failf(data, "getsockname() failed: %s",
|
||||||
Curl_strerror(conn, Curl_ourerrno()) );
|
Curl_strerror(conn, Curl_sockerrno()) );
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* step 4, listen on the socket */
|
/* step 4, listen on the socket */
|
||||||
|
|
||||||
if (listen(portsock, 1) < 0) {
|
if (listen(portsock, 1) < 0) {
|
||||||
error = Curl_ourerrno();
|
error = Curl_sockerrno();
|
||||||
sclose(portsock);
|
sclose(portsock);
|
||||||
failf(data, "socket failure: %s", Curl_strerror(conn, error));
|
failf(data, "socket failure: %s", Curl_strerror(conn, error));
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
@@ -1309,6 +1323,8 @@ static CURLcode ftp_state_post_mdtm(struct connectdata *conn)
|
|||||||
NBFTPSENDF(conn, "TYPE %c",
|
NBFTPSENDF(conn, "TYPE %c",
|
||||||
data->set.ftp_ascii?'A':'I');
|
data->set.ftp_ascii?'A':'I');
|
||||||
state(conn, FTP_TYPE);
|
state(conn, FTP_TYPE);
|
||||||
|
/* keep track of our current transfer type */
|
||||||
|
data->ftp_in_ascii_mode = data->set.ftp_ascii;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = ftp_state_post_type(conn);
|
result = ftp_state_post_type(conn);
|
||||||
@@ -2398,7 +2414,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
|||||||
state(conn, FTP_AUTH);
|
state(conn, FTP_AUTH);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ftp_state_user(conn);
|
result = ftp_state_user(conn);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -2430,8 +2446,14 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
|||||||
result = Curl_nbftpsendf(conn, "AUTH %s", ftpauth[ftp->count1]);
|
result = Curl_nbftpsendf(conn, "AUTH %s", ftpauth[ftp->count1]);
|
||||||
/* remain in this same state */
|
/* remain in this same state */
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
result = ftp_state_user(conn);
|
if(data->set.ftp_ssl > CURLFTPSSL_TRY)
|
||||||
|
/* we failed and CURLFTPSSL_CONTROL or CURLFTPSSL_ALL is set */
|
||||||
|
result = CURLE_FTP_SSL_FAILED;
|
||||||
|
else
|
||||||
|
/* ignore the failure and continue */
|
||||||
|
result = ftp_state_user(conn);
|
||||||
|
}
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
@@ -2456,7 +2478,8 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
|||||||
2)Private (requested by 'PROT P')
|
2)Private (requested by 'PROT P')
|
||||||
*/
|
*/
|
||||||
if(!conn->ssl[SECONDARYSOCKET].use) {
|
if(!conn->ssl[SECONDARYSOCKET].use) {
|
||||||
NBFTPSENDF(conn, "PROT %c", 'P');
|
NBFTPSENDF(conn, "PROT %c",
|
||||||
|
data->set.ftp_ssl == CURLFTPSSL_CONTROL ? 'C' : 'P');
|
||||||
state(conn, FTP_PROT);
|
state(conn, FTP_PROT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -2470,7 +2493,8 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
|||||||
case FTP_PROT:
|
case FTP_PROT:
|
||||||
if(ftpcode/100 == 2)
|
if(ftpcode/100 == 2)
|
||||||
/* We have enabled SSL for the data connection! */
|
/* We have enabled SSL for the data connection! */
|
||||||
conn->ssl[SECONDARYSOCKET].use = TRUE;
|
conn->ssl[SECONDARYSOCKET].use =
|
||||||
|
data->set.ftp_ssl != CURLFTPSSL_CONTROL;
|
||||||
/* FTP servers typically responds with 500 if they decide to reject
|
/* FTP servers typically responds with 500 if they decide to reject
|
||||||
our 'P' request */
|
our 'P' request */
|
||||||
else if(data->set.ftp_ssl> CURLFTPSSL_CONTROL)
|
else if(data->set.ftp_ssl> CURLFTPSSL_CONTROL)
|
||||||
@@ -2522,6 +2546,8 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
ftp->entrypath =dir; /* remember this */
|
ftp->entrypath =dir; /* remember this */
|
||||||
infof(data, "Entry path is '%s'\n", ftp->entrypath);
|
infof(data, "Entry path is '%s'\n", ftp->entrypath);
|
||||||
|
/* also save it where getinfo can access it: */
|
||||||
|
data->state.most_recent_ftp_entrypath = ftp->entrypath;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* couldn't get the path */
|
/* couldn't get the path */
|
||||||
@@ -2861,7 +2887,8 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
|
|||||||
if(ftp->prevpath)
|
if(ftp->prevpath)
|
||||||
free(ftp->prevpath);
|
free(ftp->prevpath);
|
||||||
|
|
||||||
path = curl_unescape(conn->path, 0); /* get the "raw" path */
|
/* get the "raw" path */
|
||||||
|
path = curl_easy_unescape(conn->data, conn->path, 0, NULL);
|
||||||
if(!path)
|
if(!path)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
@@ -2881,42 +2908,6 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
|
|||||||
/* free the dir tree and file parts */
|
/* free the dir tree and file parts */
|
||||||
freedirs(ftp);
|
freedirs(ftp);
|
||||||
|
|
||||||
ftp->ctl_valid = FALSE;
|
|
||||||
|
|
||||||
if(data->set.upload) {
|
|
||||||
if((-1 != data->set.infilesize) &&
|
|
||||||
(data->set.infilesize != *ftp->bytecountp) &&
|
|
||||||
!data->set.crlf &&
|
|
||||||
!ftp->no_transfer) {
|
|
||||||
failf(data, "Uploaded unaligned file size (%" FORMAT_OFF_T
|
|
||||||
" out of %" FORMAT_OFF_T " bytes)",
|
|
||||||
*ftp->bytecountp, data->set.infilesize);
|
|
||||||
conn->bits.close = TRUE; /* close this connection since we don't
|
|
||||||
know what state this error leaves us in */
|
|
||||||
return CURLE_PARTIAL_FILE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if((-1 != conn->size) && (conn->size != *ftp->bytecountp) &&
|
|
||||||
(conn->maxdownload != *ftp->bytecountp)) {
|
|
||||||
failf(data, "Received only partial file: %" FORMAT_OFF_T " bytes",
|
|
||||||
*ftp->bytecountp);
|
|
||||||
conn->bits.close = TRUE; /* close this connection since we don't
|
|
||||||
know what state this error leaves us in */
|
|
||||||
return CURLE_PARTIAL_FILE;
|
|
||||||
}
|
|
||||||
else if(!ftp->dont_check &&
|
|
||||||
!*ftp->bytecountp &&
|
|
||||||
(conn->size>0)) {
|
|
||||||
/* We consider this an error, but there's no true FTP error received
|
|
||||||
why we need to continue to "read out" the server response too.
|
|
||||||
We don't want to leave a "waiting" server reply if we'll get told
|
|
||||||
to make a second request on this same connection! */
|
|
||||||
failf(data, "No data was received!");
|
|
||||||
result = CURLE_FTP_COULDNT_RETR_FILE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(status) {
|
switch(status) {
|
||||||
case CURLE_BAD_DOWNLOAD_RESUME:
|
case CURLE_BAD_DOWNLOAD_RESUME:
|
||||||
case CURLE_FTP_WEIRD_PASV_REPLY:
|
case CURLE_FTP_WEIRD_PASV_REPLY:
|
||||||
@@ -2950,19 +2941,23 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
|
|||||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||||
|
|
||||||
if(!ftp->no_transfer && !status) {
|
if(!ftp->no_transfer && !status) {
|
||||||
/* Let's see what the server says about the transfer we just performed,
|
/*
|
||||||
|
* Let's see what the server says about the transfer we just performed,
|
||||||
* but lower the timeout as sometimes this connection has died while the
|
* but lower the timeout as sometimes this connection has died while the
|
||||||
* data has been transfered. This happens when doing through NATs etc that
|
* data has been transfered. This happens when doing through NATs etc that
|
||||||
* abandon old silent connections.
|
* abandon old silent connections.
|
||||||
*/
|
*/
|
||||||
|
long old_time = ftp->response_time;
|
||||||
|
|
||||||
ftp->response_time = 60; /* give it only a minute for now */
|
ftp->response_time = 60; /* give it only a minute for now */
|
||||||
|
|
||||||
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
|
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
|
||||||
|
|
||||||
ftp->response_time = 3600; /* set this back to one hour waits */
|
ftp->response_time = old_time; /* set this back to previous value */
|
||||||
|
|
||||||
if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) {
|
if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) {
|
||||||
failf(data, "control connection looks dead");
|
failf(data, "control connection looks dead");
|
||||||
|
ftp->ctl_valid = FALSE; /* mark control connection as bad */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2973,11 +2968,48 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
|
|||||||
/* 226 Transfer complete, 250 Requested file action okay, completed. */
|
/* 226 Transfer complete, 250 Requested file action okay, completed. */
|
||||||
if((ftpcode != 226) && (ftpcode != 250)) {
|
if((ftpcode != 226) && (ftpcode != 250)) {
|
||||||
failf(data, "server did not report OK, got %d", ftpcode);
|
failf(data, "server did not report OK, got %d", ftpcode);
|
||||||
return CURLE_FTP_WRITE_ERROR;
|
result = CURLE_PARTIAL_FILE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(result)
|
||||||
|
/* the response code from the transfer showed an error already so no
|
||||||
|
use checking further */
|
||||||
|
;
|
||||||
|
else if(data->set.upload) {
|
||||||
|
if((-1 != data->set.infilesize) &&
|
||||||
|
(data->set.infilesize != *ftp->bytecountp) &&
|
||||||
|
!data->set.crlf &&
|
||||||
|
!ftp->no_transfer) {
|
||||||
|
failf(data, "Uploaded unaligned file size (%" FORMAT_OFF_T
|
||||||
|
" out of %" FORMAT_OFF_T " bytes)",
|
||||||
|
*ftp->bytecountp, data->set.infilesize);
|
||||||
|
result = CURLE_PARTIAL_FILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if((-1 != conn->size) && (conn->size != *ftp->bytecountp) &&
|
||||||
|
#ifdef CURL_DO_LINEEND_CONV
|
||||||
|
/* Most FTP servers don't adjust their file SIZE response for CRLFs, so
|
||||||
|
* we'll check to see if the discrepancy can be explained by the number
|
||||||
|
* of CRLFs we've changed to LFs.
|
||||||
|
*/
|
||||||
|
((conn->size + data->state.crlf_conversions) != *ftp->bytecountp) &&
|
||||||
|
#endif /* CURL_DO_LINEEND_CONV */
|
||||||
|
(conn->maxdownload != *ftp->bytecountp)) {
|
||||||
|
failf(data, "Received only partial file: %" FORMAT_OFF_T " bytes",
|
||||||
|
*ftp->bytecountp);
|
||||||
|
result = CURLE_PARTIAL_FILE;
|
||||||
|
}
|
||||||
|
else if(!ftp->dont_check &&
|
||||||
|
!*ftp->bytecountp &&
|
||||||
|
(conn->size>0)) {
|
||||||
|
failf(data, "No data was received!");
|
||||||
|
result = CURLE_FTP_COULDNT_RETR_FILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* clear these for next connection */
|
/* clear these for next connection */
|
||||||
ftp->no_transfer = FALSE;
|
ftp->no_transfer = FALSE;
|
||||||
ftp->dont_check = FALSE;
|
ftp->dont_check = FALSE;
|
||||||
@@ -3057,6 +3089,8 @@ static CURLcode ftp_transfertype(struct connectdata *conn,
|
|||||||
ascii?"ASCII":"binary");
|
ascii?"ASCII":"binary");
|
||||||
return ascii? CURLE_FTP_COULDNT_SET_ASCII:CURLE_FTP_COULDNT_SET_BINARY;
|
return ascii? CURLE_FTP_COULDNT_SET_ASCII:CURLE_FTP_COULDNT_SET_BINARY;
|
||||||
}
|
}
|
||||||
|
/* keep track of our current transfer type */
|
||||||
|
data->ftp_in_ascii_mode = ascii;
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
@@ -3158,6 +3192,8 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
|||||||
if(data->set.upload) {
|
if(data->set.upload) {
|
||||||
NBFTPSENDF(conn, "TYPE %c", data->set.ftp_ascii?'A':'I');
|
NBFTPSENDF(conn, "TYPE %c", data->set.ftp_ascii?'A':'I');
|
||||||
state(conn, FTP_STOR_TYPE);
|
state(conn, FTP_STOR_TYPE);
|
||||||
|
/* keep track of our current transfer type */
|
||||||
|
data->ftp_in_ascii_mode = data->set.ftp_ascii;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* download */
|
/* download */
|
||||||
@@ -3172,10 +3208,14 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
|||||||
need to set ASCII transfer mode. */
|
need to set ASCII transfer mode. */
|
||||||
NBFTPSENDF(conn, "TYPE A", NULL);
|
NBFTPSENDF(conn, "TYPE A", NULL);
|
||||||
state(conn, FTP_LIST_TYPE);
|
state(conn, FTP_LIST_TYPE);
|
||||||
|
/* keep track of our current transfer type */
|
||||||
|
data->ftp_in_ascii_mode = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
NBFTPSENDF(conn, "TYPE %c", data->set.ftp_ascii?'A':'I');
|
NBFTPSENDF(conn, "TYPE %c", data->set.ftp_ascii?'A':'I');
|
||||||
state(conn, FTP_RETR_TYPE);
|
state(conn, FTP_RETR_TYPE);
|
||||||
|
/* keep track of our current transfer type */
|
||||||
|
data->ftp_in_ascii_mode = data->set.ftp_ascii;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = ftp_easy_statemach(conn);
|
result = ftp_easy_statemach(conn);
|
||||||
@@ -3298,6 +3338,14 @@ CURLcode Curl_nbftpsendf(struct connectdata *conn,
|
|||||||
|
|
||||||
ftp_respinit(conn);
|
ftp_respinit(conn);
|
||||||
|
|
||||||
|
#ifdef CURL_DOES_CONVERSIONS
|
||||||
|
res = Curl_convert_to_network(data, s, write_len);
|
||||||
|
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||||
|
if(res != CURLE_OK) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif /* CURL_DOES_CONVERSIONS */
|
||||||
|
|
||||||
res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
|
res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
|
||||||
&bytes_written);
|
&bytes_written);
|
||||||
|
|
||||||
@@ -3347,6 +3395,14 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
|||||||
bytes_written=0;
|
bytes_written=0;
|
||||||
write_len = strlen(s);
|
write_len = strlen(s);
|
||||||
|
|
||||||
|
#ifdef CURL_DOES_CONVERSIONS
|
||||||
|
res = Curl_convert_to_network(conn->data, s, write_len);
|
||||||
|
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||||
|
if(res != CURLE_OK) {
|
||||||
|
return(res);
|
||||||
|
}
|
||||||
|
#endif /* CURL_DOES_CONVERSIONS */
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
|
res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
|
||||||
&bytes_written);
|
&bytes_written);
|
||||||
@@ -3415,8 +3471,12 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
|||||||
if(ftp) {
|
if(ftp) {
|
||||||
(void)ftp_quit(conn); /* ignore errors on the QUIT */
|
(void)ftp_quit(conn); /* ignore errors on the QUIT */
|
||||||
|
|
||||||
if(ftp->entrypath)
|
if(ftp->entrypath) {
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
data->state.most_recent_ftp_entrypath = NULL;
|
||||||
free(ftp->entrypath);
|
free(ftp->entrypath);
|
||||||
|
ftp->entrypath = NULL;
|
||||||
|
}
|
||||||
if(ftp->cache) {
|
if(ftp->cache) {
|
||||||
free(ftp->cache);
|
free(ftp->cache);
|
||||||
ftp->cache = NULL;
|
ftp->cache = NULL;
|
||||||
@@ -3733,7 +3793,8 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
|||||||
if(!ftp->dirs)
|
if(!ftp->dirs)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
ftp->dirs[0] = curl_unescape(cur_pos, (int)(slash_pos-cur_pos));
|
ftp->dirs[0] = curl_easy_unescape(conn->data, cur_pos,
|
||||||
|
(int)(slash_pos-cur_pos), NULL);
|
||||||
if(!ftp->dirs[0]) {
|
if(!ftp->dirs[0]) {
|
||||||
free(ftp->dirs);
|
free(ftp->dirs);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
@@ -3763,8 +3824,9 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
|||||||
requires a parameter and a non-existant parameter a) doesn't work on
|
requires a parameter and a non-existant parameter a) doesn't work on
|
||||||
many servers and b) has no effect on the others. */
|
many servers and b) has no effect on the others. */
|
||||||
int len = (int)(slash_pos - cur_pos + absolute_dir);
|
int len = (int)(slash_pos - cur_pos + absolute_dir);
|
||||||
ftp->dirs[ftp->dirdepth] = curl_unescape(cur_pos - absolute_dir, len);
|
ftp->dirs[ftp->dirdepth] = curl_easy_unescape(conn->data,
|
||||||
|
cur_pos - absolute_dir,
|
||||||
|
len, NULL);
|
||||||
if (!ftp->dirs[ftp->dirdepth]) { /* run out of memory ... */
|
if (!ftp->dirs[ftp->dirdepth]) { /* run out of memory ... */
|
||||||
failf(data, "no memory");
|
failf(data, "no memory");
|
||||||
freedirs(ftp);
|
freedirs(ftp);
|
||||||
@@ -3801,7 +3863,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(*ftp->file) {
|
if(*ftp->file) {
|
||||||
ftp->file = curl_unescape(ftp->file, 0);
|
ftp->file = curl_easy_unescape(conn->data, ftp->file, 0, NULL);
|
||||||
if(NULL == ftp->file) {
|
if(NULL == ftp->file) {
|
||||||
freedirs(ftp);
|
freedirs(ftp);
|
||||||
failf(data, "no memory");
|
failf(data, "no memory");
|
||||||
@@ -3816,12 +3878,19 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
|||||||
ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL
|
ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL
|
||||||
pointer */
|
pointer */
|
||||||
|
|
||||||
|
if(data->set.upload && !ftp->file &&
|
||||||
|
(!ftp->no_transfer || conn->bits.no_body)) {
|
||||||
|
/* We need a file name when uploading. Return error! */
|
||||||
|
failf(data, "Uploading to a URL without a file name!");
|
||||||
|
return CURLE_URL_MALFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
ftp->cwddone = FALSE; /* default to not done */
|
ftp->cwddone = FALSE; /* default to not done */
|
||||||
|
|
||||||
if(ftp->prevpath) {
|
if(ftp->prevpath) {
|
||||||
/* prevpath is "raw" so we convert the input path before we compare the
|
/* prevpath is "raw" so we convert the input path before we compare the
|
||||||
strings */
|
strings */
|
||||||
char *path = curl_unescape(conn->path, 0);
|
char *path = curl_easy_unescape(conn->data, conn->path, 0, NULL);
|
||||||
if(!path)
|
if(!path)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
@@ -34,10 +34,9 @@ CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
|
|||||||
int *ftpcode);
|
int *ftpcode);
|
||||||
CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
|
CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
|
||||||
CURLcode Curl_ftp_multi_statemach(struct connectdata *conn, bool *done);
|
CURLcode Curl_ftp_multi_statemach(struct connectdata *conn, bool *done);
|
||||||
CURLcode Curl_ftp_fdset(struct connectdata *conn,
|
int Curl_ftp_getsock(struct connectdata *conn,
|
||||||
fd_set *read_fd_set,
|
curl_socket_t *socks,
|
||||||
fd_set *write_fd_set,
|
int numsocks);
|
||||||
int *max_fdp);
|
|
||||||
CURLcode Curl_ftp_doing(struct connectdata *conn,
|
CURLcode Curl_ftp_doing(struct connectdata *conn,
|
||||||
bool *dophase_done);
|
bool *dophase_done);
|
||||||
#endif /* CURL_DISABLE_FTP */
|
#endif /* CURL_DISABLE_FTP */
|
||||||
|
@@ -75,6 +75,8 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
|||||||
double *param_doublep=NULL;
|
double *param_doublep=NULL;
|
||||||
char **param_charp=NULL;
|
char **param_charp=NULL;
|
||||||
struct curl_slist **param_slistp=NULL;
|
struct curl_slist **param_slistp=NULL;
|
||||||
|
char buf;
|
||||||
|
|
||||||
va_start(arg, info);
|
va_start(arg, info);
|
||||||
|
|
||||||
switch(info&CURLINFO_TYPEMASK) {
|
switch(info&CURLINFO_TYPEMASK) {
|
||||||
@@ -187,11 +189,33 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
|||||||
case CURLINFO_COOKIELIST:
|
case CURLINFO_COOKIELIST:
|
||||||
*param_slistp = Curl_cookie_list(data);
|
*param_slistp = Curl_cookie_list(data);
|
||||||
break;
|
break;
|
||||||
|
case CURLINFO_FTP_ENTRY_PATH:
|
||||||
|
/* Return the entrypath string from the most recent connection.
|
||||||
|
This pointer was copied from the connectdata structure by FTP.
|
||||||
|
The actual string may be free()ed by subsequent libcurl calls so
|
||||||
|
it must be copied to a safer area before the next libcurl call.
|
||||||
|
Callers must never free it themselves. */
|
||||||
|
*param_charp = data->state.most_recent_ftp_entrypath;
|
||||||
|
break;
|
||||||
case CURLINFO_LASTSOCKET:
|
case CURLINFO_LASTSOCKET:
|
||||||
if((data->state.lastconnect != -1) &&
|
if((data->state.lastconnect != -1) &&
|
||||||
(data->state.connects[data->state.lastconnect] != NULL))
|
(data->state.connects[data->state.lastconnect] != NULL)) {
|
||||||
*param_longp = data->state.connects[data->state.lastconnect]->
|
*param_longp = data->state.connects[data->state.lastconnect]->
|
||||||
sock[FIRSTSOCKET];
|
sock[FIRSTSOCKET];
|
||||||
|
/* we have a socket connected, let's determine if the server shut down */
|
||||||
|
/* determine if ssl */
|
||||||
|
if(data->state.connects[data->state.lastconnect]->ssl[FIRSTSOCKET].use) {
|
||||||
|
/* use the SSL context */
|
||||||
|
if (!Curl_ssl_check_cxn(data->state.connects[data->state.lastconnect]))
|
||||||
|
*param_longp = -1; /* FIN received */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* use the socket */
|
||||||
|
if(recv((int)data->state.connects[data->state.lastconnect]->
|
||||||
|
sock[FIRSTSOCKET], (void*)&buf, 1, MSG_PEEK) == 0)
|
||||||
|
*param_longp = -1; /* FIN received */
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
*param_longp = -1;
|
*param_longp = -1;
|
||||||
break;
|
break;
|
||||||
|
@@ -159,7 +159,7 @@ static CURLcode handshake(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* anything that gets here is fatally bad */
|
/* anything that gets here is fatally bad */
|
||||||
failf(data, "select on SSL socket, errno: %d", Curl_ourerrno());
|
failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -458,6 +458,12 @@ int Curl_gtls_send(struct connectdata *conn,
|
|||||||
int rc;
|
int rc;
|
||||||
rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
|
rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
|
||||||
|
|
||||||
|
if(rc < 0 ) {
|
||||||
|
if(rc == GNUTLS_E_AGAIN)
|
||||||
|
return 0; /* EWOULDBLOCK equivalent */
|
||||||
|
rc = -1; /* generic error code for send failure */
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
lib/hash.c
26
lib/hash.c
@@ -124,8 +124,11 @@ mk_hash_element(char *key, size_t key_len, const void *p)
|
|||||||
(struct curl_hash_element *) malloc(sizeof(struct curl_hash_element));
|
(struct curl_hash_element *) malloc(sizeof(struct curl_hash_element));
|
||||||
|
|
||||||
if(he) {
|
if(he) {
|
||||||
char *dup = strdup(key);
|
char *dup = malloc(key_len);
|
||||||
if(dup) {
|
if(dup) {
|
||||||
|
/* copy the key */
|
||||||
|
memcpy(dup, key, key_len);
|
||||||
|
|
||||||
he->key = dup;
|
he->key = dup;
|
||||||
he->key_len = key_len;
|
he->key_len = key_len;
|
||||||
he->ptr = (void *) p;
|
he->ptr = (void *) p;
|
||||||
@@ -179,6 +182,23 @@ Curl_hash_add(struct curl_hash *h, char *key, size_t key_len, void *p)
|
|||||||
return NULL; /* failure */
|
return NULL; /* failure */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* remove the identified hash entry, returns non-zero on failure */
|
||||||
|
int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len)
|
||||||
|
{
|
||||||
|
struct curl_llist_element *le;
|
||||||
|
struct curl_hash_element *he;
|
||||||
|
struct curl_llist *l = FETCH_LIST(h, key, key_len);
|
||||||
|
|
||||||
|
for (le = l->head; le; le = le->next) {
|
||||||
|
he = le->ptr;
|
||||||
|
if (hash_key_compare(he->key, he->key_len, key, key_len)) {
|
||||||
|
Curl_llist_remove(l, le, (void *) h);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
Curl_hash_pick(struct curl_hash *h, char *key, size_t key_len)
|
Curl_hash_pick(struct curl_hash *h, char *key, size_t key_len)
|
||||||
{
|
{
|
||||||
@@ -186,9 +206,7 @@ Curl_hash_pick(struct curl_hash *h, char *key, size_t key_len)
|
|||||||
struct curl_hash_element *he;
|
struct curl_hash_element *he;
|
||||||
struct curl_llist *l = FETCH_LIST(h, key, key_len);
|
struct curl_llist *l = FETCH_LIST(h, key, key_len);
|
||||||
|
|
||||||
for (le = l->head;
|
for (le = l->head; le; le = le->next) {
|
||||||
le;
|
|
||||||
le = le->next) {
|
|
||||||
he = le->ptr;
|
he = le->ptr;
|
||||||
if (hash_key_compare(he->key, he->key_len, key, key_len)) {
|
if (hash_key_compare(he->key, he->key_len, key, key_len)) {
|
||||||
return he->ptr;
|
return he->ptr;
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -24,11 +24,10 @@
|
|||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#ifdef HAVE_MALLOC_H /* Win32 */
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#endif
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -55,13 +54,12 @@
|
|||||||
#include <inet.h>
|
#include <inet.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SETJMP_H
|
#ifdef HAVE_SETJMP_H
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef HAVE_PROCESS_H
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -77,6 +75,7 @@
|
|||||||
#include "share.h"
|
#include "share.h"
|
||||||
#include "strerror.h"
|
#include "strerror.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
|
#include "connect.h" /* for the Curl_sockerrno() proto */
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -105,17 +104,15 @@
|
|||||||
* Returns: CURLE_OK always!
|
* Returns: CURLE_OK always!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CURLcode Curl_resolv_fdset(struct connectdata *conn,
|
int Curl_resolv_getsock(struct connectdata *conn,
|
||||||
fd_set *read_fd_set,
|
curl_socket_t *socks,
|
||||||
fd_set *write_fd_set,
|
int numsocks)
|
||||||
int *max_fdp)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
int max = ares_fds(conn->data->state.areschannel,
|
int max = ares_getsock(conn->data->state.areschannel,
|
||||||
read_fd_set, write_fd_set);
|
(int *)socks, numsocks);
|
||||||
*max_fdp = max;
|
|
||||||
|
|
||||||
return CURLE_OK;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -211,7 +208,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
break;
|
break;
|
||||||
tvp = ares_timeout(data->state.areschannel, &store, &tv);
|
tvp = ares_timeout(data->state.areschannel, &store, &tv);
|
||||||
count = select(nfds, &read_fds, &write_fds, NULL, tvp);
|
count = select(nfds, &read_fds, &write_fds, NULL, tvp);
|
||||||
if (count < 0 && errno != EINVAL)
|
if (count < 0 && Curl_sockerrno() != EINVAL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ares_process(data->state.areschannel, &read_fds, &write_fds);
|
ares_process(data->state.areschannel, &read_fds, &write_fds);
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -24,11 +24,10 @@
|
|||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#ifdef HAVE_MALLOC_H /* Win32 */
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#endif
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -55,13 +54,12 @@
|
|||||||
#include <inet.h>
|
#include <inet.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SETJMP_H
|
#ifdef HAVE_SETJMP_H
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef HAVE_PROCESS_H
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -24,11 +24,10 @@
|
|||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#ifdef HAVE_MALLOC_H /* Win32 */
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#endif
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -55,13 +54,12 @@
|
|||||||
#include <inet.h>
|
#include <inet.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SETJMP_H
|
#ifdef HAVE_SETJMP_H
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef HAVE_PROCESS_H
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
20
lib/hostip.h
20
lib/hostip.h
@@ -160,15 +160,19 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
|||||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||||
struct Curl_dns_entry **dnsentry);
|
struct Curl_dns_entry **dnsentry);
|
||||||
|
|
||||||
/* Curl_resolv_fdset() is a generic function that exists in multiple versions
|
/* Curl_resolv_getsock() is a generic function that exists in multiple
|
||||||
depending on what name resolve technology we've built to use. The function
|
versions depending on what name resolve technology we've built to use. The
|
||||||
is called from the curl_multi_fdset() function */
|
function is called from the multi_getsock() function. 'sock' is a pointer
|
||||||
CURLcode Curl_resolv_fdset(struct connectdata *conn,
|
to an array to hold the file descriptors, with 'numsock' being the size of
|
||||||
fd_set *read_fd_set,
|
that array (in number of entries). This function is supposed to return
|
||||||
fd_set *write_fd_set,
|
bitmask indicating what file descriptors (referring to array indexes in the
|
||||||
int *max_fdp);
|
'sock' array) to wait for, read/write. */
|
||||||
|
int Curl_resolv_getsock(struct connectdata *conn, curl_socket_t *sock,
|
||||||
|
int numsocks);
|
||||||
|
|
||||||
/* unlock a previously resolved dns entry */
|
/* unlock a previously resolved dns entry */
|
||||||
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns);
|
void Curl_resolv_unlock(struct SessionHandle *data,
|
||||||
|
struct Curl_dns_entry *dns);
|
||||||
|
|
||||||
/* for debugging purposes only: */
|
/* for debugging purposes only: */
|
||||||
void Curl_scan_cache_used(void *user, void *ptr);
|
void Curl_scan_cache_used(void *user, void *ptr);
|
||||||
|
@@ -26,9 +26,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#ifdef HAVE_MALLOC_H /* Win32 */
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#endif
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -55,13 +55,12 @@
|
|||||||
#include <inet.h>
|
#include <inet.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SETJMP_H
|
#ifdef HAVE_SETJMP_H
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef HAVE_PROCESS_H
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -24,11 +24,10 @@
|
|||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#ifdef HAVE_MALLOC_H
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#endif
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -55,13 +54,12 @@
|
|||||||
#include <inet.h>
|
#include <inet.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SETJMP_H
|
#ifdef HAVE_SETJMP_H
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef HAVE_PROCESS_H
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -203,7 +201,7 @@ static void dump_addrinfo(struct connectdata *conn, const struct addrinfo *ai)
|
|||||||
if (Curl_printable_address(ai, buf, sizeof(buf)))
|
if (Curl_printable_address(ai, buf, sizeof(buf)))
|
||||||
printf("%s\n", buf);
|
printf("%s\n", buf);
|
||||||
else
|
else
|
||||||
printf("failed; %s\n", Curl_strerror(conn, Curl_ourerrno()));
|
printf("failed; %s\n", Curl_strerror(conn, Curl_sockerrno()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -24,11 +24,10 @@
|
|||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#ifdef HAVE_MALLOC_H
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#endif
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -55,13 +54,12 @@
|
|||||||
#include <inet.h>
|
#include <inet.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SETJMP_H
|
#ifdef HAVE_SETJMP_H
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef HAVE_PROCESS_H
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -126,17 +124,15 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
|||||||
* It is present here to keep #ifdefs out from multi.c
|
* It is present here to keep #ifdefs out from multi.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CURLcode Curl_resolv_fdset(struct connectdata *conn,
|
int Curl_resolv_getsock(struct connectdata *conn,
|
||||||
fd_set *read_fd_set,
|
curl_socket_t *sock,
|
||||||
fd_set *write_fd_set,
|
int numsocks)
|
||||||
int *max_fdp)
|
|
||||||
{
|
{
|
||||||
(void)conn;
|
(void)conn;
|
||||||
(void)read_fd_set;
|
(void)sock;
|
||||||
(void)write_fd_set;
|
(void)numsocks;
|
||||||
(void)max_fdp;
|
|
||||||
|
|
||||||
return CURLE_OK;
|
return 0; /* no bits since we don't use any socks */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* truly sync */
|
#endif /* truly sync */
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -26,9 +26,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#ifdef HAVE_MALLOC_H
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#endif
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -55,14 +55,12 @@
|
|||||||
#include <inet.h>
|
#include <inet.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SETJMP_H
|
#ifdef HAVE_SETJMP_H
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef HAVE_PROCESS_H
|
||||||
#include <stdlib.h>
|
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -78,6 +76,7 @@
|
|||||||
#include "share.h"
|
#include "share.h"
|
||||||
#include "strerror.h"
|
#include "strerror.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
|
#include "multiif.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -300,7 +299,7 @@ static unsigned __stdcall gethostbyname_thread (void *arg)
|
|||||||
struct thread_sync_data tsd = { 0,0,0,NULL };
|
struct thread_sync_data tsd = { 0,0,0,NULL };
|
||||||
if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) {
|
if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) {
|
||||||
/* thread synchronization data initialization failed */
|
/* thread synchronization data initialization failed */
|
||||||
return -1;
|
return (unsigned)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sharing the same _iob[] element with our parent thread should
|
/* Sharing the same _iob[] element with our parent thread should
|
||||||
@@ -569,7 +568,7 @@ static bool init_resolve_thread (struct connectdata *conn,
|
|||||||
thread_and_event[1] = td->event_thread_started;
|
thread_and_event[1] = td->event_thread_started;
|
||||||
if (WaitForMultipleObjects(sizeof(thread_and_event) /
|
if (WaitForMultipleObjects(sizeof(thread_and_event) /
|
||||||
sizeof(thread_and_event[0]),
|
sizeof(thread_and_event[0]),
|
||||||
thread_and_event, FALSE,
|
(const HANDLE*)thread_and_event, FALSE,
|
||||||
INFINITE) == WAIT_FAILED) {
|
INFINITE) == WAIT_FAILED) {
|
||||||
/* The resolver thread has been created,
|
/* The resolver thread has been created,
|
||||||
* most probably it works now - ignoring this "minor" error
|
* most probably it works now - ignoring this "minor" error
|
||||||
@@ -715,20 +714,22 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLcode Curl_resolv_fdset(struct connectdata *conn,
|
int Curl_resolv_getsock(struct connectdata *conn,
|
||||||
fd_set *read_fd_set,
|
curl_socket_t *socks,
|
||||||
fd_set *write_fd_set,
|
int numsocks)
|
||||||
int *max_fdp)
|
|
||||||
{
|
{
|
||||||
const struct thread_data *td =
|
const struct thread_data *td =
|
||||||
(const struct thread_data *) conn->async.os_specific;
|
(const struct thread_data *) conn->async.os_specific;
|
||||||
|
|
||||||
if (td && td->dummy_sock != CURL_SOCKET_BAD) {
|
if (td && td->dummy_sock != CURL_SOCKET_BAD) {
|
||||||
FD_SET(td->dummy_sock,write_fd_set);
|
if(numsocks) {
|
||||||
*max_fdp = (int)td->dummy_sock;
|
/* return one socket waiting for writable, even though this is just
|
||||||
|
a dummy */
|
||||||
|
socks[0] = td->dummy_sock;
|
||||||
|
return GETSOCK_WRITESOCK(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(void) read_fd_set;
|
return 0;
|
||||||
return CURLE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CURLRES_IPV4
|
#ifdef CURLRES_IPV4
|
||||||
|
82
lib/http.c
82
lib/http.c
@@ -37,8 +37,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
@@ -97,6 +95,7 @@
|
|||||||
#include "select.h"
|
#include "select.h"
|
||||||
#include "parsedate.h" /* for the week day and month names */
|
#include "parsedate.h" /* for the week day and month names */
|
||||||
#include "strtoofft.h"
|
#include "strtoofft.h"
|
||||||
|
#include "multiif.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -1371,13 +1370,6 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->protocol & PROT_HTTPS) {
|
|
||||||
/* perform SSL initialization for this socket */
|
|
||||||
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
|
||||||
if(result)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!data->state.this_is_a_follow) {
|
if(!data->state.this_is_a_follow) {
|
||||||
/* this is not a followed location, get the original host name */
|
/* this is not a followed location, get the original host name */
|
||||||
if (data->state.first_host)
|
if (data->state.first_host)
|
||||||
@@ -1387,11 +1379,81 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
|||||||
data->state.first_host = strdup(conn->host.name);
|
data->state.first_host = strdup(conn->host.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
*done = TRUE;
|
if(conn->protocol & PROT_HTTPS) {
|
||||||
|
/* perform SSL initialization */
|
||||||
|
if(data->state.used_interface == Curl_if_multi) {
|
||||||
|
result = Curl_https_connecting(conn, done);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* BLOCKING */
|
||||||
|
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
*done = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*done = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CURLcode Curl_https_connecting(struct connectdata *conn, bool *done)
|
||||||
|
{
|
||||||
|
CURLcode result;
|
||||||
|
curlassert(conn->protocol & PROT_HTTPS);
|
||||||
|
|
||||||
|
/* perform SSL initialization for this socket */
|
||||||
|
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
/* This function is OpenSSL-specific. It should be made to query the generic
|
||||||
|
SSL layer instead. */
|
||||||
|
int Curl_https_getsock(struct connectdata *conn,
|
||||||
|
curl_socket_t *socks,
|
||||||
|
int numsocks)
|
||||||
|
{
|
||||||
|
if (conn->protocol & PROT_HTTPS) {
|
||||||
|
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
|
||||||
|
|
||||||
|
if(!numsocks)
|
||||||
|
return GETSOCK_BLANK;
|
||||||
|
|
||||||
|
if (connssl->connecting_state == ssl_connect_2_writing) {
|
||||||
|
/* write mode */
|
||||||
|
socks[0] = conn->sock[FIRSTSOCKET];
|
||||||
|
return GETSOCK_WRITESOCK(0);
|
||||||
|
}
|
||||||
|
else if (connssl->connecting_state == ssl_connect_2_reading) {
|
||||||
|
/* read mode */
|
||||||
|
socks[0] = conn->sock[FIRSTSOCKET];
|
||||||
|
return GETSOCK_READSOCK(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
int Curl_https_getsock(struct connectdata *conn,
|
||||||
|
curl_socket_t *socks,
|
||||||
|
int numsocks)
|
||||||
|
{
|
||||||
|
(void)conn;
|
||||||
|
(void)socks;
|
||||||
|
(void)numsocks;
|
||||||
|
return GETSOCK_BLANK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_http_done() gets called from Curl_done() after a single HTTP request
|
* Curl_http_done() gets called from Curl_done() after a single HTTP request
|
||||||
* has been performed.
|
* has been performed.
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -37,6 +37,10 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
|||||||
CURLcode Curl_http(struct connectdata *conn, bool *done);
|
CURLcode Curl_http(struct connectdata *conn, bool *done);
|
||||||
CURLcode Curl_http_done(struct connectdata *, CURLcode);
|
CURLcode Curl_http_done(struct connectdata *, CURLcode);
|
||||||
CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
|
CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
|
||||||
|
CURLcode Curl_https_connecting(struct connectdata *conn, bool *done);
|
||||||
|
int Curl_https_getsock(struct connectdata *conn,
|
||||||
|
curl_socket_t *socks,
|
||||||
|
int numsocks);
|
||||||
|
|
||||||
/* The following functions are defined in http_chunks.c */
|
/* The following functions are defined in http_chunks.c */
|
||||||
void Curl_httpchunk_init(struct connectdata *conn);
|
void Curl_httpchunk_init(struct connectdata *conn);
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -303,10 +303,11 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
if(d->algo == CURLDIGESTALGO_MD5SESS) {
|
if(d->algo == CURLDIGESTALGO_MD5SESS) {
|
||||||
/* nonce and cnonce are OUTSIDE the hash */
|
/* nonce and cnonce are OUTSIDE the hash */
|
||||||
tmp = aprintf("%s:%s:%s", ha1, d->nonce, d->cnonce);
|
tmp = aprintf("%s:%s:%s", ha1, d->nonce, d->cnonce);
|
||||||
free(ha1);
|
|
||||||
if(!tmp)
|
if(!tmp)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
ha1 = (unsigned char *)tmp;
|
Curl_md5it(md5buf, (unsigned char *)tmp);
|
||||||
|
free(tmp); /* free this again */
|
||||||
|
md5_to_ascii(md5buf, ha1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -34,7 +34,6 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
|
470
lib/http_ntlm.c
470
lib/http_ntlm.c
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -27,11 +27,16 @@
|
|||||||
http://davenport.sourceforge.net/ntlm.html
|
http://davenport.sourceforge.net/ntlm.html
|
||||||
http://www.innovation.ch/java/ntlm.html
|
http://www.innovation.ch/java/ntlm.html
|
||||||
|
|
||||||
|
Another implementation:
|
||||||
|
http://lxr.mozilla.org/mozilla/source/security/manager/ssl/src/nsNTLMAuthModule.cpp
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_HTTP
|
#ifndef CURL_DISABLE_HTTP
|
||||||
#ifdef USE_NTLM
|
#ifdef USE_NTLM
|
||||||
|
|
||||||
|
#define DEBUG_ME 0
|
||||||
|
|
||||||
/* -- WIN32 approved -- */
|
/* -- WIN32 approved -- */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -46,6 +51,7 @@
|
|||||||
#include "http_ntlm.h"
|
#include "http_ntlm.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "ssluse.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -54,7 +60,9 @@
|
|||||||
|
|
||||||
#include <openssl/des.h>
|
#include <openssl/des.h>
|
||||||
#include <openssl/md4.h>
|
#include <openssl/md4.h>
|
||||||
|
#include <openssl/md5.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x00907001L
|
#if OPENSSL_VERSION_NUMBER < 0x00907001L
|
||||||
#define DES_key_schedule des_key_schedule
|
#define DES_key_schedule des_key_schedule
|
||||||
@@ -89,6 +97,102 @@ static PSecurityFunctionTable s_pSecFn = NULL;
|
|||||||
/* Define this to make the type-3 message include the NT response message */
|
/* Define this to make the type-3 message include the NT response message */
|
||||||
#define USE_NTRESPONSES 1
|
#define USE_NTRESPONSES 1
|
||||||
|
|
||||||
|
/* Define this to make the type-3 message include the NTLM2Session response
|
||||||
|
message, requires USE_NTRESPONSES. */
|
||||||
|
#define USE_NTLM2SESSION 1
|
||||||
|
|
||||||
|
#ifndef USE_WINDOWS_SSPI
|
||||||
|
/* this function converts from the little endian format used in the incoming
|
||||||
|
package to whatever endian format we're using natively */
|
||||||
|
static unsigned int readint_le(unsigned char *buf) /* must point to a
|
||||||
|
4 bytes buffer*/
|
||||||
|
{
|
||||||
|
return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
|
||||||
|
((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEBUG_ME
|
||||||
|
# define DEBUG_OUT(x) x
|
||||||
|
static void print_flags(FILE *handle, unsigned long flags)
|
||||||
|
{
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_UNICODE)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_OEM)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM ");
|
||||||
|
if(flags & NTLMFLAG_REQUEST_TARGET)
|
||||||
|
fprintf(handle, "NTLMFLAG_REQUEST_TARGET ");
|
||||||
|
if(flags & (1<<3))
|
||||||
|
fprintf(handle, "NTLMFLAG_UNKNOWN_3 ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_SIGN)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_SEAL)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_LM_KEY)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_NETWARE)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_NETWARE ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY ");
|
||||||
|
if(flags & (1<<10))
|
||||||
|
fprintf(handle, "NTLMFLAG_UNKNOWN_10 ");
|
||||||
|
if(flags & (1<<11))
|
||||||
|
fprintf(handle, "NTLMFLAG_UNKNOWN_11 ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN ");
|
||||||
|
if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN)
|
||||||
|
fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN ");
|
||||||
|
if(flags & NTLMFLAG_TARGET_TYPE_SERVER)
|
||||||
|
fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER ");
|
||||||
|
if(flags & NTLMFLAG_TARGET_TYPE_SHARE)
|
||||||
|
fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY ");
|
||||||
|
if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE)
|
||||||
|
fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE ");
|
||||||
|
if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE)
|
||||||
|
fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE ");
|
||||||
|
if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY)
|
||||||
|
fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO ");
|
||||||
|
if(flags & (1<<24))
|
||||||
|
fprintf(handle, "NTLMFLAG_UNKNOWN_24 ");
|
||||||
|
if(flags & (1<<25))
|
||||||
|
fprintf(handle, "NTLMFLAG_UNKNOWN_25 ");
|
||||||
|
if(flags & (1<<26))
|
||||||
|
fprintf(handle, "NTLMFLAG_UNKNOWN_26 ");
|
||||||
|
if(flags & (1<<27))
|
||||||
|
fprintf(handle, "NTLMFLAG_UNKNOWN_27 ");
|
||||||
|
if(flags & (1<<28))
|
||||||
|
fprintf(handle, "NTLMFLAG_UNKNOWN_28 ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_128)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_128 ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE ");
|
||||||
|
if(flags & NTLMFLAG_NEGOTIATE_56)
|
||||||
|
fprintf(handle, "NTLMFLAG_NEGOTIATE_56 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_hex(FILE *handle, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
const char *p = buf;
|
||||||
|
fprintf(stderr, "0x");
|
||||||
|
while (len-- > 0)
|
||||||
|
fprintf(stderr, "%02.2x", (unsigned int)*p++);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define DEBUG_OUT(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
(*) = A "security buffer" is a triplet consisting of two shorts and one
|
(*) = A "security buffer" is a triplet consisting of two shorts and one
|
||||||
long:
|
long:
|
||||||
@@ -107,6 +211,9 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
/* point to the correct struct with this */
|
/* point to the correct struct with this */
|
||||||
struct ntlmdata *ntlm;
|
struct ntlmdata *ntlm;
|
||||||
|
#ifndef USE_WINDOWS_SSPI
|
||||||
|
static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
|
||||||
|
#endif
|
||||||
|
|
||||||
ntlm = proxy?&conn->proxyntlm:&conn->ntlm;
|
ntlm = proxy?&conn->proxyntlm:&conn->ntlm;
|
||||||
|
|
||||||
@@ -143,19 +250,34 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn,
|
|||||||
ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
|
ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_SSPI
|
#ifdef USE_WINDOWS_SSPI
|
||||||
if ((ntlm->type_2 = malloc(size+1)) == NULL) {
|
ntlm->type_2 = malloc(size+1);
|
||||||
|
if (ntlm->type_2 == NULL) {
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
ntlm->n_type_2 = size;
|
ntlm->n_type_2 = size;
|
||||||
memcpy(ntlm->type_2, buffer, size);
|
memcpy(ntlm->type_2, buffer, size);
|
||||||
#else
|
#else
|
||||||
if(size >= 48)
|
ntlm->flags = 0;
|
||||||
/* the nonce of interest is index [24 .. 31], 8 bytes */
|
|
||||||
memcpy(ntlm->nonce, &buffer[24], 8);
|
|
||||||
/* FIX: add an else here! */
|
|
||||||
|
|
||||||
/* at index decimal 20, there's a 32bit NTLM flag field */
|
if((size < 32) ||
|
||||||
|
(memcmp(buffer, "NTLMSSP", 8) != 0) ||
|
||||||
|
(memcmp(buffer+8, type2_marker, sizeof(type2_marker)) != 0)) {
|
||||||
|
/* This was not a good enough type-2 message */
|
||||||
|
free(buffer);
|
||||||
|
return CURLNTLM_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
ntlm->flags = readint_le(&buffer[20]);
|
||||||
|
memcpy(ntlm->nonce, &buffer[24], 8);
|
||||||
|
|
||||||
|
DEBUG_OUT({
|
||||||
|
fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
|
||||||
|
print_flags(stderr, ntlm->flags);
|
||||||
|
fprintf(stderr, "\n nonce=");
|
||||||
|
print_hex(stderr, ntlm->nonce, 8);
|
||||||
|
fprintf(stderr, "\n****\n");
|
||||||
|
});
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
#endif
|
#endif
|
||||||
@@ -199,7 +321,7 @@ static void setup_des_key(unsigned char *key_56,
|
|||||||
* 8 byte plaintext is encrypted with each key and the resulting 24
|
* 8 byte plaintext is encrypted with each key and the resulting 24
|
||||||
* bytes are stored in the results array.
|
* bytes are stored in the results array.
|
||||||
*/
|
*/
|
||||||
static void calc_resp(unsigned char *keys,
|
static void lm_resp(unsigned char *keys,
|
||||||
unsigned char *plaintext,
|
unsigned char *plaintext,
|
||||||
unsigned char *results)
|
unsigned char *results)
|
||||||
{
|
{
|
||||||
@@ -218,35 +340,19 @@ static void calc_resp(unsigned char *keys,
|
|||||||
DESKEY(ks), DES_ENCRYPT);
|
DESKEY(ks), DES_ENCRYPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up lanmanager and nt hashed passwords
|
* Set up lanmanager hashed password
|
||||||
*/
|
*/
|
||||||
static void mkhash(char *password,
|
static void mk_lm_hash(char *password, unsigned char *lmbuffer /* 21 bytes */)
|
||||||
unsigned char *nonce, /* 8 bytes */
|
|
||||||
unsigned char *lmresp /* must fit 0x18 bytes */
|
|
||||||
#ifdef USE_NTRESPONSES
|
|
||||||
, unsigned char *ntresp /* must fit 0x18 bytes */
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
/* 21 bytes fits 3 7-bytes chunks, as we use 56 bit (7 bytes) as DES input,
|
unsigned char pw[14];
|
||||||
and we add three different ones, see the calc_resp() function */
|
|
||||||
unsigned char lmbuffer[21];
|
|
||||||
#ifdef USE_NTRESPONSES
|
|
||||||
unsigned char ntbuffer[21];
|
|
||||||
#endif
|
|
||||||
unsigned char *pw;
|
|
||||||
static const unsigned char magic[] = {
|
static const unsigned char magic[] = {
|
||||||
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25
|
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
|
||||||
};
|
};
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
size_t len = strlen(password);
|
size_t len = strlen(password);
|
||||||
|
|
||||||
/* make it fit at least 14 bytes */
|
|
||||||
pw = malloc(len<7?14:len*2);
|
|
||||||
if(!pw)
|
|
||||||
return; /* this will lead to a badly generated package */
|
|
||||||
|
|
||||||
if (len > 14)
|
if (len > 14)
|
||||||
len = 14;
|
len = 14;
|
||||||
|
|
||||||
@@ -257,7 +363,8 @@ static void mkhash(char *password,
|
|||||||
pw[i] = 0;
|
pw[i] = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
/* create LanManager hashed password */
|
/* Create LanManager hashed password. */
|
||||||
|
|
||||||
DES_key_schedule ks;
|
DES_key_schedule ks;
|
||||||
|
|
||||||
setup_des_key(pw, DESKEY(ks));
|
setup_des_key(pw, DESKEY(ks));
|
||||||
@@ -268,35 +375,46 @@ static void mkhash(char *password,
|
|||||||
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
|
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
|
||||||
DESKEY(ks), DES_ENCRYPT);
|
DESKEY(ks), DES_ENCRYPT);
|
||||||
|
|
||||||
memset(lmbuffer+16, 0, sizeof(lmbuffer)-16);
|
memset(lmbuffer + 16, 0, 21 - 16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* create LM responses */
|
|
||||||
calc_resp(lmbuffer, nonce, lmresp);
|
|
||||||
|
|
||||||
#ifdef USE_NTRESPONSES
|
#if USE_NTRESPONSES
|
||||||
|
static void utf8_to_unicode_le(unsigned char *dest, const char *src,
|
||||||
|
size_t srclen)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i=0; i<srclen; i++) {
|
||||||
|
dest[2*i] = (unsigned char)src[i];
|
||||||
|
dest[2*i+1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up nt hashed passwords
|
||||||
|
*/
|
||||||
|
static void mk_nt_hash(char *password, unsigned char *ntbuffer /* 21 bytes */)
|
||||||
|
{
|
||||||
|
size_t len = strlen(password);
|
||||||
|
unsigned char *pw = malloc(len*2);
|
||||||
|
|
||||||
|
utf8_to_unicode_le(pw, password, len);
|
||||||
|
|
||||||
{
|
{
|
||||||
/* create NT hashed password */
|
/* Create NT hashed password. */
|
||||||
MD4_CTX MD4;
|
MD4_CTX MD4;
|
||||||
|
|
||||||
len = strlen(password);
|
|
||||||
|
|
||||||
for (i=0; i<len; i++) {
|
|
||||||
pw[2*i] = password[i];
|
|
||||||
pw[2*i+1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
MD4_Init(&MD4);
|
MD4_Init(&MD4);
|
||||||
MD4_Update(&MD4, pw, 2*len);
|
MD4_Update(&MD4, pw, 2*len);
|
||||||
MD4_Final(ntbuffer, &MD4);
|
MD4_Final(ntbuffer, &MD4);
|
||||||
|
|
||||||
memset(ntbuffer+16, 0, sizeof(ntbuffer)-16);
|
memset(ntbuffer + 16, 0, 21 - 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
calc_resp(ntbuffer, nonce, ntresp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
free(pw);
|
free(pw);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -324,25 +442,28 @@ ntlm_sspi_cleanup(struct ntlmdata *ntlm)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8)
|
#define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff)
|
||||||
#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
|
#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
|
||||||
(((x) >>16)&0xff), ((x)>>24)
|
(((x) >>16)&0xff), (((x)>>24) & 0xff)
|
||||||
|
|
||||||
|
#define HOSTNAME_MAX 1024
|
||||||
|
|
||||||
/* this is for creating ntlm header output */
|
/* this is for creating ntlm header output */
|
||||||
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||||
bool proxy)
|
bool proxy)
|
||||||
{
|
{
|
||||||
const char *domain=""; /* empty */
|
const char *domain=""; /* empty */
|
||||||
const char *host=""; /* empty */
|
char host [HOSTNAME_MAX+ 1] = ""; /* empty */
|
||||||
#ifndef USE_WINDOWS_SSPI
|
#ifndef USE_WINDOWS_SSPI
|
||||||
int domlen=(int)strlen(domain);
|
size_t domlen = strlen(domain);
|
||||||
int hostlen = (int)strlen(host);
|
size_t hostlen = strlen(host);
|
||||||
int hostoff; /* host name offset */
|
size_t hostoff; /* host name offset */
|
||||||
int domoff; /* domain name offset */
|
size_t domoff; /* domain name offset */
|
||||||
#endif
|
#endif
|
||||||
size_t size;
|
size_t size;
|
||||||
char *base64=NULL;
|
char *base64=NULL;
|
||||||
unsigned char ntlmbuf[512]; /* enough, unless the host/domain is very long */
|
unsigned char ntlmbuf[1024]; /* enough, unless the user+host+domain is very
|
||||||
|
long */
|
||||||
|
|
||||||
/* point to the address of the pointer that holds the string to sent to the
|
/* point to the address of the pointer that holds the string to sent to the
|
||||||
server, which is for a plain host or for a HTTP proxy */
|
server, which is for a plain host or for a HTTP proxy */
|
||||||
@@ -399,11 +520,11 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
s_hSecDll = LoadLibrary("secur32.dll");
|
s_hSecDll = LoadLibrary("secur32.dll");
|
||||||
if (s_hSecDll != NULL) {
|
if (s_hSecDll != NULL) {
|
||||||
INIT_SECURITY_INTERFACE pInitSecurityInterface;
|
INIT_SECURITY_INTERFACE pInitSecurityInterface;
|
||||||
pInitSecurityInterface =
|
pInitSecurityInterface =
|
||||||
(INIT_SECURITY_INTERFACE)GetProcAddress(s_hSecDll,
|
(INIT_SECURITY_INTERFACE)GetProcAddress(s_hSecDll,
|
||||||
"InitSecurityInterfaceA");
|
"InitSecurityInterfaceA");
|
||||||
if (pInitSecurityInterface != NULL)
|
if (pInitSecurityInterface != NULL)
|
||||||
s_pSecFn = pInitSecurityInterface();
|
s_pSecFn = pInitSecurityInterface();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (s_pSecFn == NULL)
|
if (s_pSecFn == NULL)
|
||||||
@@ -500,8 +621,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
size = buf.cbBuffer;
|
size = buf.cbBuffer;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
hostoff = 32;
|
hostoff = 0;
|
||||||
domoff = hostoff + hostlen;
|
domoff = hostoff + hostlen; /* This is 0: remember that host and domain
|
||||||
|
are empty */
|
||||||
|
|
||||||
/* Create and send a type-1 message:
|
/* Create and send a type-1 message:
|
||||||
|
|
||||||
@@ -515,7 +637,11 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
32 start of data block
|
32 start of data block
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
#if USE_NTLM2SESSION
|
||||||
|
#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
|
||||||
|
#else
|
||||||
|
#define NTLM2FLAG 0
|
||||||
|
#endif
|
||||||
snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
|
snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
|
||||||
"\x01%c%c%c" /* 32-bit type = 1 */
|
"\x01%c%c%c" /* 32-bit type = 1 */
|
||||||
"%c%c%c%c" /* 32-bit NTLM flag field */
|
"%c%c%c%c" /* 32-bit NTLM flag field */
|
||||||
@@ -533,9 +659,11 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
0,0,0, /* part of type-1 long */
|
0,0,0, /* part of type-1 long */
|
||||||
|
|
||||||
LONGQUARTET(
|
LONGQUARTET(
|
||||||
NTLMFLAG_NEGOTIATE_OEM| /* 2 */
|
NTLMFLAG_NEGOTIATE_OEM|
|
||||||
NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */
|
NTLMFLAG_REQUEST_TARGET|
|
||||||
/* equals 0x0202 */
|
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||||
|
NTLM2FLAG|
|
||||||
|
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN
|
||||||
),
|
),
|
||||||
SHORTPAIR(domlen),
|
SHORTPAIR(domlen),
|
||||||
SHORTPAIR(domlen),
|
SHORTPAIR(domlen),
|
||||||
@@ -545,13 +673,34 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
SHORTPAIR(hostlen),
|
SHORTPAIR(hostlen),
|
||||||
SHORTPAIR(hostoff),
|
SHORTPAIR(hostoff),
|
||||||
0,0,
|
0,0,
|
||||||
host, domain);
|
host /* this is empty */, domain /* this is empty */);
|
||||||
|
|
||||||
/* initial packet length */
|
/* initial packet length */
|
||||||
size = 32 + hostlen + domlen;
|
size = 32 + hostlen + domlen;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* now keeper of the base64 encoded package size */
|
DEBUG_OUT({
|
||||||
|
fprintf(stderr, "**** TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
|
||||||
|
LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM|
|
||||||
|
NTLMFLAG_REQUEST_TARGET|
|
||||||
|
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||||
|
NTLM2FLAG|
|
||||||
|
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
|
||||||
|
NTLMFLAG_NEGOTIATE_OEM|
|
||||||
|
NTLMFLAG_REQUEST_TARGET|
|
||||||
|
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||||
|
NTLM2FLAG|
|
||||||
|
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
|
||||||
|
print_flags(stderr,
|
||||||
|
NTLMFLAG_NEGOTIATE_OEM|
|
||||||
|
NTLMFLAG_REQUEST_TARGET|
|
||||||
|
NTLMFLAG_NEGOTIATE_NTLM_KEY|
|
||||||
|
NTLM2FLAG|
|
||||||
|
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
|
||||||
|
fprintf(stderr, "\n****\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
/* now size is the size of the base64 encoded package size */
|
||||||
size = Curl_base64_encode((char *)ntlmbuf, size, &base64);
|
size = Curl_base64_encode((char *)ntlmbuf, size, &base64);
|
||||||
|
|
||||||
if(size >0 ) {
|
if(size >0 ) {
|
||||||
@@ -567,7 +716,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case NTLMSTATE_TYPE2:
|
case NTLMSTATE_TYPE2:
|
||||||
/* We received the type-2 already, create a type-3 message:
|
/* We received the type-2 message already, create a type-3 message:
|
||||||
|
|
||||||
Index Description Content
|
Index Description Content
|
||||||
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||||
@@ -622,14 +771,14 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
int lmrespoff;
|
int lmrespoff;
|
||||||
|
unsigned char lmresp[24]; /* fixed-size */
|
||||||
|
#if USE_NTRESPONSES
|
||||||
int ntrespoff;
|
int ntrespoff;
|
||||||
int useroff;
|
unsigned char ntresp[24]; /* fixed-size */
|
||||||
unsigned char lmresp[0x18]; /* fixed-size */
|
|
||||||
#ifdef USE_NTRESPONSES
|
|
||||||
unsigned char ntresp[0x18]; /* fixed-size */
|
|
||||||
#endif
|
#endif
|
||||||
|
size_t useroff;
|
||||||
const char *user;
|
const char *user;
|
||||||
int userlen;
|
size_t userlen;
|
||||||
|
|
||||||
user = strchr(userp, '\\');
|
user = strchr(userp, '\\');
|
||||||
if(!user)
|
if(!user)
|
||||||
@@ -637,31 +786,90 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
domain = userp;
|
domain = userp;
|
||||||
domlen = (int)(user - domain);
|
domlen = (user - domain);
|
||||||
user++;
|
user++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
user = userp;
|
user = userp;
|
||||||
userlen = (int)strlen(user);
|
userlen = strlen(user);
|
||||||
|
|
||||||
mkhash(passwdp, &ntlm->nonce[0], lmresp
|
if (gethostname(host, HOSTNAME_MAX)) {
|
||||||
#ifdef USE_NTRESPONSES
|
infof(conn->data, "gethostname() failed, continuing without!");
|
||||||
, ntresp
|
hostlen = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hostlen = strlen(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if USE_NTLM2SESSION
|
||||||
|
/* We don't support NTLM2 if we don't have USE_NTRESPONSES */
|
||||||
|
if (ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
|
||||||
|
unsigned char ntbuffer[0x18];
|
||||||
|
unsigned char tmp[0x18];
|
||||||
|
unsigned char md5sum[MD5_DIGEST_LENGTH];
|
||||||
|
MD5_CTX MD5;
|
||||||
|
unsigned char random[8];
|
||||||
|
|
||||||
|
/* Need to create 8 bytes random data */
|
||||||
|
Curl_ossl_seed(conn->data); /* Initiate the seed if not already done */
|
||||||
|
RAND_bytes(random,8);
|
||||||
|
|
||||||
|
/* 8 bytes random data as challenge in lmresp */
|
||||||
|
memcpy(lmresp,random,8);
|
||||||
|
/* Pad with zeros */
|
||||||
|
memset(lmresp+8,0,0x10);
|
||||||
|
|
||||||
|
/* Fill tmp with challenge(nonce?) + random */
|
||||||
|
memcpy(tmp,&ntlm->nonce[0],8);
|
||||||
|
memcpy(tmp+8,random,8);
|
||||||
|
|
||||||
|
MD5_Init(&MD5);
|
||||||
|
MD5_Update(&MD5, tmp, 16);
|
||||||
|
MD5_Final(md5sum, &MD5);
|
||||||
|
/* We shall only use the first 8 bytes of md5sum,
|
||||||
|
but the des code in lm_resp only encrypt the first 8 bytes */
|
||||||
|
mk_nt_hash(passwdp, ntbuffer);
|
||||||
|
lm_resp(ntbuffer, md5sum, ntresp);
|
||||||
|
|
||||||
|
/* End of NTLM2 Session code */
|
||||||
|
}
|
||||||
|
else {
|
||||||
#endif
|
#endif
|
||||||
);
|
|
||||||
|
|
||||||
domoff = 64; /* always */
|
#if USE_NTRESPONSES
|
||||||
|
unsigned char ntbuffer[0x18];
|
||||||
|
#endif
|
||||||
|
unsigned char lmbuffer[0x18];
|
||||||
|
|
||||||
|
#if USE_NTRESPONSES
|
||||||
|
mk_nt_hash(passwdp, ntbuffer);
|
||||||
|
lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mk_lm_hash(passwdp, lmbuffer);
|
||||||
|
lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
|
||||||
|
/* A safer but less compatible alternative is:
|
||||||
|
* lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
|
||||||
|
* See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
lmrespoff = 64; /* size of the message header */
|
||||||
|
#if USE_NTRESPONSES
|
||||||
|
ntrespoff = lmrespoff + 0x18;
|
||||||
|
domoff = ntrespoff + 0x18;
|
||||||
|
#else
|
||||||
|
domoff = lmrespoff + 0x18;
|
||||||
|
#endif
|
||||||
useroff = domoff + domlen;
|
useroff = domoff + domlen;
|
||||||
hostoff = useroff + userlen;
|
hostoff = useroff + userlen;
|
||||||
lmrespoff = hostoff + hostlen;
|
|
||||||
ntrespoff = lmrespoff + 0x18;
|
|
||||||
|
|
||||||
/* Create the big type-3 message binary blob */
|
/* Create the big type-3 message binary blob */
|
||||||
size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
|
size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
|
||||||
"NTLMSSP%c"
|
"NTLMSSP%c"
|
||||||
"\x03%c%c%c" /* type-3, 32 bits */
|
"\x03%c%c%c" /* type-3, 32 bits */
|
||||||
|
|
||||||
"%c%c%c%c" /* LanManager length + allocated space */
|
"%c%c" /* LanManager length */
|
||||||
|
"%c%c" /* LanManager allocated space */
|
||||||
"%c%c" /* LanManager offset */
|
"%c%c" /* LanManager offset */
|
||||||
"%c%c" /* 2 zeroes */
|
"%c%c" /* 2 zeroes */
|
||||||
|
|
||||||
@@ -683,14 +891,15 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
"%c%c" /* host length */
|
"%c%c" /* host length */
|
||||||
"%c%c" /* host allocated space */
|
"%c%c" /* host allocated space */
|
||||||
"%c%c" /* host offset */
|
"%c%c" /* host offset */
|
||||||
"%c%c%c%c%c%c" /* 6 zeroes */
|
|
||||||
|
|
||||||
"\xff\xff" /* message length */
|
|
||||||
"%c%c" /* 2 zeroes */
|
"%c%c" /* 2 zeroes */
|
||||||
|
|
||||||
"\x01\x82" /* flags */
|
"%c%c" /* session key length (unknown purpose) */
|
||||||
|
"%c%c" /* session key allocated space (unknown purpose) */
|
||||||
|
"%c%c" /* session key offset (unknown purpose) */
|
||||||
"%c%c" /* 2 zeroes */
|
"%c%c" /* 2 zeroes */
|
||||||
|
|
||||||
|
"%c%c%c%c" /* flags */
|
||||||
|
|
||||||
/* domain string */
|
/* domain string */
|
||||||
/* user string */
|
/* user string */
|
||||||
/* host string */
|
/* host string */
|
||||||
@@ -705,16 +914,17 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
SHORTPAIR(lmrespoff),
|
SHORTPAIR(lmrespoff),
|
||||||
0x0, 0x0,
|
0x0, 0x0,
|
||||||
|
|
||||||
#ifdef USE_NTRESPONSES
|
#if USE_NTRESPONSES
|
||||||
SHORTPAIR(0x18), /* NT-response length, twice */
|
SHORTPAIR(0x18), /* NT-response length, twice */
|
||||||
SHORTPAIR(0x18),
|
SHORTPAIR(0x18),
|
||||||
|
SHORTPAIR(ntrespoff),
|
||||||
|
0x0, 0x0,
|
||||||
#else
|
#else
|
||||||
0x0, 0x0,
|
0x0, 0x0,
|
||||||
0x0, 0x0,
|
0x0, 0x0,
|
||||||
#endif
|
|
||||||
SHORTPAIR(ntrespoff),
|
|
||||||
0x0, 0x0,
|
0x0, 0x0,
|
||||||
|
0x0, 0x0,
|
||||||
|
#endif
|
||||||
SHORTPAIR(domlen),
|
SHORTPAIR(domlen),
|
||||||
SHORTPAIR(domlen),
|
SHORTPAIR(domlen),
|
||||||
SHORTPAIR(domoff),
|
SHORTPAIR(domoff),
|
||||||
@@ -728,44 +938,68 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
SHORTPAIR(hostlen),
|
SHORTPAIR(hostlen),
|
||||||
SHORTPAIR(hostlen),
|
SHORTPAIR(hostlen),
|
||||||
SHORTPAIR(hostoff),
|
SHORTPAIR(hostoff),
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
|
||||||
|
|
||||||
0x0, 0x0,
|
0x0, 0x0,
|
||||||
|
|
||||||
0x0, 0x0);
|
0x0, 0x0,
|
||||||
|
0x0, 0x0,
|
||||||
|
0x0, 0x0,
|
||||||
|
0x0, 0x0,
|
||||||
|
|
||||||
/* size is now 64 */
|
LONGQUARTET(ntlm->flags));
|
||||||
size=64;
|
DEBUG_OUT(assert(size==64));
|
||||||
ntlmbuf[62]=ntlmbuf[63]=0;
|
|
||||||
|
|
||||||
/* Make sure that the user and domain strings fit in the target buffer
|
DEBUG_OUT(assert(size == lmrespoff));
|
||||||
before we copy them there. */
|
/* We append the binary hashes */
|
||||||
if(size + userlen + domlen >= sizeof(ntlmbuf)) {
|
if(size < (sizeof(ntlmbuf) - 0x18)) {
|
||||||
failf(conn->data, "user + domain name too big");
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&ntlmbuf[size], domain, domlen);
|
|
||||||
size += domlen;
|
|
||||||
|
|
||||||
memcpy(&ntlmbuf[size], user, userlen);
|
|
||||||
size += userlen;
|
|
||||||
|
|
||||||
/* we append the binary hashes to the end of the blob */
|
|
||||||
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
|
|
||||||
memcpy(&ntlmbuf[size], lmresp, 0x18);
|
memcpy(&ntlmbuf[size], lmresp, 0x18);
|
||||||
size += 0x18;
|
size += 0x18;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_NTRESPONSES
|
DEBUG_OUT({
|
||||||
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
|
fprintf(stderr, "**** TYPE3 header lmresp=");
|
||||||
|
print_hex(stderr, &ntlmbuf[lmrespoff], 0x18);
|
||||||
|
});
|
||||||
|
|
||||||
|
#if USE_NTRESPONSES
|
||||||
|
if(size < (sizeof(ntlmbuf) - 0x18)) {
|
||||||
|
DEBUG_OUT(assert(size == ntrespoff));
|
||||||
memcpy(&ntlmbuf[size], ntresp, 0x18);
|
memcpy(&ntlmbuf[size], ntresp, 0x18);
|
||||||
size += 0x18;
|
size += 0x18;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG_OUT({
|
||||||
|
fprintf(stderr, "\n ntresp=");
|
||||||
|
print_hex(stderr, &ntlmbuf[ntrespoff], 0x18);
|
||||||
|
});
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ntlmbuf[56] = (unsigned char)(size & 0xff);
|
DEBUG_OUT({
|
||||||
ntlmbuf[57] = (unsigned char)(size >> 8);
|
fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
|
||||||
|
LONGQUARTET(ntlm->flags), ntlm->flags);
|
||||||
|
print_flags(stderr, ntlm->flags);
|
||||||
|
fprintf(stderr, "\n****\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/* Make sure that the domain, user and host strings fit in the target
|
||||||
|
buffer before we copy them there. */
|
||||||
|
if(size + userlen + domlen + hostlen >= sizeof(ntlmbuf)) {
|
||||||
|
failf(conn->data, "user + domain + host name too big");
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
curlassert(size == domoff);
|
||||||
|
memcpy(&ntlmbuf[size], domain, domlen);
|
||||||
|
size += domlen;
|
||||||
|
|
||||||
|
curlassert(size == useroff);
|
||||||
|
memcpy(&ntlmbuf[size], user, userlen);
|
||||||
|
size += userlen;
|
||||||
|
|
||||||
|
curlassert(size == hostoff);
|
||||||
|
memcpy(&ntlmbuf[size], host, hostlen);
|
||||||
|
size += hostlen;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -810,8 +1044,8 @@ Curl_ntlm_cleanup(struct connectdata *conn)
|
|||||||
ntlm_sspi_cleanup(&conn->proxyntlm);
|
ntlm_sspi_cleanup(&conn->proxyntlm);
|
||||||
if (s_hSecDll != NULL) {
|
if (s_hSecDll != NULL) {
|
||||||
FreeLibrary(s_hSecDll);
|
FreeLibrary(s_hSecDll);
|
||||||
s_hSecDll = NULL;
|
s_hSecDll = NULL;
|
||||||
s_pSecFn = NULL;
|
s_pSecFn = NULL;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
(void)conn;
|
(void)conn;
|
||||||
|
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
#include "if2ip.h"
|
#include "if2ip.h"
|
||||||
|
|
||||||
#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN32__) && \
|
#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN__) && \
|
||||||
!defined(__riscos__) && !defined(__INTERIX) && !defined(NETWARE) && \
|
!defined(__riscos__) && !defined(__INTERIX) && !defined(NETWARE) && \
|
||||||
!defined(_AMIGASF)
|
!defined(_AMIGASF)
|
||||||
|
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
extern char *Curl_if2ip(const char *interf, char *buf, int buf_size);
|
extern char *Curl_if2ip(const char *interf, char *buf, int buf_size);
|
||||||
|
|
||||||
#ifdef __INTERIX
|
#ifdef __INTERIX
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
/* Nedelcho Stanev's work-around for SFU 3.0 */
|
/* Nedelcho Stanev's work-around for SFU 3.0 */
|
||||||
struct ifreq {
|
struct ifreq {
|
||||||
#define IFNAMSIZ 16
|
#define IFNAMSIZ 16
|
||||||
|
16
lib/ldap.c
16
lib/ldap.c
@@ -36,10 +36,12 @@
|
|||||||
#ifdef HAVE_SYS_STAT_H
|
#ifdef HAVE_SYS_STAT_H
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_MALLOC_H
|
||||||
|
#include <malloc.h>
|
||||||
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
# include <malloc.h>
|
|
||||||
# include <winldap.h>
|
# include <winldap.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -498,31 +500,31 @@ static char **split_str (char *str)
|
|||||||
/*
|
/*
|
||||||
* Unescape the LDAP-URL components
|
* Unescape the LDAP-URL components
|
||||||
*/
|
*/
|
||||||
static bool unescape_elements (LDAPURLDesc *ludp)
|
static bool unescape_elements (void *data, LDAPURLDesc *ludp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (ludp->lud_filter) {
|
if (ludp->lud_filter) {
|
||||||
ludp->lud_filter = curl_unescape(ludp->lud_filter, 0);
|
ludp->lud_filter = curl_easy_unescape(data, ludp->lud_filter, 0, NULL);
|
||||||
if (!ludp->lud_filter)
|
if (!ludp->lud_filter)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; ludp->lud_attrs && ludp->lud_attrs[i]; i++) {
|
for (i = 0; ludp->lud_attrs && ludp->lud_attrs[i]; i++) {
|
||||||
ludp->lud_attrs[i] = curl_unescape(ludp->lud_attrs[i], 0);
|
ludp->lud_attrs[i] = curl_easy_unescape(data, ludp->lud_attrs[i], 0, NULL);
|
||||||
if (!ludp->lud_attrs[i])
|
if (!ludp->lud_attrs[i])
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; ludp->lud_exts && ludp->lud_exts[i]; i++) {
|
for (i = 0; ludp->lud_exts && ludp->lud_exts[i]; i++) {
|
||||||
ludp->lud_exts[i] = curl_unescape(ludp->lud_exts[i], 0);
|
ludp->lud_exts[i] = curl_easy_unescape(data, ludp->lud_exts[i], 0, NULL);
|
||||||
if (!ludp->lud_exts[i])
|
if (!ludp->lud_exts[i])
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ludp->lud_dn) {
|
if (ludp->lud_dn) {
|
||||||
char *dn = ludp->lud_dn;
|
char *dn = ludp->lud_dn;
|
||||||
char *new_dn = curl_unescape(dn, 0);
|
char *new_dn = curl_easy_unescape(data, dn, 0, NULL);
|
||||||
|
|
||||||
free(dn);
|
free(dn);
|
||||||
ludp->lud_dn = new_dn;
|
ludp->lud_dn = new_dn;
|
||||||
@@ -633,7 +635,7 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
|
|||||||
LDAP_TRACE (("exts[%d] '%s'\n", i, ludp->lud_exts[i]));
|
LDAP_TRACE (("exts[%d] '%s'\n", i, ludp->lud_exts[i]));
|
||||||
|
|
||||||
success:
|
success:
|
||||||
if (!unescape_elements(ludp))
|
if (!unescape_elements(conn->data, ludp))
|
||||||
return LDAP_NO_MEMORY;
|
return LDAP_NO_MEMORY;
|
||||||
return LDAP_SUCCESS;
|
return LDAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@@ -3,19 +3,27 @@
|
|||||||
TMP_DIR = ../lib/.lib
|
TMP_DIR = ../lib/.lib
|
||||||
LIB_DIR = ../lib
|
LIB_DIR = ../lib
|
||||||
|
|
||||||
|
# Sets the SDK. 10.4u.sdk is the minimum for building a Universal Binary.
|
||||||
|
SDK = /Developer/SDKs/MacOSX10.4u.sdk
|
||||||
|
|
||||||
|
# Sets the minimum OSX version where the framework will work.
|
||||||
|
ENVP = MACOSX_DEPLOYMENT_TARGET=10.3
|
||||||
|
|
||||||
# for debug symbols add the -g option. Remove the -O2 option for best debuggin.
|
# for debug symbols add the -g option. Remove the -O2 option for best debuggin.
|
||||||
# Can be compiled with -O3 optimizations.
|
# Can be compiled with -O3 optimizations.
|
||||||
C_OPTIONS = \
|
C_OPTIONS = -isysroot $(SDK) \
|
||||||
-fno-common \
|
-fno-common \
|
||||||
-O2 \
|
-Os \
|
||||||
-DHAVE_CONFIG_H \
|
-DHAVE_CONFIG_H \
|
||||||
-DPIC \
|
-DPIC \
|
||||||
-I../lib \
|
-I../lib \
|
||||||
-I../include \
|
-I../include \
|
||||||
-Wall
|
-Wall \
|
||||||
|
-arch ppc \
|
||||||
|
-arch i386
|
||||||
|
|
||||||
LIBRARIES = /usr/lib/libssl.dylib \
|
LIBRARIES = $(SDK)/usr/lib/libssl.dylib \
|
||||||
/usr/lib/libcrypto.dylib \
|
$(SDK)/usr/lib/libcrypto.dylib \
|
||||||
-lz
|
-lz
|
||||||
|
|
||||||
# These libtool options are needed for a framework.
|
# These libtool options are needed for a framework.
|
||||||
@@ -25,7 +33,11 @@ LIBRARIES = /usr/lib/libssl.dylib \
|
|||||||
# For prebinding 0x10400000 was chosen a bit at random.
|
# For prebinding 0x10400000 was chosen a bit at random.
|
||||||
# If this overlaps one of you current libs just change in the makefile.
|
# If this overlaps one of you current libs just change in the makefile.
|
||||||
# This address is safe for all built in frameworks.
|
# This address is safe for all built in frameworks.
|
||||||
LINK_OPTIONS = -prebind \
|
LINK_OPTIONS = \
|
||||||
|
-Wl,-syslibroot,$(SDK) \
|
||||||
|
-arch ppc \
|
||||||
|
-arch i386 \
|
||||||
|
-prebind \
|
||||||
-seg1addr 0x10400000 \
|
-seg1addr 0x10400000 \
|
||||||
-dynamiclib \
|
-dynamiclib \
|
||||||
-install_name @executable_path/../Frameworks/libcurl.framework/libcurl
|
-install_name @executable_path/../Frameworks/libcurl.framework/libcurl
|
||||||
@@ -71,6 +83,7 @@ OBJECTS = $(TMP_DIR)/base64.o \
|
|||||||
$(TMP_DIR)/parsedate.o \
|
$(TMP_DIR)/parsedate.o \
|
||||||
$(TMP_DIR)/progress.o \
|
$(TMP_DIR)/progress.o \
|
||||||
$(TMP_DIR)/security.o \
|
$(TMP_DIR)/security.o \
|
||||||
|
$(TMP_DIR)/select.o \
|
||||||
$(TMP_DIR)/sendf.o \
|
$(TMP_DIR)/sendf.o \
|
||||||
$(TMP_DIR)/share.o \
|
$(TMP_DIR)/share.o \
|
||||||
$(TMP_DIR)/speedcheck.o \
|
$(TMP_DIR)/speedcheck.o \
|
||||||
@@ -81,6 +94,7 @@ OBJECTS = $(TMP_DIR)/base64.o \
|
|||||||
$(TMP_DIR)/strtok.o \
|
$(TMP_DIR)/strtok.o \
|
||||||
$(TMP_DIR)/strtoofft.o \
|
$(TMP_DIR)/strtoofft.o \
|
||||||
$(TMP_DIR)/telnet.o \
|
$(TMP_DIR)/telnet.o \
|
||||||
|
$(TMP_DIR)/tftp.o \
|
||||||
$(TMP_DIR)/timeval.o \
|
$(TMP_DIR)/timeval.o \
|
||||||
$(TMP_DIR)/transfer.o \
|
$(TMP_DIR)/transfer.o \
|
||||||
$(TMP_DIR)/url.o \
|
$(TMP_DIR)/url.o \
|
||||||
@@ -97,12 +111,16 @@ $(LIB_DIR) :
|
|||||||
# This builds the framework structure and links everything properly
|
# This builds the framework structure and links everything properly
|
||||||
$(LIB_DIR)/libcurl.framework: $(OBJECTS) $(LIB_DIR)/libcurl.plist
|
$(LIB_DIR)/libcurl.framework: $(OBJECTS) $(LIB_DIR)/libcurl.plist
|
||||||
mkdir -p $(LIB_DIR)/libcurl.framework/Versions/A/Resources
|
mkdir -p $(LIB_DIR)/libcurl.framework/Versions/A/Resources
|
||||||
$(CC) $(LINK_OPTIONS) $(LIBRARIES) $(OBJECTS) \
|
$(ENVP) $(CC) $(LINK_OPTIONS) $(LIBRARIES) $(OBJECTS) \
|
||||||
-o $(LIB_DIR)/libcurl.framework/Versions/A/libcurl
|
-o $(LIB_DIR)/libcurl.framework/Versions/A/libcurl
|
||||||
cp $(LIB_DIR)/libcurl.plist $(LIB_DIR)/libcurl.framework/Versions/A/Resources/Info.plist
|
cp $(LIB_DIR)/libcurl.plist $(LIB_DIR)/libcurl.framework/Versions/A/Resources/Info.plist
|
||||||
|
mkdir -p $(LIB_DIR)/libcurl.framework/Versions/A/Headers
|
||||||
|
cp $(LIB_DIR)/../include/curl/* $(LIB_DIR)/libcurl.framework/Versions/A/Headers
|
||||||
|
rm $(LIB_DIR)/libcurl.framework/Versions/A/Headers/Make*
|
||||||
cd $(LIB_DIR)/libcurl.framework; \
|
cd $(LIB_DIR)/libcurl.framework; \
|
||||||
ln -fs ./Versions/A/libcurl libcurl; \
|
ln -fs ./Versions/A/libcurl libcurl; \
|
||||||
ln -fs ./Versions/A/Resources Resources
|
ln -fs ./Versions/A/Resources Resources; \
|
||||||
|
ln -fs ./Versions/A/Headers Headers
|
||||||
cd $(LIB_DIR)/libcurl.framework/Versions; \
|
cd $(LIB_DIR)/libcurl.framework/Versions; \
|
||||||
ln -fs ./A Current
|
ln -fs ./A Current
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user