Compare commits
214 Commits
curl-7_22_
...
curl-7_23_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b9660dc4b2 | ||
![]() |
591c29aa49 | ||
![]() |
5e0aa3aac9 | ||
![]() |
7cfd10e255 | ||
![]() |
95ddbdb1db | ||
![]() |
6c4216b2a7 | ||
![]() |
10120e6ab5 | ||
![]() |
082e8a3b03 | ||
![]() |
fd765c627f | ||
![]() |
c8ffb4049a | ||
![]() |
e3166df1bb | ||
![]() |
06a83e8050 | ||
![]() |
2c09d21fdf | ||
![]() |
4851dafcf1 | ||
![]() |
73029dca5a | ||
![]() |
5b57c54416 | ||
![]() |
7fe9a50ab5 | ||
![]() |
6fa6567b92 | ||
![]() |
93e57d0628 | ||
![]() |
a873b95c21 | ||
![]() |
6bdeca967d | ||
![]() |
3f5e267b9d | ||
![]() |
f7dfe2b87a | ||
![]() |
af425efe83 | ||
![]() |
9cfc0c73a7 | ||
![]() |
49e3b2e03a | ||
![]() |
8bfc3a800a | ||
![]() |
b24c28e6c2 | ||
![]() |
0b315c1cf1 | ||
![]() |
e2928e1555 | ||
![]() |
f5bb370186 | ||
![]() |
bae4e3f035 | ||
![]() |
3676ec9680 | ||
![]() |
8ccf7bf8d7 | ||
![]() |
c761fcb055 | ||
![]() |
ddeab48245 | ||
![]() |
b0d42da26b | ||
![]() |
120025b7f8 | ||
![]() |
692f344118 | ||
![]() |
51e5a2bf3f | ||
![]() |
8165e05f29 | ||
![]() |
4c88866737 | ||
![]() |
4464583a6e | ||
![]() |
22502c9550 | ||
![]() |
39c6d18d9c | ||
![]() |
f4405d30e0 | ||
![]() |
e8d8843a02 | ||
![]() |
134e87c53b | ||
![]() |
515f11e79b | ||
![]() |
5850cc4808 | ||
![]() |
c295565569 | ||
![]() |
e771344611 | ||
![]() |
a4471045bb | ||
![]() |
cc76bbe79b | ||
![]() |
d7934b8bd4 | ||
![]() |
d67b75c9f9 | ||
![]() |
95d23d1ceb | ||
![]() |
a4758c3276 | ||
![]() |
9d0d1ada05 | ||
![]() |
629d2e3450 | ||
![]() |
90fcad63cb | ||
![]() |
1399c3da0d | ||
![]() |
ff0a295cdb | ||
![]() |
4fa0166173 | ||
![]() |
adaa3f6e14 | ||
![]() |
cf0f6729e7 | ||
![]() |
8036da870c | ||
![]() |
2621dd42a4 | ||
![]() |
2c8c46619b | ||
![]() |
ecbb08cea3 | ||
![]() |
491c5a497c | ||
![]() |
06e6755e87 | ||
![]() |
052a08ff59 | ||
![]() |
f6980bbf24 | ||
![]() |
d47d95ac3b | ||
![]() |
b229c8ca8b | ||
![]() |
337252bdd4 | ||
![]() |
840eff44f2 | ||
![]() |
ff03ee2a3c | ||
![]() |
62bcf005f4 | ||
![]() |
1a416cd27a | ||
![]() |
54ef47a5a0 | ||
![]() |
8af94de50a | ||
![]() |
1bab38780b | ||
![]() |
fd10c047df | ||
![]() |
ea12c72d12 | ||
![]() |
47e4537ac6 | ||
![]() |
03adff1eba | ||
![]() |
34770b8ab0 | ||
![]() |
880cf0bedc | ||
![]() |
bff78cc18e | ||
![]() |
584dc8b8af | ||
![]() |
a84b8a3922 | ||
![]() |
acaf466401 | ||
![]() |
71c9453393 | ||
![]() |
17f48fe879 | ||
![]() |
b82bd05354 | ||
![]() |
1958fe5745 | ||
![]() |
f7bfdbabf2 | ||
![]() |
7afccf7a1e | ||
![]() |
4a57bf6d10 | ||
![]() |
7296b2aa25 | ||
![]() |
6c849321d7 | ||
![]() |
0f19e0145a | ||
![]() |
ec73fd89ed | ||
![]() |
5bf0d74120 | ||
![]() |
fd87d9d2b9 | ||
![]() |
0572ad6d01 | ||
![]() |
aa7d5b946a | ||
![]() |
49b79b7631 | ||
![]() |
ca2c326361 | ||
![]() |
5c809178c2 | ||
![]() |
fa77f54a03 | ||
![]() |
bc007d8ef5 | ||
![]() |
d0dbd1e98e | ||
![]() |
4d327d20c6 | ||
![]() |
185ed3409a | ||
![]() |
d54bcebad4 | ||
![]() |
0435800f65 | ||
![]() |
56ed07f7df | ||
![]() |
381459fa65 | ||
![]() |
15e3e45170 | ||
![]() |
9dd85bced5 | ||
![]() |
5d45285cf3 | ||
![]() |
3d19e1eedf | ||
![]() |
7be872c389 | ||
![]() |
0c903ea189 | ||
![]() |
affed6725e | ||
![]() |
7f304ab84f | ||
![]() |
e709cc8627 | ||
![]() |
db060304de | ||
![]() |
5898a6a09b | ||
![]() |
57fffa728b | ||
![]() |
421a460278 | ||
![]() |
5793bc370c | ||
![]() |
ff5ba6e43d | ||
![]() |
9f2f8d5122 | ||
![]() |
bd158607ca | ||
![]() |
a2d4a98ddd | ||
![]() |
b4fccc1d8e | ||
![]() |
e2be8ceed9 | ||
![]() |
d439830621 | ||
![]() |
f4853db5e6 | ||
![]() |
d9f686db88 | ||
![]() |
a1087db5c6 | ||
![]() |
400055bfaa | ||
![]() |
5801ddb85c | ||
![]() |
38b5744266 | ||
![]() |
bc28a35dbc | ||
![]() |
d2a47021c0 | ||
![]() |
119f43360b | ||
![]() |
e276802ff8 | ||
![]() |
2d6796aac5 | ||
![]() |
bb94b92894 | ||
![]() |
230459dd00 | ||
![]() |
745014b726 | ||
![]() |
b3ea4881a8 | ||
![]() |
c6702c7d3f | ||
![]() |
8bab6700d9 | ||
![]() |
081e289315 | ||
![]() |
5f0764870f | ||
![]() |
87a45c7998 | ||
![]() |
dafa2fc944 | ||
![]() |
ef3f1f3146 | ||
![]() |
ba52e0a93b | ||
![]() |
40c27e299f | ||
![]() |
fa775b56de | ||
![]() |
fb3845a438 | ||
![]() |
3c3aa09c65 | ||
![]() |
01c172f5e8 | ||
![]() |
e9cf4cb791 | ||
![]() |
322f3d5af7 | ||
![]() |
c1057fc9aa | ||
![]() |
62b0fdca9e | ||
![]() |
3317160c19 | ||
![]() |
28526ed6e0 | ||
![]() |
e4172d934d | ||
![]() |
977825a68c | ||
![]() |
a6b69b64ad | ||
![]() |
9ecf53e154 | ||
![]() |
84221006c9 | ||
![]() |
a6c168b893 | ||
![]() |
dee7a08f64 | ||
![]() |
cd3cf55b47 | ||
![]() |
98a61d8e2e | ||
![]() |
81b41095ef | ||
![]() |
49c35a7f9f | ||
![]() |
57119495da | ||
![]() |
fdecb56cbf | ||
![]() |
00532341b5 | ||
![]() |
dae0b7d1aa | ||
![]() |
42be24af89 | ||
![]() |
260b0f4d0c | ||
![]() |
f50d4647d0 | ||
![]() |
805b4740c7 | ||
![]() |
a75888f1d3 | ||
![]() |
b4b642eb45 | ||
![]() |
c0159d0edc | ||
![]() |
93579cc363 | ||
![]() |
4322d512ea | ||
![]() |
e4819ae1ef | ||
![]() |
43c59765e1 | ||
![]() |
e533f59025 | ||
![]() |
e6697ef59c | ||
![]() |
ff9d858722 | ||
![]() |
f7583b2dea | ||
![]() |
6b33873c57 | ||
![]() |
90080da5fe | ||
![]() |
0216e517d0 | ||
![]() |
aff70e2e95 | ||
![]() |
6790a543d4 | ||
![]() |
2411adb40b | ||
![]() |
d52cd3bd17 | ||
![]() |
b7e242de0e |
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Place the curl source (including this makefile) into external/curl/ in the
|
||||
# Android source tree. Then build them with 'make curl' or just 'make libcurl'
|
||||
# from the Android root. Tested with Android 1.5 and 2.1
|
||||
# from the Android root. Tested with Android versions 1.5, 2.1-2.3
|
||||
#
|
||||
# Note: you must first create a curl_config.h file by running configure in the
|
||||
# Android environment. The only way I've found to do this is tricky. Perform a
|
||||
@@ -42,7 +42,7 @@
|
||||
# into the right place (but see the note about this below).
|
||||
#
|
||||
# Dan Fandrich
|
||||
# August 2010
|
||||
# November 2011
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
|
@@ -73,10 +73,15 @@ mingw32:
|
||||
mingw32-clean:
|
||||
$(MAKE) -C lib -f Makefile.m32 clean
|
||||
$(MAKE) -C src -f Makefile.m32 clean
|
||||
$(MAKE) -C docs/examples -f Makefile.m32 clean
|
||||
|
||||
mingw32-vclean mingw32-distclean:
|
||||
$(MAKE) -C lib -f Makefile.m32 vclean
|
||||
$(MAKE) -C src -f Makefile.m32 vclean
|
||||
$(MAKE) -C docs/examples -f Makefile.m32 vclean
|
||||
|
||||
mingw32-examples%:
|
||||
$(MAKE) -C docs/examples -f Makefile.m32 CFG=$@
|
||||
|
||||
mingw32%:
|
||||
$(MAKE) -C lib -f Makefile.m32 CFG=$@
|
||||
@@ -217,34 +222,27 @@ netware:
|
||||
$(MAKE) -C lib -f Makefile.netware
|
||||
$(MAKE) -C src -f Makefile.netware
|
||||
|
||||
netware-ares:
|
||||
$(MAKE) -C lib -f Makefile.netware WITH_ARES=1
|
||||
$(MAKE) -C src -f Makefile.netware WITH_ARES=1
|
||||
|
||||
netware-ssl:
|
||||
$(MAKE) -C lib -f Makefile.netware WITH_SSL=1
|
||||
$(MAKE) -C src -f Makefile.netware WITH_SSL=1
|
||||
|
||||
netware-ssl-zlib:
|
||||
$(MAKE) -C lib -f Makefile.netware WITH_SSL=1 WITH_ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.netware WITH_SSL=1 WITH_ZLIB=1
|
||||
|
||||
netware-ssh2-ssl-zlib:
|
||||
$(MAKE) -C lib -f Makefile.netware WITH_SSH2=1 WITH_SSL=1 WITH_ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.netware WITH_SSH2=1 WITH_SSL=1 WITH_ZLIB=1
|
||||
|
||||
netware-zlib:
|
||||
$(MAKE) -C lib -f Makefile.netware WITH_ZLIB=1
|
||||
$(MAKE) -C src -f Makefile.netware WITH_ZLIB=1
|
||||
|
||||
netware-clean:
|
||||
$(MAKE) -C lib -f Makefile.netware clean
|
||||
$(MAKE) -C src -f Makefile.netware clean
|
||||
$(MAKE) -C docs/examples -f Makefile.netware clean
|
||||
|
||||
netware-vclean netware-distclean:
|
||||
$(MAKE) -C lib -f Makefile.netware vclean
|
||||
$(MAKE) -C src -f Makefile.netware vclean
|
||||
$(MAKE) -C docs/examples -f Makefile.netware vclean
|
||||
|
||||
netware-install:
|
||||
$(MAKE) -C lib -f Makefile.netware install
|
||||
$(MAKE) -C src -f Makefile.netware install
|
||||
|
||||
netware-examples-%:
|
||||
$(MAKE) -C docs/examples -f Makefile.netware CFG=$@
|
||||
|
||||
netware-%:
|
||||
$(MAKE) -C lib -f Makefile.netware CFG=$@
|
||||
$(MAKE) -C src -f Makefile.netware CFG=$@
|
||||
|
||||
unix: all
|
||||
|
||||
unix-ssl: ssl
|
||||
|
@@ -1,6 +1,6 @@
|
||||
Curl and libcurl 7.22.0
|
||||
Curl and libcurl 7.24.0
|
||||
|
||||
Public curl releases: 124
|
||||
Public curl releases: 125
|
||||
Command line options: 149
|
||||
curl_easy_setopt() options: 192
|
||||
Public functions in libcurl: 58
|
||||
@@ -9,51 +9,11 @@ Curl and libcurl 7.22.0
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o Added CURLOPT_GSSAPI_DELEGATION
|
||||
o Added support for NTLM delegation to Samba's winbind daemon helper ntlm_auth
|
||||
o Display notes from setup file in testcurl.pl
|
||||
o BSD-style lwIP TCP/IP stack experimental support on Windows
|
||||
o OpenSSL: Use SSL_MODE_RELEASE_BUFFERS if available
|
||||
o --delegation was added to set CURLOPT_GSSAPI_DELEGATION
|
||||
o nss: start with no database if the selected database is broken
|
||||
o telnet: allow programatic use on Windows
|
||||
o
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o curl_getdate: detect some illegal dates better
|
||||
o when sending a request and an error is received before the (entire) request
|
||||
body is sent, stop sending the request and close the connection after
|
||||
having received the entire response. This is equally true if an Expect:
|
||||
100-continue header was used.
|
||||
o When using both -J and a single -O with multiple URLs, a missing init
|
||||
could cause a segfault
|
||||
o -J fixed for escaped quotes
|
||||
o -J fixed for file names with semicolons
|
||||
o progress: reset flags at transfer start to avoid wrong
|
||||
CURLINFO_CONTENT_LENGTH_DOWNLOAD
|
||||
o curl_gssapi: Guard files with HAVE_GSSAPI and rename private header
|
||||
o silence picky compilers: mark unused parameters
|
||||
o help output: more gnu like output
|
||||
o libtests: stop checking for CURLM_CALL_MULTI_PERFORM
|
||||
o setting a non-HTTP proxy with an environment variable or with CURLOPT_PROXY
|
||||
/ --proxy (without specifying CURLOPT_PROXYTYPE) would still make it do
|
||||
proxy-like HTTP requests
|
||||
o CURLFORM_BUFFER: insert filename as documented (regression)
|
||||
o SOCKS: fix the connect timeout
|
||||
o ftp_doing: bail out on error properly while multi interfacing
|
||||
o improved Content-Encoded decoding error message
|
||||
o asyn-thread: check for dotted addresses before thread starts
|
||||
o cmake: find winsock when building on windows
|
||||
o Curl_retry_request: check return code
|
||||
o cookies: handle 'secure=' as if it was 'secure'
|
||||
o tests: break busy loops in tests 502, 555, and 573
|
||||
o FTP: fix proxy connect race condition with multi interface and SOCKS proxy
|
||||
o RTSP: GET_PARAMETER requests have a body
|
||||
o fixed several memory leaks in OOM situations
|
||||
o bad expire(0) caused multi_socket API to hang
|
||||
o Avoid ftruncate() static define with mingw64
|
||||
o mk-ca-bundle.pl: ignore untrusted certs
|
||||
o builds with PolarSSL 1.0.0
|
||||
o
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
@@ -62,11 +22,6 @@ This release includes the following known bugs:
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Paolo Piacentini, Steven Parkes, Adam Tkac, Ben Winslow, Dan Fandrich,
|
||||
Julien Chaffraix, Kamil Dudka, Mandy Wu, Michael Mueller, Patrick Monnerat,
|
||||
Yang Tse, Paul Howarth, Garrett Holmstrom, Peter Hjalmarsson, Herve Amblard,
|
||||
Christian Hagele, Richard Silverman, Henry Ludemann, Cristian Rodriguez,
|
||||
Steve Holme, Jim Hollinger, Pau Garcia i Quiles, Fabian Keil, Wu Yongzheng,
|
||||
Adriano Meirelles, Jeff Pohlmeyer
|
||||
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
@@ -51,7 +51,7 @@ CURL_DEF_TOKEN $1
|
||||
],[
|
||||
tmp_exp=`eval "$ac_cpp conftest.$ac_ext" 2>/dev/null | \
|
||||
"$GREP" CURL_DEF_TOKEN 2>/dev/null | \
|
||||
"$SED" 's/.*CURL_DEF_TOKEN[[ ]]//' 2>/dev/null | \
|
||||
"$SED" 's/.*CURL_DEF_TOKEN[[ ]][[ ]]*//' 2>/dev/null | \
|
||||
"$SED" 's/[["]][[ ]]*[["]]//g' 2>/dev/null`
|
||||
if test -z "$tmp_exp" || test "$tmp_exp" = "$1"; then
|
||||
tmp_exp=""
|
||||
|
16
buildconf
16
buildconf
@@ -80,7 +80,7 @@ removethis(){
|
||||
# Ensure that buildconf runs from the subdirectory where configure.ac lives
|
||||
#
|
||||
if test ! -f configure.ac ||
|
||||
test ! -f src/main.c ||
|
||||
test ! -f src/tool_main.c ||
|
||||
test ! -f lib/urldata.h ||
|
||||
test ! -f include/curl/curl.h; then
|
||||
echo "Can not run buildconf from outside of curl's source subdirectory!"
|
||||
@@ -89,7 +89,9 @@ if test ! -f configure.ac ||
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# autoconf 2.57 or newer
|
||||
# autoconf 2.57 or newer. Unpatched version 2.67 does not generate proper
|
||||
# configure script. Unpatched version 2.68 is simply unusable, we should
|
||||
# disallow 2.68 usage.
|
||||
#
|
||||
need_autoconf="2.57"
|
||||
ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|head -n 1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
||||
@@ -108,7 +110,15 @@ if test "$1" = "2" -a "$2" -lt "57" || test "$1" -lt "2"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "buildconf: autoconf version $ac_version (ok)"
|
||||
if test "$1" = "2" -a "$2" -eq "67"; then
|
||||
echo "buildconf: autoconf version $ac_version (BAD)"
|
||||
echo " Unpatched version generates broken configure script."
|
||||
elif test "$1" = "2" -a "$2" -eq "68"; then
|
||||
echo "buildconf: autoconf version $ac_version (BAD)"
|
||||
echo " Unpatched version generates unusable configure script."
|
||||
else
|
||||
echo "buildconf: autoconf version $ac_version (ok)"
|
||||
fi
|
||||
|
||||
am4te_version=`${AUTOM4TE:-autom4te} --version 2>/dev/null|head -n 1| sed -e 's/autom4te\(.*\)/\1/' -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
||||
if test -z "$am4te_version"; then
|
||||
|
@@ -12,12 +12,6 @@ may have been fixed since this was written!
|
||||
http://curl.haxx.se/mail/lib-2009-10/0024.html
|
||||
http://curl.haxx.se/bug/view.cgi?id=2944325
|
||||
|
||||
74. The HTTP spec allows headers to be merged and become comma-separated
|
||||
instead of being repeated several times. This also include Authenticate: and
|
||||
Proxy-Authenticate: headers and while this hardly every happens in real life
|
||||
it will confuse libcurl which does not properly support it for all headers -
|
||||
like those Authenticate headers.
|
||||
|
||||
73. if a connection is made to a FTP server but the server then just never
|
||||
sends the 220 response or otherwise is dead slow, libcurl will not
|
||||
acknowledge the connection timeout during that phase but only the "real"
|
||||
|
34
docs/THANKS
34
docs/THANKS
@@ -9,12 +9,16 @@ Aaron Orenstein
|
||||
Adam D. Moss
|
||||
Adam Light
|
||||
Adam Piggott
|
||||
Adam Tkac
|
||||
Adrian Schuur
|
||||
Adriano Meirelles
|
||||
Akos Pasztory
|
||||
Alan Pinstein
|
||||
Albert Chin
|
||||
Albert Chin-A-Young
|
||||
Albert Choy
|
||||
Ale Vesely
|
||||
Alejandro Alvarez
|
||||
Aleksandar Milivojevic
|
||||
Alessandro Vesely
|
||||
Alex Bligh
|
||||
@@ -30,6 +34,7 @@ Alexander Zhuravlev
|
||||
Alexey Borzov
|
||||
Alexey Pesternikov
|
||||
Alexey Simak
|
||||
Alexey Zakhlestin
|
||||
Alexis Carvalho
|
||||
Alfred Gebert
|
||||
Allen Pulsifer
|
||||
@@ -64,6 +69,7 @@ Andy Tsouladze
|
||||
Angus Mackay
|
||||
Anthony Bryan
|
||||
Antoine Calando
|
||||
Anton Bychkov
|
||||
Anton Kalmykov
|
||||
Arkadiusz Miskiewicz
|
||||
Armel Asselin
|
||||
@@ -81,6 +87,7 @@ Ben Greear
|
||||
Ben Madsen
|
||||
Ben Noordhuis
|
||||
Ben Van Hof
|
||||
Ben Winslow
|
||||
Benbuck Nason
|
||||
Benjamin Gerard
|
||||
Bernard Leak
|
||||
@@ -126,6 +133,7 @@ Chris Gaukroger
|
||||
Chris Maltby
|
||||
Chris Mumford
|
||||
Chris Smowton
|
||||
Christian Hagele
|
||||
Christian Krause
|
||||
Christian Kurz
|
||||
Christian Robottom Reis
|
||||
@@ -136,6 +144,7 @@ Christophe Legry
|
||||
Christopher Conroy
|
||||
Christopher Palow
|
||||
Christopher R. Palmer
|
||||
Christopher Stone
|
||||
Ciprian Badescu
|
||||
Claes Jakobsson
|
||||
Clarence Gardner
|
||||
@@ -150,6 +159,7 @@ Craig A West
|
||||
Craig Davison
|
||||
Craig Markwardt
|
||||
Cris Bailiff
|
||||
Cristian Rodriguez
|
||||
Curt Bogmine
|
||||
Cyrill Osterwalder
|
||||
Dagobert Michelsen
|
||||
@@ -220,6 +230,7 @@ Dmitry Rechkin
|
||||
Dolbneff A.V
|
||||
Domenico Andreoli
|
||||
Dominick Meglio
|
||||
Dominique Leuenberger
|
||||
Doug Kaufman
|
||||
Doug Porter
|
||||
Douglas E. Wegscheid
|
||||
@@ -260,6 +271,7 @@ Erwin Authried
|
||||
Eugene Kotlyarov
|
||||
Evan Jordan
|
||||
Eygene Ryabinkin
|
||||
Fabian Hiernaux
|
||||
Fabian Keil
|
||||
Fabrizio Ammollo
|
||||
Fedor Karpelevitch
|
||||
@@ -272,11 +284,13 @@ Frank Keeney
|
||||
Frank McGeough
|
||||
Frank Meier
|
||||
Frank Ticheler
|
||||
Frank Van Uffelen
|
||||
Fred Machado
|
||||
Fred New
|
||||
Fred Noz
|
||||
Frederic Lepied
|
||||
Gabriel Kuri
|
||||
Garrett Holmstrom
|
||||
Gary Maxwell
|
||||
Gautam Kachroo
|
||||
Gautam Mani
|
||||
@@ -300,6 +314,7 @@ Giuseppe Attardi
|
||||
Giuseppe D'Ambrosio
|
||||
Glen Nakamura
|
||||
Glen Scott
|
||||
Gokhan Sengun
|
||||
Grant Erickson
|
||||
Greg Hewgill
|
||||
Greg Morse
|
||||
@@ -325,6 +340,7 @@ Heinrich Ko
|
||||
Hendrik Visage
|
||||
Henrik Storner
|
||||
Henry Ludemann
|
||||
Herve Amblard
|
||||
Hidemoto Nakada
|
||||
Hoi-Ho Chan
|
||||
Hongli Lai
|
||||
@@ -386,11 +402,13 @@ Jeffrey Pohlmeyer
|
||||
Jeremy Friesner
|
||||
Jerome Muffat-Meridol
|
||||
Jerome Vouillon
|
||||
Jerry Wu
|
||||
Jes Badwal
|
||||
Jesper Jensen
|
||||
Jesse Noller
|
||||
Jim Drash
|
||||
Jim Freeman
|
||||
Jim Hollinger
|
||||
Jim Meyering
|
||||
Jocelyn Jaubert
|
||||
Joe Halpin
|
||||
@@ -434,6 +452,7 @@ Juergen Wilke
|
||||
Jukka Pihl
|
||||
Julian Noble
|
||||
Julien Chaffraix
|
||||
Julien Royer
|
||||
Jun-ichiro itojun Hagino
|
||||
Jurij Smakov
|
||||
Justin Fletcher
|
||||
@@ -505,12 +524,14 @@ Luke Call
|
||||
Luong Dinh Dung
|
||||
Maciej Karpiuk
|
||||
Maciej W. Rozycki
|
||||
Mandy Wu
|
||||
Manfred Schwarb
|
||||
Manuel Massing
|
||||
Marc Boucher
|
||||
Marc Kleine-Budde
|
||||
Marcel Roelofs
|
||||
Marcelo Juchem
|
||||
Marcin Adamski
|
||||
Marcin Konicki
|
||||
Marco G. Salvagno
|
||||
Marco Maggi
|
||||
@@ -566,6 +587,7 @@ Michael Goffioul
|
||||
Michael Jahn
|
||||
Michael Jerris
|
||||
Michael Mealling
|
||||
Michael Mueller
|
||||
Michael Smith
|
||||
Michael Stillwell
|
||||
Michael Wallner
|
||||
@@ -620,6 +642,7 @@ Olaf St
|
||||
Oren Tirosh
|
||||
Ori Avtalion
|
||||
P R Schaffner
|
||||
Paolo Piacentini
|
||||
Pascal Terjan
|
||||
Pasha Kuznetsov
|
||||
Pat Ray
|
||||
@@ -628,6 +651,7 @@ Patrick Monnerat
|
||||
Patrick Scott
|
||||
Patrick Smith
|
||||
Patrik Thunstrom
|
||||
Pau Garcia i Quiles
|
||||
Paul Harrington
|
||||
Paul Howarth
|
||||
Paul Marquis
|
||||
@@ -645,6 +669,7 @@ Pete Su
|
||||
Peter Bray
|
||||
Peter Forret
|
||||
Peter Heuchert
|
||||
Peter Hjalmarsson
|
||||
Peter Korsgaard
|
||||
Peter Lamberg
|
||||
Peter O'Gorman
|
||||
@@ -783,6 +808,7 @@ Stephen Kick
|
||||
Stephen More
|
||||
Sterling Hughes
|
||||
Steve Green
|
||||
Steve Holme
|
||||
Steve Lhomme
|
||||
Steve Little
|
||||
Steve Marx
|
||||
@@ -791,6 +817,7 @@ Steve Roskowski
|
||||
Steven Bazyl
|
||||
Steven G. Johnson
|
||||
Steven M. Schweda
|
||||
Steven Parkes
|
||||
Stoned Elipot
|
||||
Sven Anders
|
||||
Sven Neuhaus
|
||||
@@ -798,10 +825,12 @@ Sven Wegener
|
||||
S<EFBFBD>bastien Willemijns
|
||||
T. Bharath
|
||||
T. Yamada
|
||||
Taneli Vahakangas
|
||||
Tanguy Fautre
|
||||
Temprimus
|
||||
Thomas J. Moore
|
||||
Thomas Klausner
|
||||
Thomas L. Shinnick
|
||||
Thomas Lopatic
|
||||
Thomas Schwinge
|
||||
Thomas Tonino
|
||||
@@ -810,6 +839,7 @@ Tim Baker
|
||||
Tim Bartley
|
||||
Tim Chen
|
||||
Tim Costello
|
||||
Tim Harder
|
||||
Tim Newsome
|
||||
Tim Sneddon
|
||||
Tinus van den Berg
|
||||
@@ -825,6 +855,7 @@ Tom Mattison
|
||||
Tom Moers
|
||||
Tom Mueller
|
||||
Tom Regner
|
||||
Tom Wright
|
||||
Tom Zerucha
|
||||
Tomas Pospisek
|
||||
Tomas Szepe
|
||||
@@ -854,6 +885,7 @@ Vincent Sanders
|
||||
Vincent Torri
|
||||
Vlad Grachov
|
||||
Vlad Ureche
|
||||
Vladimir Grishchenko
|
||||
Vladimir Lazarenko
|
||||
Vojtech Janota
|
||||
Vojtech Minarik
|
||||
@@ -866,10 +898,12 @@ Wesley Miaw
|
||||
Wez Furlong
|
||||
Wilfredo Sanchez
|
||||
Wojciech Zwiefka
|
||||
Wu Yongzheng
|
||||
Xavier Bouchoux
|
||||
Yang Tse
|
||||
Yarram Sunil
|
||||
Yehoshua Hershberg
|
||||
Yukihiro Kawada
|
||||
Yuriy Sosov
|
||||
Yves Lejeune
|
||||
Zmey Petroff
|
||||
|
@@ -99,6 +99,7 @@
|
||||
15.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
15.7 remove progress meter from libcurl
|
||||
15.8 remove 'curl_httppost' from public
|
||||
15.9 have form functions use CURL handle argument
|
||||
|
||||
==============================================================================
|
||||
|
||||
@@ -559,3 +560,11 @@ to provide the data to send.
|
||||
|
||||
Changing them to return a private handle will benefit the implementation and
|
||||
allow us much greater freedoms while still maintining a solid API and ABI.
|
||||
|
||||
15.9 have form functions use CURL handle argument
|
||||
|
||||
curl_formadd() and curl_formget() both currently have no CURL handle
|
||||
argument, but both can use a callback that is set in the easy handle, and
|
||||
thus curl_formget() with callback cannot function without first having
|
||||
curl_easy_perform() (or similar) called - which is hard to grasp and a design
|
||||
mistake.
|
||||
|
17
docs/curl.1
17
docs/curl.1
@@ -110,7 +110,8 @@ the --option version of them. (This concept with --no options was added in
|
||||
7.19.0. Previously most options were toggled on/off on repeated use of the
|
||||
same command line option.)
|
||||
.IP "-#, --progress-bar"
|
||||
Make curl display progress information as a progress bar instead of the
|
||||
Make curl display progress as a simple progress bar instead of the standard,
|
||||
more informational, meter.
|
||||
.IP "-0, --http1.0"
|
||||
(HTTP) Forces curl to issue its requests using HTTP 1.0 instead of using its
|
||||
internally preferred: HTTP 1.1.
|
||||
@@ -363,7 +364,7 @@ passive mode you need to not use \fI-P, --ftp-port\fP or force it with
|
||||
transfers. Curl will normally always first attempt to use EPSV before PASV,
|
||||
but with this option, it will not try using EPSV.
|
||||
|
||||
\fB--epsv\fP can be used to explicitly enable EPRT again and \fB--no-epsv\fP
|
||||
\fB--epsv\fP can be used to explicitly enable EPSV again and \fB--no-epsv\fP
|
||||
is an alias for \fB--disable-epsv\fP.
|
||||
|
||||
Disabling EPSV only changes the passive behavior. If you want to switch to
|
||||
@@ -592,7 +593,9 @@ header will be used instead of the internal one. This allows you to make even
|
||||
trickier stuff than curl would normally do. You should not replace internally
|
||||
set headers without knowing perfectly well what you're doing. Remove an
|
||||
internal header by giving a replacement without content on the right side of
|
||||
the colon, as in: -H \&"Host:".
|
||||
the colon, as in: -H \&"Host:". If you send the custom header with no-value then
|
||||
its header must be terminated with a semicolon, such as \-H "X-Custom-Header;"
|
||||
to send "X-Custom-Header:".
|
||||
|
||||
curl will make sure that each header you add/replace is sent with the proper
|
||||
end-of-line marker, you should thus \fBnot\fP add that as a part of the header
|
||||
@@ -1592,6 +1595,14 @@ Specifies a custom FTP command to use instead of LIST when doing file lists
|
||||
with FTP.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
|
||||
.IP "--xattr"
|
||||
When saving output to a file, this option tells curl to store certain file
|
||||
metadata in extened file attributes. Currently, the URL is stored in the
|
||||
xdg.origin.url attribute and, for HTTP, the content type is stored in
|
||||
the mime_type attribute. If the file system does not support extended
|
||||
attributes, a warning is issued.
|
||||
|
||||
.IP "-y, --speed-time <time>"
|
||||
If a download is slower than speed-limit bytes per second during a speed-time
|
||||
period, the download gets aborted. If speed-time is used, the default
|
||||
|
1
docs/examples/.gitignore
vendored
1
docs/examples/.gitignore
vendored
@@ -26,6 +26,7 @@ multi-single
|
||||
persistant
|
||||
post-callback
|
||||
postit2
|
||||
progressfunc
|
||||
resolve
|
||||
rtsp
|
||||
sendrecv
|
||||
|
@@ -23,7 +23,7 @@
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
EXTRA_DIST = README Makefile.example Makefile.inc Makefile.m32 \
|
||||
makefile.dj $(COMPLICATED_EXAMPLES)
|
||||
Makefile.netware makefile.dj printf_macro.h $(COMPLICATED_EXAMPLES)
|
||||
|
||||
# Specify our include paths here, and do it relative to $(top_srcdir) and
|
||||
# $(top_builddir), to ensure that these paths which belong to the library
|
||||
|
@@ -4,7 +4,8 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
|
||||
https multi-app multi-debugcallback multi-double multi-post multi-single \
|
||||
persistant post-callback postit2 sepheaders simple simplepost simplessl \
|
||||
sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
|
||||
smtp-multi simplesmtp smtp-tls rtsp externalsocket resolve
|
||||
smtp-multi simplesmtp smtp-tls rtsp externalsocket resolve \
|
||||
progressfunc
|
||||
|
||||
# These examples require external dependencies that may not be commonly
|
||||
# available on POSIX systems, so don't bother attempting to compile them here.
|
||||
|
@@ -19,31 +19,50 @@
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
#########################################################################
|
||||
#
|
||||
## Makefile for building curl examples with MingW32
|
||||
## and optionally OpenSSL (0.9.8), libssh2 (0.18), zlib (1.2.3)
|
||||
## Makefile for building curl examples with MingW (GCC-3.2 or later)
|
||||
## and optionally OpenSSL (0.9.8), libssh2 (1.3), zlib (1.2.5), librtmp (2.3)
|
||||
##
|
||||
## Usage:
|
||||
## mingw32-make -f Makefile.m32 [SSL=1] [SSH2=1] [ZLIB=1] [SSPI=1] [IPV6=1] [DYN=1]
|
||||
## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...]
|
||||
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-spi-winidn
|
||||
##
|
||||
## Hint: you can also set environment vars to control the build, f.e.:
|
||||
## set ZLIB_PATH=c:/zlib-1.2.3
|
||||
## set ZLIB_PATH=c:/zlib-1.2.5
|
||||
## set ZLIB=1
|
||||
##
|
||||
#########################################################################
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.3
|
||||
ZLIB_PATH = ../../../zlib-1.2.5
|
||||
endif
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.8k
|
||||
OPENSSL_PATH = ../../../openssl-0.9.8r
|
||||
endif
|
||||
ifndef OPENSSL_LIBPATH
|
||||
OPENSSL_LIBPATH = $(OPENSSL_PATH)/out
|
||||
endif
|
||||
ifndef OPENSSL_LIBS
|
||||
OPENSSL_LIBS = -leay32 -lssl32
|
||||
endif
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.2
|
||||
LIBSSH2_PATH = ../../../libssh2-1.3.0
|
||||
endif
|
||||
# Edit the path below to point to the base of your librtmp package.
|
||||
ifndef LIBRTMP_PATH
|
||||
LIBRTMP_PATH = ../../../librtmp-2.3
|
||||
endif
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../../libidn-1.18
|
||||
endif
|
||||
# Edit the path below to point to the base of your MS idndlpackage.
|
||||
# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1
|
||||
# http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ad6158d7-ddba-416a-9109-07607425a815
|
||||
ifndef WINIDN_PATH
|
||||
WINIDN_PATH = ../../../Microsoft IDN Mitigation APIs
|
||||
endif
|
||||
# Edit the path below to point to the base of your Novell LDAP NDK.
|
||||
ifndef LDAP_SDK
|
||||
@@ -51,25 +70,76 @@ LDAP_SDK = c:/novell/ndk/cldapsdk/win32
|
||||
endif
|
||||
|
||||
PROOT = ../..
|
||||
ARES_LIB = $(PROOT)/ares
|
||||
|
||||
SSL = 1
|
||||
ZLIB = 1
|
||||
# Edit the path below to point to the base of your c-ares package.
|
||||
ifndef LIBCARES_PATH
|
||||
LIBCARES_PATH = $(PROOT)/ares
|
||||
endif
|
||||
|
||||
# Edit the var below to set to your architecture or set environment var.
|
||||
ifndef ARCH
|
||||
ARCH = w32
|
||||
endif
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -O2 -Wall
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
ifeq ($(ARCH),w64)
|
||||
CFLAGS += -D_AMD64_
|
||||
endif
|
||||
# comment LDFLAGS below to keep debug info
|
||||
LDFLAGS = -s
|
||||
RC = windres
|
||||
RCFLAGS = --include-dir=$(PROOT)/include -O COFF -i
|
||||
RM = del /q /f > NUL 2>&1
|
||||
|
||||
RM = del /q /f 2>NUL
|
||||
CP = copy
|
||||
|
||||
########################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
ifeq ($(findstring -dyn,$(CFG)),-dyn)
|
||||
DYN = 1
|
||||
endif
|
||||
ifeq ($(findstring -ares,$(CFG)),-ares)
|
||||
ARES = 1
|
||||
endif
|
||||
ifeq ($(findstring -rtmp,$(CFG)),-rtmp)
|
||||
RTMP = 1
|
||||
SSL = 1
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -ssh2,$(CFG)),-ssh2)
|
||||
SSH2 = 1
|
||||
SSL = 1
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -ssl,$(CFG)),-ssl)
|
||||
SSL = 1
|
||||
endif
|
||||
ifeq ($(findstring -zlib,$(CFG)),-zlib)
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -idn,$(CFG)),-idn)
|
||||
IDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -winidn,$(CFG)),-winidn)
|
||||
WINIDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -sspi,$(CFG)),-sspi)
|
||||
SSPI = 1
|
||||
endif
|
||||
ifeq ($(findstring -spnego,$(CFG)),-spnego)
|
||||
SPNEGO = 1
|
||||
endif
|
||||
ifeq ($(findstring -ldaps,$(CFG)),-ldaps)
|
||||
LDAPS = 1
|
||||
endif
|
||||
ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
|
||||
IPV6 = 1
|
||||
endif
|
||||
|
||||
INCLUDES = -I. -I$(PROOT) -I$(PROOT)/include -I$(PROOT)/lib
|
||||
LINK = $(CC) $(LDFLAGS) -o $@
|
||||
|
||||
ifdef DYN
|
||||
curl_DEPENDENCIES = $(PROOT)/lib/libcurldll.a $(PROOT)/lib/libcurl.dll
|
||||
@@ -81,34 +151,45 @@ else
|
||||
endif
|
||||
ifdef ARES
|
||||
ifndef DYN
|
||||
curl_DEPENDENCIES += $(ARES_LIB)/libcares.a
|
||||
curl_DEPENDENCIES += $(LIBCARES_PATH)/libcares.a
|
||||
endif
|
||||
CFLAGS += -DUSE_ARES
|
||||
curl_LDADD += -L$(ARES_LIB) -lcares
|
||||
curl_LDADD += -L"$(LIBCARES_PATH)" -lcares
|
||||
endif
|
||||
ifdef RTMP
|
||||
CFLAGS += -DUSE_LIBRTMP
|
||||
curl_LDADD += -L"$(LIBRTMP_PATH)/librtmp" -lrtmp -lwinmm
|
||||
endif
|
||||
ifdef SSH2
|
||||
CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H
|
||||
curl_LDADD += -L$(LIBSSH2_PATH)/win32 -lssh2
|
||||
curl_LDADD += -L"$(LIBSSH2_PATH)/win32" -lssh2
|
||||
endif
|
||||
ifdef SSL
|
||||
INCLUDES += -I"$(OPENSSL_PATH)/outinc"
|
||||
CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H
|
||||
ifdef DYN
|
||||
curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32
|
||||
else
|
||||
curl_LDADD += -L$(OPENSSL_PATH)/out -lssl -lcrypto -lgdi32
|
||||
endif
|
||||
curl_LDADD += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS)
|
||||
endif
|
||||
ifdef ZLIB
|
||||
INCLUDES += -I"$(ZLIB_PATH)"
|
||||
CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
|
||||
curl_LDADD += -L$(ZLIB_PATH) -lz
|
||||
curl_LDADD += -L"$(ZLIB_PATH)" -lz
|
||||
endif
|
||||
ifdef IDN
|
||||
CFLAGS += -DUSE_LIBIDN
|
||||
curl_LDADD += -L"$(LIBIDN_PATH)/lib" -lidn
|
||||
else
|
||||
ifdef WINIDN
|
||||
CFLAGS += -DUSE_WIN32_IDN
|
||||
curl_LDADD += -L"$(WINIDN_PATH)" -lnormaliz
|
||||
endif
|
||||
endif
|
||||
ifdef SSPI
|
||||
CFLAGS += -DUSE_WINDOWS_SSPI
|
||||
endif
|
||||
ifdef SPNEGO
|
||||
CFLAGS += -DHAVE_SPNEGO
|
||||
endif
|
||||
ifdef IPV6
|
||||
CFLAGS += -DENABLE_IPV6
|
||||
CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501
|
||||
endif
|
||||
ifdef LDAPS
|
||||
CFLAGS += -DHAVE_LDAP_SSL
|
||||
@@ -123,32 +204,32 @@ ifdef USE_LDAP_OPENLDAP
|
||||
endif
|
||||
ifndef USE_LDAP_NOVELL
|
||||
ifndef USE_LDAP_OPENLDAP
|
||||
curl_LDADD += -lwldap32
|
||||
curl_LDADD += -lwldap32
|
||||
endif
|
||||
endif
|
||||
curl_LDADD += -lws2_32
|
||||
COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
|
||||
|
||||
# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines
|
||||
include Makefile.inc
|
||||
|
||||
example_PROGRAMS := $(patsubst %,%.exe,$(strip $(check_PROGRAMS)))
|
||||
|
||||
.SUFFIXES: .rc .res .o .exe
|
||||
check_PROGRAMS := $(patsubst %,%.exe,$(strip $(check_PROGRAMS)))
|
||||
check_PROGRAMS += ftpuploadresume.exe synctime.exe
|
||||
|
||||
|
||||
all: $(example_PROGRAMS)
|
||||
all: $(check_PROGRAMS)
|
||||
|
||||
.o.exe: $(curl_DEPENDENCIES)
|
||||
$(LINK) $< $(curl_LDADD)
|
||||
%.exe: %.o $(curl_DEPENDENCIES)
|
||||
$(CC) $(LDFLAGS) -o $@ $< $(curl_LDADD)
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) -c $<
|
||||
%.o: %.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
.rc.res:
|
||||
%.res: %.rc
|
||||
$(RC) $(RCFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
$(RM) $(example_PROGRAMS)
|
||||
-$(RM) $(check_PROGRAMS:.exe=.o)
|
||||
|
||||
distclean vclean: clean
|
||||
-$(RM) $(check_PROGRAMS)
|
||||
|
||||
|
441
docs/examples/Makefile.netware
Normal file
441
docs/examples/Makefile.netware
Normal file
@@ -0,0 +1,441 @@
|
||||
#################################################################
|
||||
#
|
||||
## Makefile for building curl.nlm (NetWare version - gnu make)
|
||||
## Use: make -f Makefile.netware
|
||||
##
|
||||
## Comments to: Guenter Knauf http://www.gknw.net/phpbb
|
||||
#
|
||||
#################################################################
|
||||
|
||||
# Edit the path below to point to the base of your Novell NDK.
|
||||
ifndef NDKBASE
|
||||
NDKBASE = c:/novell
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../../zlib-1.2.5
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../../openssl-0.9.8r
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../../libssh2-1.3.0
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your axTLS package.
|
||||
ifndef AXTLS_PATH
|
||||
AXTLS_PATH = ../../../axTLS-1.2.7
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../../libidn-1.18
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your librtmp package.
|
||||
ifndef LIBRTMP_PATH
|
||||
LIBRTMP_PATH = ../../../librtmp-2.3
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your fbopenssl package.
|
||||
ifndef FBOPENSSL_PATH
|
||||
FBOPENSSL_PATH = ../../fbopenssl-0.4
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your c-ares package.
|
||||
ifndef LIBCARES_PATH
|
||||
LIBCARES_PATH = ../../ares
|
||||
endif
|
||||
|
||||
ifndef INSTDIR
|
||||
INSTDIR = ..$(DS)..$(DS)curl-$(LIBCURL_VERSION_STR)-bin-nw
|
||||
endif
|
||||
|
||||
# Edit the vars below to change NLM target settings.
|
||||
TARGET = examples
|
||||
VERSION = $(LIBCURL_VERSION)
|
||||
COPYR = Copyright (C) $(LIBCURL_COPYRIGHT_STR)
|
||||
DESCR = cURL ($(LIBARCH))
|
||||
MTSAFE = YES
|
||||
STACK = 8192
|
||||
SCREEN = Example Program
|
||||
# Comment the line below if you dont want to load protected automatically.
|
||||
# LDRING = 3
|
||||
|
||||
# Uncomment the next line to enable linking with POSIX semantics.
|
||||
# POSIXFL = 1
|
||||
|
||||
# Edit the var below to point to your lib architecture.
|
||||
ifndef LIBARCH
|
||||
LIBARCH = LIBC
|
||||
endif
|
||||
|
||||
# must be equal to NDEBUG or DEBUG, CURLDEBUG
|
||||
ifndef DB
|
||||
DB = NDEBUG
|
||||
endif
|
||||
# Optimization: -O<n> or debugging: -g
|
||||
ifeq ($(DB),NDEBUG)
|
||||
OPT = -O2
|
||||
OBJDIR = release
|
||||
else
|
||||
OPT = -g
|
||||
OBJDIR = debug
|
||||
endif
|
||||
|
||||
# The following lines defines your compiler.
|
||||
ifdef CWFolder
|
||||
METROWERKS = $(CWFolder)
|
||||
endif
|
||||
ifdef METROWERKS
|
||||
# MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support
|
||||
MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support
|
||||
CC = mwccnlm
|
||||
else
|
||||
CC = gcc
|
||||
endif
|
||||
PERL = perl
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk-20100523.zip
|
||||
AWK = awk
|
||||
CP = cp -afv
|
||||
MKDIR = mkdir
|
||||
# RM = rm -f
|
||||
# If you want to mark the target as MTSAFE you will need a tool for
|
||||
# generating the xdc data for the linker; here's a minimal tool:
|
||||
# http://www.gknw.net/development/prgtools/mkxdc.zip
|
||||
MPKXDC = mkxdc
|
||||
|
||||
# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH))
|
||||
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
|
||||
|
||||
# Include the version info retrieved from curlver.h
|
||||
-include $(OBJDIR)/version.inc
|
||||
|
||||
# Global flags for all compilers
|
||||
CFLAGS += $(OPT) -D$(DB) -DNETWARE -DHAVE_CONFIG_H -nostdinc
|
||||
|
||||
ifeq ($(CC),mwccnlm)
|
||||
LD = mwldnlm
|
||||
LDFLAGS = -nostdlib $< $(PRELUDE) $(LDLIBS) -o $@ -commandfile
|
||||
LIBEXT = lib
|
||||
CFLAGS += -gccinc -inline off -opt nointrinsics -proc 586
|
||||
CFLAGS += -relax_pointers
|
||||
#CFLAGS += -w on
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
ifeq ($(POSIXFL),1)
|
||||
PRELUDE = $(NDK_LIBC)/imports/posixpre.o
|
||||
else
|
||||
PRELUDE = $(NDK_LIBC)/imports/libcpre.o
|
||||
endif
|
||||
CFLAGS += -align 4
|
||||
else
|
||||
# PRELUDE = $(NDK_CLIB)/imports/clibpre.o
|
||||
# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
|
||||
PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj"
|
||||
# CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h"
|
||||
CFLAGS += -align 1
|
||||
endif
|
||||
else
|
||||
LD = nlmconv
|
||||
LDFLAGS = -T
|
||||
LIBEXT = a
|
||||
CFLAGS += -m32
|
||||
CFLAGS += -fno-builtin -fno-strict-aliasing
|
||||
ifeq ($(findstring gcc,$(CC)),gcc)
|
||||
CFLAGS += -fpcc-struct-return
|
||||
endif
|
||||
CFLAGS += -Wall # -pedantic
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
ifeq ($(POSIXFL),1)
|
||||
PRELUDE = $(NDK_LIBC)/imports/posixpre.gcc.o
|
||||
else
|
||||
PRELUDE = $(NDK_LIBC)/imports/libcpre.gcc.o
|
||||
endif
|
||||
else
|
||||
# PRELUDE = $(NDK_CLIB)/imports/clibpre.gcc.o
|
||||
# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
|
||||
# http://www.gknw.net/development/mk_nlm/gcc_pre.zip
|
||||
PRELUDE = $(NDK_ROOT)/pre/prelude.o
|
||||
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
|
||||
endif
|
||||
endif
|
||||
|
||||
NDK_ROOT = $(NDKBASE)/ndk
|
||||
ifndef NDK_CLIB
|
||||
NDK_CLIB = $(NDK_ROOT)/nwsdk
|
||||
endif
|
||||
ifndef NDK_LIBC
|
||||
NDK_LIBC = $(NDK_ROOT)/libc
|
||||
endif
|
||||
ifndef NDK_LDAP
|
||||
NDK_LDAP = $(NDK_ROOT)/cldapsdk/netware
|
||||
endif
|
||||
CURL_INC = ../../include
|
||||
CURL_LIB = ../../lib
|
||||
|
||||
INCLUDES = -I$(CURL_INC)
|
||||
|
||||
ifeq ($(findstring -static,$(CFG)),-static)
|
||||
LINK_STATIC = 1
|
||||
endif
|
||||
ifeq ($(findstring -ares,$(CFG)),-ares)
|
||||
WITH_ARES = 1
|
||||
endif
|
||||
ifeq ($(findstring -rtmp,$(CFG)),-rtmp)
|
||||
WITH_RTMP = 1
|
||||
WITH_SSL = 1
|
||||
WITH_ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -ssh2,$(CFG)),-ssh2)
|
||||
WITH_SSH2 = 1
|
||||
WITH_SSL = 1
|
||||
WITH_ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -axtls,$(CFG)),-axtls)
|
||||
WITH_AXTLS = 1
|
||||
WITH_SSL =
|
||||
else
|
||||
ifeq ($(findstring -ssl,$(CFG)),-ssl)
|
||||
WITH_SSL = 1
|
||||
endif
|
||||
endif
|
||||
ifeq ($(findstring -zlib,$(CFG)),-zlib)
|
||||
WITH_ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -idn,$(CFG)),-idn)
|
||||
WITH_IDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -spnego,$(CFG)),-spnego)
|
||||
WITH_SPNEGO = 1
|
||||
endif
|
||||
ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
|
||||
ENABLE_IPV6 = 1
|
||||
endif
|
||||
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS = $(CURL_LIB)/libcurl.$(LIBEXT)
|
||||
ifdef WITH_ARES
|
||||
LDLIBS += $(LIBCARES_PATH)/libcares.$(LIBEXT)
|
||||
endif
|
||||
else
|
||||
MODULES = libcurl.nlm
|
||||
IMPORTS = @$(CURL_LIB)/libcurl.imp
|
||||
endif
|
||||
ifdef WITH_SSH2
|
||||
# INCLUDES += -I$(LIBSSH2_PATH)/include
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(LIBSSH2_PATH)/nw/libssh2.$(LIBEXT)
|
||||
else
|
||||
MODULES += libssh2.nlm
|
||||
IMPORTS += @$(LIBSSH2_PATH)/nw/libssh2.imp
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_RTMP
|
||||
# INCLUDES += -I$(LIBRTMP_PATH)
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(LIBRTMP_PATH)/librtmp/librtmp.$(LIBEXT)
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_SSL
|
||||
INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L)
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT)
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
|
||||
IMPORTS += GetProcessSwitchCount RunningProcess
|
||||
ifdef WITH_SPNEGO
|
||||
# INCLUDES += -I$(FBOPENSSL_PATH)/include
|
||||
LDLIBS += $(FBOPENSSL_PATH)/nw/fbopenssl.$(LIBEXT)
|
||||
endif
|
||||
else
|
||||
ifdef WITH_AXTLS
|
||||
INCLUDES += -I$(AXTLS_PATH)/inc
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(AXTLS_PATH)/lib/libaxtls.$(LIBEXT)
|
||||
else
|
||||
MODULES += libaxtls.nlm
|
||||
IMPORTS += $(AXTLS_PATH)/lib/libaxtls.imp
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_ZLIB
|
||||
# INCLUDES += -I$(ZLIB_PATH)
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(ZLIB_PATH)/nw/$(LIBARCH)/libz.$(LIBEXT)
|
||||
else
|
||||
MODULES += libz.nlm
|
||||
IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_IDN
|
||||
# INCLUDES += -I$(LIBIDN_PATH)/include
|
||||
LDLIBS += $(LIBIDN_PATH)/lib/libidn.$(LIBEXT)
|
||||
endif
|
||||
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
INCLUDES += -I$(NDK_LIBC)/include
|
||||
# INCLUDES += -I$(NDK_LIBC)/include/nks
|
||||
# INCLUDES += -I$(NDK_LIBC)/include/winsock
|
||||
CFLAGS += -D_POSIX_SOURCE
|
||||
else
|
||||
INCLUDES += -I$(NDK_CLIB)/include/nlm
|
||||
# INCLUDES += -I$(NDK_CLIB)/include
|
||||
endif
|
||||
ifndef DISABLE_LDAP
|
||||
# INCLUDES += -I$(NDK_LDAP)/$(LIBARCH_L)/inc
|
||||
endif
|
||||
CFLAGS += $(INCLUDES)
|
||||
|
||||
ifeq ($(MTSAFE),YES)
|
||||
XDCOPT = -n
|
||||
endif
|
||||
ifeq ($(MTSAFE),NO)
|
||||
XDCOPT = -u
|
||||
endif
|
||||
ifdef XDCOPT
|
||||
XDCDATA = $(OBJDIR)/$(TARGET).xdc
|
||||
endif
|
||||
|
||||
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||
DL = '
|
||||
DS = /
|
||||
PCT = %
|
||||
#-include $(NDKBASE)/nlmconv/ncpfs.inc
|
||||
else
|
||||
DS = \\
|
||||
PCT = %%
|
||||
endif
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include Makefile.inc
|
||||
|
||||
check_PROGRAMS := $(patsubst %,%.nlm,$(strip $(check_PROGRAMS)))
|
||||
|
||||
.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc
|
||||
|
||||
|
||||
all: prebuild $(check_PROGRAMS)
|
||||
|
||||
prebuild: $(OBJDIR) $(OBJDIR)/version.inc
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
@echo Compiling $<
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJDIR)/version.inc: $(CURL_INC)/curl/curlver.h $(OBJDIR)
|
||||
@echo Creating $@
|
||||
@$(AWK) -f ../../packages/NetWare/get_ver.awk $< > $@
|
||||
|
||||
install: $(INSTDIR) all
|
||||
@$(CP) $(check_PROGRAMS) $(INSTDIR)
|
||||
|
||||
clean:
|
||||
-$(RM) -r $(OBJDIR)
|
||||
|
||||
distclean vclean: clean
|
||||
-$(RM) $(check_PROGRAMS)
|
||||
|
||||
$(OBJDIR) $(INSTDIR):
|
||||
@$(MKDIR) $@
|
||||
|
||||
%.nlm: $(OBJDIR)/%.o $(OBJDIR)/%.def $(XDCDATA)
|
||||
@echo Linking $@
|
||||
@-$(RM) $@
|
||||
@$(LD) $(LDFLAGS) $(OBJDIR)/$(@:.nlm=.def)
|
||||
|
||||
$(OBJDIR)/%.xdc: Makefile.netware
|
||||
@echo Creating $@
|
||||
@$(MPKXDC) $(XDCOPT) $@
|
||||
|
||||
$(OBJDIR)/%.def: Makefile.netware
|
||||
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
|
||||
@echo $(DL)# Do not edit this file - it is created by Make!$(DL) >> $@
|
||||
@echo $(DL)# All your changes will be lost!!$(DL) >> $@
|
||||
@echo $(DL)#$(DL) >> $@
|
||||
@echo $(DL)copyright "$(COPYR)"$(DL) >> $@
|
||||
@echo $(DL)description "$(DESCR) $(notdir $(@:.def=)) Example"$(DL) >> $@
|
||||
@echo $(DL)version $(VERSION)$(DL) >> $@
|
||||
ifdef NLMTYPE
|
||||
@echo $(DL)type $(NLMTYPE)$(DL) >> $@
|
||||
endif
|
||||
ifdef STACK
|
||||
@echo $(DL)stack $(STACK)$(DL) >> $@
|
||||
endif
|
||||
ifdef SCREEN
|
||||
@echo $(DL)screenname "$(DESCR) $(notdir $(@:.def=)) $(SCREEN)"$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)screenname "DEFAULT"$(DL) >> $@
|
||||
endif
|
||||
ifneq ($(DB),NDEBUG)
|
||||
@echo $(DL)debug$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)threadname "_$(notdir $(@:.def=))"$(DL) >> $@
|
||||
ifdef XDCDATA
|
||||
@echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(LDRING),0)
|
||||
@echo $(DL)flag_on 16$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(LDRING),3)
|
||||
@echo $(DL)flag_on 512$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(LIBARCH),CLIB)
|
||||
@echo $(DL)start _Prelude$(DL) >> $@
|
||||
@echo $(DL)exit _Stop$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_CLIB)/imports/clib.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_CLIB)/imports/threads.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_CLIB)/imports/nlmlib.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_CLIB)/imports/socklib.imp$(DL) >> $@
|
||||
@echo $(DL)module clib$(DL) >> $@
|
||||
ifndef DISABLE_LDAP
|
||||
@echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@
|
||||
# @echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@
|
||||
@echo $(DL)module ldapsdk ldapssl$(DL) >> $@
|
||||
endif
|
||||
else
|
||||
ifeq ($(POSIXFL),1)
|
||||
@echo $(DL)flag_on 4194304$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)flag_on 64$(DL) >> $@
|
||||
@echo $(DL)pseudopreemption$(DL) >> $@
|
||||
ifeq ($(findstring posixpre,$(PRELUDE)),posixpre)
|
||||
@echo $(DL)start POSIX_Start$(DL) >> $@
|
||||
@echo $(DL)exit POSIX_Stop$(DL) >> $@
|
||||
@echo $(DL)check POSIX_CheckUnload$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)start _LibCPrelude$(DL) >> $@
|
||||
@echo $(DL)exit _LibCPostlude$(DL) >> $@
|
||||
@echo $(DL)check _LibCCheckUnload$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)import @$(NDK_LIBC)/imports/libc.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_LIBC)/imports/netware.imp$(DL) >> $@
|
||||
@echo $(DL)module libc$(DL) >> $@
|
||||
ifndef DISABLE_LDAP
|
||||
@echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@
|
||||
# @echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@
|
||||
@echo $(DL)module lldapsdk lldapssl$(DL) >> $@
|
||||
endif
|
||||
endif
|
||||
ifdef MODULES
|
||||
@echo $(DL)module $(MODULES)$(DL) >> $@
|
||||
endif
|
||||
ifdef EXPORTS
|
||||
@echo $(DL)export $(EXPORTS)$(DL) >> $@
|
||||
endif
|
||||
ifdef IMPORTS
|
||||
@echo $(DL)import $(IMPORTS)$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(findstring nlmconv,$(LD)),nlmconv)
|
||||
@echo $(DL)input $(PRELUDE)$(DL) >> $@
|
||||
@echo $(DL)input $(@:.def=.o)$(DL) >> $@
|
||||
ifdef LDLIBS
|
||||
@echo $(DL)input $(LDLIBS)$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
|
||||
endif
|
@@ -41,6 +41,7 @@
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "printf_macro.h"
|
||||
|
||||
#if LIBCURL_VERSION_NUM < 0x070c03
|
||||
#error "upgrade your libcurl to no less than 7.12.3"
|
||||
@@ -92,7 +93,7 @@ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
|
||||
retcode = read(fd, ptr, size * nmemb);
|
||||
|
||||
fprintf(stderr, "*** We read %d bytes from file\n", retcode);
|
||||
fprintf(stderr, "*** We read %" _FMT_SIZE_T " bytes from file\n", retcode);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
@@ -28,13 +28,17 @@
|
||||
#include <stdlib.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <sys/socket.h> /* socket definitions */
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#define close closesocket
|
||||
#else
|
||||
#include <sys/types.h> /* socket types */
|
||||
#include <sys/socket.h> /* socket definitions */
|
||||
#include <arpa/inet.h> /* inet (3) funtions */
|
||||
#include <unistd.h> /* misc. UNIX functions */
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
@@ -72,6 +76,16 @@ int main(void)
|
||||
struct sockaddr_in servaddr; /* socket address structure */
|
||||
curl_socket_t sockfd;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsaData;
|
||||
int initwsa;
|
||||
|
||||
if((initwsa = WSAStartup(MAKEWORD(2,0), &wsaData)) != 0) {
|
||||
printf("WSAStartup failed: %d\n", initwsa);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/*
|
||||
@@ -81,16 +95,16 @@ int main(void)
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999");
|
||||
|
||||
/* Create the socket "manually" */
|
||||
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
|
||||
fprintf(stderr, "ECHOCLNT: Error creating listening socket.\n");
|
||||
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
|
||||
printf("Error creating listening socket.\n");
|
||||
return 3;
|
||||
}
|
||||
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_port = htons(PORTNUM);
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_port = htons(PORTNUM);
|
||||
|
||||
if(inet_aton(IPADDR, &servaddr.sin_addr) <= 0 )
|
||||
if (INADDR_NONE == (servaddr.sin_addr.s_addr = inet_addr(IPADDR)))
|
||||
return 2;
|
||||
|
||||
if(connect(sockfd,(struct sockaddr *) &servaddr, sizeof(servaddr)) ==
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "printf_macro.h"
|
||||
|
||||
/*
|
||||
* This example shows an FTP upload, with a rename of the file just after
|
||||
@@ -56,7 +57,7 @@ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
by default internally */
|
||||
size_t retcode = fread(ptr, size, nmemb, stream);
|
||||
|
||||
fprintf(stderr, "*** We read %d bytes from file\n", retcode);
|
||||
fprintf(stderr, "*** We read %" _FMT_SIZE_T " bytes from file\n", retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,7 @@
|
||||
|
||||
/* The MinGW headers are missing a few Win32 function definitions,
|
||||
you shouldn't need this if you use VC++ */
|
||||
#ifdef __MINGW32__
|
||||
#if defined(__MINGW32__) && !defined(__MINGW64__)
|
||||
int __cdecl _snscanf(const char * input, size_t length, const char * format, ...);
|
||||
#endif
|
||||
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "printf_macro.h"
|
||||
|
||||
/*
|
||||
* This example shows a HTTP PUT operation. PUTs a file given as a command
|
||||
@@ -45,7 +46,7 @@ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
by default internally */
|
||||
retcode = fread(ptr, size, nmemb, stream);
|
||||
|
||||
fprintf(stderr, "*** We read %d bytes from file\n", retcode);
|
||||
fprintf(stderr, "*** We read %" _FMT_SIZE_T " bytes from file\n", retcode);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
45
docs/examples/printf_macro.h
Normal file
45
docs/examples/printf_macro.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* Simple hack trying to get a valid printf format string for size_t.
|
||||
* If that fails for your platform you can define your own _FMT_SIZE_T,
|
||||
* f.e.: -D_FMT_SIZE_T="zd"
|
||||
*/
|
||||
#ifndef _PRINTF_MACRO_H
|
||||
#define _PRINTF_MACRO_H
|
||||
|
||||
#ifndef _FMT_SIZE_T
|
||||
#ifdef WIN32
|
||||
#define _FMT_SIZE_T "Id"
|
||||
#else
|
||||
/*
|
||||
"zd" is a GNU extension to POSIX; so we dont use it for size_t but hack around
|
||||
#define _FMT_SIZE_T "zd"
|
||||
*/
|
||||
#ifdef __x86_64__
|
||||
#define _FMT_SIZE_T "lu"
|
||||
#else
|
||||
#define _FMT_SIZE_T "u"
|
||||
#endif /* __x86_64__ */
|
||||
#endif /* WIN32 */
|
||||
#endif /* !_FMT_SIZE_T */
|
||||
|
||||
#endif /* !_PRINTF_MACRO_H */
|
58
docs/examples/progressfunc.c
Normal file
58
docs/examples/progressfunc.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES 6000
|
||||
|
||||
static int progress(void *p,
|
||||
double dltotal, double dlnow,
|
||||
double ultotal, double ulnow)
|
||||
{
|
||||
fprintf(stderr, "UP: %g of %g DOWN: %g of %g\r\n",
|
||||
ulnow, ultotal, dlnow, dltotal);
|
||||
|
||||
if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res=0;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(res)
|
||||
fprintf(stderr, "%s\n", curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return (int)res;
|
||||
}
|
@@ -73,7 +73,7 @@ static void rtsp_options(CURL *curl, const char *uri)
|
||||
CURLcode res = CURLE_OK;
|
||||
printf("\nRTSP: OPTIONS %s\n", uri);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS);
|
||||
my_curl_easy_perform(curl);
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ static void rtsp_describe(CURL *curl, const char *uri,
|
||||
printf("Writing SDP to '%s'\n", sdp_filename);
|
||||
}
|
||||
my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, sdp_fp);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_DESCRIBE);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_DESCRIBE);
|
||||
my_curl_easy_perform(curl);
|
||||
my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout);
|
||||
if (sdp_fp != stdout) {
|
||||
@@ -109,7 +109,7 @@ static void rtsp_setup(CURL *curl, const char *uri, const char *transport)
|
||||
printf(" TRANSPORT %s\n", transport);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_TRANSPORT, transport);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_SETUP);
|
||||
my_curl_easy_perform(curl);
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ static void rtsp_play(CURL *curl, const char *uri, const char *range)
|
||||
printf("\nRTSP: PLAY %s\n", uri);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RANGE, range);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
|
||||
my_curl_easy_perform(curl);
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ static void rtsp_teardown(CURL *curl, const char *uri)
|
||||
{
|
||||
CURLcode res = CURLE_OK;
|
||||
printf("\nRTSP: TEARDOWN %s\n", uri);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_TEARDOWN);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_TEARDOWN);
|
||||
my_curl_easy_perform(curl);
|
||||
}
|
||||
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
#include "printf_macro.h"
|
||||
|
||||
/* Auxiliary function that waits on the socket. */
|
||||
static int wait_on_socket(curl_socket_t sockfd, int for_recv, long timeout_ms)
|
||||
@@ -122,7 +123,7 @@ int main(void)
|
||||
if(CURLE_OK != res)
|
||||
break;
|
||||
|
||||
printf("Received %u bytes.\n", iolen);
|
||||
printf("Received %" _FMT_SIZE_T " bytes.\n", iolen);
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
|
@@ -123,13 +123,13 @@ int main(void)
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, MAILFROM);
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list);
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,0);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_SSLVERSION, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_SSLVERSION, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0L);
|
||||
curl_multi_add_handle(mcurl, curl);
|
||||
|
||||
mp_timedout = 0;
|
||||
|
@@ -94,13 +94,13 @@ int main(void)
|
||||
* of using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer
|
||||
* will continue anyway - see the security discussion in the libcurl
|
||||
* tutorial for more details. */
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
|
||||
|
||||
/* If your server doesn't have a valid certificate, then you can disable
|
||||
* part of the Transport Layer Security protection by setting the
|
||||
* CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false).
|
||||
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
* That is, in general, a bad idea. It is still better than sending your
|
||||
* authentication details in plain text though.
|
||||
* Instead, you should get the issuer certificate (or the host certificate
|
||||
@@ -135,7 +135,7 @@ int main(void)
|
||||
/* Since the traffic will be encrypted, it is very useful to turn on debug
|
||||
* information within libcurl to see what is happening during the transfer.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* send the message (including headers) */
|
||||
res = curl_easy_perform(curl);
|
||||
|
@@ -147,7 +147,7 @@ size_t SyncTime_CURL_WriteHeader(void *ptr, size_t size, size_t nmemb,
|
||||
TmpStr1 & 2? */
|
||||
AutoSyncTime = 0;
|
||||
else {
|
||||
RetVal = sscanf ((char *)(ptr), "Date: %s %d %s %d %d:%d:%d",
|
||||
RetVal = sscanf ((char *)(ptr), "Date: %s %hu %s %hu %hu:%hu:%hu",
|
||||
TmpStr1, &SYSTime.wDay, TmpStr2, &SYSTime.wYear,
|
||||
&SYSTime.wHour, &SYSTime.wMinute, &SYSTime.wSecond);
|
||||
|
||||
|
@@ -171,8 +171,12 @@ Set the \fIuserdata\fP argument with the \fICURLOPT_WRITEDATA\fP option.
|
||||
|
||||
The callback function will be passed as much data as possible in all invokes,
|
||||
but you cannot possibly make any assumptions. It may be one byte, it may be
|
||||
thousands. The maximum amount of data that can be passed to the write callback
|
||||
is defined in the curl.h header file: CURL_MAX_WRITE_SIZE.
|
||||
thousands. The maximum amount of body data that can be passed to the write
|
||||
callback is defined in the curl.h header file: CURL_MAX_WRITE_SIZE (the usual
|
||||
default is 16K). If you however have \fICURLOPT_HEADER\fP set, which sends
|
||||
header data to the write callback, you can get up to
|
||||
\fICURL_MAX_HTTP_HEADER\fP bytes of header data passed into it. This usually
|
||||
means 100K.
|
||||
.IP CURLOPT_WRITEDATA
|
||||
Data pointer to pass to the file write function. If you use the
|
||||
\fICURLOPT_WRITEFUNCTION\fP option, this is the pointer you'll get as
|
||||
@@ -354,6 +358,9 @@ of bytes actually taken care of. If that amount differs from the amount passed
|
||||
to your function, it'll signal an error to the library. This will abort the
|
||||
transfer and return \fICURL_WRITE_ERROR\fP.
|
||||
|
||||
A complete header that is passed to this function can be up to
|
||||
\fICURL_MAX_HTTP_HEADER\fP (100K) bytes.
|
||||
|
||||
If this option is not set, or if it is set to NULL, but
|
||||
\fICURLOPT_HEADERDATA\fP (\fICURLOPT_WRITEHEADER\fP) is set to anything but
|
||||
NULL, the function used to accept response data will be used instead. That is,
|
||||
@@ -584,20 +591,162 @@ POST/PUT and a 401 or 407 is received immediately afterwards.
|
||||
.SH NETWORK OPTIONS
|
||||
.IP CURLOPT_URL
|
||||
The actual URL to deal with. The parameter should be a char * to a zero
|
||||
terminated string.
|
||||
terminated string which must be URL-encoded in the following format:
|
||||
|
||||
If the given URL lacks the protocol part ("http://" or "ftp://" etc), it will
|
||||
attempt to guess which protocol to use based on the given host name. If the
|
||||
given protocol of the set URL is not supported, libcurl will return on error
|
||||
(\fICURLE_UNSUPPORTED_PROTOCOL\fP) when you call \fIcurl_easy_perform(3)\fP or
|
||||
\fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed info
|
||||
on which protocols are supported.
|
||||
scheme://host:port/path
|
||||
|
||||
The string given to CURLOPT_URL must be url-encoded and follow RFC 2396
|
||||
For a greater explanation of the format please see RFC 2396
|
||||
(http://curl.haxx.se/rfc/rfc2396.txt).
|
||||
|
||||
Starting with version 7.20.0, the fragment part of the URI will not be send as
|
||||
part of the path, which was the case previously.
|
||||
If the given URL lacks the scheme, or protocol, part ("http://" or "ftp://"
|
||||
etc), libcurl will attempt to resolve which protocol to use based on the
|
||||
given host mame. If the protocol is not supported, libcurl will return
|
||||
(\fICURLE_UNSUPPORTED_PROTOCOL\fP) when you call \fIcurl_easy_perform(3)\fP
|
||||
or \fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed
|
||||
information on which protocols are supported.
|
||||
|
||||
The host part of the URL contains the address of the server that you want to
|
||||
connect to. This can be the fully qualified domain name of the server, the
|
||||
local network name of the machine on your network or the IP address of the
|
||||
server or machine represented by either an IPv4 or IPv6 address. For example:
|
||||
|
||||
http://www.example.com/
|
||||
|
||||
http://hostname/
|
||||
|
||||
http://192.168.0.1/
|
||||
|
||||
http://[2001:1890:1112:1::20]/
|
||||
|
||||
It is also possible to specify the user name and password as part of the
|
||||
host, for some protocols, when connecting to servers that require
|
||||
authentication.
|
||||
|
||||
For example the following types of authentication support this:
|
||||
|
||||
http://user:password@www.domain.com
|
||||
ftp://user:password@ftp.domain.com
|
||||
pop3://user:password@mail.domain.com
|
||||
|
||||
The port is optional and when not specified libcurl will use the default port
|
||||
based on the determined or specified protocol: 80 for http, 21 for ftp and 25
|
||||
for smtp, etc. The following examples show how to specify the port:
|
||||
|
||||
http://www.weirdserver.com:8080/ - This will connect to a web server using
|
||||
port 8080.
|
||||
|
||||
smtp://mail.domain.com:587/ - This will connect to a smtp server on the
|
||||
alternative mail port.
|
||||
|
||||
The path part of the URL is protocol specific and whilst some examples are
|
||||
given below this list is not conclusive:
|
||||
|
||||
.B HTTP
|
||||
|
||||
The path part of a HTTP request specifies the file to retrieve and from what
|
||||
directory. If the directory is not specified then the web server's root
|
||||
directory is used. If the file is omitted then the default document will be
|
||||
retrieved for either the directory specified or the root directory. The
|
||||
exact resource returned for each URL is entirely dependent on the server's
|
||||
configuration.
|
||||
|
||||
http://www.netscape.com - This gets the main page (index.html in this
|
||||
example) from Netscape's web server.
|
||||
|
||||
http://www.netscape.com/index.html - This returns the main page from Netscape
|
||||
by specifying the page to get.
|
||||
|
||||
http://www.netscape.com/contactus/ - This returns the default document from
|
||||
the contactus directory.
|
||||
|
||||
.B FTP
|
||||
|
||||
The path part of an FTP request specifies the file to retrieve and from what
|
||||
directory. If the file part is omitted then libcurl downloads the directory
|
||||
listing for the directory specified. If the directory is omitted then
|
||||
the directory listing for the root / home directory will be returned.
|
||||
|
||||
ftp://cool.haxx.se - This retrieves the directory listing for our FTP server.
|
||||
|
||||
ftp://cool.haxx.se/readme.txt - This downloads the file readme.txt from the
|
||||
root directory.
|
||||
|
||||
ftp://cool.haxx.se/libcurl/readme.txt - This downloads readme.txt from the
|
||||
libcurl directory.
|
||||
|
||||
ftp://user:password@my.example.com/readme.txt - This retrieves the readme.txt
|
||||
file from the user's home directory. When a username and password is
|
||||
specified, everything that is specified in the path part is relative to the
|
||||
user's home directory. To retrieve files from the root directory or a
|
||||
directory underneath the root directory then the absolute path must be
|
||||
specified by prepending an additional forward slash to the beginning of the
|
||||
path.
|
||||
|
||||
ftp://user:password@my.example.com//readme.txt - This retrieves the readme.txt
|
||||
from the root directory when logging in as a specified user.
|
||||
|
||||
.B SMTP
|
||||
|
||||
The path part of a SMTP request specifies the host name to present during
|
||||
communication with the mail server. If the path is omitted then libcurl will
|
||||
attempt to resolve the local computer's host name. However, this may not
|
||||
return the fully qualified domain name that is required by some mail servers
|
||||
and specifying this path allows you to set an alternative name, such as
|
||||
your machine's fully qualified domain name, which you might have obtained
|
||||
from an external function such as gethostname or getaddrinfo.
|
||||
|
||||
smtp://mail.domain.com - This connects to the mail server at domain.com and
|
||||
sends your local computer's host name in the HELO / EHLO command.
|
||||
|
||||
smtp://mail.domain.com/client.domain.com - This will send client.domain.com in
|
||||
the HELO / EHLO command to the mail server at domain.com.
|
||||
|
||||
.B POP3
|
||||
|
||||
The path part of a POP3 request specifies the mailbox (message) to retrieve.
|
||||
If the mailbox is not specified then a list of waiting messages is returned
|
||||
instead.
|
||||
|
||||
pop3://user:password@mail.domain.com - This lists the available messages
|
||||
pop3://user:password@mail.domain.com/1 - This retrieves the first message
|
||||
|
||||
.B SCP
|
||||
|
||||
The path part of an SCP request specifies the file to retrieve and from what
|
||||
directory. The file part may not be omitted. The file is taken as an absolute
|
||||
path from the root directory on the server. To specify a path relative to
|
||||
the user's home directory on the server, prepend ~/ to the path portion.
|
||||
If the user name is not embedded in the URL, it can be set with the
|
||||
\fICURLOPT_USERPWD\fP or \fBCURLOPT_USERNAME\fP option.
|
||||
|
||||
scp://user@example.com/etc/issue - This specifies the file /etc/issue
|
||||
|
||||
scp://example.com/~/my-file - This specifies the file my-file in the
|
||||
user's home directory on the server
|
||||
|
||||
.B SFTP
|
||||
|
||||
The path part of an SFTP request specifies the file to retrieve and from what
|
||||
directory. If the file part is omitted then libcurl downloads the directory
|
||||
listing for the directory specified. If the path ends in a / then a directory
|
||||
listing is returned instead of a file. If the path is omitted entirely then
|
||||
the directory listing for the root / home directory will be returned.
|
||||
If the user name is not embedded in the URL, it can be set with the
|
||||
\fICURLOPT_USERPWD\fP or \fBCURLOPT_USERNAME\fP option.
|
||||
|
||||
sftp://user:password@example.com/etc/issue - This specifies the file
|
||||
/etc/issue
|
||||
|
||||
sftp://user@example.com/~/my-file - This specifies the file my-file in the
|
||||
user's home directory
|
||||
|
||||
sftp://ssh.example.com/~/Documents/ - This requests a directory listing
|
||||
of the Documents directory under the user's home directory
|
||||
|
||||
.B NOTES
|
||||
|
||||
Starting with version 7.20.0, the fragment part of the URI will not be sent as
|
||||
part of the path, which was previously the case.
|
||||
|
||||
\fICURLOPT_URL\fP is the only option that \fBmust\fP be set before
|
||||
\fIcurl_easy_perform(3)\fP is called.
|
||||
@@ -666,10 +815,10 @@ this are \fICURLPROXY_HTTP\fP, \fICURLPROXY_HTTP_1_0\fP (added in 7.19.4),
|
||||
|
||||
If you set \fBCURLOPT_PROXYTYPE\fP to \fICURLPROXY_HTTP_1_0\fP, it will only
|
||||
affect how libcurl speaks to a proxy when CONNECT is used. The HTTP version
|
||||
used for "regular" HTTP requests is instead controled with
|
||||
used for "regular" HTTP requests is instead controlled with
|
||||
\fICURLOPT_HTTP_VERSION\fP.
|
||||
.IP CURLOPT_NOPROXY
|
||||
Pass a pointer to a zero terminated string. The should be a comma- separated
|
||||
Pass a pointer to a zero terminated string. The should be a comma separated
|
||||
list of hosts which do not use a proxy, if one is specified. The only
|
||||
wildcard is a single * character, which matches all hosts, and effectively
|
||||
disables the proxy. Each name in this list is matched as either a domain which
|
||||
@@ -933,12 +1082,12 @@ You need to build libcurl with GnuTLS or OpenSSL with TLS-SRP support for this
|
||||
to work. (Added in 7.21.4)
|
||||
.RE
|
||||
.IP CURLOPT_TLSAUTH_USERNAME
|
||||
Pass a char * as parameter, which should point to the zero-terminated username
|
||||
Pass a char * as parameter, which should point to the zero terminated username
|
||||
to use for the TLS authentication method specified with the
|
||||
\fICURLOPT_TLSAUTH_TYPE\fP option. Requires that the
|
||||
\fICURLOPT_TLS_PASSWORD\fP option also be set. (Added in 7.21.4)
|
||||
.IP CURLOPT_TLSAUTH_PASSWORD
|
||||
Pass a char * as parameter, which should point to the zero-terminated password
|
||||
Pass a char * as parameter, which should point to the zero terminated password
|
||||
to use for the TLS authentication method specified with the
|
||||
\fICURLOPT_TLSAUTH_TYPE\fP option. Requires that the
|
||||
\fICURLOPT_TLS_USERNAME\fP option also be set. (Added in 7.21.4)
|
||||
@@ -1471,7 +1620,7 @@ a reply.
|
||||
Initiate the shutdown and wait for a reply.
|
||||
.RE
|
||||
.IP CURLOPT_FTP_ACCOUNT
|
||||
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,
|
||||
this data is sent off using the ACCT command. (Added in 7.13.0)
|
||||
.IP CURLOPT_FTP_FILEMETHOD
|
||||
|
@@ -40,19 +40,28 @@ but be sure to FD_ZERO them before calling this function as
|
||||
otherwise remove any others. The \fIcurl_multi_perform(3)\fP function should be
|
||||
called as soon as one of them is ready to be read from or written to.
|
||||
|
||||
To be sure to have up-to-date results, you should call
|
||||
\fIcurl_multi_perform\fP until it does not return CURLM_CALL_MULTI_PERFORM
|
||||
prior to calling \fIcurl_multi_fdset\fP. This will make sure that libcurl has
|
||||
updated the handles' socket states.
|
||||
|
||||
If no file descriptors are set by libcurl, \fImax_fd\fP will contain -1 when
|
||||
this function returns. Otherwise it will contain the higher descriptor number
|
||||
libcurl set.
|
||||
libcurl set. When libcurl returns -1 in \fImax_fd\fP, it is because libcurl
|
||||
currently does something that isn't possible for your application to monitor
|
||||
with a socket and unfortunately you can then not know exactly when the current
|
||||
action is completed using select(). When max_fd returns with -1, you need to
|
||||
wait a while and then proceed and call \fIcurl_multi_perform\fP anyway. How
|
||||
long to wait? I would suggest 100 milliseconds at least, but you may want to
|
||||
test it out in your own particular conditions to find a suitable value.
|
||||
|
||||
When doing select(), you should use \fBcurl_multi_timeout\fP to figure out how
|
||||
long to wait for action. Call \fIcurl_multi_perform\fP even if no activity has
|
||||
been seen on the fd_sets after the timeout expires as otherwise internal
|
||||
retries and timeouts may not work as you'd think and want.
|
||||
|
||||
If one of the sockets used by libcurl happens to be larger than what can be
|
||||
set in an fd_set, which on POSIX systems means that the file descriptor is
|
||||
larger than FD_SETSIZE, then libcurl will try to not set it. Setting a too
|
||||
large file descriptor in an fd_set implies an out of bounds write which can
|
||||
cause crashes, or worse. The effect of NOT storing it will possibly save you
|
||||
from the crash, but will make your program NOT wait for sockets it should wait
|
||||
for...
|
||||
.SH RETURN VALUE
|
||||
CURLMcode type, general libcurl multi interface error code. See
|
||||
\fIlibcurl-errors(3)\fP
|
||||
|
@@ -64,6 +64,11 @@ Cached DNS hosts will be shared across the easy handles using this shared
|
||||
object. Note that when you use the multi interface, all easy handles added to
|
||||
the same multi handle will share DNS cache by default without this having to
|
||||
be used!
|
||||
.IP CURL_LOCK_DATA_SSL_SESSION
|
||||
SSL session IDs will be shared accross the easy handles using this shared
|
||||
object. This will reduce the time spent in the SSL handshake when reconnecting
|
||||
to the same server. Note SSL session IDs are reused within the same easy handle
|
||||
by default.
|
||||
.RE
|
||||
.IP CURLSHOPT_UNSHARE
|
||||
This option does the opposite of \fICURLSHOPT_SHARE\fP. It specifies that
|
||||
|
@@ -277,3 +277,6 @@ An invalid share object was passed to the function.
|
||||
.IP "CURLSHE_NOMEM (4)"
|
||||
Not enough memory was available.
|
||||
(Added in 7.12.0)
|
||||
.IP "CURLSHE_NOT_BUILT_IN (5)"
|
||||
The requsted sharing could not be done because the library you use don't have
|
||||
that particular feature enabled. (Added in 7.23.0)
|
||||
|
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" * Copyright (C) 1998 - 2011, 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
|
||||
@@ -82,14 +82,6 @@ might need attention. This also makes it very easy for your program to wait
|
||||
for input on your own private file descriptors at the same time or perhaps
|
||||
timeout every now and then, should you want that.
|
||||
|
||||
A little note here about the return codes from the multi functions, and
|
||||
especially the \fIcurl_multi_perform(3)\fP: if you receive
|
||||
\fICURLM_CALL_MULTI_PERFORM\fP, this basically means that you should call
|
||||
\fIcurl_multi_perform(3)\fP again, before you select() on more actions. You
|
||||
don't have to do it immediately, but the return code means that libcurl may
|
||||
have more data available to return or that there may be more data to send off
|
||||
before it is "satisfied".
|
||||
|
||||
\fIcurl_multi_perform(3)\fP stores the number of still running transfers in
|
||||
one of its input arguments, and by reading that you can figure out when all
|
||||
the transfers in the multi handles are done. 'done' does not mean
|
||||
@@ -118,21 +110,39 @@ If you want to re-use an easy handle that was added to the multi handle for
|
||||
transfer, you must first remove it from the multi stack and then re-add it
|
||||
again (possibly after having altered some options at your own choice).
|
||||
.SH "MULTI_SOCKET"
|
||||
Since 7.16.0, the \fIcurl_multi_socket_action(3)\fP function offers a way for
|
||||
applications to not only avoid being forced to use select(), but it also
|
||||
offers a much more high-performance API that will make a significant
|
||||
difference for applications using large numbers of simultaneous connections.
|
||||
\fIcurl_multi_socket_action(3)\fP function offers a way for applications to
|
||||
not only avoid being forced to use select(), but it also offers a much more
|
||||
high-performance API that will make a significant difference for applications
|
||||
using large numbers of simultaneous connections.
|
||||
|
||||
\fIcurl_multi_socket_action(3)\fP is then used
|
||||
instead of \fIcurl_multi_perform(3)\fP.
|
||||
\fIcurl_multi_socket_action(3)\fP is then used instead of
|
||||
\fIcurl_multi_perform(3)\fP.
|
||||
|
||||
When using this API, you add easy handles to the multi handle just as with the
|
||||
normal multi interface. Then you also set two callbacks with the
|
||||
CURLMOPT_SOCKETFUNCTION and CURLMOPT_TIMERFUNCTION options to
|
||||
\fIcurl_multi_setopt(3)\fP.
|
||||
|
||||
The API is then designed to inform your application about which sockets
|
||||
libcurl is currently using and for what activities (read and/or write) on
|
||||
those sockets your application is expected to wait for.
|
||||
|
||||
Your application must then make sure to receive all sockets informed about in
|
||||
the CURLMOPT_SOCKETFUNCTION callback and make sure it reacts on the given
|
||||
activity on them. When a socket has the given activity, you call
|
||||
\fIcurl_multi_socket_action(3)\fP specifying which socket and action there
|
||||
are.
|
||||
|
||||
The CURLMOPT_TIMERFUNCTION callback is called to set a timeout. When that
|
||||
timeout expires, your application should call the
|
||||
\fIcurl_multi_socket_action(3)\fP function saying it was due to a timeout.
|
||||
.SH "BLOCKING"
|
||||
A few areas in the code are still using blocking code, even when used from the
|
||||
multi interface. While we certainly want and intend for these to get fixed in
|
||||
the future, you should be aware of the following current restrictions:
|
||||
|
||||
.nf
|
||||
- Name resolves on non-windows unless c-ares is used
|
||||
- GnuTLS SSL connections
|
||||
- Name resolves unless the c-ares or threaded-resolver backends are used
|
||||
- NSS SSL connections
|
||||
- Active FTP connections
|
||||
- HTTP proxy CONNECT operations
|
||||
|
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" * Copyright (C) 1998 - 2011, 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
|
||||
@@ -249,9 +249,11 @@ complication for you. Given simply the URL to a file, libcurl will take care
|
||||
of all the details needed to get the file moved from one machine to another.
|
||||
|
||||
.SH "Multi-threading Issues"
|
||||
The first basic rule is that you must \fBnever\fP share a libcurl handle (be
|
||||
it easy or multi or whatever) between multiple threads. Only use one handle in
|
||||
one thread at a time.
|
||||
The first basic rule is that you must \fBnever\fP simultaneously share a
|
||||
libcurl handle (be it easy or multi or whatever) between multiple
|
||||
threads. Only use one handle in one thread at any time. You can pass the
|
||||
handles around among threads, but you must never use a single handle from more
|
||||
than one thread at any given time.
|
||||
|
||||
libcurl is completely thread safe, except for two issues: signals and SSL/TLS
|
||||
handlers. Signals are used for timing out name resolves (during DNS lookup) -
|
||||
|
@@ -157,6 +157,7 @@ x=CURLOPT_FILE;
|
||||
x=CURLOPT_ERRORBUFFER;
|
||||
x=CURLOPT_STDERR;
|
||||
x=CURLOPT_VERBOSE;
|
||||
if (x) ;
|
||||
])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no)
|
||||
|
||||
CPPFLAGS=$_libcurl_save_cppflags
|
||||
|
@@ -550,6 +550,7 @@ CURLSHE_BAD_OPTION 7.10.3
|
||||
CURLSHE_INVALID 7.10.3
|
||||
CURLSHE_IN_USE 7.10.3
|
||||
CURLSHE_NOMEM 7.12.0
|
||||
CURLSHE_NOT_BUILT_IN 7.23.0
|
||||
CURLSHE_OK 7.10.3
|
||||
CURLSHOPT_LOCKFUNC 7.10.3
|
||||
CURLSHOPT_NONE 7.10.3
|
||||
|
@@ -187,10 +187,10 @@ typedef int (*curl_progress_callback)(void *clientp,
|
||||
#define CURL_MAX_HTTP_HEADER (100*1024)
|
||||
#endif
|
||||
|
||||
|
||||
/* This is a magic return code for the write callback that, when returned,
|
||||
will signal libcurl to pause receiving on the current transfer. */
|
||||
#define CURL_WRITEFUNC_PAUSE 0x10000001
|
||||
|
||||
typedef size_t (*curl_write_callback)(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
@@ -2014,8 +2014,9 @@ typedef enum {
|
||||
CURLSHE_BAD_OPTION, /* 1 */
|
||||
CURLSHE_IN_USE, /* 2 */
|
||||
CURLSHE_INVALID, /* 3 */
|
||||
CURLSHE_NOMEM, /* out of memory */
|
||||
CURLSHE_LAST /* never use */
|
||||
CURLSHE_NOMEM, /* 4 out of memory */
|
||||
CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */
|
||||
CURLSHE_LAST /* never use */
|
||||
} CURLSHcode;
|
||||
|
||||
typedef enum {
|
||||
|
@@ -30,12 +30,12 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.22.0-DEV"
|
||||
#define LIBCURL_VERSION "7.24.0-DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 22
|
||||
#define LIBCURL_VERSION_MINOR 24
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
@@ -53,7 +53,7 @@
|
||||
and it is always a greater number in a more recent release. It makes
|
||||
comparisons with greater than and less than work.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x071600
|
||||
#define LIBCURL_VERSION_NUM 0x071800
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
@@ -392,7 +392,8 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
|
||||
/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
|
||||
/* XXX: also check size of an char[] array? */
|
||||
#define _curl_is_error_buffer(expr) \
|
||||
(__builtin_types_compatible_p(__typeof__(expr), char *) || \
|
||||
(_curl_is_NULL(expr) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), char *) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), char[]))
|
||||
|
||||
/* evaluates to true if expr is of type (const) void* or (const) FILE* */
|
||||
@@ -521,7 +522,11 @@ typedef int (_curl_progress_callback2)(const void *,
|
||||
_curl_callback_compatible((expr), _curl_debug_callback1) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback2) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback3) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback4))
|
||||
_curl_callback_compatible((expr), _curl_debug_callback4) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback5) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback6) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback7) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback8))
|
||||
typedef int (_curl_debug_callback1) (CURL *,
|
||||
curl_infotype, char *, size_t, void *);
|
||||
typedef int (_curl_debug_callback2) (CURL *,
|
||||
@@ -530,6 +535,14 @@ typedef int (_curl_debug_callback3) (CURL *,
|
||||
curl_infotype, const char *, size_t, void *);
|
||||
typedef int (_curl_debug_callback4) (CURL *,
|
||||
curl_infotype, const char *, size_t, const void *);
|
||||
typedef int (_curl_debug_callback5) (CURL *,
|
||||
curl_infotype, unsigned char *, size_t, void *);
|
||||
typedef int (_curl_debug_callback6) (CURL *,
|
||||
curl_infotype, unsigned char *, size_t, const void *);
|
||||
typedef int (_curl_debug_callback7) (CURL *,
|
||||
curl_infotype, const unsigned char *, size_t, void *);
|
||||
typedef int (_curl_debug_callback8) (CURL *,
|
||||
curl_infotype, const unsigned char *, size_t, const void *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
|
||||
/* this is getting even messier... */
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#########################################################################
|
||||
###########################################################################
|
||||
#
|
||||
## Makefile for building libcurl.a with MingW32 (GCC-3.2 or later)
|
||||
## and optionally OpenSSL (0.9.8), libssh2 (1.2), zlib (1.2.5), librtmp (2.3)
|
||||
## Makefile for building libcurl.a with MingW (GCC-3.2 or later)
|
||||
## and optionally OpenSSL (0.9.8), libssh2 (1.3), zlib (1.2.5), librtmp (2.3)
|
||||
##
|
||||
## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...]
|
||||
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-sspi-winidn
|
||||
@@ -9,10 +9,8 @@
|
||||
## Hint: you can also set environment vars to control the build, f.e.:
|
||||
## set ZLIB_PATH=c:/zlib-1.2.5
|
||||
## set ZLIB=1
|
||||
##
|
||||
## Comments to: Troy Engel <tengel@sonic.net> or
|
||||
## Joern Hartroth <hartroth@acm.org>
|
||||
#########################################################################
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ifndef ZLIB_PATH
|
||||
@@ -22,6 +20,15 @@ endif
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.8r
|
||||
endif
|
||||
ifndef OPENSSL_INCLUDE
|
||||
OPENSSL_INCLUDE = $(OPENSSL_PATH)/outinc
|
||||
endif
|
||||
ifndef OPENSSL_LIBPATH
|
||||
OPENSSL_LIBPATH = $(OPENSSL_PATH)/out
|
||||
endif
|
||||
ifndef OPENSSL_LIBS
|
||||
OPENSSL_LIBS = -leay32 -lssl32
|
||||
endif
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.3.0
|
||||
@@ -45,9 +52,11 @@ ifndef LDAP_SDK
|
||||
LDAP_SDK = c:/novell/ndk/cldapsdk/win32
|
||||
endif
|
||||
|
||||
PROOT = ..
|
||||
|
||||
# Edit the path below to point to the base of your c-ares package.
|
||||
ifndef LIBCARES_PATH
|
||||
LIBCARES_PATH = ../ares
|
||||
LIBCARES_PATH = $(PROOT)/ares
|
||||
endif
|
||||
|
||||
# Edit the var below to set to your architecture or set environment var.
|
||||
@@ -57,6 +66,7 @@ endif
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -O2 -Wall
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
ifeq ($(ARCH),w64)
|
||||
CFLAGS += -D_AMD64_
|
||||
endif
|
||||
@@ -65,10 +75,12 @@ LDFLAGS = -s
|
||||
AR = ar
|
||||
RANLIB = ranlib
|
||||
RC = windres
|
||||
RCFLAGS = --include-dir=../include -DDEBUGBUILD=0 -O COFF -i
|
||||
RM = del /q /f 2>NUL
|
||||
RCFLAGS = --include-dir=$(PROOT)/include -DDEBUGBUILD=0 -O COFF -i
|
||||
STRIP = strip -g
|
||||
|
||||
RM = del /q /f 2>NUL
|
||||
CP = copy
|
||||
|
||||
########################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
@@ -115,10 +127,11 @@ endif
|
||||
|
||||
INCLUDES = -I. -I../include
|
||||
CFLAGS += -DBUILDING_LIBCURL
|
||||
|
||||
ifdef ARES
|
||||
INCLUDES += -I$(LIBCARES_PATH)
|
||||
INCLUDES += -I"$(LIBCARES_PATH)"
|
||||
CFLAGS += -DUSE_ARES
|
||||
DLL_LIBS += -L$(LIBCARES_PATH) -lcares
|
||||
DLL_LIBS += -L"$(LIBCARES_PATH)" -lcares
|
||||
libcurl_dll_DEPENDENCIES = $(LIBCARES_PATH)/libcares.a
|
||||
endif
|
||||
ifdef RTMP
|
||||
@@ -129,24 +142,24 @@ endif
|
||||
ifdef SSH2
|
||||
INCLUDES += -I"$(LIBSSH2_PATH)/include" -I"$(LIBSSH2_PATH)/win32"
|
||||
CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H
|
||||
DLL_LIBS += -L$(LIBSSH2_PATH)/win32 -lssh2
|
||||
DLL_LIBS += -L"$(LIBSSH2_PATH)/win32" -lssh2
|
||||
endif
|
||||
ifdef SSL
|
||||
INCLUDES += -I"$(OPENSSL_PATH)/outinc" -I"$(OPENSSL_PATH)/outinc/openssl"
|
||||
INCLUDES += -I"$(OPENSSL_INCLUDE)"
|
||||
CFLAGS += -DUSE_SSLEAY -DUSE_OPENSSL -DHAVE_OPENSSL_ENGINE_H -DHAVE_OPENSSL_PKCS12_H \
|
||||
-DHAVE_ENGINE_LOAD_BUILTIN_ENGINES -DOPENSSL_NO_KRB5 \
|
||||
-DCURL_WANTS_CA_BUNDLE_ENV
|
||||
DLL_LIBS += -L$(OPENSSL_PATH)/out -leay32 -lssl32
|
||||
DLL_LIBS += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS)
|
||||
endif
|
||||
ifdef ZLIB
|
||||
INCLUDES += -I"$(ZLIB_PATH)"
|
||||
CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
|
||||
DLL_LIBS += -L$(ZLIB_PATH) -lz
|
||||
DLL_LIBS += -L"$(ZLIB_PATH)" -lz
|
||||
endif
|
||||
ifdef IDN
|
||||
INCLUDES += -I"$(LIBIDN_PATH)/include"
|
||||
CFLAGS += -DUSE_LIBIDN
|
||||
DLL_LIBS += -L$(LIBIDN_PATH)/lib -lidn
|
||||
DLL_LIBS += -L"$(LIBIDN_PATH)/lib" -lidn
|
||||
else
|
||||
ifdef WINIDN
|
||||
CFLAGS += -DUSE_WIN32_IDN
|
||||
@@ -161,7 +174,7 @@ ifdef SPNEGO
|
||||
CFLAGS += -DHAVE_SPNEGO
|
||||
endif
|
||||
ifdef IPV6
|
||||
CFLAGS += -DENABLE_IPV6
|
||||
CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501
|
||||
endif
|
||||
ifdef LDAPS
|
||||
CFLAGS += -DHAVE_LDAP_SSL
|
||||
@@ -178,11 +191,10 @@ ifdef USE_LDAP_OPENLDAP
|
||||
endif
|
||||
ifndef USE_LDAP_NOVELL
|
||||
ifndef USE_LDAP_OPENLDAP
|
||||
DLL_LIBS += -lwldap32
|
||||
DLL_LIBS += -lwldap32
|
||||
endif
|
||||
endif
|
||||
DLL_LIBS += -lws2_32
|
||||
COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include Makefile.inc
|
||||
@@ -196,7 +208,6 @@ libcurl_a_DEPENDENCIES := $(strip $(CSOURCES) $(HHEADERS))
|
||||
|
||||
RESOURCE = libcurl.res
|
||||
|
||||
.SUFFIXES: .rc .res
|
||||
|
||||
all: $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY)
|
||||
|
||||
@@ -213,20 +224,25 @@ $(libcurl_dll_LIBRARY): $(libcurl_a_OBJECTS) $(RESOURCE) $(libcurl_dll_DEPENDENC
|
||||
$(CC) $(LDFLAGS) -shared -Wl,--out-implib,$(libcurl_dll_a_LIBRARY) \
|
||||
-o $@ $(libcurl_a_OBJECTS) $(RESOURCE) $(DLL_LIBS)
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) -c $<
|
||||
%.o: %.c $(PROOT)/include/curl/curlbuild.h
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
.rc.res:
|
||||
%.res: %.rc
|
||||
$(RC) $(RCFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
ifeq "$(wildcard $(PROOT)/include/curl/curlbuild.h.dist)" "$(PROOT)/include/curl/curlbuild.h.dist"
|
||||
-$(RM) $(subst /,\,$(PROOT)/include/curl/curlbuild.h)
|
||||
endif
|
||||
-$(RM) $(libcurl_a_OBJECTS) $(RESOURCE)
|
||||
|
||||
distclean vclean: clean
|
||||
-$(RM) $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY) $(libcurl_dll_a_LIBRARY)
|
||||
|
||||
FORCE: ;
|
||||
|
||||
$(LIBCARES_PATH)/libcares.a:
|
||||
$(MAKE) -C $(LIBCARES_PATH) -f Makefile.m32
|
||||
|
||||
$(PROOT)/include/curl/curlbuild.h:
|
||||
@echo Creating $@
|
||||
@$(CP) $(subst /,\,$@).dist $(subst /,\,$@)
|
||||
|
||||
|
@@ -42,6 +42,11 @@ ifndef LIBRTMP_PATH
|
||||
LIBRTMP_PATH = ../../librtmp-2.3
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your fbopenssl package.
|
||||
ifndef FBOPENSSL_PATH
|
||||
FBOPENSSL_PATH = ../../fbopenssl-0.4
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your c-ares package.
|
||||
ifndef LIBCARES_PATH
|
||||
LIBCARES_PATH = ../ares
|
||||
@@ -181,6 +186,43 @@ CURL_LIB = ../lib
|
||||
|
||||
INCLUDES = -I$(CURL_INC) -I$(CURL_LIB)
|
||||
|
||||
ifeq ($(findstring -static,$(CFG)),-static)
|
||||
LINK_STATIC = 1
|
||||
endif
|
||||
ifeq ($(findstring -ares,$(CFG)),-ares)
|
||||
WITH_ARES = 1
|
||||
endif
|
||||
ifeq ($(findstring -rtmp,$(CFG)),-rtmp)
|
||||
WITH_RTMP = 1
|
||||
WITH_SSL = 1
|
||||
WITH_ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -ssh2,$(CFG)),-ssh2)
|
||||
WITH_SSH2 = 1
|
||||
WITH_SSL = 1
|
||||
WITH_ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -axtls,$(CFG)),-axtls)
|
||||
WITH_AXTLS = 1
|
||||
WITH_SSL =
|
||||
else
|
||||
ifeq ($(findstring -ssl,$(CFG)),-ssl)
|
||||
WITH_SSL = 1
|
||||
endif
|
||||
endif
|
||||
ifeq ($(findstring -zlib,$(CFG)),-zlib)
|
||||
WITH_ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -idn,$(CFG)),-idn)
|
||||
WITH_IDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -spnego,$(CFG)),-spnego)
|
||||
WITH_SPNEGO = 1
|
||||
endif
|
||||
ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
|
||||
ENABLE_IPV6 = 1
|
||||
endif
|
||||
|
||||
ifdef WITH_ARES
|
||||
INCLUDES += -I$(LIBCARES_PATH)
|
||||
LDLIBS += $(LIBCARES_PATH)/libcares.$(LIBEXT)
|
||||
@@ -204,6 +246,10 @@ ifdef WITH_SSL
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
|
||||
IMPORTS += GetProcessSwitchCount RunningProcess
|
||||
INSTDEP += ca-bundle.crt
|
||||
ifdef WITH_SPNEGO
|
||||
INCLUDES += -I$(FBOPENSSL_PATH)/include
|
||||
LDLIBS += $(FBOPENSSL_PATH)/nw/fbopenssl.$(LIBEXT)
|
||||
endif
|
||||
else
|
||||
ifdef WITH_AXTLS
|
||||
INCLUDES += -I$(AXTLS_PATH)/inc
|
||||
@@ -584,6 +630,9 @@ ifdef WITH_SSL
|
||||
@echo $(DL)#define HAVE_LIBSSL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBCRYPTO 1$(DL) >> $@
|
||||
@echo $(DL)#define OPENSSL_NO_KRB5 1$(DL) >> $@
|
||||
ifdef WITH_SPNEGO
|
||||
@echo $(DL)#define HAVE_SPNEGO 1$(DL) >> $@
|
||||
endif
|
||||
else
|
||||
ifdef WITH_AXTLS
|
||||
@echo $(DL)#define USE_AXTLS 1$(DL) >> $@
|
||||
|
@@ -653,10 +653,10 @@
|
||||
#undef OS
|
||||
#if defined(_M_IX86) || defined(__i386__) /* x86 (MSVC or gcc) */
|
||||
#define OS "i386-pc-win32"
|
||||
#elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (MSVC >=2005 or gcc) */
|
||||
#define OS "x86_64-pc-win32"
|
||||
#elif defined(_M_IA64) /* Itanium */
|
||||
#define OS "ia64-pc-win32"
|
||||
#elif defined(_M_X64) /* AMD64/EM64T - Not defined until MSVC 2005 */
|
||||
#define OS "amd64-pc-win32"
|
||||
#else
|
||||
#define OS "unknown-pc-win32"
|
||||
#endif
|
||||
|
@@ -836,7 +836,7 @@ singleipconnect(struct connectdata *conn,
|
||||
{
|
||||
struct Curl_sockaddr_ex addr;
|
||||
int rc;
|
||||
int error;
|
||||
int error = 0;
|
||||
bool isconnected = FALSE;
|
||||
struct SessionHandle *data = conn->data;
|
||||
curl_socket_t sockfd;
|
||||
@@ -907,11 +907,6 @@ singleipconnect(struct connectdata *conn,
|
||||
|
||||
Curl_persistconninfo(conn);
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
if(addr.family == AF_INET6)
|
||||
conn->bits.ipv6 = TRUE;
|
||||
#endif
|
||||
|
||||
if(data->set.tcp_nodelay)
|
||||
tcpnodelay(conn, sockfd);
|
||||
|
||||
@@ -946,6 +941,8 @@ singleipconnect(struct connectdata *conn,
|
||||
/* Connect TCP sockets, bind UDP */
|
||||
if(!isconnected && (conn->socktype == SOCK_STREAM)) {
|
||||
rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
|
||||
if(-1 == rc)
|
||||
error = SOCKERRNO;
|
||||
conn->connecttime = Curl_tvnow();
|
||||
if(conn->num_addr > 1)
|
||||
Curl_expire(data, conn->timeoutms_per_addr);
|
||||
@@ -954,8 +951,6 @@ singleipconnect(struct connectdata *conn,
|
||||
rc = 0;
|
||||
|
||||
if(-1 == rc) {
|
||||
error = SOCKERRNO;
|
||||
|
||||
switch (error) {
|
||||
case EINPROGRESS:
|
||||
case EWOULDBLOCK:
|
||||
@@ -999,6 +994,10 @@ singleipconnect(struct connectdata *conn,
|
||||
/* we are connected, awesome! */
|
||||
*connected = TRUE; /* this is a true connect */
|
||||
infof(data, "connected\n");
|
||||
#ifdef ENABLE_IPV6
|
||||
conn->bits.ipv6 = (addr.family == AF_INET6)?TRUE:FALSE;
|
||||
#endif
|
||||
|
||||
Curl_updateconninfo(conn, sockfd);
|
||||
*sockp = sockfd;
|
||||
return CURLE_OK;
|
||||
|
21
lib/cookie.c
21
lib/cookie.c
@@ -144,9 +144,9 @@ void Curl_cookie_loadfiles(struct SessionHandle *data)
|
||||
data->set.cookiesession);
|
||||
list = list->next;
|
||||
}
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
curl_slist_free_all(data->change.cookielist); /* clean up list */
|
||||
data->change.cookielist = NULL; /* don't do this again! */
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1107,23 +1107,20 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
|
||||
|
||||
c = data->cookies->cookies;
|
||||
|
||||
beg = list;
|
||||
while(c) {
|
||||
/* fill the list with _all_ the cookies we know */
|
||||
line = get_netscape_format(c);
|
||||
if(line == NULL) {
|
||||
curl_slist_free_all(beg);
|
||||
if(!line) {
|
||||
curl_slist_free_all(list);
|
||||
return NULL;
|
||||
}
|
||||
list = curl_slist_append(list, line);
|
||||
beg = curl_slist_append(list, line);
|
||||
free(line);
|
||||
if(list == NULL) {
|
||||
curl_slist_free_all(beg);
|
||||
if(!beg) {
|
||||
curl_slist_free_all(list);
|
||||
return NULL;
|
||||
}
|
||||
else if(beg == NULL) {
|
||||
beg = list;
|
||||
}
|
||||
list = beg;
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
@@ -1148,10 +1145,12 @@ void Curl_flush_cookies(struct SessionHandle *data, int cleanup)
|
||||
data->set.str[STRING_COOKIEJAR]);
|
||||
}
|
||||
else {
|
||||
if(cleanup && data->change.cookielist)
|
||||
if(cleanup && data->change.cookielist) {
|
||||
/* since nothing is written, we can just free the list of cookie file
|
||||
names */
|
||||
curl_slist_free_all(data->change.cookielist); /* clean up list */
|
||||
data->change.cookielist = NULL;
|
||||
}
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
}
|
||||
|
||||
|
@@ -32,12 +32,16 @@
|
||||
* Curl_gethostname() is a wrapper around gethostname() which allows
|
||||
* overriding the host name that the function would normally return.
|
||||
* This capability is used by the test suite to verify exact matching
|
||||
* of NTLM authentication, which exercises libcurl's MD4 and DES code.
|
||||
* of NTLM authentication, which exercises libcurl's MD4 and DES code
|
||||
* as well as by the SMTP module when a hostname is not provided.
|
||||
*
|
||||
* For libcurl debug enabled builds host name overriding takes place
|
||||
* when environment variable CURL_GETHOSTNAME is set, using the value
|
||||
* held by the variable to override returned host name.
|
||||
*
|
||||
* Note: The function always returns the un-qualified hostname rather
|
||||
* than being provider dependent.
|
||||
*
|
||||
* For libcurl shared library release builds the test suite preloads
|
||||
* another shared library named libhostname using the LD_PRELOAD
|
||||
* mechanism which intercepts, and might override, the gethostname()
|
||||
@@ -58,6 +62,8 @@ int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) {
|
||||
return -1;
|
||||
|
||||
#else
|
||||
int err;
|
||||
char* dot;
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
|
||||
@@ -65,17 +71,34 @@ int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) {
|
||||
const char *force_hostname = getenv("CURL_GETHOSTNAME");
|
||||
if(force_hostname) {
|
||||
strncpy(name, force_hostname, namelen);
|
||||
name[namelen-1] = '\0';
|
||||
return 0;
|
||||
err = 0;
|
||||
}
|
||||
else {
|
||||
name[0] = '\0';
|
||||
err = gethostname(name, namelen);
|
||||
}
|
||||
|
||||
#endif /* DEBUGBUILD */
|
||||
#else /* DEBUGBUILD */
|
||||
|
||||
/* The call to system's gethostname() might get intercepted by the
|
||||
libhostname library when libcurl is built as a non-debug shared
|
||||
library when running the test suite. */
|
||||
return gethostname(name, namelen);
|
||||
name[0] = '\0';
|
||||
err = gethostname(name, namelen);
|
||||
|
||||
#endif
|
||||
|
||||
name[namelen - 1] = '\0';
|
||||
|
||||
if(err)
|
||||
return err;
|
||||
|
||||
/* Truncate domain, leave only machine name */
|
||||
dot = strchr(name, '.');
|
||||
if(dot)
|
||||
*dot = '\0';
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@@ -22,6 +22,10 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* Hostname buffer size */
|
||||
#define HOSTNAME_MAX 1024
|
||||
|
||||
/* This returns the local machine's un-qualified hostname */
|
||||
int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen);
|
||||
|
||||
#endif /* HEADER_CURL_GETHOSTNAME_H */
|
||||
|
@@ -114,6 +114,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
bool proxy)
|
||||
{
|
||||
char *base64 = NULL;
|
||||
size_t len = 0;
|
||||
CURLcode error;
|
||||
|
||||
/* point to the address of the pointer that holds the string to send to the
|
||||
@@ -172,7 +173,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
case NTLMSTATE_TYPE1:
|
||||
default: /* for the weird cases we (re)start here */
|
||||
/* Create a type-1 message */
|
||||
error = Curl_ntlm_create_type1_message(userp, passwdp, ntlm, &base64);
|
||||
error = Curl_ntlm_create_type1_message(userp, passwdp, ntlm, &base64,
|
||||
&len);
|
||||
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
@@ -189,7 +192,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
case NTLMSTATE_TYPE2:
|
||||
/* We already received the type-2 message, create a type-3 message */
|
||||
error = Curl_ntlm_create_type3_message(conn->data, userp, passwdp,
|
||||
ntlm, &base64);
|
||||
ntlm, &base64, &len);
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
|
@@ -93,9 +93,6 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Hostname buffer size */
|
||||
#define HOSTNAME_MAX 1024
|
||||
|
||||
/* "NTLMSSP" signature is always in ASCII regardless of the platform */
|
||||
#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
|
||||
|
||||
@@ -357,13 +354,15 @@ static void unicodecpy(unsigned char *dest,
|
||||
* ntlm [in/out] - The ntlm data struct being used and modified.
|
||||
* outptr [in/out] - The adress where a pointer to newly allocated memory
|
||||
* holding the result will be stored upon completion.
|
||||
* outlen [out] - The length of the output message.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
const char *passwdp,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr)
|
||||
char **outptr,
|
||||
size_t *outlen)
|
||||
{
|
||||
/* NTLM type-1 message structure:
|
||||
|
||||
@@ -380,7 +379,6 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
*/
|
||||
|
||||
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
||||
size_t base64_sz = 0;
|
||||
size_t size;
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
@@ -559,7 +557,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
});
|
||||
|
||||
/* Return with binary blob encoded into base64 */
|
||||
return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, &base64_sz);
|
||||
return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -577,6 +575,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
* ntlm [in/out] - The ntlm data struct being used and modified.
|
||||
* outptr [in/out] - The adress where a pointer to newly allocated memory
|
||||
* holding the result will be stored upon completion.
|
||||
* outlen [out] - The length of the output message.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
@@ -584,7 +583,8 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr)
|
||||
char **outptr,
|
||||
size_t *outlen)
|
||||
{
|
||||
/* NTLM type-3 message structure:
|
||||
|
||||
@@ -605,7 +605,6 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
*/
|
||||
|
||||
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
||||
size_t base64_sz = 0;
|
||||
size_t size;
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
@@ -686,18 +685,13 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
if(user)
|
||||
userlen = strlen(user);
|
||||
|
||||
if(Curl_gethostname(host, HOSTNAME_MAX)) {
|
||||
/* Get the machine's un-qualified host name as NTLM doesn't like the fully
|
||||
qualified domain name */
|
||||
if(Curl_gethostname(host, sizeof(host))) {
|
||||
infof(data, "gethostname() failed, continuing without!");
|
||||
hostlen = 0;
|
||||
}
|
||||
else {
|
||||
/* If the workstation if configured with a full DNS name (i.e.
|
||||
* workstation.somewhere.net) gethostname() returns the fully qualified
|
||||
* name, which NTLM doesn't like.
|
||||
*/
|
||||
char *dot = strchr(host, '.');
|
||||
if(dot)
|
||||
*dot = '\0';
|
||||
hostlen = strlen(host);
|
||||
}
|
||||
|
||||
@@ -726,7 +720,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
gcry_randomize(entropy, 8, GCRY_STRONG_RANDOM);
|
||||
#elif defined(USE_NSS)
|
||||
PK11Context *MD5pw;
|
||||
unsigned int outlen;
|
||||
unsigned int MD5len;
|
||||
Curl_nss_seed(data); /* Initiate the seed if not already done */
|
||||
PK11_GenerateRandom(entropy, 8);
|
||||
#endif
|
||||
@@ -753,7 +747,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
#elif defined(USE_NSS)
|
||||
MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
|
||||
PK11_DigestOp(MD5pw, tmp, 16);
|
||||
PK11_DigestFinal(MD5pw, md5sum, &outlen, MD5_DIGEST_LENGTH);
|
||||
PK11_DigestFinal(MD5pw, md5sum, &MD5len, MD5_DIGEST_LENGTH);
|
||||
PK11_DestroyContext(MD5pw, PR_TRUE);
|
||||
#endif
|
||||
|
||||
@@ -958,7 +952,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
#endif
|
||||
|
||||
/* Return with binary blob encoded into base64 */
|
||||
return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, &base64_sz);
|
||||
return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM */
|
||||
|
@@ -30,14 +30,16 @@
|
||||
CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
const char *passwdp,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr);
|
||||
char **outptr,
|
||||
size_t *outlen);
|
||||
|
||||
/* This is to generate a base64 encoded NTLM type-3 message */
|
||||
CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr);
|
||||
char **outptr,
|
||||
size_t *outlen);
|
||||
|
||||
/* This is to decode a NTLM type-2 message */
|
||||
CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
|
||||
@@ -47,6 +49,8 @@ CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
|
||||
/* This is to clean up the ntlm data structure */
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm);
|
||||
#else
|
||||
#define Curl_ntlm_sspi_cleanup(x)
|
||||
#endif
|
||||
|
||||
/* NTLM buffer fixed size, large enough for long user + host + domain */
|
||||
|
@@ -71,6 +71,7 @@ const struct Curl_handler Curl_handler_rtmp = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -90,6 +91,7 @@ const struct Curl_handler Curl_handler_rtmpt = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -109,6 +111,7 @@ const struct Curl_handler Curl_handler_rtmpe = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -128,6 +131,7 @@ const struct Curl_handler Curl_handler_rtmpte = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -147,6 +151,7 @@ const struct Curl_handler Curl_handler_rtmps = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -166,6 +171,7 @@ const struct Curl_handler Curl_handler_rtmpts = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
|
@@ -92,6 +92,7 @@ const struct Curl_handler Curl_handler_dict = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
|
21
lib/easy.c
21
lib/easy.c
@@ -676,16 +676,15 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
|
||||
if(outcurl) {
|
||||
if(outcurl->state.connc &&
|
||||
(outcurl->state.connc->type == CONNCACHE_PRIVATE))
|
||||
(outcurl->state.connc->type == CONNCACHE_PRIVATE)) {
|
||||
Curl_rm_connc(outcurl->state.connc);
|
||||
if(outcurl->state.headerbuff)
|
||||
free(outcurl->state.headerbuff);
|
||||
if(outcurl->change.cookielist)
|
||||
curl_slist_free_all(outcurl->change.cookielist);
|
||||
if(outcurl->change.url)
|
||||
free(outcurl->change.url);
|
||||
if(outcurl->change.referer)
|
||||
free(outcurl->change.referer);
|
||||
outcurl->state.connc = NULL;
|
||||
}
|
||||
curl_slist_free_all(outcurl->change.cookielist);
|
||||
outcurl->change.cookielist = NULL;
|
||||
Curl_safefree(outcurl->state.headerbuff);
|
||||
Curl_safefree(outcurl->change.url);
|
||||
Curl_safefree(outcurl->change.referer);
|
||||
Curl_freeset(outcurl);
|
||||
free(outcurl);
|
||||
}
|
||||
@@ -702,10 +701,10 @@ void curl_easy_reset(CURL *curl)
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
Curl_safefree(data->state.pathbuffer);
|
||||
data->state.pathbuffer=NULL;
|
||||
|
||||
data->state.path = NULL;
|
||||
|
||||
Curl_safefree(data->state.proto.generic);
|
||||
data->state.proto.generic=NULL;
|
||||
|
||||
/* zero out UserDefined data: */
|
||||
Curl_freeset(data);
|
||||
|
52
lib/file.c
52
lib/file.c
@@ -67,6 +67,7 @@
|
||||
#include "url.h"
|
||||
#include "curl_memory.h"
|
||||
#include "parsedate.h" /* for the week day and month names */
|
||||
#include "warnless.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -93,6 +94,9 @@ static CURLcode file_do(struct connectdata *, bool *done);
|
||||
static CURLcode file_done(struct connectdata *conn,
|
||||
CURLcode status, bool premature);
|
||||
static CURLcode file_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode file_disconnect(struct connectdata *conn,
|
||||
bool dead_connection);
|
||||
|
||||
|
||||
/*
|
||||
* FILE scheme handler.
|
||||
@@ -109,8 +113,9 @@ const struct Curl_handler Curl_handler_file = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
file_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
0, /* defport */
|
||||
CURLPROTO_FILE, /* protocol */
|
||||
@@ -179,7 +184,7 @@ static CURLcode file_range(struct connectdata *conn)
|
||||
static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
char *real_path = curl_easy_unescape(data, data->state.path, 0, NULL);
|
||||
char *real_path;
|
||||
struct FILEPROTO *file;
|
||||
int fd;
|
||||
#ifdef DOS_FILESYSTEM
|
||||
@@ -187,13 +192,14 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
char *actual_path;
|
||||
#endif
|
||||
|
||||
if(!real_path)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* If there already is a protocol-specific struct allocated for this
|
||||
sessionhandle, deal with it */
|
||||
Curl_reset_reqproto(conn);
|
||||
|
||||
real_path = curl_easy_unescape(data, data->state.path, 0, NULL);
|
||||
if(!real_path)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(!data->state.proto.file) {
|
||||
file = calloc(1, sizeof(struct FILEPROTO));
|
||||
if(!file) {
|
||||
@@ -206,10 +212,9 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
/* file is not a protocol that can deal with "persistancy" */
|
||||
file = data->state.proto.file;
|
||||
Curl_safefree(file->freepath);
|
||||
file->path = NULL;
|
||||
if(file->fd != -1)
|
||||
close(file->fd);
|
||||
file->path = NULL;
|
||||
file->freepath = NULL;
|
||||
file->fd = -1;
|
||||
}
|
||||
|
||||
@@ -266,10 +271,31 @@ static CURLcode file_done(struct connectdata *conn,
|
||||
struct FILEPROTO *file = conn->data->state.proto.file;
|
||||
(void)status; /* not used */
|
||||
(void)premature; /* not used */
|
||||
Curl_safefree(file->freepath);
|
||||
|
||||
if(file->fd != -1)
|
||||
close(file->fd);
|
||||
if(file) {
|
||||
Curl_safefree(file->freepath);
|
||||
file->path = NULL;
|
||||
if(file->fd != -1)
|
||||
close(file->fd);
|
||||
file->fd = -1;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode file_disconnect(struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
struct FILEPROTO *file = conn->data->state.proto.file;
|
||||
(void)dead_connection; /* not used */
|
||||
|
||||
if(file) {
|
||||
Curl_safefree(file->freepath);
|
||||
file->path = NULL;
|
||||
if(file->fd != -1)
|
||||
close(file->fd);
|
||||
file->fd = -1;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -422,7 +448,6 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
curl_off_t expected_size=0;
|
||||
bool fstated=FALSE;
|
||||
ssize_t nread;
|
||||
size_t bytestoread;
|
||||
struct SessionHandle *data = conn->data;
|
||||
char *buf = data->state.buffer;
|
||||
curl_off_t bytecount = 0;
|
||||
@@ -544,7 +569,10 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
|
||||
while(res == CURLE_OK) {
|
||||
/* Don't fill a whole buffer if we want less than all data */
|
||||
bytestoread = (expected_size < BUFSIZE-1)?(size_t)expected_size:BUFSIZE-1;
|
||||
size_t bytestoread =
|
||||
(expected_size < CURL_OFF_T_C(BUFSIZE) - CURL_OFF_T_C(1)) ?
|
||||
curlx_sotouz(expected_size) : BUFSIZE - 1;
|
||||
|
||||
nread = read(fd, buf, bytestoread);
|
||||
|
||||
if(nread > 0)
|
||||
|
@@ -48,8 +48,7 @@ void Curl_fileinfo_dtor(void *user, void *element)
|
||||
if(!finfo)
|
||||
return;
|
||||
|
||||
if(finfo->b_data)
|
||||
free(finfo->b_data);
|
||||
Curl_safefree(finfo->b_data);
|
||||
|
||||
free(finfo);
|
||||
}
|
||||
|
@@ -855,10 +855,11 @@ int curl_formget(struct curl_httppost *form, void *arg,
|
||||
|
||||
do {
|
||||
nread = readfromfile(&temp, buffer, sizeof(buffer));
|
||||
if((nread == (size_t) -1) || (nread != append(arg, buffer, nread))) {
|
||||
if(temp.fp) {
|
||||
if((nread == (size_t) -1) ||
|
||||
(nread > sizeof(buffer)) ||
|
||||
(nread != append(arg, buffer, nread))) {
|
||||
if(temp.fp)
|
||||
fclose(temp.fp);
|
||||
}
|
||||
Curl_formclean(&data);
|
||||
return -1;
|
||||
}
|
||||
@@ -1269,6 +1270,13 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata )
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* readfromfile()
|
||||
*
|
||||
* The read callback that this function may use can return a value larger than
|
||||
* 'size' (which then this function returns) that indicates a problem and it
|
||||
* must be properly dealt with
|
||||
*/
|
||||
static size_t readfromfile(struct Form *form, char *buffer,
|
||||
size_t size)
|
||||
{
|
||||
@@ -1280,11 +1288,6 @@ static size_t readfromfile(struct Form *form, char *buffer,
|
||||
return 0;
|
||||
else
|
||||
nread = form->fread_func(buffer, 1, size, form->data->line);
|
||||
|
||||
if(nread > size)
|
||||
/* the read callback can return a value larger than the buffer but
|
||||
treat any such as no data in this case */
|
||||
nread = 0;
|
||||
}
|
||||
else {
|
||||
if(!form->fp) {
|
||||
|
108
lib/ftp.c
108
lib/ftp.c
@@ -134,9 +134,10 @@ static CURLcode ftp_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
|
||||
static CURLcode ftp_nextconnect(struct connectdata *conn);
|
||||
static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
|
||||
static int ftp_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks,
|
||||
int numsocks);
|
||||
static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
|
||||
int numsocks);
|
||||
static CURLcode ftp_doing(struct connectdata *conn,
|
||||
bool *dophase_done);
|
||||
static CURLcode ftp_setup_connection(struct connectdata * conn);
|
||||
@@ -171,6 +172,7 @@ const struct Curl_handler Curl_handler_ftp = {
|
||||
ftp_doing, /* doing */
|
||||
ftp_getsock, /* proto_getsock */
|
||||
ftp_getsock, /* doing_getsock */
|
||||
ftp_domore_getsock, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -196,6 +198,7 @@ const struct Curl_handler Curl_handler_ftps = {
|
||||
ftp_doing, /* doing */
|
||||
ftp_getsock, /* proto_getsock */
|
||||
ftp_getsock, /* doing_getsock */
|
||||
ftp_domore_getsock, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -222,6 +225,7 @@ static const struct Curl_handler Curl_handler_ftp_proxy = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -247,6 +251,7 @@ static const struct Curl_handler Curl_handler_ftps_proxy = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -634,6 +639,37 @@ static int ftp_getsock(struct connectdata *conn,
|
||||
return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
|
||||
}
|
||||
|
||||
/* For the FTP "DO_MORE" phase only */
|
||||
static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
|
||||
if(!numsocks)
|
||||
return GETSOCK_BLANK;
|
||||
|
||||
/* When in DO_MORE state, we could be either waiting for us to connect to a
|
||||
remote site, or we could wait for that site to connect to us. Or just
|
||||
handle ordinary commands.
|
||||
|
||||
When waiting for a connect, we will be in FTP_STOP state and then we wait
|
||||
for the secondary socket to become writeable. If we're in another state,
|
||||
we're still handling commands on the control (primary) connection.
|
||||
|
||||
*/
|
||||
|
||||
switch(ftpc->state) {
|
||||
case FTP_STOP:
|
||||
break;
|
||||
default:
|
||||
return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
|
||||
}
|
||||
|
||||
socks[0] = conn->sock[SECONDARYSOCKET];
|
||||
|
||||
return GETSOCK_READSOCK(0);
|
||||
}
|
||||
|
||||
/* This is called after the FTP_QUOTE state is passed.
|
||||
|
||||
ftp_state_cwd() sends the range of CWD commands to the server to change to
|
||||
@@ -711,12 +747,13 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
static const char mode[][5] = { "EPRT", "PORT" };
|
||||
int rc;
|
||||
int error;
|
||||
char *host=NULL;
|
||||
char *host = NULL;
|
||||
char *string_ftpport = data->set.str[STRING_FTPPORT];
|
||||
struct Curl_dns_entry *h=NULL;
|
||||
unsigned short port_min = 0;
|
||||
unsigned short port_max = 0;
|
||||
unsigned short port;
|
||||
bool possibly_non_local = TRUE;
|
||||
|
||||
char *addr = NULL;
|
||||
|
||||
@@ -819,8 +856,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
|
||||
failf(data, "getsockname() failed: %s",
|
||||
Curl_strerror(conn, SOCKERRNO) );
|
||||
if(addr)
|
||||
free(addr);
|
||||
Curl_safefree(addr);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
switch(sa->sa_family) {
|
||||
@@ -834,6 +870,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
host = hbuf; /* use this host name */
|
||||
possibly_non_local = FALSE; /* we know it is local now */
|
||||
}
|
||||
|
||||
/* resolv ip/host to ip */
|
||||
@@ -849,14 +886,15 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
else
|
||||
res = NULL; /* failure! */
|
||||
|
||||
if(addr)
|
||||
free(addr);
|
||||
|
||||
if(res == NULL) {
|
||||
failf(data, "Curl_resolv failed, we can not recover!");
|
||||
failf(data, "failed to resolve the address provided to PORT: %s", host);
|
||||
Curl_safefree(addr);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
Curl_safefree(addr);
|
||||
host = NULL;
|
||||
|
||||
/* step 2, create a socket for the requested address */
|
||||
|
||||
portsock = CURL_SOCKET_BAD;
|
||||
@@ -896,12 +934,12 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
if(bind(portsock, sa, sslen) ) {
|
||||
/* It failed. */
|
||||
error = SOCKERRNO;
|
||||
if(error == EADDRNOTAVAIL) {
|
||||
|
||||
if(possibly_non_local && (error == EADDRNOTAVAIL)) {
|
||||
/* The requested bind address is not local. Use the address used for
|
||||
* the control connection instead and restart the port loop
|
||||
*/
|
||||
failf(data, "bind(port=%hu) failed: %s", port,
|
||||
|
||||
infof(data, "bind(port=%hu) on non-local address failed: %s", port,
|
||||
Curl_strerror(conn, error) );
|
||||
|
||||
sslen = sizeof(ss);
|
||||
@@ -912,6 +950,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
port = port_min;
|
||||
possibly_non_local = FALSE; /* don't try this again */
|
||||
continue;
|
||||
}
|
||||
else if(error != EADDRINUSE && error != EACCES) {
|
||||
@@ -1001,6 +1040,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
sa->sa_family == AF_INET?1:2,
|
||||
myhost, port);
|
||||
if(result) {
|
||||
failf(data, "Failure sending EPRT command: %s",
|
||||
curl_easy_strerror(result));
|
||||
Curl_closesocket(conn, portsock);
|
||||
/* don't retry using PORT */
|
||||
ftpc->count1 = PORT;
|
||||
@@ -1028,6 +1069,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
|
||||
result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp);
|
||||
if(result) {
|
||||
failf(data, "Failure sending PORT command: %s",
|
||||
curl_easy_strerror(result));
|
||||
Curl_closesocket(conn, portsock);
|
||||
/* bail out */
|
||||
state(conn, FTP_STOP);
|
||||
@@ -2453,7 +2496,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(data->set.ftp_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
/* We don't have a SSL/TLS connection yet, but FTPS is
|
||||
requested. Try a FTPS connection now */
|
||||
|
||||
@@ -2509,7 +2552,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
/* remain in this same state */
|
||||
}
|
||||
else {
|
||||
if(data->set.ftp_ssl > CURLUSESSL_TRY)
|
||||
if(data->set.use_ssl > CURLUSESSL_TRY)
|
||||
/* we failed and CURLUSESSL_CONTROL or CURLUSESSL_ALL is set */
|
||||
result = CURLE_USE_SSL_FAILED;
|
||||
else
|
||||
@@ -2532,7 +2575,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
|
||||
case FTP_PBSZ:
|
||||
PPSENDF(&ftpc->pp, "PROT %c",
|
||||
data->set.ftp_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
|
||||
data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
|
||||
state(conn, FTP_PROT);
|
||||
|
||||
break;
|
||||
@@ -2541,10 +2584,10 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
if(ftpcode/100 == 2)
|
||||
/* We have enabled SSL for the data connection! */
|
||||
conn->ssl[SECONDARYSOCKET].use =
|
||||
(data->set.ftp_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
|
||||
(data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
|
||||
/* FTP servers typically responds with 500 if they decide to reject
|
||||
our 'P' request */
|
||||
else if(data->set.ftp_ssl > CURLUSESSL_CONTROL)
|
||||
else if(data->set.use_ssl > CURLUSESSL_CONTROL)
|
||||
/* we failed and bails out */
|
||||
return CURLE_USE_SSL_FAILED;
|
||||
|
||||
@@ -3025,7 +3068,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
struct pingpong *pp = &ftpc->pp;
|
||||
ssize_t nread;
|
||||
int ftpcode;
|
||||
CURLcode result=CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
bool was_ctl_valid = ftpc->ctl_valid;
|
||||
char *path;
|
||||
const char *path_to_use = data->state.path;
|
||||
@@ -3083,8 +3126,12 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
path = curl_easy_unescape(data, path_to_use, 0, NULL);
|
||||
if(!path) {
|
||||
/* out of memory, but we can limp along anyway (and should try to
|
||||
* since we're in the out of memory cleanup path) */
|
||||
ftpc->prevpath = NULL; /* no path */
|
||||
* since we may already be in the out of memory cleanup path) */
|
||||
if(!result)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
ftpc->ctl_valid = FALSE; /* mark control connection as bad */
|
||||
conn->bits.close = TRUE; /* mark for connection closure */
|
||||
ftpc->prevpath = NULL; /* no path remembering */
|
||||
}
|
||||
else {
|
||||
size_t flen = ftpc->file?strlen(ftpc->file):0; /* file is "raw" already */
|
||||
@@ -3122,6 +3169,12 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
if(!result && ftpc->dont_check && data->req.maxdownload > 0)
|
||||
/* partial download completed */
|
||||
result = Curl_pp_sendf(pp, "ABOR");
|
||||
if(result) {
|
||||
failf(data, "Failure sending ABOR command: %s",
|
||||
curl_easy_strerror(result));
|
||||
ftpc->ctl_valid = FALSE; /* mark control connection as bad */
|
||||
conn->bits.close = TRUE; /* mark for connection closure */
|
||||
}
|
||||
|
||||
if(conn->ssl[SECONDARYSOCKET].use) {
|
||||
/* The secondary socket is using SSL so we must close down that part
|
||||
@@ -3134,6 +3187,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
|
||||
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||
conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3663,8 +3717,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
||||
strcat(tmp_path, finfo->filename);
|
||||
/* switch default "state.pathbuffer" and tmp_path, good to see
|
||||
ftp_parse_url_path function to understand this trick */
|
||||
if(conn->data->state.pathbuffer)
|
||||
free(conn->data->state.pathbuffer);
|
||||
Curl_safefree(conn->data->state.pathbuffer);
|
||||
conn->data->state.pathbuffer = tmp_path;
|
||||
conn->data->state.path = tmp_path;
|
||||
|
||||
@@ -3853,7 +3906,16 @@ static CURLcode ftp_quit(struct connectdata *conn)
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(conn->proto.ftpc.ctl_valid) {
|
||||
PPSENDF(&conn->proto.ftpc.pp, "QUIT", NULL);
|
||||
result = Curl_pp_sendf(&conn->proto.ftpc.pp, "QUIT", NULL);
|
||||
if(result) {
|
||||
failf(conn->data, "Failure sending QUIT command: %s",
|
||||
curl_easy_strerror(result));
|
||||
conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
|
||||
conn->bits.close = TRUE; /* mark for connection closure */
|
||||
state(conn, FTP_STOP);
|
||||
return result;
|
||||
}
|
||||
|
||||
state(conn, FTP_QUIT);
|
||||
|
||||
result = ftp_easy_statemach(conn);
|
||||
|
@@ -97,6 +97,7 @@ const struct Curl_handler Curl_handler_gopher = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
|
24
lib/gtls.c
24
lib/gtls.c
@@ -78,6 +78,18 @@ static void tls_log_func(int level, const char *str)
|
||||
#endif
|
||||
static bool gtls_inited = FALSE;
|
||||
|
||||
#if defined(GNUTLS_VERSION_NUMBER)
|
||||
# if (GNUTLS_VERSION_NUMBER >= 0x020c00)
|
||||
# undef gnutls_transport_set_lowat
|
||||
# define gnutls_transport_set_lowat(A,B) Curl_nop_stmt
|
||||
# define USE_GNUTLS_PRIORITY_SET_DIRECT 1
|
||||
# endif
|
||||
# if (GNUTLS_VERSION_NUMBER >= 0x020c03)
|
||||
# undef gnutls_transport_set_global_errno
|
||||
# define gnutls_transport_set_global_errno(A) SET_ERRNO((A))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Custom push and pull callback functions used by GNU TLS to read and write
|
||||
* to the socket. These functions are simple wrappers to send() and recv()
|
||||
@@ -309,7 +321,9 @@ static CURLcode
|
||||
gtls_connect_step1(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
|
||||
static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
|
||||
#endif
|
||||
struct SessionHandle *data = conn->data;
|
||||
gnutls_session session;
|
||||
int rc;
|
||||
@@ -429,18 +443,26 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) {
|
||||
#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
|
||||
static const int protocol_priority[] = { GNUTLS_SSL3, 0 };
|
||||
gnutls_protocol_set_priority(session, protocol_priority);
|
||||
rc = gnutls_protocol_set_priority(session, protocol_priority);
|
||||
#else
|
||||
const char *err;
|
||||
rc = gnutls_priority_set_direct(session, "-VERS-TLS-ALL:+VERS-SSL3.0",
|
||||
&err);
|
||||
#endif
|
||||
if(rc != GNUTLS_E_SUCCESS)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
|
||||
/* Sets the priority on the certificate types supported by gnutls. Priority
|
||||
is higher for types specified before others. After specifying the types
|
||||
you want, you must append a 0. */
|
||||
rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
|
||||
if(rc != GNUTLS_E_SUCCESS)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
#endif
|
||||
|
||||
if(data->set.str[STRING_CERT]) {
|
||||
if(gnutls_certificate_set_x509_key_file(
|
||||
|
23
lib/hash.c
23
lib/hash.c
@@ -38,11 +38,14 @@ hash_element_dtor(void *user, void *element)
|
||||
struct curl_hash *h = (struct curl_hash *) user;
|
||||
struct curl_hash_element *e = (struct curl_hash_element *) element;
|
||||
|
||||
if(e->key)
|
||||
free(e->key);
|
||||
Curl_safefree(e->key);
|
||||
|
||||
if(e->ptr)
|
||||
if(e->ptr) {
|
||||
h->dtor(e->ptr);
|
||||
e->ptr = NULL;
|
||||
}
|
||||
|
||||
e->key_len = 0;
|
||||
|
||||
free(e);
|
||||
}
|
||||
@@ -72,16 +75,22 @@ Curl_hash_init(struct curl_hash *h,
|
||||
for(i = 0; i < slots; ++i) {
|
||||
h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
|
||||
if(!h->table[i]) {
|
||||
while(i--)
|
||||
while(i--) {
|
||||
Curl_llist_destroy(h->table[i], NULL);
|
||||
h->table[i] = NULL;
|
||||
}
|
||||
free(h->table);
|
||||
h->table = NULL;
|
||||
h->slots = 0;
|
||||
return 1; /* failure */
|
||||
}
|
||||
}
|
||||
return 0; /* fine */
|
||||
}
|
||||
else
|
||||
else {
|
||||
h->slots = 0;
|
||||
return 1; /* failure */
|
||||
}
|
||||
}
|
||||
|
||||
struct curl_hash *
|
||||
@@ -187,6 +196,7 @@ int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
|
||||
he = le->ptr;
|
||||
if(h->comp_func(he->key, he->key_len, key, key_len)) {
|
||||
Curl_llist_remove(l, le, (void *) h);
|
||||
--h->size;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -240,6 +250,9 @@ Curl_hash_clean(struct curl_hash *h)
|
||||
}
|
||||
|
||||
free(h->table);
|
||||
h->table = NULL;
|
||||
h->size = 0;
|
||||
h->slots = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
360
lib/http.c
360
lib/http.c
@@ -118,6 +118,7 @@ const struct Curl_handler Curl_handler_http = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
http_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -141,6 +142,7 @@ const struct Curl_handler Curl_handler_https = {
|
||||
ZERO_NULL, /* doing */
|
||||
https_getsock, /* proto_getsock */
|
||||
http_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -546,7 +548,7 @@ output_auth_headers(struct connectdata *conn,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef NTLM_WB_ENABLED
|
||||
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
|
||||
if(authstatus->picked == CURLAUTH_NTLM_WB) {
|
||||
auth="NTLM_WB";
|
||||
result = Curl_output_ntlm_wb(conn, proxy);
|
||||
@@ -731,95 +733,74 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||
*
|
||||
*/
|
||||
|
||||
while(*start) {
|
||||
#ifdef USE_HTTP_NEGOTIATE
|
||||
if(checkprefix("GSS-Negotiate", start) ||
|
||||
checkprefix("Negotiate", start)) {
|
||||
int neg;
|
||||
*availp |= CURLAUTH_GSSNEGOTIATE;
|
||||
authp->avail |= CURLAUTH_GSSNEGOTIATE;
|
||||
if(checkprefix("GSS-Negotiate", start) ||
|
||||
checkprefix("Negotiate", start)) {
|
||||
int neg;
|
||||
*availp |= CURLAUTH_GSSNEGOTIATE;
|
||||
authp->avail |= CURLAUTH_GSSNEGOTIATE;
|
||||
|
||||
if(data->state.negotiate.state == GSS_AUTHSENT) {
|
||||
/* if we sent GSS authentication in the outgoing request and we get this
|
||||
back, we're in trouble */
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
else {
|
||||
neg = Curl_input_negotiate(conn, (httpcode == 407)?TRUE:FALSE, start);
|
||||
if(neg == 0) {
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
data->req.newurl = strdup(data->change.url);
|
||||
if(!data->req.newurl)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
data->state.authproblem = FALSE;
|
||||
/* we received GSS auth info and we dealt with it fine */
|
||||
data->state.negotiate.state = GSS_AUTHRECV;
|
||||
}
|
||||
else {
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_NTLM
|
||||
/* NTLM support requires the SSL crypto libs */
|
||||
if(checkprefix("NTLM", start)) {
|
||||
*availp |= CURLAUTH_NTLM;
|
||||
authp->avail |= CURLAUTH_NTLM;
|
||||
if(authp->picked == CURLAUTH_NTLM ||
|
||||
authp->picked == CURLAUTH_NTLM_WB) {
|
||||
/* NTLM authentication is picked and activated */
|
||||
CURLcode ntlm =
|
||||
Curl_input_ntlm(conn, (httpcode == 407)?TRUE:FALSE, start);
|
||||
if(CURLE_OK == ntlm) {
|
||||
data->state.authproblem = FALSE;
|
||||
#ifdef NTLM_WB_ENABLED
|
||||
if(authp->picked == CURLAUTH_NTLM_WB) {
|
||||
*availp &= ~CURLAUTH_NTLM;
|
||||
authp->avail &= ~CURLAUTH_NTLM;
|
||||
*availp |= CURLAUTH_NTLM_WB;
|
||||
authp->avail |= CURLAUTH_NTLM_WB;
|
||||
|
||||
/* Get the challenge-message which will be passed to
|
||||
* ntlm_auth for generating the type 3 message later */
|
||||
while(*start && ISSPACE(*start))
|
||||
start++;
|
||||
if(checkprefix("NTLM", start)) {
|
||||
start += strlen("NTLM");
|
||||
while(*start && ISSPACE(*start))
|
||||
start++;
|
||||
if(*start)
|
||||
if((conn->challenge_header = strdup(start)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if(authp->picked == CURLAUTH_GSSNEGOTIATE) {
|
||||
if(data->state.negotiate.state == GSS_AUTHSENT) {
|
||||
/* if we sent GSS authentication in the outgoing request and we get
|
||||
this back, we're in trouble */
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
else {
|
||||
neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
|
||||
if(neg == 0) {
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
data->req.newurl = strdup(data->change.url);
|
||||
if(!data->req.newurl)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
data->state.authproblem = FALSE;
|
||||
/* we received GSS auth info and we dealt with it fine */
|
||||
data->state.negotiate.state = GSS_AUTHRECV;
|
||||
}
|
||||
else
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if(checkprefix("Digest", start)) {
|
||||
if((authp->avail & CURLAUTH_DIGEST) != 0) {
|
||||
infof(data, "Ignoring duplicate digest auth header.\n");
|
||||
}
|
||||
else {
|
||||
CURLdigest dig;
|
||||
*availp |= CURLAUTH_DIGEST;
|
||||
authp->avail |= CURLAUTH_DIGEST;
|
||||
#ifdef USE_NTLM
|
||||
/* NTLM support requires the SSL crypto libs */
|
||||
if(checkprefix("NTLM", start)) {
|
||||
*availp |= CURLAUTH_NTLM;
|
||||
authp->avail |= CURLAUTH_NTLM;
|
||||
if(authp->picked == CURLAUTH_NTLM ||
|
||||
authp->picked == CURLAUTH_NTLM_WB) {
|
||||
/* NTLM authentication is picked and activated */
|
||||
CURLcode ntlm =
|
||||
Curl_input_ntlm(conn, (httpcode == 407)?TRUE:FALSE, start);
|
||||
if(CURLE_OK == ntlm) {
|
||||
data->state.authproblem = FALSE;
|
||||
#ifdef NTLM_WB_ENABLED
|
||||
if(authp->picked == CURLAUTH_NTLM_WB) {
|
||||
*availp &= ~CURLAUTH_NTLM;
|
||||
authp->avail &= ~CURLAUTH_NTLM;
|
||||
*availp |= CURLAUTH_NTLM_WB;
|
||||
authp->avail |= CURLAUTH_NTLM_WB;
|
||||
|
||||
/* We call this function on input Digest headers even if Digest
|
||||
* authentication isn't activated yet, as we need to store the
|
||||
* incoming data from this header in case we are gonna use Digest. */
|
||||
dig = Curl_input_digest(conn, (httpcode == 407)?TRUE:FALSE, start);
|
||||
|
||||
if(CURLDIGEST_FINE != dig) {
|
||||
/* Get the challenge-message which will be passed to
|
||||
* ntlm_auth for generating the type 3 message later */
|
||||
while(*start && ISSPACE(*start))
|
||||
start++;
|
||||
if(checkprefix("NTLM", start)) {
|
||||
start += strlen("NTLM");
|
||||
while(*start && ISSPACE(*start))
|
||||
start++;
|
||||
if(*start)
|
||||
if((conn->challenge_header = strdup(start)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
@@ -827,19 +808,51 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if(checkprefix("Basic", start)) {
|
||||
*availp |= CURLAUTH_BASIC;
|
||||
authp->avail |= CURLAUTH_BASIC;
|
||||
if(authp->picked == CURLAUTH_BASIC) {
|
||||
/* We asked for Basic authentication but got a 40X back
|
||||
anyway, which basically means our name+password isn't
|
||||
valid. */
|
||||
authp->avail = CURLAUTH_NONE;
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if(checkprefix("Digest", start)) {
|
||||
if((authp->avail & CURLAUTH_DIGEST) != 0) {
|
||||
infof(data, "Ignoring duplicate digest auth header.\n");
|
||||
}
|
||||
else {
|
||||
CURLdigest dig;
|
||||
*availp |= CURLAUTH_DIGEST;
|
||||
authp->avail |= CURLAUTH_DIGEST;
|
||||
|
||||
/* We call this function on input Digest headers even if Digest
|
||||
* authentication isn't activated yet, as we need to store the
|
||||
* incoming data from this header in case we are gonna use
|
||||
* Digest. */
|
||||
dig = Curl_input_digest(conn, (httpcode == 407)?TRUE:FALSE, start);
|
||||
|
||||
if(CURLDIGEST_FINE != dig) {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if(checkprefix("Basic", start)) {
|
||||
*availp |= CURLAUTH_BASIC;
|
||||
authp->avail |= CURLAUTH_BASIC;
|
||||
if(authp->picked == CURLAUTH_BASIC) {
|
||||
/* We asked for Basic authentication but got a 40X back
|
||||
anyway, which basically means our name+password isn't
|
||||
valid. */
|
||||
authp->avail = CURLAUTH_NONE;
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* there may be multiple methods on one line, so keep reading */
|
||||
while(*start && *start != ',') /* read up to the next comma */
|
||||
start++;
|
||||
if(*start == ',') /* if we're on a comma, skip it */
|
||||
start++;
|
||||
while(*start && ISSPACE(*start))
|
||||
start++;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -1559,6 +1572,31 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ptr = strchr(headers->data, ';');
|
||||
if(ptr) {
|
||||
|
||||
ptr++; /* pass the semicolon */
|
||||
while(*ptr && ISSPACE(*ptr))
|
||||
ptr++;
|
||||
|
||||
if(*ptr) {
|
||||
/* this may be used for something else in the future */
|
||||
}
|
||||
else {
|
||||
if(*(--ptr) == ';') {
|
||||
CURLcode result;
|
||||
|
||||
/* send no-value custom header if terminated by semicolon */
|
||||
*ptr = ':';
|
||||
result = Curl_add_bufferf(req_buffer, "%s\r\n",
|
||||
headers->data);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
headers = headers->next;
|
||||
}
|
||||
return CURLE_OK;
|
||||
@@ -1778,8 +1816,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
else {
|
||||
if((conn->handler->protocol&CURLPROTO_HTTP) &&
|
||||
data->set.upload &&
|
||||
(data->set.infilesize == -1)) {
|
||||
data->set.upload &&
|
||||
(data->set.infilesize == -1)) {
|
||||
if(conn->bits.authneg)
|
||||
/* don't enable chunked during auth neg */
|
||||
;
|
||||
@@ -1887,8 +1925,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
memcpy(newurl + newlen + (ptr - url),
|
||||
ptr + currlen, /* copy the trailing zero byte too */
|
||||
urllen - (ptr-url) - currlen + 1);
|
||||
if(data->change.url_alloc)
|
||||
free(data->change.url);
|
||||
if(data->change.url_alloc) {
|
||||
Curl_safefree(data->change.url);
|
||||
data->change.url_alloc = FALSE;
|
||||
}
|
||||
data->change.url = newurl;
|
||||
data->change.url_alloc = TRUE;
|
||||
}
|
||||
@@ -1957,7 +1997,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
* This is meant to get the size of the present remote-file by itself.
|
||||
* We don't support this now. Bail out!
|
||||
*/
|
||||
data->state.resume_from = 0;
|
||||
data->state.resume_from = 0;
|
||||
}
|
||||
|
||||
if(data->state.resume_from && !data->state.this_is_a_follow) {
|
||||
@@ -2048,17 +2088,17 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
curl_off_t total_expected_size=
|
||||
data->state.resume_from + data->set.infilesize;
|
||||
conn->allocptr.rangeline =
|
||||
aprintf("Content-Range: bytes %s%" FORMAT_OFF_T
|
||||
"/%" FORMAT_OFF_T "\r\n",
|
||||
data->state.range, total_expected_size-1,
|
||||
total_expected_size);
|
||||
aprintf("Content-Range: bytes %s%" FORMAT_OFF_T
|
||||
"/%" FORMAT_OFF_T "\r\n",
|
||||
data->state.range, total_expected_size-1,
|
||||
total_expected_size);
|
||||
}
|
||||
else {
|
||||
/* Range was selected and then we just pass the incoming range and
|
||||
append total size */
|
||||
conn->allocptr.rangeline =
|
||||
aprintf("Content-Range: bytes %s/%" FORMAT_OFF_T "\r\n",
|
||||
data->state.range, data->set.infilesize);
|
||||
aprintf("Content-Range: bytes %s/%" FORMAT_OFF_T "\r\n",
|
||||
data->state.range, data->set.infilesize);
|
||||
}
|
||||
if(!conn->allocptr.rangeline)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@@ -2091,45 +2131,47 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"%s" /* ftp typecode (;type=x) */
|
||||
" HTTP/%s\r\n" /* HTTP version */
|
||||
"%s" /* proxyuserpwd */
|
||||
"%s" /* userpwd */
|
||||
"%s" /* range */
|
||||
"%s" /* user agent */
|
||||
"%s" /* host */
|
||||
"%s" /* accept */
|
||||
"%s" /* TE: */
|
||||
"%s" /* accept-encoding */
|
||||
"%s" /* referer */
|
||||
"%s" /* Proxy-Connection */
|
||||
"%s",/* transfer-encoding */
|
||||
result =
|
||||
Curl_add_bufferf(req_buffer,
|
||||
"%s" /* ftp typecode (;type=x) */
|
||||
" HTTP/%s\r\n" /* HTTP version */
|
||||
"%s" /* proxyuserpwd */
|
||||
"%s" /* userpwd */
|
||||
"%s" /* range */
|
||||
"%s" /* user agent */
|
||||
"%s" /* host */
|
||||
"%s" /* accept */
|
||||
"%s" /* TE: */
|
||||
"%s" /* accept-encoding */
|
||||
"%s" /* referer */
|
||||
"%s" /* Proxy-Connection */
|
||||
"%s",/* transfer-encoding */
|
||||
|
||||
ftp_typecode,
|
||||
httpstring,
|
||||
conn->allocptr.proxyuserpwd?
|
||||
conn->allocptr.proxyuserpwd:"",
|
||||
conn->allocptr.userpwd?conn->allocptr.userpwd:"",
|
||||
(data->state.use_range && conn->allocptr.rangeline)?
|
||||
conn->allocptr.rangeline:"",
|
||||
(data->set.str[STRING_USERAGENT] &&
|
||||
*data->set.str[STRING_USERAGENT] && conn->allocptr.uagent)?
|
||||
conn->allocptr.uagent:"",
|
||||
(conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
|
||||
http->p_accept?http->p_accept:"",
|
||||
conn->allocptr.te?conn->allocptr.te:"",
|
||||
(data->set.str[STRING_ENCODING] &&
|
||||
*data->set.str[STRING_ENCODING] &&
|
||||
conn->allocptr.accept_encoding)?
|
||||
conn->allocptr.accept_encoding:"",
|
||||
(data->change.referer && conn->allocptr.ref)?
|
||||
conn->allocptr.ref:"" /* Referer: <data> */,
|
||||
(conn->bits.httpproxy &&
|
||||
!conn->bits.tunnel_proxy &&
|
||||
!Curl_checkheaders(data, "Proxy-Connection:"))?
|
||||
"Proxy-Connection: Keep-Alive\r\n":"",
|
||||
te
|
||||
ftp_typecode,
|
||||
httpstring,
|
||||
conn->allocptr.proxyuserpwd?
|
||||
conn->allocptr.proxyuserpwd:"",
|
||||
conn->allocptr.userpwd?conn->allocptr.userpwd:"",
|
||||
(data->state.use_range && conn->allocptr.rangeline)?
|
||||
conn->allocptr.rangeline:"",
|
||||
(data->set.str[STRING_USERAGENT] &&
|
||||
*data->set.str[STRING_USERAGENT] &&
|
||||
conn->allocptr.uagent)?
|
||||
conn->allocptr.uagent:"",
|
||||
(conn->allocptr.host?conn->allocptr.host:""),
|
||||
http->p_accept?http->p_accept:"",
|
||||
conn->allocptr.te?conn->allocptr.te:"",
|
||||
(data->set.str[STRING_ENCODING] &&
|
||||
*data->set.str[STRING_ENCODING] &&
|
||||
conn->allocptr.accept_encoding)?
|
||||
conn->allocptr.accept_encoding:"",
|
||||
(data->change.referer && conn->allocptr.ref)?
|
||||
conn->allocptr.ref:"" /* Referer: <data> */,
|
||||
(conn->bits.httpproxy &&
|
||||
!conn->bits.tunnel_proxy &&
|
||||
!Curl_checkheaders(data, "Proxy-Connection:"))?
|
||||
"Proxy-Connection: Keep-Alive\r\n":"",
|
||||
te
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -2169,8 +2211,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
break;
|
||||
}
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"%s%s=%s", count?"; ":"",
|
||||
co->name, co->value);
|
||||
"%s%s=%s", count?"; ":"",
|
||||
co->name, co->value);
|
||||
if(result)
|
||||
break;
|
||||
count++;
|
||||
@@ -2184,8 +2226,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
result = Curl_add_bufferf(req_buffer, "Cookie: ");
|
||||
if(CURLE_OK == result) {
|
||||
result = Curl_add_bufferf(req_buffer, "%s%s",
|
||||
count?"; ":"",
|
||||
addcookies);
|
||||
count?"; ":"",
|
||||
addcookies);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -2252,11 +2294,12 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
|
||||
http->sending = HTTPSEND_BODY;
|
||||
|
||||
if(!data->req.upload_chunky) {
|
||||
if(!data->req.upload_chunky &&
|
||||
!Curl_checkheaders(data, "Content-Length:")) {
|
||||
/* only add Content-Length if not uploading chunked */
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Length: %" FORMAT_OFF_T "\r\n",
|
||||
http->postsize);
|
||||
"Content-Length: %" FORMAT_OFF_T "\r\n",
|
||||
http->postsize);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@@ -2323,11 +2366,12 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
else
|
||||
postsize = data->set.infilesize;
|
||||
|
||||
if((postsize != -1) && !data->req.upload_chunky) {
|
||||
if((postsize != -1) && !data->req.upload_chunky &&
|
||||
!Curl_checkheaders(data, "Content-Length:")) {
|
||||
/* only add Content-Length if not uploading chunked */
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Length: %" FORMAT_OFF_T "\r\n",
|
||||
postsize );
|
||||
"Content-Length: %" FORMAT_OFF_T "\r\n",
|
||||
postsize );
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@@ -2377,8 +2421,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
/* we allow replacing this header if not during auth negotiation,
|
||||
although it isn't very wise to actually set your own */
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Length: %" FORMAT_OFF_T"\r\n",
|
||||
postsize);
|
||||
"Content-Length: %" FORMAT_OFF_T"\r\n",
|
||||
postsize);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@@ -2428,7 +2472,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
/* We're not sending it 'chunked', append it to the request
|
||||
already now to reduce the number if send() calls */
|
||||
result = Curl_add_buffer(req_buffer, data->set.postfields,
|
||||
(size_t)postsize);
|
||||
(size_t)postsize);
|
||||
included_body = postsize;
|
||||
}
|
||||
else {
|
||||
@@ -2436,10 +2480,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
|
||||
if(CURLE_OK == result)
|
||||
result = Curl_add_buffer(req_buffer, data->set.postfields,
|
||||
(size_t)postsize);
|
||||
(size_t)postsize);
|
||||
if(CURLE_OK == result)
|
||||
result = Curl_add_buffer(req_buffer,
|
||||
"\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
|
||||
"\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
|
||||
/* CR LF 0 CR LF CR LF */
|
||||
included_body = postsize + 7;
|
||||
}
|
||||
@@ -2475,7 +2519,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
/* Chunky upload is selected and we're negotiating auth still, send
|
||||
end-of-data only */
|
||||
result = Curl_add_buffer(req_buffer,
|
||||
"\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
|
||||
"\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
|
||||
/* CR LF 0 CR LF CR LF */
|
||||
if(result)
|
||||
return result;
|
||||
@@ -2536,7 +2580,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(http->writebytecount >= postsize) {
|
||||
/* already sent the entire request body, mark the "upload" as
|
||||
complete */
|
||||
infof(data, "upload completely sent off: %" FORMAT_OFF_T "out of "
|
||||
infof(data, "upload completely sent off: %" FORMAT_OFF_T " out of "
|
||||
"%" FORMAT_OFF_T " bytes\n",
|
||||
http->writebytecount, postsize);
|
||||
data->req.upload_done = TRUE;
|
||||
|
@@ -119,6 +119,7 @@ const struct Curl_handler Curl_handler_imap = {
|
||||
imap_doing, /* doing */
|
||||
imap_getsock, /* proto_getsock */
|
||||
imap_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
imap_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -144,6 +145,7 @@ const struct Curl_handler Curl_handler_imaps = {
|
||||
imap_doing, /* doing */
|
||||
imap_getsock, /* proto_getsock */
|
||||
imap_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
imap_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -169,6 +171,7 @@ static const struct Curl_handler Curl_handler_imap_proxy = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -194,6 +197,7 @@ static const struct Curl_handler Curl_handler_imaps_proxy = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -576,7 +580,7 @@ static CURLcode imap_statemach_act(struct connectdata *conn)
|
||||
return CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
if(data->set.ftp_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
/* We don't have a SSL/TLS connection yet, but SSL is requested. Switch
|
||||
to TLS connection now */
|
||||
const char *str;
|
||||
|
@@ -130,6 +130,7 @@ const struct Curl_handler Curl_handler_ldap = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -154,6 +155,7 @@ const struct Curl_handler Curl_handler_ldaps = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
|
@@ -9,6 +9,8 @@
|
||||
curl_easy_init,
|
||||
curl_easy_pause,
|
||||
curl_easy_perform,
|
||||
curl_easy_recv,
|
||||
curl_easy_send,
|
||||
curl_easy_setopt,
|
||||
curl_escape,
|
||||
curl_unescape,
|
||||
@@ -38,6 +40,8 @@
|
||||
curl_multi_perform,
|
||||
curl_multi_cleanup,
|
||||
curl_multi_info_read,
|
||||
curl_multi_setopt,
|
||||
curl_multi_timeout,
|
||||
curl_free,
|
||||
curl_version_info,
|
||||
curl_share_init,
|
||||
|
@@ -46,7 +46,7 @@ Curl_llist_alloc(curl_llist_dtor dtor)
|
||||
struct curl_llist *list;
|
||||
|
||||
list = malloc(sizeof(struct curl_llist));
|
||||
if(NULL == list)
|
||||
if(!list)
|
||||
return NULL;
|
||||
|
||||
llist_init(list, dtor);
|
||||
@@ -131,6 +131,10 @@ Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
|
||||
|
||||
list->dtor(user, e->ptr);
|
||||
|
||||
e->ptr = NULL;
|
||||
e->prev = NULL;
|
||||
e->next = NULL;
|
||||
|
||||
free(e);
|
||||
--list->size;
|
||||
|
||||
|
@@ -152,8 +152,10 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
|
||||
/*
|
||||
* Curl_safefree defined as a macro to allow MemoryTracking feature
|
||||
* to log free() calls at same location where Curl_safefree is used.
|
||||
* This macro also assigns NULL to given pointer when free'd.
|
||||
*/
|
||||
|
||||
#define Curl_safefree(ptr) do {if((ptr)) free((ptr));} WHILE_FALSE
|
||||
#define Curl_safefree(ptr) \
|
||||
do {if((ptr)) {free((ptr)); (ptr) = NULL;}} WHILE_FALSE
|
||||
|
||||
#endif /* HEADER_CURL_MEMDEBUG_H */
|
||||
|
@@ -160,7 +160,8 @@ while (<TXT>) {
|
||||
}
|
||||
while (<TXT>) {
|
||||
last if (/^#$/);
|
||||
$untrusted = 1 if (/^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_NOT_TRUSTED$/);
|
||||
$untrusted = 1 if (/^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_NOT_TRUSTED$/
|
||||
or /^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_TRUST_UNKNOWN$/);
|
||||
}
|
||||
if ($untrusted) {
|
||||
$skipnum ++;
|
||||
|
@@ -26,7 +26,7 @@
|
||||
'* Hacked by Guenter Knauf
|
||||
'***************************************************************************
|
||||
Option Explicit
|
||||
Const myVersion = "0.3.5"
|
||||
Const myVersion = "0.3.6"
|
||||
|
||||
Const myUrl = "http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1"
|
||||
|
||||
@@ -96,8 +96,10 @@ If (myAskTiF = TRUE) Then
|
||||
End If
|
||||
End If
|
||||
' Process the received data
|
||||
Dim myLines, myPattern, myInsideCert, myInsideLicense, myLicenseText, myNumCerts
|
||||
Dim myLabel, myOctets, myData, myPem, myRev, j
|
||||
Dim myLines, myPattern, myInsideCert, myInsideLicense, myLicenseText, myNumCerts, myNumSkipped
|
||||
Dim myLabel, myOctets, myData, myPem, myRev, myUntrusted, j
|
||||
myNumSkipped = 0
|
||||
myNumCerts = 0
|
||||
myData = ""
|
||||
myLines = Split(myCdData, vbLf, -1)
|
||||
Set myFh = objFSO.OpenTextFile(myCaFile, 2, TRUE)
|
||||
@@ -109,7 +111,7 @@ myFh.Write "##" & vbLf
|
||||
myFh.Write "## This is a bundle of X.509 certificates of public Certificate Authorities" & vbLf
|
||||
myFh.Write "## (CA). These were automatically extracted from Mozilla's root certificates" & vbLf
|
||||
myFh.Write "## file (certdata.txt). This file can be found in the mozilla source tree:" & vbLf
|
||||
myFh.Write "## '/mozilla/security/nss/lib/ckfw/builtins/certdata.txt'" & vbLf
|
||||
myFh.Write "## '/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt'" & vbLf
|
||||
myFh.Write "##" & vbLf
|
||||
myFh.Write "## It contains the certificates in PEM format and therefore" & vbLf
|
||||
myFh.Write "## can be directly used with curl / libcurl / php_curl, or with" & vbLf
|
||||
@@ -125,36 +127,46 @@ For i = 0 To UBound(myLines)
|
||||
If (myInsideCert = TRUE) Then
|
||||
If InstrRev(myLines(i), "END") Then
|
||||
myInsideCert = FALSE
|
||||
myFh.Write myLabel & vbLf
|
||||
myFh.Write String(Len(myLabel), "=") & vbLf
|
||||
myPem = "-----BEGIN CERTIFICATE-----" & vbLf & _
|
||||
Base64Encode(myData) & vbLf & _
|
||||
"-----END CERTIFICATE-----" & vbLf
|
||||
If (myOptTxt = FALSE) Then
|
||||
myFh.Write myPem & vbLf
|
||||
Else
|
||||
Dim myCmd, myRval, myTmpIn, myTmpOut
|
||||
myTmpIn = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName
|
||||
myTmpOut = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName
|
||||
Set myTmpFh = objFSO.OpenTextFile(myTmpIn, 2, TRUE)
|
||||
myTmpFh.Write myPem
|
||||
myTmpFh.Close
|
||||
myCmd = myOpenssl & " x509 -md5 -fingerprint -text -inform PEM" & _
|
||||
" -in " & myTmpIn & " -out " & myTmpOut
|
||||
myRval = objShell.Run (myCmd, 0, TRUE)
|
||||
objFSO.DeleteFile myTmpIn, TRUE
|
||||
If Not (myRval = 0) Then
|
||||
MsgBox("Failed to process PEM cert with OpenSSL commandline!"), vbCritical, mySelf
|
||||
objFSO.DeleteFile myTmpOut, TRUE
|
||||
WScript.Quit 3
|
||||
While (i < UBound(myLines)) And Not (myLines(i) = "#")
|
||||
i = i + 1
|
||||
If (InstrRev(myLines(i), "CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED") Or _
|
||||
InstrRev(myLines(i), "CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUST_UNKNOWN")) Then
|
||||
myUntrusted = TRUE
|
||||
End If
|
||||
Set myTmpFh = objFSO.OpenTextFile(myTmpOut, 1)
|
||||
myFh.Write myTmpFh.ReadAll & vbLf
|
||||
myTmpFh.Close
|
||||
objFSO.DeleteFile myTmpOut, TRUE
|
||||
Wend
|
||||
If (myUntrusted = TRUE) Then
|
||||
myNumSkipped = myNumSkipped + 1
|
||||
Else
|
||||
myFh.Write myLabel & vbLf
|
||||
myFh.Write String(Len(myLabel), "=") & vbLf
|
||||
myPem = "-----BEGIN CERTIFICATE-----" & vbLf & _
|
||||
Base64Encode(myData) & vbLf & _
|
||||
"-----END CERTIFICATE-----" & vbLf
|
||||
If (myOptTxt = FALSE) Then
|
||||
myFh.Write myPem & vbLf
|
||||
Else
|
||||
Dim myCmd, myRval, myTmpIn, myTmpOut
|
||||
myTmpIn = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName
|
||||
myTmpOut = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName
|
||||
Set myTmpFh = objFSO.OpenTextFile(myTmpIn, 2, TRUE)
|
||||
myTmpFh.Write myPem
|
||||
myTmpFh.Close
|
||||
myCmd = myOpenssl & " x509 -md5 -fingerprint -text -inform PEM" & _
|
||||
" -in " & myTmpIn & " -out " & myTmpOut
|
||||
myRval = objShell.Run (myCmd, 0, TRUE)
|
||||
objFSO.DeleteFile myTmpIn, TRUE
|
||||
If Not (myRval = 0) Then
|
||||
MsgBox("Failed to process PEM cert with OpenSSL commandline!"), vbCritical, mySelf
|
||||
objFSO.DeleteFile myTmpOut, TRUE
|
||||
WScript.Quit 3
|
||||
End If
|
||||
Set myTmpFh = objFSO.OpenTextFile(myTmpOut, 1)
|
||||
myFh.Write myTmpFh.ReadAll & vbLf
|
||||
myTmpFh.Close
|
||||
objFSO.DeleteFile myTmpOut, TRUE
|
||||
End If
|
||||
myNumCerts = myNumCerts + 1
|
||||
End If
|
||||
myData = ""
|
||||
myNumCerts = myNumCerts + 1
|
||||
Else
|
||||
myOctets = Split(myLines(i), "\")
|
||||
For j = 1 To UBound(myOctets)
|
||||
@@ -169,6 +181,8 @@ For i = 0 To UBound(myLines)
|
||||
End If
|
||||
If InstrRev(myLines(i), "CKA_VALUE MULTILINE_OCTAL") Then
|
||||
myInsideCert = TRUE
|
||||
myUntrusted = FALSE
|
||||
myData = ""
|
||||
End If
|
||||
If InstrRev(myLines(i), "***** BEGIN LICENSE BLOCK *****") Then
|
||||
myInsideLicense = TRUE
|
||||
@@ -191,7 +205,8 @@ For i = 0 To UBound(myLines)
|
||||
End If
|
||||
Next
|
||||
myFh.Close
|
||||
objShell.PopUp "Done (" & myNumCerts & " CA certs processed).", 20, mySelf, vbInformation
|
||||
objShell.PopUp "Done (" & myNumCerts & " CA certs processed, " & myNumSkipped & _
|
||||
" untrusted skipped).", 20, mySelf, vbInformation
|
||||
WScript.Quit 0
|
||||
|
||||
Function ConvertBinaryData(arrBytes)
|
||||
|
237
lib/multi.c
237
lib/multi.c
@@ -41,6 +41,7 @@
|
||||
#include "sendf.h"
|
||||
#include "timeval.h"
|
||||
#include "http.h"
|
||||
#include "select.h"
|
||||
#include "warnless.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
@@ -124,9 +125,9 @@ struct Curl_one_easy {
|
||||
#define CURL_MULTI_HANDLE 0x000bab1e
|
||||
|
||||
#define GOOD_MULTI_HANDLE(x) \
|
||||
((x)&&(((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE))
|
||||
((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE))
|
||||
#define GOOD_EASY_HANDLE(x) \
|
||||
(((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER)
|
||||
((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER))
|
||||
|
||||
/* This is the struct known as CURLM on the outside */
|
||||
struct Curl_multi {
|
||||
@@ -134,7 +135,7 @@ struct Curl_multi {
|
||||
this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */
|
||||
long type;
|
||||
|
||||
/* We have a linked list with easy handles */
|
||||
/* We have a doubly-linked circular list with easy handles */
|
||||
struct Curl_one_easy easy;
|
||||
|
||||
int num_easy; /* amount of entries in the linked list above. */
|
||||
@@ -424,12 +425,13 @@ CURLM *curl_multi_init(void)
|
||||
return (CURLM *) multi;
|
||||
|
||||
error:
|
||||
if(multi->sockhash)
|
||||
Curl_hash_destroy(multi->sockhash);
|
||||
if(multi->hostcache)
|
||||
Curl_hash_destroy(multi->hostcache);
|
||||
if(multi->connc)
|
||||
Curl_rm_connc(multi->connc);
|
||||
|
||||
Curl_hash_destroy(multi->sockhash);
|
||||
multi->sockhash = NULL;
|
||||
Curl_hash_destroy(multi->hostcache);
|
||||
multi->hostcache = NULL;
|
||||
Curl_rm_connc(multi->connc);
|
||||
multi->connc = NULL;
|
||||
|
||||
free(multi);
|
||||
return NULL;
|
||||
@@ -438,11 +440,12 @@ CURLM *curl_multi_init(void)
|
||||
CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
CURL *easy_handle)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct curl_llist *timeoutlist;
|
||||
struct Curl_one_easy *easy;
|
||||
struct closure *cl;
|
||||
struct closure *prev=NULL;
|
||||
struct SessionHandle *data = easy_handle;
|
||||
struct closure *prev = NULL;
|
||||
struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
|
||||
struct SessionHandle *data = (struct SessionHandle *)easy_handle;
|
||||
|
||||
/* First, make some basic checks that the CURLM handle is a good handle */
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
@@ -452,39 +455,77 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
if(!GOOD_EASY_HANDLE(easy_handle))
|
||||
return CURLM_BAD_EASY_HANDLE;
|
||||
|
||||
/* Prevent users to add the same handle more than once! */
|
||||
if(((struct SessionHandle *)easy_handle)->multi)
|
||||
/* Prevent users from adding same easy handle more than
|
||||
once and prevent adding to more than one multi stack */
|
||||
if(data->multi)
|
||||
/* possibly we should create a new unique error code for this condition */
|
||||
return CURLM_BAD_EASY_HANDLE;
|
||||
|
||||
data->state.timeoutlist = Curl_llist_alloc(multi_freetimeout);
|
||||
if(!data->state.timeoutlist)
|
||||
/* We want the connection cache to have plenty of room. Before we supported
|
||||
the shared cache every single easy handle had 5 entries in their cache
|
||||
by default. */
|
||||
if(((multi->num_easy + 1) * 4) > multi->connc->num) {
|
||||
long newmax = (multi->num_easy + 1) * 4;
|
||||
|
||||
if(multi->maxconnects && (newmax > multi->maxconnects))
|
||||
/* don't grow beyond the allowed size */
|
||||
newmax = multi->maxconnects;
|
||||
|
||||
if(newmax > multi->connc->num) {
|
||||
/* we only do this is we can in fact grow the cache */
|
||||
CURLcode res = Curl_ch_connc(data, multi->connc, newmax);
|
||||
if(res)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate and initialize timeout list for easy handle */
|
||||
timeoutlist = Curl_llist_alloc(multi_freetimeout);
|
||||
if(!timeoutlist)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
|
||||
/* Now, time to add an easy handle to the multi stack */
|
||||
/* Allocate new node for the doubly-linked circular list of
|
||||
Curl_one_easy structs that holds pointers to easy handles */
|
||||
easy = calloc(1, sizeof(struct Curl_one_easy));
|
||||
if(!easy)
|
||||
if(!easy) {
|
||||
Curl_llist_destroy(timeoutlist, NULL);
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
** No failure allowed in this function beyond this point. And
|
||||
** no modification of easy nor multi handle allowed before this
|
||||
** except for potential multi's connection cache growing which
|
||||
** won't be undone in this function no matter what.
|
||||
*/
|
||||
|
||||
/* Make easy handle use timeout list initialized above */
|
||||
data->state.timeoutlist = timeoutlist;
|
||||
timeoutlist = NULL;
|
||||
|
||||
/* Remove handle from the list of 'closure handles' in case it is there */
|
||||
cl = multi->closure;
|
||||
while(cl) {
|
||||
struct closure *next = cl->next;
|
||||
if(cl->easy_handle == (struct SessionHandle *)easy_handle) {
|
||||
/* remove this handle from the closure list */
|
||||
if(cl->easy_handle == data) {
|
||||
/* Remove node from list */
|
||||
free(cl);
|
||||
if(prev)
|
||||
prev->next = next;
|
||||
else
|
||||
multi->closure = next;
|
||||
break; /* no need to continue since this handle can only be present once
|
||||
in the list */
|
||||
/* removed from closure list now, this might reuse an existing
|
||||
existing connection but we don't know that at this point */
|
||||
data->state.shared_conn = NULL;
|
||||
/* No need to continue, handle can only be present once in the list */
|
||||
break;
|
||||
}
|
||||
prev = cl;
|
||||
cl = next;
|
||||
}
|
||||
|
||||
/* set the easy handle */
|
||||
easy->easy_handle = easy_handle;
|
||||
easy->easy_handle = data;
|
||||
multistate(easy, CURLM_STATE_INIT);
|
||||
|
||||
/* set the back pointer to one_easy to assist in removal */
|
||||
@@ -505,25 +546,21 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
easy->easy_handle->dns.hostcachetype = HCACHE_MULTI;
|
||||
}
|
||||
|
||||
if(easy->easy_handle->state.connc) {
|
||||
if(easy->easy_handle->state.connc->type == CONNCACHE_PRIVATE) {
|
||||
/* kill old private version */
|
||||
Curl_rm_connc(easy->easy_handle->state.connc);
|
||||
/* point out our shared one instead */
|
||||
easy->easy_handle->state.connc = multi->connc;
|
||||
}
|
||||
/* else it is already using multi? */
|
||||
/* On a multi stack the connection cache, owned by the multi handle,
|
||||
is shared between all easy handles within the multi handle. */
|
||||
if(easy->easy_handle->state.connc &&
|
||||
(easy->easy_handle->state.connc->type == CONNCACHE_PRIVATE)) {
|
||||
/* kill old private connection cache */
|
||||
Curl_rm_connc(easy->easy_handle->state.connc);
|
||||
easy->easy_handle->state.connc = NULL;
|
||||
}
|
||||
else
|
||||
/* point out our shared one */
|
||||
easy->easy_handle->state.connc = multi->connc;
|
||||
|
||||
/* Make sure the type is setup correctly */
|
||||
/* Point now to this multi's connection cache */
|
||||
easy->easy_handle->state.connc = multi->connc;
|
||||
easy->easy_handle->state.connc->type = CONNCACHE_MULTI;
|
||||
|
||||
/* This adds the new entry at the back of the list
|
||||
to try and maintain a FIFO queue so the pipelined
|
||||
requests are in order. */
|
||||
/* This adds the new entry at the 'end' of the doubly-linked circular
|
||||
list of Curl_one_easy structs to try and maintain a FIFO queue so
|
||||
the pipelined requests are in order. */
|
||||
|
||||
/* We add this new entry last in the list. We make our 'next' point to the
|
||||
'first' struct and our 'prev' point to the previous 'prev' */
|
||||
@@ -537,6 +574,7 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
the new node */
|
||||
easy->prev->next = easy;
|
||||
|
||||
/* make the SessionHandle refer back to this multi handle */
|
||||
Curl_easy_addmulti(easy_handle, multi_handle);
|
||||
|
||||
/* make the SessionHandle struct refer back to this struct */
|
||||
@@ -553,27 +591,6 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
/* increase the node-counter */
|
||||
multi->num_easy++;
|
||||
|
||||
if((multi->num_easy * 4) > multi->connc->num) {
|
||||
/* We want the connection cache to have plenty room. Before we supported
|
||||
the shared cache every single easy handle had 5 entries in their cache
|
||||
by default. */
|
||||
long newmax = multi->num_easy * 4;
|
||||
|
||||
if(multi->maxconnects && (multi->maxconnects < newmax))
|
||||
/* don't grow beyond the allowed size */
|
||||
newmax = multi->maxconnects;
|
||||
|
||||
if(newmax > multi->connc->num) {
|
||||
/* we only do this is we can in fact grow the cache */
|
||||
CURLcode res = Curl_ch_connc(easy_handle, multi->connc, newmax);
|
||||
if(res != CURLE_OK) {
|
||||
/* FIXME: may need to do more cleanup here */
|
||||
curl_multi_remove_handle(multi_handle, easy_handle);
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* increase the alive-counter */
|
||||
multi->num_alive++;
|
||||
|
||||
@@ -802,20 +819,12 @@ static int waitconnect_getsock(struct connectdata *conn,
|
||||
}
|
||||
|
||||
static int domore_getsock(struct connectdata *conn,
|
||||
curl_socket_t *sock,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
if(!numsocks)
|
||||
return GETSOCK_BLANK;
|
||||
|
||||
/* When in DO_MORE state, we could be either waiting for us
|
||||
to connect to a remote site, or we could wait for that site
|
||||
to connect to us. It makes a difference in the way: if we
|
||||
connect to the site we wait for the socket to become writable, if
|
||||
the site connects to us we wait for it to become readable */
|
||||
sock[0] = conn->sock[SECONDARYSOCKET];
|
||||
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
if(conn && conn->handler->domore_getsock)
|
||||
return conn->handler->domore_getsock(conn, socks, numsocks);
|
||||
return GETSOCK_BLANK;
|
||||
}
|
||||
|
||||
/* returns bitmapped flags for this handle and its sockets */
|
||||
@@ -907,11 +916,11 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
|
||||
curl_socket_t s = CURL_SOCKET_BAD;
|
||||
|
||||
if(bitmap & GETSOCK_READSOCK(i)) {
|
||||
if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
|
||||
FD_SET(sockbunch[i], read_fd_set);
|
||||
s = sockbunch[i];
|
||||
}
|
||||
if(bitmap & GETSOCK_WRITESOCK(i)) {
|
||||
if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
|
||||
FD_SET(sockbunch[i], write_fd_set);
|
||||
s = sockbunch[i];
|
||||
}
|
||||
@@ -1040,7 +1049,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* Add this handle to the send or pend pipeline */
|
||||
easy->result = addHandleToSendOrPendPipeline(data,
|
||||
easy->easy_conn);
|
||||
if(CURLE_OK == easy->result) {
|
||||
if(CURLE_OK != easy->result)
|
||||
disconnect_conn = TRUE;
|
||||
else {
|
||||
if(async)
|
||||
/* We're now waiting for an asynchronous name lookup */
|
||||
multistate(easy, CURLM_STATE_WAITRESOLVE);
|
||||
@@ -1331,18 +1342,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
&dophase_done);
|
||||
if(CURLE_OK == easy->result) {
|
||||
if(dophase_done) {
|
||||
/* after DO, go PERFORM... or DO_MORE */
|
||||
if(easy->easy_conn->bits.do_more) {
|
||||
/* we're supposed to do more, but we need to sit down, relax
|
||||
and wait a little while first */
|
||||
multistate(easy, CURLM_STATE_DO_MORE);
|
||||
result = CURLM_OK;
|
||||
}
|
||||
else {
|
||||
/* we're done with the DO, now DO_DONE */
|
||||
multistate(easy, CURLM_STATE_DO_DONE);
|
||||
result = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
/* after DO, go DO_DONE or DO_MORE */
|
||||
multistate(easy, easy->easy_conn->bits.do_more?
|
||||
CURLM_STATE_DO_MORE:
|
||||
CURLM_STATE_DO_DONE);
|
||||
result = CURLM_CALL_MULTI_PERFORM;
|
||||
} /* dophase_done */
|
||||
}
|
||||
else {
|
||||
@@ -1538,8 +1542,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
newurl = data->req.location;
|
||||
data->req.location = NULL;
|
||||
easy->result = Curl_follow(data, newurl, FOLLOW_FAKE);
|
||||
if(easy->result)
|
||||
if(easy->result) {
|
||||
disconnect_conn = TRUE;
|
||||
free(newurl);
|
||||
}
|
||||
}
|
||||
|
||||
multistate(easy, CURLM_STATE_DONE);
|
||||
@@ -1616,7 +1622,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
return CURLM_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if(CURLM_STATE_COMPLETED > easy->state) {
|
||||
if(easy->state < CURLM_STATE_COMPLETED) {
|
||||
if(CURLE_OK != easy->result) {
|
||||
/*
|
||||
* If an error was returned, and we aren't in completed state now,
|
||||
@@ -1640,23 +1646,35 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
easy->easy_conn->done_pipe);
|
||||
/* Check if we can move pending requests to send pipe */
|
||||
checkPendPipeline(easy->easy_conn);
|
||||
|
||||
if(disconnect_conn) {
|
||||
/* disconnect properly */
|
||||
Curl_disconnect(easy->easy_conn, /* dead_connection */ FALSE);
|
||||
|
||||
/* This is where we make sure that the easy_conn pointer is reset.
|
||||
We don't have to do this in every case block above where a
|
||||
failure is detected */
|
||||
easy->easy_conn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(disconnect_conn) {
|
||||
/* disconnect properly */
|
||||
Curl_disconnect(easy->easy_conn, /* dead_connection */ FALSE);
|
||||
|
||||
/* This is where we make sure that the easy_conn pointer is reset.
|
||||
We don't have to do this in every case block above where a
|
||||
failure is detected */
|
||||
easy->easy_conn = NULL;
|
||||
else if(easy->state == CURLM_STATE_CONNECT) {
|
||||
/* Curl_connect() failed */
|
||||
(void)Curl_posttransfer(data);
|
||||
}
|
||||
|
||||
multistate(easy, CURLM_STATE_COMPLETED);
|
||||
}
|
||||
/* if there's still a connection to use, call the progress function */
|
||||
else if(easy->easy_conn && Curl_pgrsUpdate(easy->easy_conn))
|
||||
easy->result = CURLE_ABORTED_BY_CALLBACK;
|
||||
else if(easy->easy_conn && Curl_pgrsUpdate(easy->easy_conn)) {
|
||||
/* aborted due to progress callback return code must close the
|
||||
connection */
|
||||
easy->easy_conn->bits.close = TRUE;
|
||||
|
||||
/* if not yet in DONE state, go there, otherwise COMPLETED */
|
||||
multistate(easy, (easy->state < CURLM_STATE_DONE)?
|
||||
CURLM_STATE_DONE: CURLM_STATE_COMPLETED);
|
||||
result = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
}
|
||||
} WHILE_FALSE; /* just to break out from! */
|
||||
|
||||
@@ -1760,10 +1778,6 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
|
||||
if(GOOD_MULTI_HANDLE(multi)) {
|
||||
multi->type = 0; /* not good anymore */
|
||||
Curl_hash_destroy(multi->hostcache);
|
||||
Curl_hash_destroy(multi->sockhash);
|
||||
multi->hostcache = NULL;
|
||||
multi->sockhash = NULL;
|
||||
|
||||
/* go over all connections that have close actions */
|
||||
for(i=0; i< multi->connc->num; i++) {
|
||||
@@ -1777,7 +1791,7 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
able to close connections "properly" */
|
||||
cl = multi->closure;
|
||||
while(cl) {
|
||||
cl->easy_handle->state.shared_conn = NULL; /* no more shared */
|
||||
cl->easy_handle->state.shared_conn = NULL; /* allow cleanup */
|
||||
if(cl->easy_handle->state.closed)
|
||||
/* close handle only if curl_easy_cleanup() already has been called
|
||||
for this easy handle */
|
||||
@@ -1787,10 +1801,18 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
cl= n;
|
||||
}
|
||||
|
||||
Curl_hash_destroy(multi->hostcache);
|
||||
multi->hostcache = NULL;
|
||||
|
||||
Curl_hash_destroy(multi->sockhash);
|
||||
multi->sockhash = NULL;
|
||||
|
||||
Curl_rm_connc(multi->connc);
|
||||
multi->connc = NULL;
|
||||
|
||||
/* remove the pending list of messages */
|
||||
Curl_llist_destroy(multi->msglist, NULL);
|
||||
multi->msglist = NULL;
|
||||
|
||||
/* remove all easy handles */
|
||||
easy = multi->easy.next;
|
||||
@@ -2689,12 +2711,15 @@ static void multi_connc_remove_handle(struct Curl_multi *multi,
|
||||
/* out of memory - so much for graceful shutdown */
|
||||
Curl_disconnect(conn, /* dead_connection */ FALSE);
|
||||
multi->connc->connects[i] = NULL;
|
||||
data->state.shared_conn = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
/* disconect the easy handle from the connection since the connection
|
||||
will now remain but this easy handle is going */
|
||||
data->state.shared_conn = NULL;
|
||||
conn->data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
244
lib/nss.c
244
lib/nss.c
@@ -278,17 +278,16 @@ static int is_file(const char *filename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return on heap allocated filename/nickname of a certificate. The returned
|
||||
* string should be later deallocated using free(). *is_nickname is set to
|
||||
* TRUE if the given string is treated as nickname; FALSE if the given string
|
||||
* is treated as file name.
|
||||
/* Check if the given string is filename or nickname of a certificate. If the
|
||||
* given string is recognized as filename, return NULL. If the given string is
|
||||
* recognized as nickname, return a duplicated string. The returned string
|
||||
* should be later deallocated using free(). If the OOM failure occurs, we
|
||||
* return NULL, too.
|
||||
*/
|
||||
static char *fmt_nickname(struct SessionHandle *data, enum dupstring cert_kind,
|
||||
bool *is_nickname)
|
||||
static char* dup_nickname(struct SessionHandle *data, enum dupstring cert_kind)
|
||||
{
|
||||
const char *str = data->set.str[cert_kind];
|
||||
const char *n;
|
||||
*is_nickname = TRUE;
|
||||
|
||||
if(!is_file(str))
|
||||
/* no such file exists, use the string as nickname */
|
||||
@@ -303,10 +302,7 @@ static char *fmt_nickname(struct SessionHandle *data, enum dupstring cert_kind,
|
||||
}
|
||||
|
||||
/* we'll use the PEM reader to read the certificate from file */
|
||||
*is_nickname = FALSE;
|
||||
|
||||
n++; /* skip last slash */
|
||||
return aprintf("PEM Token #%d:%s", 1, n);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
@@ -323,6 +319,9 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
|
||||
CK_BBOOL ckfalse = CK_FALSE;
|
||||
CK_ATTRIBUTE attrs[/* max count of attributes */ 4];
|
||||
int attr_cnt = 0;
|
||||
CURLcode err = (cacert)
|
||||
? CURLE_SSL_CACERT_BADFILE
|
||||
: CURLE_SSL_CERTPROBLEM;
|
||||
|
||||
const int slot_id = (cacert) ? 0 : 1;
|
||||
char *slot_name = aprintf("PEM Token #%d", slot_id);
|
||||
@@ -332,7 +331,7 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
|
||||
slot = PK11_FindSlotByName(slot_name);
|
||||
free(slot_name);
|
||||
if(!slot)
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
return err;
|
||||
|
||||
PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class, sizeof(obj_class));
|
||||
PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
|
||||
@@ -347,13 +346,17 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
|
||||
obj = PK11_CreateGenericObject(slot, attrs, attr_cnt, PR_FALSE);
|
||||
PK11_FreeSlot(slot);
|
||||
if(!obj)
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
return err;
|
||||
|
||||
if(!Curl_llist_insert_next(ssl->obj_list, ssl->obj_list->tail, obj)) {
|
||||
PK11_DestroyGenericObject(obj);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!cacert && CKO_CERTIFICATE == obj_class)
|
||||
/* store reference to a client certificate */
|
||||
ssl->obj_clicert = obj;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -368,76 +371,43 @@ static void nss_destroy_object(void *user, void *ptr)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int nss_load_cert(struct ssl_connect_data *ssl,
|
||||
const char *filename, PRBool cacert)
|
||||
static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
|
||||
const char *filename, PRBool cacert)
|
||||
{
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
/* All CA and trust objects go into slot 0. Other slots are used
|
||||
* for storing certificates.
|
||||
*/
|
||||
const int slot_id = (cacert) ? 0 : 1;
|
||||
#endif
|
||||
CERTCertificate *cert;
|
||||
char *nickname = NULL;
|
||||
char *n = NULL;
|
||||
CURLcode err = (cacert)
|
||||
? CURLE_SSL_CACERT_BADFILE
|
||||
: CURLE_SSL_CERTPROBLEM;
|
||||
|
||||
/* If there is no slash in the filename it is assumed to be a regular
|
||||
* NSS nickname.
|
||||
*/
|
||||
if(is_file(filename)) {
|
||||
n = strrchr(filename, '/');
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
/* libnsspem.so leaks memory if the requested file does not exist. For more
|
||||
* details, go to <https://bugzilla.redhat.com/734760>. */
|
||||
if(is_file(filename))
|
||||
err = nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert);
|
||||
|
||||
if(CURLE_OK == err && !cacert) {
|
||||
/* we have successfully loaded a client certificate */
|
||||
CERTCertificate *cert;
|
||||
char *nickname = NULL;
|
||||
char *n = strrchr(filename, '/');
|
||||
if(n)
|
||||
n++;
|
||||
if(!mod)
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
/* A nickname from the NSS internal database */
|
||||
if(cacert)
|
||||
return 0; /* You can't specify an NSS CA nickname this way */
|
||||
nickname = strdup(filename);
|
||||
if(!nickname)
|
||||
return 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
nickname = aprintf("PEM Token #%d:%s", slot_id, n);
|
||||
if(!nickname)
|
||||
return 0;
|
||||
/* The following undocumented magic helps to avoid a SIGSEGV on call
|
||||
* of PK11_ReadRawAttribute() from SelectClientCert() when using an
|
||||
* immature version of libnsspem.so. For more details, go to
|
||||
* <https://bugzilla.redhat.com/733685>. */
|
||||
nickname = aprintf("PEM Token #1:%s", n);
|
||||
if(nickname) {
|
||||
cert = PK11_FindCertFromNickname(nickname, NULL);
|
||||
if(cert)
|
||||
CERT_DestroyCertificate(cert);
|
||||
|
||||
if(CURLE_OK != nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert)) {
|
||||
free(nickname);
|
||||
return 0;
|
||||
free(nickname);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/* We don't have PK11_CreateGenericObject but a file-based cert was passed
|
||||
* in. We need to fail.
|
||||
*/
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
done:
|
||||
/* Double-check that the certificate or nickname requested exists in
|
||||
* either the token or the NSS certificate database.
|
||||
*/
|
||||
if(!cacert) {
|
||||
cert = PK11_FindCertFromNickname((char *)nickname, NULL);
|
||||
|
||||
/* An invalid nickname was passed in */
|
||||
if(cert == NULL) {
|
||||
free(nickname);
|
||||
PR_SetError(SEC_ERROR_UNKNOWN_CERT, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CERT_DestroyCertificate(cert);
|
||||
}
|
||||
|
||||
free(nickname);
|
||||
|
||||
return 1;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* add given CRL to cache if it is not already there */
|
||||
@@ -526,23 +496,23 @@ fail:
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
static int nss_load_key(struct connectdata *conn, int sockindex,
|
||||
char *key_file)
|
||||
static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
|
||||
char *key_file)
|
||||
{
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
PK11SlotInfo *slot;
|
||||
SECStatus status;
|
||||
struct ssl_connect_data *ssl = conn->ssl;
|
||||
(void)sockindex; /* unused */
|
||||
|
||||
if(CURLE_OK != nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE)) {
|
||||
CURLcode rv = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE);
|
||||
if(CURLE_OK != rv) {
|
||||
PR_SetError(SEC_ERROR_BAD_KEY, 0);
|
||||
return 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
slot = PK11_FindSlotByName("PEM Token #1");
|
||||
if(!slot)
|
||||
return 0;
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
|
||||
/* This will force the token to be seen as re-inserted */
|
||||
SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
|
||||
@@ -551,16 +521,18 @@ static int nss_load_key(struct connectdata *conn, int sockindex,
|
||||
status = PK11_Authenticate(slot, PR_TRUE,
|
||||
conn->data->set.str[STRING_KEY_PASSWD]);
|
||||
PK11_FreeSlot(slot);
|
||||
return (SECSuccess == status) ? 1 : 0;
|
||||
return (SECSuccess == status)
|
||||
? CURLE_OK
|
||||
: CURLE_SSL_CERTPROBLEM;
|
||||
#else
|
||||
/* If we don't have PK11_CreateGenericObject then we can't load a file-based
|
||||
* key.
|
||||
*/
|
||||
(void)conn; /* unused */
|
||||
(void)key_file; /* unused */
|
||||
(void)sockindex; /* unused */
|
||||
return 0;
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
#endif
|
||||
(void)sockindex; /* unused */
|
||||
}
|
||||
|
||||
static int display_error(struct connectdata *conn, PRInt32 err,
|
||||
@@ -579,34 +551,37 @@ static int display_error(struct connectdata *conn, PRInt32 err,
|
||||
return 0; /* The caller will print a generic error */
|
||||
}
|
||||
|
||||
static int cert_stuff(struct connectdata *conn,
|
||||
int sockindex, char *cert_file, char *key_file)
|
||||
static CURLcode cert_stuff(struct connectdata *conn, int sockindex,
|
||||
char *cert_file, char *key_file)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
int rv = 0;
|
||||
CURLcode rv;
|
||||
|
||||
if(cert_file) {
|
||||
rv = nss_load_cert(&conn->ssl[sockindex], cert_file, PR_FALSE);
|
||||
if(!rv) {
|
||||
if(CURLE_OK != rv) {
|
||||
if(!display_error(conn, PR_GetError(), cert_file))
|
||||
failf(data, "Unable to load client cert %d.", PR_GetError());
|
||||
return 0;
|
||||
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if(key_file || (is_file(cert_file))) {
|
||||
if(key_file)
|
||||
rv = nss_load_key(conn, sockindex, key_file);
|
||||
else
|
||||
/* In case the cert file also has the key */
|
||||
rv = nss_load_key(conn, sockindex, cert_file);
|
||||
if(!rv) {
|
||||
if(CURLE_OK != rv) {
|
||||
if(!display_error(conn, PR_GetError(), key_file))
|
||||
failf(data, "Unable to load client key %d.", PR_GetError());
|
||||
|
||||
return 0;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static char * nss_get_password(PK11SlotInfo * slot, PRBool retry, void *arg)
|
||||
@@ -773,7 +748,6 @@ static SECStatus check_issuer_cert(PRFileDesc *sock,
|
||||
cert_issuer = CERT_FindCertIssuer(cert,PR_Now(),certUsageObjectSigner);
|
||||
|
||||
proto_win = SSL_RevealPinArg(sock);
|
||||
issuer = NULL;
|
||||
issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win);
|
||||
|
||||
if((!cert_issuer) || (!issuer))
|
||||
@@ -797,44 +771,51 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
||||
struct CERTCertificateStr **pRetCert,
|
||||
struct SECKEYPrivateKeyStr **pRetKey)
|
||||
{
|
||||
static const char pem_nickname[] = "PEM Token #1";
|
||||
const char *pem_slotname = pem_nickname;
|
||||
|
||||
struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
|
||||
struct SessionHandle *data = connssl->data;
|
||||
const char *nickname = connssl->client_nickname;
|
||||
|
||||
if(mod && nickname &&
|
||||
0 == strncmp(nickname, pem_nickname, /* length of "PEM Token" */ 9)) {
|
||||
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
if(connssl->obj_clicert) {
|
||||
/* use the cert/key provided by PEM reader */
|
||||
PK11SlotInfo *slot;
|
||||
static const char pem_slotname[] = "PEM Token #1";
|
||||
SECItem cert_der = { 0, NULL, 0 };
|
||||
void *proto_win = SSL_RevealPinArg(sock);
|
||||
*pRetKey = NULL;
|
||||
|
||||
*pRetCert = PK11_FindCertFromNickname(nickname, proto_win);
|
||||
if(NULL == *pRetCert) {
|
||||
failf(data, "NSS: client certificate not found: %s", nickname);
|
||||
PK11SlotInfo *slot = PK11_FindSlotByName(pem_slotname);
|
||||
if(NULL == slot) {
|
||||
failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
slot = PK11_FindSlotByName(pem_slotname);
|
||||
if(NULL == slot) {
|
||||
failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
|
||||
if(PK11_ReadRawAttribute(PK11_TypeGeneric, connssl->obj_clicert, CKA_VALUE,
|
||||
&cert_der) != SECSuccess) {
|
||||
failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
|
||||
PK11_FreeSlot(slot);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
*pRetCert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
|
||||
SECITEM_FreeItem(&cert_der, PR_FALSE);
|
||||
if(NULL == *pRetCert) {
|
||||
failf(data, "NSS: client certificate from file not found");
|
||||
PK11_FreeSlot(slot);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
*pRetKey = PK11_FindPrivateKeyFromCert(slot, *pRetCert, NULL);
|
||||
PK11_FreeSlot(slot);
|
||||
if(NULL == *pRetKey) {
|
||||
failf(data, "NSS: private key not found for certificate: %s", nickname);
|
||||
failf(data, "NSS: private key from file not found");
|
||||
CERT_DestroyCertificate(*pRetCert);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
infof(data, "NSS: client certificate: %s\n", nickname);
|
||||
infof(data, "NSS: client certificate from file\n");
|
||||
display_cert_info(data, *pRetCert);
|
||||
return SECSuccess;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* use the default NSS hook */
|
||||
if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
|
||||
@@ -1076,6 +1057,7 @@ void Curl_nss_close(struct connectdata *conn, int sockindex)
|
||||
/* destroy all NSS objects in order to avoid failure of NSS shutdown */
|
||||
Curl_llist_destroy(connssl->obj_list, NULL);
|
||||
connssl->obj_list = NULL;
|
||||
connssl->obj_clicert = NULL;
|
||||
#endif
|
||||
PR_Close(connssl->handle);
|
||||
connssl->handle = NULL;
|
||||
@@ -1123,8 +1105,11 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
|
||||
const char *cafile = data->set.ssl.CAfile;
|
||||
const char *capath = data->set.ssl.CApath;
|
||||
|
||||
if(cafile && !nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE))
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
if(cafile) {
|
||||
CURLcode rv = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE);
|
||||
if(CURLE_OK != rv)
|
||||
return rv;
|
||||
}
|
||||
|
||||
if(capath) {
|
||||
struct_stat st;
|
||||
@@ -1144,7 +1129,7 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE))
|
||||
if(CURLE_OK != nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE))
|
||||
/* This is purposefully tolerant of errors so non-PEM files can
|
||||
* be in the same directory */
|
||||
infof(data, "failed to load '%s' from CURLOPT_CAPATH\n", fullpath);
|
||||
@@ -1339,16 +1324,21 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
if(data->set.str[STRING_CERT]) {
|
||||
bool is_nickname;
|
||||
char *nickname = fmt_nickname(data, STRING_CERT, &is_nickname);
|
||||
if(!nickname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(!is_nickname && !cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
|
||||
data->set.str[STRING_KEY])) {
|
||||
/* failf() is already done in cert_stuff() */
|
||||
free(nickname);
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
char *nickname = dup_nickname(data, STRING_CERT);
|
||||
if(nickname) {
|
||||
/* we are not going to use libnsspem.so to read the client cert */
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
connssl->obj_clicert = NULL;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
CURLcode rv = cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
|
||||
data->set.str[STRING_KEY]);
|
||||
if(CURLE_OK != rv) {
|
||||
/* failf() is already done in cert_stuff() */
|
||||
curlerr = rv;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* store the nickname for SelectClientCert() called during handshake */
|
||||
@@ -1407,16 +1397,12 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
|
||||
if(data->set.str[STRING_SSL_ISSUERCERT]) {
|
||||
SECStatus ret = SECFailure;
|
||||
bool is_nickname;
|
||||
char *nickname = fmt_nickname(data, STRING_SSL_ISSUERCERT, &is_nickname);
|
||||
if(!nickname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(is_nickname)
|
||||
char *nickname = dup_nickname(data, STRING_SSL_ISSUERCERT);
|
||||
if(nickname) {
|
||||
/* we support only nicknames in case of STRING_SSL_ISSUERCERT for now */
|
||||
ret = check_issuer_cert(connssl->handle, nickname);
|
||||
|
||||
free(nickname);
|
||||
free(nickname);
|
||||
}
|
||||
|
||||
if(SECFailure == ret) {
|
||||
infof(data,"SSL certificate issuer check failed\n");
|
||||
|
@@ -83,6 +83,7 @@ const struct Curl_handler Curl_handler_ldap = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ldap_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -107,6 +108,7 @@ const struct Curl_handler Curl_handler_ldaps = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ldap_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
|
@@ -315,10 +315,9 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
|
||||
/* we had data in the "cache", copy that instead of doing an actual
|
||||
* read
|
||||
*
|
||||
* ftp->cache_size is cast to int here. This should be safe,
|
||||
* because it would have been populated with something of size
|
||||
* int to begin with, even though its datatype may be larger
|
||||
* than an int.
|
||||
* pp->cache_size is cast to ssize_t here. This should be safe, because
|
||||
* it would have been populated with something of size int to begin
|
||||
* with, even though its datatype may be larger than an int.
|
||||
*/
|
||||
DEBUGASSERT((ptr+pp->cache_size) <= (buf+BUFSIZE+1));
|
||||
memcpy(ptr, pp->cache, pp->cache_size);
|
||||
@@ -375,7 +374,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
|
||||
for(i = 0; i < gotbytes; ptr++, i++) {
|
||||
perline++;
|
||||
if(*ptr=='\n') {
|
||||
/* a newline is CRLF in ftp-talk, so the CR is ignored as
|
||||
/* a newline is CRLF in pp-talk, so the CR is ignored as
|
||||
the line isn't really terminated until the LF comes */
|
||||
|
||||
/* output debug output if that is requested */
|
||||
|
@@ -119,6 +119,7 @@ const struct Curl_handler Curl_handler_pop3 = {
|
||||
pop3_doing, /* doing */
|
||||
pop3_getsock, /* proto_getsock */
|
||||
pop3_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
pop3_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -144,6 +145,7 @@ const struct Curl_handler Curl_handler_pop3s = {
|
||||
pop3_doing, /* doing */
|
||||
pop3_getsock, /* proto_getsock */
|
||||
pop3_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
pop3_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -169,6 +171,7 @@ static const struct Curl_handler Curl_handler_pop3_proxy = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -194,6 +197,7 @@ static const struct Curl_handler Curl_handler_pop3s_proxy = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -517,7 +521,7 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
|
||||
return CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
if(data->set.ftp_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
/* We don't have a SSL/TLS connection yet, but SSL is requested. Switch
|
||||
to TLS connection now */
|
||||
result = Curl_pp_sendf(&pop3c->pp, "STLS");
|
||||
|
@@ -201,7 +201,8 @@ void Curl_pgrsStartNow(struct SessionHandle *data)
|
||||
{
|
||||
data->progress.speeder_c = 0; /* reset the progress meter display */
|
||||
data->progress.start = Curl_tvnow();
|
||||
data->progress.flags &= PGRS_HIDE; /* clear all bits except HIDE */
|
||||
/* clear all bits except HIDE and HEADERS_OUT */
|
||||
data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT;
|
||||
}
|
||||
|
||||
void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, curl_off_t size)
|
||||
|
@@ -113,6 +113,7 @@ const struct Curl_handler Curl_handler_rtsp = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
rtsp_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtsp_disconnect, /* disconnect */
|
||||
rtsp_rtp_readwrite, /* readwrite */
|
||||
|
14
lib/select.c
14
lib/select.c
@@ -46,20 +46,6 @@
|
||||
#include "select.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1] */
|
||||
|
||||
#if defined(USE_WINSOCK) || defined(TPF)
|
||||
#define VERIFY_SOCK(x) Curl_nop_stmt
|
||||
#else
|
||||
#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
|
||||
#define VERIFY_SOCK(x) do { \
|
||||
if(!VALID_SOCK(x)) { \
|
||||
SET_SOCKERRNO(EINVAL); \
|
||||
return -1; \
|
||||
} \
|
||||
} WHILE_FALSE
|
||||
#endif
|
||||
|
||||
/* Convenience local macros */
|
||||
|
||||
#define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
|
||||
|
16
lib/select.h
16
lib/select.h
@@ -96,4 +96,20 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
|
||||
fd_set* excepts, struct timeval* tv);
|
||||
#endif
|
||||
|
||||
/* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1], which
|
||||
unfortunately makes it impossible for us to easily check if they're valid
|
||||
*/
|
||||
#if defined(USE_WINSOCK) || defined(TPF)
|
||||
#define VALID_SOCK(x) 1
|
||||
#define VERIFY_SOCK(x) Curl_nop_stmt
|
||||
#else
|
||||
#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
|
||||
#define VERIFY_SOCK(x) do { \
|
||||
if(!VALID_SOCK(x)) { \
|
||||
SET_SOCKERRNO(EINVAL); \
|
||||
return -1; \
|
||||
} \
|
||||
} WHILE_FALSE
|
||||
#endif
|
||||
|
||||
#endif /* __SELECT_H */
|
||||
|
@@ -319,6 +319,7 @@
|
||||
# include <io.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# undef lseek
|
||||
# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence)
|
||||
# define fstat(fdes,stp) _fstati64(fdes, stp)
|
||||
# define stat(fname,stp) _stati64(fname, stp)
|
||||
@@ -334,6 +335,7 @@
|
||||
# include <io.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# undef lseek
|
||||
# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence)
|
||||
# define fstat(fdes,stp) _fstat(fdes, stp)
|
||||
# define stat(fname,stp) _stat(fname, stp)
|
||||
|
48
lib/share.c
48
lib/share.c
@@ -25,6 +25,7 @@
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "share.h"
|
||||
#include "sslgen.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
@@ -72,17 +73,32 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
|
||||
}
|
||||
break;
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
case CURL_LOCK_DATA_COOKIE:
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
if(!share->cookies) {
|
||||
share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE );
|
||||
if(!share->cookies)
|
||||
return CURLSHE_NOMEM;
|
||||
}
|
||||
break;
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
#else /* CURL_DISABLE_HTTP */
|
||||
return CURLSHE_NOT_BUILT_IN;
|
||||
#endif
|
||||
|
||||
case CURL_LOCK_DATA_SSL_SESSION:
|
||||
#ifdef USE_SSL
|
||||
if(!share->sslsession) {
|
||||
share->nsslsession = 8;
|
||||
share->sslsession = calloc(share->nsslsession,
|
||||
sizeof(struct curl_ssl_session));
|
||||
if(!share->sslsession)
|
||||
return CURLSHE_NOMEM;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
return CURLSHE_NOT_BUILT_IN;
|
||||
#endif
|
||||
|
||||
case CURL_LOCK_DATA_SSL_SESSION: /* not supported (yet) */
|
||||
case CURL_LOCK_DATA_CONNECT: /* not supported (yet) */
|
||||
|
||||
default:
|
||||
@@ -102,17 +118,28 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
|
||||
}
|
||||
break;
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
case CURL_LOCK_DATA_COOKIE:
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
if(share->cookies) {
|
||||
Curl_cookie_cleanup(share->cookies);
|
||||
share->cookies = NULL;
|
||||
}
|
||||
break;
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
#else /* CURL_DISABLE_HTTP */
|
||||
return CURLSHE_NOT_BUILT_IN;
|
||||
#endif
|
||||
|
||||
case CURL_LOCK_DATA_SSL_SESSION:
|
||||
#ifdef USE_SSL
|
||||
if(share->sslsession) {
|
||||
free(share->sslsession);
|
||||
share->sslsession = NULL;
|
||||
share->nsslsession = 0;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
return CURLSHE_NOT_BUILT_IN;
|
||||
#endif
|
||||
|
||||
case CURL_LOCK_DATA_CONNECT:
|
||||
break;
|
||||
@@ -167,8 +194,19 @@ curl_share_cleanup(CURLSH *sh)
|
||||
share->hostcache = NULL;
|
||||
}
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
if(share->cookies)
|
||||
Curl_cookie_cleanup(share->cookies);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSL
|
||||
if(share->sslsession) {
|
||||
unsigned int i;
|
||||
for(i = 0; i < share->nsslsession; ++i)
|
||||
Curl_ssl_kill_session(&(share->sslsession[i]));
|
||||
free(share->sslsession);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(share->unlockfunc)
|
||||
share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
|
||||
|
@@ -8,7 +8,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, 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
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "setup.h"
|
||||
#include <curl/curl.h>
|
||||
#include "cookie.h"
|
||||
#include "urldata.h"
|
||||
|
||||
/* SalfordC says "A structure member may not be volatile". Hence:
|
||||
*/
|
||||
@@ -45,7 +46,12 @@ struct Curl_share {
|
||||
void *clientdata;
|
||||
|
||||
struct curl_hash *hostcache;
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
struct CookieInfo *cookies;
|
||||
#endif
|
||||
|
||||
struct curl_ssl_session *sslsession;
|
||||
unsigned int nsslsession;
|
||||
};
|
||||
|
||||
CURLSHcode Curl_share_lock (struct SessionHandle *, curl_lock_data,
|
||||
|
@@ -119,10 +119,7 @@ void curl_slist_free_all(struct curl_slist *list)
|
||||
item = list;
|
||||
do {
|
||||
next = item->next;
|
||||
|
||||
if(item->data) {
|
||||
free(item->data);
|
||||
}
|
||||
Curl_safefree(item->data);
|
||||
free(item);
|
||||
item = next;
|
||||
} while(next);
|
||||
|
372
lib/smtp.c
372
lib/smtp.c
@@ -85,6 +85,7 @@
|
||||
#include "curl_md5.h"
|
||||
#include "curl_hmac.h"
|
||||
#include "curl_gethostname.h"
|
||||
#include "curl_ntlm_msgs.h"
|
||||
#include "warnless.h"
|
||||
#include "http_proxy.h"
|
||||
|
||||
@@ -111,7 +112,6 @@ static CURLcode smtp_doing(struct connectdata *conn,
|
||||
static CURLcode smtp_setup_connection(struct connectdata * conn);
|
||||
static CURLcode smtp_state_upgrade_tls(struct connectdata *conn);
|
||||
|
||||
|
||||
/*
|
||||
* SMTP protocol handler.
|
||||
*/
|
||||
@@ -127,6 +127,7 @@ const struct Curl_handler Curl_handler_smtp = {
|
||||
smtp_doing, /* doing */
|
||||
smtp_getsock, /* proto_getsock */
|
||||
smtp_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
smtp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -135,7 +136,6 @@ const struct Curl_handler Curl_handler_smtp = {
|
||||
PROTOPT_CLOSEACTION /* flags */
|
||||
};
|
||||
|
||||
|
||||
#ifdef USE_SSL
|
||||
/*
|
||||
* SMTPS protocol handler.
|
||||
@@ -152,6 +152,7 @@ const struct Curl_handler Curl_handler_smtps = {
|
||||
smtp_doing, /* doing */
|
||||
smtp_getsock, /* proto_getsock */
|
||||
smtp_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
smtp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -177,6 +178,7 @@ static const struct Curl_handler Curl_handler_smtp_proxy = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -185,7 +187,6 @@ static const struct Curl_handler Curl_handler_smtp_proxy = {
|
||||
PROTOPT_NONE /* flags */
|
||||
};
|
||||
|
||||
|
||||
#ifdef USE_SSL
|
||||
/*
|
||||
* HTTP-proxyed SMTPS protocol handler.
|
||||
@@ -202,6 +203,7 @@ static const struct Curl_handler Curl_handler_smtps_proxy = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -212,7 +214,6 @@ static const struct Curl_handler Curl_handler_smtps_proxy = {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Function that checks for an ending smtp status code at the start of the
|
||||
given string.
|
||||
As a side effect, it also flags allowed authentication mechanisms according
|
||||
@@ -267,6 +268,8 @@ static int smtp_endofresp(struct pingpong *pp, int *resp)
|
||||
smtpc->authmechs |= SMTP_AUTH_GSSAPI;
|
||||
else if(wordlen == 8 && !memcmp(line, "EXTERNAL", 8))
|
||||
smtpc->authmechs |= SMTP_AUTH_EXTERNAL;
|
||||
else if(wordlen == 4 && !memcmp(line, "NTLM", 4))
|
||||
smtpc->authmechs |= SMTP_AUTH_NTLM;
|
||||
|
||||
line += wordlen;
|
||||
len -= wordlen;
|
||||
@@ -294,6 +297,8 @@ static void state(struct connectdata *conn,
|
||||
"AUTHLOGIN",
|
||||
"AUTHPASSWD",
|
||||
"AUTHCRAM",
|
||||
"AUTHNTLM",
|
||||
"AUTHNTLM_TYPE2MSG",
|
||||
"AUTH",
|
||||
"MAIL",
|
||||
"RCPT",
|
||||
@@ -315,6 +320,8 @@ static CURLcode smtp_state_ehlo(struct connectdata *conn)
|
||||
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
||||
|
||||
smtpc->authmechs = 0; /* No known authentication mechanisms yet. */
|
||||
smtpc->authused = 0; /* Clear the authentication mechanism used
|
||||
for esmtp connections */
|
||||
|
||||
/* send EHLO */
|
||||
result = Curl_pp_sendf(&smtpc->pp, "EHLO %s", smtpc->domain);
|
||||
@@ -331,6 +338,9 @@ static CURLcode smtp_state_helo(struct connectdata *conn)
|
||||
CURLcode result;
|
||||
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
||||
|
||||
smtpc->authused = 0; /* No authentication mechanism used in smtp
|
||||
connections */
|
||||
|
||||
/* send HELO */
|
||||
result = Curl_pp_sendf(&smtpc->pp, "HELO %s", smtpc->domain);
|
||||
|
||||
@@ -384,68 +394,87 @@ static CURLcode smtp_auth_login_user(struct connectdata *conn,
|
||||
return Curl_base64_encode(conn->data, conn->user, ulen, outptr, outlen);
|
||||
}
|
||||
|
||||
#ifdef USE_NTLM
|
||||
static CURLcode smtp_auth_ntlm_type1_message(struct connectdata *conn,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
return Curl_ntlm_create_type1_message(conn->user, conn->passwd,
|
||||
&conn->ntlm, outptr, outlen);
|
||||
}
|
||||
#endif
|
||||
|
||||
static CURLcode smtp_authenticate(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
||||
char * initresp;
|
||||
const char * mech;
|
||||
size_t l;
|
||||
smtpstate state1;
|
||||
smtpstate state2;
|
||||
char *initresp = NULL;
|
||||
const char *mech = NULL;
|
||||
size_t len = 0;
|
||||
smtpstate state1 = SMTP_STOP;
|
||||
smtpstate state2 = SMTP_STOP;
|
||||
|
||||
if(!conn->bits.user_passwd)
|
||||
state(conn, SMTP_STOP); /* End of connect phase. */
|
||||
else {
|
||||
initresp = (char *) NULL;
|
||||
l = 1;
|
||||
/* Check we have a username and password to authenticate with and end the
|
||||
connect phase if we don't. */
|
||||
if(!conn->bits.user_passwd) {
|
||||
state(conn, SMTP_STOP);
|
||||
|
||||
/* Check supported authentication mechanisms by decreasing order of
|
||||
security. */
|
||||
mech = (const char *) NULL; /* Avoid compiler warnings. */
|
||||
state1 = SMTP_STOP;
|
||||
state2 = SMTP_STOP;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Check supported authentication mechanisms by decreasing order of
|
||||
security. */
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if(smtpc->authmechs & SMTP_AUTH_CRAM_MD5) {
|
||||
mech = "CRAM-MD5";
|
||||
state1 = SMTP_AUTHCRAM;
|
||||
}
|
||||
else
|
||||
if(smtpc->authmechs & SMTP_AUTH_CRAM_MD5) {
|
||||
mech = "CRAM-MD5";
|
||||
state1 = SMTP_AUTHCRAM;
|
||||
smtpc->authused = SMTP_AUTH_CRAM_MD5;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if(smtpc->authmechs & SMTP_AUTH_LOGIN) {
|
||||
mech = "LOGIN";
|
||||
state1 = SMTP_AUTHLOGIN;
|
||||
state2 = SMTP_AUTHPASSWD;
|
||||
result = smtp_auth_login_user(conn, &initresp, &l);
|
||||
}
|
||||
else if(smtpc->authmechs & SMTP_AUTH_PLAIN) {
|
||||
mech = "PLAIN";
|
||||
state1 = SMTP_AUTHPLAIN;
|
||||
state2 = SMTP_AUTH;
|
||||
result = smtp_auth_plain_data(conn, &initresp, &l);
|
||||
#ifdef USE_NTLM
|
||||
if(smtpc->authmechs & SMTP_AUTH_NTLM) {
|
||||
mech = "NTLM";
|
||||
state1 = SMTP_AUTHNTLM;
|
||||
state2 = SMTP_AUTHNTLM_TYPE2MSG;
|
||||
smtpc->authused = SMTP_AUTH_NTLM;
|
||||
result = smtp_auth_ntlm_type1_message(conn, &initresp, &len);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if(smtpc->authmechs & SMTP_AUTH_LOGIN) {
|
||||
mech = "LOGIN";
|
||||
state1 = SMTP_AUTHLOGIN;
|
||||
state2 = SMTP_AUTHPASSWD;
|
||||
smtpc->authused = SMTP_AUTH_LOGIN;
|
||||
result = smtp_auth_login_user(conn, &initresp, &len);
|
||||
}
|
||||
else if(smtpc->authmechs & SMTP_AUTH_PLAIN) {
|
||||
mech = "PLAIN";
|
||||
state1 = SMTP_AUTHPLAIN;
|
||||
state2 = SMTP_AUTH;
|
||||
smtpc->authused = SMTP_AUTH_PLAIN;
|
||||
result = smtp_auth_plain_data(conn, &initresp, &len);
|
||||
}
|
||||
else {
|
||||
infof(conn->data, "No known auth mechanisms supported!\n");
|
||||
result = CURLE_LOGIN_DENIED; /* Other mechanisms not supported. */
|
||||
}
|
||||
|
||||
if(!result) {
|
||||
if(initresp &&
|
||||
strlen(mech) + len <= 512 - 8) { /* AUTH <mech> ...<crlf> */
|
||||
result = Curl_pp_sendf(&smtpc->pp, "AUTH %s %s", mech, initresp);
|
||||
|
||||
if(!result)
|
||||
state(conn, state2);
|
||||
}
|
||||
else {
|
||||
infof(conn->data, "No known auth mechanisms supported!\n");
|
||||
result = CURLE_LOGIN_DENIED; /* Other mechanisms not supported. */
|
||||
}
|
||||
|
||||
if(!result) {
|
||||
if(initresp &&
|
||||
l + strlen(mech) <= 512 - 8) { /* AUTH <mech> ...<crlf> */
|
||||
result = Curl_pp_sendf(&smtpc->pp, "AUTH %s %s", mech, initresp);
|
||||
|
||||
if(!result)
|
||||
state(conn, state2);
|
||||
}
|
||||
else {
|
||||
result = Curl_pp_sendf(&smtpc->pp, "AUTH %s", mech);
|
||||
|
||||
if(!result)
|
||||
state(conn, state1);
|
||||
}
|
||||
Curl_safefree(initresp);
|
||||
result = Curl_pp_sendf(&smtpc->pp, "AUTH %s", mech);
|
||||
|
||||
if(!result)
|
||||
state(conn, state1);
|
||||
}
|
||||
Curl_safefree(initresp);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -478,7 +507,7 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(smtpcode != 220) {
|
||||
if(data->set.ftp_ssl != CURLUSESSL_TRY) {
|
||||
if(data->set.use_ssl != CURLUSESSL_TRY) {
|
||||
failf(data, "STARTTLS denied. %c", smtpcode);
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
@@ -498,6 +527,7 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -527,7 +557,7 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn,
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(smtpcode/100 != 2) {
|
||||
if((data->set.ftp_ssl <= CURLUSESSL_TRY || conn->ssl[FIRSTSOCKET].use) &&
|
||||
if((data->set.use_ssl <= CURLUSESSL_TRY || conn->ssl[FIRSTSOCKET].use) &&
|
||||
!conn->bits.user_passwd)
|
||||
result = smtp_state_helo(conn);
|
||||
else {
|
||||
@@ -535,7 +565,7 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn,
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
}
|
||||
else if(data->set.ftp_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
/* We don't have a SSL/TLS connection yet, but SSL is requested. Switch
|
||||
to TLS connection now */
|
||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "STARTTLS");
|
||||
@@ -565,6 +595,7 @@ static CURLcode smtp_state_helo_resp(struct connectdata *conn,
|
||||
/* end the connect phase */
|
||||
state(conn, SMTP_STOP);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -575,8 +606,8 @@ static CURLcode smtp_state_authplain_resp(struct connectdata *conn,
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
size_t l = 0;
|
||||
char * plainauth = NULL;
|
||||
size_t len = 0;
|
||||
char *plainauth = NULL;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
@@ -585,7 +616,7 @@ static CURLcode smtp_state_authplain_resp(struct connectdata *conn,
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
else {
|
||||
result = smtp_auth_plain_data(conn, &plainauth, &l);
|
||||
result = smtp_auth_plain_data(conn, &plainauth, &len);
|
||||
|
||||
if(!result) {
|
||||
if(plainauth) {
|
||||
@@ -608,8 +639,8 @@ static CURLcode smtp_state_authlogin_resp(struct connectdata *conn,
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
size_t l = 0;
|
||||
char * authuser = NULL;
|
||||
size_t len = 0;
|
||||
char *authuser = NULL;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
@@ -618,7 +649,7 @@ static CURLcode smtp_state_authlogin_resp(struct connectdata *conn,
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
else {
|
||||
result = smtp_auth_login_user(conn, &authuser, &l);
|
||||
result = smtp_auth_login_user(conn, &authuser, &len);
|
||||
|
||||
if(!result) {
|
||||
if(authuser) {
|
||||
@@ -642,7 +673,7 @@ static CURLcode smtp_state_authpasswd_resp(struct connectdata *conn,
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
size_t plen;
|
||||
size_t l = 0;
|
||||
size_t len = 0;
|
||||
char *authpasswd = NULL;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
@@ -657,7 +688,7 @@ static CURLcode smtp_state_authpasswd_resp(struct connectdata *conn,
|
||||
if(!plen)
|
||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "=");
|
||||
else {
|
||||
result = Curl_base64_encode(data, conn->passwd, plen, &authpasswd, &l);
|
||||
result = Curl_base64_encode(data, conn->passwd, plen, &authpasswd, &len);
|
||||
|
||||
if(!result) {
|
||||
if(authpasswd) {
|
||||
@@ -686,9 +717,9 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,
|
||||
char * chlg64 = data->state.buffer;
|
||||
unsigned char * chlg;
|
||||
size_t chlglen;
|
||||
size_t l = 0;
|
||||
char * rplyb64 = NULL;
|
||||
HMAC_context * ctxt;
|
||||
size_t len = 0;
|
||||
char *rplyb64 = NULL;
|
||||
HMAC_context *ctxt;
|
||||
unsigned char digest[16];
|
||||
char reply[MAX_CURL_USER_LENGTH + 32 /* 2 * size of MD5 digest */ + 1];
|
||||
|
||||
@@ -707,13 +738,13 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,
|
||||
chlglen = 0;
|
||||
|
||||
if(*chlg64 != '=') {
|
||||
for(l = strlen(chlg64); l--;)
|
||||
if(chlg64[l] != '\r' && chlg64[l] != '\n' && chlg64[l] != ' ' &&
|
||||
chlg64[l] != '\t')
|
||||
for(len = strlen(chlg64); len--;)
|
||||
if(chlg64[len] != '\r' && chlg64[len] != '\n' && chlg64[len] != ' ' &&
|
||||
chlg64[len] != '\t')
|
||||
break;
|
||||
|
||||
if(++l) {
|
||||
chlg64[l] = '\0';
|
||||
if(++len) {
|
||||
chlg64[len] = '\0';
|
||||
|
||||
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
|
||||
if(result)
|
||||
@@ -747,7 +778,7 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,
|
||||
digest[12], digest[13], digest[14], digest[15]);
|
||||
|
||||
/* Encode it to base64 and send it. */
|
||||
result = Curl_base64_encode(data, reply, 0, &rplyb64, &l);
|
||||
result = Curl_base64_encode(data, reply, 0, &rplyb64, &len);
|
||||
|
||||
if(!result) {
|
||||
if(rplyb64) {
|
||||
@@ -764,6 +795,79 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_NTLM
|
||||
/* for the AUTH NTLM (without initial response) response. */
|
||||
static CURLcode smtp_state_auth_ntlm_resp(struct connectdata *conn,
|
||||
int smtpcode,
|
||||
smtpstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
char *type1msg = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(smtpcode != 334) {
|
||||
failf(data, "Access denied: %d", smtpcode);
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
else {
|
||||
result = smtp_auth_ntlm_type1_message(conn, &type1msg, &len);
|
||||
|
||||
if(!result) {
|
||||
if(type1msg) {
|
||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", type1msg);
|
||||
|
||||
if(!result)
|
||||
state(conn, SMTP_AUTHNTLM_TYPE2MSG);
|
||||
}
|
||||
Curl_safefree(type1msg);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* for the NTLM type-2 response (sent in reponse to our type-1 message). */
|
||||
static CURLcode smtp_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
|
||||
int smtpcode,
|
||||
smtpstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
char *type3msg = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(smtpcode != 334) {
|
||||
failf(data, "Access denied: %d", smtpcode);
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
else {
|
||||
result = Curl_ntlm_decode_type2_message(data, data->state.buffer + 4,
|
||||
&conn->ntlm);
|
||||
if(!result) {
|
||||
result = Curl_ntlm_create_type3_message(conn->data, conn->user,
|
||||
conn->passwd, &conn->ntlm,
|
||||
&type3msg, &len);
|
||||
if(!result) {
|
||||
if(type3msg) {
|
||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", type3msg);
|
||||
|
||||
if(!result)
|
||||
state(conn, SMTP_AUTH);
|
||||
}
|
||||
Curl_safefree(type3msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* for final responses to AUTH sequences. */
|
||||
static CURLcode smtp_state_auth_resp(struct connectdata *conn,
|
||||
int smtpcode,
|
||||
@@ -787,20 +891,49 @@ static CURLcode smtp_state_auth_resp(struct connectdata *conn,
|
||||
/* start the DO phase */
|
||||
static CURLcode smtp_mail(struct connectdata *conn)
|
||||
{
|
||||
char *from = NULL;
|
||||
char *size = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
/* send MAIL FROM */
|
||||
if(data->set.str[STRING_MAIL_FROM][0] == '<')
|
||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "MAIL FROM:%s",
|
||||
data->set.str[STRING_MAIL_FROM]);
|
||||
/* calculate the FROM parameter */
|
||||
if(!data->set.str[STRING_MAIL_FROM])
|
||||
/* null reverse-path, RFC-2821, sect. 3.7 */
|
||||
from = strdup("<>");
|
||||
else if(data->set.str[STRING_MAIL_FROM][0] == '<')
|
||||
from = aprintf("%s", data->set.str[STRING_MAIL_FROM]);
|
||||
else
|
||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "MAIL FROM:<%s>",
|
||||
data->set.str[STRING_MAIL_FROM]);
|
||||
from = aprintf("<%s>", data->set.str[STRING_MAIL_FROM]);
|
||||
|
||||
if(!from)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* calculate the optional SIZE parameter */
|
||||
if(conn->data->set.infilesize > 0) {
|
||||
size = aprintf("%" FORMAT_OFF_T, data->set.infilesize);
|
||||
|
||||
if(!size) {
|
||||
Curl_safefree(from);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
/* send MAIL FROM */
|
||||
if(!size)
|
||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "MAIL FROM:%s", from);
|
||||
else
|
||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "MAIL FROM:%s SIZE=%s",
|
||||
from, size);
|
||||
|
||||
Curl_safefree(size);
|
||||
Curl_safefree(from);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
state(conn, SMTP_MAIL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -820,6 +953,7 @@ static CURLcode smtp_rcpt_to(struct connectdata *conn)
|
||||
if(!result)
|
||||
state(conn, SMTP_RCPT);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -880,6 +1014,7 @@ static CURLcode smtp_state_rcpt_resp(struct connectdata *conn,
|
||||
|
||||
state(conn, SMTP_DATA);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -920,6 +1055,7 @@ static CURLcode smtp_state_postdata_resp(struct connectdata *conn,
|
||||
result = CURLE_RECV_ERROR;
|
||||
|
||||
state(conn, SMTP_STOP);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -989,6 +1125,17 @@ static CURLcode smtp_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef USE_NTLM
|
||||
case SMTP_AUTHNTLM:
|
||||
result = smtp_state_auth_ntlm_resp(conn, smtpcode, smtpc->state);
|
||||
break;
|
||||
|
||||
case SMTP_AUTHNTLM_TYPE2MSG:
|
||||
result = smtp_state_auth_ntlm_type2msg_resp(conn, smtpcode,
|
||||
smtpc->state);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SMTP_AUTH:
|
||||
result = smtp_state_auth_resp(conn, smtpcode, smtpc->state);
|
||||
break;
|
||||
@@ -1017,6 +1164,7 @@ static CURLcode smtp_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1096,7 +1244,7 @@ static CURLcode smtp_connect(struct connectdata *conn,
|
||||
struct pingpong *pp = &smtpc->pp;
|
||||
const char *path = conn->data->state.path;
|
||||
int len;
|
||||
char localhost[1024 + 1];
|
||||
char localhost[HOSTNAME_MAX + 1];
|
||||
|
||||
*done = FALSE; /* default to not done yet */
|
||||
|
||||
@@ -1374,6 +1522,13 @@ static CURLcode smtp_disconnect(struct connectdata *conn,
|
||||
|
||||
Curl_pp_disconnect(&smtpc->pp);
|
||||
|
||||
#ifdef USE_NTLM
|
||||
/* Cleanup the ntlm structure */
|
||||
if(smtpc->authused == SMTP_AUTH_NTLM) {
|
||||
Curl_ntlm_sspi_cleanup(&conn->ntlm);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This won't already be freed in some error cases */
|
||||
Curl_safefree(smtpc->domain);
|
||||
smtpc->domain = NULL;
|
||||
@@ -1411,6 +1566,7 @@ static CURLcode smtp_doing(struct connectdata *conn,
|
||||
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1509,35 +1665,36 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
|
||||
}
|
||||
/* This loop can be improved by some kind of Boyer-Moore style of
|
||||
approach but that is saved for later... */
|
||||
for(i = 0, si = 0; i < nread; i++, si++) {
|
||||
ssize_t left = nread - i;
|
||||
for(i = 0, si = 0; i < nread; i++) {
|
||||
|
||||
if(left >= (ssize_t)(SMTP_EOB_LEN - smtpc->eob)) {
|
||||
if(!memcmp(SMTP_EOB + smtpc->eob, &data->req.upload_fromhere[i],
|
||||
SMTP_EOB_LEN - smtpc->eob)) {
|
||||
/* It matched, copy the replacement data to the target buffer
|
||||
instead. Note that the replacement does not contain the
|
||||
trailing CRLF but we instead continue to match on that one
|
||||
to deal with repeated sequences. Like CRLF.CRLF.CRLF etc
|
||||
*/
|
||||
memcpy(&data->state.scratch[si], SMTP_EOB_REPL,
|
||||
SMTP_EOB_REPL_LEN);
|
||||
si += SMTP_EOB_REPL_LEN - 1; /* minus one since the for() increments
|
||||
it */
|
||||
i += SMTP_EOB_LEN - smtpc->eob - 1 - 2;
|
||||
smtpc->eob = 0; /* start over */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if(!memcmp(SMTP_EOB + smtpc->eob, &data->req.upload_fromhere[i],
|
||||
left)) {
|
||||
/* the last piece of the data matches the EOB so we can't send that
|
||||
until we know the rest of it */
|
||||
smtpc->eob += left;
|
||||
break;
|
||||
if(SMTP_EOB[smtpc->eob] == data->req.upload_fromhere[i])
|
||||
smtpc->eob++;
|
||||
else if(smtpc->eob) {
|
||||
/* previously a substring matched, output that first */
|
||||
memcpy(&data->state.scratch[si], SMTP_EOB, smtpc->eob);
|
||||
si += smtpc->eob;
|
||||
|
||||
/* then compare the first byte */
|
||||
if(SMTP_EOB[0] == data->req.upload_fromhere[i])
|
||||
smtpc->eob = 1;
|
||||
else
|
||||
smtpc->eob = 0;
|
||||
}
|
||||
|
||||
data->state.scratch[si] = data->req.upload_fromhere[i];
|
||||
if(SMTP_EOB_LEN == smtpc->eob) {
|
||||
/* It matched, copy the replacement data to the target buffer
|
||||
instead. Note that the replacement does not contain the
|
||||
trailing CRLF but we instead continue to match on that one
|
||||
to deal with repeated sequences. Like CRLF.CRLF.CRLF etc
|
||||
*/
|
||||
memcpy(&data->state.scratch[si], SMTP_EOB_REPL,
|
||||
SMTP_EOB_REPL_LEN);
|
||||
si += SMTP_EOB_REPL_LEN;
|
||||
smtpc->eob = 2; /* start over at two bytes */
|
||||
}
|
||||
else if(!smtpc->eob)
|
||||
data->state.scratch[si++] = data->req.upload_fromhere[i];
|
||||
|
||||
} /* for() */
|
||||
|
||||
if(si != nread) {
|
||||
@@ -1550,6 +1707,7 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
|
||||
/* set the new amount too */
|
||||
data->req.upload_present = nread;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
@@ -40,6 +40,8 @@ typedef enum {
|
||||
SMTP_AUTHLOGIN,
|
||||
SMTP_AUTHPASSWD,
|
||||
SMTP_AUTHCRAM,
|
||||
SMTP_AUTHNTLM,
|
||||
SMTP_AUTHNTLM_TYPE2MSG,
|
||||
SMTP_AUTH,
|
||||
SMTP_MAIL, /* MAIL FROM */
|
||||
SMTP_RCPT, /* RCPT TO */
|
||||
@@ -57,6 +59,7 @@ struct smtp_conn {
|
||||
size_t eob; /* number of bytes of the EOB (End Of Body) that has been
|
||||
received thus far */
|
||||
unsigned int authmechs; /* Accepted authentication methods. */
|
||||
unsigned int authused; /* Authentication method used for the connection */
|
||||
smtpstate state; /* always use smtp.c:state() to change state! */
|
||||
struct curl_slist *rcpt;
|
||||
bool ssldone; /* is connect() over SSL done? only relevant in multi mode */
|
||||
@@ -69,6 +72,7 @@ struct smtp_conn {
|
||||
#define SMTP_AUTH_DIGEST_MD5 0x0008
|
||||
#define SMTP_AUTH_GSSAPI 0x0010
|
||||
#define SMTP_AUTH_EXTERNAL 0x0020
|
||||
#define SMTP_AUTH_NTLM 0x0040
|
||||
|
||||
extern const struct Curl_handler Curl_handler_smtp;
|
||||
extern const struct Curl_handler Curl_handler_smtps;
|
||||
|
@@ -165,6 +165,7 @@ const struct Curl_handler Curl_handler_scp = {
|
||||
scp_doing, /* doing */
|
||||
ssh_getsock, /* proto_getsock */
|
||||
ssh_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ssh_perform_getsock, /* perform_getsock */
|
||||
scp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -189,6 +190,7 @@ const struct Curl_handler Curl_handler_sftp = {
|
||||
sftp_doing, /* doing */
|
||||
ssh_getsock, /* proto_getsock */
|
||||
ssh_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ssh_perform_getsock, /* perform_getsock */
|
||||
sftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
|
54
lib/sslgen.c
54
lib/sslgen.c
@@ -62,6 +62,7 @@
|
||||
#include "url.h"
|
||||
#include "curl_memory.h"
|
||||
#include "progress.h"
|
||||
#include "share.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -236,6 +237,10 @@ int Curl_ssl_getsessionid(struct connectdata *conn,
|
||||
/* session ID re-use is disabled */
|
||||
return TRUE;
|
||||
|
||||
/* Lock for reading if shared */
|
||||
if(data->share && data->share->sslsession == data->state.session)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SHARED);
|
||||
|
||||
for(i=0; i< data->set.ssl.numsessions; i++) {
|
||||
check = &data->state.session[i];
|
||||
if(!check->sessionid)
|
||||
@@ -254,13 +259,19 @@ int Curl_ssl_getsessionid(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
*ssl_sessionid = NULL;
|
||||
|
||||
/* Unlock for reading */
|
||||
if(data->share && data->share->sslsession == data->state.session)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Kill a single session ID entry in the cache.
|
||||
*/
|
||||
static int kill_session(struct curl_ssl_session *session)
|
||||
int Curl_ssl_kill_session(struct curl_ssl_session *session)
|
||||
{
|
||||
if(session->sessionid) {
|
||||
/* defensive check */
|
||||
@@ -288,14 +299,23 @@ static int kill_session(struct curl_ssl_session *session)
|
||||
void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i< conn->data->set.ssl.numsessions; i++) {
|
||||
struct curl_ssl_session *check = &conn->data->state.session[i];
|
||||
struct SessionHandle *data=conn->data;
|
||||
|
||||
if(data->share && data->share->sslsession == data->state.session)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION,
|
||||
CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
for(i=0; i< data->set.ssl.numsessions; i++) {
|
||||
struct curl_ssl_session *check = &data->state.session[i];
|
||||
|
||||
if(check->sessionid == ssl_sessionid) {
|
||||
kill_session(check);
|
||||
Curl_ssl_kill_session(check);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(data->share && data->share->sslsession == data->state.session)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -325,6 +345,10 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
|
||||
/* Now we should add the session ID and the host name to the cache, (remove
|
||||
the oldest if necessary) */
|
||||
|
||||
/* If using shared SSL session, lock! */
|
||||
if(data->share && data->share->sslsession == data->state.session)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
/* find an empty slot for us, or find the oldest */
|
||||
for(i=1; (i<data->set.ssl.numsessions) &&
|
||||
data->state.session[i].sessionid; i++) {
|
||||
@@ -335,7 +359,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
|
||||
}
|
||||
if(i == data->set.ssl.numsessions)
|
||||
/* cache is full, we must "kill" the oldest entry! */
|
||||
kill_session(store);
|
||||
Curl_ssl_kill_session(store);
|
||||
else
|
||||
store = &data->state.session[i]; /* use this slot */
|
||||
|
||||
@@ -349,6 +373,11 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
|
||||
store->name = clone_host; /* clone host name */
|
||||
store->remote_port = conn->remote_port; /* port number */
|
||||
|
||||
|
||||
/* Unlock */
|
||||
if(data->share && data->share->sslsession == data->state.session)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
|
||||
|
||||
if(!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config)) {
|
||||
store->sessionid = NULL; /* let caller free sessionid */
|
||||
free(clone_host);
|
||||
@@ -363,14 +392,20 @@ void Curl_ssl_close_all(struct SessionHandle *data)
|
||||
{
|
||||
long i;
|
||||
/* kill the session ID cache */
|
||||
if(data->state.session) {
|
||||
if(data->state.session &&
|
||||
!(data->share && data->share->sslsession == data->state.session)) {
|
||||
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
for(i=0; i< data->set.ssl.numsessions; i++)
|
||||
/* the single-killer function handles empty table slots */
|
||||
kill_session(&data->state.session[i]);
|
||||
Curl_ssl_kill_session(&data->state.session[i]);
|
||||
|
||||
/* free the cache data */
|
||||
free(data->state.session);
|
||||
data->state.session = NULL;
|
||||
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
|
||||
}
|
||||
|
||||
curlssl_close_all(data);
|
||||
@@ -469,9 +504,12 @@ void Curl_ssl_free_certinfo(struct SessionHandle *data)
|
||||
struct curl_certinfo *ci = &data->info.certs;
|
||||
if(ci->num_of_certs) {
|
||||
/* free all individual lists used */
|
||||
for(i=0; i<ci->num_of_certs; i++)
|
||||
for(i=0; i<ci->num_of_certs; i++) {
|
||||
curl_slist_free_all(ci->certinfo[i]);
|
||||
ci->certinfo[i] = NULL;
|
||||
}
|
||||
free(ci->certinfo); /* free the actual array too */
|
||||
ci->certinfo = NULL;
|
||||
ci->num_of_certs = 0;
|
||||
}
|
||||
}
|
||||
|
@@ -64,6 +64,8 @@ int Curl_ssl_getsessionid(struct connectdata *conn,
|
||||
CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
|
||||
void *ssl_sessionid,
|
||||
size_t idsize);
|
||||
/* Kill a single session ID entry in the cache */
|
||||
int Curl_ssl_kill_session(struct curl_ssl_session *session);
|
||||
/* delete a session from the cache */
|
||||
void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid);
|
||||
|
||||
@@ -88,6 +90,7 @@ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid);
|
||||
#define Curl_ssl_check_cxn(x) 0
|
||||
#define Curl_ssl_free_certinfo(x) Curl_nop_stmt
|
||||
#define Curl_ssl_connect_nonblocking(x,y,z) CURLE_NOT_BUILT_IN
|
||||
#define Curl_ssl_kill_session(x) 0
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SSLGEN_H */
|
||||
|
50
lib/ssluse.c
50
lib/ssluse.c
@@ -123,6 +123,10 @@
|
||||
#define X509_STORE_set_flags(x,y) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
#define HAVE_ERR_REMOVE_THREAD_STATE 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Number of bytes to read from the random number seed file. This must be
|
||||
* a finite value (because some entropy "files" like /dev/urandom have
|
||||
@@ -697,21 +701,28 @@ int Curl_ossl_init(void)
|
||||
/* Global cleanup */
|
||||
void Curl_ossl_cleanup(void)
|
||||
{
|
||||
/* Free the SSL error strings */
|
||||
ERR_free_strings();
|
||||
|
||||
/* EVP_cleanup() removes all ciphers and digests from the table. */
|
||||
/* Free ciphers and digests lists */
|
||||
EVP_cleanup();
|
||||
|
||||
#ifdef HAVE_ENGINE_CLEANUP
|
||||
/* Free engine list */
|
||||
ENGINE_cleanup();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
||||
/* this function was not present in 0.9.6b, but was added sometimes
|
||||
later */
|
||||
/* Free OpenSSL ex_data table */
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
#endif
|
||||
|
||||
/* Free OpenSSL error strings */
|
||||
ERR_free_strings();
|
||||
|
||||
/* Free thread local error state, destroying hash upon zero refcount */
|
||||
#ifdef HAVE_ERR_REMOVE_THREAD_STATE
|
||||
ERR_remove_thread_state(NULL);
|
||||
#else
|
||||
ERR_remove_state(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -810,18 +821,16 @@ struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
|
||||
{
|
||||
struct curl_slist *list = NULL;
|
||||
#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
|
||||
struct curl_slist *beg = NULL;
|
||||
struct curl_slist *beg;
|
||||
ENGINE *e;
|
||||
|
||||
for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
|
||||
list = curl_slist_append(list, ENGINE_get_id(e));
|
||||
if(list == NULL) {
|
||||
curl_slist_free_all(beg);
|
||||
beg = curl_slist_append(list, ENGINE_get_id(e));
|
||||
if(!beg) {
|
||||
curl_slist_free_all(list);
|
||||
return NULL;
|
||||
}
|
||||
else if(beg == NULL) {
|
||||
beg = list;
|
||||
}
|
||||
list = beg;
|
||||
}
|
||||
#endif
|
||||
(void) data;
|
||||
@@ -962,17 +971,6 @@ void Curl_ossl_session_free(void *ptr)
|
||||
*/
|
||||
int Curl_ossl_close_all(struct SessionHandle *data)
|
||||
{
|
||||
/*
|
||||
ERR_remove_state() frees the error queue associated with
|
||||
thread pid. If pid == 0, the current thread will have its
|
||||
error queue removed.
|
||||
|
||||
Since error queue data structures are allocated
|
||||
automatically for new threads, they must be freed when
|
||||
threads are terminated in oder to avoid memory leaks.
|
||||
*/
|
||||
ERR_remove_state(0);
|
||||
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
if(data->state.engine) {
|
||||
ENGINE_finish(data->state.engine);
|
||||
@@ -1857,15 +1855,15 @@ static CURLcode push_certinfo_len(struct SessionHandle *data,
|
||||
equivalent of curl_slist_append but doesn't strdup() the given data as
|
||||
like in this place the extra malloc/free is totally pointless */
|
||||
nl = curl_slist_append(ci->certinfo[certnum], output);
|
||||
free(output);
|
||||
if(!nl) {
|
||||
curl_slist_free_all(ci->certinfo[certnum]);
|
||||
ci->certinfo[certnum] = NULL;
|
||||
res = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
ci->certinfo[certnum] = nl;
|
||||
|
||||
free(output);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@@ -384,6 +384,9 @@ curl_share_strerror(CURLSHcode error)
|
||||
case CURLSHE_NOMEM:
|
||||
return "Out of memory";
|
||||
|
||||
case CURLSHE_NOT_BUILT_IN:
|
||||
return "Feature not enabled in this library";
|
||||
|
||||
case CURLSHE_LAST:
|
||||
break;
|
||||
}
|
||||
|
37
lib/telnet.c
37
lib/telnet.c
@@ -182,6 +182,7 @@ const struct Curl_handler Curl_handler_telnet = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -763,18 +764,24 @@ static void printsub(struct SessionHandle *data,
|
||||
static CURLcode check_telnet_options(struct connectdata *conn)
|
||||
{
|
||||
struct curl_slist *head;
|
||||
struct curl_slist *beg;
|
||||
char option_keyword[128];
|
||||
char option_arg[256];
|
||||
char *buf;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct TELNET *tn = (struct TELNET *)conn->data->state.proto.telnet;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
/* Add the user name as an environment variable if it
|
||||
was given on the command line */
|
||||
if(conn->bits.user_passwd) {
|
||||
snprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user);
|
||||
tn->telnet_vars = curl_slist_append(tn->telnet_vars, option_arg);
|
||||
|
||||
beg = curl_slist_append(tn->telnet_vars, option_arg);
|
||||
if(!beg) {
|
||||
curl_slist_free_all(tn->telnet_vars);
|
||||
tn->telnet_vars = NULL;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
tn->telnet_vars = beg;
|
||||
tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
|
||||
}
|
||||
|
||||
@@ -800,24 +807,33 @@ static CURLcode check_telnet_options(struct connectdata *conn)
|
||||
|
||||
/* Environment variable */
|
||||
if(Curl_raw_equal(option_keyword, "NEW_ENV")) {
|
||||
buf = strdup(option_arg);
|
||||
if(!buf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
tn->telnet_vars = curl_slist_append(tn->telnet_vars, buf);
|
||||
beg = curl_slist_append(tn->telnet_vars, option_arg);
|
||||
if(!beg) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
tn->telnet_vars = beg;
|
||||
tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
|
||||
continue;
|
||||
}
|
||||
|
||||
failf(data, "Unknown telnet option %s", head->data);
|
||||
return CURLE_UNKNOWN_TELNET_OPTION;
|
||||
result = CURLE_UNKNOWN_TELNET_OPTION;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
failf(data, "Syntax error in telnet option: %s", head->data);
|
||||
return CURLE_TELNET_OPTION_SYNTAX;
|
||||
result = CURLE_TELNET_OPTION_SYNTAX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
if(result) {
|
||||
curl_slist_free_all(tn->telnet_vars);
|
||||
tn->telnet_vars = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1109,6 +1125,7 @@ static CURLcode telnet_done(struct connectdata *conn,
|
||||
(void)premature; /* not used */
|
||||
|
||||
curl_slist_free_all(tn->telnet_vars);
|
||||
tn->telnet_vars = NULL;
|
||||
|
||||
free(conn->data->state.proto.telnet);
|
||||
conn->data->state.proto.telnet = NULL;
|
||||
|
20
lib/tftp.c
20
lib/tftp.c
@@ -184,6 +184,7 @@ const struct Curl_handler Curl_handler_tftp = {
|
||||
tftp_doing, /* doing */
|
||||
tftp_getsock, /* proto_getsock */
|
||||
tftp_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
tftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -248,11 +249,11 @@ static CURLcode tftp_set_timeouts(tftp_state_data_t *state)
|
||||
|
||||
state->max_time = state->start_time+maxtime;
|
||||
|
||||
/* Set per-block timeout to 10% of total */
|
||||
timeout = maxtime/10 ;
|
||||
/* Set per-block timeout to total */
|
||||
timeout = maxtime;
|
||||
|
||||
/* Average reposting an ACK after 15 seconds */
|
||||
state->retry_max = (int)timeout/15;
|
||||
/* Average reposting an ACK after 5 seconds */
|
||||
state->retry_max = (int)timeout/5;
|
||||
}
|
||||
/* But bound the total number */
|
||||
if(state->retry_max<3)
|
||||
@@ -591,15 +592,10 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
|
||||
/* Is this the block we expect? */
|
||||
rblock = getrpacketblock(&state->rpacket);
|
||||
if(NEXT_BLOCKNUM(state->block) != rblock) {
|
||||
/* No, log it, up the retry count and fail if over the limit */
|
||||
/* No, log it */
|
||||
infof(data,
|
||||
"Received unexpected DATA packet block %d\n", rblock);
|
||||
state->retries++;
|
||||
if(state->retries > state->retry_max) {
|
||||
failf(data, "tftp_rx: giving up waiting for block %d",
|
||||
NEXT_BLOCKNUM(state->block));
|
||||
return CURLE_TFTP_ILLEGAL;
|
||||
}
|
||||
"Received unexpected DATA packet block %d, expecting block %d\n",
|
||||
rblock, NEXT_BLOCKNUM(state->block));
|
||||
break;
|
||||
}
|
||||
/* This is the expected block. Reset counters and ACK it. */
|
||||
|
@@ -1699,26 +1699,37 @@ static char *concat_url(const char *base, const char *relurl)
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* We got a new absolute path for this server, cut off from the
|
||||
first slash */
|
||||
pathsep = strchr(protsep, '/');
|
||||
if(pathsep) {
|
||||
/* When people use badly formatted URLs, such as
|
||||
"http://www.url.com?dir=/home/daniel" we must not use the first
|
||||
slash, if there's a ?-letter before it! */
|
||||
char *sep = strchr(protsep, '?');
|
||||
if(sep && (sep < pathsep))
|
||||
pathsep = sep;
|
||||
*pathsep=0;
|
||||
/* We got a new absolute path for this server */
|
||||
|
||||
if((relurl[0] == '/') && (relurl[1] == '/')) {
|
||||
/* the new URL starts with //, just keep the protocol part from the
|
||||
original one */
|
||||
*protsep=0;
|
||||
useurl = &relurl[2]; /* we keep the slashes from the original, so we
|
||||
skip the new ones */
|
||||
}
|
||||
else {
|
||||
/* There was no slash. Now, since we might be operating on a badly
|
||||
formatted URL, such as "http://www.url.com?id=2380" which doesn't
|
||||
use a slash separator as it is supposed to, we need to check for a
|
||||
?-letter as well! */
|
||||
pathsep = strchr(protsep, '?');
|
||||
if(pathsep)
|
||||
/* cut off the original URL from the first slash, or deal with URLs
|
||||
without slash */
|
||||
pathsep = strchr(protsep, '/');
|
||||
if(pathsep) {
|
||||
/* When people use badly formatted URLs, such as
|
||||
"http://www.url.com?dir=/home/daniel" we must not use the first
|
||||
slash, if there's a ?-letter before it! */
|
||||
char *sep = strchr(protsep, '?');
|
||||
if(sep && (sep < pathsep))
|
||||
pathsep = sep;
|
||||
*pathsep=0;
|
||||
}
|
||||
else {
|
||||
/* There was no slash. Now, since we might be operating on a badly
|
||||
formatted URL, such as "http://www.url.com?id=2380" which doesn't
|
||||
use a slash separator as it is supposed to, we need to check for a
|
||||
?-letter as well! */
|
||||
pathsep = strchr(protsep, '?');
|
||||
if(pathsep)
|
||||
*pathsep=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1731,8 +1742,8 @@ static char *concat_url(const char *base, const char *relurl)
|
||||
|
||||
urllen = strlen(url_clone);
|
||||
|
||||
newest = malloc( urllen + 1 + /* possible slash */
|
||||
newlen + 1 /* zero byte */);
|
||||
newest = malloc(urllen + 1 + /* possible slash */
|
||||
newlen + 1 /* zero byte */);
|
||||
|
||||
if(!newest) {
|
||||
free(url_clone); /* don't leak this */
|
||||
@@ -1795,15 +1806,14 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
||||
when we get the next URL. We pick the ->url field, which may or may
|
||||
not be 100% correct */
|
||||
|
||||
if(data->change.referer_alloc)
|
||||
/* If we already have an allocated referer, free this first */
|
||||
free(data->change.referer);
|
||||
if(data->change.referer_alloc) {
|
||||
Curl_safefree(data->change.referer);
|
||||
data->change.referer_alloc = FALSE;
|
||||
}
|
||||
|
||||
data->change.referer = strdup(data->change.url);
|
||||
if(!data->change.referer) {
|
||||
data->change.referer_alloc = FALSE;
|
||||
if(!data->change.referer)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
data->change.referer_alloc = TRUE; /* yes, free this later */
|
||||
}
|
||||
}
|
||||
@@ -1850,12 +1860,13 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
||||
if(disallowport)
|
||||
data->state.allow_port = FALSE;
|
||||
|
||||
if(data->change.url_alloc)
|
||||
free(data->change.url);
|
||||
else
|
||||
data->change.url_alloc = TRUE; /* the URL is allocated */
|
||||
if(data->change.url_alloc) {
|
||||
Curl_safefree(data->change.url);
|
||||
data->change.url_alloc = FALSE;
|
||||
}
|
||||
|
||||
data->change.url = newurl;
|
||||
data->change.url_alloc = TRUE;
|
||||
newurl = NULL; /* don't free! */
|
||||
|
||||
infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
|
||||
@@ -1980,12 +1991,17 @@ connect_host(struct SessionHandle *data,
|
||||
/* Now, if async is TRUE here, we need to wait for the name
|
||||
to resolve */
|
||||
res = Curl_resolver_wait_resolv(*conn, NULL);
|
||||
if(CURLE_OK == res)
|
||||
if(CURLE_OK == res) {
|
||||
/* Resolved, continue with the connection */
|
||||
res = Curl_async_resolved(*conn, &protocol_done);
|
||||
else
|
||||
if(res)
|
||||
*conn = NULL;
|
||||
}
|
||||
else {
|
||||
/* if we can't resolve, we kill this "connection" now */
|
||||
(void)Curl_disconnect(*conn, /* dead_connection */ FALSE);
|
||||
*conn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
141
lib/url.c
141
lib/url.c
@@ -136,6 +136,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out);
|
||||
static long ConnectionKillOne(struct SessionHandle *data);
|
||||
static void conn_free(struct connectdata *conn);
|
||||
static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
|
||||
static CURLcode do_init(struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* Protocol table.
|
||||
@@ -245,6 +246,7 @@ static const struct Curl_handler Curl_handler_dummy = {
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
@@ -275,10 +277,7 @@ static CURLcode setstropt(char **charp, char * s)
|
||||
/* Release the previous storage at `charp' and replace by a dynamic storage
|
||||
copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
|
||||
|
||||
if(*charp) {
|
||||
free(*charp);
|
||||
*charp = (char *) NULL;
|
||||
}
|
||||
Curl_safefree(*charp);
|
||||
|
||||
if(s) {
|
||||
s = strdup(s);
|
||||
@@ -457,6 +456,7 @@ CURLcode Curl_close(struct SessionHandle *data)
|
||||
|
||||
/* free the connection cache if allocated privately */
|
||||
Curl_rm_connc(data->state.connc);
|
||||
data->state.connc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,6 +478,8 @@ CURLcode Curl_close(struct SessionHandle *data)
|
||||
|
||||
/* Free the pathbuffer */
|
||||
Curl_safefree(data->state.pathbuffer);
|
||||
data->state.path = NULL;
|
||||
|
||||
Curl_safefree(data->state.proto.generic);
|
||||
|
||||
/* Close down all open SSL info and sessions */
|
||||
@@ -486,11 +488,17 @@ CURLcode Curl_close(struct SessionHandle *data)
|
||||
Curl_safefree(data->state.scratch);
|
||||
Curl_ssl_free_certinfo(data);
|
||||
|
||||
if(data->change.referer_alloc)
|
||||
free(data->change.referer);
|
||||
if(data->change.referer_alloc) {
|
||||
Curl_safefree(data->change.referer);
|
||||
data->change.referer_alloc = FALSE;
|
||||
}
|
||||
data->change.referer = NULL;
|
||||
|
||||
if(data->change.url_alloc)
|
||||
free(data->change.url);
|
||||
if(data->change.url_alloc) {
|
||||
Curl_safefree(data->change.url);
|
||||
data->change.url_alloc = FALSE;
|
||||
}
|
||||
data->change.url = NULL;
|
||||
|
||||
Curl_safefree(data->state.headerbuff);
|
||||
|
||||
@@ -585,8 +593,10 @@ CURLcode Curl_ch_connc(struct SessionHandle *data,
|
||||
NOTE: for conncache_multi cases we must make sure that we only
|
||||
close handles not in use.
|
||||
*/
|
||||
for(i=newamount; i< c->num; i++)
|
||||
for(i=newamount; i< c->num; i++) {
|
||||
Curl_disconnect(c->connects[i], /* dead_connection */ FALSE);
|
||||
c->connects[i] = NULL;
|
||||
}
|
||||
|
||||
/* If the most recent connection is no longer valid, mark it
|
||||
invalid. */
|
||||
@@ -617,13 +627,19 @@ CURLcode Curl_ch_connc(struct SessionHandle *data,
|
||||
curl_multi_cleanup(). */
|
||||
void Curl_rm_connc(struct conncache *c)
|
||||
{
|
||||
if(!c)
|
||||
return;
|
||||
|
||||
if(c->connects) {
|
||||
long i;
|
||||
for(i = 0; i < c->num; ++i)
|
||||
for(i = 0; i < c->num; ++i) {
|
||||
conn_free(c->connects[i]);
|
||||
|
||||
c->connects[i] = NULL;
|
||||
}
|
||||
free(c->connects);
|
||||
c->connects = NULL;
|
||||
}
|
||||
c->num = 0;
|
||||
|
||||
free(c);
|
||||
}
|
||||
@@ -1208,7 +1224,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
* String to set in the HTTP Referer: field.
|
||||
*/
|
||||
if(data->change.referer_alloc) {
|
||||
free(data->change.referer);
|
||||
Curl_safefree(data->change.referer);
|
||||
data->change.referer_alloc = FALSE;
|
||||
}
|
||||
result = setstropt(&data->set.str[STRING_SET_REFERER],
|
||||
@@ -1257,10 +1273,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
/* append the cookie file name to the list of file names, and deal with
|
||||
them later */
|
||||
cl = curl_slist_append(data->change.cookielist, argptr);
|
||||
|
||||
if(!cl)
|
||||
if(!cl) {
|
||||
curl_slist_free_all(data->change.cookielist);
|
||||
data->change.cookielist = NULL;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
}
|
||||
data->change.cookielist = cl; /* store the list for later use */
|
||||
}
|
||||
break;
|
||||
@@ -1380,10 +1397,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
|
||||
/* switch off bits we can't support */
|
||||
#ifndef USE_NTLM
|
||||
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
|
||||
#endif
|
||||
#ifndef NTLM_WB_ENABLED
|
||||
auth &= ~CURLAUTH_NTLM_WB;
|
||||
auth &= ~CURLAUTH_NTLM; /* no NTLM support */
|
||||
auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
|
||||
#elif !defined(NTLM_WB_ENABLED)
|
||||
auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
|
||||
#endif
|
||||
#ifndef USE_HTTP_NEGOTIATE
|
||||
auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or
|
||||
@@ -1443,10 +1460,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
}
|
||||
/* switch off bits we can't support */
|
||||
#ifndef USE_NTLM
|
||||
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
|
||||
#endif
|
||||
#ifndef NTLM_WB_ENABLED
|
||||
auth &= ~CURLAUTH_NTLM_WB;
|
||||
auth &= ~CURLAUTH_NTLM; /* no NTLM support */
|
||||
auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
|
||||
#elif !defined(NTLM_WB_ENABLED)
|
||||
auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
|
||||
#endif
|
||||
#ifndef USE_HTTP_NEGOTIATE
|
||||
auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or
|
||||
@@ -1624,8 +1641,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
*/
|
||||
if(data->change.url_alloc) {
|
||||
/* the already set URL is allocated, free it first! */
|
||||
free(data->change.url);
|
||||
data->change.url_alloc=FALSE;
|
||||
Curl_safefree(data->change.url);
|
||||
data->change.url_alloc = FALSE;
|
||||
}
|
||||
result = setstropt(&data->set.str[STRING_SET_URL],
|
||||
va_arg(param, char *));
|
||||
@@ -2080,8 +2097,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
data->dns.hostcachetype = HCACHE_NONE;
|
||||
}
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
if(data->share->cookies == data->cookies)
|
||||
data->cookies = NULL;
|
||||
#endif
|
||||
|
||||
if(data->share->sslsession == data->state.session) {
|
||||
data->state.session = NULL;
|
||||
data->set.ssl.numsessions = 0;
|
||||
}
|
||||
|
||||
data->share->dirty--;
|
||||
|
||||
@@ -2114,6 +2138,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
data->cookies = data->share->cookies;
|
||||
}
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
if(data->share->sslsession) {
|
||||
data->set.ssl.numsessions = data->share->nsslsession;
|
||||
data->state.session = data->share->sslsession;
|
||||
}
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
|
||||
|
||||
}
|
||||
@@ -2141,7 +2169,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
/*
|
||||
* Make transfers attempt to use SSL/TLS.
|
||||
*/
|
||||
data->set.ftp_ssl = (curl_usessl)va_arg(param, long);
|
||||
data->set.use_ssl = (curl_usessl)va_arg(param, long);
|
||||
break;
|
||||
#endif
|
||||
case CURLOPT_FTPSSLAUTH:
|
||||
@@ -2531,7 +2559,7 @@ static void conn_free(struct connectdata *conn)
|
||||
if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
|
||||
Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
|
||||
|
||||
#ifdef NTLM_WB_ENABLED
|
||||
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
|
||||
Curl_ntlm_wb_cleanup(conn);
|
||||
#endif
|
||||
|
||||
@@ -2559,6 +2587,11 @@ static void conn_free(struct connectdata *conn)
|
||||
Curl_llist_destroy(conn->pend_pipe, NULL);
|
||||
Curl_llist_destroy(conn->done_pipe, NULL);
|
||||
|
||||
conn->send_pipe = NULL;
|
||||
conn->recv_pipe = NULL;
|
||||
conn->pend_pipe = NULL;
|
||||
conn->done_pipe = NULL;
|
||||
|
||||
Curl_safefree(conn->localdev);
|
||||
Curl_free_ssl_config(&conn->ssl_config);
|
||||
|
||||
@@ -2573,7 +2606,7 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
data = conn->data;
|
||||
|
||||
if(!data) {
|
||||
DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n"));
|
||||
DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -3524,7 +3557,7 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
|
||||
|
||||
conn->ip_version = data->set.ipver;
|
||||
|
||||
#ifdef NTLM_WB_ENABLED
|
||||
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
|
||||
conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
|
||||
conn->ntlm_auth_hlpr_pid = 0;
|
||||
conn->challenge_header = NULL;
|
||||
@@ -3573,6 +3606,12 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
|
||||
Curl_llist_destroy(conn->recv_pipe, NULL);
|
||||
Curl_llist_destroy(conn->pend_pipe, NULL);
|
||||
Curl_llist_destroy(conn->done_pipe, NULL);
|
||||
|
||||
conn->send_pipe = NULL;
|
||||
conn->recv_pipe = NULL;
|
||||
conn->pend_pipe = NULL;
|
||||
conn->done_pipe = NULL;
|
||||
|
||||
Curl_safefree(conn->master_buffer);
|
||||
Curl_safefree(conn->localdev);
|
||||
Curl_safefree(conn);
|
||||
@@ -4399,8 +4438,10 @@ static CURLcode parse_remote_port(struct SessionHandle *data,
|
||||
if(!url)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(data->change.url_alloc)
|
||||
free(data->change.url);
|
||||
if(data->change.url_alloc) {
|
||||
Curl_safefree(data->change.url);
|
||||
data->change.url_alloc = FALSE;
|
||||
}
|
||||
|
||||
data->change.url = url;
|
||||
data->change.url_alloc = TRUE;
|
||||
@@ -4624,11 +4665,12 @@ static void reuse_conn(struct connectdata *old_conn,
|
||||
|
||||
/* host can change, when doing keepalive with a proxy ! */
|
||||
if(conn->bits.proxy) {
|
||||
free(conn->host.rawalloc);
|
||||
Curl_safefree(conn->host.rawalloc);
|
||||
conn->host=old_conn->host;
|
||||
}
|
||||
else
|
||||
free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
|
||||
/* free the newly allocated name buffer */
|
||||
Curl_safefree(old_conn->host.rawalloc);
|
||||
|
||||
/* persist connection info in session handle */
|
||||
Curl_persistconninfo(conn);
|
||||
@@ -4640,10 +4682,17 @@ static void reuse_conn(struct connectdata *old_conn,
|
||||
Curl_safefree(old_conn->passwd);
|
||||
Curl_safefree(old_conn->proxyuser);
|
||||
Curl_safefree(old_conn->proxypasswd);
|
||||
|
||||
Curl_llist_destroy(old_conn->send_pipe, NULL);
|
||||
Curl_llist_destroy(old_conn->recv_pipe, NULL);
|
||||
Curl_llist_destroy(old_conn->pend_pipe, NULL);
|
||||
Curl_llist_destroy(old_conn->done_pipe, NULL);
|
||||
|
||||
old_conn->send_pipe = NULL;
|
||||
old_conn->recv_pipe = NULL;
|
||||
old_conn->pend_pipe = NULL;
|
||||
old_conn->done_pipe = NULL;
|
||||
|
||||
Curl_safefree(old_conn->master_buffer);
|
||||
}
|
||||
|
||||
@@ -4720,14 +4769,19 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||
*/
|
||||
|
||||
Curl_safefree(data->state.pathbuffer);
|
||||
data->state.path = NULL;
|
||||
|
||||
data->state.pathbuffer = malloc(urllen+2);
|
||||
if(NULL == data->state.pathbuffer)
|
||||
return CURLE_OUT_OF_MEMORY; /* really bad error */
|
||||
data->state.path = data->state.pathbuffer;
|
||||
|
||||
conn->host.rawalloc = malloc(urllen+2);
|
||||
if(NULL == conn->host.rawalloc)
|
||||
if(NULL == conn->host.rawalloc) {
|
||||
Curl_safefree(data->state.pathbuffer);
|
||||
data->state.path = NULL;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
conn->host.name = conn->host.rawalloc;
|
||||
conn->host.name[0] = 0;
|
||||
@@ -4752,6 +4806,11 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(data->change.url_alloc) {
|
||||
Curl_safefree(data->change.url);
|
||||
data->change.url_alloc = FALSE;
|
||||
}
|
||||
|
||||
data->change.url = reurl;
|
||||
data->change.url_alloc = TRUE; /* free this later */
|
||||
}
|
||||
@@ -4979,6 +5038,9 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||
ConnectionStore(data, conn);
|
||||
}
|
||||
|
||||
/* Setup and init stuff before DO starts, in preparing for the transfer. */
|
||||
do_init(conn);
|
||||
|
||||
/*
|
||||
* Setup whatever necessary for a resumed transfer
|
||||
*/
|
||||
@@ -5016,7 +5078,7 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||
CURLcode Curl_setup_conn(struct connectdata *conn,
|
||||
bool *protocol_done)
|
||||
{
|
||||
CURLcode result=CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
Curl_pgrsTime(data, TIMER_NAMELOOKUP);
|
||||
@@ -5062,6 +5124,12 @@ CURLcode Curl_setup_conn(struct connectdata *conn,
|
||||
|
||||
result = ConnectPlease(data, conn, &connected);
|
||||
|
||||
if(result && !conn->ip_addr) {
|
||||
/* transport connection failure not related with authentication */
|
||||
conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
|
||||
return result;
|
||||
}
|
||||
|
||||
if(connected) {
|
||||
result = Curl_protocol_connect(conn, protocol_done);
|
||||
if(CURLE_OK == result)
|
||||
@@ -5325,9 +5393,6 @@ CURLcode Curl_do(struct connectdata **connp, bool *done)
|
||||
struct connectdata *conn = *connp;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
/* setup and init stuff before DO starts, in preparing for the transfer */
|
||||
do_init(conn);
|
||||
|
||||
if(conn->handler->do_it) {
|
||||
/* generic protocol-specific function pointer set in curl_connect() */
|
||||
result = conn->handler->do_it(conn, done);
|
||||
|
@@ -273,6 +273,7 @@ struct ssl_connect_data {
|
||||
struct SessionHandle *data;
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
struct curl_llist *obj_list;
|
||||
PK11GenericObject *obj_clicert;
|
||||
#endif
|
||||
#endif /* USE_NSS */
|
||||
#ifdef USE_QSOSSL
|
||||
@@ -670,6 +671,12 @@ struct Curl_handler {
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
|
||||
/* Called from the multi interface during the DO_MORE phase, and it should
|
||||
then return a proper fd set */
|
||||
int (*domore_getsock)(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
|
||||
/* Called from the multi interface during the DO_DONE, PERFORM and
|
||||
WAITPERFORM phases, and it should then return a proper fd set. Not setting
|
||||
this will make libcurl use the generic default one. */
|
||||
@@ -905,7 +912,7 @@ struct connectdata {
|
||||
single requests! */
|
||||
struct ntlmdata proxyntlm; /* NTLM data for proxy */
|
||||
|
||||
#ifdef NTLM_WB_ENABLED
|
||||
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
|
||||
/* used for communication with Samba's winbind daemon helper ntlm_auth */
|
||||
curl_socket_t ntlm_auth_hlpr_socket;
|
||||
pid_t ntlm_auth_hlpr_pid;
|
||||
@@ -1486,7 +1493,7 @@ struct UserDefined {
|
||||
bool ftp_use_eprt; /* if EPRT is to be attempted or not */
|
||||
bool ftp_use_pret; /* if PRET is to be used before PASV or not */
|
||||
|
||||
curl_usessl ftp_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
|
||||
curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
|
||||
IMAP or POP3 or others! */
|
||||
curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */
|
||||
curl_ftpccc ftp_ccc; /* FTP CCC options */
|
||||
|
@@ -240,7 +240,7 @@ static curl_version_info_data version_info = {
|
||||
#ifdef USE_NTLM
|
||||
| CURL_VERSION_NTLM
|
||||
#endif
|
||||
#ifdef NTLM_WB_ENABLED
|
||||
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
|
||||
| CURL_VERSION_NTLM_WB
|
||||
#endif
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
|
@@ -55,7 +55,7 @@ AC_DEFUN([CURL_CHECK_OPENSSL_API_HEADERS], [
|
||||
tst_verfix=`echo $curl_cv_def_OPENSSL_VERSION_NUMBER | cut -c 5`
|
||||
tst_api=0x$tst_vermaj$tst_vermin$tst_verfix
|
||||
;;
|
||||
x11)
|
||||
x11|x10)
|
||||
tst_vermaj=`echo $curl_cv_def_OPENSSL_VERSION_NUMBER | cut -c 3`
|
||||
tst_vermin=`echo $curl_cv_def_OPENSSL_VERSION_NUMBER | cut -c 5`
|
||||
tst_verfix=`echo $curl_cv_def_OPENSSL_VERSION_NUMBER | cut -c 7`
|
||||
|
2
maketgz
2
maketgz
@@ -43,7 +43,7 @@ patch=`echo $libversion |cut -d. -f3 | cut -d- -f1 | sed -e "s/[^0-9]//g"`
|
||||
numeric=`perl -e 'printf("%02x%02x%02x\n", '"$major, $minor, $patch);"`
|
||||
|
||||
HEADER=include/curl/curlver.h
|
||||
CHEADER=src/version.h
|
||||
CHEADER=src/tool_version.h
|
||||
|
||||
# requires a date command that knows -u for UTC time zone
|
||||
datestamp=`date -u`
|
||||
|
@@ -70,49 +70,50 @@ options:
|
||||
CURLOPT_COOKIEFILE
|
||||
CURLOPT_COOKIEJAR
|
||||
CURLOPT_COOKIELIST
|
||||
CURLOPT_COPYPOSTFIELDS
|
||||
CURLOPT_CRLFILE
|
||||
CURLOPT_CUSTOMREQUEST
|
||||
CURLOPT_EGDSOCKET
|
||||
CURLOPT_ENCODING
|
||||
CURLOPT_FTPPORT
|
||||
CURLOPT_FTP_ACCOUNT
|
||||
CURLOPT_FTP_ALTERNATIVE_TO_USER
|
||||
CURLOPT_FTPPORT
|
||||
CURLOPT_INTERFACE
|
||||
CURLOPT_ISSUERCERT
|
||||
CURLOPT_KEYPASSWD
|
||||
CURLOPT_KRBLEVEL
|
||||
CURLOPT_MAIL_FROM
|
||||
CURLOPT_NETRC_FILE
|
||||
CURLOPT_COPYPOSTFIELDS
|
||||
CURLOPT_NOPROXY
|
||||
CURLOPT_PASSWORD
|
||||
CURLOPT_PROXY
|
||||
CURLOPT_PROXYPASSWORD
|
||||
CURLOPT_PROXYUSERNAME
|
||||
CURLOPT_PROXYUSERPWD
|
||||
CURLOPT_RANDOM_FILE
|
||||
CURLOPT_RANGE
|
||||
CURLOPT_REFERER
|
||||
CURLOPT_SSH_PRIVATE_KEYFILE
|
||||
CURLOPT_SSH_PUBLIC_KEYFILE
|
||||
CURLOPT_SSLCERT
|
||||
CURLOPT_SSLCERTTYPE
|
||||
CURLOPT_SSLENGINE
|
||||
CURLOPT_SSLKEY
|
||||
CURLOPT_SSLKEYTYPE
|
||||
CURLOPT_SSL_CIPHER_LIST
|
||||
CURLOPT_URL
|
||||
CURLOPT_USERAGENT
|
||||
CURLOPT_USERPWD
|
||||
CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
|
||||
CURLOPT_CRLFILE
|
||||
CURLOPT_ISSUERCERT
|
||||
CURLOPT_USERNAME
|
||||
CURLOPT_PASSWORD
|
||||
CURLOPT_PROXYUSERNAME
|
||||
CURLOPT_PROXYPASSWORD
|
||||
CURLOPT_NOPROXY
|
||||
CURLOPT_RTSP_SESSION_UID
|
||||
CURLOPT_RTSP_STREAM_URI
|
||||
CURLOPT_RTSP_TRANSPORT
|
||||
CURLOPT_SOCKS5_GSSAPI_SERVICE
|
||||
CURLOPT_MAIL_FROM
|
||||
CURLOPT_TLSAUTH_USERNAME
|
||||
CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 Note: SSH not available on OS400.
|
||||
CURLOPT_SSH_KNOWNHOSTS Note: SSH not available on OS400.
|
||||
CURLOPT_SSH_PRIVATE_KEYFILE Note: SSH not available on OS400.
|
||||
CURLOPT_SSH_PUBLIC_KEYFILE Note: SSH not available on OS400.
|
||||
CURLOPT_SSLCERT
|
||||
CURLOPT_SSLCERTTYPE
|
||||
CURLOPT_SSL_CIPHER_LIST
|
||||
CURLOPT_SSLENGINE
|
||||
CURLOPT_SSLKEY
|
||||
CURLOPT_SSLKEYTYPE
|
||||
CURLOPT_TLSAUTH_PASSWORD
|
||||
CURLOPT_TLSAUTH_TYPE
|
||||
CURLOPT_TLSAUTH_USERNAME
|
||||
CURLOPT_URL
|
||||
CURLOPT_USERAGENT
|
||||
CURLOPT_USERNAME
|
||||
CURLOPT_USERPWD
|
||||
Else it is the same as for curl_easy_setopt().
|
||||
Note that CURLOPT_ERRORBUFFER is not in the list above, since it gives the
|
||||
address of an (empty) character buffer, not the address of a string.
|
||||
|
@@ -1049,52 +1049,49 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
|
||||
case CURLOPT_COOKIEFILE:
|
||||
case CURLOPT_COOKIEJAR:
|
||||
case CURLOPT_COOKIELIST:
|
||||
case CURLOPT_CRLFILE:
|
||||
case CURLOPT_CUSTOMREQUEST:
|
||||
case CURLOPT_EGDSOCKET:
|
||||
case CURLOPT_ENCODING:
|
||||
case CURLOPT_FTPPORT:
|
||||
case CURLOPT_FTP_ACCOUNT:
|
||||
case CURLOPT_FTP_ALTERNATIVE_TO_USER:
|
||||
case CURLOPT_FTPPORT:
|
||||
case CURLOPT_INTERFACE:
|
||||
case CURLOPT_ISSUERCERT:
|
||||
case CURLOPT_KEYPASSWD:
|
||||
case CURLOPT_KRBLEVEL:
|
||||
case CURLOPT_MAIL_FROM:
|
||||
case CURLOPT_NETRC_FILE:
|
||||
case CURLOPT_NOPROXY:
|
||||
case CURLOPT_PASSWORD:
|
||||
case CURLOPT_PROXY:
|
||||
case CURLOPT_PROXYPASSWORD:
|
||||
case CURLOPT_PROXYUSERNAME:
|
||||
case CURLOPT_PROXYUSERPWD:
|
||||
case CURLOPT_RANDOM_FILE:
|
||||
case CURLOPT_RANGE:
|
||||
case CURLOPT_REFERER:
|
||||
case CURLOPT_RTSP_SESSION_ID:
|
||||
case CURLOPT_RTSP_STREAM_URI:
|
||||
case CURLOPT_RTSP_TRANSPORT:
|
||||
case CURLOPT_SOCKS5_GSSAPI_SERVICE:
|
||||
case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
|
||||
case CURLOPT_SSH_KNOWNHOSTS:
|
||||
case CURLOPT_SSH_PRIVATE_KEYFILE:
|
||||
case CURLOPT_SSH_PUBLIC_KEYFILE:
|
||||
case CURLOPT_SSLCERT:
|
||||
case CURLOPT_SSLCERTTYPE:
|
||||
case CURLOPT_SSL_CIPHER_LIST:
|
||||
case CURLOPT_SSLENGINE:
|
||||
case CURLOPT_SSLKEY:
|
||||
case CURLOPT_SSLKEYTYPE:
|
||||
case CURLOPT_SSL_CIPHER_LIST:
|
||||
case CURLOPT_URL:
|
||||
case CURLOPT_USERAGENT:
|
||||
case CURLOPT_USERPWD:
|
||||
case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
|
||||
case CURLOPT_CRLFILE:
|
||||
case CURLOPT_ISSUERCERT:
|
||||
case CURLOPT_USERNAME:
|
||||
case CURLOPT_PASSWORD:
|
||||
case CURLOPT_PROXYUSERNAME:
|
||||
case CURLOPT_PROXYPASSWORD:
|
||||
case CURLOPT_NOPROXY:
|
||||
case CURLOPT_RTSP_SESSION_ID:
|
||||
case CURLOPT_RTSP_STREAM_URI:
|
||||
case CURLOPT_RTSP_TRANSPORT:
|
||||
/* SSH2 not (yet) implemented on OS400. */
|
||||
/* case CURLOPT_SSH_KNOWNHOSTS: */
|
||||
case CURLOPT_SOCKS5_GSSAPI_SERVICE:
|
||||
case CURLOPT_MAIL_FROM:
|
||||
#ifdef USE_TLS_SRP
|
||||
case CURLOPT_TLSAUTH_USERNAME:
|
||||
case CURLOPT_TLSAUTH_PASSWORD:
|
||||
case CURLOPT_TLSAUTH_TYPE:
|
||||
#endif
|
||||
case CURLOPT_TLSAUTH_USERNAME:
|
||||
case CURLOPT_URL:
|
||||
case CURLOPT_USERAGENT:
|
||||
case CURLOPT_USERNAME:
|
||||
case CURLOPT_USERPWD:
|
||||
s = va_arg(arg, char *);
|
||||
ccsid = va_arg(arg, unsigned int);
|
||||
|
||||
|
@@ -111,6 +111,8 @@
|
||||
d c X'00002000'
|
||||
d CURL_VERSION_TLSAUTH_SRP...
|
||||
d c X'00004000'
|
||||
d CURL_VERSION_NTLM_WB...
|
||||
d c X'00008000'
|
||||
*
|
||||
d HTTPPOST_FILENAME...
|
||||
d c X'00000001'
|
||||
@@ -151,6 +153,8 @@
|
||||
d CURLAUTH_NTLM c X'00000008'
|
||||
d CURLAUTH_DIGEST_IE...
|
||||
d c X'00000010'
|
||||
d CURLAUTH_NTLM_WB...
|
||||
d c X'00000020'
|
||||
d CURLAUTH_ONLY...
|
||||
d c X'80000000'
|
||||
d CURLAUTH_ANY c X'7FFFFFEF'
|
||||
@@ -172,6 +176,13 @@
|
||||
d CURLSSH_AUTH_DEFAULT...
|
||||
d c X'7FFFFFFF' CURLSSH_AUTH_ANY
|
||||
*
|
||||
d CURLGSSAPI_DELEGATION_NONE...
|
||||
d c 0
|
||||
d CURLGSSAPI_DELEGATION_POLICY_FLAG...
|
||||
d c X'00000001'
|
||||
d CURLGSSAPI_DELEGATION_FLAG...
|
||||
d c X'00000002'
|
||||
*
|
||||
d CURL_ERROR_SIZE...
|
||||
d c 256
|
||||
*
|
||||
@@ -1111,6 +1122,8 @@
|
||||
d c 20208
|
||||
d CURLOPT_CLOSESOCKETDATA...
|
||||
d c 10209
|
||||
d CURLOPT_GSSAPI_DELEGATION...
|
||||
d c 00210
|
||||
*
|
||||
/if not defined(CURL_NO_OLDIES)
|
||||
d CURLOPT_SSLKEYPASSWD...
|
||||
@@ -1341,6 +1354,8 @@
|
||||
d c 3
|
||||
d CURLSHE_NOMEM...
|
||||
d c 4
|
||||
d CURLSHE_NOT_BUILT_IN...
|
||||
d c 5
|
||||
*
|
||||
d CURLSHoption...
|
||||
d s 10i 0 based(######ptr######) Enum
|
||||
|
@@ -8,8 +8,44 @@ UID 0x00000000 0xF0206442
|
||||
|
||||
SOURCEPATH ../../../src
|
||||
SOURCE \
|
||||
main.c hugehelp.c urlglob.c writeout.c writeenv.c \
|
||||
getpass.c homedir.c curlutil.c os-specific.c xattr.c
|
||||
hugehelp.c \
|
||||
tool_binmode.c \
|
||||
tool_bname.c \
|
||||
tool_cb_dbg.c \
|
||||
tool_cb_hdr.c \
|
||||
tool_cb_prg.c \
|
||||
tool_cb_rea.c \
|
||||
tool_cb_see.c \
|
||||
tool_cb_skt.c \
|
||||
tool_cb_wrt.c \
|
||||
tool_cfgable.c \
|
||||
tool_convert.c \
|
||||
tool_dirhie.c \
|
||||
tool_doswin.c \
|
||||
tool_easysrc.c \
|
||||
tool_formparse.c \
|
||||
tool_getparam.c \
|
||||
tool_getpass.c \
|
||||
tool_help.c \
|
||||
tool_helpers.c \
|
||||
tool_homedir.c \
|
||||
tool_libinfo.c \
|
||||
tool_main.c \
|
||||
tool_mfiles.c \
|
||||
tool_msgs.c \
|
||||
tool_operate.c \
|
||||
tool_operhlp.c \
|
||||
tool_panykey.c \
|
||||
tool_paramhlp.c \
|
||||
tool_parsecfg.c \
|
||||
tool_setopt.c \
|
||||
tool_sleep.c \
|
||||
tool_urlglob.c \
|
||||
tool_util.c \
|
||||
tool_vms.c \
|
||||
tool_writeenv.c \
|
||||
tool_writeout.c \
|
||||
tool_xattr.c
|
||||
|
||||
SOURCEPATH ../../../lib
|
||||
SOURCE \
|
||||
|
1
src/.gitignore
vendored
1
src/.gitignore
vendored
@@ -6,5 +6,6 @@ stamp-h2
|
||||
Makefile.vc8.dist
|
||||
Makefile.vc9.dist
|
||||
version.h.dist
|
||||
tool_version.h.dist
|
||||
Makefile.vc10.dist
|
||||
config-win32.h
|
||||
|
@@ -14,13 +14,86 @@ CURLX_ONES = $(top_srcdir)/lib/strtoofft.c \
|
||||
$(top_srcdir)/lib/rawstr.c \
|
||||
$(top_srcdir)/lib/nonblock.c
|
||||
|
||||
CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \
|
||||
getpass.c homedir.c curlutil.c os-specific.c xattr.c
|
||||
CURL_CFILES = hugehelp.c \
|
||||
tool_binmode.c \
|
||||
tool_bname.c \
|
||||
tool_cb_dbg.c \
|
||||
tool_cb_hdr.c \
|
||||
tool_cb_prg.c \
|
||||
tool_cb_rea.c \
|
||||
tool_cb_see.c \
|
||||
tool_cb_skt.c \
|
||||
tool_cb_wrt.c \
|
||||
tool_cfgable.c \
|
||||
tool_convert.c \
|
||||
tool_dirhie.c \
|
||||
tool_doswin.c \
|
||||
tool_easysrc.c \
|
||||
tool_formparse.c \
|
||||
tool_getparam.c \
|
||||
tool_getpass.c \
|
||||
tool_help.c \
|
||||
tool_helpers.c \
|
||||
tool_homedir.c \
|
||||
tool_libinfo.c \
|
||||
tool_main.c \
|
||||
tool_mfiles.c \
|
||||
tool_msgs.c \
|
||||
tool_operate.c \
|
||||
tool_operhlp.c \
|
||||
tool_panykey.c \
|
||||
tool_paramhlp.c \
|
||||
tool_parsecfg.c \
|
||||
tool_setopt.c \
|
||||
tool_sleep.c \
|
||||
tool_urlglob.c \
|
||||
tool_util.c \
|
||||
tool_vms.c \
|
||||
tool_writeenv.c \
|
||||
tool_writeout.c \
|
||||
tool_xattr.c
|
||||
|
||||
CURL_HFILES = hugehelp.h setup.h config-win32.h config-mac.h \
|
||||
config-riscos.h urlglob.h version.h os-specific.h \
|
||||
writeout.h writeenv.h getpass.h homedir.h curlutil.h \
|
||||
xattr.h
|
||||
config-riscos.h \
|
||||
tool_binmode.h \
|
||||
tool_bname.h \
|
||||
tool_cb_dbg.h \
|
||||
tool_cb_hdr.h \
|
||||
tool_cb_prg.h \
|
||||
tool_cb_rea.h \
|
||||
tool_cb_see.h \
|
||||
tool_cb_skt.h \
|
||||
tool_cb_wrt.h \
|
||||
tool_cfgable.h \
|
||||
tool_convert.h \
|
||||
tool_dirhie.h \
|
||||
tool_doswin.h \
|
||||
tool_easysrc.h \
|
||||
tool_formparse.h \
|
||||
tool_getparam.h \
|
||||
tool_getpass.h \
|
||||
tool_help.h \
|
||||
tool_helpers.h \
|
||||
tool_homedir.h \
|
||||
tool_libinfo.h \
|
||||
tool_main.h \
|
||||
tool_mfiles.h \
|
||||
tool_msgs.h \
|
||||
tool_operate.h \
|
||||
tool_operhlp.h \
|
||||
tool_panykey.h \
|
||||
tool_paramhlp.h \
|
||||
tool_parsecfg.h \
|
||||
tool_sdecls.h \
|
||||
tool_setopt.h \
|
||||
tool_sleep.h \
|
||||
tool_urlglob.h \
|
||||
tool_util.h \
|
||||
tool_version.h \
|
||||
tool_vms.h \
|
||||
tool_writeenv.h \
|
||||
tool_writeout.h \
|
||||
tool_xattr.h
|
||||
|
||||
curl_SOURCES = $(CURL_CFILES) $(CURLX_ONES) $(CURL_HFILES)
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#########################################################################
|
||||
###########################################################################
|
||||
#
|
||||
## Makefile for building curl.exe with MingW32 (GCC-3.2 or later)
|
||||
## and optionally OpenSSL (0.9.8), libssh2 (1.2), zlib (1.2.5), librtmp (2.3)
|
||||
## Makefile for building curl.exe with MingW (GCC-3.2 or later)
|
||||
## and optionally OpenSSL (0.9.8), libssh2 (1.3), zlib (1.2.5), librtmp (2.3)
|
||||
##
|
||||
## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...]
|
||||
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-spi-winidn
|
||||
@@ -9,10 +9,8 @@
|
||||
## Hint: you can also set environment vars to control the build, f.e.:
|
||||
## set ZLIB_PATH=c:/zlib-1.2.5
|
||||
## set ZLIB=1
|
||||
##
|
||||
## Comments to: Troy Engel <tengel@sonic.net> or
|
||||
## Joern Hartroth <hartroth@acm.org>
|
||||
#########################################################################
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ifndef ZLIB_PATH
|
||||
@@ -22,6 +20,12 @@ endif
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.8r
|
||||
endif
|
||||
ifndef OPENSSL_LIBPATH
|
||||
OPENSSL_LIBPATH = $(OPENSSL_PATH)/out
|
||||
endif
|
||||
ifndef OPENSSL_LIBS
|
||||
OPENSSL_LIBS = -leay32 -lssl32
|
||||
endif
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.3.0
|
||||
@@ -45,9 +49,11 @@ ifndef LDAP_SDK
|
||||
LDAP_SDK = c:/novell/ndk/cldapsdk/win32
|
||||
endif
|
||||
|
||||
PROOT = ..
|
||||
|
||||
# Edit the path below to point to the base of your c-ares package.
|
||||
ifndef LIBCARES_PATH
|
||||
LIBCARES_PATH = ../ares
|
||||
LIBCARES_PATH = $(PROOT)/ares
|
||||
endif
|
||||
|
||||
# Edit the var below to set to your architecture or set environment var.
|
||||
@@ -57,13 +63,15 @@ endif
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -O2 -Wall
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
ifeq ($(ARCH),w64)
|
||||
CFLAGS += -D_AMD64_
|
||||
endif
|
||||
# comment LDFLAGS below to keep debug info
|
||||
LDFLAGS = -s
|
||||
RC = windres
|
||||
RCFLAGS = --include-dir=../include -O COFF -i
|
||||
RCFLAGS = --include-dir=$(PROOT)/include -O COFF -i
|
||||
|
||||
RM = del /q /f 2>NUL
|
||||
CP = copy
|
||||
|
||||
@@ -116,15 +124,13 @@ IPV6 = 1
|
||||
endif
|
||||
|
||||
INCLUDES = -I. -I.. -I../include -I../lib
|
||||
LINK = $(CC) $(LDFLAGS) -o $@
|
||||
|
||||
curl_PROGRAMS = curl.exe
|
||||
ifdef DYN
|
||||
curl_DEPENDENCIES = ../lib/libcurldll.a ../lib/libcurl.dll
|
||||
curl_LDADD = -L../lib -lcurldll
|
||||
curl_DEPENDENCIES = $(PROOT)/lib/libcurldll.a $(PROOT)/lib/libcurl.dll
|
||||
curl_LDADD = -L$(PROOT)/lib -lcurldll
|
||||
else
|
||||
curl_DEPENDENCIES = ../lib/libcurl.a
|
||||
curl_LDADD = -L../lib -lcurl
|
||||
curl_DEPENDENCIES = $(PROOT)/lib/libcurl.a
|
||||
curl_LDADD = -L$(PROOT)/lib -lcurl
|
||||
CFLAGS += -DCURL_STATICLIB
|
||||
endif
|
||||
ifdef ARES
|
||||
@@ -132,7 +138,7 @@ ifdef ARES
|
||||
curl_DEPENDENCIES += $(LIBCARES_PATH)/libcares.a
|
||||
endif
|
||||
CFLAGS += -DUSE_ARES
|
||||
curl_LDADD += -L$(LIBCARES_PATH) -lcares
|
||||
curl_LDADD += -L"$(LIBCARES_PATH)" -lcares
|
||||
endif
|
||||
ifdef RTMP
|
||||
CFLAGS += -DUSE_LIBRTMP
|
||||
@@ -140,25 +146,24 @@ ifdef RTMP
|
||||
endif
|
||||
ifdef SSH2
|
||||
CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H
|
||||
curl_LDADD += -L$(LIBSSH2_PATH)/win32 -lssh2
|
||||
curl_LDADD += -L"$(LIBSSH2_PATH)/win32" -lssh2
|
||||
endif
|
||||
ifdef SSL
|
||||
CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H
|
||||
curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32
|
||||
curl_LDADD += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS)
|
||||
endif
|
||||
ifdef ZLIB
|
||||
INCLUDES += -I"$(ZLIB_PATH)"
|
||||
CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
|
||||
curl_LDADD += -L$(ZLIB_PATH) -lz
|
||||
curl_LDADD += -L"$(ZLIB_PATH)" -lz
|
||||
endif
|
||||
ifdef IDN
|
||||
INCLUDES += -I"$(LIBIDN_PATH)/include"
|
||||
CFLAGS += -DUSE_LIBIDN
|
||||
curl_LDADD += -L$(LIBIDN_PATH)/lib -lidn
|
||||
curl_LDADD += -L"$(LIBIDN_PATH)/lib" -lidn
|
||||
else
|
||||
ifdef WINIDN
|
||||
CFLAGS += -DUSE_WIN32_IDN
|
||||
DLL_LIBS += -L"$(WINIDN_PATH)" -lnormaliz
|
||||
curl_LDADD += -L"$(WINIDN_PATH)" -lnormaliz
|
||||
endif
|
||||
endif
|
||||
ifdef SSPI
|
||||
@@ -168,7 +173,7 @@ ifdef SPNEGO
|
||||
CFLAGS += -DHAVE_SPNEGO
|
||||
endif
|
||||
ifdef IPV6
|
||||
CFLAGS += -DENABLE_IPV6
|
||||
CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501
|
||||
endif
|
||||
ifdef LDAPS
|
||||
CFLAGS += -DHAVE_LDAP_SSL
|
||||
@@ -187,48 +192,47 @@ curl_LDADD += -lwldap32
|
||||
endif
|
||||
endif
|
||||
curl_LDADD += -lws2_32
|
||||
COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include Makefile.inc
|
||||
|
||||
curl_PROGRAMS = curl.exe
|
||||
curl_OBJECTS := $(patsubst %.c,%.o,$(strip $(CURL_CFILES)))
|
||||
ifdef DYN
|
||||
curlx_OBJECTS := $(patsubst %.c,%.o,$(notdir $(strip $(CURLX_ONES))))
|
||||
ifdef DYN
|
||||
curl_OBJECTS += $(curlx_OBJECTS)
|
||||
vpath %.c ../lib
|
||||
vpath %.c $(PROOT)/lib
|
||||
endif
|
||||
|
||||
RESOURCE = curl.res
|
||||
|
||||
.SUFFIXES: .rc .res
|
||||
|
||||
all: curl.exe
|
||||
all: $(curl_PROGRAMS)
|
||||
|
||||
curl.exe: $(RESOURCE) $(curl_OBJECTS) $(curl_DEPENDENCIES)
|
||||
-$(RM) $@
|
||||
$(LINK) $< $(curl_OBJECTS) $(curl_LDADD)
|
||||
$(CC) $(LDFLAGS) -o $@ $< $(curl_OBJECTS) $(curl_LDADD)
|
||||
|
||||
# We don't have nroff normally under win32
|
||||
# hugehelp.c: ../README.curl ../curl.1 mkhelp.pl
|
||||
# hugehelp.c: $(PROOT)/README.curl $(PROOT)/curl.1 mkhelp.pl
|
||||
# -$(RM) hugehelp.c
|
||||
# $(NROFF) -man ../curl.1 | $(PERL) mkhelp.pl ../README.curl > hugehelp.c
|
||||
# $(NROFF) -man $(PROOT)/curl.1 | $(PERL) mkhelp.pl $(PROOT)/README.curl > hugehelp.c
|
||||
|
||||
hugehelp.c:
|
||||
@echo Creating $@
|
||||
@$(CP) hugehelp.c.cvs $@
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) -c $<
|
||||
%.o: %.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
.rc.res:
|
||||
%.res: %.rc
|
||||
$(RC) $(RCFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
ifeq "$(wildcard hugehelp.c.cvs)" "hugehelp.c.cvs"
|
||||
-$(RM) hugehelp.c
|
||||
endif
|
||||
-$(RM) $(curl_OBJECTS) $(RESOURCE)
|
||||
-$(RM) $(curl_OBJECTS) $(curlx_OBJECTS) $(RESOURCE)
|
||||
|
||||
distclean vclean: clean
|
||||
-$(RM) $(curl_PROGRAMS)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user