Compare commits
71 Commits
curl-7_9_7
...
curl-7_9_8
Author | SHA1 | Date | |
---|---|---|---|
![]() |
67273eed9b | ||
![]() |
3c63e1d8d9 | ||
![]() |
cae555c977 | ||
![]() |
407583e8e2 | ||
![]() |
131645dc31 | ||
![]() |
dafd644fe7 | ||
![]() |
73cc1742af | ||
![]() |
87afd7686f | ||
![]() |
8ce10b5dfa | ||
![]() |
943e31b35c | ||
![]() |
20f85b94df | ||
![]() |
17b784381e | ||
![]() |
e3031fddb9 | ||
![]() |
38c994a7ae | ||
![]() |
85e2e96fb6 | ||
![]() |
be35b3ad03 | ||
![]() |
dbbd871ea1 | ||
![]() |
813911db59 | ||
![]() |
3c49b405de | ||
![]() |
4cfffd6c4a | ||
![]() |
e9f1c12f0f | ||
![]() |
4fe252847c | ||
![]() |
109cbbe9c5 | ||
![]() |
fd3881eaa6 | ||
![]() |
08ef208fb7 | ||
![]() |
8c45e2a641 | ||
![]() |
25dc520163 | ||
![]() |
fc37ef9e4b | ||
![]() |
11ba367fc9 | ||
![]() |
78473f71eb | ||
![]() |
8b77f40f99 | ||
![]() |
d866716565 | ||
![]() |
307d0effe2 | ||
![]() |
b47b053e54 | ||
![]() |
b79f01caf3 | ||
![]() |
0db227f55e | ||
![]() |
ac48b38842 | ||
![]() |
0cbb9365c6 | ||
![]() |
798b8c522b | ||
![]() |
15bc7e19f9 | ||
![]() |
0be3f1a063 | ||
![]() |
c0257c6721 | ||
![]() |
9aec0fc7de | ||
![]() |
bce5e0d82c | ||
![]() |
62032ee248 | ||
![]() |
775645f29b | ||
![]() |
99c0456872 | ||
![]() |
0236bee5de | ||
![]() |
59c11b82d5 | ||
![]() |
98871d1e9e | ||
![]() |
b40dc5d742 | ||
![]() |
17b0723713 | ||
![]() |
ec585e8907 | ||
![]() |
0aeb25ff3b | ||
![]() |
a928f2c4aa | ||
![]() |
51fcee6f81 | ||
![]() |
654be65590 | ||
![]() |
105ec79b2b | ||
![]() |
c759d8427a | ||
![]() |
c7b03d6479 | ||
![]() |
2080738883 | ||
![]() |
48bc73c271 | ||
![]() |
3d0969d1d1 | ||
![]() |
323f195036 | ||
![]() |
c3c392fc98 | ||
![]() |
5d2944c211 | ||
![]() |
fe3ba1dd11 | ||
![]() |
0c00eb93a0 | ||
![]() |
baa77ec13b | ||
![]() |
9263652c6d | ||
![]() |
bc74375543 |
141
CHANGES
141
CHANGES
@@ -6,6 +6,147 @@
|
||||
|
||||
History of Changes
|
||||
|
||||
Version 7.9.8
|
||||
|
||||
Daniel (13 Jun 2002)
|
||||
- Time to let this baby go.
|
||||
|
||||
Daniel (12 Jun 2002)
|
||||
- Chris Combes added three new options for curl_formadd(): CURLFORM_BUFFER,
|
||||
CURLFORM_BUFFERPTR, CURLFORM_BUFFERLENGTH. They are used to create a
|
||||
multipart that appears as a regular file upload, but the data is provided
|
||||
with a pointer and length.
|
||||
|
||||
- Nico Baggus made the VMS version use sigsetjmp() too.
|
||||
|
||||
- J<>rn Hartroth fixed the mingw32 build using the mm lib.
|
||||
|
||||
- Applied patches by Kris Kennaway that correct format string problems in
|
||||
lib/ftp.c and lib/ldap.c.
|
||||
|
||||
Version 7.9.8-pre3
|
||||
|
||||
Daniel (11 Jun 2002)
|
||||
- James Cone brought the idea of using sigsetjmp() in the signal handler to
|
||||
make the time-out of name lookups to work, even when the underlying name
|
||||
resolver library traps EINTR. The use of sigsetjmp() and siglongjmp() for
|
||||
this may be a bit drastic, and also not likely to exist on all platforms. I
|
||||
added careful checking for this in the configure script, even checks for it
|
||||
being a macro (which seems to be the case in for example Linux).
|
||||
|
||||
sigsetjmp() seems to be mentioned in the Single Unix specification.
|
||||
|
||||
- Miklos Nemeth brought a patch that allows libcurl to get built with specific
|
||||
protocols disabled. This is done by running ./configure
|
||||
--disable-[protocol].
|
||||
|
||||
- FTP range downloads could make CURLE_FTP_WRITE_ERROR get returned. We now
|
||||
make precautions to not return this for range downloads.
|
||||
|
||||
Added test case 135 that makes an ftp range download. Had to tweak the
|
||||
runtests.pl script a bit too.
|
||||
|
||||
- Bug report #566835 identified a strlen() on a NULL pointer. Added additional
|
||||
check to prevent this.
|
||||
|
||||
Daniel (10 Jun 2002)
|
||||
- Found and corrected a connect failure problem that didn't create a human
|
||||
error text.
|
||||
|
||||
- Added code to compile with OpenSSL 0.9.7. Based on patch from Jacob Meuser
|
||||
and comments from G<>tz Babin-Ebell.
|
||||
|
||||
- Gautam Mani found a socket descriptor leak that happened when FTP transfers
|
||||
failed and you reinvoked curl_easy_perform().
|
||||
|
||||
Daniel (5 Jun 2002)
|
||||
- Gustaf Hui corrected curl_multi_remove_handle() so that it won't crash no
|
||||
matter when you decide to remove the CURL handle.
|
||||
|
||||
- HAVE_RAND_STATUS was added to lib/config-win32.h by Andreas Olsson, as it
|
||||
makes windows builds stop complaining about "weak seeding" when it in fact
|
||||
isn't.
|
||||
|
||||
- Another 64bit architecture crash that was introduced in 7.9.7 was now
|
||||
removed, as bug report #564585 clarified. This happened due to our attempts
|
||||
to only allocate only as much memory as is actually needed for name
|
||||
resolving (using realloc) which called for a function that could 'move' a
|
||||
hostent struct in memory.
|
||||
|
||||
Version 7.9.8-pre2
|
||||
|
||||
Daniel (3 Jun 2002)
|
||||
- T. Bharath fixed the CURLINFO_REDIRECT_TIME to return a correct time and
|
||||
made the CURLINFO_REQUEST_SIZE return the correct total request size. He
|
||||
also made the win32 timers use higher resolution than before.
|
||||
|
||||
Daniel (29 May 2002)
|
||||
- Renaud Chaillat made me aware of the fact that libcurl returned an error if
|
||||
you tried to get an empty FTP file. This seemed like a wrong thing to do, so
|
||||
now it no longer does that! I just hope that no one built anything fancy
|
||||
upon this unexpected behavior...
|
||||
|
||||
Daniel (28 May 2002)
|
||||
- Cris Bailiff brought CURLOPT_CAPATH that works like CURLOPT_CAINFO but
|
||||
specifies a path to a directory with certificates rather than a single file
|
||||
with them all concatenated. --capath was added to the command line tool
|
||||
for the same function.
|
||||
|
||||
Windows users need to pay attention that the directory should be setup with
|
||||
the c_rehash tool of the OpenSSL package, and that creates symlinks by
|
||||
default that need to be replaced with actual copies to work on Windows.
|
||||
|
||||
- Gustaf Hui provided new code that changes how curl_multi_info_read()
|
||||
messages are stored, so that they don't have to be kept around for the multi
|
||||
handle's entire life time. He also made it return failure codes properly
|
||||
which it didn't do before.
|
||||
|
||||
Daniel (27 May 2002)
|
||||
- Gustaf Hui pointed out that running curl_multi_perform() without doing
|
||||
curl_multi_fdset() first was not really a working combo. I added an internal
|
||||
check for this and have some extra select() code without timeout to make the
|
||||
library internals work identically nevertheless. We might need to somehow
|
||||
either document that once you've used the *_fdset() you should remain using
|
||||
them in select() or you should blank them somehow so that libcurl won't go
|
||||
crazy.
|
||||
|
||||
Version 7.9.8-pre1
|
||||
|
||||
Daniel (22 May 2002)
|
||||
- James Cone brought an excellent patch, including several tests and docs!
|
||||
CURLOPT_NETRC now takes an enum as argument instead of the previous boolean.
|
||||
--netrc-optional was introduced as an addition to --netrc to allow the
|
||||
command line client to take use of all that new netrc stuff.
|
||||
|
||||
- Bug report #558888 showed a case where libcurl re-used the previous host
|
||||
name when a connection over a proxy was re-used but to a different target
|
||||
host.
|
||||
|
||||
Daniel (21 May 2002)
|
||||
- Edin Kadribasic helped me sort out a problem to made libcurl crash when
|
||||
trying to HTTP POST an empty string.
|
||||
|
||||
- Clarified that Juergen Wilke donated the original tests/server/sws.c code.
|
||||
|
||||
- Jean-Philippe Barrette-LaPierre made curl_formadd() return a typedef named
|
||||
CURLFORMcode instead of the previous 'int', and the various return codes are
|
||||
now globally exported. It allows applications to better figure out what goes
|
||||
wrong when curl_formadd() returns errors.
|
||||
|
||||
Daniel (20 May 2002)
|
||||
- Roland Zimmermann pointed out that SSL_CTX_use_certificate_chain_file()
|
||||
is prefered to SSL_CTX_use_certificate_file().
|
||||
|
||||
Daniel (17 May 2002)
|
||||
- Bug report #556869 pointed out that src/writeout.c didn't compile on freebsd
|
||||
after my AIX fixes the other week.
|
||||
|
||||
- Bug report #556930 pointed out a FreeBSD core dump introduced in 7.9.7 in
|
||||
the DNS struct realloc stuff. Actually, this crash could happen on all
|
||||
systems that made the pack_hostent() function get invoked.
|
||||
|
||||
- I removed several compiler warnings in the test suite's HTTP server.
|
||||
|
||||
Version 7.9.7
|
||||
|
||||
Daniel (10 May 2002)
|
||||
|
21
acconfig.h
21
acconfig.h
@@ -64,3 +64,24 @@
|
||||
|
||||
/* Define this to 'int' if in_addr_t is not an available typedefed type */
|
||||
#undef in_addr_t
|
||||
|
||||
/* Define to disable DICT */
|
||||
#undef CURL_DISABLE_DICT
|
||||
|
||||
/* Define to disable FILE */
|
||||
#undef CURL_DISABLE_FILE
|
||||
|
||||
/* Define to disable FTP */
|
||||
#undef CURL_DISABLE_FTP
|
||||
|
||||
/* Define to disable GOPHER */
|
||||
#undef CURL_DISABLE_GOPHER
|
||||
|
||||
/* Define to disable HTTP */
|
||||
#undef CURL_DISABLE_HTTP
|
||||
|
||||
/* Define to disable LDAP */
|
||||
#undef CURL_DISABLE_LDAP
|
||||
|
||||
/* Define to disable TELNET */
|
||||
#undef CURL_DISABLE_TELNET
|
||||
|
150
configure.in
150
configure.in
@@ -56,24 +56,117 @@ dnl AC_PROG_INSTALL
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
dnl ************************************************************
|
||||
dnl lame option to switch on debug options
|
||||
dnl switch off particular protocols
|
||||
dnl
|
||||
AC_MSG_CHECKING([whether to enable debug options])
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug Enable pedantic debug options
|
||||
--disable-debug Disable debug options],
|
||||
AC_MSG_CHECKING([whether to support http])
|
||||
AC_ARG_ENABLE(http,
|
||||
[ --enable-http Enable HTTP support
|
||||
--disable-http Disable HTTP support],
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(CURL_DISABLE_HTTP)
|
||||
AC_MSG_WARN([disable HTTP disables FTP over proxy and GOPHER too])
|
||||
AC_DEFINE(CURL_DISABLE_GOPHER)
|
||||
AC_SUBST(CURL_DISABLE_HTTP)
|
||||
AC_SUBST(CURL_DISABLE_GOPHER)
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
|
||||
CPPFLAGS="$CPPFLAGS -DMALLOCDEBUG"
|
||||
CFLAGS="-W -Wall -Wwrite-strings -pedantic -Wundef -Wpointer-arith -Wcast-align -Wnested-externs -g"
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
AC_MSG_CHECKING([whether to support ftp])
|
||||
AC_ARG_ENABLE(ftp,
|
||||
[ --enable-ftp Enable FTP support
|
||||
--disable-ftp Disable FTP support],
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(CURL_DISABLE_FTP)
|
||||
AC_SUBST(CURL_DISABLE_FTP)
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
AC_MSG_CHECKING([whether to support gopher])
|
||||
AC_ARG_ENABLE(gopher,
|
||||
[ --enable-gopher Enable GOPHER support
|
||||
--disable-gopher Disable GOPHER support],
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(CURL_DISABLE_GOPHER)
|
||||
AC_SUBST(CURL_DISABLE_GOPHER)
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
AC_MSG_CHECKING([whether to support file])
|
||||
AC_ARG_ENABLE(file,
|
||||
[ --enable-file Enable FILE support
|
||||
--disable-file Disable FILE support],
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(CURL_DISABLE_FILE)
|
||||
AC_SUBST(CURL_DISABLE_FILE)
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
AC_MSG_CHECKING([whether to support ldap])
|
||||
AC_ARG_ENABLE(ldap,
|
||||
[ --enable-ldap Enable LDAP support
|
||||
--disable-ldap Disable LDAP support],
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(CURL_DISABLE_LDAP)
|
||||
AC_SUBST(CURL_DISABLE_LDAP)
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
AC_MSG_CHECKING([whether to support dict])
|
||||
AC_ARG_ENABLE(dict,
|
||||
[ --enable-dict Enable DICT support
|
||||
--disable-dict Disable DICT support],
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(CURL_DISABLE_DICT)
|
||||
AC_SUBST(CURL_DISABLE_DICT)
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
AC_MSG_CHECKING([whether to support telnet])
|
||||
AC_ARG_ENABLE(telnet,
|
||||
[ --enable-telnet Enable TELNET support
|
||||
--disable-telnet Disable TELNET support],
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(CURL_DISABLE_TELNET)
|
||||
AC_SUBST(CURL_DISABLE_TELNET)
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Checks for IPv6
|
||||
@@ -510,7 +603,8 @@ AC_CHECK_HEADERS( \
|
||||
io.h \
|
||||
pwd.h \
|
||||
utime.h \
|
||||
sys/utime.h
|
||||
sys/utime.h \
|
||||
setjmp.h
|
||||
)
|
||||
|
||||
dnl Check for libz header
|
||||
@@ -565,9 +659,23 @@ AC_CHECK_FUNCS( socket \
|
||||
getpwuid \
|
||||
geteuid \
|
||||
dlopen \
|
||||
utime
|
||||
utime \
|
||||
sigsetjmp
|
||||
)
|
||||
|
||||
dnl sigsetjmp() might be a macro and no function so if it isn't found already
|
||||
dnl we make an extra check here!
|
||||
if test "$ac_cv_func_sigsetjmp" != "yes"; then
|
||||
AC_MSG_CHECKING([for sigsetjmp defined as macro])
|
||||
AC_TRY_LINK( [#include <setjmp.h>],
|
||||
[sigjmp_buf jmpenv;
|
||||
sigsetjmp(jmpenv, 1);],
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SIGSETJMP),
|
||||
AC_MSG_RESULT(no)
|
||||
)
|
||||
fi
|
||||
|
||||
dnl removed 'getpass' check on October 26, 2000
|
||||
|
||||
if test "$ac_cv_func_select" != "yes"; then
|
||||
@@ -591,6 +699,26 @@ dnl AC_PATH_PROG( RANLIB, ranlib, /usr/bin/ranlib,
|
||||
dnl $PATH:/usr/bin/:/usr/local/bin )
|
||||
dnl AC_SUBST(RANLIB)
|
||||
|
||||
dnl ************************************************************
|
||||
dnl lame option to switch on debug options
|
||||
dnl
|
||||
AC_MSG_CHECKING([whether to enable debug options])
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug Enable pedantic debug options
|
||||
--disable-debug Disable debug options],
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
|
||||
CPPFLAGS="$CPPFLAGS -DMALLOCDEBUG"
|
||||
CFLAGS="-W -Wall -Wwrite-strings -pedantic -Wundef -Wpointer-arith -Wcast-align -Wnested-externs -g"
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(no)
|
||||
)
|
||||
|
||||
AC_CONFIG_FILES([Makefile \
|
||||
docs/Makefile \
|
||||
docs/examples/Makefile \
|
||||
|
@@ -61,6 +61,27 @@ while test $# -gt 0; do
|
||||
if test "@IPV6_ENABLED@" = "1"; then
|
||||
echo "IPv6"
|
||||
fi
|
||||
if test "@CURL_DISABLE_HTTP@" = "1"; then
|
||||
echo "HTTP-disabled"
|
||||
fi
|
||||
if test "@CURL_DISABLE_FTP@" = "1"; then
|
||||
echo "FTP-disabled"
|
||||
fi
|
||||
if test "@CURL_DISABLE_GOPHER@" = "1"; then
|
||||
echo "GOPHER-disabled"
|
||||
fi
|
||||
if test "@CURL_DISABLE_FILE@" = "1"; then
|
||||
echo "FILE-disabled"
|
||||
fi
|
||||
if test "@CURL_DISABLE_TELNET@" = "1"; then
|
||||
echo "TELNET-disabled"
|
||||
fi
|
||||
if test "@CURL_DISABLE_LDAP@" = "1"; then
|
||||
echo "LDAP-disabled"
|
||||
fi
|
||||
if test "@CURL_DISABLE_DICT@" = "1"; then
|
||||
echo "DICT-disabled"
|
||||
fi
|
||||
;;
|
||||
|
||||
--version)
|
||||
|
@@ -45,9 +45,14 @@ Lua
|
||||
Written by Steve Dekorte.
|
||||
http://curl.haxx.se/libcurl/lua/
|
||||
|
||||
Object-Pascal
|
||||
|
||||
Free Pascal, Delphi and Kylix binding written by Christophe Espern.
|
||||
http://www.tekool.com/opcurl
|
||||
|
||||
Pascal
|
||||
|
||||
Free Pascal binding written by Jeffrey Pohlmeyer.
|
||||
Free Pascal, Delphi and Kylix binding written by Jeffrey Pohlmeyer.
|
||||
http://houston.quik.com/jkp/curlpas/
|
||||
|
||||
Perl
|
||||
|
62
docs/FAQ
62
docs/FAQ
@@ -1,4 +1,4 @@
|
||||
Updated: April 27, 2002 (http://curl.haxx.se/docs/faq.shtml)
|
||||
Updated: May 23, 2002 (http://curl.haxx.se/docs/faq.html)
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
@@ -31,14 +31,15 @@ FAQ
|
||||
3.3 Why doesn't my posting using -F work?
|
||||
3.4 How do I tell curl to run custom FTP commands?
|
||||
3.5 How can I disable the Pragma: nocache header?
|
||||
3.6 Does curl support javascript, ASP, XML, XHTML or HTML version Y?
|
||||
3.6 Does curl support ASP, XML, XHTML or HTML version Y?
|
||||
3.7 Can I use curl to delete/rename a file through FTP?
|
||||
3.8 How do I tell curl to follow HTTP redirects?
|
||||
3.9 How do I use curl in my favourite programming language?
|
||||
3.9 How do I use curl in my favorite programming language?
|
||||
3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP?
|
||||
3.11 How do I POST with a different Content-Type?
|
||||
3.12 Why do FTP specific features over HTTP proxy fail?
|
||||
3.13 Why does my single/double quotes fail?
|
||||
3.14 Does curl support javascript or pac (automated proxy config)?
|
||||
|
||||
4. Running Problems
|
||||
4.1 Problems connecting to SSL servers.
|
||||
@@ -56,6 +57,7 @@ FAQ
|
||||
4.7 How do I keep user names and passwords secret in Curl command lines?
|
||||
4.8 I found a bug!
|
||||
4.9 Curl can't authenticate to the server that requires NTLM?
|
||||
4.10 My HTTP request using HEAD, PUT or DELETE doesn't work!
|
||||
|
||||
5. libcurl Issues
|
||||
5.1 Is libcurl thread-safe?
|
||||
@@ -201,7 +203,7 @@ FAQ
|
||||
mailing lists are listed in the MANUAL document and online at
|
||||
http://curl.haxx.se/mail/
|
||||
|
||||
Keeping curl-related questions and dicussions on mailing lists allows others
|
||||
Keeping curl-related questions and discussions on mailing lists allows others
|
||||
to join in and help, to share their ideas, contribute their suggestions and
|
||||
spread their wisdom. Keeping discussions on public mailing lists also allows
|
||||
for others to learn from this (both current and future users thanks to the
|
||||
@@ -324,16 +326,14 @@ FAQ
|
||||
the -H/--header option. By adding a header with empty contents you safely
|
||||
disable that one. Use -H "Pragma:" to disable that specific header.
|
||||
|
||||
3.6. Does curl support javascript, ASP, XML, XHTML or HTML version Y?
|
||||
3.6. Does curl support ASP, XML, XHTML or HTML version Y?
|
||||
|
||||
To curl, all contents are alike. It doesn't matter how the page was
|
||||
generated. It may be ASP, PHP, Perl, shell-script, SSI or plain
|
||||
HTML-files. There's no difference to curl and it doesn't even know what kind
|
||||
of language that generated the page.
|
||||
|
||||
Javascript is slightly different since that is code embedded in the HTML
|
||||
that is sent for the client to interpret and curl has no javascript
|
||||
interpreter.
|
||||
See also item 3.14 regarding javascript.
|
||||
|
||||
3.7. Can I use curl to delete/rename a file through FTP?
|
||||
|
||||
@@ -351,7 +351,7 @@ FAQ
|
||||
|
||||
curl -L http://redirector.com
|
||||
|
||||
3.9 How do I use curl in my favourite programming language?
|
||||
3.9 How do I use curl in my favorite programming language?
|
||||
|
||||
There exist many language interfaces/bindings for curl that integrates it
|
||||
better with various languages. If you are fluid in a script language, you
|
||||
@@ -388,7 +388,7 @@ FAQ
|
||||
|
||||
Because when you use a HTTP proxy, the protocol spoken on the network will
|
||||
be HTTP, even if you specify a FTP URL. This effectively means that you
|
||||
normally can't use FTP specific features such as ftp upload and ftp quote
|
||||
normally can't use FTP specific features such as FTP upload and FTP quote
|
||||
etc.
|
||||
|
||||
There is one exception to this rule, and that is if you can "tunnel through"
|
||||
@@ -408,17 +408,41 @@ FAQ
|
||||
curl -d ' with spaces ' url.com
|
||||
|
||||
Exactly what kind of quotes and how to do this is entirely up to the shell
|
||||
or command line interepreter that you are using. For most unix shells, you
|
||||
or command line interpreter that you are using. For most unix shells, you
|
||||
can more or less pick either single (') or double (") quotes. For
|
||||
Windows/DOS prompts I believe you're forced to use double (") quotes.
|
||||
|
||||
Please study the documentaion for your particular environment. Examples in
|
||||
Please study the documentation for your particular environment. Examples in
|
||||
the curl docs will use a mix of both these ones as shown above. You must
|
||||
adjust them to work in your environment.
|
||||
|
||||
Remember that curl works and runs on more operating systems than most single
|
||||
individuals have ever tried.
|
||||
|
||||
3.14 Does curl support javascript or pac (automated proxy config)?
|
||||
|
||||
Many web pages do magic stuff using embedded javascript. Curl and libcurl
|
||||
have no built-in support for that, so it will be treated just like any other
|
||||
contents.
|
||||
|
||||
.pac files are a netscape invention and are sometimes used by organizations
|
||||
to allow them to differentiate which proxies to use. The .pac contents is
|
||||
just a javascript program that gets invoked by the browser and that returns
|
||||
the name of the proxy to connect to. Since curl doesn't support javascript,
|
||||
it can't support .pac proxy configuration either.
|
||||
|
||||
Some work-arounds usually suggested to overcome this javascript dependency:
|
||||
|
||||
- Depending on the javascript complexity, write up a script that
|
||||
translates it to another language and execute that.
|
||||
|
||||
- Read the javascript code and rewrite the same logic in another language.
|
||||
|
||||
- Implement a javascript interpreted, people have successfully used the
|
||||
Mozilla javascript engine in the past.
|
||||
|
||||
- Ask your admins to stop this, for a static proxy setup or similar.
|
||||
|
||||
|
||||
4. Running Problems
|
||||
|
||||
@@ -511,7 +535,7 @@ FAQ
|
||||
|
||||
4.5.6 "301 Moved Permanently"
|
||||
|
||||
If you get this return code and an HTML outpt similar to this:
|
||||
If you get this return code and an HTML output similar to this:
|
||||
|
||||
<H1>Moved Permanently</H1> The document has moved <A
|
||||
HREF="http://same_url_now_with_a_trailing_slash/">here</A>.
|
||||
@@ -562,6 +586,18 @@ FAQ
|
||||
currently support that. Proprietary formats are evil. You should not use
|
||||
such ones.
|
||||
|
||||
4.10 My HTTP request using HEAD, PUT or DELETE doesn't work!
|
||||
|
||||
Many web servers allow or demand that the administrator configures the
|
||||
server properly for these requests to work on the web server.
|
||||
|
||||
Some servers seem to support HEAD only on certain kinds of URLs.
|
||||
|
||||
To fully grasp this, try the documentation for the particular server
|
||||
software you're trying to interact with. This is not anything curl can do
|
||||
anything about.
|
||||
|
||||
|
||||
5. libcurl Issues
|
||||
|
||||
5.1. Is libcurl thread-safe?
|
||||
|
@@ -434,6 +434,7 @@ PORTS
|
||||
- i386 SCO unix
|
||||
- i386 Solaris 2.7
|
||||
- i386 Windows 95, 98, ME, NT, 2000
|
||||
- i386 QNX 6
|
||||
- ia64 Linux 2.3.99
|
||||
- m68k AmigaOS 3
|
||||
- m68k Linux
|
||||
|
@@ -716,9 +716,9 @@ NETRC
|
||||
passwords, so therefor most unix programs won't read this file unless it is
|
||||
only readable by yourself (curl doesn't care though).
|
||||
|
||||
Curl supports .netrc files if told so (using the -n/--netrc option). This is
|
||||
not restricted to only ftp, but curl can use it for all protocols where
|
||||
authentication is used.
|
||||
Curl supports .netrc files if told so (using the -n/--netrc and
|
||||
--netrc-optional options). This is not restricted to only ftp,
|
||||
but curl can use it for all protocols where authentication is used.
|
||||
|
||||
A very simple .netrc file could look something like:
|
||||
|
||||
|
10
docs/TODO
10
docs/TODO
@@ -17,16 +17,10 @@ TODO
|
||||
|
||||
* Make content encoding/decoding internally be made using a filter system.
|
||||
|
||||
* Test the 'multi' interface more.
|
||||
|
||||
* Introduce another callback interface for upload/download that makes one
|
||||
less copy of data and thus a faster operation.
|
||||
[http://curl.haxx.se/dev/no_copy_callbacks.txt]
|
||||
|
||||
* Add configure options that disables certain protocols in libcurl to
|
||||
decrease footprint. '--disable-[protocol]' where protocol is http, ftp,
|
||||
telnet, ldap, dict or file.
|
||||
|
||||
* Add asynchronous name resolving. http://curl.haxx.se/dev/async-resolver.txt
|
||||
This should be made to work on most of the supported platforms, or
|
||||
otherwise it isn't really interesting.
|
||||
@@ -59,6 +53,10 @@ TODO
|
||||
* Make the built-in progress meter use its own dedicated output stream, and
|
||||
make it possible to set it. Use stderr by default.
|
||||
|
||||
* CURLOPT_MAXFILESIZE. Prevent downloads that are larger than the specified
|
||||
size. CURLE_FILESIZE_EXCEEDED would then be returned. Gautam Mani
|
||||
requested.
|
||||
|
||||
DOCUMENTATION
|
||||
|
||||
|
||||
|
12
docs/curl.1
12
docs/curl.1
@@ -211,7 +211,17 @@ certificate concatenated!
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--cacert <CA certificate>"
|
||||
(HTTPS) Tells curl to use the specified certificate file to verify the
|
||||
peer. The certificate must be in PEM format.
|
||||
peer. The file may contain multiple CA certificates. The certificate(s) must
|
||||
be in PEM format.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--capath <CA certificate directory>"
|
||||
(HTTPS) Tells curl to use the specified certificate directory to verify the
|
||||
peer. The certificates must be in PEM format, and the directory must have been
|
||||
processed using the c_rehash utility supplied with openssl. Certificate directories
|
||||
are not supported under Windows (because c_rehash uses symbolink links to
|
||||
create them). Using --capath can allow curl to make https connections much
|
||||
more efficiently than using --cacert if the --cacert file contains many CA certificates.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-f/--fail"
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_easy_setopt 3 "3 May 2002" "libcurl 7.9.6" "libcurl Manual"
|
||||
.TH curl_easy_setopt 3 "28 May 2002" "libcurl 7.9.8" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_setopt - Set curl easy-session options
|
||||
.SH SYNOPSIS
|
||||
@@ -181,10 +181,39 @@ A non-zero parameter tells the library to append to the remote file instead of
|
||||
overwrite it. This is only useful when uploading to a ftp site.
|
||||
.TP
|
||||
.B CURLOPT_NETRC
|
||||
A non-zero parameter tells the library to scan your \fI~/.netrc\fP file to
|
||||
find user name and password for the remote site you are about to access. Only
|
||||
machine name, user name and password is taken into account (init macros and
|
||||
similar things aren't supported).
|
||||
This parameter controls the preference of libcurl between using user names and
|
||||
passwords from your \fI~/.netrc\fP file, relative to user names and passwords
|
||||
in the URL supplied with \fICURLOPT_URL\fP.
|
||||
|
||||
\fBNote:\fP libcurl uses a user name (and supplied or prompted password)
|
||||
supplied with \fICURLOPT_USERPWD\fP in preference to any of the options
|
||||
controlled by this parameter.
|
||||
|
||||
Pass a long, set to one of the values described below.
|
||||
.RS
|
||||
.TP 5
|
||||
.B CURL_NETRC_OPTIONAL
|
||||
The use of your \fI~/.netrc\fP file is optional,
|
||||
and information in the URL is to be preferred. The file will be scanned
|
||||
with the host and user name (to find the password only) or with the host only,
|
||||
to find the first user name and password after that \fImachine\fP,
|
||||
which ever information is not specified in the URL.
|
||||
|
||||
Undefined values of the option will have this effect.
|
||||
.TP
|
||||
.B CURL_NETRC_IGNORED
|
||||
The library will ignore the file and use only the information in the URL.
|
||||
|
||||
This is the default.
|
||||
.TP
|
||||
.B CURL_NETRC_REQUIRED
|
||||
This value tells the library that use of the file is required,
|
||||
to ignore the information in the URL,
|
||||
and to search the file with the host only.
|
||||
.RE
|
||||
.TP
|
||||
Only machine name, user name and password are taken into account
|
||||
(init macros and similar things aren't supported).
|
||||
|
||||
\fBNote:\fP libcurl does not verify that the file has the correct properties
|
||||
set (as the standard Unix ftp client does). It should only be readable by
|
||||
@@ -485,12 +514,20 @@ argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP.
|
||||
.B CURLOPT_SSL_VERIFYPEER
|
||||
Pass a long that is set to a non-zero value to make curl verify the peer's
|
||||
certificate. The certificate to verify against must be specified with the
|
||||
CURLOPT_CAINFO option. (Added in 7.4.2)
|
||||
CURLOPT_CAINFO option (Added in 7.4.2) or a certificate directory must be specified
|
||||
with the CURLOPT_CAPATH option (Added in 7.9.8).
|
||||
.TP
|
||||
.B CURLOPT_CAINFO
|
||||
Pass a char * to a zero terminated file naming holding the certificate to
|
||||
verify the peer with. This only makes sense when used in combination with the
|
||||
CURLOPT_SSL_VERIFYPEER option. (Added in 7.4.2)
|
||||
Pass a char * to a zero terminated string naming a file holding one or more
|
||||
certificates to verify the peer with. This only makes sense when used in
|
||||
combination with the CURLOPT_SSL_VERIFYPEER option. (Added in 7.4.2)
|
||||
.TP
|
||||
.B CURLOPT_CAPATH
|
||||
Pass a char * to a zero terminated string naming a directory holding multiple CA
|
||||
certificates to verify the peer with. The certificate directory must be prepared using
|
||||
the openssl c_rehash utility. This only makes sense when used in combination with the
|
||||
CURLOPT_SSL_VERIFYPEER option. The CAPATH function apparently does not work in Windows
|
||||
due to some limitation in openssl. (Added in 7.9.8)
|
||||
.TP
|
||||
.B CURLOPT_PASSWDFUNCTION
|
||||
Pass a pointer to a \fIcurl_passwd_callback\fP function that will be called
|
||||
|
@@ -2,13 +2,13 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_formadd 3 "1 Match 2002" "libcurl 7.9.1" "libcurl Manual"
|
||||
.TH curl_formadd 3 "21 May 2002" "libcurl 7.9.8" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_formadd - add a section to a multipart/formdata HTTP POST
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
.sp
|
||||
.BI "int curl_formadd(struct HttpPost ** " firstitem,
|
||||
.BI "CURLFORMcode curl_formadd(struct HttpPost ** " firstitem,
|
||||
.BI "struct HttpPost ** " lastitem, " ...);"
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
@@ -83,7 +83,9 @@ you call \fIcurl_form_free\fP and \fIcurl_easy_cleanup\fP.
|
||||
|
||||
See example below.
|
||||
.SH RETURN VALUE
|
||||
Returns non-zero if an error occurs.
|
||||
0 means everything was ok, non-zero means an error occurred as
|
||||
.I <curl/curl.h>
|
||||
defines.
|
||||
.SH EXAMPLE
|
||||
.nf
|
||||
|
||||
|
@@ -65,6 +65,11 @@ struct curl_httppost {
|
||||
long namelength; /* length of name length */
|
||||
char *contents; /* pointer to allocated data contents */
|
||||
long contentslength; /* length of contents field */
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
char *buffer; /* pointer to allocated buffer contents */
|
||||
long bufferlength; /* length of buffer field */
|
||||
|
||||
char *contenttype; /* Content-Type */
|
||||
struct curl_slist* contentheader; /* list of extra headers for this form */
|
||||
struct curl_httppost *more; /* if one field name has more than one file, this
|
||||
@@ -76,6 +81,11 @@ struct curl_httppost {
|
||||
do not free in formfree */
|
||||
#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
|
||||
do not free in formfree */
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
|
||||
#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
|
||||
|
||||
char *showfilename; /* The file name to show. If not set, the actual
|
||||
file name will be used (if this is a file part) */
|
||||
};
|
||||
@@ -379,7 +389,11 @@ typedef enum {
|
||||
CINIT(FTPLISTONLY, LONG, 48), /* Use NLST when listing ftp dir */
|
||||
|
||||
CINIT(FTPAPPEND, LONG, 50), /* Append instead of overwrite on upload! */
|
||||
CINIT(NETRC, LONG, 51), /* read user+password from .netrc */
|
||||
|
||||
/* Specify whether to read the user+password from the .netrc or the URL.
|
||||
* This must be one of the CURL_NETRC_* enums below. */
|
||||
CINIT(NETRC, LONG, 51),
|
||||
|
||||
CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */
|
||||
|
||||
/* This FTPASCII name is now obsolete, to be removed, use the TRANSFERTEXT
|
||||
@@ -541,6 +555,10 @@ typedef enum {
|
||||
/* mark this as start of a cookie session */
|
||||
CINIT(COOKIESESSION, LONG, 96),
|
||||
|
||||
/* The CApath directory used to validate the peer certificate
|
||||
this option is used only if SSL_VERIFYPEER is true */
|
||||
CINIT(CAPATH, OBJECTPOINT, 97),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unusued */
|
||||
} CURLoption;
|
||||
|
||||
@@ -560,6 +578,18 @@ enum {
|
||||
CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
|
||||
};
|
||||
|
||||
/* These enums are for use with the CURLOPT_NETRC option. */
|
||||
enum CURL_NETRC_OPTION {
|
||||
CURL_NETRC_IGNORED, /* The .netrc will never be read.
|
||||
* This is the default. */
|
||||
CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred
|
||||
* to one in the .netrc. */
|
||||
CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored.
|
||||
* Unless one is set programmatically, the .netrc
|
||||
* will be queried. */
|
||||
CURL_NETRC_LAST
|
||||
};
|
||||
|
||||
enum {
|
||||
CURL_SSLVERSION_DEFAULT,
|
||||
CURL_SSLVERSION_TLSv1,
|
||||
@@ -638,6 +668,11 @@ typedef enum {
|
||||
CFINIT(ARRAY),
|
||||
CFINIT(OBSOLETE),
|
||||
CFINIT(FILE),
|
||||
|
||||
CFINIT(BUFFER),
|
||||
CFINIT(BUFFERPTR),
|
||||
CFINIT(BUFFERLENGTH),
|
||||
|
||||
CFINIT(CONTENTTYPE),
|
||||
CFINIT(CONTENTHEADER),
|
||||
CFINIT(FILENAME),
|
||||
@@ -656,7 +691,35 @@ struct curl_forms {
|
||||
};
|
||||
|
||||
/* use this for multipart formpost building */
|
||||
int curl_formadd(struct curl_httppost **httppost,
|
||||
/* Returns code for curl_formadd()
|
||||
*
|
||||
* Returns:
|
||||
* CURL_FORMADD_OK on success
|
||||
* CURL_FORMADD_MEMORY if the FormInfo allocation fails
|
||||
* CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
|
||||
* CURL_FORMADD_NULL if a null pointer was given for a char
|
||||
* CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
|
||||
* CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
|
||||
* CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
|
||||
* CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated
|
||||
* CURL_FORMADD_MEMORY if some allocation for string copying failed.
|
||||
* CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
|
||||
*
|
||||
***************************************************************************/
|
||||
typedef enum {
|
||||
CURL_FORMADD_OK, /* first, no error */
|
||||
|
||||
CURL_FORMADD_MEMORY,
|
||||
CURL_FORMADD_OPTION_TWICE,
|
||||
CURL_FORMADD_NULL,
|
||||
CURL_FORMADD_UNKNOWN_OPTION,
|
||||
CURL_FORMADD_INCOMPLETE,
|
||||
CURL_FORMADD_ILLEGAL_ARRAY,
|
||||
|
||||
CURL_FORMADD_LAST /* last */
|
||||
} CURLFORMcode;
|
||||
|
||||
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||
struct curl_httppost **last_post,
|
||||
...);
|
||||
|
||||
@@ -684,8 +747,8 @@ CURLcode curl_global_init(long flags);
|
||||
void curl_global_cleanup(void);
|
||||
|
||||
/* This is the version number */
|
||||
#define LIBCURL_VERSION "7.9.7"
|
||||
#define LIBCURL_VERSION_NUM 0x070907
|
||||
#define LIBCURL_VERSION "7.9.8"
|
||||
#define LIBCURL_VERSION_NUM 0x070908
|
||||
|
||||
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
||||
struct curl_slist {
|
||||
|
@@ -61,7 +61,7 @@ libcurl.a: $(libcurl_a_OBJECTS) $(libcurl_a_DEPENDENCIES)
|
||||
|
||||
libcurl.dll libcurldll.a: libcurl.a libcurl.def dllinit.o
|
||||
-@erase $@
|
||||
dllwrap --dllname $@ --output-lib libcurldll.a --export-all --def libcurl.def $(libcurl_a_LIBRARIES) dllinit.o -L$(OPENSSL_PATH)/out $(DLL_LIBS) -lwsock32 -lws2_32
|
||||
dllwrap --dllname $@ --output-lib libcurldll.a --export-all --def libcurl.def $(libcurl_a_LIBRARIES) dllinit.o -L$(OPENSSL_PATH)/out $(DLL_LIBS) -lwsock32 -lws2_32 -lwinmm
|
||||
$(STRIP) $@
|
||||
|
||||
# remove the last line above to keep debug info
|
||||
|
@@ -198,7 +198,8 @@ X_OBJS= \
|
||||
$(DIROBJ)\strtok.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\llist.obj
|
||||
$(DIROBJ)\llist.obj \
|
||||
$(DIROBJ)\multi.obj
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef CURL_DISABLE_TELNET
|
||||
/*
|
||||
* Telnet option defines. Add more here if in need.
|
||||
*/
|
||||
@@ -97,5 +97,5 @@ static const char *telnetcmds[]=
|
||||
#define TELCMD_OK(x) ( ((unsigned int)(x) >= TELCMD_MINIMUM) && \
|
||||
((unsigned int)(x) <= TELCMD_MAXIMUM) )
|
||||
#define TELCMD(x) telnetcmds[(x)-TELCMD_MINIMUM]
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -366,3 +366,6 @@
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
#define HAVE_FIONBIO 1
|
||||
|
||||
/* Define if you have the `sigsetjmp' function. */
|
||||
#define HAVE_SIGSETJMP 1
|
||||
|
@@ -179,6 +179,9 @@
|
||||
/* Define if you have the RAND_screen function when using SSL */
|
||||
#define HAVE_RAND_SCREEN 1
|
||||
|
||||
/* Define if you have the `RAND_status' function. */
|
||||
#define HAVE_RAND_STATUS 1
|
||||
|
||||
/* Define this to if in_addr_t is not an available typedefed type */
|
||||
#define in_addr_t unsigned long
|
||||
|
||||
|
@@ -457,6 +457,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
/* we are connected, awesome! */
|
||||
break;
|
||||
}
|
||||
failf(data, "socket error: %d", err);
|
||||
/* we are _not_ connected, it was a false alert, continue please */
|
||||
}
|
||||
|
||||
@@ -580,6 +581,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
/* no good connect was made */
|
||||
sclose(sockfd);
|
||||
*sockconn = -1;
|
||||
failf(data, "Connect failed");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
|
@@ -79,6 +79,8 @@ Example set of cookies:
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
@@ -761,6 +763,8 @@ int main(int argc, char **argv)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
|
||||
/*
|
||||
* local variables:
|
||||
* eval: (load-file "../curl-mode.el")
|
||||
|
@@ -54,7 +54,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib ws2_32.lib /nologo /dll /map /debug /machine:I386 /out:"Release/libcurl.dll"
|
||||
# ADD LINK32 kernel32.lib ws2_32.lib winmm.lib /nologo /dll /map /debug /machine:I386 /out:"Release/libcurl.dll"
|
||||
|
||||
!ELSEIF "$(CFG)" == "curllib - Win32 Debug"
|
||||
|
||||
@@ -81,7 +81,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib ws2_32.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug/libcurl.dll" /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib ws2_32.lib winmm.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug/libcurl.dll" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /nodefaultlib
|
||||
|
||||
!ENDIF
|
||||
|
@@ -23,7 +23,8 @@
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
#ifndef CURL_DISABLE_DICT
|
||||
CURLcode Curl_dict(struct connectdata *conn);
|
||||
CURLcode Curl_dict_done(struct connectdata *conn);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_FILE
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -204,3 +205,4 @@ CURLcode Curl_file(struct connectdata *conn)
|
||||
* vim600: fdm=marker
|
||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||
*/
|
||||
#endif
|
||||
|
@@ -23,6 +23,8 @@
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
#ifndef CURL_DISABLE_FILE
|
||||
CURLcode Curl_file(struct connectdata *conn);
|
||||
CURLcode Curl_file_connect(struct connectdata *conn);
|
||||
#endif
|
||||
#endif
|
||||
|
201
lib/formdata.c
201
lib/formdata.c
@@ -109,6 +109,8 @@ Content-Disposition: form-data; name="FILECONTENT"
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -398,6 +400,10 @@ int curl_formparse(char *input,
|
||||
static struct curl_httppost *
|
||||
AddHttpPost(char * name, long namelength,
|
||||
char * value, long contentslength,
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
char * buffer, long bufferlength,
|
||||
|
||||
char *contenttype,
|
||||
long flags,
|
||||
struct curl_slist* contentHeader,
|
||||
@@ -414,6 +420,11 @@ AddHttpPost(char * name, long namelength,
|
||||
post->namelength = name?(namelength?namelength:(long)strlen(name)):0;
|
||||
post->contents = value;
|
||||
post->contentslength = contentslength;
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
post->buffer = buffer;
|
||||
post->bufferlength = bufferlength;
|
||||
|
||||
post->contenttype = contenttype;
|
||||
post->contentheader = contentHeader;
|
||||
post->showfilename = showfilename;
|
||||
@@ -602,39 +613,26 @@ static int AllocAndCopy (char **buffer, int buffer_length)
|
||||
* CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
|
||||
*
|
||||
* Returns:
|
||||
* FORMADD_OK on success
|
||||
* FORMADD_MEMORY if the FormInfo allocation fails
|
||||
* FORMADD_OPTION_TWICE if one option is given twice for one Form
|
||||
* FORMADD_NULL if a null pointer was given for a char
|
||||
* FORMADD_MEMORY if the allocation of a FormInfo struct failed
|
||||
* FORMADD_UNKNOWN_OPTION if an unknown option was used
|
||||
* FORMADD_INCOMPLETE if the some FormInfo is not complete (or an error)
|
||||
* FORMADD_MEMORY if a HttpPost struct cannot be allocated
|
||||
* FORMADD_MEMORY if some allocation for string copying failed.
|
||||
* FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
|
||||
* CURL_FORMADD_OK on success
|
||||
* CURL_FORMADD_MEMORY if the FormInfo allocation fails
|
||||
* CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
|
||||
* CURL_FORMADD_NULL if a null pointer was given for a char
|
||||
* CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
|
||||
* CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
|
||||
* CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or an error)
|
||||
* CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated
|
||||
* CURL_FORMADD_MEMORY if some allocation for string copying failed.
|
||||
* CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
FORMADD_OK, /* first, no error */
|
||||
|
||||
FORMADD_MEMORY,
|
||||
FORMADD_OPTION_TWICE,
|
||||
FORMADD_NULL,
|
||||
FORMADD_UNKNOWN_OPTION,
|
||||
FORMADD_INCOMPLETE,
|
||||
FORMADD_ILLEGAL_ARRAY,
|
||||
|
||||
FORMADD_LAST /* last */
|
||||
} FORMcode;
|
||||
|
||||
static
|
||||
FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
struct curl_httppost **last_post,
|
||||
va_list params)
|
||||
{
|
||||
FormInfo *first_form, *current_form, *form;
|
||||
FORMcode return_value = FORMADD_OK;
|
||||
CURLFORMcode return_value = CURL_FORMADD_OK;
|
||||
const char *prevtype = NULL;
|
||||
struct curl_httppost *post = NULL;
|
||||
CURLformoption option;
|
||||
@@ -655,7 +653,7 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
current_form = first_form;
|
||||
}
|
||||
else
|
||||
return FORMADD_MEMORY;
|
||||
return CURL_FORMADD_MEMORY;
|
||||
|
||||
/*
|
||||
* Loop through all the options set.
|
||||
@@ -663,7 +661,7 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
while (1) {
|
||||
|
||||
/* break if we have an error to report */
|
||||
if (return_value != FORMADD_OK)
|
||||
if (return_value != CURL_FORMADD_OK)
|
||||
break;
|
||||
|
||||
/* first see if we have more parts of the array param */
|
||||
@@ -690,13 +688,13 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
case CURLFORM_ARRAY:
|
||||
if(array_state)
|
||||
/* we don't support an array from within an array */
|
||||
return_value = FORMADD_ILLEGAL_ARRAY;
|
||||
return_value = CURL_FORMADD_ILLEGAL_ARRAY;
|
||||
else {
|
||||
forms = va_arg(params, struct curl_forms *);
|
||||
if (forms)
|
||||
array_state = TRUE;
|
||||
else
|
||||
return_value = FORMADD_NULL;
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -707,19 +705,19 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
|
||||
case CURLFORM_COPYNAME:
|
||||
if (current_form->name)
|
||||
return_value = FORMADD_OPTION_TWICE;
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else {
|
||||
char *name = array_state?
|
||||
array_value:va_arg(params, char *);
|
||||
if (name)
|
||||
current_form->name = name; /* store for the moment */
|
||||
else
|
||||
return_value = FORMADD_NULL;
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
}
|
||||
break;
|
||||
case CURLFORM_NAMELENGTH:
|
||||
if (current_form->namelength)
|
||||
return_value = FORMADD_OPTION_TWICE;
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else
|
||||
current_form->namelength =
|
||||
array_state?(long)array_value:va_arg(params, long);
|
||||
@@ -732,19 +730,19 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
|
||||
case CURLFORM_COPYCONTENTS:
|
||||
if (current_form->value)
|
||||
return_value = FORMADD_OPTION_TWICE;
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else {
|
||||
char *value =
|
||||
array_state?array_value:va_arg(params, char *);
|
||||
if (value)
|
||||
current_form->value = value; /* store for the moment */
|
||||
else
|
||||
return_value = FORMADD_NULL;
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
}
|
||||
break;
|
||||
case CURLFORM_CONTENTSLENGTH:
|
||||
if (current_form->contentslength)
|
||||
return_value = FORMADD_OPTION_TWICE;
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else
|
||||
current_form->contentslength =
|
||||
array_state?(long)array_value:va_arg(params, long);
|
||||
@@ -753,7 +751,7 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
/* Get contents from a given file name */
|
||||
case CURLFORM_FILECONTENT:
|
||||
if (current_form->flags != 0)
|
||||
return_value = FORMADD_OPTION_TWICE;
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else {
|
||||
char *filename = array_state?
|
||||
array_value:va_arg(params, char *);
|
||||
@@ -762,7 +760,7 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
current_form->flags |= HTTPPOST_READFILE;
|
||||
}
|
||||
else
|
||||
return_value = FORMADD_NULL;
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -777,23 +775,77 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
if (filename) {
|
||||
if (!(current_form = AddFormInfo(strdup(filename),
|
||||
NULL, current_form)))
|
||||
return_value = FORMADD_MEMORY;
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else
|
||||
return_value = FORMADD_NULL;
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
}
|
||||
else
|
||||
return_value = FORMADD_OPTION_TWICE;
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
}
|
||||
else {
|
||||
if (filename)
|
||||
current_form->value = strdup(filename);
|
||||
else
|
||||
return_value = FORMADD_NULL;
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
current_form->flags |= HTTPPOST_FILENAME;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
case CURLFORM_BUFFER:
|
||||
{
|
||||
char *filename = array_state?array_value:
|
||||
va_arg(params, char *);
|
||||
|
||||
if (current_form->value) {
|
||||
if (current_form->flags & HTTPPOST_BUFFER) {
|
||||
if (filename) {
|
||||
if (!(current_form = AddFormInfo(strdup(filename),
|
||||
NULL, current_form)))
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
}
|
||||
else
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
}
|
||||
else {
|
||||
if (filename)
|
||||
current_form->value = strdup(filename);
|
||||
else
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
current_form->flags |= HTTPPOST_BUFFER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
case CURLFORM_BUFFERPTR:
|
||||
current_form->flags |= HTTPPOST_PTRBUFFER;
|
||||
if (current_form->buffer)
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else {
|
||||
char *buffer =
|
||||
array_state?array_value:va_arg(params, char *);
|
||||
if (buffer)
|
||||
current_form->buffer = buffer; /* store for the moment */
|
||||
else
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
case CURLFORM_BUFFERLENGTH:
|
||||
if (current_form->bufferlength)
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else
|
||||
current_form->bufferlength =
|
||||
array_state?(long)array_value:va_arg(params, long);
|
||||
break;
|
||||
|
||||
case CURLFORM_CONTENTTYPE:
|
||||
{
|
||||
char *contenttype =
|
||||
@@ -804,19 +856,19 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
if (!(current_form = AddFormInfo(NULL,
|
||||
strdup(contenttype),
|
||||
current_form)))
|
||||
return_value = FORMADD_MEMORY;
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else
|
||||
return_value = FORMADD_NULL;
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
}
|
||||
else
|
||||
return_value = FORMADD_OPTION_TWICE;
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
}
|
||||
else {
|
||||
if (contenttype)
|
||||
current_form->contenttype = strdup(contenttype);
|
||||
else
|
||||
return_value = FORMADD_NULL;
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -829,7 +881,7 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
va_arg(params, struct curl_slist*);
|
||||
|
||||
if( current_form->contentheader )
|
||||
return_value = FORMADD_OPTION_TWICE;
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else
|
||||
current_form->contentheader = list;
|
||||
|
||||
@@ -840,17 +892,17 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
char *filename = array_state?array_value:
|
||||
va_arg(params, char *);
|
||||
if( current_form->showfilename )
|
||||
return_value = FORMADD_OPTION_TWICE;
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else
|
||||
current_form->showfilename = strdup(filename);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return_value = FORMADD_UNKNOWN_OPTION;
|
||||
return_value = CURL_FORMADD_UNKNOWN_OPTION;
|
||||
}
|
||||
}
|
||||
|
||||
if(FORMADD_OK == return_value) {
|
||||
if(CURL_FORMADD_OK == return_value) {
|
||||
/* go through the list, check for copleteness and if everything is
|
||||
* alright add the HttpPost item otherwise set return_value accordingly */
|
||||
|
||||
@@ -863,14 +915,21 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
(form->flags & HTTPPOST_FILENAME) ) ||
|
||||
( (form->flags & HTTPPOST_FILENAME) &&
|
||||
(form->flags & HTTPPOST_PTRCONTENTS) ) ||
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
( (!form->buffer) &&
|
||||
(form->flags & HTTPPOST_BUFFER) &&
|
||||
(form->flags & HTTPPOST_PTRBUFFER) ) ||
|
||||
|
||||
( (form->flags & HTTPPOST_READFILE) &&
|
||||
(form->flags & HTTPPOST_PTRCONTENTS) )
|
||||
) {
|
||||
return_value = FORMADD_INCOMPLETE;
|
||||
return_value = CURL_FORMADD_INCOMPLETE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if ( (form->flags & HTTPPOST_FILENAME) &&
|
||||
if ( ((form->flags & HTTPPOST_FILENAME) ||
|
||||
(form->flags & HTTPPOST_BUFFER)) &&
|
||||
!form->contenttype ) {
|
||||
/* our contenttype is missing */
|
||||
form->contenttype
|
||||
@@ -880,28 +939,36 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
(form == first_form) ) {
|
||||
/* copy name (without strdup; possibly contains null characters) */
|
||||
if (AllocAndCopy(&form->name, form->namelength)) {
|
||||
return_value = FORMADD_MEMORY;
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !(form->flags & HTTPPOST_FILENAME) &&
|
||||
!(form->flags & HTTPPOST_READFILE) &&
|
||||
!(form->flags & HTTPPOST_PTRCONTENTS) ) {
|
||||
!(form->flags & HTTPPOST_PTRCONTENTS) &&
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
!(form->flags & HTTPPOST_PTRBUFFER) ) {
|
||||
|
||||
/* copy value (without strdup; possibly contains null characters) */
|
||||
if (AllocAndCopy(&form->value, form->contentslength)) {
|
||||
return_value = FORMADD_MEMORY;
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
post = AddHttpPost(form->name, form->namelength,
|
||||
form->value, form->contentslength,
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
form->buffer, form->bufferlength,
|
||||
|
||||
form->contenttype, form->flags,
|
||||
form->contentheader, form->showfilename,
|
||||
post, httppost,
|
||||
last_post);
|
||||
|
||||
if(!post)
|
||||
return_value = FORMADD_MEMORY;
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
|
||||
if (form->contenttype)
|
||||
prevtype = form->contenttype;
|
||||
@@ -922,12 +989,12 @@ FORMcode FormAdd(struct curl_httppost **httppost,
|
||||
return return_value;
|
||||
}
|
||||
|
||||
int curl_formadd(struct curl_httppost **httppost,
|
||||
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||
struct curl_httppost **last_post,
|
||||
...)
|
||||
{
|
||||
va_list arg;
|
||||
int result;
|
||||
CURLFORMcode result;
|
||||
va_start(arg, last_post);
|
||||
result = FormAdd(httppost, last_post, arg);
|
||||
va_end(arg);
|
||||
@@ -1118,7 +1185,11 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
(file->showfilename?file->showfilename:
|
||||
file->contents));
|
||||
}
|
||||
else if(post->flags & HTTPPOST_FILENAME) {
|
||||
else if((post->flags & HTTPPOST_FILENAME) ||
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
(post->flags & HTTPPOST_BUFFER)) {
|
||||
|
||||
size += AddFormDataf(&form,
|
||||
"; filename=\"%s\"",
|
||||
(post->showfilename?post->showfilename:
|
||||
@@ -1164,9 +1235,9 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
|
||||
fileread = strequal("-", file->contents)?stdin:
|
||||
/* binary read for win32 crap */
|
||||
/*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */
|
||||
/*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */
|
||||
/*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
|
||||
/*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */
|
||||
/*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */
|
||||
/*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
|
||||
if(fileread) {
|
||||
while((nread = fread(buffer, 1, 1024, fileread)))
|
||||
size += AddFormData(&form, buffer, nread);
|
||||
@@ -1184,7 +1255,13 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
*finalform = NULL;
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
} else if (post->flags & HTTPPOST_BUFFER) {
|
||||
/* include contents of buffer */
|
||||
size += AddFormData(&form, post->buffer, post->bufferlength);
|
||||
}
|
||||
|
||||
else {
|
||||
/* include the contents we got */
|
||||
size += AddFormData(&form, post->contents, post->contentslength);
|
||||
@@ -1518,6 +1595,8 @@ int main(int argc, char **argv)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
|
||||
/*
|
||||
* local variables:
|
||||
* eval: (load-file "../curl-mode.el")
|
||||
|
@@ -45,6 +45,10 @@ typedef struct FormInfo {
|
||||
char *contenttype;
|
||||
long flags;
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
char *buffer; /* pointer to existing buffer used for file upload */
|
||||
long bufferlength;
|
||||
|
||||
char *showfilename; /* The file name to show. If not set, the actual
|
||||
file name will be used */
|
||||
struct curl_slist* contentheader;
|
||||
|
39
lib/ftp.c
39
lib/ftp.c
@@ -23,6 +23,8 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
/* MN 06/07/02 */
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -635,9 +637,9 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
|
||||
failf(data, "Received only partial file: %d bytes", *ftp->bytecountp);
|
||||
return CURLE_PARTIAL_FILE;
|
||||
}
|
||||
else if(!conn->bits.resume_done &&
|
||||
!data->set.no_body &&
|
||||
(0 == *ftp->bytecountp)) {
|
||||
else if(!ftp->dont_check &&
|
||||
!*ftp->bytecountp &&
|
||||
(conn->size>0)) {
|
||||
/* We consider this an error, but there's no true FTP error received
|
||||
why we need to continue to "read out" the server response too.
|
||||
We don't want to leave a "waiting" server reply if we'll get told
|
||||
@@ -654,9 +656,9 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
|
||||
sclose(conn->secondarysocket);
|
||||
conn->secondarysocket = -1;
|
||||
|
||||
if(!data->set.no_body && !conn->bits.resume_done) {
|
||||
/* now let's see what the server says about the transfer we
|
||||
just performed: */
|
||||
if(!data->set.no_body && !ftp->dont_check) {
|
||||
/* now let's see what the server says about the transfer we just
|
||||
performed: */
|
||||
nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
|
||||
if(nread < 0)
|
||||
return CURLE_OPERATION_TIMEOUTED;
|
||||
@@ -667,6 +669,11 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
|
||||
return CURLE_FTP_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
if(ftp->dont_check) {
|
||||
/* if we don't check, we can't re-use this connection as it leaves the
|
||||
control connection in a weird status */
|
||||
conn->bits.close = TRUE;
|
||||
}
|
||||
|
||||
conn->bits.resume_done = FALSE; /* clean this for next connection */
|
||||
|
||||
@@ -1067,13 +1074,13 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
if (portsock < 0) {
|
||||
failf(data, strerror(errno));
|
||||
failf(data, "%s", strerror(errno));
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
sslen = sizeof(ss);
|
||||
if (getsockname(portsock, sa, &sslen) < 0) {
|
||||
failf(data, strerror(errno));
|
||||
failf(data, "%s", strerror(errno));
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
@@ -1370,7 +1377,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
||||
|
||||
for (modeoff = (data->set.ftp_use_epsv?0:1);
|
||||
mode[modeoff]; modeoff++) {
|
||||
result = Curl_ftpsendf(conn, mode[modeoff]);
|
||||
result = Curl_ftpsendf(conn, "%s", mode[modeoff]);
|
||||
if(result)
|
||||
return result;
|
||||
nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
|
||||
@@ -1597,7 +1604,7 @@ CURLcode ftp_perform(struct connectdata *conn)
|
||||
|
||||
if(data->set.no_body)
|
||||
/* don't transfer the data */
|
||||
;
|
||||
ftp->dont_check = TRUE;
|
||||
/* Get us a second connection up and connected */
|
||||
else if(data->set.ftp_use_port) {
|
||||
/* We have chosen to use the PORT command */
|
||||
@@ -1693,10 +1700,11 @@ CURLcode ftp_perform(struct connectdata *conn)
|
||||
/* no data to transfer */
|
||||
result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
|
||||
/* Set resume done so that we won't get any error in
|
||||
* Curl_ftp_done() because we didn't transfer the amount of bytes
|
||||
* that the local file file obviously is */
|
||||
/* Set resume done and dont_check so that we won't get any error
|
||||
* in Curl_ftp_done() because we didn't transfer the amount of
|
||||
* bytes that the local file file obviously is */
|
||||
conn->bits.resume_done = TRUE;
|
||||
ftp->dont_check = TRUE;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -1785,6 +1793,8 @@ CURLcode ftp_perform(struct connectdata *conn)
|
||||
}
|
||||
infof(data, "range-download from %d to %d, totally %d bytes\n",
|
||||
from, to, totalsize);
|
||||
conn->bits.resume_done = TRUE; /* to prevent some error due to this */
|
||||
ftp->dont_check = TRUE; /* dont check for successful transfer */
|
||||
}
|
||||
|
||||
if((data->set.ftp_list_only) || !ftp->file) {
|
||||
@@ -1881,6 +1891,7 @@ CURLcode ftp_perform(struct connectdata *conn)
|
||||
* because we didn't transfer the amount of bytes that the remote
|
||||
* file obviously is */
|
||||
conn->bits.resume_done = TRUE;
|
||||
ftp->dont_check = TRUE;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -2141,3 +2152,5 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
||||
* vim600: fdm=marker
|
||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||
*/
|
||||
|
||||
#endif /* CURL_DISABLE_FTP */
|
||||
|
@@ -23,6 +23,10 @@
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
/* MN 06/07/02 */
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
|
||||
CURLcode Curl_ftp(struct connectdata *conn);
|
||||
CURLcode Curl_ftp_done(struct connectdata *conn);
|
||||
CURLcode Curl_ftp_connect(struct connectdata *conn);
|
||||
@@ -34,4 +38,8 @@ CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
|
||||
int Curl_GetFTPResponse(char *buf, struct connectdata *conn,
|
||||
int *ftpcode);
|
||||
|
||||
/* MN 06/07/02 */
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
57
lib/hostip.c
57
lib/hostip.c
@@ -56,6 +56,10 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETJMP_H
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
@@ -191,6 +195,11 @@ hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
|
||||
return (__v); \
|
||||
}
|
||||
|
||||
#ifdef HAVE_SIGSETJMP
|
||||
/* Beware this is a global and unique instance */
|
||||
sigjmp_buf curl_jmpenv;
|
||||
#endif
|
||||
|
||||
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||
char *hostname,
|
||||
int port)
|
||||
@@ -201,6 +210,14 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||
time_t now;
|
||||
char *bufp;
|
||||
|
||||
#ifdef HAVE_SIGSETJMP
|
||||
if(sigsetjmp(curl_jmpenv, 1) != 0) {
|
||||
/* this is coming from a siglongjmp() */
|
||||
failf(data, "name lookup time-outed");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the host cache timeout is 0, we don't do DNS cach'ing
|
||||
so fall through */
|
||||
if (data->set.dns_cache_timeout == 0) {
|
||||
@@ -344,7 +361,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
||||
snprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
error = getaddrinfo(hostname, sbuf, &hints, &res);
|
||||
if (error) {
|
||||
infof(data, "getaddrinfo(3) failed for %s\n", hostname);
|
||||
infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
|
||||
return NULL;
|
||||
}
|
||||
*bufp=(char *)res; /* make it point to the result struct */
|
||||
@@ -354,6 +371,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
||||
#else /* following code is IPv4-only */
|
||||
|
||||
#ifndef HAVE_GETHOSTBYNAME_R
|
||||
static void hostcache_fixoffset(struct hostent *h, int offset);
|
||||
/**
|
||||
* Performs a "deep" copy of a hostent into a buffer (returns a pointer to the
|
||||
* copy). Make absolutely sure the destination buffer is big enough!
|
||||
@@ -362,11 +380,12 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
||||
* 10/3/2001 */
|
||||
static struct hostent* pack_hostent(char** buf, struct hostent* orig)
|
||||
{
|
||||
char* bufptr;
|
||||
char *bufptr;
|
||||
char *newbuf;
|
||||
struct hostent* copy;
|
||||
|
||||
int i;
|
||||
char* str;
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
bufptr = *buf;
|
||||
@@ -427,7 +446,18 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
|
||||
}
|
||||
copy->h_addr_list[i] = NULL;
|
||||
|
||||
*buf=(char *)realloc(*buf, (int)bufptr-(int)(*buf));
|
||||
/* now, shrink the allocated buffer to the size we actually need, which
|
||||
most often is only a fraction of the original alloc */
|
||||
newbuf=(char *)realloc(*buf, (int)bufptr-(int)(*buf));
|
||||
|
||||
/* if the alloc moved, we need to adjust things again */
|
||||
if(newbuf != *buf)
|
||||
hostcache_fixoffset((struct hostent*)newbuf, (int)newbuf-(int)*buf);
|
||||
|
||||
/* setup the return */
|
||||
*buf = newbuf;
|
||||
copy = (struct hostent*)newbuf;
|
||||
|
||||
return copy;
|
||||
}
|
||||
#endif
|
||||
@@ -460,16 +490,16 @@ static char *MakeIP(unsigned long num,char *addr, int addr_len)
|
||||
static void hostcache_fixoffset(struct hostent *h, int offset)
|
||||
{
|
||||
int i=0;
|
||||
h->h_name=(char *)((int)h->h_name+offset);
|
||||
h->h_aliases=(char **)((int)h->h_aliases+offset);
|
||||
h->h_name=(char *)((long)h->h_name+offset);
|
||||
h->h_aliases=(char **)((long)h->h_aliases+offset);
|
||||
while(h->h_aliases[i]) {
|
||||
h->h_aliases[i]=(char *)((int)h->h_aliases[i]+offset);
|
||||
h->h_aliases[i]=(char *)((long)h->h_aliases[i]+offset);
|
||||
i++;
|
||||
}
|
||||
h->h_addr_list=(char **)((int)h->h_addr_list+offset);
|
||||
h->h_addr_list=(char **)((long)h->h_addr_list+offset);
|
||||
i=0;
|
||||
while(h->h_addr_list[i]) {
|
||||
h->h_addr_list[i]=(char *)((int)h->h_addr_list[i]+offset);
|
||||
h->h_addr_list[i]=(char *)((long)h->h_addr_list[i]+offset);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -496,7 +526,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
||||
|
||||
if ( (in=inet_addr(hostname)) != INADDR_NONE ) {
|
||||
struct in_addr *addrentry;
|
||||
int *buf = (int *)malloc(128);
|
||||
long *buf = (long *)malloc(sizeof(struct hostent)+128);
|
||||
if(!buf)
|
||||
return NULL; /* major failure */
|
||||
*bufp = (char *)buf;
|
||||
@@ -511,7 +541,8 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
||||
h->h_length = sizeof(*addrentry);
|
||||
h->h_name = *(h->h_addr_list) + h->h_length;
|
||||
/* bad one h->h_name = (char*)(h->h_addr_list + h->h_length); */
|
||||
MakeIP(ntohl(in),h->h_name, 128 - (long)(h->h_name) + (long)buf);
|
||||
MakeIP(ntohl(in),h->h_name, sizeof(struct hostent)+128 -
|
||||
(long)(h->h_name) + (long)buf);
|
||||
}
|
||||
#if defined(HAVE_GETHOSTBYNAME_R)
|
||||
else {
|
||||
@@ -553,7 +584,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
||||
if(h) {
|
||||
int offset;
|
||||
h=(struct hostent *)realloc(buf, step_size);
|
||||
offset=(int)h-(int)buf;
|
||||
offset=(long)h-(long)buf;
|
||||
hostcache_fixoffset(h, offset);
|
||||
buf=(int *)h;
|
||||
*bufp=(char *)buf;
|
||||
@@ -577,7 +608,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
||||
if(!res) {
|
||||
int offset;
|
||||
h=(struct hostent *)realloc(buf, step_size);
|
||||
offset=(int)h-(int)buf;
|
||||
offset=(long)h-(long)buf;
|
||||
hostcache_fixoffset(h, offset);
|
||||
buf=(int *)h;
|
||||
*bufp=(char *)buf;
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -161,7 +162,7 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in,
|
||||
free(in->buffer);
|
||||
free(in);
|
||||
|
||||
*bytes_written = amount;
|
||||
*bytes_written += amount;
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -924,8 +925,9 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
actually set your own */
|
||||
add_bufferf(req_buffer,
|
||||
"Content-Length: %d\r\n",
|
||||
(data->set.postfieldsize?data->set.postfieldsize:
|
||||
strlen(data->set.postfields)) );
|
||||
data->set.postfieldsize?
|
||||
data->set.postfieldsize:
|
||||
(data->set.postfields?strlen(data->set.postfields):0) );
|
||||
|
||||
if(!checkheaders(data, "Content-Type:"))
|
||||
add_bufferf(req_buffer,
|
||||
@@ -986,3 +988,4 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
* vim600: fdm=marker
|
||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||
*/
|
||||
#endif
|
||||
|
@@ -23,7 +23,7 @@
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/* ftp can use this as well */
|
||||
CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
int tunnelsocket,
|
||||
@@ -38,5 +38,5 @@ CURLcode Curl_http_connect(struct connectdata *conn);
|
||||
void Curl_httpchunk_init(struct connectdata *conn);
|
||||
CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
|
||||
ssize_t length, ssize_t *wrote);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -22,6 +22,7 @@
|
||||
*****************************************************************************/
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -228,3 +229,4 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
* vim600: fdm=marker
|
||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||
*/
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
|
@@ -40,6 +40,7 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#ifdef KRB4
|
||||
|
||||
#include "security.h"
|
||||
@@ -391,6 +392,7 @@ void Curl_krb_kauth(struct connectdata *conn)
|
||||
}
|
||||
|
||||
#endif /* KRB4 */
|
||||
#endif /* CURL_DISABLE_FTP */
|
||||
|
||||
/*
|
||||
* local variables:
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_LDAP
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -147,7 +148,7 @@ CURLcode Curl_ldap(struct connectdata *conn)
|
||||
int ldaptext;
|
||||
struct SessionHandle *data=conn->data;
|
||||
|
||||
infof(data, "LDAP: %s %s\n", data->change.url);
|
||||
infof(data, "LDAP: %s\n", data->change.url);
|
||||
|
||||
DynaOpen();
|
||||
if (libldap == NULL) {
|
||||
@@ -229,3 +230,4 @@ CURLcode Curl_ldap(struct connectdata *conn)
|
||||
* vim600: fdm=marker
|
||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||
*/
|
||||
#endif
|
||||
|
@@ -23,7 +23,8 @@
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
#ifndef CURL_DISABLE_LDAP
|
||||
CURLcode Curl_ldap(struct connectdata *conn);
|
||||
CURLcode Curl_ldap_done(struct connectdata *conn);
|
||||
|
||||
#endif
|
||||
#endif /* __LDAP_H */
|
||||
|
@@ -49,7 +49,9 @@
|
||||
|
||||
struct memdebug {
|
||||
int size;
|
||||
char mem[1];
|
||||
double mem[1];
|
||||
/* I'm hoping this is the thing with the strictest alignment
|
||||
* requirements. That also means we waste some space :-( */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -1028,7 +1028,6 @@ static int alloc_addbyter(int output, FILE *data)
|
||||
infop->len++;
|
||||
|
||||
return output; /* fputc() returns like this on success */
|
||||
|
||||
}
|
||||
|
||||
char *curl_maprintf(const char *format, ...)
|
||||
@@ -1044,12 +1043,17 @@ char *curl_maprintf(const char *format, ...)
|
||||
va_start(ap_save, format);
|
||||
retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
|
||||
va_end(ap_save);
|
||||
if(info.len) {
|
||||
if(-1 == retcode) {
|
||||
if(info.alloc)
|
||||
free(info.buffer);
|
||||
return NULL;
|
||||
}
|
||||
if(info.alloc) {
|
||||
info.buffer[info.len] = 0; /* we terminate this with a zero byte */
|
||||
return info.buffer;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return strdup("");
|
||||
}
|
||||
|
||||
char *curl_mvaprintf(const char *format, va_list ap_save)
|
||||
@@ -1062,13 +1066,18 @@ char *curl_mvaprintf(const char *format, va_list ap_save)
|
||||
info.alloc = 0;
|
||||
|
||||
retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
|
||||
info.buffer[info.len] = 0; /* we terminate this with a zero byte */
|
||||
if(info.len) {
|
||||
if(-1 == retcode) {
|
||||
if(info.alloc)
|
||||
free(info.buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(info.alloc) {
|
||||
info.buffer[info.len] = 0; /* we terminate this with a zero byte */
|
||||
return info.buffer;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return strdup("");
|
||||
}
|
||||
|
||||
static int storebuffer(int output, FILE *data)
|
||||
|
127
lib/multi.c
127
lib/multi.c
@@ -62,6 +62,13 @@ struct Curl_one_easy {
|
||||
|
||||
CURLMstate state; /* the handle's state */
|
||||
CURLcode result; /* previous result */
|
||||
|
||||
struct Curl_message *msg; /* A pointer to one single posted message.
|
||||
Cleanup should be done on this pointer NOT on
|
||||
the linked list in Curl_multi. This message
|
||||
will be deleted when this handle is removed
|
||||
from the multi-handle */
|
||||
int msg_num; /* number of messages left in 'msg' to return */
|
||||
};
|
||||
|
||||
|
||||
@@ -81,14 +88,7 @@ struct Curl_multi {
|
||||
/* This is the amount of entries in the linked list above. */
|
||||
int num_easy;
|
||||
|
||||
/* this is a linked list of posted messages */
|
||||
struct Curl_message *msgs; /* the messages remain here until the handle is
|
||||
closed */
|
||||
struct Curl_message *lastmsg; /* points to the last entry */
|
||||
struct Curl_message *readptr; /* NULL before no one read anything */
|
||||
|
||||
int num_msgs; /* amount of messages in the queue */
|
||||
int num_read; /* amount of read messages */
|
||||
int num_msgs; /* total amount of messages in the easy handles */
|
||||
|
||||
/* Hostname cache */
|
||||
curl_hash *hostcache;
|
||||
@@ -179,6 +179,9 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
/* If the 'state' is not INIT or COMPLETED, we might need to do something
|
||||
nice to put the easy_handle in a good known state when this returns. */
|
||||
|
||||
/* clear out the usage of the shared DNS cache */
|
||||
easy->easy_handle->hostcache = NULL;
|
||||
|
||||
/* make the previous node point to our next */
|
||||
if(easy->prev)
|
||||
easy->prev->next = easy->next;
|
||||
@@ -188,6 +191,8 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
|
||||
/* NOTE NOTE NOTE
|
||||
We do not touch the easy handle here! */
|
||||
if (easy->msg)
|
||||
free(easy->msg);
|
||||
free(easy);
|
||||
|
||||
multi->num_easy--; /* one less to care about now */
|
||||
@@ -245,6 +250,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
||||
struct Curl_one_easy *easy;
|
||||
bool done;
|
||||
CURLMcode result=CURLM_OK;
|
||||
struct Curl_message *msg = NULL;
|
||||
|
||||
*running_handles = 0; /* bump this once for every living handle */
|
||||
|
||||
@@ -315,35 +321,6 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
||||
/* after we have DONE what we're supposed to do, go COMPLETED, and
|
||||
it doesn't matter what the Curl_done() returned! */
|
||||
easy->state = CURLM_STATE_COMPLETED;
|
||||
|
||||
/* clear out the usage of the shared DNS cache */
|
||||
easy->easy_handle->hostcache = NULL;
|
||||
|
||||
/* now add a node to the Curl_message linked list with this info */
|
||||
{
|
||||
struct Curl_message *msg = (struct Curl_message *)
|
||||
malloc(sizeof(struct Curl_message));
|
||||
|
||||
if(!msg)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
|
||||
msg->extmsg.msg = CURLMSG_DONE;
|
||||
msg->extmsg.easy_handle = easy->easy_handle;
|
||||
msg->extmsg.data.result = easy->result;
|
||||
msg->next=NULL;
|
||||
|
||||
if(multi->lastmsg) {
|
||||
multi->lastmsg->next = msg;
|
||||
multi->lastmsg = msg;
|
||||
}
|
||||
else {
|
||||
multi->msgs = msg;
|
||||
multi->lastmsg = msg;
|
||||
}
|
||||
multi->num_msgs++; /* increase message counter */
|
||||
|
||||
}
|
||||
result = CURLM_CALL_MULTI_PERFORM;
|
||||
break;
|
||||
|
||||
case CURLM_STATE_COMPLETED:
|
||||
@@ -356,17 +333,37 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
||||
return CURLM_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if((CURLM_STATE_COMPLETED != easy->state) &&
|
||||
(CURLE_OK != easy->result)) {
|
||||
if(CURLM_STATE_COMPLETED != easy->state) {
|
||||
if(CURLE_OK != easy->result)
|
||||
/*
|
||||
* If an error was returned, and we aren't in completed now,
|
||||
* then we go to completed and consider this transfer aborted.
|
||||
*/
|
||||
* If an error was returned, and we aren't in completed state now,
|
||||
* then we go to completed and consider this transfer aborted. */
|
||||
easy->state = CURLM_STATE_COMPLETED;
|
||||
}
|
||||
else if(CURLM_STATE_COMPLETED != easy->state)
|
||||
else
|
||||
/* this one still lives! */
|
||||
(*running_handles)++;
|
||||
}
|
||||
|
||||
if ((CURLM_STATE_COMPLETED == easy->state) && !easy->msg) {
|
||||
/* clear out the usage of the shared DNS cache */
|
||||
easy->easy_handle->hostcache = NULL;
|
||||
|
||||
/* now add a node to the Curl_message linked list with this info */
|
||||
msg = (struct Curl_message *)malloc(sizeof(struct Curl_message));
|
||||
|
||||
if(!msg)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
|
||||
msg->extmsg.msg = CURLMSG_DONE;
|
||||
msg->extmsg.easy_handle = easy->easy_handle;
|
||||
msg->extmsg.data.result = easy->result;
|
||||
msg->next=NULL;
|
||||
|
||||
easy->msg = msg;
|
||||
easy->msg_num = 1; /* there is one unread message here */
|
||||
|
||||
multi->num_msgs++; /* increase message counter */
|
||||
}
|
||||
|
||||
easy = easy->next; /* operate on next handle */
|
||||
}
|
||||
@@ -379,8 +376,6 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct Curl_one_easy *easy;
|
||||
struct Curl_one_easy *nexteasy;
|
||||
struct Curl_message *msg;
|
||||
struct Curl_message *nextmsg;
|
||||
|
||||
if(GOOD_MULTI_HANDLE(multi)) {
|
||||
multi->type = 0; /* not good anymore */
|
||||
@@ -393,18 +388,12 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
/* clear out the usage of the shared DNS cache */
|
||||
easy->easy_handle->hostcache = NULL;
|
||||
|
||||
if (easy->msg)
|
||||
free(easy->msg);
|
||||
free(easy);
|
||||
easy = nexteasy;
|
||||
}
|
||||
|
||||
/* remove all struct Curl_message nodes left */
|
||||
msg = multi->msgs;
|
||||
while(msg) {
|
||||
nextmsg = msg->next;
|
||||
free(msg);
|
||||
msg = nextmsg;
|
||||
}
|
||||
|
||||
free(multi);
|
||||
|
||||
return CURLM_OK;
|
||||
@@ -416,26 +405,28 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
|
||||
if(GOOD_MULTI_HANDLE(multi)) {
|
||||
CURLMsg *msg;
|
||||
struct Curl_one_easy *easy;
|
||||
|
||||
if(!multi->readptr && !multi->num_read)
|
||||
multi->readptr = multi->msgs;
|
||||
if(!multi->num_msgs)
|
||||
return NULL; /* no messages left to return */
|
||||
|
||||
if(!multi->readptr) {
|
||||
*msgs_in_queue = 0;
|
||||
return NULL;
|
||||
easy=multi->easy.next;
|
||||
while(easy) {
|
||||
if(easy->msg_num) {
|
||||
easy->msg_num--;
|
||||
break;
|
||||
}
|
||||
easy = easy->next;
|
||||
}
|
||||
if(!easy)
|
||||
return NULL; /* this means internal count confusion really */
|
||||
|
||||
multi->num_read++;
|
||||
multi->num_msgs--;
|
||||
*msgs_in_queue = multi->num_msgs;
|
||||
|
||||
*msgs_in_queue = multi->num_msgs - multi->num_read;
|
||||
msg = &multi->readptr->extmsg;
|
||||
|
||||
/* advance read pointer */
|
||||
multi->readptr = multi->readptr->next;
|
||||
|
||||
return msg;
|
||||
return &easy->msg->extmsg;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
|
44
lib/netrc.c
44
lib/netrc.c
@@ -79,11 +79,14 @@ int Curl_parsenetrc(char *host,
|
||||
char netrcbuffer[256];
|
||||
int retcode=1;
|
||||
|
||||
int specific_login = (login[0] != 0);
|
||||
|
||||
char *home = NULL;
|
||||
int state=NOTHING;
|
||||
|
||||
char state_login=0;
|
||||
char state_password=0;
|
||||
char state_login=0; /* Found a login keyword */
|
||||
char state_password=0; /* Found a password keyword */
|
||||
char state_our_login=0; /* With specific_login, found *our* login name */
|
||||
|
||||
#define NETRC DOT_CHAR "netrc"
|
||||
|
||||
@@ -116,6 +119,30 @@ int Curl_parsenetrc(char *host,
|
||||
|
||||
sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC);
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
{
|
||||
/* This is a hack to allow testing.
|
||||
* If compiled with --enable-debug and CURL_DEBUG_NETRC is defined,
|
||||
* then it's the path to a substitute .netrc for testing purposes *only* */
|
||||
|
||||
char *override = curl_getenv("CURL_DEBUG_NETRC");
|
||||
|
||||
if (override != NULL) {
|
||||
printf("NETRC: overridden .netrc file: %s\n", home);
|
||||
|
||||
if (strlen(override)+1 > sizeof(netrcbuffer)) {
|
||||
free(override);
|
||||
if(NULL==pw)
|
||||
free(home);
|
||||
|
||||
return -1;
|
||||
}
|
||||
strcpy(netrcbuffer, override);
|
||||
free(override);
|
||||
}
|
||||
}
|
||||
#endif /* MALLOCDEBUG */
|
||||
|
||||
file = fopen(netrcbuffer, "r");
|
||||
if(file) {
|
||||
char *tok;
|
||||
@@ -123,6 +150,10 @@ int Curl_parsenetrc(char *host,
|
||||
while(fgets(netrcbuffer, sizeof(netrcbuffer), file)) {
|
||||
tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
|
||||
while(tok) {
|
||||
|
||||
if (login[0] && password[0])
|
||||
goto done;
|
||||
|
||||
switch(state) {
|
||||
case NOTHING:
|
||||
if(strequal("machine", tok)) {
|
||||
@@ -149,17 +180,23 @@ int Curl_parsenetrc(char *host,
|
||||
case HOSTVALID:
|
||||
/* we are now parsing sub-keywords concerning "our" host */
|
||||
if(state_login) {
|
||||
if (specific_login) {
|
||||
state_our_login = strequal(login, tok);
|
||||
}else{
|
||||
strncpy(login, tok, LOGINSIZE-1);
|
||||
#ifdef _NETRC_DEBUG
|
||||
printf("LOGIN: %s\n", login);
|
||||
#endif
|
||||
}
|
||||
state_login=0;
|
||||
}
|
||||
else if(state_password) {
|
||||
if (state_our_login || !specific_login) {
|
||||
strncpy(password, tok, PASSWORDSIZE-1);
|
||||
#ifdef _NETRC_DEBUG
|
||||
printf("PASSWORD: %s\n", password);
|
||||
#endif
|
||||
}
|
||||
state_password=0;
|
||||
}
|
||||
else if(strequal("login", tok))
|
||||
@@ -169,13 +206,16 @@ int Curl_parsenetrc(char *host,
|
||||
else if(strequal("machine", tok)) {
|
||||
/* ok, there's machine here go => */
|
||||
state = HOSTFOUND;
|
||||
state_our_login = 0;
|
||||
}
|
||||
break;
|
||||
} /* switch (state) */
|
||||
|
||||
tok = strtok_r(NULL, " \t\n", &tok_buf);
|
||||
} /* while (tok) */
|
||||
} /* while fgets() */
|
||||
|
||||
done:
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
|
@@ -25,4 +25,9 @@
|
||||
int Curl_parsenetrc(char *host,
|
||||
char *login,
|
||||
char *password);
|
||||
/* Assume: password[0]=0, host[0] != 0.
|
||||
* If login[0] = 0, search for login and password within a machine section
|
||||
* in the netrc.
|
||||
* If login[0] != 0, search for password within machine and login.
|
||||
*/
|
||||
#endif
|
||||
|
@@ -149,7 +149,7 @@ void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
|
||||
break;
|
||||
case TIMER_REDIRECT:
|
||||
data->progress.t_redirect =
|
||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
|
||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.start)/1000.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -40,6 +40,7 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#ifdef KRB4
|
||||
|
||||
#define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */
|
||||
@@ -552,6 +553,7 @@ Curl_sec_end(struct connectdata *conn)
|
||||
}
|
||||
|
||||
#endif /* KRB4 */
|
||||
#endif /* CURL_DISABLE_FTP */
|
||||
|
||||
/*
|
||||
* local variables:
|
||||
|
12
lib/setup.h
12
lib/setup.h
@@ -23,7 +23,17 @@
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/* MN 06/07/02 */
|
||||
/* #define HTTP_ONLY
|
||||
*/
|
||||
#ifdef HTTP_ONLY
|
||||
#define CURL_DISABLE_FTP
|
||||
#define CURL_DISABLE_LDAP
|
||||
#define CURL_DISABLE_TELNET
|
||||
#define CURL_DISABLE_DICT
|
||||
#define CURL_DISABLE_FILE
|
||||
#define CURL_DISABLE_GOPHER
|
||||
#endif
|
||||
|
||||
#if !defined(WIN32) && defined(_WIN32)
|
||||
/* This _might_ be a good Borland fix. Please report whether this works or
|
||||
|
47
lib/ssluse.c
47
lib/ssluse.c
@@ -55,6 +55,15 @@
|
||||
#undef HAVE_USERDATA_IN_PWD_CALLBACK
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00907001L
|
||||
/* ENGINE_load_private_key() takes four arguments */
|
||||
#define HAVE_ENGINE_LOAD_FOUR_ARGS
|
||||
#else
|
||||
/* ENGINE_load_private_key() takes three arguments */
|
||||
#undef HAVE_ENGINE_LOAD_FOUR_ARGS
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
|
||||
static char global_passwd[64];
|
||||
#endif
|
||||
@@ -223,30 +232,22 @@ int cert_stuff(struct connectdata *conn,
|
||||
SSL_CTX_set_default_passwd_cb(conn->ssl.ctx, passwd_callback);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
|
||||
cert_file,
|
||||
SSL_FILETYPE_PEM) != 1) {
|
||||
failf(data, "unable to set certificate file (wrong password?)");
|
||||
return(0);
|
||||
}
|
||||
if (key_file == NULL)
|
||||
key_file=cert_file;
|
||||
|
||||
if (SSL_CTX_use_PrivateKey_file(conn->ssl.ctx,
|
||||
key_file,
|
||||
SSL_FILETYPE_PEM) != 1) {
|
||||
failf(data, "unable to set public key file");
|
||||
return(0);
|
||||
}
|
||||
#else
|
||||
/* The '#ifdef 0' section above was removed on 17-dec-2001 */
|
||||
|
||||
file_type = do_file_type(cert_type);
|
||||
|
||||
switch(file_type) {
|
||||
case SSL_FILETYPE_PEM:
|
||||
/* SSL_CTX_use_certificate_chain_file() only works on PEM files */
|
||||
if (SSL_CTX_use_certificate_chain_file(conn->ssl.ctx,
|
||||
cert_file) != 1) {
|
||||
failf(data, "unable to set certificate file (wrong password?)");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SSL_FILETYPE_ASN1:
|
||||
/* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
|
||||
we use the case above for PEM so this can only be performed with
|
||||
ASN1 files. */
|
||||
if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
|
||||
cert_file,
|
||||
file_type) != 1) {
|
||||
@@ -283,11 +284,17 @@ int cert_stuff(struct connectdata *conn,
|
||||
{ /* XXXX still needs some work */
|
||||
EVP_PKEY *priv_key = NULL;
|
||||
if (conn && conn->data && conn->data->engine) {
|
||||
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
|
||||
UI_METHOD *ui_method = UI_OpenSSL();
|
||||
#endif
|
||||
if (!key_file || !key_file[0]) {
|
||||
failf(data, "no key set to load from crypto engine\n");
|
||||
return 0;
|
||||
}
|
||||
priv_key = ENGINE_load_private_key(conn->data->engine,key_file,
|
||||
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
|
||||
ui_method,
|
||||
#endif
|
||||
data->set.key_passwd);
|
||||
if (!priv_key) {
|
||||
failf(data, "failed to load private key from crypto engine\n");
|
||||
@@ -315,8 +322,6 @@ int cert_stuff(struct connectdata *conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ssl=SSL_new(conn->ssl.ctx);
|
||||
x509=SSL_get_certificate(ssl);
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_TELNET
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -1211,3 +1212,4 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
||||
* vim600: fdm=marker
|
||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||
*/
|
||||
#endif
|
||||
|
@@ -23,7 +23,8 @@
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
#ifndef CURL_DISABLE_TELNET
|
||||
CURLcode Curl_telnet(struct connectdata *conn);
|
||||
CURLcode Curl_telnet_done(struct connectdata *conn);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -32,6 +32,7 @@
|
||||
int
|
||||
gettimeofday (struct timeval *tp, void *nothing)
|
||||
{
|
||||
#ifdef WITHOUT_MM_LIB
|
||||
SYSTEMTIME st;
|
||||
time_t tt;
|
||||
struct tm tmtm;
|
||||
@@ -47,6 +48,19 @@ gettimeofday (struct timeval *tp, void *nothing)
|
||||
tt = mktime (&tmtm);
|
||||
tp->tv_sec = tt;
|
||||
tp->tv_usec = st.wMilliseconds * 1000;
|
||||
#else
|
||||
/**
|
||||
** The earlier time calculations using GetLocalTime
|
||||
** had a time resolution of 10ms.The timeGetTime, part
|
||||
** of multimedia apis offer a better time resolution
|
||||
** of 1ms.Need to link against winmm.lib for this
|
||||
**/
|
||||
unsigned long Ticks = 0;
|
||||
Ticks = timeGetTime();
|
||||
tp->tv_sec = Ticks%1000;
|
||||
tp->tv_usec = (Ticks - (tp->tv_sec*1000))*1000;
|
||||
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
#define HAVE_GETTIMEOFDAY
|
||||
|
@@ -168,6 +168,10 @@ compareheader(char *headerline, /* line to check */
|
||||
return FALSE; /* no match */
|
||||
}
|
||||
|
||||
/* We keep this static and global since this is read-only and NEVER
|
||||
changed. It should just remain a blanked-out timeout value. */
|
||||
static struct timeval notimeout={0,0};
|
||||
|
||||
CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
bool *done)
|
||||
{
|
||||
@@ -177,13 +181,42 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
ssize_t nread; /* number of bytes read */
|
||||
int didwhat=0;
|
||||
|
||||
/* These two are used only if no other select() or _fdset() have been
|
||||
invoked before this. This typicly happens if you use the multi interface
|
||||
and call curl_multi_perform() without calling curl_multi_fdset()
|
||||
first. */
|
||||
fd_set extrareadfd;
|
||||
fd_set extrawritefd;
|
||||
|
||||
fd_set *readfdp = k->readfdp;
|
||||
fd_set *writefdp = k->writefdp;
|
||||
|
||||
if((k->keepon & KEEP_READ) && !readfdp) {
|
||||
/* reading is requested, but no socket descriptor pointer was set */
|
||||
FD_ZERO(&extrareadfd);
|
||||
FD_SET(conn->sockfd, &extrareadfd);
|
||||
readfdp = &extrareadfd;
|
||||
|
||||
/* no write, no exceptions, no timeout */
|
||||
select(conn->sockfd+1, readfdp, NULL, NULL, ¬imeout);
|
||||
}
|
||||
if((k->keepon & KEEP_WRITE) && !writefdp) {
|
||||
/* writing is requested, but no socket descriptor pointer was set */
|
||||
FD_ZERO(&extrawritefd);
|
||||
FD_SET(conn->writesockfd, &extrawritefd);
|
||||
writefdp = &extrawritefd;
|
||||
|
||||
/* no read, no exceptions, no timeout */
|
||||
select(conn->writesockfd+1, NULL, writefdp, NULL, ¬imeout);
|
||||
}
|
||||
|
||||
do {
|
||||
/* If we still have reading to do, we check if we have a readable
|
||||
socket. Sometimes the reafdp is NULL, it no fd_set was done using
|
||||
the multi interface and then we can do nothing but to attempt a
|
||||
read to be sure. */
|
||||
if((k->keepon & KEEP_READ) &&
|
||||
(!k->readfdp || FD_ISSET(conn->sockfd, k->readfdp))) {
|
||||
(FD_ISSET(conn->sockfd, readfdp))) {
|
||||
|
||||
/* read! */
|
||||
result = Curl_read(conn, conn->sockfd, k->buf,
|
||||
@@ -755,7 +788,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
the multi interface and then we can do nothing but to attempt a
|
||||
write to be sure. */
|
||||
if((k->keepon & KEEP_WRITE) &&
|
||||
(!k->writefdp || FD_ISSET(conn->writesockfd, k->writefdp)) ) {
|
||||
(FD_ISSET(conn->writesockfd, writefdp)) ) {
|
||||
/* write */
|
||||
|
||||
int i, si;
|
||||
@@ -970,9 +1003,6 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
|
||||
k->rkeepfd = k->readfd;
|
||||
k->wkeepfd = k->writefd;
|
||||
|
||||
k->writefdp = &k->writefd; /* store the address of the set */
|
||||
k->readfdp = &k->readfd; /* store the address of the set */
|
||||
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
@@ -1034,6 +1064,9 @@ Transfer(struct connectdata *conn)
|
||||
if(!conn->getheader && data->set.no_body)
|
||||
return CURLE_OK;
|
||||
|
||||
k->writefdp = &k->writefd; /* store the address of the set */
|
||||
k->readfdp = &k->readfd; /* store the address of the set */
|
||||
|
||||
while (!done) {
|
||||
struct timeval interval;
|
||||
k->readfd = k->rkeepfd; /* set these every lap in the loop */
|
||||
@@ -1155,12 +1188,20 @@ CURLcode Curl_perform(struct SessionHandle *data)
|
||||
* may be free()ed in the Curl_done() function.
|
||||
*/
|
||||
newurl = conn->newurl?strdup(conn->newurl):NULL;
|
||||
else
|
||||
else {
|
||||
/* The transfer phase returned error, we mark the connection to get
|
||||
* closed to prevent being re-used. This is becasue we can't
|
||||
* possibly know if the connection is in a good shape or not now. */
|
||||
conn->bits.close = TRUE;
|
||||
|
||||
if(-1 !=conn->secondarysocket) {
|
||||
/* if we failed anywhere, we must clean up the secondary socket if
|
||||
it was used */
|
||||
sclose(conn->secondarysocket);
|
||||
conn->secondarysocket=-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Always run Curl_done(), even if some of the previous calls
|
||||
failed, but return the previous (original) error code */
|
||||
res2 = Curl_done(conn);
|
||||
|
372
lib/url.c
372
lib/url.c
@@ -72,6 +72,10 @@
|
||||
#include <inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETJMP_H
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SELECT
|
||||
#error "We can't compile without select() support!"
|
||||
#endif
|
||||
@@ -120,6 +124,7 @@
|
||||
#ifdef KRB4
|
||||
#include "security.h"
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#include "memdebug.h"
|
||||
@@ -138,11 +143,17 @@ static unsigned int ConnectionStore(struct SessionHandle *data,
|
||||
#ifndef RETSIGTYPE
|
||||
#define RETSIGTYPE void
|
||||
#endif
|
||||
#ifdef HAVE_SIGSETJMP
|
||||
extern sigjmp_buf curl_jmpenv;
|
||||
#endif
|
||||
static
|
||||
RETSIGTYPE alarmfunc(int signal)
|
||||
{
|
||||
/* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
|
||||
(void)signal;
|
||||
#ifdef HAVE_SIGSETJMP
|
||||
siglongjmp(curl_jmpenv, 1);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -182,11 +193,13 @@ CURLcode Curl_close(struct SessionHandle *data)
|
||||
if(data->state.headerbuff)
|
||||
free(data->state.headerbuff);
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
if(data->set.cookiejar)
|
||||
/* we have a "destination" for all the cookies to get dumped to */
|
||||
Curl_cookie_output(data->cookies, data->set.cookiejar);
|
||||
|
||||
Curl_cookie_cleanup(data->cookies);
|
||||
#endif
|
||||
|
||||
/* free the connection cache */
|
||||
free(data->state.connects);
|
||||
@@ -441,7 +454,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||
/*
|
||||
* Parse the $HOME/.netrc file
|
||||
*/
|
||||
data->set.use_netrc = va_arg(param, long)?TRUE:FALSE;
|
||||
data->set.use_netrc = va_arg(param, long);
|
||||
break;
|
||||
case CURLOPT_FOLLOWLOCATION:
|
||||
/*
|
||||
@@ -514,6 +527,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||
data->set.cookiesession = (bool)va_arg(param, long);
|
||||
break;
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
case CURLOPT_COOKIEFILE:
|
||||
/*
|
||||
* Set cookie file to read and parse. Can be used multiple times.
|
||||
@@ -537,6 +551,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||
data->cookies = Curl_cookie_init(NULL, data->cookies,
|
||||
data->set.cookiesession);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CURLOPT_WRITEHEADER:
|
||||
/*
|
||||
* Custom pointer to pass the header write callback function
|
||||
@@ -981,7 +997,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||
* Set CA info for SSL connection. Specify file name of the CA certificate
|
||||
*/
|
||||
data->set.ssl.CAfile = va_arg(param, char *);
|
||||
data->set.ssl.CApath = NULL; /*This does not work on windows.*/
|
||||
break;
|
||||
case CURLOPT_CAPATH:
|
||||
/*
|
||||
* Set CA path info for SSL connection. Specify directory name of the CA certificates
|
||||
* which have been prepared using openssl c_rehash utility.
|
||||
*/
|
||||
data->set.ssl.CApath = va_arg(param, char *); /*This does not work on windows.*/
|
||||
break;
|
||||
case CURLOPT_TELNETOPTIONS:
|
||||
/*
|
||||
@@ -1351,7 +1373,6 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
char resumerange[40]="";
|
||||
struct connectdata *conn;
|
||||
struct connectdata *conn_temp;
|
||||
char endbracket;
|
||||
int urllen;
|
||||
Curl_addrinfo *hostaddr;
|
||||
#ifdef HAVE_ALARM
|
||||
@@ -1533,35 +1554,12 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
|
||||
buf = data->state.buffer; /* this is our buffer */
|
||||
|
||||
/*************************************************************
|
||||
* Take care of user and password authentication stuff
|
||||
*************************************************************/
|
||||
|
||||
if(conn->bits.user_passwd && !data->set.use_netrc) {
|
||||
data->state.user[0] =0;
|
||||
data->state.passwd[0]=0;
|
||||
|
||||
if(*data->set.userpwd != ':') {
|
||||
/* the name is given, get user+password */
|
||||
sscanf(data->set.userpwd, "%127[^:]:%127[^\n]",
|
||||
data->state.user, data->state.passwd);
|
||||
}
|
||||
else
|
||||
/* no name given, get the password only */
|
||||
sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd);
|
||||
|
||||
/* check for password, if no ask for one */
|
||||
if( !data->state.passwd[0] ) {
|
||||
if(!data->set.fpasswd ||
|
||||
data->set.fpasswd(data->set.passwd_client,
|
||||
"password:", data->state.passwd,
|
||||
sizeof(data->state.passwd)))
|
||||
{
|
||||
failf(data, "Bad password from password callback");
|
||||
return CURLE_BAD_PASSWORD_ENTERED;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* So if the URL was A://B/C,
|
||||
* conn->protostr is A
|
||||
* conn->gname is B
|
||||
* conn->path is /C
|
||||
*/
|
||||
|
||||
/*************************************************************
|
||||
* Take care of proxy authentication stuff
|
||||
@@ -1730,6 +1728,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
conn->protocol &= ~PROT_MISSING; /* switch that one off again */
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/************************************************************
|
||||
* RESUME on a HTTP page is a tricky business. First, let's just check that
|
||||
* 'range' isn't used, then set the range parameter and leave the resume as
|
||||
@@ -1748,12 +1747,13 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
conn->bits.use_range = 1; /* switch on range usage */
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/*************************************************************
|
||||
* Setup internals depending on protocol
|
||||
*************************************************************/
|
||||
|
||||
if (strequal(conn->protostr, "HTTP")) {
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||
data->set.use_port:PORT_HTTP;
|
||||
conn->remote_port = PORT_HTTP;
|
||||
@@ -1761,9 +1761,14 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
conn->curl_do = Curl_http;
|
||||
conn->curl_done = Curl_http_done;
|
||||
conn->curl_connect = Curl_http_connect;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with HTTP disabled, http: not supported!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
else if (strequal(conn->protostr, "HTTPS")) {
|
||||
#ifdef USE_SSLEAY
|
||||
#if defined(USE_SSLEAY) && !defined(CURL_DISABLE_HTTP)
|
||||
|
||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||
data->set.use_port:PORT_HTTPS;
|
||||
@@ -1781,6 +1786,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
#endif /* !USE_SSLEAY */
|
||||
}
|
||||
else if (strequal(conn->protostr, "GOPHER")) {
|
||||
#ifndef CURL_DISABLE_GOPHER
|
||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||
data->set.use_port:PORT_GOPHER;
|
||||
conn->remote_port = PORT_GOPHER;
|
||||
@@ -1793,9 +1799,16 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
conn->protocol |= PROT_GOPHER;
|
||||
conn->curl_do = Curl_http;
|
||||
conn->curl_done = Curl_http_done;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with GOPHER disabled, gopher: not supported!");
|
||||
#endif
|
||||
}
|
||||
else if(strequal(conn->protostr, "FTP") ||
|
||||
strequal(conn->protostr, "FTPS")) {
|
||||
|
||||
/* MN 06/07/02 */
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
char *type;
|
||||
|
||||
if(strequal(conn->protostr, "FTPS")) {
|
||||
@@ -1823,8 +1836,13 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
failf(data, "ftps does not work through http proxy!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
conn->curl_do = Curl_http;
|
||||
conn->curl_done = Curl_http_done;
|
||||
#else
|
||||
failf(data, "FTP over http proxy requires HTTP support built-in!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
conn->curl_do = Curl_ftp;
|
||||
@@ -1843,7 +1861,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
}
|
||||
if(type) {
|
||||
char command;
|
||||
*type=0;
|
||||
*type=0; /* it was in the middle of the hostname */
|
||||
command = toupper(type[6]);
|
||||
switch(command) {
|
||||
case 'A': /* ASCII mode */
|
||||
@@ -1859,8 +1877,16 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* MN 06/07/02 */
|
||||
#else /* CURL_DISABLE_FTP */
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with FTP disabled, ftp/ftps: not supported!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
else if(strequal(conn->protostr, "TELNET")) {
|
||||
#ifndef CURL_DISABLE_TELNET
|
||||
/* telnet testing factory */
|
||||
conn->protocol |= PROT_TELNET;
|
||||
|
||||
@@ -1869,24 +1895,39 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
conn->remote_port = PORT_TELNET;
|
||||
conn->curl_do = Curl_telnet;
|
||||
conn->curl_done = Curl_telnet_done;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with TELNET disabled!");
|
||||
#endif
|
||||
}
|
||||
else if (strequal(conn->protostr, "DICT")) {
|
||||
#ifndef CURL_DISABLE_DICT
|
||||
conn->protocol |= PROT_DICT;
|
||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||
data->set.use_port:PORT_DICT;
|
||||
conn->remote_port = PORT_DICT;
|
||||
conn->curl_do = Curl_dict;
|
||||
conn->curl_done = NULL; /* no DICT-specific done */
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with DICT disabled!");
|
||||
#endif
|
||||
}
|
||||
else if (strequal(conn->protostr, "LDAP")) {
|
||||
#ifndef CURL_DISABLE_LDAP
|
||||
conn->protocol |= PROT_LDAP;
|
||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||
data->set.use_port:PORT_LDAP;
|
||||
conn->remote_port = PORT_LDAP;
|
||||
conn->curl_do = Curl_ldap;
|
||||
conn->curl_done = NULL; /* no LDAP-specific done */
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with LDAP disabled!");
|
||||
#endif
|
||||
}
|
||||
else if (strequal(conn->protostr, "FILE")) {
|
||||
#ifndef CURL_DISABLE_FILE
|
||||
conn->protocol |= PROT_FILE;
|
||||
|
||||
conn->curl_do = Curl_file;
|
||||
@@ -1903,6 +1944,10 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
return result;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with FILE disabled!");
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* We fell through all checks and thus we don't support the specified
|
||||
@@ -1911,86 +1956,6 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* .netrc scanning coming up
|
||||
*************************************************************/
|
||||
if(data->set.use_netrc) {
|
||||
if(Curl_parsenetrc(conn->hostname,
|
||||
data->state.user,
|
||||
data->state.passwd)) {
|
||||
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
|
||||
conn->hostname);
|
||||
}
|
||||
else
|
||||
conn->bits.user_passwd = 1; /* enable user+password */
|
||||
|
||||
/* weather we failed or not, we don't know which fields that were filled
|
||||
in anyway */
|
||||
if(!data->state.user[0])
|
||||
strcpy(data->state.user, CURL_DEFAULT_USER);
|
||||
if(!data->state.passwd[0])
|
||||
strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
|
||||
}
|
||||
else if(!(conn->bits.user_passwd) &&
|
||||
(conn->protocol & (PROT_FTP|PROT_HTTP)) ) {
|
||||
/* This is a FTP or HTTP URL, and we haven't got the user+password in
|
||||
* the extra parameter, we will now try to extract the possible
|
||||
* user+password pair in a string like:
|
||||
* ftp://user:password@ftp.my.site:8021/README */
|
||||
char *ptr=NULL; /* assign to remove possible warnings */
|
||||
if((ptr=strchr(conn->name, '@'))) {
|
||||
/* there's a user+password given here, to the left of the @ */
|
||||
|
||||
data->state.user[0] =0;
|
||||
data->state.passwd[0]=0;
|
||||
|
||||
if(*conn->name != ':') {
|
||||
/* the name is given, get user+password */
|
||||
sscanf(conn->name, "%127[^:@]:%127[^@]",
|
||||
data->state.user, data->state.passwd);
|
||||
}
|
||||
else
|
||||
/* no name given, get the password only */
|
||||
sscanf(conn->name+1, "%127[^@]", data->state.passwd);
|
||||
|
||||
if(data->state.user[0]) {
|
||||
char *newname=curl_unescape(data->state.user, 0);
|
||||
if(strlen(newname) < sizeof(data->state.user)) {
|
||||
strcpy(data->state.user, newname);
|
||||
}
|
||||
/* if the new name is longer than accepted, then just use
|
||||
the unconverted name, it'll be wrong but what the heck */
|
||||
free(newname);
|
||||
}
|
||||
|
||||
/* check for password, if no ask for one */
|
||||
if( !data->state.passwd[0] ) {
|
||||
if(!data->set.fpasswd ||
|
||||
data->set.fpasswd(data->set.passwd_client,
|
||||
"password:", data->state.passwd,
|
||||
sizeof(data->state.passwd))) {
|
||||
failf(data, "Bad password from password callback");
|
||||
return CURLE_BAD_PASSWORD_ENTERED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* we have a password found in the URL, decode it! */
|
||||
char *newpasswd=curl_unescape(data->state.passwd, 0);
|
||||
if(strlen(newpasswd) < sizeof(data->state.passwd)) {
|
||||
strcpy(data->state.passwd, newpasswd);
|
||||
}
|
||||
free(newpasswd);
|
||||
}
|
||||
|
||||
conn->name = ++ptr;
|
||||
conn->bits.user_passwd=TRUE; /* enable user+password */
|
||||
}
|
||||
else {
|
||||
strcpy(data->state.user, CURL_DEFAULT_USER);
|
||||
strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* Figure out the remote port number
|
||||
*
|
||||
@@ -1999,29 +1964,32 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
*
|
||||
* To be able to detect port number flawlessly, we must not confuse them
|
||||
* IPv6-specified addresses in the [0::1] style. (RFC2732)
|
||||
*
|
||||
* The conn->name is currently [user:passwd@]host[:port] where host could
|
||||
* be a hostname, IPv4 address or IPv6 address.
|
||||
*************************************************************/
|
||||
|
||||
if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) &&
|
||||
(']' == endbracket)) {
|
||||
/* This is a (IPv6-style) specified IP-address. We support _any_
|
||||
IP within brackets to be really generic. */
|
||||
conn->name++; /* pass the starting bracket */
|
||||
|
||||
tmp = strchr(conn->name, ']');
|
||||
*tmp = 0; /* zero terminate */
|
||||
|
||||
tmp++; /* pass the ending bracket */
|
||||
if(':' != *tmp)
|
||||
tmp = NULL; /* no port number available */
|
||||
}
|
||||
else {
|
||||
/* traditional IPv4-style port-extracting */
|
||||
tmp = strchr(conn->name, ':');
|
||||
}
|
||||
tmp = strrchr(conn->name, ':');
|
||||
|
||||
if (tmp) {
|
||||
*tmp++ = '\0'; /* cut off the name there */
|
||||
conn->remote_port = atoi(tmp);
|
||||
char *rest;
|
||||
unsigned long port;
|
||||
|
||||
port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */
|
||||
|
||||
if (rest != (tmp+1) && *rest == '\0') {
|
||||
/* The colon really did have only digits after it,
|
||||
* so it is either a port number or a mistake */
|
||||
|
||||
if (port > 0xffff) { /* Single unix standard says port numbers are
|
||||
* 16 bits long */
|
||||
failf(data, "Port number too large: %lu", port);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
*tmp = '\0'; /* cut off the name there */
|
||||
conn->remote_port = port;
|
||||
}
|
||||
}
|
||||
|
||||
if(data->change.proxy) {
|
||||
@@ -2075,6 +2043,138 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
free(proxydup); /* free the duplicate pointer and not the modified */
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* Take care of user and password authentication stuff
|
||||
*************************************************************/
|
||||
|
||||
/*
|
||||
* Inputs: data->set.userpwd (CURLOPT_USERPWD)
|
||||
* data->set.fpasswd (CURLOPT_PASSWDFUNCTION)
|
||||
* data->set.use_netrc (CURLOPT_NETRC)
|
||||
* conn->hostname
|
||||
* netrc file
|
||||
* hard-coded defaults
|
||||
*
|
||||
* Outputs: (almost :- all currently undefined)
|
||||
* conn->bits.user_passwd - non-zero if non-default passwords exist
|
||||
* conn->state.user - non-zero length if defined
|
||||
* conn->state.passwd - ditto
|
||||
* conn->hostname - remove user name and password
|
||||
*/
|
||||
|
||||
/* At this point, we're hoping all the other special cases have
|
||||
* been taken care of, so conn->hostname is at most
|
||||
* [user[:password]]@]hostname
|
||||
*
|
||||
* We need somewhere to put the embedded details, so do that first.
|
||||
*/
|
||||
|
||||
data->state.user[0] =0; /* to make everything well-defined */
|
||||
data->state.passwd[0]=0;
|
||||
|
||||
if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
|
||||
/* This is a FTP or HTTP URL, we will now try to extract the possible
|
||||
* user+password pair in a string like:
|
||||
* ftp://user:password@ftp.my.site:8021/README */
|
||||
char *ptr=strchr(conn->name, '@');
|
||||
char *userpass = conn->name;
|
||||
if(ptr != NULL) {
|
||||
/* there's a user+password given here, to the left of the @ */
|
||||
|
||||
conn->name = conn->hostname = ++ptr;
|
||||
|
||||
/* So the hostname is sane. Only bother interpreting the
|
||||
* results if we could care. It could still be wasted
|
||||
* work because it might be overtaken by the programmatically
|
||||
* set user/passwd, but doing that first adds more cases here :-(
|
||||
*/
|
||||
|
||||
if (data->set.use_netrc != CURL_NETRC_REQUIRED) {
|
||||
/* We could use the one in the URL */
|
||||
|
||||
conn->bits.user_passwd = 1; /* enable user+password */
|
||||
|
||||
if(*userpass != ':') {
|
||||
/* the name is given, get user+password */
|
||||
sscanf(userpass, "%127[^:@]:%127[^@]",
|
||||
data->state.user, data->state.passwd);
|
||||
}
|
||||
else
|
||||
/* no name given, get the password only */
|
||||
sscanf(userpass, ":%127[^@]", data->state.passwd);
|
||||
|
||||
if(data->state.user[0]) {
|
||||
char *newname=curl_unescape(data->state.user, 0);
|
||||
if(strlen(newname) < sizeof(data->state.user)) {
|
||||
strcpy(data->state.user, newname);
|
||||
}
|
||||
/* if the new name is longer than accepted, then just use
|
||||
the unconverted name, it'll be wrong but what the heck */
|
||||
free(newname);
|
||||
}
|
||||
if (data->state.passwd[0]) {
|
||||
/* we have a password found in the URL, decode it! */
|
||||
char *newpasswd=curl_unescape(data->state.passwd, 0);
|
||||
if(strlen(newpasswd) < sizeof(data->state.passwd)) {
|
||||
strcpy(data->state.passwd, newpasswd);
|
||||
}
|
||||
free(newpasswd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Programmatically set password:
|
||||
* - always applies, if available
|
||||
* - takes precedence over the values we just set above
|
||||
* so scribble it over the top.
|
||||
* User-supplied passwords are assumed not to need unescaping.
|
||||
*
|
||||
* user_password is set in "inherite initial knowledge' above,
|
||||
* so it doesn't have to be set in this block
|
||||
*/
|
||||
if (data->set.userpwd != NULL) {
|
||||
if(*data->set.userpwd != ':') {
|
||||
/* the name is given, get user+password */
|
||||
sscanf(data->set.userpwd, "%127[^:]:%127[^\n]",
|
||||
data->state.user, data->state.passwd);
|
||||
}
|
||||
else
|
||||
/* no name given, get the password only */
|
||||
sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd);
|
||||
}
|
||||
|
||||
if (data->set.use_netrc != CURL_NETRC_IGNORED &&
|
||||
data->state.passwd[0] == '\0' ) { /* need passwd */
|
||||
if(Curl_parsenetrc(conn->hostname,
|
||||
data->state.user,
|
||||
data->state.passwd)) {
|
||||
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
|
||||
conn->hostname);
|
||||
} else
|
||||
conn->bits.user_passwd = 1; /* enable user+password */
|
||||
}
|
||||
|
||||
/* if we have a user but no password, ask for one */
|
||||
if(conn->bits.user_passwd &&
|
||||
!data->state.passwd[0] ) {
|
||||
if(!data->set.fpasswd ||
|
||||
data->set.fpasswd(data->set.passwd_client,
|
||||
"password:", data->state.passwd,
|
||||
sizeof(data->state.passwd)))
|
||||
return CURLE_BAD_PASSWORD_ENTERED;
|
||||
}
|
||||
|
||||
/* So we could have a password but no user; that's just too bad. */
|
||||
|
||||
/* If our protocol needs a password and we have none, use the defaults */
|
||||
if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) &&
|
||||
!conn->bits.user_passwd) {
|
||||
strcpy(data->state.user, CURL_DEFAULT_USER);
|
||||
strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
|
||||
/* This is the default password, so DON'T set conn->bits.user_passwd */
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* Check the current list of connections to see if we can
|
||||
* re-use an already existing one or if we have to create a
|
||||
@@ -2098,6 +2198,10 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
free(old_conn->proxyhost);
|
||||
conn = conn_temp; /* use this connection from now on */
|
||||
|
||||
/* If we speak over a proxy, we need to copy the host name too, as it
|
||||
might be another remote host even when re-using a connection */
|
||||
strcpy(conn->gname, old_conn->gname); /* safe strcpy() */
|
||||
|
||||
/* we need these pointers if we speak over a proxy */
|
||||
conn->hostname = conn->gname;
|
||||
conn->name = &conn->gname[old_conn->name - old_conn->gname];
|
||||
|
@@ -180,6 +180,8 @@ struct FTP {
|
||||
|
||||
char *cache; /* data cache between getresponse()-calls */
|
||||
size_t cache_size; /* size of cache in bytes */
|
||||
bool dont_check; /* set to TRUE to prevent the final (post-transfer)
|
||||
file size and 226/250 status check */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@@ -650,7 +652,8 @@ struct UserDefined {
|
||||
bool no_body;
|
||||
bool set_port;
|
||||
bool upload;
|
||||
bool use_netrc;
|
||||
enum CURL_NETRC_OPTION
|
||||
use_netrc; /* defined in include/curl.h */
|
||||
bool verbose;
|
||||
bool krb4; /* kerberos4 connection requested */
|
||||
bool reuse_forbid; /* forbidden to be reused, close after use */
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
CC = gcc
|
||||
STRIP = strip -s
|
||||
OPENSSL_PATH = ../../openssl-0.9.6b
|
||||
OPENSSL_PATH = ../../openssl-0.9.6d
|
||||
|
||||
# We may need these someday
|
||||
# PERL = perl
|
||||
@@ -36,7 +36,7 @@ else
|
||||
curl_DEPENDENCIES = ../lib/libcurl.a
|
||||
curl_LDADD = -L../lib -lcurl
|
||||
endif
|
||||
curl_LDADD += -lwsock32 -lws2_32
|
||||
curl_LDADD += -lwsock32 -lws2_32 -lwinmm
|
||||
ifdef SSL
|
||||
curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32 -lRSAglue
|
||||
endif
|
||||
|
@@ -20,5 +20,8 @@
|
||||
/* Define if you have the <sys/utime.h> header file */
|
||||
#undef HAVE_SYS_UTIME_H
|
||||
|
||||
/* Define if you have the <sys/types.h> header file */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define if you have the <sys/select.h> header file */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
56
src/main.c
56
src/main.c
@@ -117,6 +117,9 @@ typedef enum {
|
||||
|
||||
#define CONF_MUTE (1<<28) /* force NOPROGRESS */
|
||||
|
||||
#define CONF_NETRC_OPT (1<<29) /* read user+password from either
|
||||
* .netrc or URL*/
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
/* Ultrix doesn't have strdup(), so make a quick clone: */
|
||||
char *strdup(char *str)
|
||||
@@ -336,14 +339,16 @@ static void help(void)
|
||||
#endif
|
||||
" -e/--referer Referer page (H)");
|
||||
puts(" -E/--cert <cert[:passwd]> Specifies your certificate file and password (HTTPS)\n"
|
||||
" --cert-type <type> Specifies your certificate file type (DER/PEM/ENG) (HTTPS)\n"
|
||||
" --key <key> Specifies your private key file (HTTPS)\n"
|
||||
" --key-type <type> Specifies your private key file type (DER/PEM/ENG) (HTTPS)\n"
|
||||
" --pass <pass> Specifies your passphrase for the private key (HTTPS)");
|
||||
" --cert-type <type> Specifies certificate file type (DER/PEM/ENG) (HTTPS)\n"
|
||||
" --key <key> Specifies private key file (HTTPS)\n"
|
||||
" --key-type <type> Specifies private key file type (DER/PEM/ENG) (HTTPS)\n"
|
||||
" --pass <pass> Specifies passphrase for the private key (HTTPS)");
|
||||
puts(" --engine <eng> Specifies the crypto engine to use (HTTPS)\n"
|
||||
" --cacert <file> CA certifciate to verify peer against (SSL)\n"
|
||||
" --ciphers <list> What SSL ciphers to use (SSL)\n"
|
||||
" --connect-timeout <seconds> Maximum time allowed for connection\n"
|
||||
" --capath <directory> CA directory (made using c_rehash) to verify\n"
|
||||
" peer against (SSL, NOT Windows)\n"
|
||||
" --ciphers <list> What SSL ciphers to use (SSL)");
|
||||
puts(" --connect-timeout <seconds> Maximum time allowed for connection\n"
|
||||
" -f/--fail Fail silently (no output at all) on errors (H)\n"
|
||||
" -F/--form <name=content> Specify HTTP POST data (H)\n"
|
||||
" -g/--globoff Disable URL sequences and ranges using {} and []\n"
|
||||
@@ -360,7 +365,8 @@ static void help(void)
|
||||
puts(" -L/--location Follow Location: hints (H)\n"
|
||||
" -m/--max-time <seconds> Maximum time allowed for the transfer\n"
|
||||
" -M/--manual Display huge help text\n"
|
||||
" -n/--netrc Read .netrc for user name and password\n"
|
||||
" -n/--netrc Must read .netrc for user name and password\n"
|
||||
" --netrc-optional Use either .netrc or URL; overrides -n\n"
|
||||
" -N/--no-buffer Disables the buffering of the output stream");
|
||||
puts(" -o/--output <file> Write output to <file> instead of stdout\n"
|
||||
" -O/--remote-name Write output to a file named as the remote file\n"
|
||||
@@ -379,10 +385,11 @@ static void help(void)
|
||||
" -T/--upload-file <file> Transfer/upload <file> to remote site\n"
|
||||
" --url <URL> Another way to specify URL to work with");
|
||||
puts(" -u/--user <user[:password]> Specify user and password to use\n"
|
||||
" Overrides -n and --netrc-optional\n"
|
||||
" -U/--proxy-user <user[:password]> Specify Proxy authentication\n"
|
||||
" -v/--verbose Makes the operation more talkative\n"
|
||||
" -V/--version Outputs version number then quits\n"
|
||||
" -w/--write-out [format] What to output after completion\n"
|
||||
" -V/--version Outputs version number then quits");
|
||||
puts(" -w/--write-out [format] What to output after completion\n"
|
||||
" -x/--proxy <host[:port]> Use proxy. (Default port is 1080)\n"
|
||||
" --random-file <file> File to use for reading random data from (SSL)\n"
|
||||
" -X/--request <command> Specific request command to use");
|
||||
@@ -449,6 +456,7 @@ struct Configurable {
|
||||
char *cert;
|
||||
char *cert_type;
|
||||
char *cacert;
|
||||
char *capath;
|
||||
char *key;
|
||||
char *key_type;
|
||||
char *key_passwd;
|
||||
@@ -994,6 +1002,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
{"Ed","key-type", TRUE},
|
||||
{"Ee","pass", TRUE},
|
||||
{"Ef","engine", TRUE},
|
||||
{"Eg","capath ", TRUE},
|
||||
{"f", "fail", FALSE},
|
||||
{"F", "form", TRUE},
|
||||
{"g", "globoff", FALSE},
|
||||
@@ -1009,6 +1018,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
{"m", "max-time", TRUE},
|
||||
{"M", "manual", FALSE},
|
||||
{"n", "netrc", FALSE},
|
||||
{"no", "netrc-optional", FALSE},
|
||||
{"N", "no-buffer", FALSE},
|
||||
{"o", "output", TRUE},
|
||||
{"O", "remote-name", FALSE},
|
||||
@@ -1329,6 +1339,10 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
case 'f': /* crypto engine */
|
||||
GetStr(&config->engine, nextarg);
|
||||
break;
|
||||
case 'g': /* CA info PEM file */
|
||||
/* CA cert directory */
|
||||
GetStr(&config->capath, nextarg);
|
||||
break;
|
||||
default: /* certificate file */
|
||||
{
|
||||
char *ptr = strchr(nextarg, ':');
|
||||
@@ -1433,10 +1447,18 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
hugehelp();
|
||||
return PARAM_HELP_REQUESTED;
|
||||
case 'n':
|
||||
switch(subletter) {
|
||||
case 'o': /* CA info PEM file */
|
||||
/* use .netrc or URL */
|
||||
config->conf ^= CONF_NETRC_OPT;
|
||||
break;
|
||||
default:
|
||||
/* pick info from .netrc, if this is used for http, curl will
|
||||
automatically enfore user+password with the request */
|
||||
config->conf ^= CONF_NETRC;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'N':
|
||||
/* disable the output I/O buffering */
|
||||
config->nobuffer ^= 1;
|
||||
@@ -2068,6 +2090,8 @@ void free_config_fields(struct Configurable *config)
|
||||
curl_formfree(config->httppost);
|
||||
if(config->cacert)
|
||||
free(config->cacert);
|
||||
if(config->capath)
|
||||
free(config->capath);
|
||||
if(config->cookiejar)
|
||||
free(config->cookiejar);
|
||||
|
||||
@@ -2504,7 +2528,14 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
curl_easy_setopt(curl, CURLOPT_FTPLISTONLY,
|
||||
config->conf&CONF_FTPLISTONLY);
|
||||
curl_easy_setopt(curl, CURLOPT_FTPAPPEND, config->conf&CONF_FTPAPPEND);
|
||||
curl_easy_setopt(curl, CURLOPT_NETRC, config->conf&CONF_NETRC);
|
||||
|
||||
if (config->conf&CONF_NETRC_OPT)
|
||||
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
|
||||
else if (config->conf&CONF_NETRC)
|
||||
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_REQUIRED);
|
||||
else
|
||||
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_IGNORED);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,
|
||||
config->conf&CONF_FOLLOWLOCATION);
|
||||
curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, config->conf&CONF_GETTEXT);
|
||||
@@ -2537,8 +2568,9 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, config->key_type);
|
||||
curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, config->key_passwd);
|
||||
|
||||
if(config->cacert) {
|
||||
curl_easy_setopt(curl, CURLOPT_CAINFO, config->cacert);
|
||||
if(config->cacert || config->capath) {
|
||||
if (config->cacert) curl_easy_setopt(curl, CURLOPT_CAINFO, config->cacert);
|
||||
if (config->capath) curl_easy_setopt(curl, CURLOPT_CAPATH, config->capath);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
|
||||
}
|
||||
|
@@ -1,3 +1,3 @@
|
||||
#define CURL_NAME "curl"
|
||||
#define CURL_VERSION "7.9.7"
|
||||
#define CURL_VERSION "7.9.8"
|
||||
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
||||
|
@@ -26,6 +26,9 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
@@ -19,8 +19,10 @@ data to sent to the client on its request and later verified that it arrived
|
||||
safely. Set the nocheck=1 to prevent the test script to verify the arrival
|
||||
of this data.
|
||||
</data>
|
||||
<datacheck>
|
||||
if the data is sent but this is what should be checked afterwards
|
||||
<datacheck [nonewline=yes]>
|
||||
if the data is sent but this is what should be checked afterwards. If
|
||||
'nonewline' is set, we will cut off the trailing newline of this given data
|
||||
before comparing with the one actually received by the client
|
||||
</datacheck>
|
||||
<size>
|
||||
number to return on a ftp SIZE command
|
||||
|
@@ -15,5 +15,6 @@ test104 test113 test122 test18 test23 test301 test402 test9 \
|
||||
test105 test114 test123 test19 test24 test302 test43 test31 \
|
||||
test106 test115 test124 test190 test25 test303 test44 test38 \
|
||||
test107 test116 test125 test2 test26 test33 test45 test126 \
|
||||
test304 test39 test32 test128 test48
|
||||
test304 test39 test32 test128 test48 \
|
||||
test130 test131 test132 test133 test134 test135
|
||||
|
||||
|
49
tests/data/test130
Normal file
49
tests/data/test130
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# Server-side
|
||||
<reply name="1">
|
||||
<data>
|
||||
total 20
|
||||
drwxr-xr-x 8 98 98 512 Oct 22 13:06 .
|
||||
drwxr-xr-x 8 98 98 512 Oct 22 13:06 ..
|
||||
drwxr-xr-x 2 98 98 512 May 2 1996 .NeXT
|
||||
-r--r--r-- 1 0 1 35 Jul 16 1996 README
|
||||
lrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin
|
||||
dr-xr-xr-x 2 0 1 512 Oct 1 1997 dev
|
||||
drwxrwxrwx 2 98 98 512 May 29 16:04 download.html
|
||||
dr-xr-xr-x 2 0 1 512 Nov 30 1995 etc
|
||||
drwxrwxrwx 2 98 1 512 Oct 30 14:33 pub
|
||||
dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client requires=netrc_debug>
|
||||
<name>
|
||||
FTP (optional .netrc; no user/pass) dir list PASV
|
||||
</name>
|
||||
<command>
|
||||
--netrc-optional ftp://%HOSTIP:%FTPPORT/
|
||||
</command>
|
||||
<file name="log/netrc" >
|
||||
# the following two lines were created while testing curl
|
||||
machine %HOSTIP login user1 password passwd1
|
||||
machine %HOSTIP login user2 password passwd2
|
||||
</file>
|
||||
</test>
|
||||
|
||||
#
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<strip>
|
||||
filter off really nothing
|
||||
</strip>
|
||||
<protocol>
|
||||
USER user1
|
||||
PASS passwd1
|
||||
PWD
|
||||
EPSV
|
||||
TYPE A
|
||||
LIST
|
||||
</protocol>
|
||||
</verify>
|
49
tests/data/test131
Normal file
49
tests/data/test131
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# Server-side
|
||||
<reply name="1">
|
||||
<data>
|
||||
total 20
|
||||
drwxr-xr-x 8 98 98 512 Oct 22 13:06 .
|
||||
drwxr-xr-x 8 98 98 512 Oct 22 13:06 ..
|
||||
drwxr-xr-x 2 98 98 512 May 2 1996 .NeXT
|
||||
-r--r--r-- 1 0 1 35 Jul 16 1996 README
|
||||
lrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin
|
||||
dr-xr-xr-x 2 0 1 512 Oct 1 1997 dev
|
||||
drwxrwxrwx 2 98 98 512 May 29 16:04 download.html
|
||||
dr-xr-xr-x 2 0 1 512 Nov 30 1995 etc
|
||||
drwxrwxrwx 2 98 1 512 Oct 30 14:33 pub
|
||||
dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client requires=netrc_debug>
|
||||
<name>
|
||||
FTP (optional .netrc; user/no pass) dir list PASV
|
||||
</name>
|
||||
<command>
|
||||
--netrc-optional ftp://user2@%HOSTIP:%FTPPORT/
|
||||
</command>
|
||||
<file name="log/netrc" >
|
||||
# the following two lines were created while testing curl
|
||||
machine %HOSTIP login user1 password passwd1
|
||||
machine %HOSTIP login user2 password passwd2
|
||||
</file>
|
||||
</test>
|
||||
|
||||
#
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<strip>
|
||||
filter off really nothing
|
||||
</strip>
|
||||
<protocol>
|
||||
USER user2
|
||||
PASS passwd2
|
||||
PWD
|
||||
EPSV
|
||||
TYPE A
|
||||
LIST
|
||||
</protocol>
|
||||
</verify>
|
49
tests/data/test132
Normal file
49
tests/data/test132
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# Server-side
|
||||
<reply name="1">
|
||||
<data>
|
||||
total 20
|
||||
drwxr-xr-x 8 98 98 512 Oct 22 13:06 .
|
||||
drwxr-xr-x 8 98 98 512 Oct 22 13:06 ..
|
||||
drwxr-xr-x 2 98 98 512 May 2 1996 .NeXT
|
||||
-r--r--r-- 1 0 1 35 Jul 16 1996 README
|
||||
lrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin
|
||||
dr-xr-xr-x 2 0 1 512 Oct 1 1997 dev
|
||||
drwxrwxrwx 2 98 98 512 May 29 16:04 download.html
|
||||
dr-xr-xr-x 2 0 1 512 Nov 30 1995 etc
|
||||
drwxrwxrwx 2 98 1 512 Oct 30 14:33 pub
|
||||
dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client requires=netrc_debug>
|
||||
<name>
|
||||
FTP (optional .netrc; user/passwd supplied) dir list PASV
|
||||
</name>
|
||||
<command>
|
||||
--netrc-optional ftp://mary:mark@%HOSTIP:%FTPPORT/
|
||||
</command>
|
||||
<file name="log/netrc" >
|
||||
# the following two lines were created while testing curl
|
||||
machine %HOSTIP login user1 password passwd1
|
||||
machine %HOSTIP login user2 password passwd2
|
||||
</file>
|
||||
</test>
|
||||
|
||||
#
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<strip>
|
||||
filter off really nothing
|
||||
</strip>
|
||||
<protocol>
|
||||
USER mary
|
||||
PASS mark
|
||||
PWD
|
||||
EPSV
|
||||
TYPE A
|
||||
LIST
|
||||
</protocol>
|
||||
</verify>
|
49
tests/data/test133
Normal file
49
tests/data/test133
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# Server-side
|
||||
<reply name="1">
|
||||
<data>
|
||||
total 20
|
||||
drwxr-xr-x 8 98 98 512 Oct 22 13:06 .
|
||||
drwxr-xr-x 8 98 98 512 Oct 22 13:06 ..
|
||||
drwxr-xr-x 2 98 98 512 May 2 1996 .NeXT
|
||||
-r--r--r-- 1 0 1 35 Jul 16 1996 README
|
||||
lrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin
|
||||
dr-xr-xr-x 2 0 1 512 Oct 1 1997 dev
|
||||
drwxrwxrwx 2 98 98 512 May 29 16:04 download.html
|
||||
dr-xr-xr-x 2 0 1 512 Nov 30 1995 etc
|
||||
drwxrwxrwx 2 98 1 512 Oct 30 14:33 pub
|
||||
dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client requires=netrc_debug>
|
||||
<name>
|
||||
FTP (compulsory .netrc; ignored user/passwd) dir list PASV
|
||||
</name>
|
||||
<command>
|
||||
-n ftp://mary:mark@%HOSTIP:%FTPPORT/
|
||||
</command>
|
||||
<file name="log/netrc" >
|
||||
# the following two lines were created while testing curl
|
||||
machine %HOSTIP login user1 password passwd1
|
||||
machine %HOSTIP login user2 password passwd2
|
||||
</file>
|
||||
</test>
|
||||
|
||||
#
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<strip>
|
||||
filter off really nothing
|
||||
</strip>
|
||||
<protocol>
|
||||
USER user1
|
||||
PASS passwd1
|
||||
PWD
|
||||
EPSV
|
||||
TYPE A
|
||||
LIST
|
||||
</protocol>
|
||||
</verify>
|
49
tests/data/test134
Normal file
49
tests/data/test134
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# Server-side
|
||||
<reply name="1">
|
||||
<data>
|
||||
total 20
|
||||
drwxr-xr-x 8 98 98 512 Oct 22 13:06 .
|
||||
drwxr-xr-x 8 98 98 512 Oct 22 13:06 ..
|
||||
drwxr-xr-x 2 98 98 512 May 2 1996 .NeXT
|
||||
-r--r--r-- 1 0 1 35 Jul 16 1996 README
|
||||
lrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin
|
||||
dr-xr-xr-x 2 0 1 512 Oct 1 1997 dev
|
||||
drwxrwxrwx 2 98 98 512 May 29 16:04 download.html
|
||||
dr-xr-xr-x 2 0 1 512 Nov 30 1995 etc
|
||||
drwxrwxrwx 2 98 1 512 Oct 30 14:33 pub
|
||||
dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client requires=netrc_debug>
|
||||
<name>
|
||||
FTP (optional .netrc; programmatic user/passwd) dir list PASV
|
||||
</name>
|
||||
<command>
|
||||
--netrc-optional -u romulus:rhemus ftp://mary:mark@%HOSTIP:%FTPPORT/
|
||||
</command>
|
||||
<file name="log/netrc" >
|
||||
# the following two lines were created while testing curl
|
||||
machine %HOSTIP login user1 password passwd1
|
||||
machine %HOSTIP login user2 password passwd2
|
||||
</file>
|
||||
</test>
|
||||
|
||||
#
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<strip>
|
||||
filter off really nothing
|
||||
</strip>
|
||||
<protocol>
|
||||
USER romulus
|
||||
PASS rhemus
|
||||
PWD
|
||||
EPSV
|
||||
TYPE A
|
||||
LIST
|
||||
</protocol>
|
||||
</verify>
|
39
tests/data/test135
Normal file
39
tests/data/test135
Normal file
@@ -0,0 +1,39 @@
|
||||
# Server-side
|
||||
<reply>
|
||||
<data>
|
||||
0123456789abcdef
|
||||
0123456789abcdef
|
||||
0123456789abcdef
|
||||
0123456789abcdef
|
||||
</data>
|
||||
<datacheck nonewline=yes>
|
||||
0123456789abc
|
||||
</datacheck>
|
||||
<size>
|
||||
64
|
||||
</size>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<name>
|
||||
FTP retrieve a byte-range
|
||||
</name>
|
||||
<command>
|
||||
-r 4-16 ftp://%HOSTIP:%FTPPORT/135
|
||||
</command>
|
||||
</test>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol>
|
||||
USER anonymous
|
||||
PASS curl_by_daniel@haxx.se
|
||||
PWD
|
||||
EPSV
|
||||
TYPE I
|
||||
SIZE 135
|
||||
REST 4
|
||||
RETR 135
|
||||
</protocol>
|
||||
</verify>
|
@@ -7,6 +7,9 @@ my $warning=0;
|
||||
my $trace=0;
|
||||
|
||||
sub getpartattr {
|
||||
# if $part is undefined (ie only one argument) then
|
||||
# return the attributes of the section
|
||||
|
||||
my ($section, $part)=@_;
|
||||
|
||||
my %hash;
|
||||
@@ -19,7 +22,9 @@ sub getpartattr {
|
||||
if(!$inside && ($_ =~ /^ *\<$section/)) {
|
||||
$inside++;
|
||||
}
|
||||
elsif((1 ==$inside) && ($_ =~ /^ *\<$part([^>]*)/)) {
|
||||
if((1 ==$inside) && ( ($_ =~ /^ *\<$part([^>]*)/) ||
|
||||
!(defined($part)) )
|
||||
) {
|
||||
$inside++;
|
||||
my $attr=$1;
|
||||
my @p=split("[ \t]", $attr);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/perl
|
||||
#!/usr/bin/env perl
|
||||
#
|
||||
# Example input:
|
||||
#
|
||||
|
@@ -7,6 +7,7 @@
|
||||
# These should be the only variables that might be needed to get edited:
|
||||
|
||||
use strict;
|
||||
#use warnings;
|
||||
|
||||
@INC=(@INC, $ENV{'srcdir'}, ".");
|
||||
|
||||
@@ -20,6 +21,7 @@ my $HTTPSPORT=8433; # this is the HTTPS server port
|
||||
my $FTPPORT=8921; # this is the FTP server port
|
||||
my $FTPSPORT=8821; # this is the FTPS server port
|
||||
my $CURL="../src/curl"; # what curl executable to run on the tests
|
||||
my $DBGCURL=$CURL; #"../src/.libs/curl"; # alternative for debugging
|
||||
my $LOGDIR="log";
|
||||
my $TESTDIR="data";
|
||||
my $SERVERIN="$LOGDIR/server.input"; # what curl sent the server
|
||||
@@ -48,6 +50,11 @@ my $perl="perl -I$srcdir";
|
||||
# this gets set if curl is compiled with memory debugging:
|
||||
my $memory_debug=0;
|
||||
|
||||
# this gets set if curl is compiled with netrc debugging:
|
||||
# It has to be in the global symbol table because of the way 'requires' works
|
||||
$main::netrc_debug=0;
|
||||
my $netrc_debug = \$main::netrc_debug;
|
||||
|
||||
# name of the file that the memory debugging creates:
|
||||
my $memdump="memdump";
|
||||
|
||||
@@ -58,6 +65,8 @@ my $checkstunnel = &checkstunnel;
|
||||
|
||||
my $ssl_version; # set if libcurl is built with SSL support
|
||||
|
||||
my $skipped=0; # number of tests skipped; reported in main loop
|
||||
|
||||
#######################################################################
|
||||
# variables the command line options may set
|
||||
#
|
||||
@@ -390,14 +399,35 @@ sub displaydata {
|
||||
# enabled and we shall verify that no memory leaks exist
|
||||
# after each and every test!
|
||||
$memory_debug=1;
|
||||
|
||||
# there's only one debug control in the configure script
|
||||
# so hope netrc debugging is enabled and set it up
|
||||
$$netrc_debug = 1;
|
||||
$ENV{'CURL_DEBUG_NETRC'} = 'log/netrc';
|
||||
}
|
||||
printf("* Memory debugging: %s\n", $memory_debug?"ON":"OFF");
|
||||
printf("* Netrc debugging: %s\n", $$netrc_debug?"ON":"OFF");
|
||||
printf("* HTTPS server: %s\n", $checkstunnel?"ON":"OFF");
|
||||
printf("* FTPS server: %s\n", $checkstunnel?"ON":"OFF");
|
||||
printf("* libcurl SSL: %s\n", $ssl_version?"ON":"OFF");
|
||||
print "***************************************** \n";
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# substitute the variable stuff into either a joined up file or
|
||||
# a command, in either case passed by reference
|
||||
#
|
||||
sub subVariables {
|
||||
my ($thing) = @_;
|
||||
$$thing =~ s/%HOSTIP/$HOSTIP/g;
|
||||
$$thing =~ s/%HOSTPORT/$HOSTPORT/g;
|
||||
$$thing =~ s/%HTTPSPORT/$HTTPSPORT/g;
|
||||
$$thing =~ s/%FTPPORT/$FTPPORT/g;
|
||||
$$thing =~ s/%FTPSPORT/$FTPSPORT/g;
|
||||
$$thing =~ s/%SRCDIR/$srcdir/g;
|
||||
$$thing =~ s/%PWD/$pwd/g;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# Run a single specified test case
|
||||
#
|
||||
@@ -414,12 +444,41 @@ sub singletest {
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
my %hash = getpartattr("client");
|
||||
my $requires = $hash{'requires'};
|
||||
|
||||
if (defined($requires)) {
|
||||
no strict "refs";
|
||||
my $value=${$requires};
|
||||
# print "This test requires '$requires' with value '$value' \n";
|
||||
|
||||
if (${$requires}) {
|
||||
# this test is OK
|
||||
;
|
||||
}else {
|
||||
print "$testnum requires $requires, which is not set; skipping\n";
|
||||
$skipped++;
|
||||
return 0; # look successful
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# extract the reply data
|
||||
my @reply = getpart("reply", "data");
|
||||
my @replycheck = getpart("reply", "datacheck");
|
||||
|
||||
if (@replycheck) {
|
||||
# we use this file instead to check the final output against
|
||||
|
||||
my %hash = getpartattr("reply", "datacheck");
|
||||
if($hash{'nonewline'}) {
|
||||
# Yes, we must cut off the final newline from the final line
|
||||
# of the datacheck
|
||||
chomp($replycheck[$#replycheck]);
|
||||
}
|
||||
|
||||
@reply=@replycheck;
|
||||
}
|
||||
|
||||
@@ -471,13 +530,16 @@ sub singletest {
|
||||
|
||||
# make some nice replace operations
|
||||
$cmd =~ s/\n//g; # no newlines please
|
||||
$cmd =~ s/%HOSTIP/$HOSTIP/g;
|
||||
$cmd =~ s/%HOSTPORT/$HOSTPORT/g;
|
||||
$cmd =~ s/%HTTPSPORT/$HTTPSPORT/g;
|
||||
$cmd =~ s/%FTPPORT/$FTPPORT/g;
|
||||
$cmd =~ s/%FTPSPORT/$FTPSPORT/g;
|
||||
$cmd =~ s/%SRCDIR/$srcdir/g;
|
||||
$cmd =~ s/%PWD/$pwd/g;
|
||||
|
||||
subVariables \$cmd;
|
||||
|
||||
# $cmd =~ s/%HOSTIP/$HOSTIP/g;
|
||||
# $cmd =~ s/%HOSTPORT/$HOSTPORT/g;
|
||||
# $cmd =~ s/%HTTPSPORT/$HTTPSPORT/g;
|
||||
# $cmd =~ s/%FTPPORT/$FTPPORT/g;
|
||||
# $cmd =~ s/%FTPSPORT/$FTPSPORT/g;
|
||||
# $cmd =~ s/%SRCDIR/$srcdir/g;
|
||||
# $cmd =~ s/%PWD/$pwd/g;
|
||||
|
||||
#$cmd =~ s/%HOSTNAME/$HOSTNAME/g;
|
||||
|
||||
@@ -491,11 +553,17 @@ sub singletest {
|
||||
my %hash = getpartattr("client", "file");
|
||||
|
||||
my $filename=$hash{'name'};
|
||||
|
||||
if(!$filename) {
|
||||
print "ERROR: section client=>file has no name attribute!\n";
|
||||
exit;
|
||||
}
|
||||
writearray($filename, \@inputfile);
|
||||
my $fileContent = join('', @inputfile);
|
||||
subVariables \$fileContent;
|
||||
# print "DEBUG: writing file " . $filename . "\n";
|
||||
open OUTFILE, ">$filename";
|
||||
print OUTFILE $fileContent;
|
||||
close OUTFILE;
|
||||
}
|
||||
|
||||
my %cmdhash = getpartattr("client", "command");
|
||||
@@ -537,7 +605,7 @@ sub singletest {
|
||||
print GDBCMD "set args $cmdargs\n";
|
||||
print GDBCMD "show args\n";
|
||||
close(GDBCMD);
|
||||
system("gdb $CURL -x log/gdbcmd");
|
||||
system("gdb $DBGCURL -x log/gdbcmd");
|
||||
$res =0; # makes it always continue after a debugged run
|
||||
}
|
||||
else {
|
||||
@@ -909,7 +977,6 @@ my $failed;
|
||||
my $testnum;
|
||||
my $ok=0;
|
||||
my $total=0;
|
||||
my $skipped=0;
|
||||
|
||||
foreach $testnum (split(" ", $TESTCASES)) {
|
||||
|
||||
|
@@ -4,8 +4,8 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define EAT_SPACE(ptr) while( ptr && *ptr && isspace(*ptr) ) ptr++
|
||||
#define EAT_WORD(ptr) while( ptr && *ptr && !isspace(*ptr) && ('>' != *ptr)) ptr++
|
||||
#define EAT_SPACE(ptr) while( ptr && *ptr && isspace((int)*ptr) ) ptr++
|
||||
#define EAT_WORD(ptr) while( ptr && *ptr && !isspace((int)*ptr) && ('>' != *ptr)) ptr++
|
||||
|
||||
#ifdef DEBUG
|
||||
#define show(x) printf x
|
||||
|
@@ -1,4 +1,32 @@
|
||||
/* sws.c: simple (silly?) web server */
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* In order to be useful for every potential user, curl and libcurl are
|
||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||
*
|
||||
* 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 MPL or the MIT/X-derivate
|
||||
* licenses. You may pick one of these licenses.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
/* sws.c: simple (silly?) web server
|
||||
|
||||
This code was originally graciously donated to the project Juergen
|
||||
Wilke. Thanks a bunch!
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -13,7 +41,10 @@
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
char *spitout(FILE *stream, char *main, char *sub, int *size);
|
||||
const char *
|
||||
spitout(FILE *stream,
|
||||
const char *main,
|
||||
const char *sub, int *size);
|
||||
|
||||
#define DEFAULT_PORT 8999
|
||||
|
||||
@@ -27,8 +58,8 @@ char *spitout(FILE *stream, char *main, char *sub, int *size);
|
||||
|
||||
#define TEST_DATA_PATH "data/test%d"
|
||||
|
||||
static char *docfriends = "HTTP/1.1 200 Mighty fine indeed\r\n\r\nWE ROOLZ\r\n";
|
||||
static char *doc404 = "HTTP/1.1 404 Not Found\n"
|
||||
static const char *docfriends = "HTTP/1.1 200 Mighty fine indeed\r\n\r\nWE ROOLZ\r\n";
|
||||
static const char *doc404 = "HTTP/1.1 404 Not Found\n"
|
||||
"Server: " VERSION "\n"
|
||||
"Connection: close\n"
|
||||
"Content-Type: text/html\n"
|
||||
@@ -41,7 +72,9 @@ static char *doc404 = "HTTP/1.1 404 Not Found\n"
|
||||
"The requested URL was not found on this server.\n"
|
||||
"<P><HR><ADDRESS>" VERSION "</ADDRESS>\n" "</BODY></HTML>\n";
|
||||
|
||||
static volatile int sigpipe, sigterm;
|
||||
#ifdef HAVE_SIGNAL
|
||||
static volatile int sigpipe;
|
||||
#endif
|
||||
static FILE *logfp;
|
||||
|
||||
|
||||
@@ -53,27 +86,21 @@ static void logmsg(const char *msg)
|
||||
|
||||
strcpy(loctime, asctime(curr_time));
|
||||
loctime[strlen(loctime) - 1] = '\0';
|
||||
fprintf(logfp, "%s: pid %d: %s\n", loctime, getpid(), msg);
|
||||
fprintf(logfp, "%s: pid %d: %s\n", loctime, (int)getpid(), msg);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "%s: pid %d: %s\n", loctime, getpid(), msg);
|
||||
fprintf(stderr, "%s: pid %d: %s\n", loctime, (int)getpid(), msg);
|
||||
#endif
|
||||
fflush(logfp);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_SIGNAL
|
||||
static void sigpipe_handler(int sig)
|
||||
{
|
||||
(void)sig; /* prevent warning */
|
||||
sigpipe = 1;
|
||||
}
|
||||
|
||||
|
||||
static void sigterm_handler(int sig)
|
||||
{
|
||||
char logbuf[100];
|
||||
sprintf(logbuf, "Got signal %d, terminating", sig);
|
||||
logmsg(logbuf);
|
||||
sigterm = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ProcessRequest(char *request)
|
||||
{
|
||||
@@ -237,7 +264,7 @@ static int send_doc(int sock, int doc, int part_no)
|
||||
{
|
||||
int written;
|
||||
int count;
|
||||
char *buffer;
|
||||
const char *buffer;
|
||||
char *ptr;
|
||||
FILE *stream;
|
||||
char *cmd=NULL;
|
||||
@@ -271,7 +298,8 @@ static int send_doc(int sock, int doc, int part_no)
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
ptr = buffer = spitout(stream, "reply", partbuf, &count);
|
||||
buffer = spitout(stream, "reply", partbuf, &count);
|
||||
ptr = (char *)buffer;
|
||||
fclose(stream);
|
||||
}
|
||||
|
||||
@@ -283,7 +311,7 @@ static int send_doc(int sock, int doc, int part_no)
|
||||
}
|
||||
else {
|
||||
/* get the custom server control "commands" */
|
||||
cmd = spitout(stream, "reply", "postcmd", &cmdsize);
|
||||
cmd = (char *)spitout(stream, "reply", "postcmd", &cmdsize);
|
||||
fclose(stream);
|
||||
}
|
||||
}
|
||||
@@ -330,7 +358,7 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in me;
|
||||
int sock, msgsock, flag;
|
||||
unsigned short port = DEFAULT_PORT;
|
||||
char *logfile = DEFAULT_LOGFILE;
|
||||
const char *logfile = DEFAULT_LOGFILE;
|
||||
int part_no;
|
||||
FILE *pidfile;
|
||||
|
||||
@@ -348,12 +376,8 @@ int main(int argc, char *argv[])
|
||||
#ifdef HAVE_SIGNAL
|
||||
/* FIX: make a more portable signal handler */
|
||||
signal(SIGPIPE, sigpipe_handler);
|
||||
signal(SIGINT, sigterm_handler);
|
||||
signal(SIGTERM, sigterm_handler);
|
||||
|
||||
siginterrupt(SIGPIPE, 1);
|
||||
siginterrupt(SIGINT, 1);
|
||||
siginterrupt(SIGTERM, 1);
|
||||
#endif
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
@@ -394,18 +418,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
fprintf(stderr, "*** %s listening on port %u ***\n", VERSION, port);
|
||||
|
||||
while (!sigterm) {
|
||||
while (1) {
|
||||
int doc;
|
||||
|
||||
msgsock = accept(sock, NULL, NULL);
|
||||
|
||||
if (msgsock == -1) {
|
||||
if (sigterm) {
|
||||
break;
|
||||
}
|
||||
/* perror("accept"); */
|
||||
if (msgsock == -1)
|
||||
continue;
|
||||
}
|
||||
|
||||
logmsg("New client connected");
|
||||
|
||||
|
Reference in New Issue
Block a user