Compare commits

..

79 Commits

Author SHA1 Message Date
Daniel Stenberg
67273eed9b 7.9.8 commit 2002-06-13 14:37:15 +00:00
Daniel Stenberg
3c63e1d8d9 Added 'dont_check' to be set during an FTP operation if the final status
message is supposed to be ignored.
2002-06-13 09:21:08 +00:00
Daniel Stenberg
cae555c977 when no FTP transfer was done, don't attempt to read the download transfer
thing. The 'resumed' flag is also causing confusions. I'll deal with that
tomorrow.
2002-06-12 22:05:28 +00:00
Daniel Stenberg
407583e8e2 Moved the secondarysocket cleanup. The 'conn' struct may have been cleared
already at that other place.
2002-06-12 22:04:25 +00:00
Daniel Stenberg
131645dc31 Chris Combes added CURLFORM_BUFFER, CURLFORM_BUFFERPTR, CURLFORM_BUFFERLENGTH 2002-06-12 21:40:59 +00:00
Daniel Stenberg
dafd644fe7 fixing builds, patching bugs, adding curl_formadd() options 2002-06-12 21:40:30 +00:00
Daniel Stenberg
73cc1742af HAVE_SIGSETJMP 2002-06-12 17:56:22 +00:00
Daniel Stenberg
87afd7686f added a connect failure error message that might get empty otherwise 2002-06-12 09:48:26 +00:00
Daniel Stenberg
8ce10b5dfa Jrn fixes for 7.9.8 build 2002-06-12 09:18:37 +00:00
Daniel Stenberg
943e31b35c CURLOPT_MAXFILESIZE 2002-06-12 08:16:59 +00:00
Daniel Stenberg
20f85b94df kris@freebsd.org fixed a bad format string 2002-06-12 07:45:11 +00:00
Daniel Stenberg
17b784381e kris@freebsd.org fixed a few bad format strings 2002-06-12 07:44:22 +00:00
Daniel Stenberg
e3031fddb9 Add QNX 2002-06-12 07:26:13 +00:00
Daniel Stenberg
38c994a7ae put #ifdefs around the sigjmp_buf declaration too, as it should be 2002-06-11 15:47:01 +00:00
Daniel Stenberg
85e2e96fb6 corrected the signal handler 2002-06-11 15:44:27 +00:00
Daniel Stenberg
be35b3ad03 7.9.8-pre3 commit 2002-06-11 15:28:50 +00:00
Daniel Stenberg
dbbd871ea1 the disable protocol stuff is now added 2002-06-11 15:24:47 +00:00
Daniel Stenberg
813911db59 more nonewline support 2002-06-11 15:11:41 +00:00
Daniel Stenberg
3c49b405de Now uses sigsetjmp() and siglongjmp() to bail out from slow name lookups in
case a timeout is set. This seems to work. God knows if it is good enough
or what kind of side-effects we introduce here and now.

I'll close my eyes and cross my fingers. Hard.
2002-06-11 15:10:18 +00:00
Daniel Stenberg
4cfffd6c4a cut up the string in more pieces for <512 bytes strings 2002-06-11 15:09:02 +00:00
Daniel Stenberg
e9f1c12f0f removed accidentally added debug-code! 2002-06-11 14:10:32 +00:00
Daniel Stenberg
4fe252847c ftp range downloads make us ignore the final status message as the server
will most likely treat the download as failed as we might abort it
pre-maturely
2002-06-11 12:35:03 +00:00
Daniel Stenberg
109cbbe9c5 added test135 ftp byte-range download 2002-06-11 12:25:46 +00:00
Daniel Stenberg
fd3881eaa6 added --disable-[protocol] support 2002-06-11 11:13:29 +00:00
Daniel Stenberg
08ef208fb7 added disable-[protocol] support, largely provided by Miklos Nemeth 2002-06-11 11:13:01 +00:00
Daniel Stenberg
8c45e2a641 Added disable-defines 2002-06-11 11:12:27 +00:00
Daniel Stenberg
25dc520163 added multi.obj 2002-06-11 11:11:06 +00:00
Daniel Stenberg
fc37ef9e4b make sure data->set.postfields is non-NULL before doing strlen() on the
pointer. Bugs item #566835.
2002-06-11 07:20:21 +00:00
Daniel Stenberg
11ba367fc9 getaddrinfo() failures now show port number too in informational output 2002-06-10 13:26:02 +00:00
Daniel Stenberg
78473f71eb added a missing failf() for certain connect failures 2002-06-10 13:25:03 +00:00
Daniel Stenberg
8b77f40f99 This fix MIGHT make us build nicely with OpenSSL 0.9.7. This fix is based
on a patch from Jacob Meuser, input from Gtz Babin-Ebell and my own
browsing of the latest include files.
2002-06-10 12:38:10 +00:00
Daniel Stenberg
d866716565 Gautam Mani found a socket descriptor leak that happened when FTP transfers
failed and you reinvoked curl_easy_perform().
2002-06-10 12:34:04 +00:00
Daniel Stenberg
307d0effe2 Added HAVE_SYS_TYPES_H 2002-06-07 06:17:05 +00:00
Daniel Stenberg
b47b053e54 Gustaf Hui fixed curl_multi_remove_handle() to prevent a potential crash 2002-06-05 21:29:20 +00:00
Daniel Stenberg
b79f01caf3 set HAVE_RAND_STATUS too 2002-06-05 14:14:54 +00:00
Daniel Stenberg
0db227f55e hostcache_fixoffset() is now corrected to work on 64bit architectures
Bug report #564585.
2002-06-05 13:41:33 +00:00
Daniel Stenberg
ac48b38842 more stuff since pre1 2002-06-04 11:53:31 +00:00
Daniel Stenberg
0cbb9365c6 indent like the other ones 2002-06-03 13:37:09 +00:00
Daniel Stenberg
798b8c522b Christophe Espern wrote another binding! 2002-06-03 13:20:23 +00:00
Daniel Stenberg
15bc7e19f9 updated header 2002-06-03 13:04:35 +00:00
Daniel Stenberg
0be3f1a063 T. Bharath's updates since curl now uses the winmm lib for higher resolution
timer
2002-06-03 12:48:31 +00:00
Daniel Stenberg
c0257c6721 T. Bharath made the request size add up as it is documented to do. 2002-06-03 12:47:08 +00:00
Daniel Stenberg
9aec0fc7de T. Bharath fixed higher resolution time for windows builds 2002-06-03 12:46:32 +00:00
Daniel Stenberg
bce5e0d82c T. Bharath fixed the TIMER_REDIRECT. 2002-06-03 12:46:04 +00:00
Daniel Stenberg
62032ee248 Getting an empty FTP file no longer makes us return error 19. An empty file
is fine to get.
2002-05-28 22:33:30 +00:00
Daniel Stenberg
775645f29b 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.

 I made the messages only get stored per easy-handle so that they can be
 independently killed easier without ruining the "master list". It makes
 the info_read() function slightly less beautiful as it has to scan for
 messages to return, but it makes removing individual handles a lot easier
 and less error prone.
2002-05-28 14:45:50 +00:00
Daniel Stenberg
99c0456872 Adjusted to make curl_multi_perform() work properly even when
curl_multi_fdset() is not used.
2002-05-28 14:18:36 +00:00
Daniel Stenberg
0236bee5de I trimmed the --help output slightly to better fit within 80 cols 2002-05-28 09:31:48 +00:00
Daniel Stenberg
59c11b82d5 Cris Bailiff's CAPATH support added 2002-05-28 09:21:29 +00:00
Daniel Stenberg
98871d1e9e new url, spell checked 2002-05-22 22:14:03 +00:00
Daniel Stenberg
b40dc5d742 since 7.9.7 2002-05-22 11:08:19 +00:00
Daniel Stenberg
17b0723713 James Cone's little work-around for the strict error 2002-05-21 22:39:09 +00:00
Daniel Stenberg
ec585e8907 When re-using a connection, make sure that we use the current host name as
we might actually re-use a connection to a different host, when using proxies!

This was what bug report #558888 was all about.
2002-05-21 22:24:56 +00:00
Daniel Stenberg
0aeb25ff3b James Cone added the new CURL_NETRC_OPTION enum 2002-05-21 22:22:28 +00:00
Daniel Stenberg
a928f2c4aa test suite mods for the netrc testing stuff 2002-05-21 22:20:52 +00:00
Daniel Stenberg
51fcee6f81 James Cone added CURLOPT_NETRC / --netrc / --netrc-optional descriptions 2002-05-21 22:20:16 +00:00
Daniel Stenberg
654be65590 Use the new CURLOPT_NETRC option and adds --netrc-optional, by James Cone 2002-05-21 22:18:34 +00:00
Daniel Stenberg
105ec79b2b James Cone's efforts to add another netrc parsing "mode" 2002-05-21 22:17:19 +00:00
Daniel Stenberg
c759d8427a five new test cases for the netrc parsing 2002-05-21 22:14:08 +00:00
Daniel Stenberg
c7b03d6479 maprintf() and vmaprintf() now work better when printfing "%s" with an
empty string
2002-05-21 17:59:57 +00:00
Daniel Stenberg
2080738883 corrected see also 2002-05-21 14:00:55 +00:00
Daniel Stenberg
48bc73c271 3.14 added, javascript support 2002-05-21 13:53:32 +00:00
Daniel Stenberg
3d0969d1d1 Added source header and made it clear that this code was originally donated
to us by Juergen Wilke.
2002-05-21 08:22:00 +00:00
Daniel Stenberg
323f195036 ASN1 files don't work for the *chain_file(), make them use the previous
version
2002-05-21 08:15:42 +00:00
Daniel Stenberg
c3c392fc98 return type CURLFORMcode instead of plain int 2002-05-21 07:47:09 +00:00
Daniel Stenberg
5d2944c211 curl_formadd() now returns 'CURLFORMcode' instead of int, to better enable
checking for particular errors. curl/curl.h defines the errros
2002-05-21 07:44:27 +00:00
Daniel Stenberg
fe3ba1dd11 Roland Zimmermann's hint, we use SSL_CTX_use_certificate_chain_file() instead
of the previous one that used SSL_CTX_use_certificate_file()
2002-05-20 14:25:35 +00:00
Daniel Stenberg
0c00eb93a0 removed compiler warnings 2002-05-17 08:15:33 +00:00
Daniel Stenberg
baa77ec13b FreeBSD needs sys/types.h before we include sys/select.h that was included
mainly for AIX in the first place...! As reported in bug report #556869
2002-05-17 07:57:13 +00:00
Daniel Stenberg
9263652c6d Fixes bug report #556930 - we need to make sure that the data is all right
after we've realloc() the packed hostent struct.
2002-05-17 07:49:28 +00:00
Daniel Stenberg
bc74375543 Added item 4.10 after talks with Russ Freeman 2002-05-15 21:40:29 +00:00
Daniel Stenberg
edb1756050 7.9.7 commit 2002-05-13 09:40:16 +00:00
Daniel Stenberg
5215f6f654 we don't need win32sockets.c anymore, we support this internally 2002-05-13 07:29:22 +00:00
Daniel Stenberg
1913b4eeed fopen.c added, a fopen() style emulation for URL reading 2002-05-13 07:28:10 +00:00
Daniel Stenberg
b44a4da5df Friday's fixes 2002-05-12 16:10:12 +00:00
Daniel Stenberg
919878fbb2 AIX 5.1 2002-05-10 16:01:24 +00:00
Daniel Stenberg
06bdf83419 Kein Roth made --trace-ascii look even better, and make OD 0A occurances
get output as plain newlines.
2002-05-10 15:59:42 +00:00
Daniel Stenberg
2ff2810a92 AIX wants sys/select.h for the fd_set stuff in curl/multi.h, and even though
it is a bit ugly work-around to add this here, it is still a working work-
around! ;-)
2002-05-10 14:37:39 +00:00
Daniel Stenberg
20d9c1b30d Patrick Smith's contributed docs improvements for when NLST is used by
curl...
2002-05-07 23:36:53 +00:00
72 changed files with 2487 additions and 1007 deletions

149
CHANGES
View File

@@ -6,6 +6,155 @@
History of Changes 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)
- Kevin Roth adjusted the --trace-ascii output slightly.
- Paul Harrington found out that src/writeout.c needed an additional header
file included for AIX builds
Version 7.9.7-pre2 Version 7.9.7-pre2
Daniel (7 May 2002) Daniel (7 May 2002)

View File

@@ -64,3 +64,24 @@
/* Define this to 'int' if in_addr_t is not an available typedefed type */ /* Define this to 'int' if in_addr_t is not an available typedefed type */
#undef in_addr_t #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

View File

@@ -56,24 +56,117 @@ dnl AC_PROG_INSTALL
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
dnl ************************************************************ dnl ************************************************************
dnl lame option to switch on debug options dnl switch off particular protocols
dnl dnl
AC_MSG_CHECKING([whether to enable debug options]) AC_MSG_CHECKING([whether to support http])
AC_ARG_ENABLE(debug, AC_ARG_ENABLE(http,
[ --enable-debug Enable pedantic debug options [ --enable-http Enable HTTP support
--disable-debug Disable debug options], --disable-http Disable HTTP support],
[ case "$enableval" in [ case "$enableval" in
no) no)
AC_MSG_RESULT(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) *) AC_MSG_RESULT(yes)
CPPFLAGS="$CPPFLAGS -DMALLOCDEBUG"
CFLAGS="-W -Wall -Wwrite-strings -pedantic -Wundef -Wpointer-arith -Wcast-align -Wnested-externs -g"
;; ;;
esac ], 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 **********************************************************************
dnl Checks for IPv6 dnl Checks for IPv6
@@ -82,7 +175,7 @@ dnl **********************************************************************
AC_MSG_CHECKING([whether to enable ipv6]) AC_MSG_CHECKING([whether to enable ipv6])
AC_ARG_ENABLE(ipv6, AC_ARG_ENABLE(ipv6,
[ --enable-ipv6 Enable ipv6 (with ipv4) support [ --enable-ipv6 Enable ipv6 (with ipv4) support
--disable-ipv6 Disable ipv6 support], --disable-ipv6 Disable ipv6 support],
[ case "$enableval" in [ case "$enableval" in
no) no)
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
@@ -510,7 +603,8 @@ AC_CHECK_HEADERS( \
io.h \ io.h \
pwd.h \ pwd.h \
utime.h \ utime.h \
sys/utime.h sys/utime.h \
setjmp.h
) )
dnl Check for libz header dnl Check for libz header
@@ -565,9 +659,23 @@ AC_CHECK_FUNCS( socket \
getpwuid \ getpwuid \
geteuid \ geteuid \
dlopen \ 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 dnl removed 'getpass' check on October 26, 2000
if test "$ac_cv_func_select" != "yes"; then 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 $PATH:/usr/bin/:/usr/local/bin )
dnl AC_SUBST(RANLIB) 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 \ AC_CONFIG_FILES([Makefile \
docs/Makefile \ docs/Makefile \
docs/examples/Makefile \ docs/examples/Makefile \

View File

@@ -61,6 +61,27 @@ while test $# -gt 0; do
if test "@IPV6_ENABLED@" = "1"; then if test "@IPV6_ENABLED@" = "1"; then
echo "IPv6" echo "IPv6"
fi 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) --version)

View File

@@ -45,9 +45,14 @@ Lua
Written by Steve Dekorte. Written by Steve Dekorte.
http://curl.haxx.se/libcurl/lua/ http://curl.haxx.se/libcurl/lua/
Object-Pascal
Free Pascal, Delphi and Kylix binding written by Christophe Espern.
http://www.tekool.com/opcurl
Pascal Pascal
Free Pascal binding written by Jeffrey Pohlmeyer. Free Pascal, Delphi and Kylix binding written by Jeffrey Pohlmeyer.
http://houston.quik.com/jkp/curlpas/ http://houston.quik.com/jkp/curlpas/
Perl Perl

View File

@@ -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.3 Why doesn't my posting using -F work?
3.4 How do I tell curl to run custom FTP commands? 3.4 How do I tell curl to run custom FTP commands?
3.5 How can I disable the Pragma: nocache header? 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.7 Can I use curl to delete/rename a file through FTP?
3.8 How do I tell curl to follow HTTP redirects? 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.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP?
3.11 How do I POST with a different Content-Type? 3.11 How do I POST with a different Content-Type?
3.12 Why do FTP specific features over HTTP proxy fail? 3.12 Why do FTP specific features over HTTP proxy fail?
3.13 Why does my single/double quotes 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. Running Problems
4.1 Problems connecting to SSL servers. 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.7 How do I keep user names and passwords secret in Curl command lines?
4.8 I found a bug! 4.8 I found a bug!
4.9 Curl can't authenticate to the server that requires NTLM? 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. libcurl Issues
5.1 Is libcurl thread-safe? 5.1 Is libcurl thread-safe?
@@ -201,7 +203,7 @@ FAQ
mailing lists are listed in the MANUAL document and online at mailing lists are listed in the MANUAL document and online at
http://curl.haxx.se/mail/ 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 to join in and help, to share their ideas, contribute their suggestions and
spread their wisdom. Keeping discussions on public mailing lists also allows 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 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 the -H/--header option. By adding a header with empty contents you safely
disable that one. Use -H "Pragma:" to disable that specific header. 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 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 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 HTML-files. There's no difference to curl and it doesn't even know what kind
of language that generated the page. of language that generated the page.
Javascript is slightly different since that is code embedded in the HTML See also item 3.14 regarding javascript.
that is sent for the client to interpret and curl has no javascript
interpreter.
3.7. Can I use curl to delete/rename a file through FTP? 3.7. Can I use curl to delete/rename a file through FTP?
@@ -351,7 +351,7 @@ FAQ
curl -L http://redirector.com 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 There exist many language interfaces/bindings for curl that integrates it
better with various languages. If you are fluid in a script language, you 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 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 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. etc.
There is one exception to this rule, and that is if you can "tunnel through" 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 curl -d ' with spaces ' url.com
Exactly what kind of quotes and how to do this is entirely up to the shell 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 can more or less pick either single (') or double (") quotes. For
Windows/DOS prompts I believe you're forced to use double (") quotes. 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 the curl docs will use a mix of both these ones as shown above. You must
adjust them to work in your environment. adjust them to work in your environment.
Remember that curl works and runs on more operating systems than most single Remember that curl works and runs on more operating systems than most single
individuals have ever tried. 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 4. Running Problems
@@ -511,7 +535,7 @@ FAQ
4.5.6 "301 Moved Permanently" 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 <H1>Moved Permanently</H1> The document has moved <A
HREF="http://same_url_now_with_a_trailing_slash/">here</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 currently support that. Proprietary formats are evil. You should not use
such ones. 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. libcurl Issues
5.1. Is libcurl thread-safe? 5.1. Is libcurl thread-safe?

View File

@@ -411,7 +411,7 @@ PORTS
- MIPS IRIX 6.2, 6.5 - MIPS IRIX 6.2, 6.5
- MIPS Linux - MIPS Linux
- Pocket PC/Win CE 3.0 - Pocket PC/Win CE 3.0
- Power AIX 4.2, 4.3.1, 4.3.2 - Power AIX 4.2, 4.3.1, 4.3.2, 5.1
- PowerPC Darwin 1.0 - PowerPC Darwin 1.0
- PowerPC Linux - PowerPC Linux
- PowerPC Mac OS 9 - PowerPC Mac OS 9
@@ -434,6 +434,7 @@ PORTS
- i386 SCO unix - i386 SCO unix
- i386 Solaris 2.7 - i386 Solaris 2.7
- i386 Windows 95, 98, ME, NT, 2000 - i386 Windows 95, 98, ME, NT, 2000
- i386 QNX 6
- ia64 Linux 2.3.99 - ia64 Linux 2.3.99
- m68k AmigaOS 3 - m68k AmigaOS 3
- m68k Linux - m68k Linux

View File

@@ -716,9 +716,9 @@ NETRC
passwords, so therefor most unix programs won't read this file unless it is passwords, so therefor most unix programs won't read this file unless it is
only readable by yourself (curl doesn't care though). only readable by yourself (curl doesn't care though).
Curl supports .netrc files if told so (using the -n/--netrc option). This is Curl supports .netrc files if told so (using the -n/--netrc and
not restricted to only ftp, but curl can use it for all protocols where --netrc-optional options). This is not restricted to only ftp,
authentication is used. but curl can use it for all protocols where authentication is used.
A very simple .netrc file could look something like: A very simple .netrc file could look something like:

View File

@@ -17,16 +17,10 @@ TODO
* Make content encoding/decoding internally be made using a filter system. * 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 * Introduce another callback interface for upload/download that makes one
less copy of data and thus a faster operation. less copy of data and thus a faster operation.
[http://curl.haxx.se/dev/no_copy_callbacks.txt] [http://curl.haxx.se/dev/no_copy_callbacks.txt]
* 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 * 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 This should be made to work on most of the supported platforms, or
otherwise it isn't really interesting. 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 the built-in progress meter use its own dedicated output stream, and
make it possible to set it. Use stderr by default. 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 DOCUMENTATION

View File

@@ -211,7 +211,17 @@ certificate concatenated!
If this option is used several times, the last one will be used. If this option is used several times, the last one will be used.
.IP "--cacert <CA certificate>" .IP "--cacert <CA certificate>"
(HTTPS) Tells curl to use the specified certificate file to verify the (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. If this option is used several times, the last one will be used.
.IP "-f/--fail" .IP "-f/--fail"
@@ -329,6 +339,10 @@ Especially useful if you want to machine-parse the contents of an FTP
directory since the normal directory view doesn't use a standard look directory since the normal directory view doesn't use a standard look
or format. or format.
This option causes an FTP NLST command to be sent. Some FTP servers
list only files in their response to NLST; they do not include
subdirectories and symbolic links.
If this option is used twice, the second will again disable list only. If this option is used twice, the second will again disable list only.
.IP "-L/--location" .IP "-L/--location"
(HTTP/HTTPS) If the server reports that the requested page has a different (HTTP/HTTPS) If the server reports that the requested page has a different

View File

@@ -4,11 +4,12 @@
AUTOMAKE_OPTIONS = foreign no-dependencies AUTOMAKE_OPTIONS = foreign no-dependencies
EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \ EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \
win32sockets.c persistant.c ftpget.c Makefile.example \ persistant.c ftpget.c Makefile.example \
multithread.c getinmemory.c ftpupload.c httpput.c \ multithread.c getinmemory.c ftpupload.c httpput.c \
simplessl.c ftpgetresp.c http-post.c post-callback.c \ simplessl.c ftpgetresp.c http-post.c post-callback.c \
multi-app.c multi-double.c multi-single.c multi-post.c multi-app.c multi-double.c multi-single.c multi-post.c \
fopen.c
all: all:
@echo "done" @echo "done"

222
docs/examples/fopen.c Normal file
View File

@@ -0,0 +1,222 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*
* This example source code introduces an fopen()/fread()/fclose() emulation
* for URL reads. Using an approach similar to this, you could replace your
* program's fopen() with this url_fopen() and fread() with url_fread() and
* it should be possible to read remote streams instead of (only) local files.
*
* See the main() function at the bottom that shows a tiny app in action.
*
* This source code is a proof of concept. It will need further attention to
* become production-use useful and solid.
*
* This example requires libcurl 7.9.7 or later.
*/
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
struct data {
int type;
union {
CURL *curl;
FILE *file;
} handle;
/* TODO: We should perhaps document the biggest possible buffer chunk we can
get from libcurl in one single callback... */
char buffer[CURL_MAX_WRITE_SIZE];
char *readptr; /* read from here */
int bytes; /* bytes available from read pointer */
CURLMcode m; /* stored from a previous url_fread() */
};
typedef struct data URL_FILE;
/* we use a global one for convenience */
CURLM *multi_handle;
static
size_t write_callback(char *buffer,
size_t size,
size_t nitems,
void *userp)
{
URL_FILE *url = (URL_FILE *)userp;
size *= nitems;
memcpy(url->readptr, buffer, size);
url->readptr += size;
url->bytes += size;
return size;
}
URL_FILE *url_fopen(char *url, char *operation)
{
/* this code could check for URLs or types in the 'url' and
basicly use the real fopen() for standard files */
URL_FILE *file;
int still_running;
file = (URL_FILE *)malloc(sizeof(URL_FILE));
if(!file)
return NULL;
memset(file, 0, sizeof(URL_FILE));
file->type = 1; /* marked as URL, use 0 for plain file */
file->handle.curl = curl_easy_init();
curl_easy_setopt(file->handle.curl, CURLOPT_URL, url);
curl_easy_setopt(file->handle.curl, CURLOPT_FILE, file);
curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, FALSE);
curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback);
if(!multi_handle)
multi_handle = curl_multi_init();
curl_multi_add_handle(multi_handle, file->handle.curl);
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running));
/* if still_running would be 0 now, we should return NULL */
return file;
}
void url_fclose(URL_FILE *file)
{
/* make sure the easy handle is not in the multi handle anymore */
curl_multi_remove_handle(multi_handle, file->handle.curl);
/* cleanup */
curl_easy_cleanup(file->handle.curl);
}
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
{
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd;
struct timeval timeout;
int rc;
int still_running = 0;
if(!file->bytes) { /* no data available at this point */
file->readptr = file->buffer; /* reset read pointer */
if(CURLM_CALL_MULTI_PERFORM == file->m) {
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running)) {
if(file->bytes) {
printf("(fread) WOAH! THis happened!\n");
break;
}
}
if(!still_running) {
printf("NO MORE RUNNING AROUND!\n");
return 0;
}
}
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
/* set a suitable timeout to fail on */
timeout.tv_sec = 500; /* 5 minutes */
timeout.tv_usec = 0;
/* get file descriptors from the transfers */
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
switch(rc) {
case -1:
/* select error */
break;
case 0:
break;
default:
/* timeout or readable/writable sockets */
do {
file->m = curl_multi_perform(multi_handle, &still_running);
if(file->bytes)
/* we have received data, return that now */
break;
} while(CURLM_CALL_MULTI_PERFORM == file->m);
if(!still_running)
printf("NO MORE RUNNING AROUND!\n");
break;
}
}
else
printf("(fread) Skip network read\n");
if(file->bytes) {
/* data already available, return that */
int want = size * nmemb;
if(file->bytes < want)
want = file->bytes;
memcpy(ptr, file->readptr, want);
file->readptr += want;
file->bytes -= want;
printf("(fread) return %d bytes\n", want);
return want;
}
return 0; /* no data available to return */
}
int main(int argc, char *argv[])
{
URL_FILE *handle;
int nread;
char buffer[256];
handle = url_fopen("http://www.haxx.se", "r");
if(!handle) {
printf("couldn't url_fopen()\n");
}
do {
nread = url_fread(buffer, sizeof(buffer), 1, handle);
printf("We got: %d bytes\n", nread);
} while(nread);
url_fclose(handle);
return 0;
}

View File

@@ -1,49 +0,0 @@
/*
* Note: This is only required if you use curl 7.8 or lower, later
* versions provide an option to curl_global_init() that does the
* win32 initialization for you.
*/
/*
* These are example functions doing socket init that Windows
* require. If you don't use windows, you can safely ignore this crap.
*/
#include <windows.h>
void win32_cleanup(void)
{
WSACleanup();
}
int win32_init(void)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
/* Tell the user that we couldn't find a useable */
/* winsock.dll. */
return 1;
/* Confirm that the Windows Sockets DLL supports 1.1.*/
/* Note that if the DLL supports versions greater */
/* than 1.1 in addition to 1.1, it will still return */
/* 1.1 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we couldn't find a useable */
/* winsock.dll. */
WSACleanup();
return 1;
}
return 0; /* 0 is ok */
}

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file] .\" nroff -man [file]
.\" $Id$ .\" $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 .SH NAME
curl_easy_setopt - Set curl easy-session options curl_easy_setopt - Set curl easy-session options
.SH SYNOPSIS .SH SYNOPSIS
@@ -171,16 +171,49 @@ will imply this option.
A non-zero parameter tells the library to just list the names of an ftp A non-zero parameter tells the library to just list the names of an ftp
directory, instead of doing a full directory listing that would include file directory, instead of doing a full directory listing that would include file
sizes, dates etc. sizes, dates etc.
This causes an FTP NLST command to be sent. Beware that some FTP servers
list only files in their response to NLST; they do not include
subdirectories and symbolic links.
.TP .TP
.B CURLOPT_FTPAPPEND .B CURLOPT_FTPAPPEND
A non-zero parameter tells the library to append to the remote file instead of 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. overwrite it. This is only useful when uploading to a ftp site.
.TP .TP
.B CURLOPT_NETRC .B CURLOPT_NETRC
A non-zero parameter tells the library to scan your \fI~/.netrc\fP file to This parameter controls the preference of libcurl between using user names and
find user name and password for the remote site you are about to access. Only passwords from your \fI~/.netrc\fP file, relative to user names and passwords
machine name, user name and password is taken into account (init macros and in the URL supplied with \fICURLOPT_URL\fP.
similar things aren't supported).
\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 \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 set (as the standard Unix ftp client does). It should only be readable by
@@ -481,12 +514,20 @@ argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP.
.B CURLOPT_SSL_VERIFYPEER .B CURLOPT_SSL_VERIFYPEER
Pass a long that is set to a non-zero value to make curl verify the peer's 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 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 .TP
.B CURLOPT_CAINFO .B CURLOPT_CAINFO
Pass a char * to a zero terminated file naming holding the certificate to Pass a char * to a zero terminated string naming a file holding one or more
verify the peer with. This only makes sense when used in combination with the certificates to verify the peer with. This only makes sense when used in
CURLOPT_SSL_VERIFYPEER option. (Added in 7.4.2) 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 .TP
.B CURLOPT_PASSWDFUNCTION .B CURLOPT_PASSWDFUNCTION
Pass a pointer to a \fIcurl_passwd_callback\fP function that will be called Pass a pointer to a \fIcurl_passwd_callback\fP function that will be called

View File

@@ -2,13 +2,13 @@
.\" nroff -man [file] .\" nroff -man [file]
.\" $Id$ .\" $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 .SH NAME
curl_formadd - add a section to a multipart/formdata HTTP POST curl_formadd - add a section to a multipart/formdata HTTP POST
.SH SYNOPSIS .SH SYNOPSIS
.B #include <curl/curl.h> .B #include <curl/curl.h>
.sp .sp
.BI "int curl_formadd(struct HttpPost ** " firstitem, .BI "CURLFORMcode curl_formadd(struct HttpPost ** " firstitem,
.BI "struct HttpPost ** " lastitem, " ...);" .BI "struct HttpPost ** " lastitem, " ...);"
.ad .ad
.SH DESCRIPTION .SH DESCRIPTION
@@ -83,7 +83,9 @@ you call \fIcurl_form_free\fP and \fIcurl_easy_cleanup\fP.
See example below. See example below.
.SH RETURN VALUE .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 .SH EXAMPLE
.nf .nf

View File

@@ -65,6 +65,11 @@ struct curl_httppost {
long namelength; /* length of name length */ long namelength; /* length of name length */
char *contents; /* pointer to allocated data contents */ char *contents; /* pointer to allocated data contents */
long contentslength; /* length of contents field */ 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 */ char *contenttype; /* Content-Type */
struct curl_slist* contentheader; /* list of extra headers for this form */ 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 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 */ do not free in formfree */
#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer #define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
do not free in formfree */ 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 char *showfilename; /* The file name to show. If not set, the actual
file name will be used (if this is a file part) */ 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(FTPLISTONLY, LONG, 48), /* Use NLST when listing ftp dir */
CINIT(FTPAPPEND, LONG, 50), /* Append instead of overwrite on upload! */ 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! */ CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */
/* This FTPASCII name is now obsolete, to be removed, use the TRANSFERTEXT /* This FTPASCII name is now obsolete, to be removed, use the TRANSFERTEXT
@@ -540,6 +554,10 @@ typedef enum {
/* mark this as start of a cookie session */ /* mark this as start of a cookie session */
CINIT(COOKIESESSION, LONG, 96), 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 */ CURLOPT_LASTENTRY /* the last unusued */
} CURLoption; } CURLoption;
@@ -560,6 +578,18 @@ enum {
CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ 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 { enum {
CURL_SSLVERSION_DEFAULT, CURL_SSLVERSION_DEFAULT,
CURL_SSLVERSION_TLSv1, CURL_SSLVERSION_TLSv1,
@@ -638,6 +668,11 @@ typedef enum {
CFINIT(ARRAY), CFINIT(ARRAY),
CFINIT(OBSOLETE), CFINIT(OBSOLETE),
CFINIT(FILE), CFINIT(FILE),
CFINIT(BUFFER),
CFINIT(BUFFERPTR),
CFINIT(BUFFERLENGTH),
CFINIT(CONTENTTYPE), CFINIT(CONTENTTYPE),
CFINIT(CONTENTHEADER), CFINIT(CONTENTHEADER),
CFINIT(FILENAME), CFINIT(FILENAME),
@@ -656,7 +691,35 @@ struct curl_forms {
}; };
/* use this for multipart formpost building */ /* 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, struct curl_httppost **last_post,
...); ...);
@@ -684,8 +747,8 @@ CURLcode curl_global_init(long flags);
void curl_global_cleanup(void); void curl_global_cleanup(void);
/* This is the version number */ /* This is the version number */
#define LIBCURL_VERSION "7.9.7-pre2" #define LIBCURL_VERSION "7.9.8"
#define LIBCURL_VERSION_NUM 0x070907 #define LIBCURL_VERSION_NUM 0x070908
/* linked-list structure for the CURLOPT_QUOTE option (and other) */ /* linked-list structure for the CURLOPT_QUOTE option (and other) */
struct curl_slist { struct curl_slist {

View File

@@ -61,7 +61,7 @@ libcurl.a: $(libcurl_a_OBJECTS) $(libcurl_a_DEPENDENCIES)
libcurl.dll libcurldll.a: libcurl.a libcurl.def dllinit.o libcurl.dll libcurldll.a: libcurl.a libcurl.def dllinit.o
-@erase $@ -@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) $@ $(STRIP) $@
# remove the last line above to keep debug info # remove the last line above to keep debug info

View File

@@ -198,7 +198,8 @@ X_OBJS= \
$(DIROBJ)\strtok.obj \ $(DIROBJ)\strtok.obj \
$(DIROBJ)\connect.obj \ $(DIROBJ)\connect.obj \
$(DIROBJ)\hash.obj \ $(DIROBJ)\hash.obj \
$(DIROBJ)\llist.obj $(DIROBJ)\llist.obj \
$(DIROBJ)\multi.obj
all : $(TARGET) all : $(TARGET)

View File

@@ -22,7 +22,7 @@
* *
* $Id$ * $Id$
*****************************************************************************/ *****************************************************************************/
#ifndef CURL_DISABLE_TELNET
/* /*
* Telnet option defines. Add more here if in need. * 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) && \ #define TELCMD_OK(x) ( ((unsigned int)(x) >= TELCMD_MINIMUM) && \
((unsigned int)(x) <= TELCMD_MAXIMUM) ) ((unsigned int)(x) <= TELCMD_MAXIMUM) )
#define TELCMD(x) telnetcmds[(x)-TELCMD_MINIMUM] #define TELCMD(x) telnetcmds[(x)-TELCMD_MINIMUM]
#endif
#endif #endif

View File

@@ -366,3 +366,6 @@
#define HAVE_MEMORY_H 1 #define HAVE_MEMORY_H 1
#define HAVE_FIONBIO 1 #define HAVE_FIONBIO 1
/* Define if you have the `sigsetjmp' function. */
#define HAVE_SIGSETJMP 1

View File

@@ -179,6 +179,9 @@
/* Define if you have the RAND_screen function when using SSL */ /* Define if you have the RAND_screen function when using SSL */
#define HAVE_RAND_SCREEN 1 #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 this to if in_addr_t is not an available typedefed type */
#define in_addr_t unsigned long #define in_addr_t unsigned long

View File

@@ -457,6 +457,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
/* we are connected, awesome! */ /* we are connected, awesome! */
break; break;
} }
failf(data, "socket error: %d", err);
/* we are _not_ connected, it was a false alert, continue please */ /* 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 */ /* no good connect was made */
sclose(sockfd); sclose(sockfd);
*sockconn = -1; *sockconn = -1;
failf(data, "Connect failed");
return CURLE_COULDNT_CONNECT; return CURLE_COULDNT_CONNECT;
} }

View File

@@ -79,6 +79,8 @@ Example set of cookies:
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_HTTP
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
@@ -761,6 +763,8 @@ int main(int argc, char **argv)
#endif #endif
#endif /* CURL_DISABLE_HTTP */
/* /*
* local variables: * local variables:
* eval: (load-file "../curl-mode.el") * eval: (load-file "../curl-mode.el")

View File

@@ -1,394 +1,394 @@
# Microsoft Developer Studio Project File - Name="curllib" - Package Owner=<4> # Microsoft Developer Studio Project File - Name="curllib" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00 # Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT ** # ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=curllib - Win32 Debug CFG=curllib - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run !MESSAGE use the Export Makefile command and run
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "curllib.mak". !MESSAGE NMAKE /f "curllib.mak".
!MESSAGE !MESSAGE
!MESSAGE You can specify a configuration when running NMAKE !MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "curllib.mak" CFG="curllib - Win32 Debug" !MESSAGE NMAKE /f "curllib.mak" CFG="curllib - Win32 Debug"
!MESSAGE !MESSAGE
!MESSAGE Possible choices for configuration are: !MESSAGE Possible choices for configuration are:
!MESSAGE !MESSAGE
!MESSAGE "curllib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "curllib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "curllib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "curllib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE !MESSAGE
# Begin Project # Begin Project
# PROP AllowPerConfigDependencies 0 # PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName "" # PROP Scc_ProjName ""
# PROP Scc_LocalPath "" # PROP Scc_LocalPath ""
CPP=cl.exe CPP=cl.exe
MTL=midl.exe MTL=midl.exe
RSC=rc.exe RSC=rc.exe
!IF "$(CFG)" == "curllib - Win32 Release" !IF "$(CFG)" == "curllib - Win32 Release"
# PROP BASE Use_MFC 0 # PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0 # PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release" # PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release" # PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir "" # PROP BASE Target_Dir ""
# PROP Use_MFC 0 # PROP Use_MFC 0
# PROP Use_Debug_Libraries 0 # PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release" # PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release" # PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /FR /FD /c # ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /FR /FD /c
# SUBTRACT CPP /YX # SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
# ADD BASE BSC32 /nologo # ADD BASE BSC32 /nologo
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe 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 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" !ELSEIF "$(CFG)" == "curllib - Win32 Debug"
# PROP BASE Use_MFC 0 # PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1 # PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug" # PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug" # PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir "" # PROP BASE Target_Dir ""
# PROP Use_MFC 0 # PROP Use_MFC 0
# PROP Use_Debug_Libraries 1 # PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug" # PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug" # PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /FR /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /FR /FD /GZ /c
# SUBTRACT CPP /WX /YX # SUBTRACT CPP /WX /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
# ADD BASE BSC32 /nologo # ADD BASE BSC32 /nologo
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe 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 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 # SUBTRACT LINK32 /nodefaultlib
!ENDIF !ENDIF
# Begin Target # Begin Target
# Name "curllib - Win32 Release" # Name "curllib - Win32 Release"
# Name "curllib - Win32 Debug" # Name "curllib - Win32 Debug"
# Begin Group "Source Files" # Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File # Begin Source File
SOURCE=.\base64.c SOURCE=.\base64.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\connect.c SOURCE=.\connect.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\cookie.c SOURCE=.\cookie.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\dict.c SOURCE=.\dict.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\dllinit.c SOURCE=.\dllinit.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\easy.c SOURCE=.\easy.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\escape.c SOURCE=.\escape.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\file.c SOURCE=.\file.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\formdata.c SOURCE=.\formdata.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\ftp.c SOURCE=.\ftp.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\getdate.c SOURCE=.\getdate.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\getenv.c SOURCE=.\getenv.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\getinfo.c SOURCE=.\getinfo.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\getpass.c SOURCE=.\getpass.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\hash.c SOURCE=.\hash.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\hostip.c SOURCE=.\hostip.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\http.c SOURCE=.\http.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\http_chunks.c SOURCE=.\http_chunks.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\if2ip.c SOURCE=.\if2ip.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\krb4.c SOURCE=.\krb4.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\ldap.c SOURCE=.\ldap.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\libcurl.def SOURCE=.\libcurl.def
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\llist.c SOURCE=.\llist.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\memdebug.c SOURCE=.\memdebug.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\mprintf.c SOURCE=.\mprintf.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\netrc.c SOURCE=.\netrc.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\progress.c SOURCE=.\progress.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\security.c SOURCE=.\security.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\sendf.c SOURCE=.\sendf.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\speedcheck.c SOURCE=.\speedcheck.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\ssluse.c SOURCE=.\ssluse.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\strequal.c SOURCE=.\strequal.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\strtok.c SOURCE=.\strtok.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\telnet.c SOURCE=.\telnet.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\timeval.c SOURCE=.\timeval.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\transfer.c SOURCE=.\transfer.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\url.c SOURCE=.\url.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\version.c SOURCE=.\version.c
# End Source File # End Source File
# End Group # End Group
# Begin Group "Header Files" # Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl" # PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File # Begin Source File
SOURCE=.\arpa_telnet.h SOURCE=.\arpa_telnet.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\base64.h SOURCE=.\base64.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\connect.h SOURCE=.\connect.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\cookie.h SOURCE=.\cookie.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\dict.h SOURCE=.\dict.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\escape.h SOURCE=.\escape.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\file.h SOURCE=.\file.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\formdata.h SOURCE=.\formdata.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\ftp.h SOURCE=.\ftp.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\getdate.h SOURCE=.\getdate.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\getenv.h SOURCE=.\getenv.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\getpass.h SOURCE=.\getpass.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\hostip.h SOURCE=.\hostip.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\http.h SOURCE=.\http.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\http_chunks.h SOURCE=.\http_chunks.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\if2ip.h SOURCE=.\if2ip.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\inet_ntoa_r.h SOURCE=.\inet_ntoa_r.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\krb4.h SOURCE=.\krb4.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\ldap.h SOURCE=.\ldap.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\memdebug.h SOURCE=.\memdebug.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\netrc.h SOURCE=.\netrc.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\progress.h SOURCE=.\progress.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\security.h SOURCE=.\security.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\sendf.h SOURCE=.\sendf.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\setup.h SOURCE=.\setup.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\speedcheck.h SOURCE=.\speedcheck.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\ssluse.h SOURCE=.\ssluse.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\strequal.h SOURCE=.\strequal.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\strtok.h SOURCE=.\strtok.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\telnet.h SOURCE=.\telnet.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\timeval.h SOURCE=.\timeval.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\transfer.h SOURCE=.\transfer.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\url.h SOURCE=.\url.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\urldata.h SOURCE=.\urldata.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "Resource Files" # Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group # End Group
# End Target # End Target
# End Project # End Project

View File

@@ -1,29 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00 Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
############################################################################### ###############################################################################
Project: "curllib"=".\curllib.dsp" - Package Owner=<4> Project: "curllib"=".\curllib.dsp" - Package Owner=<4>
Package=<5> Package=<5>
{{{ {{{
}}} }}}
Package=<4> Package=<4>
{{{ {{{
}}} }}}
############################################################################### ###############################################################################
Global: Global:
Package=<5> Package=<5>
{{{ {{{
}}} }}}
Package=<3> Package=<3>
{{{ {{{
}}} }}}
############################################################################### ###############################################################################

View File

@@ -23,7 +23,8 @@
* *
* $Id$ * $Id$
*****************************************************************************/ *****************************************************************************/
#ifndef CURL_DISABLE_DICT
CURLcode Curl_dict(struct connectdata *conn); CURLcode Curl_dict(struct connectdata *conn);
CURLcode Curl_dict_done(struct connectdata *conn); CURLcode Curl_dict_done(struct connectdata *conn);
#endif
#endif #endif

View File

@@ -23,6 +23,7 @@
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_FILE
/* -- WIN32 approved -- */ /* -- WIN32 approved -- */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -204,3 +205,4 @@ CURLcode Curl_file(struct connectdata *conn)
* vim600: fdm=marker * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */
#endif

View File

@@ -23,6 +23,8 @@
* *
* $Id$ * $Id$
*****************************************************************************/ *****************************************************************************/
#ifndef CURL_DISABLE_FILE
CURLcode Curl_file(struct connectdata *conn); CURLcode Curl_file(struct connectdata *conn);
CURLcode Curl_file_connect(struct connectdata *conn); CURLcode Curl_file_connect(struct connectdata *conn);
#endif #endif
#endif

View File

@@ -109,6 +109,8 @@ Content-Disposition: form-data; name="FILECONTENT"
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_HTTP
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -398,6 +400,10 @@ int curl_formparse(char *input,
static struct curl_httppost * static struct curl_httppost *
AddHttpPost(char * name, long namelength, AddHttpPost(char * name, long namelength,
char * value, long contentslength, char * value, long contentslength,
/* CMC: Added support for buffer uploads */
char * buffer, long bufferlength,
char *contenttype, char *contenttype,
long flags, long flags,
struct curl_slist* contentHeader, struct curl_slist* contentHeader,
@@ -414,6 +420,11 @@ AddHttpPost(char * name, long namelength,
post->namelength = name?(namelength?namelength:(long)strlen(name)):0; post->namelength = name?(namelength?namelength:(long)strlen(name)):0;
post->contents = value; post->contents = value;
post->contentslength = contentslength; post->contentslength = contentslength;
/* CMC: Added support for buffer uploads */
post->buffer = buffer;
post->bufferlength = bufferlength;
post->contenttype = contenttype; post->contenttype = contenttype;
post->contentheader = contentHeader; post->contentheader = contentHeader;
post->showfilename = showfilename; post->showfilename = showfilename;
@@ -602,39 +613,26 @@ static int AllocAndCopy (char **buffer, int buffer_length)
* CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
* *
* Returns: * Returns:
* FORMADD_OK on success * CURL_FORMADD_OK on success
* FORMADD_MEMORY if the FormInfo allocation fails * CURL_FORMADD_MEMORY if the FormInfo allocation fails
* FORMADD_OPTION_TWICE if one option is given twice for one Form * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
* FORMADD_NULL if a null pointer was given for a char * CURL_FORMADD_NULL if a null pointer was given for a char
* FORMADD_MEMORY if the allocation of a FormInfo struct failed * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
* FORMADD_UNKNOWN_OPTION if an unknown option was used * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
* FORMADD_INCOMPLETE if the some FormInfo is not complete (or an error) * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or an error)
* FORMADD_MEMORY if a HttpPost struct cannot be allocated * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated
* FORMADD_MEMORY if some allocation for string copying failed. * CURL_FORMADD_MEMORY if some allocation for string copying failed.
* FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array * 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 static
FORMcode FormAdd(struct curl_httppost **httppost, CURLFORMcode FormAdd(struct curl_httppost **httppost,
struct curl_httppost **last_post, struct curl_httppost **last_post,
va_list params) va_list params)
{ {
FormInfo *first_form, *current_form, *form; FormInfo *first_form, *current_form, *form;
FORMcode return_value = FORMADD_OK; CURLFORMcode return_value = CURL_FORMADD_OK;
const char *prevtype = NULL; const char *prevtype = NULL;
struct curl_httppost *post = NULL; struct curl_httppost *post = NULL;
CURLformoption option; CURLformoption option;
@@ -655,7 +653,7 @@ FORMcode FormAdd(struct curl_httppost **httppost,
current_form = first_form; current_form = first_form;
} }
else else
return FORMADD_MEMORY; return CURL_FORMADD_MEMORY;
/* /*
* Loop through all the options set. * Loop through all the options set.
@@ -663,7 +661,7 @@ FORMcode FormAdd(struct curl_httppost **httppost,
while (1) { while (1) {
/* break if we have an error to report */ /* break if we have an error to report */
if (return_value != FORMADD_OK) if (return_value != CURL_FORMADD_OK)
break; break;
/* first see if we have more parts of the array param */ /* first see if we have more parts of the array param */
@@ -690,13 +688,13 @@ FORMcode FormAdd(struct curl_httppost **httppost,
case CURLFORM_ARRAY: case CURLFORM_ARRAY:
if(array_state) if(array_state)
/* we don't support an array from within an array */ /* we don't support an array from within an array */
return_value = FORMADD_ILLEGAL_ARRAY; return_value = CURL_FORMADD_ILLEGAL_ARRAY;
else { else {
forms = va_arg(params, struct curl_forms *); forms = va_arg(params, struct curl_forms *);
if (forms) if (forms)
array_state = TRUE; array_state = TRUE;
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
break; break;
@@ -707,19 +705,19 @@ FORMcode FormAdd(struct curl_httppost **httppost,
current_form->flags |= HTTPPOST_PTRNAME; /* fall through */ current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
case CURLFORM_COPYNAME: case CURLFORM_COPYNAME:
if (current_form->name) if (current_form->name)
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else { else {
char *name = array_state? char *name = array_state?
array_value:va_arg(params, char *); array_value:va_arg(params, char *);
if (name) if (name)
current_form->name = name; /* store for the moment */ current_form->name = name; /* store for the moment */
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
break; break;
case CURLFORM_NAMELENGTH: case CURLFORM_NAMELENGTH:
if (current_form->namelength) if (current_form->namelength)
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else else
current_form->namelength = current_form->namelength =
array_state?(long)array_value:va_arg(params, long); 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 */ current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
case CURLFORM_COPYCONTENTS: case CURLFORM_COPYCONTENTS:
if (current_form->value) if (current_form->value)
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else { else {
char *value = char *value =
array_state?array_value:va_arg(params, char *); array_state?array_value:va_arg(params, char *);
if (value) if (value)
current_form->value = value; /* store for the moment */ current_form->value = value; /* store for the moment */
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
break; break;
case CURLFORM_CONTENTSLENGTH: case CURLFORM_CONTENTSLENGTH:
if (current_form->contentslength) if (current_form->contentslength)
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else else
current_form->contentslength = current_form->contentslength =
array_state?(long)array_value:va_arg(params, long); 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 */ /* Get contents from a given file name */
case CURLFORM_FILECONTENT: case CURLFORM_FILECONTENT:
if (current_form->flags != 0) if (current_form->flags != 0)
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else { else {
char *filename = array_state? char *filename = array_state?
array_value:va_arg(params, char *); array_value:va_arg(params, char *);
@@ -762,7 +760,7 @@ FORMcode FormAdd(struct curl_httppost **httppost,
current_form->flags |= HTTPPOST_READFILE; current_form->flags |= HTTPPOST_READFILE;
} }
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
break; break;
@@ -777,26 +775,80 @@ FORMcode FormAdd(struct curl_httppost **httppost,
if (filename) { if (filename) {
if (!(current_form = AddFormInfo(strdup(filename), if (!(current_form = AddFormInfo(strdup(filename),
NULL, current_form))) NULL, current_form)))
return_value = FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
} }
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
else else
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
} }
else { else {
if (filename) if (filename)
current_form->value = strdup(filename); current_form->value = strdup(filename);
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
current_form->flags |= HTTPPOST_FILENAME; current_form->flags |= HTTPPOST_FILENAME;
} }
break; 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: case CURLFORM_CONTENTTYPE:
{ {
char *contenttype = char *contenttype =
array_state?array_value:va_arg(params, char *); array_state?array_value:va_arg(params, char *);
if (current_form->contenttype) { if (current_form->contenttype) {
if (current_form->flags & HTTPPOST_FILENAME) { if (current_form->flags & HTTPPOST_FILENAME) {
@@ -804,19 +856,19 @@ FORMcode FormAdd(struct curl_httppost **httppost,
if (!(current_form = AddFormInfo(NULL, if (!(current_form = AddFormInfo(NULL,
strdup(contenttype), strdup(contenttype),
current_form))) current_form)))
return_value = FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
} }
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
else else
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
} }
else { else {
if (contenttype) if (contenttype)
current_form->contenttype = strdup(contenttype); current_form->contenttype = strdup(contenttype);
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
break; break;
} }
@@ -829,7 +881,7 @@ FORMcode FormAdd(struct curl_httppost **httppost,
va_arg(params, struct curl_slist*); va_arg(params, struct curl_slist*);
if( current_form->contentheader ) if( current_form->contentheader )
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else else
current_form->contentheader = list; current_form->contentheader = list;
@@ -840,17 +892,17 @@ FORMcode FormAdd(struct curl_httppost **httppost,
char *filename = array_state?array_value: char *filename = array_state?array_value:
va_arg(params, char *); va_arg(params, char *);
if( current_form->showfilename ) if( current_form->showfilename )
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else else
current_form->showfilename = strdup(filename); current_form->showfilename = strdup(filename);
break; break;
} }
default: 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 /* go through the list, check for copleteness and if everything is
* alright add the HttpPost item otherwise set return_value accordingly */ * 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_FILENAME) && ( (form->flags & HTTPPOST_FILENAME) &&
(form->flags & HTTPPOST_PTRCONTENTS) ) || (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_READFILE) &&
(form->flags & HTTPPOST_PTRCONTENTS) ) (form->flags & HTTPPOST_PTRCONTENTS) )
) { ) {
return_value = FORMADD_INCOMPLETE; return_value = CURL_FORMADD_INCOMPLETE;
break; break;
} }
else { else {
if ( (form->flags & HTTPPOST_FILENAME) && if ( ((form->flags & HTTPPOST_FILENAME) ||
(form->flags & HTTPPOST_BUFFER)) &&
!form->contenttype ) { !form->contenttype ) {
/* our contenttype is missing */ /* our contenttype is missing */
form->contenttype form->contenttype
@@ -880,28 +939,36 @@ FORMcode FormAdd(struct curl_httppost **httppost,
(form == first_form) ) { (form == first_form) ) {
/* copy name (without strdup; possibly contains null characters) */ /* copy name (without strdup; possibly contains null characters) */
if (AllocAndCopy(&form->name, form->namelength)) { if (AllocAndCopy(&form->name, form->namelength)) {
return_value = FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
break; break;
} }
} }
if ( !(form->flags & HTTPPOST_FILENAME) && if ( !(form->flags & HTTPPOST_FILENAME) &&
!(form->flags & HTTPPOST_READFILE) && !(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) */ /* copy value (without strdup; possibly contains null characters) */
if (AllocAndCopy(&form->value, form->contentslength)) { if (AllocAndCopy(&form->value, form->contentslength)) {
return_value = FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
break; break;
} }
} }
post = AddHttpPost(form->name, form->namelength, post = AddHttpPost(form->name, form->namelength,
form->value, form->contentslength, form->value, form->contentslength,
/* CMC: Added support for buffer uploads */
form->buffer, form->bufferlength,
form->contenttype, form->flags, form->contenttype, form->flags,
form->contentheader, form->showfilename, form->contentheader, form->showfilename,
post, httppost, post, httppost,
last_post); last_post);
if(!post) if(!post)
return_value = FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
if (form->contenttype) if (form->contenttype)
prevtype = form->contenttype; prevtype = form->contenttype;
@@ -922,12 +989,12 @@ FORMcode FormAdd(struct curl_httppost **httppost,
return return_value; return return_value;
} }
int curl_formadd(struct curl_httppost **httppost, CURLFORMcode curl_formadd(struct curl_httppost **httppost,
struct curl_httppost **last_post, struct curl_httppost **last_post,
...) ...)
{ {
va_list arg; va_list arg;
int result; CURLFORMcode result;
va_start(arg, last_post); va_start(arg, last_post);
result = FormAdd(httppost, last_post, arg); result = FormAdd(httppost, last_post, arg);
va_end(arg); va_end(arg);
@@ -1096,9 +1163,9 @@ CURLcode Curl_getFormData(struct FormData **finalform,
fileboundary = Curl_FormBoundary(); fileboundary = Curl_FormBoundary();
size += AddFormDataf(&form, size += AddFormDataf(&form,
"\r\nContent-Type: multipart/mixed," "\r\nContent-Type: multipart/mixed,"
" boundary=%s\r\n", " boundary=%s\r\n",
fileboundary); fileboundary);
} }
file = post; file = post;
@@ -1110,26 +1177,30 @@ CURLcode Curl_getFormData(struct FormData **finalform,
local file name should be added. */ local file name should be added. */
if(post->more) { if(post->more) {
/* if multiple-file */ /* if multiple-file */
size += AddFormDataf(&form, size += AddFormDataf(&form,
"\r\n--%s\r\nContent-Disposition: " "\r\n--%s\r\nContent-Disposition: "
"attachment; filename=\"%s\"", "attachment; filename=\"%s\"",
fileboundary, fileboundary,
(file->showfilename?file->showfilename: (file->showfilename?file->showfilename:
file->contents)); file->contents));
} }
else if(post->flags & HTTPPOST_FILENAME) { else if((post->flags & HTTPPOST_FILENAME) ||
size += AddFormDataf(&form,
"; filename=\"%s\"", /* CMC: Added support for buffer uploads */
(post->showfilename?post->showfilename: (post->flags & HTTPPOST_BUFFER)) {
size += AddFormDataf(&form,
"; filename=\"%s\"",
(post->showfilename?post->showfilename:
post->contents)); post->contents));
} }
if(file->contenttype) { if(file->contenttype) {
/* we have a specified type */ /* we have a specified type */
size += AddFormDataf(&form, size += AddFormDataf(&form,
"\r\nContent-Type: %s", "\r\nContent-Type: %s",
file->contenttype); file->contenttype);
} }
curList = file->contentheader; curList = file->contentheader;
@@ -1147,47 +1218,53 @@ CURLcode Curl_getFormData(struct FormData **finalform,
*/ */
if(file->contenttype && if(file->contenttype &&
!strnequal("text/", file->contenttype, 5)) { !strnequal("text/", file->contenttype, 5)) {
/* this is not a text content, mention our binary encoding */ /* this is not a text content, mention our binary encoding */
size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0); size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0);
} }
#endif #endif
size += AddFormData(&form, "\r\n\r\n", 0); size += AddFormData(&form, "\r\n\r\n", 0);
if((post->flags & HTTPPOST_FILENAME) || if((post->flags & HTTPPOST_FILENAME) ||
(post->flags & HTTPPOST_READFILE)) { (post->flags & HTTPPOST_READFILE)) {
/* we should include the contents from the specified file */ /* we should include the contents from the specified file */
FILE *fileread; FILE *fileread;
char buffer[1024]; char buffer[1024];
int nread; int nread;
fileread = strequal("-", file->contents)?stdin: fileread = strequal("-", file->contents)?stdin:
/* binary read for win32 crap */ /* binary read for win32 crap */
/*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */ /*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?? 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?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
if(fileread) { if(fileread) {
while((nread = fread(buffer, 1, 1024, fileread))) while((nread = fread(buffer, 1, 1024, fileread)))
size += AddFormData(&form, buffer, nread); size += AddFormData(&form, buffer, nread);
if(fileread != stdin) if(fileread != stdin)
fclose(fileread); fclose(fileread);
} }
else { else {
#if 0 #if 0
/* File wasn't found, add a nothing field! */ /* File wasn't found, add a nothing field! */
size += AddFormData(&form, "", 0); size += AddFormData(&form, "", 0);
#endif #endif
Curl_formclean(firstform); Curl_formclean(firstform);
free(boundary); free(boundary);
*finalform = NULL; *finalform = NULL;
return CURLE_READ_ERROR; 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 { else {
/* include the contents we got */ /* include the contents we got */
size += AddFormData(&form, post->contents, post->contentslength); size += AddFormData(&form, post->contents, post->contentslength);
} }
} while((file = file->more)); /* for each specified file for this field */ } while((file = file->more)); /* for each specified file for this field */
@@ -1195,8 +1272,8 @@ CURLcode Curl_getFormData(struct FormData **finalform,
/* this was a multiple-file inclusion, make a termination file /* this was a multiple-file inclusion, make a termination file
boundary: */ boundary: */
size += AddFormDataf(&form, size += AddFormDataf(&form,
"\r\n--%s--", "\r\n--%s--",
fileboundary); fileboundary);
free(fileboundary); free(fileboundary);
} }
@@ -1204,8 +1281,8 @@ CURLcode Curl_getFormData(struct FormData **finalform,
/* end-boundary for everything */ /* end-boundary for everything */
size += AddFormDataf(&form, size += AddFormDataf(&form,
"\r\n--%s--\r\n", "\r\n--%s--\r\n",
boundary); boundary);
*sizep = size; *sizep = size;
@@ -1518,6 +1595,8 @@ int main(int argc, char **argv)
#endif #endif
#endif /* CURL_DISABLE_HTTP */
/* /*
* local variables: * local variables:
* eval: (load-file "../curl-mode.el") * eval: (load-file "../curl-mode.el")

View File

@@ -45,6 +45,10 @@ typedef struct FormInfo {
char *contenttype; char *contenttype;
long flags; 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 char *showfilename; /* The file name to show. If not set, the actual
file name will be used */ file name will be used */
struct curl_slist* contentheader; struct curl_slist* contentheader;

View File

@@ -23,6 +23,8 @@
#include "setup.h" #include "setup.h"
/* MN 06/07/02 */
#ifndef CURL_DISABLE_FTP
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.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); failf(data, "Received only partial file: %d bytes", *ftp->bytecountp);
return CURLE_PARTIAL_FILE; return CURLE_PARTIAL_FILE;
} }
else if(!conn->bits.resume_done && else if(!ftp->dont_check &&
!data->set.no_body && !*ftp->bytecountp &&
(0 == *ftp->bytecountp)) { (conn->size>0)) {
/* We consider this an error, but there's no true FTP error received /* 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. 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 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); sclose(conn->secondarysocket);
conn->secondarysocket = -1; conn->secondarysocket = -1;
if(!data->set.no_body && !conn->bits.resume_done) { if(!data->set.no_body && !ftp->dont_check) {
/* now let's see what the server says about the transfer we /* now let's see what the server says about the transfer we just
just performed: */ performed: */
nread = Curl_GetFTPResponse(buf, conn, &ftpcode); nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
if(nread < 0) if(nread < 0)
return CURLE_OPERATION_TIMEOUTED; return CURLE_OPERATION_TIMEOUTED;
@@ -667,6 +669,11 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
return CURLE_FTP_WRITE_ERROR; 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 */ conn->bits.resume_done = FALSE; /* clean this for next connection */
@@ -1067,13 +1074,13 @@ CURLcode ftp_use_port(struct connectdata *conn)
} }
freeaddrinfo(res); freeaddrinfo(res);
if (portsock < 0) { if (portsock < 0) {
failf(data, strerror(errno)); failf(data, "%s", strerror(errno));
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
} }
sslen = sizeof(ss); sslen = sizeof(ss);
if (getsockname(portsock, sa, &sslen) < 0) { if (getsockname(portsock, sa, &sslen) < 0) {
failf(data, strerror(errno)); failf(data, "%s", strerror(errno));
return CURLE_FTP_PORT_FAILED; 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); for (modeoff = (data->set.ftp_use_epsv?0:1);
mode[modeoff]; modeoff++) { mode[modeoff]; modeoff++) {
result = Curl_ftpsendf(conn, mode[modeoff]); result = Curl_ftpsendf(conn, "%s", mode[modeoff]);
if(result) if(result)
return result; return result;
nread = Curl_GetFTPResponse(buf, conn, &ftpcode); nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
@@ -1597,7 +1604,7 @@ CURLcode ftp_perform(struct connectdata *conn)
if(data->set.no_body) if(data->set.no_body)
/* don't transfer the data */ /* don't transfer the data */
; ftp->dont_check = TRUE;
/* Get us a second connection up and connected */ /* Get us a second connection up and connected */
else if(data->set.ftp_use_port) { else if(data->set.ftp_use_port) {
/* We have chosen to use the PORT command */ /* We have chosen to use the PORT command */
@@ -1693,10 +1700,11 @@ CURLcode ftp_perform(struct connectdata *conn)
/* no data to transfer */ /* no data to transfer */
result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
/* Set resume done so that we won't get any error in /* Set resume done and dont_check so that we won't get any error
* Curl_ftp_done() because we didn't transfer the amount of bytes * in Curl_ftp_done() because we didn't transfer the amount of
* that the local file file obviously is */ * bytes that the local file file obviously is */
conn->bits.resume_done = TRUE; conn->bits.resume_done = TRUE;
ftp->dont_check = TRUE;
return CURLE_OK; 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", infof(data, "range-download from %d to %d, totally %d bytes\n",
from, to, totalsize); 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) { 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 * because we didn't transfer the amount of bytes that the remote
* file obviously is */ * file obviously is */
conn->bits.resume_done = TRUE; conn->bits.resume_done = TRUE;
ftp->dont_check = TRUE;
return CURLE_OK; return CURLE_OK;
} }
@@ -2141,3 +2152,5 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
* vim600: fdm=marker * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */
#endif /* CURL_DISABLE_FTP */

View File

@@ -23,6 +23,10 @@
* *
* $Id$ * $Id$
*****************************************************************************/ *****************************************************************************/
/* MN 06/07/02 */
#ifndef CURL_DISABLE_FTP
CURLcode Curl_ftp(struct connectdata *conn); CURLcode Curl_ftp(struct connectdata *conn);
CURLcode Curl_ftp_done(struct connectdata *conn); CURLcode Curl_ftp_done(struct connectdata *conn);
CURLcode Curl_ftp_connect(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 Curl_GetFTPResponse(char *buf, struct connectdata *conn,
int *ftpcode); int *ftpcode);
/* MN 06/07/02 */
#endif
#endif #endif

View File

@@ -56,6 +56,10 @@
#endif #endif
#endif #endif
#ifdef HAVE_SETJMP_H
#include <setjmp.h>
#endif
#include "urldata.h" #include "urldata.h"
#include "sendf.h" #include "sendf.h"
#include "hostip.h" #include "hostip.h"
@@ -191,6 +195,11 @@ hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
return (__v); \ 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, Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
char *hostname, char *hostname,
int port) int port)
@@ -201,6 +210,14 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
time_t now; time_t now;
char *bufp; 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 /* If the host cache timeout is 0, we don't do DNS cach'ing
so fall through */ so fall through */
if (data->set.dns_cache_timeout == 0) { if (data->set.dns_cache_timeout == 0) {
@@ -344,7 +361,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
snprintf(sbuf, sizeof(sbuf), "%d", port); snprintf(sbuf, sizeof(sbuf), "%d", port);
error = getaddrinfo(hostname, sbuf, &hints, &res); error = getaddrinfo(hostname, sbuf, &hints, &res);
if (error) { if (error) {
infof(data, "getaddrinfo(3) failed for %s\n", hostname); infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
return NULL; return NULL;
} }
*bufp=(char *)res; /* make it point to the result struct */ *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 */ #else /* following code is IPv4-only */
#ifndef HAVE_GETHOSTBYNAME_R #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 * 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! * copy). Make absolutely sure the destination buffer is big enough!
@@ -362,11 +380,12 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
* 10/3/2001 */ * 10/3/2001 */
static struct hostent* pack_hostent(char** buf, struct hostent* orig) static struct hostent* pack_hostent(char** buf, struct hostent* orig)
{ {
char* bufptr; char *bufptr;
char *newbuf;
struct hostent* copy; struct hostent* copy;
int i; int i;
char* str; char *str;
int len; int len;
bufptr = *buf; bufptr = *buf;
@@ -427,7 +446,18 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
} }
copy->h_addr_list[i] = NULL; 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; return copy;
} }
#endif #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) static void hostcache_fixoffset(struct hostent *h, int offset)
{ {
int i=0; int i=0;
h->h_name=(char *)((int)h->h_name+offset); h->h_name=(char *)((long)h->h_name+offset);
h->h_aliases=(char **)((int)h->h_aliases+offset); h->h_aliases=(char **)((long)h->h_aliases+offset);
while(h->h_aliases[i]) { 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++; 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; i=0;
while(h->h_addr_list[i]) { 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++; i++;
} }
} }
@@ -496,7 +526,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
if ( (in=inet_addr(hostname)) != INADDR_NONE ) { if ( (in=inet_addr(hostname)) != INADDR_NONE ) {
struct in_addr *addrentry; struct in_addr *addrentry;
int *buf = (int *)malloc(128); long *buf = (long *)malloc(sizeof(struct hostent)+128);
if(!buf) if(!buf)
return NULL; /* major failure */ return NULL; /* major failure */
*bufp = (char *)buf; *bufp = (char *)buf;
@@ -511,7 +541,8 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
h->h_length = sizeof(*addrentry); h->h_length = sizeof(*addrentry);
h->h_name = *(h->h_addr_list) + h->h_length; h->h_name = *(h->h_addr_list) + h->h_length;
/* bad one h->h_name = (char*)(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) #if defined(HAVE_GETHOSTBYNAME_R)
else { else {
@@ -553,7 +584,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
if(h) { if(h) {
int offset; int offset;
h=(struct hostent *)realloc(buf, step_size); h=(struct hostent *)realloc(buf, step_size);
offset=(int)h-(int)buf; offset=(long)h-(long)buf;
hostcache_fixoffset(h, offset); hostcache_fixoffset(h, offset);
buf=(int *)h; buf=(int *)h;
*bufp=(char *)buf; *bufp=(char *)buf;
@@ -577,7 +608,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
if(!res) { if(!res) {
int offset; int offset;
h=(struct hostent *)realloc(buf, step_size); h=(struct hostent *)realloc(buf, step_size);
offset=(int)h-(int)buf; offset=(long)h-(long)buf;
hostcache_fixoffset(h, offset); hostcache_fixoffset(h, offset);
buf=(int *)h; buf=(int *)h;
*bufp=(char *)buf; *bufp=(char *)buf;

View File

@@ -23,6 +23,7 @@
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_HTTP
/* -- WIN32 approved -- */ /* -- WIN32 approved -- */
#include <stdio.h> #include <stdio.h>
#include <string.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->buffer);
free(in); free(in);
*bytes_written = amount; *bytes_written += amount;
return res; return res;
} }
@@ -924,8 +925,9 @@ CURLcode Curl_http(struct connectdata *conn)
actually set your own */ actually set your own */
add_bufferf(req_buffer, add_bufferf(req_buffer,
"Content-Length: %d\r\n", "Content-Length: %d\r\n",
(data->set.postfieldsize?data->set.postfieldsize: data->set.postfieldsize?
strlen(data->set.postfields)) ); data->set.postfieldsize:
(data->set.postfields?strlen(data->set.postfields):0) );
if(!checkheaders(data, "Content-Type:")) if(!checkheaders(data, "Content-Type:"))
add_bufferf(req_buffer, add_bufferf(req_buffer,
@@ -986,3 +988,4 @@ CURLcode Curl_http(struct connectdata *conn)
* vim600: fdm=marker * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */
#endif

View File

@@ -23,7 +23,7 @@
* *
* $Id$ * $Id$
*****************************************************************************/ *****************************************************************************/
#ifndef CURL_DISABLE_HTTP
/* ftp can use this as well */ /* ftp can use this as well */
CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
int tunnelsocket, int tunnelsocket,
@@ -38,5 +38,5 @@ CURLcode Curl_http_connect(struct connectdata *conn);
void Curl_httpchunk_init(struct connectdata *conn); void Curl_httpchunk_init(struct connectdata *conn);
CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap, CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
ssize_t length, ssize_t *wrote); ssize_t length, ssize_t *wrote);
#endif
#endif #endif

View File

@@ -22,6 +22,7 @@
*****************************************************************************/ *****************************************************************************/
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_HTTP
/* -- WIN32 approved -- */ /* -- WIN32 approved -- */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -228,3 +229,4 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
* vim600: fdm=marker * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */
#endif /* CURL_DISABLE_HTTP */

View File

@@ -40,6 +40,7 @@
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_FTP
#ifdef KRB4 #ifdef KRB4
#include "security.h" #include "security.h"
@@ -391,6 +392,7 @@ void Curl_krb_kauth(struct connectdata *conn)
} }
#endif /* KRB4 */ #endif /* KRB4 */
#endif /* CURL_DISABLE_FTP */
/* /*
* local variables: * local variables:

View File

@@ -23,6 +23,7 @@
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_LDAP
/* -- WIN32 approved -- */ /* -- WIN32 approved -- */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -147,7 +148,7 @@ CURLcode Curl_ldap(struct connectdata *conn)
int ldaptext; int ldaptext;
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
infof(data, "LDAP: %s %s\n", data->change.url); infof(data, "LDAP: %s\n", data->change.url);
DynaOpen(); DynaOpen();
if (libldap == NULL) { if (libldap == NULL) {
@@ -229,3 +230,4 @@ CURLcode Curl_ldap(struct connectdata *conn)
* vim600: fdm=marker * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */
#endif

View File

@@ -23,7 +23,8 @@
* *
* $Id$ * $Id$
*****************************************************************************/ *****************************************************************************/
#ifndef CURL_DISABLE_LDAP
CURLcode Curl_ldap(struct connectdata *conn); CURLcode Curl_ldap(struct connectdata *conn);
CURLcode Curl_ldap_done(struct connectdata *conn); CURLcode Curl_ldap_done(struct connectdata *conn);
#endif
#endif /* __LDAP_H */ #endif /* __LDAP_H */

View File

@@ -49,7 +49,9 @@
struct memdebug { struct memdebug {
int size; 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 :-( */
}; };
/* /*

View File

@@ -1028,7 +1028,6 @@ static int alloc_addbyter(int output, FILE *data)
infop->len++; infop->len++;
return output; /* fputc() returns like this on success */ return output; /* fputc() returns like this on success */
} }
char *curl_maprintf(const char *format, ...) char *curl_maprintf(const char *format, ...)
@@ -1044,12 +1043,17 @@ char *curl_maprintf(const char *format, ...)
va_start(ap_save, format); va_start(ap_save, format);
retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
va_end(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 */ info.buffer[info.len] = 0; /* we terminate this with a zero byte */
return info.buffer; return info.buffer;
} }
else else
return NULL; return strdup("");
} }
char *curl_mvaprintf(const char *format, va_list ap_save) 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; info.alloc = 0;
retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
info.buffer[info.len] = 0; /* we terminate this with a zero byte */ if(-1 == retcode) {
if(info.len) { if(info.alloc)
free(info.buffer);
return NULL;
}
if(info.alloc) {
info.buffer[info.len] = 0; /* we terminate this with a zero byte */ info.buffer[info.len] = 0; /* we terminate this with a zero byte */
return info.buffer; return info.buffer;
} }
else else
return NULL; return strdup("");
} }
static int storebuffer(int output, FILE *data) static int storebuffer(int output, FILE *data)

View File

@@ -62,6 +62,13 @@ struct Curl_one_easy {
CURLMstate state; /* the handle's state */ CURLMstate state; /* the handle's state */
CURLcode result; /* previous result */ 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. */ /* This is the amount of entries in the linked list above. */
int num_easy; int num_easy;
/* this is a linked list of posted messages */ int num_msgs; /* total amount of messages in the easy handles */
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 */
/* Hostname cache */ /* Hostname cache */
curl_hash *hostcache; 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 /* 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. */ 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 */ /* make the previous node point to our next */
if(easy->prev) if(easy->prev)
easy->prev->next = easy->next; easy->prev->next = easy->next;
@@ -188,6 +191,8 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
/* NOTE NOTE NOTE /* NOTE NOTE NOTE
We do not touch the easy handle here! */ We do not touch the easy handle here! */
if (easy->msg)
free(easy->msg);
free(easy); free(easy);
multi->num_easy--; /* one less to care about now */ 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; struct Curl_one_easy *easy;
bool done; bool done;
CURLMcode result=CURLM_OK; CURLMcode result=CURLM_OK;
struct Curl_message *msg = NULL;
*running_handles = 0; /* bump this once for every living handle */ *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 /* after we have DONE what we're supposed to do, go COMPLETED, and
it doesn't matter what the Curl_done() returned! */ it doesn't matter what the Curl_done() returned! */
easy->state = CURLM_STATE_COMPLETED; 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; break;
case CURLM_STATE_COMPLETED: case CURLM_STATE_COMPLETED:
@@ -356,17 +333,37 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
return CURLM_INTERNAL_ERROR; return CURLM_INTERNAL_ERROR;
} }
if((CURLM_STATE_COMPLETED != easy->state) && if(CURLM_STATE_COMPLETED != easy->state) {
(CURLE_OK != easy->result)) { if(CURLE_OK != easy->result)
/* /*
* If an error was returned, and we aren't in completed now, * If an error was returned, and we aren't in completed state now,
* then we go to completed and consider this transfer aborted. * then we go to completed and consider this transfer aborted. */
*/ easy->state = CURLM_STATE_COMPLETED;
easy->state = CURLM_STATE_COMPLETED; 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 */
} }
else if(CURLM_STATE_COMPLETED != easy->state)
/* this one still lives! */
(*running_handles)++;
easy = easy->next; /* operate on next handle */ 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_multi *multi=(struct Curl_multi *)multi_handle;
struct Curl_one_easy *easy; struct Curl_one_easy *easy;
struct Curl_one_easy *nexteasy; struct Curl_one_easy *nexteasy;
struct Curl_message *msg;
struct Curl_message *nextmsg;
if(GOOD_MULTI_HANDLE(multi)) { if(GOOD_MULTI_HANDLE(multi)) {
multi->type = 0; /* not good anymore */ 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 */ /* clear out the usage of the shared DNS cache */
easy->easy_handle->hostcache = NULL; easy->easy_handle->hostcache = NULL;
if (easy->msg)
free(easy->msg);
free(easy); free(easy);
easy = nexteasy; easy = nexteasy;
} }
/* remove all struct Curl_message nodes left */
msg = multi->msgs;
while(msg) {
nextmsg = msg->next;
free(msg);
msg = nextmsg;
}
free(multi); free(multi);
return CURLM_OK; 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) CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue)
{ {
struct Curl_multi *multi=(struct Curl_multi *)multi_handle; struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
if(GOOD_MULTI_HANDLE(multi)) { if(GOOD_MULTI_HANDLE(multi)) {
CURLMsg *msg; struct Curl_one_easy *easy;
if(!multi->readptr && !multi->num_read)
multi->readptr = multi->msgs;
if(!multi->readptr) {
*msgs_in_queue = 0;
return NULL;
}
multi->num_read++; if(!multi->num_msgs)
return NULL; /* no messages left to return */
*msgs_in_queue = multi->num_msgs - multi->num_read; easy=multi->easy.next;
msg = &multi->readptr->extmsg; while(easy) {
if(easy->msg_num) {
easy->msg_num--;
break;
}
easy = easy->next;
}
if(!easy)
return NULL; /* this means internal count confusion really */
/* advance read pointer */ multi->num_msgs--;
multi->readptr = multi->readptr->next; *msgs_in_queue = multi->num_msgs;
return msg; return &easy->msg->extmsg;
} }
else else
return NULL; return NULL;

View File

@@ -78,12 +78,15 @@ int Curl_parsenetrc(char *host,
FILE *file; FILE *file;
char netrcbuffer[256]; char netrcbuffer[256];
int retcode=1; int retcode=1;
int specific_login = (login[0] != 0);
char *home = NULL; char *home = NULL;
int state=NOTHING; int state=NOTHING;
char state_login=0; char state_login=0; /* Found a login keyword */
char state_password=0; 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" #define NETRC DOT_CHAR "netrc"
@@ -116,6 +119,30 @@ int Curl_parsenetrc(char *host,
sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC); 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"); file = fopen(netrcbuffer, "r");
if(file) { if(file) {
char *tok; char *tok;
@@ -123,6 +150,10 @@ int Curl_parsenetrc(char *host,
while(fgets(netrcbuffer, sizeof(netrcbuffer), file)) { while(fgets(netrcbuffer, sizeof(netrcbuffer), file)) {
tok=strtok_r(netrcbuffer, " \t\n", &tok_buf); tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
while(tok) { while(tok) {
if (login[0] && password[0])
goto done;
switch(state) { switch(state) {
case NOTHING: case NOTHING:
if(strequal("machine", tok)) { if(strequal("machine", tok)) {
@@ -149,17 +180,23 @@ int Curl_parsenetrc(char *host,
case HOSTVALID: case HOSTVALID:
/* we are now parsing sub-keywords concerning "our" host */ /* we are now parsing sub-keywords concerning "our" host */
if(state_login) { if(state_login) {
strncpy(login, tok, LOGINSIZE-1); if (specific_login) {
state_our_login = strequal(login, tok);
}else{
strncpy(login, tok, LOGINSIZE-1);
#ifdef _NETRC_DEBUG #ifdef _NETRC_DEBUG
printf("LOGIN: %s\n", login); printf("LOGIN: %s\n", login);
#endif #endif
}
state_login=0; state_login=0;
} }
else if(state_password) { else if(state_password) {
strncpy(password, tok, PASSWORDSIZE-1); if (state_our_login || !specific_login) {
strncpy(password, tok, PASSWORDSIZE-1);
#ifdef _NETRC_DEBUG #ifdef _NETRC_DEBUG
printf("PASSWORD: %s\n", password); printf("PASSWORD: %s\n", password);
#endif #endif
}
state_password=0; state_password=0;
} }
else if(strequal("login", tok)) else if(strequal("login", tok))
@@ -169,13 +206,16 @@ int Curl_parsenetrc(char *host,
else if(strequal("machine", tok)) { else if(strequal("machine", tok)) {
/* ok, there's machine here go => */ /* ok, there's machine here go => */
state = HOSTFOUND; state = HOSTFOUND;
state_our_login = 0;
} }
break; break;
} /* switch (state) */ } /* switch (state) */
tok = strtok_r(NULL, " \t\n", &tok_buf); tok = strtok_r(NULL, " \t\n", &tok_buf);
} /* while (tok) */ } /* while (tok) */
} /* while fgets() */ } /* while fgets() */
done:
fclose(file); fclose(file);
} }

View File

@@ -25,4 +25,9 @@
int Curl_parsenetrc(char *host, int Curl_parsenetrc(char *host,
char *login, char *login,
char *password); 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 #endif

View File

@@ -149,7 +149,7 @@ void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
break; break;
case TIMER_REDIRECT: case TIMER_REDIRECT:
data->progress.t_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; break;
} }
} }

View File

@@ -40,6 +40,7 @@
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_FTP
#ifdef KRB4 #ifdef KRB4
#define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */ #define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */
@@ -552,6 +553,7 @@ Curl_sec_end(struct connectdata *conn)
} }
#endif /* KRB4 */ #endif /* KRB4 */
#endif /* CURL_DISABLE_FTP */
/* /*
* local variables: * local variables:

View File

@@ -23,7 +23,17 @@
* $Id$ * $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) #if !defined(WIN32) && defined(_WIN32)
/* This _might_ be a good Borland fix. Please report whether this works or /* This _might_ be a good Borland fix. Please report whether this works or

View File

@@ -55,6 +55,15 @@
#undef HAVE_USERDATA_IN_PWD_CALLBACK #undef HAVE_USERDATA_IN_PWD_CALLBACK
#endif #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 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
static char global_passwd[64]; static char global_passwd[64];
#endif #endif
@@ -223,30 +232,22 @@ int cert_stuff(struct connectdata *conn,
SSL_CTX_set_default_passwd_cb(conn->ssl.ctx, passwd_callback); 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); file_type = do_file_type(cert_type);
switch(file_type) { switch(file_type) {
case SSL_FILETYPE_PEM: 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: 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, if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
cert_file, cert_file,
file_type) != 1) { file_type) != 1) {
@@ -283,11 +284,17 @@ int cert_stuff(struct connectdata *conn,
{ /* XXXX still needs some work */ { /* XXXX still needs some work */
EVP_PKEY *priv_key = NULL; EVP_PKEY *priv_key = NULL;
if (conn && conn->data && conn->data->engine) { 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]) { if (!key_file || !key_file[0]) {
failf(data, "no key set to load from crypto engine\n"); failf(data, "no key set to load from crypto engine\n");
return 0; return 0;
} }
priv_key = ENGINE_load_private_key(conn->data->engine,key_file, priv_key = ENGINE_load_private_key(conn->data->engine,key_file,
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
ui_method,
#endif
data->set.key_passwd); data->set.key_passwd);
if (!priv_key) { if (!priv_key) {
failf(data, "failed to load private key from crypto engine\n"); failf(data, "failed to load private key from crypto engine\n");
@@ -315,8 +322,6 @@ int cert_stuff(struct connectdata *conn,
return 0; return 0;
} }
#endif
ssl=SSL_new(conn->ssl.ctx); ssl=SSL_new(conn->ssl.ctx);
x509=SSL_get_certificate(ssl); x509=SSL_get_certificate(ssl);

View File

@@ -23,6 +23,7 @@
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_TELNET
/* -- WIN32 approved -- */ /* -- WIN32 approved -- */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -1211,3 +1212,4 @@ CURLcode Curl_telnet(struct connectdata *conn)
* vim600: fdm=marker * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */
#endif

View File

@@ -23,7 +23,8 @@
* *
* $Id$ * $Id$
*****************************************************************************/ *****************************************************************************/
#ifndef CURL_DISABLE_TELNET
CURLcode Curl_telnet(struct connectdata *conn); CURLcode Curl_telnet(struct connectdata *conn);
CURLcode Curl_telnet_done(struct connectdata *conn); CURLcode Curl_telnet_done(struct connectdata *conn);
#endif
#endif #endif

View File

@@ -32,22 +32,36 @@
int int
gettimeofday (struct timeval *tp, void *nothing) gettimeofday (struct timeval *tp, void *nothing)
{ {
SYSTEMTIME st; #ifdef WITHOUT_MM_LIB
time_t tt; SYSTEMTIME st;
struct tm tmtm; time_t tt;
/* mktime converts local to UTC */ struct tm tmtm;
GetLocalTime (&st); /* mktime converts local to UTC */
tmtm.tm_sec = st.wSecond; GetLocalTime (&st);
tmtm.tm_min = st.wMinute; tmtm.tm_sec = st.wSecond;
tmtm.tm_hour = st.wHour; tmtm.tm_min = st.wMinute;
tmtm.tm_mday = st.wDay; tmtm.tm_hour = st.wHour;
tmtm.tm_mon = st.wMonth - 1; tmtm.tm_mday = st.wDay;
tmtm.tm_year = st.wYear - 1900; tmtm.tm_mon = st.wMonth - 1;
tmtm.tm_isdst = -1; tmtm.tm_year = st.wYear - 1900;
tt = mktime (&tmtm); tmtm.tm_isdst = -1;
tp->tv_sec = tt; tt = mktime (&tmtm);
tp->tv_usec = st.wMilliseconds * 1000; tp->tv_sec = tt;
return 1; 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 #define HAVE_GETTIMEOFDAY
#endif #endif

View File

@@ -168,6 +168,10 @@ compareheader(char *headerline, /* line to check */
return FALSE; /* no match */ 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, CURLcode Curl_readwrite(struct connectdata *conn,
bool *done) bool *done)
{ {
@@ -176,6 +180,35 @@ CURLcode Curl_readwrite(struct connectdata *conn,
int result; int result;
ssize_t nread; /* number of bytes read */ ssize_t nread; /* number of bytes read */
int didwhat=0; 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, &notimeout);
}
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, &notimeout);
}
do { do {
/* If we still have reading to do, we check if we have a readable /* If we still have reading to do, we check if we have a readable
@@ -183,7 +216,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
the multi interface and then we can do nothing but to attempt a the multi interface and then we can do nothing but to attempt a
read to be sure. */ read to be sure. */
if((k->keepon & KEEP_READ) && if((k->keepon & KEEP_READ) &&
(!k->readfdp || FD_ISSET(conn->sockfd, k->readfdp))) { (FD_ISSET(conn->sockfd, readfdp))) {
/* read! */ /* read! */
result = Curl_read(conn, conn->sockfd, k->buf, 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 the multi interface and then we can do nothing but to attempt a
write to be sure. */ write to be sure. */
if((k->keepon & KEEP_WRITE) && if((k->keepon & KEEP_WRITE) &&
(!k->writefdp || FD_ISSET(conn->writesockfd, k->writefdp)) ) { (FD_ISSET(conn->writesockfd, writefdp)) ) {
/* write */ /* write */
int i, si; int i, si;
@@ -970,9 +1003,6 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
k->rkeepfd = k->readfd; k->rkeepfd = k->readfd;
k->wkeepfd = k->writefd; 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; return CURLE_OK;
@@ -1034,6 +1064,9 @@ Transfer(struct connectdata *conn)
if(!conn->getheader && data->set.no_body) if(!conn->getheader && data->set.no_body)
return CURLE_OK; 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) { while (!done) {
struct timeval interval; struct timeval interval;
k->readfd = k->rkeepfd; /* set these every lap in the loop */ 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. * may be free()ed in the Curl_done() function.
*/ */
newurl = conn->newurl?strdup(conn->newurl):NULL; newurl = conn->newurl?strdup(conn->newurl):NULL;
else else {
/* The transfer phase returned error, we mark the connection to get /* The transfer phase returned error, we mark the connection to get
* closed to prevent being re-used. This is becasue we can't * 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. */ * possibly know if the connection is in a good shape or not now. */
conn->bits.close = TRUE; 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 /* Always run Curl_done(), even if some of the previous calls
failed, but return the previous (original) error code */ failed, but return the previous (original) error code */
res2 = Curl_done(conn); res2 = Curl_done(conn);

374
lib/url.c
View File

@@ -72,6 +72,10 @@
#include <inet.h> #include <inet.h>
#endif #endif
#ifdef HAVE_SETJMP_H
#include <setjmp.h>
#endif
#ifndef HAVE_SELECT #ifndef HAVE_SELECT
#error "We can't compile without select() support!" #error "We can't compile without select() support!"
#endif #endif
@@ -120,6 +124,7 @@
#ifdef KRB4 #ifdef KRB4
#include "security.h" #include "security.h"
#endif #endif
/* The last #include file should be: */ /* The last #include file should be: */
#ifdef MALLOCDEBUG #ifdef MALLOCDEBUG
#include "memdebug.h" #include "memdebug.h"
@@ -138,11 +143,17 @@ static unsigned int ConnectionStore(struct SessionHandle *data,
#ifndef RETSIGTYPE #ifndef RETSIGTYPE
#define RETSIGTYPE void #define RETSIGTYPE void
#endif #endif
#ifdef HAVE_SIGSETJMP
extern sigjmp_buf curl_jmpenv;
#endif
static static
RETSIGTYPE alarmfunc(int signal) RETSIGTYPE alarmfunc(int signal)
{ {
/* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
(void)signal; (void)signal;
#ifdef HAVE_SIGSETJMP
siglongjmp(curl_jmpenv, 1);
#endif
return; return;
} }
#endif #endif
@@ -182,11 +193,13 @@ CURLcode Curl_close(struct SessionHandle *data)
if(data->state.headerbuff) if(data->state.headerbuff)
free(data->state.headerbuff); free(data->state.headerbuff);
#ifndef CURL_DISABLE_HTTP
if(data->set.cookiejar) if(data->set.cookiejar)
/* we have a "destination" for all the cookies to get dumped to */ /* we have a "destination" for all the cookies to get dumped to */
Curl_cookie_output(data->cookies, data->set.cookiejar); Curl_cookie_output(data->cookies, data->set.cookiejar);
Curl_cookie_cleanup(data->cookies); Curl_cookie_cleanup(data->cookies);
#endif
/* free the connection cache */ /* free the connection cache */
free(data->state.connects); free(data->state.connects);
@@ -441,7 +454,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
/* /*
* Parse the $HOME/.netrc file * Parse the $HOME/.netrc file
*/ */
data->set.use_netrc = va_arg(param, long)?TRUE:FALSE; data->set.use_netrc = va_arg(param, long);
break; break;
case CURLOPT_FOLLOWLOCATION: case CURLOPT_FOLLOWLOCATION:
/* /*
@@ -514,6 +527,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->set.cookiesession = (bool)va_arg(param, long); data->set.cookiesession = (bool)va_arg(param, long);
break; break;
#ifndef CURL_DISABLE_HTTP
case CURLOPT_COOKIEFILE: case CURLOPT_COOKIEFILE:
/* /*
* Set cookie file to read and parse. Can be used multiple times. * 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->cookies = Curl_cookie_init(NULL, data->cookies,
data->set.cookiesession); data->set.cookiesession);
break; break;
#endif
case CURLOPT_WRITEHEADER: case CURLOPT_WRITEHEADER:
/* /*
* Custom pointer to pass the header write callback function * 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 * Set CA info for SSL connection. Specify file name of the CA certificate
*/ */
data->set.ssl.CAfile = va_arg(param, char *); 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; break;
case CURLOPT_TELNETOPTIONS: case CURLOPT_TELNETOPTIONS:
/* /*
@@ -1351,7 +1373,6 @@ static CURLcode CreateConnection(struct SessionHandle *data,
char resumerange[40]=""; char resumerange[40]="";
struct connectdata *conn; struct connectdata *conn;
struct connectdata *conn_temp; struct connectdata *conn_temp;
char endbracket;
int urllen; int urllen;
Curl_addrinfo *hostaddr; Curl_addrinfo *hostaddr;
#ifdef HAVE_ALARM #ifdef HAVE_ALARM
@@ -1406,7 +1427,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
connections, so we set this to force-close. Protocols that support connections, so we set this to force-close. Protocols that support
this need to set this to FALSE in their "curl_do" functions. */ this need to set this to FALSE in their "curl_do" functions. */
conn->bits.close = TRUE; conn->bits.close = TRUE;
/* inherite initial knowledge from the data struct */ /* inherite initial knowledge from the data struct */
conn->bits.user_passwd = data->set.userpwd?1:0; conn->bits.user_passwd = data->set.userpwd?1:0;
conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0;
@@ -1533,35 +1554,12 @@ static CURLcode CreateConnection(struct SessionHandle *data,
buf = data->state.buffer; /* this is our buffer */ buf = data->state.buffer; /* this is our buffer */
/************************************************************* /*
* Take care of user and password authentication stuff * So if the URL was A://B/C,
*************************************************************/ * conn->protostr is A
* conn->gname is B
if(conn->bits.user_passwd && !data->set.use_netrc) { * conn->path is /C
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;
}
}
}
/************************************************************* /*************************************************************
* Take care of proxy authentication stuff * 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 */ 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 * 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 * '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 */ conn->bits.use_range = 1; /* switch on range usage */
} }
} }
#endif
/************************************************************* /*************************************************************
* Setup internals depending on protocol * Setup internals depending on protocol
*************************************************************/ *************************************************************/
if (strequal(conn->protostr, "HTTP")) { if (strequal(conn->protostr, "HTTP")) {
#ifndef CURL_DISABLE_HTTP
conn->port = (data->set.use_port && data->state.allow_port)? conn->port = (data->set.use_port && data->state.allow_port)?
data->set.use_port:PORT_HTTP; data->set.use_port:PORT_HTTP;
conn->remote_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_do = Curl_http;
conn->curl_done = Curl_http_done; conn->curl_done = Curl_http_done;
conn->curl_connect = Curl_http_connect; 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")) { 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)? conn->port = (data->set.use_port && data->state.allow_port)?
data->set.use_port:PORT_HTTPS; data->set.use_port:PORT_HTTPS;
@@ -1781,6 +1786,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
#endif /* !USE_SSLEAY */ #endif /* !USE_SSLEAY */
} }
else if (strequal(conn->protostr, "GOPHER")) { else if (strequal(conn->protostr, "GOPHER")) {
#ifndef CURL_DISABLE_GOPHER
conn->port = (data->set.use_port && data->state.allow_port)? conn->port = (data->set.use_port && data->state.allow_port)?
data->set.use_port:PORT_GOPHER; data->set.use_port:PORT_GOPHER;
conn->remote_port = PORT_GOPHER; conn->remote_port = PORT_GOPHER;
@@ -1793,9 +1799,16 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->protocol |= PROT_GOPHER; conn->protocol |= PROT_GOPHER;
conn->curl_do = Curl_http; conn->curl_do = Curl_http;
conn->curl_done = Curl_http_done; 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") || else if(strequal(conn->protostr, "FTP") ||
strequal(conn->protostr, "FTPS")) { strequal(conn->protostr, "FTPS")) {
/* MN 06/07/02 */
#ifndef CURL_DISABLE_FTP
char *type; char *type;
if(strequal(conn->protostr, "FTPS")) { if(strequal(conn->protostr, "FTPS")) {
@@ -1823,8 +1836,13 @@ static CURLcode CreateConnection(struct SessionHandle *data,
failf(data, "ftps does not work through http proxy!"); failf(data, "ftps does not work through http proxy!");
return CURLE_UNSUPPORTED_PROTOCOL; return CURLE_UNSUPPORTED_PROTOCOL;
} }
#ifndef CURL_DISABLE_HTTP
conn->curl_do = Curl_http; conn->curl_do = Curl_http;
conn->curl_done = Curl_http_done; conn->curl_done = Curl_http_done;
#else
failf(data, "FTP over http proxy requires HTTP support built-in!");
return CURLE_UNSUPPORTED_PROTOCOL;
#endif
} }
else { else {
conn->curl_do = Curl_ftp; conn->curl_do = Curl_ftp;
@@ -1843,7 +1861,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
} }
if(type) { if(type) {
char command; char command;
*type=0; *type=0; /* it was in the middle of the hostname */
command = toupper(type[6]); command = toupper(type[6]);
switch(command) { switch(command) {
case 'A': /* ASCII mode */ case 'A': /* ASCII mode */
@@ -1859,8 +1877,16 @@ static CURLcode CreateConnection(struct SessionHandle *data,
break; 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")) { else if(strequal(conn->protostr, "TELNET")) {
#ifndef CURL_DISABLE_TELNET
/* telnet testing factory */ /* telnet testing factory */
conn->protocol |= PROT_TELNET; conn->protocol |= PROT_TELNET;
@@ -1869,24 +1895,39 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->remote_port = PORT_TELNET; conn->remote_port = PORT_TELNET;
conn->curl_do = Curl_telnet; conn->curl_do = Curl_telnet;
conn->curl_done = Curl_telnet_done; conn->curl_done = Curl_telnet_done;
#else
failf(data, LIBCURL_NAME
" was built with TELNET disabled!");
#endif
} }
else if (strequal(conn->protostr, "DICT")) { else if (strequal(conn->protostr, "DICT")) {
#ifndef CURL_DISABLE_DICT
conn->protocol |= PROT_DICT; conn->protocol |= PROT_DICT;
conn->port = (data->set.use_port && data->state.allow_port)? conn->port = (data->set.use_port && data->state.allow_port)?
data->set.use_port:PORT_DICT; data->set.use_port:PORT_DICT;
conn->remote_port = PORT_DICT; conn->remote_port = PORT_DICT;
conn->curl_do = Curl_dict; conn->curl_do = Curl_dict;
conn->curl_done = NULL; /* no DICT-specific done */ 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")) { else if (strequal(conn->protostr, "LDAP")) {
#ifndef CURL_DISABLE_LDAP
conn->protocol |= PROT_LDAP; conn->protocol |= PROT_LDAP;
conn->port = (data->set.use_port && data->state.allow_port)? conn->port = (data->set.use_port && data->state.allow_port)?
data->set.use_port:PORT_LDAP; data->set.use_port:PORT_LDAP;
conn->remote_port = PORT_LDAP; conn->remote_port = PORT_LDAP;
conn->curl_do = Curl_ldap; conn->curl_do = Curl_ldap;
conn->curl_done = NULL; /* no LDAP-specific done */ 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")) { else if (strequal(conn->protostr, "FILE")) {
#ifndef CURL_DISABLE_FILE
conn->protocol |= PROT_FILE; conn->protocol |= PROT_FILE;
conn->curl_do = Curl_file; conn->curl_do = Curl_file;
@@ -1903,6 +1944,10 @@ static CURLcode CreateConnection(struct SessionHandle *data,
} }
return result; return result;
#else
failf(data, LIBCURL_NAME
" was built with FILE disabled!");
#endif
} }
else { else {
/* We fell through all checks and thus we don't support the specified /* 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; 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 * 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 * To be able to detect port number flawlessly, we must not confuse them
* IPv6-specified addresses in the [0::1] style. (RFC2732) * 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)) && tmp = strrchr(conn->name, ':');
(']' == 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, ':');
}
if (tmp) { if (tmp) {
*tmp++ = '\0'; /* cut off the name there */ char *rest;
conn->remote_port = atoi(tmp); 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) { if(data->change.proxy) {
@@ -2075,6 +2043,138 @@ static CURLcode CreateConnection(struct SessionHandle *data,
free(proxydup); /* free the duplicate pointer and not the modified */ 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 * Check the current list of connections to see if we can
* re-use an already existing one or if we have to create a * 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); free(old_conn->proxyhost);
conn = conn_temp; /* use this connection from now on */ 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 */ /* we need these pointers if we speak over a proxy */
conn->hostname = conn->gname; conn->hostname = conn->gname;
conn->name = &conn->gname[old_conn->name - old_conn->gname]; conn->name = &conn->gname[old_conn->name - old_conn->gname];

View File

@@ -179,7 +179,9 @@ struct FTP {
char *entrypath; /* the PWD reply when we logged on */ char *entrypath; /* the PWD reply when we logged on */
char *cache; /* data cache between getresponse()-calls */ char *cache; /* data cache between getresponse()-calls */
size_t cache_size; /* size of cache in bytes */ 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 no_body;
bool set_port; bool set_port;
bool upload; bool upload;
bool use_netrc; enum CURL_NETRC_OPTION
use_netrc; /* defined in include/curl.h */
bool verbose; bool verbose;
bool krb4; /* kerberos4 connection requested */ bool krb4; /* kerberos4 connection requested */
bool reuse_forbid; /* forbidden to be reused, close after use */ bool reuse_forbid; /* forbidden to be reused, close after use */

View File

@@ -11,7 +11,7 @@
CC = gcc CC = gcc
STRIP = strip -s STRIP = strip -s
OPENSSL_PATH = ../../openssl-0.9.6b OPENSSL_PATH = ../../openssl-0.9.6d
# We may need these someday # We may need these someday
# PERL = perl # PERL = perl
@@ -36,7 +36,7 @@ else
curl_DEPENDENCIES = ../lib/libcurl.a curl_DEPENDENCIES = ../lib/libcurl.a
curl_LDADD = -L../lib -lcurl curl_LDADD = -L../lib -lcurl
endif endif
curl_LDADD += -lwsock32 -lws2_32 curl_LDADD += -lwsock32 -lws2_32 -lwinmm
ifdef SSL ifdef SSL
curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32 -lRSAglue curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32 -lRSAglue
endif endif

View File

@@ -17,5 +17,11 @@
/* Define if you have the <utime.h> header file */ /* Define if you have the <utime.h> header file */
#undef HAVE_UTIME_H #undef HAVE_UTIME_H
/* Define if you have thhe <sys/utime.h> header file */ /* Define if you have the <sys/utime.h> header file */
#undef HAVE_SYS_UTIME_H #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

View File

@@ -117,6 +117,9 @@ typedef enum {
#define CONF_MUTE (1<<28) /* force NOPROGRESS */ #define CONF_MUTE (1<<28) /* force NOPROGRESS */
#define CONF_NETRC_OPT (1<<29) /* read user+password from either
* .netrc or URL*/
#ifndef HAVE_STRDUP #ifndef HAVE_STRDUP
/* Ultrix doesn't have strdup(), so make a quick clone: */ /* Ultrix doesn't have strdup(), so make a quick clone: */
char *strdup(char *str) char *strdup(char *str)
@@ -336,14 +339,16 @@ static void help(void)
#endif #endif
" -e/--referer Referer page (H)"); " -e/--referer Referer page (H)");
puts(" -E/--cert <cert[:passwd]> Specifies your certificate file and password (HTTPS)\n" 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" " --cert-type <type> Specifies certificate file type (DER/PEM/ENG) (HTTPS)\n"
" --key <key> Specifies your private key file (HTTPS)\n" " --key <key> Specifies private key file (HTTPS)\n"
" --key-type <type> Specifies your private key file type (DER/PEM/ENG) (HTTPS)\n" " --key-type <type> Specifies private key file type (DER/PEM/ENG) (HTTPS)\n"
" --pass <pass> Specifies your passphrase for the private key (HTTPS)"); " --pass <pass> Specifies passphrase for the private key (HTTPS)");
puts(" --engine <eng> Specifies the crypto engine to use (HTTPS)\n" puts(" --engine <eng> Specifies the crypto engine to use (HTTPS)\n"
" --cacert <file> CA certifciate to verify peer against (SSL)\n" " --cacert <file> CA certifciate to verify peer against (SSL)\n"
" --ciphers <list> What SSL ciphers to use (SSL)\n" " --capath <directory> CA directory (made using c_rehash) to verify\n"
" --connect-timeout <seconds> Maximum time allowed for connection\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/--fail Fail silently (no output at all) on errors (H)\n"
" -F/--form <name=content> Specify HTTP POST data (H)\n" " -F/--form <name=content> Specify HTTP POST data (H)\n"
" -g/--globoff Disable URL sequences and ranges using {} and []\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" puts(" -L/--location Follow Location: hints (H)\n"
" -m/--max-time <seconds> Maximum time allowed for the transfer\n" " -m/--max-time <seconds> Maximum time allowed for the transfer\n"
" -M/--manual Display huge help text\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"); " -N/--no-buffer Disables the buffering of the output stream");
puts(" -o/--output <file> Write output to <file> instead of stdout\n" 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" " -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" " -T/--upload-file <file> Transfer/upload <file> to remote site\n"
" --url <URL> Another way to specify URL to work with"); " --url <URL> Another way to specify URL to work with");
puts(" -u/--user <user[:password]> Specify user and password to use\n" 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" " -U/--proxy-user <user[:password]> Specify Proxy authentication\n"
" -v/--verbose Makes the operation more talkative\n" " -v/--verbose Makes the operation more talkative\n"
" -V/--version Outputs version number then quits\n" " -V/--version Outputs version number then quits");
" -w/--write-out [format] What to output after completion\n" puts(" -w/--write-out [format] What to output after completion\n"
" -x/--proxy <host[:port]> Use proxy. (Default port is 1080)\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" " --random-file <file> File to use for reading random data from (SSL)\n"
" -X/--request <command> Specific request command to use"); " -X/--request <command> Specific request command to use");
@@ -449,6 +456,7 @@ struct Configurable {
char *cert; char *cert;
char *cert_type; char *cert_type;
char *cacert; char *cacert;
char *capath;
char *key; char *key;
char *key_type; char *key_type;
char *key_passwd; char *key_passwd;
@@ -994,6 +1002,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
{"Ed","key-type", TRUE}, {"Ed","key-type", TRUE},
{"Ee","pass", TRUE}, {"Ee","pass", TRUE},
{"Ef","engine", TRUE}, {"Ef","engine", TRUE},
{"Eg","capath ", TRUE},
{"f", "fail", FALSE}, {"f", "fail", FALSE},
{"F", "form", TRUE}, {"F", "form", TRUE},
{"g", "globoff", FALSE}, {"g", "globoff", FALSE},
@@ -1009,6 +1018,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
{"m", "max-time", TRUE}, {"m", "max-time", TRUE},
{"M", "manual", FALSE}, {"M", "manual", FALSE},
{"n", "netrc", FALSE}, {"n", "netrc", FALSE},
{"no", "netrc-optional", FALSE},
{"N", "no-buffer", FALSE}, {"N", "no-buffer", FALSE},
{"o", "output", TRUE}, {"o", "output", TRUE},
{"O", "remote-name", FALSE}, {"O", "remote-name", FALSE},
@@ -1329,6 +1339,10 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
case 'f': /* crypto engine */ case 'f': /* crypto engine */
GetStr(&config->engine, nextarg); GetStr(&config->engine, nextarg);
break; break;
case 'g': /* CA info PEM file */
/* CA cert directory */
GetStr(&config->capath, nextarg);
break;
default: /* certificate file */ default: /* certificate file */
{ {
char *ptr = strchr(nextarg, ':'); char *ptr = strchr(nextarg, ':');
@@ -1433,9 +1447,17 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
hugehelp(); hugehelp();
return PARAM_HELP_REQUESTED; return PARAM_HELP_REQUESTED;
case 'n': case 'n':
/* pick info from .netrc, if this is used for http, curl will switch(subletter) {
automatically enfore user+password with the request */ case 'o': /* CA info PEM file */
config->conf ^= CONF_NETRC; /* 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; break;
case 'N': case 'N':
/* disable the output I/O buffering */ /* disable the output I/O buffering */
@@ -1951,7 +1973,7 @@ void dump(const char *text,
/* without the hex output, we can fit more on screen */ /* without the hex output, we can fit more on screen */
width = 0x40; width = 0x40;
fprintf(stream, "%s %d (0x%x) bytes\n", text, size, size); fprintf(stream, "%s, %d bytes (0x%x)\n", text, size, size);
for(i=0; i<size; i+= width) { for(i=0; i<size; i+= width) {
@@ -1965,12 +1987,22 @@ void dump(const char *text,
else else
fputs(" ", stream); fputs(" ", stream);
} }
for(c = 0; (c < width) && (i+c < size); c++)
for(c = 0; (c < width) && (i+c < size); c++) {
/* check for 0D0A; if found, skip past and start a new line of output */
if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
i+=(c+2-width);
break;
}
fprintf(stream, "%c", fprintf(stream, "%c",
(ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.'); (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
/* check again for 0D0A, to avoid an extra \n if it's at width */
if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
i+=(c+3-width);
break;
}
}
fputc('\n', stream); /* newline */ fputc('\n', stream); /* newline */
} }
} }
@@ -2058,6 +2090,8 @@ void free_config_fields(struct Configurable *config)
curl_formfree(config->httppost); curl_formfree(config->httppost);
if(config->cacert) if(config->cacert)
free(config->cacert); free(config->cacert);
if(config->capath)
free(config->capath);
if(config->cookiejar) if(config->cookiejar)
free(config->cookiejar); free(config->cookiejar);
@@ -2494,7 +2528,14 @@ operate(struct Configurable *config, int argc, char *argv[])
curl_easy_setopt(curl, CURLOPT_FTPLISTONLY, curl_easy_setopt(curl, CURLOPT_FTPLISTONLY,
config->conf&CONF_FTPLISTONLY); config->conf&CONF_FTPLISTONLY);
curl_easy_setopt(curl, CURLOPT_FTPAPPEND, config->conf&CONF_FTPAPPEND); 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, curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,
config->conf&CONF_FOLLOWLOCATION); config->conf&CONF_FOLLOWLOCATION);
curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, config->conf&CONF_GETTEXT); curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, config->conf&CONF_GETTEXT);
@@ -2527,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_SSLKEYTYPE, config->key_type);
curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, config->key_passwd); curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, config->key_passwd);
if(config->cacert) { if(config->cacert || config->capath) {
curl_easy_setopt(curl, CURLOPT_CAINFO, config->cacert); 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_VERIFYPEER, TRUE);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
} }

View File

@@ -1,3 +1,3 @@
#define CURL_NAME "curl" #define CURL_NAME "curl"
#define CURL_VERSION "7.9.7-pre2" #define CURL_VERSION "7.9.8"
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") " #define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "

View File

@@ -21,9 +21,18 @@
* $Id$ * $Id$
*****************************************************************************/ *****************************************************************************/
#include "setup.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <curl/curl.h> #include <curl/curl.h>
#define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */ #define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */

View File

@@ -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 safely. Set the nocheck=1 to prevent the test script to verify the arrival
of this data. of this data.
</data> </data>
<datacheck> <datacheck [nonewline=yes]>
if the data is sent but this is what should be checked afterwards 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> </datacheck>
<size> <size>
number to return on a ftp SIZE command number to return on a ftp SIZE command

View File

@@ -15,5 +15,6 @@ test104 test113 test122 test18 test23 test301 test402 test9 \
test105 test114 test123 test19 test24 test302 test43 test31 \ test105 test114 test123 test19 test24 test302 test43 test31 \
test106 test115 test124 test190 test25 test303 test44 test38 \ test106 test115 test124 test190 test25 test303 test44 test38 \
test107 test116 test125 test2 test26 test33 test45 test126 \ 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
View 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
View 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
View 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
View 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
View 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
View 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>

View File

@@ -7,6 +7,9 @@ my $warning=0;
my $trace=0; my $trace=0;
sub getpartattr { sub getpartattr {
# if $part is undefined (ie only one argument) then
# return the attributes of the section
my ($section, $part)=@_; my ($section, $part)=@_;
my %hash; my %hash;
@@ -19,7 +22,9 @@ sub getpartattr {
if(!$inside && ($_ =~ /^ *\<$section/)) { if(!$inside && ($_ =~ /^ *\<$section/)) {
$inside++; $inside++;
} }
elsif((1 ==$inside) && ($_ =~ /^ *\<$part([^>]*)/)) { if((1 ==$inside) && ( ($_ =~ /^ *\<$part([^>]*)/) ||
!(defined($part)) )
) {
$inside++; $inside++;
my $attr=$1; my $attr=$1;
my @p=split("[ \t]", $attr); my @p=split("[ \t]", $attr);

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl #!/usr/bin/env perl
# #
# Example input: # Example input:
# #

View File

@@ -7,6 +7,7 @@
# These should be the only variables that might be needed to get edited: # These should be the only variables that might be needed to get edited:
use strict; use strict;
#use warnings;
@INC=(@INC, $ENV{'srcdir'}, "."); @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 $FTPPORT=8921; # this is the FTP server port
my $FTPSPORT=8821; # this is the FTPS server port my $FTPSPORT=8821; # this is the FTPS server port
my $CURL="../src/curl"; # what curl executable to run on the tests 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 $LOGDIR="log";
my $TESTDIR="data"; my $TESTDIR="data";
my $SERVERIN="$LOGDIR/server.input"; # what curl sent the server 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: # this gets set if curl is compiled with memory debugging:
my $memory_debug=0; 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: # name of the file that the memory debugging creates:
my $memdump="memdump"; my $memdump="memdump";
@@ -58,6 +65,8 @@ my $checkstunnel = &checkstunnel;
my $ssl_version; # set if libcurl is built with SSL support 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 # variables the command line options may set
# #
@@ -390,14 +399,35 @@ sub displaydata {
# enabled and we shall verify that no memory leaks exist # enabled and we shall verify that no memory leaks exist
# after each and every test! # after each and every test!
$memory_debug=1; $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("* 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("* HTTPS server: %s\n", $checkstunnel?"ON":"OFF");
printf("* FTPS server: %s\n", $checkstunnel?"ON":"OFF"); printf("* FTPS server: %s\n", $checkstunnel?"ON":"OFF");
printf("* libcurl SSL: %s\n", $ssl_version?"ON":"OFF"); printf("* libcurl SSL: %s\n", $ssl_version?"ON":"OFF");
print "***************************************** \n"; 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 # Run a single specified test case
# #
@@ -414,12 +444,41 @@ sub singletest {
return -1; 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 # extract the reply data
my @reply = getpart("reply", "data"); my @reply = getpart("reply", "data");
my @replycheck = getpart("reply", "datacheck"); my @replycheck = getpart("reply", "datacheck");
if (@replycheck) { if (@replycheck) {
# we use this file instead to check the final output against # 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; @reply=@replycheck;
} }
@@ -471,13 +530,16 @@ sub singletest {
# make some nice replace operations # make some nice replace operations
$cmd =~ s/\n//g; # no newlines please $cmd =~ s/\n//g; # no newlines please
$cmd =~ s/%HOSTIP/$HOSTIP/g;
$cmd =~ s/%HOSTPORT/$HOSTPORT/g; subVariables \$cmd;
$cmd =~ s/%HTTPSPORT/$HTTPSPORT/g;
$cmd =~ s/%FTPPORT/$FTPPORT/g; # $cmd =~ s/%HOSTIP/$HOSTIP/g;
$cmd =~ s/%FTPSPORT/$FTPSPORT/g; # $cmd =~ s/%HOSTPORT/$HOSTPORT/g;
$cmd =~ s/%SRCDIR/$srcdir/g; # $cmd =~ s/%HTTPSPORT/$HTTPSPORT/g;
$cmd =~ s/%PWD/$pwd/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; #$cmd =~ s/%HOSTNAME/$HOSTNAME/g;
@@ -491,11 +553,17 @@ sub singletest {
my %hash = getpartattr("client", "file"); my %hash = getpartattr("client", "file");
my $filename=$hash{'name'}; my $filename=$hash{'name'};
if(!$filename) { if(!$filename) {
print "ERROR: section client=>file has no name attribute!\n"; print "ERROR: section client=>file has no name attribute!\n";
exit; 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"); my %cmdhash = getpartattr("client", "command");
@@ -537,7 +605,7 @@ sub singletest {
print GDBCMD "set args $cmdargs\n"; print GDBCMD "set args $cmdargs\n";
print GDBCMD "show args\n"; print GDBCMD "show args\n";
close(GDBCMD); close(GDBCMD);
system("gdb $CURL -x log/gdbcmd"); system("gdb $DBGCURL -x log/gdbcmd");
$res =0; # makes it always continue after a debugged run $res =0; # makes it always continue after a debugged run
} }
else { else {
@@ -909,7 +977,6 @@ my $failed;
my $testnum; my $testnum;
my $ok=0; my $ok=0;
my $total=0; my $total=0;
my $skipped=0;
foreach $testnum (split(" ", $TESTCASES)) { foreach $testnum (split(" ", $TESTCASES)) {

View File

@@ -4,8 +4,8 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#define EAT_SPACE(ptr) while( ptr && *ptr && isspace(*ptr) ) ptr++ #define EAT_SPACE(ptr) while( ptr && *ptr && isspace((int)*ptr) ) ptr++
#define EAT_WORD(ptr) while( ptr && *ptr && !isspace(*ptr) && ('>' != *ptr)) ptr++ #define EAT_WORD(ptr) while( ptr && *ptr && !isspace((int)*ptr) && ('>' != *ptr)) ptr++
#ifdef DEBUG #ifdef DEBUG
#define show(x) printf x #define show(x) printf x

View File

@@ -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 <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -13,7 +41,10 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <netdb.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 #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" #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 const 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 *doc404 = "HTTP/1.1 404 Not Found\n"
"Server: " VERSION "\n" "Server: " VERSION "\n"
"Connection: close\n" "Connection: close\n"
"Content-Type: text/html\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" "The requested URL was not found on this server.\n"
"<P><HR><ADDRESS>" VERSION "</ADDRESS>\n" "</BODY></HTML>\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; static FILE *logfp;
@@ -53,27 +86,21 @@ static void logmsg(const char *msg)
strcpy(loctime, asctime(curr_time)); strcpy(loctime, asctime(curr_time));
loctime[strlen(loctime) - 1] = '\0'; 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 #ifdef DEBUG
fprintf(stderr, "%s: pid %d: %s\n", loctime, getpid(), msg); fprintf(stderr, "%s: pid %d: %s\n", loctime, (int)getpid(), msg);
#endif #endif
fflush(logfp); fflush(logfp);
} }
#ifdef HAVE_SIGNAL
static void sigpipe_handler(int sig) static void sigpipe_handler(int sig)
{ {
sigpipe = 1; (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) int ProcessRequest(char *request)
{ {
@@ -237,7 +264,7 @@ static int send_doc(int sock, int doc, int part_no)
{ {
int written; int written;
int count; int count;
char *buffer; const char *buffer;
char *ptr; char *ptr;
FILE *stream; FILE *stream;
char *cmd=NULL; char *cmd=NULL;
@@ -271,7 +298,8 @@ static int send_doc(int sock, int doc, int part_no)
return 0; return 0;
} }
else { else {
ptr = buffer = spitout(stream, "reply", partbuf, &count); buffer = spitout(stream, "reply", partbuf, &count);
ptr = (char *)buffer;
fclose(stream); fclose(stream);
} }
@@ -283,7 +311,7 @@ static int send_doc(int sock, int doc, int part_no)
} }
else { else {
/* get the custom server control "commands" */ /* get the custom server control "commands" */
cmd = spitout(stream, "reply", "postcmd", &cmdsize); cmd = (char *)spitout(stream, "reply", "postcmd", &cmdsize);
fclose(stream); fclose(stream);
} }
} }
@@ -330,7 +358,7 @@ int main(int argc, char *argv[])
struct sockaddr_in me; struct sockaddr_in me;
int sock, msgsock, flag; int sock, msgsock, flag;
unsigned short port = DEFAULT_PORT; unsigned short port = DEFAULT_PORT;
char *logfile = DEFAULT_LOGFILE; const char *logfile = DEFAULT_LOGFILE;
int part_no; int part_no;
FILE *pidfile; FILE *pidfile;
@@ -348,12 +376,8 @@ int main(int argc, char *argv[])
#ifdef HAVE_SIGNAL #ifdef HAVE_SIGNAL
/* FIX: make a more portable signal handler */ /* FIX: make a more portable signal handler */
signal(SIGPIPE, sigpipe_handler); signal(SIGPIPE, sigpipe_handler);
signal(SIGINT, sigterm_handler);
signal(SIGTERM, sigterm_handler);
siginterrupt(SIGPIPE, 1); siginterrupt(SIGPIPE, 1);
siginterrupt(SIGINT, 1);
siginterrupt(SIGTERM, 1);
#endif #endif
sock = socket(AF_INET, SOCK_STREAM, 0); 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); fprintf(stderr, "*** %s listening on port %u ***\n", VERSION, port);
while (!sigterm) { while (1) {
int doc; int doc;
msgsock = accept(sock, NULL, NULL); msgsock = accept(sock, NULL, NULL);
if (msgsock == -1) { if (msgsock == -1)
if (sigterm) {
break;
}
/* perror("accept"); */
continue; continue;
}
logmsg("New client connected"); logmsg("New client connected");