Compare commits
205 Commits
curl-7_10_
...
curl-7_10_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bdb5e5a250 | ||
![]() |
48a580e609 | ||
![]() |
1361fc69b9 | ||
![]() |
93352e56d8 | ||
![]() |
d9246ff24d | ||
![]() |
9301bc3444 | ||
![]() |
76352c4e2d | ||
![]() |
428f41bd12 | ||
![]() |
99c32e460f | ||
![]() |
83f249cf65 | ||
![]() |
2c2baa93ea | ||
![]() |
f0278ca114 | ||
![]() |
297b1b5013 | ||
![]() |
e9f63bf4e8 | ||
![]() |
556ce1c6a1 | ||
![]() |
cc4ff62681 | ||
![]() |
0423fd9b55 | ||
![]() |
789ab20bf7 | ||
![]() |
b47462bd68 | ||
![]() |
1a94fee42d | ||
![]() |
a91ce6a5d6 | ||
![]() |
981ffd9fce | ||
![]() |
e76c960624 | ||
![]() |
416c92cc6f | ||
![]() |
fb731eb3e7 | ||
![]() |
6f2a4d290f | ||
![]() |
cefc8ba938 | ||
![]() |
d0bd644eef | ||
![]() |
071c95128e | ||
![]() |
1a192c489b | ||
![]() |
56014e74a0 | ||
![]() |
172271498d | ||
![]() |
f2882cb88c | ||
![]() |
152f1fee40 | ||
![]() |
968234e6ae | ||
![]() |
5e133e2dff | ||
![]() |
0049c09fc3 | ||
![]() |
a2a63c27f4 | ||
![]() |
c50a601f1a | ||
![]() |
bc0fd6db71 | ||
![]() |
52b631fade | ||
![]() |
2f0bc9d1f7 | ||
![]() |
5ef6520d4e | ||
![]() |
2c1925161e | ||
![]() |
0529b349d5 | ||
![]() |
b4620364a2 | ||
![]() |
634aef3895 | ||
![]() |
06c86d1a8c | ||
![]() |
79749f8eb4 | ||
![]() |
b036986b3e | ||
![]() |
938f1d1da7 | ||
![]() |
58b6b3df06 | ||
![]() |
f9c3347f7c | ||
![]() |
5b72eb0b03 | ||
![]() |
6dd4c13bc0 | ||
![]() |
e4e7db551f | ||
![]() |
ebfde8da56 | ||
![]() |
756bc0f4b7 | ||
![]() |
269d491b6a | ||
![]() |
449e5bc2ad | ||
![]() |
8736c11d84 | ||
![]() |
45fc760985 | ||
![]() |
7968e3c2de | ||
![]() |
964a41c75c | ||
![]() |
5931d53637 | ||
![]() |
3ed3ae5bcf | ||
![]() |
6519cc70c5 | ||
![]() |
505a4f27fa | ||
![]() |
79144eba99 | ||
![]() |
26e17d89c9 | ||
![]() |
4322c1106f | ||
![]() |
73071dfd4f | ||
![]() |
b7c14b3c27 | ||
![]() |
3130b44535 | ||
![]() |
a2bd73334f | ||
![]() |
1a393f5625 | ||
![]() |
d4951e837e | ||
![]() |
26f6365e93 | ||
![]() |
3a552b1e63 | ||
![]() |
69eb1790da | ||
![]() |
a1af6f3614 | ||
![]() |
3aced61465 | ||
![]() |
6f02ddfce8 | ||
![]() |
c2faa39b62 | ||
![]() |
2d3734b8b5 | ||
![]() |
ed908b7f89 | ||
![]() |
f7d795a364 | ||
![]() |
8919b39d54 | ||
![]() |
84cedc094e | ||
![]() |
3b2b2496d7 | ||
![]() |
445684c409 | ||
![]() |
898e067ccc | ||
![]() |
12859e345f | ||
![]() |
89f4af695e | ||
![]() |
308bc9d919 | ||
![]() |
db566c54ae | ||
![]() |
81d403e207 | ||
![]() |
2bd71d70ff | ||
![]() |
1eef6f44ba | ||
![]() |
204f03912f | ||
![]() |
f8c3b3aa18 | ||
![]() |
d4df981463 | ||
![]() |
497c6d516d | ||
![]() |
8288862b7e | ||
![]() |
9aae16c236 | ||
![]() |
80c194a70a | ||
![]() |
c832b2db5b | ||
![]() |
27018882ec | ||
![]() |
caf6e9c540 | ||
![]() |
e727fb82f2 | ||
![]() |
c78df56801 | ||
![]() |
d13202f43b | ||
![]() |
9d139a6b35 | ||
![]() |
d2abe44e6f | ||
![]() |
bc67228576 | ||
![]() |
ecf32c964a | ||
![]() |
e58f30b82a | ||
![]() |
654e3f1101 | ||
![]() |
86689dc524 | ||
![]() |
5f62a0c1ca | ||
![]() |
ad1bf0f389 | ||
![]() |
9c7703ace1 | ||
![]() |
4a8155b53c | ||
![]() |
80d6d5c5c4 | ||
![]() |
c624be8388 | ||
![]() |
09df1cd41e | ||
![]() |
52c5b57200 | ||
![]() |
5ea04a852e | ||
![]() |
a2eef05198 | ||
![]() |
55f75af353 | ||
![]() |
fb6a51b8fd | ||
![]() |
252cc2213e | ||
![]() |
73c5f24fa4 | ||
![]() |
4c80e103a0 | ||
![]() |
39ea557360 | ||
![]() |
d0cc92a01a | ||
![]() |
d7980c1a45 | ||
![]() |
e56ae1426c | ||
![]() |
696843c020 | ||
![]() |
6ff5621dd7 | ||
![]() |
e7fb72a732 | ||
![]() |
8d30d34e0c | ||
![]() |
bc7fe85f8a | ||
![]() |
89352d92c5 | ||
![]() |
c32390d84c | ||
![]() |
45ca866a2d | ||
![]() |
ceef206c21 | ||
![]() |
7c6424f0a9 | ||
![]() |
bc942de6f1 | ||
![]() |
06984df5cb | ||
![]() |
4f136a3a76 | ||
![]() |
363bf3ba30 | ||
![]() |
acb895956a | ||
![]() |
21e87b9bb3 | ||
![]() |
c896ebcf12 | ||
![]() |
d288222e80 | ||
![]() |
4eb2a6c9a3 | ||
![]() |
2563731c4d | ||
![]() |
4e410111db | ||
![]() |
5670563a26 | ||
![]() |
6caa656d01 | ||
![]() |
c12af7aed1 | ||
![]() |
dcb6d1c01d | ||
![]() |
18234cbdac | ||
![]() |
06bf988dc1 | ||
![]() |
55ff4c3f08 | ||
![]() |
4915002168 | ||
![]() |
5bd8d60e41 | ||
![]() |
fc872808c5 | ||
![]() |
0f4feda382 | ||
![]() |
90b0f38316 | ||
![]() |
18f630ab21 | ||
![]() |
e97fd44151 | ||
![]() |
b75679778f | ||
![]() |
35a84ad576 | ||
![]() |
4ed28be75a | ||
![]() |
e2f4656a86 | ||
![]() |
1e14da5c60 | ||
![]() |
b2ef79ef3d | ||
![]() |
f488874ff5 | ||
![]() |
23258648da | ||
![]() |
6b84ebe501 | ||
![]() |
07dd067f73 | ||
![]() |
420744d048 | ||
![]() |
01108e3a63 | ||
![]() |
8026b1e194 | ||
![]() |
a39d77227f | ||
![]() |
9f69deec7d | ||
![]() |
e912f772e0 | ||
![]() |
0102726aeb | ||
![]() |
1e7aa04040 | ||
![]() |
00a7c6fe6b | ||
![]() |
87f8c0d471 | ||
![]() |
334d78cd18 | ||
![]() |
2356325592 | ||
![]() |
d78ec593fa | ||
![]() |
d5043133e6 | ||
![]() |
509f69a457 | ||
![]() |
662c659220 | ||
![]() |
9a6566e774 | ||
![]() |
4da0428d9e | ||
![]() |
8ee1177206 | ||
![]() |
e9154b2549 | ||
![]() |
d398a0dd58 | ||
![]() |
7723a24297 |
@@ -9,3 +9,6 @@ config.status
|
||||
curl-config
|
||||
autom4te.cache
|
||||
depcomp
|
||||
config.guess
|
||||
config.sub
|
||||
ltmain.sh
|
||||
|
1504
CHANGES.2002
Normal file
1504
CHANGES.2002
Normal file
File diff suppressed because it is too large
Load Diff
4
CVS-INFO
4
CVS-INFO
@@ -16,8 +16,8 @@ Compile and build instructions follow below.
|
||||
CHANGES.$year contains changes for the particular year.
|
||||
|
||||
tests/memanalyze.pl
|
||||
is for analyzing the output generated by curl if -DMALLOCDEBUG
|
||||
is used when compiling
|
||||
is for analyzing the output generated by curl if -DCURLDEBUG
|
||||
is used when compiling (run configure with --enable-debug)
|
||||
|
||||
buildconf builds the makefiles and configure stuff
|
||||
|
||||
|
14
Makefile.am
14
Makefile.am
@@ -4,12 +4,13 @@
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
EXTRA_DIST = CHANGES COPYING maketgz SSLCERTS reconf Makefile.dist \
|
||||
EXTRA_DIST = CHANGES COPYING maketgz reconf Makefile.dist \
|
||||
curl-config.in build_vms.com curl-style.el sample.emacs testcurl.sh
|
||||
|
||||
bin_SCRIPTS = curl-config
|
||||
|
||||
SUBDIRS = docs lib src include tests packages
|
||||
SUBDIRS = lib src
|
||||
DIST_SUBDIRS = $(SUBDIRS) tests include packages docs
|
||||
|
||||
# create a root makefile in the distribution:
|
||||
dist-hook:
|
||||
@@ -25,10 +26,10 @@ pdf:
|
||||
check: test
|
||||
|
||||
test:
|
||||
@(cd tests; $(MAKE) quiet-test)
|
||||
@(cd tests; $(MAKE) all quiet-test)
|
||||
|
||||
test-full:
|
||||
@(cd tests; $(MAKE) full-test)
|
||||
@(cd tests; $(MAKE) all full-test)
|
||||
|
||||
#
|
||||
# Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros
|
||||
@@ -77,3 +78,8 @@ pkgadd:
|
||||
# resulting .tar.bz2 file will end up at packages/Win32/cygwin
|
||||
cygwinbin:
|
||||
$(MAKE) -C packages/Win32/cygwin cygwinbin
|
||||
|
||||
# We extend the standard install with a custom hook:
|
||||
install-data-hook:
|
||||
cd include && $(MAKE) install
|
||||
cd docs && $(MAKE) install
|
||||
|
@@ -59,6 +59,10 @@ vc-ssl-dll:
|
||||
cd ..\src
|
||||
nmake -f Makefile.vc6
|
||||
|
||||
djgpp:
|
||||
make -C lib -f Makefile.dj
|
||||
make -C src -f Makefile.dj
|
||||
|
||||
cygwin:
|
||||
./configure
|
||||
make
|
||||
|
8
README
8
README
@@ -49,15 +49,15 @@ CVS
|
||||
|
||||
To download the very latest source off the CVS server do this:
|
||||
|
||||
cvs -d :pserver:anonymous@cvs.curl.sourceforge.net:/cvsroot/curl login
|
||||
cvs -d :pserver:cvsread@cvs.php.net:/repository login
|
||||
|
||||
(just press enter when asked for password)
|
||||
(enter "phpfi" when asked for password)
|
||||
|
||||
cvs -d :pserver:anonymous@cvs.curl.sourceforge.net:/cvsroot/curl co curl
|
||||
cvs -d :pserver:cvsread@cvs.php.net:/repository co curl
|
||||
|
||||
(you'll get a directory named curl created, filled with the source code)
|
||||
|
||||
cvs -d :pserver:anonymous@cvs.curl.sourceforge.net:/cvsroot/curl logout
|
||||
cvs -d :pserver:cvsread@cvs.php.net:/repository logout
|
||||
|
||||
(you're off the hook!)
|
||||
|
||||
|
131
configure.ac
131
configure.ac
@@ -14,7 +14,7 @@ This configure script may be copied, distributed and modified under the
|
||||
terms of the curl license; see COPYING for more details])
|
||||
|
||||
AC_CONFIG_SRCDIR([lib/urldata.h])
|
||||
AM_CONFIG_HEADER(lib/config.h src/config.h tests/server/config.h lib/ca-bundle.h)
|
||||
AM_CONFIG_HEADER(lib/config.h src/config.h tests/server/config.h )
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AC_PATH_PROG( SED, sed, , $PATH:/usr/bin:/usr/local/bin)
|
||||
@@ -454,6 +454,63 @@ else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for GSS-API libraries
|
||||
dnl **********************************************************************
|
||||
|
||||
AC_ARG_WITH(gssapi-includes,
|
||||
AC_HELP_STRING([--with-gssapi-includes=DIR],
|
||||
[Specify location of GSSAPI header]),
|
||||
[ GSSAPI_INCS="-I$withval"
|
||||
want_gss="yes" ]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(gssapi-libs,
|
||||
AC_HELP_STRING([--with-gssapi-libs=DIR],
|
||||
[Specify location of GSSAPI libs]),
|
||||
[ GSSAPI_LIBS="-L$withval -lgssapi"
|
||||
want_gss="yes" ]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(gssapi,
|
||||
AC_HELP_STRING([--with-gssapi=DIR],
|
||||
[Where to look for GSSAPI]),
|
||||
[ GSSAPI_ROOT="$withval"
|
||||
want_gss="yes" ]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([if GSSAPI support is requested])
|
||||
if test x"$want_gss" = xyes; then
|
||||
if test -z "$GSSAPI_INCS"; then
|
||||
if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
|
||||
gss_cppflags=`$GSSAPI_ROOT/bin/krb5-config --cflags gssapi`
|
||||
CPPFLAGS="$CPPFLAGS $gss_cppflags"
|
||||
else
|
||||
CPPFLAGS="$GSSAPI_ROOT/include"
|
||||
fi
|
||||
else
|
||||
CPPFLAGS="$CPPFLAGS $GSSAPI_INCS"
|
||||
fi
|
||||
|
||||
if test -z "$GSSAPI_LIB_DIR"; then
|
||||
if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
|
||||
gss_ldflags=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi`
|
||||
LDFLAGS="$LDFLAGS $gss_ldflags"
|
||||
else
|
||||
LDFLAGS="$LDFLAGS $GSSAPI_ROOT/lib -lgssapi"
|
||||
fi
|
||||
else
|
||||
LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR"
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(GSSAPI, 1, [if you have the gssapi libraries])
|
||||
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
|
||||
dnl Detect the pkg-config tool, as it may have extra info about the
|
||||
dnl openssl installation we can use. I *believe* this is what we are
|
||||
dnl expected to do on really recent Redhat Linux hosts.
|
||||
@@ -486,6 +543,8 @@ dnl **********************************************************************
|
||||
|
||||
dnl Default to compiler & linker defaults for SSL files & libraries.
|
||||
OPT_SSL=off
|
||||
dnl Default to no CA bundle
|
||||
ca="no"
|
||||
AC_ARG_WITH(ssl,dnl
|
||||
AC_HELP_STRING([--with-ssl=PATH],[where to look for SSL, PATH points to the SSL installation (default: /usr/local/ssl)])
|
||||
AC_HELP_STRING([--without-ssl], [disable SSL]),
|
||||
@@ -569,13 +628,29 @@ else
|
||||
|
||||
AC_SUBST(OPENSSL_ENABLED)
|
||||
|
||||
AC_MSG_CHECKING([CA cert bundle install path])
|
||||
|
||||
AC_ARG_WITH(ca-bundle,
|
||||
AC_HELP_STRING([--with-ca-bundle=FILE], [File name to install the CA bundle as])
|
||||
AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
|
||||
[ ca="$withval" ],
|
||||
[
|
||||
if test "x$prefix" != xNONE; then
|
||||
ca="\${prefix}/share/curl/curl-ca-bundle.crt"
|
||||
else
|
||||
ca="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
|
||||
fi
|
||||
] )
|
||||
|
||||
if test X"$OPT_SSL" = Xno; then
|
||||
ca="no"
|
||||
fi
|
||||
|
||||
if test X"$OPT_SSL" != Xoff &&
|
||||
test "$OPENSSL_ENABLED" != "1"; then
|
||||
AC_MSG_ERROR([OpenSSL libs and/or directories were not found where specified!])
|
||||
if test "x$ca" != "xno"; then
|
||||
CURL_CA_BUNDLE='"'$ca'"'
|
||||
AC_SUBST(CURL_CA_BUNDLE)
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$ca])
|
||||
|
||||
dnl these can only exist if openssl exists
|
||||
|
||||
@@ -583,8 +658,17 @@ else
|
||||
RAND_screen \
|
||||
RAND_egd )
|
||||
|
||||
fi
|
||||
|
||||
if test X"$OPT_SSL" != Xoff &&
|
||||
test "$OPENSSL_ENABLED" != "1"; then
|
||||
AC_MSG_ERROR([OpenSSL libs and/or directories were not found where specified!])
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(CABUNDLE, test x$ca != xno)
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for the presence of ZLIB libraries and headers
|
||||
dnl **********************************************************************
|
||||
@@ -627,6 +711,9 @@ case "$OPT_ZLIB" in
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl set variable for use in automakefile(s)
|
||||
AM_CONDITIONAL(HAVE_LIBZ, test x"$HAVE_LIBZ" = x1)
|
||||
|
||||
dnl Default is to try the thread-safe versions of a few functions
|
||||
OPT_THREAD=on
|
||||
|
||||
@@ -774,7 +861,6 @@ AC_CHECK_FUNCS( socket \
|
||||
tcgetattr \
|
||||
perror \
|
||||
closesocket \
|
||||
setvbuf \
|
||||
sigaction \
|
||||
signal \
|
||||
getpass_r \
|
||||
@@ -822,36 +908,6 @@ AC_PATH_PROGS( NROFF, gnroff nroff, ,
|
||||
$PATH:/usr/bin/:/usr/local/bin )
|
||||
AC_SUBST(NROFF)
|
||||
|
||||
AC_MSG_CHECKING([CA cert bundle install path])
|
||||
|
||||
AC_ARG_WITH(ca-bundle,
|
||||
AC_HELP_STRING([--with-ca-bundle=FILE], [File name to install the CA bundle as])
|
||||
AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
|
||||
[ ca="$withval" ],
|
||||
[
|
||||
if test "x$prefix" != xNONE; then
|
||||
ca="$prefix/share/curl/curl-ca-bundle.crt"
|
||||
else
|
||||
ca="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
|
||||
fi
|
||||
] )
|
||||
|
||||
if test X"$OPT_SSL" = Xno
|
||||
then
|
||||
ca="no"
|
||||
fi
|
||||
|
||||
if test "x$ca" = "xno"; then
|
||||
dnl let's not keep "no" as path name, blank it instead
|
||||
ca=""
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(CURL_CA_BUNDLE, "$ca", [CA bundle full path name])
|
||||
fi
|
||||
|
||||
CURL_CA_BUNDLE="$ca"
|
||||
AC_SUBST(CURL_CA_BUNDLE)
|
||||
AC_MSG_RESULT([$ca])
|
||||
|
||||
AC_PROG_YACC
|
||||
|
||||
dnl AC_PATH_PROG( RANLIB, ranlib, /usr/bin/ranlib,
|
||||
@@ -871,7 +927,7 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
|
||||
CPPFLAGS="$CPPFLAGS -DMALLOCDEBUG"
|
||||
CPPFLAGS="$CPPFLAGS -DCURLDEBUG"
|
||||
CFLAGS="$CFLAGS -g"
|
||||
if test "$GCC" = "yes"; then
|
||||
CFLAGS="$CFLAGS -W -Wall -Wwrite-strings -pedantic -Wundef -Wpointer-arith -Wnested-externs"
|
||||
@@ -914,6 +970,7 @@ AC_CONFIG_FILES([Makefile \
|
||||
packages/Linux/RPM/curl.spec \
|
||||
packages/Linux/RPM/curl-ssl.spec \
|
||||
packages/Solaris/Makefile \
|
||||
packages/DOS/Makefile \
|
||||
packages/EPM/curl.list \
|
||||
packages/EPM/Makefile \
|
||||
curl-config
|
||||
|
@@ -37,7 +37,7 @@
|
||||
(setq tab-width 8
|
||||
indent-tabs-mode nil ; Use spaces. Not tabs.
|
||||
comment-column 40
|
||||
c-font-lock-extra-types (append '("bool" "CURL" "CURLcode" "ssize_t" "size_t" "socklen_t" "fd_set"))
|
||||
c-font-lock-extra-types (append '("bool" "CURL" "CURLcode" "ssize_t" "size_t" "socklen_t" "fd_set" "time_t"))
|
||||
)
|
||||
;; keybindings for C, C++, and Objective-C. We can put these in
|
||||
;; c-mode-base-map because of inheritance ...
|
||||
|
15
docs/FAQ
15
docs/FAQ
@@ -1,4 +1,4 @@
|
||||
Updated: May 9, 2003 (http://curl.haxx.se/docs/faq.html)
|
||||
Updated: June 17, 2003 (http://curl.haxx.se/docs/faq.html)
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
@@ -593,9 +593,11 @@ FAQ
|
||||
|
||||
4.9. Curl can't authenticate to the server that requires NTLM?
|
||||
|
||||
NTLM is a Microsoft proprietary protocol. Unfortunately, curl does not
|
||||
currently support that. Proprietary formats are evil. You should not use
|
||||
such ones.
|
||||
This is supported in curl 7.10.6 or later. No earlier curl version knows
|
||||
of this magic.
|
||||
|
||||
NTLM is a Microsoft proprietary protocol. Proprietary formats are evil. You
|
||||
should not use such ones.
|
||||
|
||||
4.10 My HTTP request using HEAD, PUT or DELETE doesn't work!
|
||||
|
||||
@@ -776,6 +778,5 @@ FAQ
|
||||
discussions and a large amount of people have contributed with source code
|
||||
knowing that this is the license we use. This license puts the restrictions
|
||||
we want on curl/libcurl and it does not spread to other programs or
|
||||
libraries that use it. The recent dual license modification should make it
|
||||
possible for everyone to use libcurl or curl in their projects, no matter
|
||||
what license they already have in use.
|
||||
libraries that use it. It should be possible for everyone to use libcurl or
|
||||
curl in their projects, no matter what license they already have in use.
|
||||
|
@@ -17,27 +17,30 @@ Misc
|
||||
- progress bar/time specs while downloading
|
||||
- "standard" proxy environment variables support
|
||||
- config file support
|
||||
- compiles on win32 (reported built on 29 operating systems)
|
||||
- compiles on win32 (reported builds on 40+ operating systems)
|
||||
- redirectable stderr
|
||||
- use selected network interface for outgoing traffic
|
||||
- selectable network interface for outgoing traffic
|
||||
- IPv6 support
|
||||
- persistant connections
|
||||
- socks5 support
|
||||
- supports user name + password in proxy environment variables
|
||||
- operations through proxy "tunnel" (using CONNECT)
|
||||
|
||||
HTTP
|
||||
- HTTP/1.1 compliant
|
||||
- HTTP/1.1 compliant (optionally uses 1.0)
|
||||
- GET
|
||||
- PUT
|
||||
- HEAD
|
||||
- POST
|
||||
- multipart POST
|
||||
- authentication
|
||||
- multipart formpost (RFC1867-style)
|
||||
- authentication (Basic, Digest, NTLM(*1), GSS-Negotiate(*3))
|
||||
- resume (both GET and PUT)
|
||||
- follow redirects
|
||||
- maximum amount of redirects to follow
|
||||
- custom HTTP request
|
||||
- cookie get/send fully parsed
|
||||
- understands the netscape cookie file format
|
||||
- custom headers (that can replace/remove internally generated headers)
|
||||
- reads/writes the netscape cookie file format
|
||||
- custom headers (replace/remove internally generated headers)
|
||||
- custom user-agent string
|
||||
- custom referer string
|
||||
- range
|
||||
@@ -45,12 +48,16 @@ HTTP
|
||||
- time conditions
|
||||
- via http-proxy
|
||||
- retrieve file modification date
|
||||
- Content-Encoding support for deflate and gzip
|
||||
- "Transfer-Encoding: chunked" support for "uploads"
|
||||
|
||||
HTTPS (*1)
|
||||
- (all the HTTP features)
|
||||
- using certificates
|
||||
- verify server certificate
|
||||
- via http-proxy
|
||||
- select desired encryption
|
||||
- force usage of a specific SSL version (SSLv2, SSLv3 or TLSv1)
|
||||
|
||||
FTP
|
||||
- download
|
||||
@@ -92,3 +99,4 @@ FILE
|
||||
|
||||
*1 = requires OpenSSL
|
||||
*2 = requires OpenLDAP
|
||||
*3 = requires a GSSAPI-compliant library, such as Heimdal or similar.
|
||||
|
@@ -448,6 +448,7 @@ PORTS
|
||||
- StrongARM NetBSD 1.4.1
|
||||
- Ultrix 4.3a
|
||||
- i386 BeOS
|
||||
- i386 DOS
|
||||
- i386 FreeBSD
|
||||
- i386 HURD
|
||||
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4
|
||||
|
@@ -3,6 +3,12 @@ join in and help us correct one or more of these! Also be sure to check the
|
||||
changelog of the current development status, as one or more of these problems
|
||||
may have been fixed since this was written!
|
||||
|
||||
* LDAP output is garbled. Hardly anyone seems to care about LDAP functionality
|
||||
in curl/libcurl why this report has been closed and set to be solved later.
|
||||
If you feel this is something you want fixed, get in touch and we'll start
|
||||
working.
|
||||
http://sourceforge.net/tracker/index.php?func=detail&aid=735752&group_id=976&atid=100976
|
||||
|
||||
* IPv6 support on AIX 4.3.3 doesn't work due to a missing sockaddr_storage
|
||||
struct. It has been reported to work on AIX 5.1 though.
|
||||
|
||||
|
@@ -11,7 +11,7 @@ SIMPLE USAGE
|
||||
|
||||
curl http://www.netscape.com/
|
||||
|
||||
Get the root README file from funet's ftp-server:
|
||||
Get the README file the user's home directory at funet's ftp-server:
|
||||
|
||||
curl ftp://ftp.funet.fi/README
|
||||
|
||||
@@ -19,7 +19,7 @@ SIMPLE USAGE
|
||||
|
||||
curl http://www.weirdserver.com:8000/
|
||||
|
||||
Get a list of the root directory of an FTP site:
|
||||
Get a list of a directory of an FTP site:
|
||||
|
||||
curl ftp://cool.haxx.se/
|
||||
|
||||
|
@@ -19,7 +19,7 @@ PDFPAGES = \
|
||||
|
||||
SUBDIRS = examples libcurl
|
||||
|
||||
EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS \
|
||||
EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
|
||||
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS \
|
||||
VERSIONS KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) \
|
||||
HISTORY INSTALL libcurl-the-guide $(PDFPAGES)
|
||||
|
@@ -13,8 +13,8 @@ README.win32
|
||||
are win32-based.
|
||||
|
||||
The unix-style man pages are tricky to read on windows, so therefore are all
|
||||
those pages also converted to HTML and those are also included in the
|
||||
release archives.
|
||||
those pages converted to HTML as well as pdf, and included in the release
|
||||
archives.
|
||||
|
||||
The main curl.1 man page is also "built-in" in the command line tool. Use a
|
||||
command line similar to this in order to extract a separate text file:
|
||||
|
@@ -90,3 +90,4 @@ that have contributed with non-trivial parts:
|
||||
- Dan Fandrich <dan@coneharvesters.com>
|
||||
- Jean-Philippe Barrette-LaPierre <jpb@rrette.com>
|
||||
- Richard Bramante <RBramante@on.com>
|
||||
- Daniel Kouril <kouril@ics.muni.cz>
|
||||
|
54
docs/TODO
54
docs/TODO
@@ -16,7 +16,7 @@ TODO
|
||||
know what cookies that are received. Pushing interface that calls a
|
||||
callback on each received cookie? Querying interface that asks about
|
||||
existing cookies? We probably need both. Enable applications to modify
|
||||
existing cookies as well.
|
||||
existing cookies as well. http://curl.haxx.se/dev/COOKIES
|
||||
|
||||
* Make content encoding/decoding internally be made using a filter system.
|
||||
|
||||
@@ -50,10 +50,6 @@ TODO
|
||||
requested. That is, the download should not even begin but be aborted
|
||||
immediately.
|
||||
|
||||
* Allow the http_proxy (and other) environment variables to contain user and
|
||||
password as well in the style: http://proxyuser:proxypasswd@proxy:port
|
||||
Berend Reitsma suggested.
|
||||
|
||||
LIBCURL - multi interface
|
||||
|
||||
* Make sure we don't ever loop because of non-blocking sockets return
|
||||
@@ -76,55 +72,21 @@ TODO
|
||||
* Make CURLOPT_FTPPORT support an additional port number on the IP/if/name,
|
||||
like "blabla:[port]" or possibly even "blabla:[portfirst]-[portsecond]".
|
||||
|
||||
* FTP ASCII upload does not follow RFC959 section 3.1.1.1: "The sender
|
||||
converts the data from an internal character representation to the standard
|
||||
8-bit NVT-ASCII representation (see the Telnet specification). The
|
||||
receiver will convert the data from the standard form to his own internal
|
||||
form."
|
||||
* FTP ASCII transfers do not follow RFC959. They don't convert the data
|
||||
accordingly.
|
||||
|
||||
* Since USERPWD always override the user and password specified in URLs, we
|
||||
might need another way to specify user+password for anonymous ftp logins.
|
||||
|
||||
* An option to only download remote FTP files if they're newer than the local
|
||||
one is a good idea, and it would fit right into the same syntax as the
|
||||
already working http dito works (-z). It of course requires that 'MDTM'
|
||||
works, and it isn't a standard FTP command.
|
||||
|
||||
* Add FTPS support with SSL for the data connection too. This should be made
|
||||
according to the specs written in draft-murray-auth-ftp-ssl-08.txt,
|
||||
"Securing FTP with TLS"
|
||||
|
||||
* --disable-epsv exists, but for active connections we have no --disable-eprt
|
||||
(or even --disable-lprt).
|
||||
according to the specs written in draft-murray-auth-ftp-ssl-11.txt,
|
||||
"Securing FTP with TLS", valid until September 27th 2003.
|
||||
http://curl.haxx.se/rfc/draft-murray-auth-ftp-ssl-11.txt
|
||||
|
||||
HTTP
|
||||
|
||||
* If the "body" of the POST is < MSS it really aught to be sent along with
|
||||
the headers. More generally, if the last chunk of the POST body is < MSS,
|
||||
it should be sent with the previous chunk (which may be the POST headers).
|
||||
So long as any one send is larger than MSS (or there is only one send when
|
||||
< MSS :), the Nagle Algorithm will not be a problem on any stack where
|
||||
Nagle is implemented correctly. (pointed out by Rick Jones)
|
||||
|
||||
* Authentication: NTLM. Support for that MS crap called NTLM
|
||||
authentication. MS proxies and servers sometime require that. Since that
|
||||
protocol is a proprietary one, it involves reverse engineering and network
|
||||
sniffing. This should however be a library-based functionality. There are a
|
||||
few different efforts "out there" to make open source HTTP clients support
|
||||
this and it should be possible to take advantage of other people's hard
|
||||
work. http://modntlm.sourceforge.net/ is one. There's a web page at
|
||||
http://www.innovation.ch/java/ntlm.html that contains detailed reverse-
|
||||
engineered info.
|
||||
|
||||
* RFC2617 compliance, "Digest Access Authentication" A valid test page seem
|
||||
to exist at: http://hopf.math.nwu.edu/testpage/digest/ And some friendly
|
||||
person's server source code is available at
|
||||
http://hopf.math.nwu.edu/digestauth/index.html Then there's the Apache
|
||||
mod_digest source code too of course. It seems as if Netscape doesn't
|
||||
support this, and not many servers do. Although this is a lot better
|
||||
authentication method than the more common "Basic". Basic sends the
|
||||
password in cleartext over the network, this "Digest" method uses a
|
||||
challange-response protocol which increases security quite a lot.
|
||||
* Digest, NTLM and GSS-Negotiate support for HTTP proxies. They all work
|
||||
on direct-connections to the server.
|
||||
|
||||
* Pipelining. Sending multiple requests before the previous one(s) are done.
|
||||
This could possibly be implemented using the multi interface to queue
|
||||
|
133
docs/curl.1
133
docs/curl.1
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man curl.1
|
||||
.\" Written by Daniel Stenberg
|
||||
.\"
|
||||
.TH curl 1 "14 Feb 2003" "Curl 7.10.3" "Curl Manual"
|
||||
.TH curl 1 "18 June 2003" "Curl 7.10.6" "Curl Manual"
|
||||
.SH NAME
|
||||
curl \- transfer a URL
|
||||
.SH SYNOPSIS
|
||||
@@ -10,14 +10,18 @@ curl \- transfer a URL
|
||||
.I [URL...]
|
||||
.SH DESCRIPTION
|
||||
.B curl
|
||||
is a client to get documents/files from or send documents to a server, using
|
||||
any of the supported protocols (HTTP, HTTPS, FTP, GOPHER, DICT, TELNET, LDAP
|
||||
or FILE). The command is designed to work without user interaction or any kind
|
||||
of interactivity.
|
||||
is a tool to transfer data from or to a server, using one of the supported
|
||||
protocols (HTTP, HTTPS, FTP, FTPS, GOPHER, DICT, TELNET, LDAP or FILE). The
|
||||
command is designed to work without user interaction.
|
||||
|
||||
curl offers a busload of useful tricks like proxy support, user
|
||||
authentication, ftp upload, HTTP post, SSL (https:) connections, cookies, file
|
||||
transfer resume and more.
|
||||
transfer resume and more. As you will see below, the amount of features will
|
||||
make your head spin!
|
||||
|
||||
curl is powered by libcurl for all transfer-related features. See
|
||||
.BR libcurl (3)
|
||||
for details.
|
||||
.SH URL
|
||||
The URL syntax is protocol dependent. You'll find a detailed description in
|
||||
RFC 2396.
|
||||
@@ -48,10 +52,8 @@ specified on a single command line and cannot be used between separate curl
|
||||
invokes.
|
||||
.SH OPTIONS
|
||||
.IP "-a/--append"
|
||||
(FTP)
|
||||
When used in a ftp upload, this will tell curl to append to the target
|
||||
file instead of overwriting it. If the file doesn't exist, it will
|
||||
be created.
|
||||
(FTP) When used in an FTP upload, this will tell curl to append to the target
|
||||
file instead of overwriting it. If the file doesn't exist, it will be created.
|
||||
|
||||
If this option is used twice, the second one will disable append mode again.
|
||||
.IP "-A/--user-agent <agent string>"
|
||||
@@ -63,6 +65,16 @@ surround the string with single quote marks. This can also be set with the
|
||||
|
||||
If this option is set more than once, the last one will be the one that's
|
||||
used.
|
||||
.IP "--anyauth"
|
||||
(HTTP) Tells curl to figure out authentication method by itself, and use the
|
||||
most secure one the remote site claims it supports. This is done by first
|
||||
doing a request and checking the response-headers, thus inducing an extra
|
||||
network round-trip. This is used instead of setting a specific authentication
|
||||
method, which you can do with \fI--digest\fP, \fI--ntlm\fP, and
|
||||
\fI--negotiate\fP. (Added in 7.10.6)
|
||||
|
||||
If this option is used several times, the following occurrences make no
|
||||
difference.
|
||||
.IP "-b/--cookie <name=data>"
|
||||
(HTTP)
|
||||
Pass the data to the HTTP server as a cookie. It is supposedly the
|
||||
@@ -90,6 +102,14 @@ also be enforced by using an URL that ends with ";type=A". This option causes
|
||||
data sent to stdout to be in text mode for win32 systems.
|
||||
|
||||
If this option is used twice, the second one will disable ASCII usage.
|
||||
.IP "--basic"
|
||||
(HTTP) Tells curl to use HTTP Basic authentication. This is the default and
|
||||
this option is usually pointless, unless you use it to override a previously
|
||||
set option that sets a different authentication method (such as \fI--ntlm\fP,
|
||||
\fI--digest\fP and \fI--negotiate\fP). (Added in 7.10.6)
|
||||
|
||||
If this option is used several times, the following occurrences make no
|
||||
difference.
|
||||
.IP "--ciphers <list of ciphers>"
|
||||
(SSL) Specifies which ciphers to use in the connection. The list of ciphers
|
||||
must be using valid ciphers. Read up on SSL cipher list details on this URL:
|
||||
@@ -97,9 +117,11 @@ must be using valid ciphers. Read up on SSL cipher list details on this URL:
|
||||
|
||||
If this option is used several times, the last one will override the others.
|
||||
.IP "--compressed"
|
||||
(HTTP) Request a compressed response using the deflate or gzip
|
||||
algorithms and return the uncompressed document. If this option is used
|
||||
and the server sends an unsupported encoding, Curl will report an error.
|
||||
(HTTP) Request a compressed response using one of the algorithms libcurl
|
||||
supports, and return the uncompressed document. If this option is used and
|
||||
the server sends an unsupported encoding, Curl will report an error.
|
||||
|
||||
If this option is used several times, each occurrence will toggle it on/off.
|
||||
.IP "--connect-timeout <seconds>"
|
||||
Maximum time in seconds that you allow the connection to the server to take.
|
||||
This only limits the connection phase, once curl has connected this option is
|
||||
@@ -176,9 +198,27 @@ want to post a binary file without the strip-newlines feature of the
|
||||
|
||||
If this option is used several times, the ones following the first will
|
||||
append data.
|
||||
.IP "--digest"
|
||||
(HTTP) Enables HTTP Digest authentication. This is a authentication that
|
||||
prevents the password from being sent over the wire in clear text. Use this in
|
||||
combination with the normal -u/--user option to set user name and
|
||||
password. See also \fI--ntlm\fP, \fP--negotiate\fI and \fI--anyauth\fP for
|
||||
related options. (Added in curl 7.10.6)
|
||||
|
||||
If this option is used several times, the following occurrences make no
|
||||
difference.
|
||||
.IP "--disable-eprt"
|
||||
(FTP) Tell curl to disable the use of the EPRT and LPRT commands when doing
|
||||
active FTP transfers. Curl will normally always first attempt to use EPRT,
|
||||
then LPRT before using PORT, but with this option, it will use PORT right
|
||||
away. EPRT and LPRT are extensions to the original FTP protocol, may not work
|
||||
on all servers but enable more functionality in a better way than the
|
||||
traditional PORT command. (Aded in 7.10.5)
|
||||
|
||||
If this option is used several times, each occurrence will toggle this on/off.
|
||||
.IP "--disable-epsv"
|
||||
(FTP) Tell curl to disable the use of the EPSV command when doing passive FTP
|
||||
downloads. Curl will normally always first attempt to use EPSV before PASV,
|
||||
transfers. Curl will normally always first attempt to use EPSV before PASV,
|
||||
but with this option, it will not try using EPSV.
|
||||
|
||||
If this option is used several times, each occurrence will toggle this on/off.
|
||||
@@ -397,9 +437,18 @@ If this option is used twice, the second will again disable list only.
|
||||
(HTTP/HTTPS) If the server reports that the requested page has a different
|
||||
location (indicated with the header line Location:) this flag will let curl
|
||||
attempt to reattempt the get on the new place. If used together with -i or -I,
|
||||
headers from all requested pages will be shown. If this flag is used when
|
||||
making a HTTP POST, curl will automatically switch to GET after the initial
|
||||
POST has been done.
|
||||
headers from all requested pages will be shown. If authentication is used,
|
||||
curl will only send its credentials to the initial host, so if a redirect
|
||||
takes curl to a different host, it won't intercept the user+password. See also
|
||||
\fI--location-trusted\fP on how to change this.
|
||||
|
||||
If this option is used twice, the second will again disable location following.
|
||||
.IP "--location-trusted"
|
||||
(HTTP/HTTPS) Like \fI--location\fP, but will allow sending the name + password
|
||||
to all hosts that the site may redirect to. This may or may not introduce a
|
||||
security breach if the site redirects you do a site to which you'll send your
|
||||
authentication info (which is plaintext in the case of HTTP Basic
|
||||
authentication).
|
||||
|
||||
If this option is used twice, the second will again disable location following.
|
||||
.IP "-m/--max-time <seconds>"
|
||||
@@ -433,6 +482,19 @@ to allow curl to ftp to the machine host.domain.com with user name
|
||||
.B "machine host.domain.com login myself password secret"
|
||||
|
||||
If this option is used twice, the second will again disable netrc usage.
|
||||
.IP "--negotiate"
|
||||
(HTTP) Enables GSS-Negotiate authentication. The GSS-Negotiate method was
|
||||
designed by Microsoft and is used in their web aplications. It is primarily
|
||||
meant as a support for Kerberos5 authentication but may be also used along
|
||||
with another authentication methods. For more information see IETF draft
|
||||
draft-brezak-spnego-http-04.txt. (Added in 7.10.6)
|
||||
|
||||
\fBNOTE\fP that this option requiures that the library was built with GSSAPI
|
||||
support. This is not very common. Use \fIcurl --version\fP to see if your
|
||||
version supports GSS-Negotiate.
|
||||
|
||||
If this option is used several times, the following occurrences make no
|
||||
difference.
|
||||
.IP "-N/--no-buffer"
|
||||
Disables the buffering of the output stream. In normal work situations, curl
|
||||
will use a standard buffered output stream that will have the effect that it
|
||||
@@ -440,6 +502,19 @@ will output the data in chunks, not necessarily exactly when the data arrives.
|
||||
Using this option will disable that buffering.
|
||||
|
||||
If this option is used twice, the second will again switch on buffering.
|
||||
.IP "--ntlm"
|
||||
(HTTP) Enables NTLM authentication. The NTLM authentication method was
|
||||
designed by Microsoft and is used by IIS web servers. It is a proprietary
|
||||
protocol, reversed engineered by clever people and implemented in curl based
|
||||
on their efforts. This kind of behavior should not be endorsed, you should
|
||||
encourage everyone who uses NTLM to switch to a public and documented
|
||||
authentication method instead. Such as Digest. (Added in 7.10.6)
|
||||
|
||||
\fBNOTE\fP that this option requiures that the library was built with SSL
|
||||
support. Use \fIcurl --version\fP to see if your version supports NTLM.
|
||||
|
||||
If this option is used several times, the following occurrences make no
|
||||
difference.
|
||||
.IP "-o/--output <file>"
|
||||
Write output to <file> instead of stdout. If you are using {} or [] to fetch
|
||||
multiple documents, you can use '#' followed by a number in the <file>
|
||||
@@ -456,8 +531,8 @@ You may use this option as many times as you have number of URLs.
|
||||
|
||||
See also the --create-dirs option to create the local directories dynamically.
|
||||
.IP "-O/--remote-name"
|
||||
Write output to a local file named like the remote file we get. (Only
|
||||
the file part of the remote file is used, the path is cut off.)
|
||||
Write output to a local file named like the remote file we get. (Only the file
|
||||
part of the remote file is used, the path is cut off.)
|
||||
|
||||
You may use this option as many times as you have number of URLs.
|
||||
.IP "-p/--proxytunnel"
|
||||
@@ -596,7 +671,7 @@ descriptive information, to the given output file. Use "-" as filename to have
|
||||
the output sent to stdout.
|
||||
|
||||
If this option is used several times, the last one will be used. (Added in
|
||||
curl 7.9.7)
|
||||
7.9.7)
|
||||
.IP "--trace-ascii <file>"
|
||||
Enables a full trace dump of all incoming and outgoing data, including
|
||||
descriptive information, to the given output file. Use "-" as filename to have
|
||||
@@ -607,12 +682,15 @@ the ASCII part of the dump. It makes smaller output that might be easier to
|
||||
read for untrained humans.
|
||||
|
||||
If this option is used several times, the last one will be used. (Added in
|
||||
curl 7.9.7)
|
||||
7.9.7)
|
||||
.IP "-u/--user <user:password>"
|
||||
Specify user and password to use when fetching. Read the MANUAL for detailed
|
||||
examples of how to use this. If no password is specified, curl will ask for it
|
||||
interactively.
|
||||
|
||||
You can also use the --digest option to enable Digest authentication when
|
||||
communicating with HTTP 1.1 servers.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-U/--proxy-user <user:password>"
|
||||
Specify user and password to use for Proxy authentication. If no
|
||||
@@ -642,8 +720,17 @@ If you think this option still doesn't give you enough details, consider using
|
||||
|
||||
If this option is used twice, the second will again disable verbose.
|
||||
.IP "-V/--version"
|
||||
Displays the full version of curl, libcurl and other 3rd party libraries
|
||||
linked with the executable.
|
||||
Displays information about curl and the libcurl version it uses.
|
||||
|
||||
The first line includes the full version of curl, libcurl and other 3rd party
|
||||
libraries linked with the executable.
|
||||
|
||||
The second line (starts with "Protocols:") shows all protocols that libcurl
|
||||
reports to support.
|
||||
|
||||
The third line (starts with "Features:") shows specific features libcurl
|
||||
reports to offer.
|
||||
|
||||
.IP "-w/--write-out <format>"
|
||||
Defines what to display after a completed and successful operation. The format
|
||||
is a string that may contain plain text mixed with any number of variables. The
|
||||
|
@@ -9,7 +9,7 @@ EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \
|
||||
multithread.c getinmemory.c ftpupload.c httpput.c \
|
||||
simplessl.c ftpgetresp.c http-post.c post-callback.c \
|
||||
multi-app.c multi-double.c multi-single.c multi-post.c \
|
||||
fopen.c simplepost.c
|
||||
fopen.c simplepost.c makefile.dj
|
||||
|
||||
all:
|
||||
@echo "done"
|
||||
|
31
docs/examples/makefile.dj
Normal file
31
docs/examples/makefile.dj
Normal file
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# Adapted for djgpp / Watt-32 / DOS by
|
||||
# Gisle Vanem <giva@bgnett.no>
|
||||
#
|
||||
|
||||
include ../../packages/DOS/common.dj
|
||||
|
||||
CFLAGS += -I../../include
|
||||
|
||||
LIBS = ../../lib/libcurl.a
|
||||
|
||||
ifeq ($(USE_SSL),1)
|
||||
LIBS += $(OPENSSL_ROOT)/lib/libssl.a $(OPENSSL_ROOT)/lib/libcrypt.a
|
||||
endif
|
||||
|
||||
LIBS += $(WATT32_ROOT)/lib/libwatt.a $(ZLIB_ROOT)/libz.a
|
||||
|
||||
PROGRAMS = fopen.exe ftpget.exe ftpgetre.exe ftpuploa.exe getinmem.exe \
|
||||
http-pos.exe httpput.exe multi-ap.exe multi-do.exe \
|
||||
multi-po.exe multi-si.exe persista.exe post-cal.exe \
|
||||
postit2.exe sepheade.exe simple.exe simpless.exe
|
||||
|
||||
all: $(PROGRAMS)
|
||||
|
||||
.c.exe:
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
@echo
|
||||
|
||||
clean:
|
||||
rm -f $(PROGRAMS)
|
||||
|
@@ -40,7 +40,7 @@ int main(int argc, char **argv)
|
||||
FILE *headerfile;
|
||||
|
||||
const char *pCertFile = "testcert.pem";
|
||||
const char *pCACertFile="cacert.pem"
|
||||
const char *pCACertFile="cacert.pem";
|
||||
|
||||
const char *pKeyName;
|
||||
const char *pKeyType;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_easy_setopt 3 "3 Dec 2002" "libcurl 7.10.3" "libcurl Manual"
|
||||
.TH curl_easy_setopt 3 "10 Jun 2003" "libcurl 7.10.6" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_setopt - set options for a curl easy handle
|
||||
.SH SYNOPSIS
|
||||
@@ -272,7 +272,7 @@ The main point of this would be that the write callback gets called more often
|
||||
and with smaller chunks. This is just treated as a request, not an order. You
|
||||
cannot be guaranteed to actually get the given size. (Added in 7.10)
|
||||
.PP
|
||||
.SH NAMES and PASSWORDS OPTIONS
|
||||
.SH NAMES and PASSWORDS OPTIONS (Authentication)
|
||||
.TP 0.4i
|
||||
.B CURLOPT_NETRC
|
||||
This parameter controls the preference of libcurl between using user names and
|
||||
@@ -322,15 +322,60 @@ prompt function.
|
||||
|
||||
When using HTTP and CURLOPT_FOLLOWLOCATION, libcurl might perform several
|
||||
requests to possibly different hosts. libcurl will only send this user and
|
||||
password information to hosts using the initial host name, so if libcurl
|
||||
follows locations to other hosts it will not send the user and password to
|
||||
those. This is enforced to prevent accidental information leakage.
|
||||
password information to hosts using the initial host name (unless
|
||||
CURLOPT_UNRESTRICTED_AUTH is set), so if libcurl follows locations to other
|
||||
hosts it will not send the user and password to those. This is enforced to
|
||||
prevent accidental information leakage.
|
||||
.TP
|
||||
.B CURLOPT_PROXYUSERPWD
|
||||
Pass a char * as parameter, which should be [user name]:[password] to use for
|
||||
the connection to the HTTP proxy. If the password is left out, you will be
|
||||
prompted for it. \fICURLOPT_PASSWDFUNCTION\fP can be used to set your own
|
||||
prompt function.
|
||||
.TP
|
||||
.B CURLOPT_HTTPAUTH
|
||||
Pass a long as parameter, which is set to a bitmask, to tell libcurl what
|
||||
authentication method(s) you want it to use. The available bits are listed
|
||||
below. If more than one bit is set, libcurl will first query the site to see
|
||||
what authentication methods it supports and then pick the best one you allow
|
||||
it to use. Note that for some methods, this will induce an extra network
|
||||
round-trip. Set the actual name and password with the \fICURLOPT_USERPWD\fP
|
||||
option. (Added in 7.10.6)
|
||||
.RS
|
||||
.TP 5
|
||||
.B CURLAUTH_BASIC
|
||||
HTTP Basic authentication. This is the default choice, and the only method
|
||||
that is in wide-spread use and supported virtually everywhere. This is sending
|
||||
the user name and password over the network in plain text, easily captured by
|
||||
others.
|
||||
.TP
|
||||
.B CURLAUTH_DIGEST
|
||||
HTTP Digest authentication. Digest authentication is defined in RFC2617 and
|
||||
is a more secure way to do authentication over public networks than the
|
||||
regular old-fashioned Basic method.
|
||||
.TP
|
||||
.B CURLAUTH_GSSNEGOTIATE
|
||||
HTTP GSS-Negotiate authentication. The GSS-Negotiate method was designed by
|
||||
Microsoft and is used in their web aplications. It is primarily meant as a
|
||||
support for Kerberos5 authentication but may be also used along with another
|
||||
authentication methods. For more information see IETF draft
|
||||
draft-brezak-spnego-http-04.txt.
|
||||
.TP
|
||||
.B CURLAUTH_NTLM
|
||||
HTTP NTLM authentication. A proprietary protocol invented and used by
|
||||
Microsoft. It uses a challenge-response and hash concept similar to Digest to
|
||||
prevent the password from being evesdropped.
|
||||
.TP
|
||||
.B CURLAUTH_ANY
|
||||
This is a convenience macro that sets all bits and thus makes libcurl pick any
|
||||
it finds suitable. libcurl will automaticly select the one it finds most
|
||||
secure.
|
||||
.TP
|
||||
.B CURLAUTH_ANYSAFE
|
||||
This is a convenience macro that sets all bits except Basic and thus makes
|
||||
libcurl pick any it finds suitable. libcurl will automaticly select the one it
|
||||
finds most secure.
|
||||
.RE
|
||||
.PP
|
||||
.SH HTTP OPTIONS
|
||||
.TP 0.4i
|
||||
@@ -437,6 +482,10 @@ curl adds CRLF after each header item. Failure to comply with this will
|
||||
result in strange bugs because the server will most likely ignore part
|
||||
of the headers you specified.
|
||||
|
||||
The first line in a request (usually containing a GET or POST) is not a header
|
||||
and cannot be replaced using this option. Only the lines following the
|
||||
request-line are headers.
|
||||
|
||||
\fBNOTE:\fPThe most commonly replaced headers have "shortcuts" in the options
|
||||
CURLOPT_COOKIE, CURLOPT_USERAGENT and CURLOPT_REFERER.
|
||||
.TP
|
||||
@@ -615,9 +664,18 @@ want the transfer to start from.
|
||||
.TP
|
||||
.B CURLOPT_CUSTOMREQUEST
|
||||
Pass a pointer to a zero terminated string as parameter. It will be user
|
||||
instead of GET or HEAD when doing the HTTP request. This is useful for doing
|
||||
DELETE or other more or less obscure HTTP requests. Don't do this at will,
|
||||
make sure your server supports the command first.
|
||||
instead of GET or HEAD when doing a HTTP request, or instead of LIST or NLST
|
||||
when doing an ftp directory listing. This is useful for doing DELETE or other
|
||||
more or less obscure HTTP requests. Don't do this at will, make sure your
|
||||
server supports the command first.
|
||||
|
||||
NOTE: many people have wrongly used this option to replace the entire request
|
||||
with their own, including multiple headers and POST contents. While that might
|
||||
work in many cases, it will cause libcurl to send invalid requests and it
|
||||
could possibly confuse the remote server badly. Use \fICURLOPT_POST\fP and
|
||||
\fICURLOPT_POSTFIELDS\fP to set POST data. Use \fICURLOPT_HTTPHEADER\fP to
|
||||
replace or extend the set of headers sent by libcurl. Use
|
||||
\fICURLOPT_HTTP_VERSION\fP to change HTTP version.
|
||||
.TP
|
||||
.B CURLOPT_FILETIME
|
||||
Pass a long. If it is a non-zero value, libcurl will attempt to get the
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_slist_append 3 "21 Feb 2003" "libcurl 7.10.4" "libcurl Manual"
|
||||
.TH curl_slist_append 3 "19 Jun 2003" "libcurl 7.10.4" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_slist_append - add a string to an slist
|
||||
.SH SYNOPSIS
|
||||
@@ -15,7 +15,8 @@ curl_slist_append - add a string to an slist
|
||||
curl_slist_append() appends a specified string to a linked list of
|
||||
strings. The existing \fIlist\fP should be passed as the first argument while
|
||||
the new list is returned from this function. The specified \fIstring\fP has
|
||||
been appended when this function returns.
|
||||
been appended when this function returns. curl_slist_append() copies the
|
||||
string.
|
||||
|
||||
The list should be freed again (after usage) with \fBcurl_slist_free_all()\fP.
|
||||
.SH RETURN VALUE
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" $Id$
|
||||
.\"
|
||||
.TH curl_version_info 3 "30 Sep 2002" "libcurl 7.10" "libcurl Manual"
|
||||
.TH curl_version_info 3 "17 Jun 2003" "libcurl 7.10.6" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_version_info - returns run-time libcurl version info
|
||||
.SH SYNOPSIS
|
||||
@@ -69,6 +69,16 @@ supports SSL (HTTPS/FTPS)
|
||||
.TP
|
||||
.B CURL_VERSION_LIBZ
|
||||
supports HTTP deflate using libz
|
||||
.TP
|
||||
.B CURL_VERSION_NTLM
|
||||
supports HTTP NTLM (added in 7.10.6)
|
||||
.TP
|
||||
.B CURL_VERSION_GSSNEGOTIATE
|
||||
supports HTTP GSS-Negotiate (added in 7.10.6)
|
||||
.TP
|
||||
.B CURL_VERSION_DEBUG
|
||||
libcurl was built with extra debug capabilities built-in. This is mainly of
|
||||
interest for libcurl hackers. (added in 7.10.6)
|
||||
.PP
|
||||
\fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
|
||||
has no SSL support, this is NULL.
|
||||
@@ -83,8 +93,6 @@ libcurl has no libz support, this is NULL.
|
||||
names protocols that libcurl supports (using lowercase letters). The protocol
|
||||
names are the same as would be used in URLs. The array is terminated by a NULL
|
||||
entry.
|
||||
|
||||
|
||||
.SH RETURN VALUE
|
||||
A pointer to a curl_version_info_data struct.
|
||||
.SH "SEE ALSO"
|
||||
|
@@ -13,3 +13,26 @@ of environment. You should include files from here using...
|
||||
|
||||
... style and point the compiler's include path to the directory holding the
|
||||
curl subdirectory. It makes it more likely to survive future modifications.
|
||||
|
||||
NOTE FOR LIBCURL HACKERS
|
||||
|
||||
All the include files in this tree are written and intended to be installed on
|
||||
a system that may serve multiple platforms and multiple applications, all
|
||||
using libcurl (possibly even different libcurl installations using different
|
||||
versions). Therefore, all header files in here must obey these rules:
|
||||
|
||||
* They cannot depend on or use configure-generated results from libcurl's or
|
||||
curl's directories. Other applications may not run configure as (lib)curl
|
||||
does, and using platform dependent info here may break other platforms.
|
||||
|
||||
* We cannot assume anything else but very basic compiler features being
|
||||
present. While libcurl requires an ANSI C compiler to build, some of the
|
||||
earlier ANSI compilers clearly can't deal with some preprocessor operators.
|
||||
|
||||
* Newlines must remain unix-style for older compilers' sake.
|
||||
|
||||
* Comments must be written in the old-style /* unnested C-fashion */
|
||||
|
||||
To figure out how to do good and portable checks for features, operating
|
||||
systems or specific hardwarare, a very good resource is Bjorn Reese's
|
||||
collection at http://predef.sf.net/
|
||||
|
@@ -23,23 +23,39 @@
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
/* If you have problems, all libcurl docs and details are found here:
|
||||
http://curl.haxx.se/libcurl/
|
||||
*/
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.10.6"
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||
always follow this syntax:
|
||||
|
||||
0xXXYYZZ
|
||||
|
||||
Where XX, YY and ZZ are the main version, release and patch numbers in
|
||||
hexadecimal. All three numbers are always represented using two digits. 1.2
|
||||
would appear as "0x010200" while version 9.11.7 appears as "0x090b07".
|
||||
|
||||
This 6-digit hexadecimal number does not show pre-release number, and it is
|
||||
always a greater number in a more recent release. It makes comparisons with
|
||||
greater than and less than work.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x070a06
|
||||
|
||||
#include <stdio.h>
|
||||
/* The include stuff here is mainly for time_t! */
|
||||
|
||||
/* The include stuff here below is mainly for time_t! */
|
||||
#ifdef vms
|
||||
# include <types.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
# ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
# else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif /* defined (vms) */
|
||||
|
||||
#ifndef TRUE
|
||||
@@ -55,8 +71,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* stupid #define trick to preserve functionality with older code, but
|
||||
making it use our name space for the future */
|
||||
/* silly trick to preserve functionality with older code, but making it use
|
||||
our name space for the future */
|
||||
#define HttpPost curl_httppost
|
||||
|
||||
struct curl_httppost {
|
||||
@@ -65,15 +81,13 @@ struct curl_httppost {
|
||||
long namelength; /* length of name length */
|
||||
char *contents; /* pointer to allocated data contents */
|
||||
long contentslength; /* length of contents field */
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
char *buffer; /* pointer to allocated buffer contents */
|
||||
long bufferlength; /* length of buffer field */
|
||||
|
||||
char *contenttype; /* Content-Type */
|
||||
struct curl_slist* contentheader; /* list of extra headers for this form */
|
||||
struct curl_httppost *more; /* if one field name has more than one file, this
|
||||
link should link to following files */
|
||||
struct curl_httppost *more; /* if one field name has more than one
|
||||
file, this link should link to following
|
||||
files */
|
||||
long flags; /* as defined below */
|
||||
#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
|
||||
#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */
|
||||
@@ -81,13 +95,12 @@ struct curl_httppost {
|
||||
do not free in formfree */
|
||||
#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
|
||||
do not free in formfree */
|
||||
|
||||
/* CMC: Added support for buffer uploads */
|
||||
#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
|
||||
#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
|
||||
|
||||
char *showfilename; /* The file name to show. If not set, the actual
|
||||
file name will be used (if this is a file part) */
|
||||
char *showfilename; /* The file name to show. If not set, the
|
||||
actual file name will be used (if this
|
||||
is a file part) */
|
||||
};
|
||||
|
||||
typedef int (*curl_progress_callback)(void *clientp,
|
||||
@@ -130,7 +143,7 @@ typedef int (*curl_debug_callback)
|
||||
curl_infotype type, /* what kind of data */
|
||||
char *data, /* points to the data */
|
||||
size_t size, /* size of the data pointed to */
|
||||
void *userp); /* whatever the user please */
|
||||
void *userptr); /* whatever the user please */
|
||||
|
||||
/* All possible error codes from all sorts of curl functions. Future versions
|
||||
may return other values, stay prepared.
|
||||
@@ -207,6 +220,11 @@ typedef enum {
|
||||
CURL_LAST /* never use! */
|
||||
} CURLcode;
|
||||
|
||||
typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
|
||||
void *ssl_ctx, /* actually an
|
||||
OpenSSL SSL_CTX */
|
||||
void *userptr);
|
||||
|
||||
/* Make a spelling correction for the operation timed-out define */
|
||||
#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
|
||||
#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
|
||||
@@ -217,6 +235,14 @@ typedef enum {
|
||||
CURLPROXY_SOCKS5 = 5
|
||||
} curl_proxytype;
|
||||
|
||||
#define CURLAUTH_NONE 0 /* nothing */
|
||||
#define CURLAUTH_BASIC (1<<0) /* Basic (default) */
|
||||
#define CURLAUTH_DIGEST (1<<1) /* Digest */
|
||||
#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */
|
||||
#define CURLAUTH_NTLM (1<<3) /* NTLM */
|
||||
#define CURLAUTH_ANY ~0 /* all types set */
|
||||
#define CURLAUTH_ANYSAFE (~CURLAUTH_BASIC)
|
||||
|
||||
/* this was the error code 50 in 7.7.3 and a few earlier versions, this
|
||||
is no longer used by libcurl but is instead #defined here only to not
|
||||
make programs break */
|
||||
@@ -266,6 +292,12 @@ typedef enum {
|
||||
#define CINIT(name,type,number) CURLOPT_/**/name = type + number
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This macro-mania below setups the CURLOPT_[what] enum, to be used with
|
||||
* curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
|
||||
* word.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/
|
||||
|
||||
@@ -275,24 +307,19 @@ typedef enum {
|
||||
/* The full URL to get/put */
|
||||
CINIT(URL, OBJECTPOINT, 2),
|
||||
|
||||
/* Port number to connect to, if other than default. Specify the CONF_PORT
|
||||
flag in the CURLOPT_FLAGS to activate this */
|
||||
/* Port number to connect to, if other than default. */
|
||||
CINIT(PORT, LONG, 3),
|
||||
|
||||
/* Name of proxy to use. Specify the CONF_PROXY flag in the CURLOPT_FLAGS to
|
||||
activate this */
|
||||
/* Name of proxy to use. */
|
||||
CINIT(PROXY, OBJECTPOINT, 4),
|
||||
|
||||
/* Name and password to use when fetching. Specify the CONF_USERPWD flag in
|
||||
the CURLOPT_FLAGS to activate this */
|
||||
/* "name:password" to use when fetching. */
|
||||
CINIT(USERPWD, OBJECTPOINT, 5),
|
||||
|
||||
/* Name and password to use with Proxy. Specify the CONF_PROXYUSERPWD
|
||||
flag in the CURLOPT_FLAGS to activate this */
|
||||
/* "name:password" to use with proxy. */
|
||||
CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
|
||||
|
||||
/* Range to get, specified as an ASCII string. Specify the CONF_RANGE flag
|
||||
in the CURLOPT_FLAGS to activate this */
|
||||
/* Range to get, specified as an ASCII string. */
|
||||
CINIT(RANGE, OBJECTPOINT, 7),
|
||||
|
||||
/* not used */
|
||||
@@ -413,7 +440,6 @@ typedef enum {
|
||||
as described elsewhere. */
|
||||
CINIT(WRITEINFO, OBJECTPOINT, 40),
|
||||
|
||||
/* Previous FLAG bits */
|
||||
CINIT(VERBOSE, LONG, 41), /* talk a lot */
|
||||
CINIT(HEADER, LONG, 42), /* throw the header out too */
|
||||
CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
|
||||
@@ -629,6 +655,20 @@ typedef enum {
|
||||
attempted before the good old traditional PORT command. */
|
||||
CINIT(FTP_USE_EPRT, LONG, 106),
|
||||
|
||||
/* Set this to a bitmask value to enable the particular authentications
|
||||
methods you like. Use this in combination with CURLOPT_USERPWD.
|
||||
Note that setting multiple bits may cause extra network round-trips. */
|
||||
CINIT(HTTPAUTH, LONG, 107),
|
||||
|
||||
/* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
|
||||
in second argument. The function must be matching the
|
||||
curl_ssl_ctx_callback proto. */
|
||||
CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
|
||||
|
||||
/* Set the userdata for the ssl context callback function's third
|
||||
argument */
|
||||
CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -697,9 +737,9 @@ typedef enum {
|
||||
#endif
|
||||
|
||||
|
||||
/* These functions are in the libcurl, they're here for portable reasons and
|
||||
they are used by the 'curl' client. They really should be moved to some kind
|
||||
of "portability library" since it has nothing to do with file transfers and
|
||||
/* These functions are in libcurl, they're here for portable reasons and they
|
||||
are used by the 'curl' client. They really should be moved to some kind of
|
||||
"portability library" since it has nothing to do with file transfers and
|
||||
might be usable to other programs...
|
||||
|
||||
NOTE: they return TRUE if the strings match *case insensitively*.
|
||||
@@ -707,9 +747,12 @@ typedef enum {
|
||||
extern int (curl_strequal)(const char *s1, const char *s2);
|
||||
extern int (curl_strnequal)(const char *s1, const char *s2, size_t n);
|
||||
|
||||
/* DEPRECATED function to build formdata */
|
||||
#ifdef CURL_OLDSTYLE
|
||||
/* DEPRECATED function to build formdata. Stop using this, it will cease
|
||||
to exist. */
|
||||
int curl_formparse(char *, struct curl_httppost **,
|
||||
struct curl_httppost **_post);
|
||||
#endif
|
||||
|
||||
/* name is uppercase CURLFORM_<name> */
|
||||
#ifdef CFINIT
|
||||
@@ -788,47 +831,122 @@ typedef enum {
|
||||
CURL_FORMADD_LAST /* last */
|
||||
} CURLFORMcode;
|
||||
|
||||
/*
|
||||
* NAME curl_formadd()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Pretty advanved function for building multi-part formposts. Each invoke
|
||||
* adds one part that together construct a full post. Then use
|
||||
* CURLOPT_HTTPPOST to send it off to libcurl.
|
||||
*/
|
||||
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||
struct curl_httppost **last_post,
|
||||
...);
|
||||
|
||||
/* cleanup a form: */
|
||||
/*
|
||||
* NAME curl_formfree()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Free a multipart formpost previously built with curl_formadd().
|
||||
*/
|
||||
void curl_formfree(struct curl_httppost *form);
|
||||
|
||||
/* Unix and Win32 getenv function call, this returns a malloc()'ed string that
|
||||
MUST be free()ed after usage is complete. */
|
||||
/*
|
||||
* NAME curl_getenv()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Returns a malloc()'ed string that MUST be curl_free()ed after usage is
|
||||
* complete.
|
||||
*/
|
||||
char *curl_getenv(const char *variable);
|
||||
|
||||
/* Returns a static ascii string of the libcurl version. */
|
||||
/*
|
||||
* NAME curl_version()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Returns a static ascii string of the libcurl version.
|
||||
*/
|
||||
char *curl_version(void);
|
||||
|
||||
/* Escape and unescape URL encoding in strings. The functions return a new
|
||||
* allocated string or NULL if an error occurred. */
|
||||
/*
|
||||
* NAME curl_escape()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Escapes URL strings (converts all letters consider illegal in URLs to their
|
||||
* %XX versions). This function returns a new allocated string or NULL if an
|
||||
* error occurred.
|
||||
*/
|
||||
char *curl_escape(const char *string, int length);
|
||||
|
||||
/*
|
||||
* NAME curl_unescape()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Unescapes URL encoding in strings (converts all %XX codes to their 8bit
|
||||
* versions). This function returns a new allocated string or NULL if an error
|
||||
* occurred.
|
||||
*/
|
||||
char *curl_unescape(const char *string, int length);
|
||||
/* 20020912 WJM. Provide for a de-allocation in the same translation unit
|
||||
that did the allocation. Added in libcurl 7.10 */
|
||||
|
||||
/*
|
||||
* NAME curl_free()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Provided for de-allocation in the same translation unit that did the
|
||||
* allocation. Added in libcurl 7.10
|
||||
*/
|
||||
void curl_free(void *p);
|
||||
|
||||
/* curl_global_init() should be invoked exactly once for each application that
|
||||
uses libcurl */
|
||||
/*
|
||||
* NAME curl_global_init()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* curl_global_init() should be invoked exactly once for each application that
|
||||
* uses libcurl
|
||||
*/
|
||||
CURLcode curl_global_init(long flags);
|
||||
|
||||
/* curl_global_cleanup() should be invoked exactly once for each application
|
||||
that uses libcurl */
|
||||
/*
|
||||
* NAME curl_global_cleanup()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* curl_global_cleanup() should be invoked exactly once for each application
|
||||
* that uses libcurl
|
||||
*/
|
||||
void curl_global_cleanup(void);
|
||||
|
||||
/* This is the version number */
|
||||
#define LIBCURL_VERSION "7.10.5"
|
||||
#define LIBCURL_VERSION_NUM 0x070a05
|
||||
|
||||
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
||||
struct curl_slist {
|
||||
char *data;
|
||||
struct curl_slist *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* NAME curl_slist_append()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Appends a string to a linked list. If no list exists, it will be created
|
||||
* first. Returns the new list, after appending.
|
||||
*/
|
||||
struct curl_slist *curl_slist_append(struct curl_slist *, const char *);
|
||||
|
||||
/*
|
||||
* NAME curl_slist_free_all()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* free a previously built curl_slist.
|
||||
*/
|
||||
void curl_slist_free_all(struct curl_slist *);
|
||||
|
||||
/*
|
||||
@@ -996,8 +1114,18 @@ typedef struct {
|
||||
#define CURL_VERSION_KERBEROS4 (1<<1)
|
||||
#define CURL_VERSION_SSL (1<<2)
|
||||
#define CURL_VERSION_LIBZ (1<<3)
|
||||
#define CURL_VERSION_NTLM (1<<4)
|
||||
#define CURL_VERSION_GSSNEGOTIATE (1<<5)
|
||||
#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */
|
||||
|
||||
/* returns a pointer to a static copy of the version info struct */
|
||||
/*
|
||||
* NAME curl_version_info()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This function returns a pointer to a static copy of the version info
|
||||
* struct. See above.
|
||||
*/
|
||||
curl_version_info_data *curl_version_info(CURLversion);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -45,11 +45,23 @@
|
||||
file descriptors simultaneous easily.
|
||||
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(WIN32)
|
||||
/* Chris Lewis mentioned that he doesn't get WIN32 defined, only _WIN32 so we
|
||||
make this adjustment to catch this. */
|
||||
#define WIN32 1
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||
#include <winsock.h>
|
||||
#else
|
||||
|
||||
#ifdef _AIX
|
||||
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
|
||||
libc5-based Linux systems. Only include it on system that are known to
|
||||
require it! */
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
@@ -23,9 +23,7 @@
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
size_t fread (void *, size_t, size_t, FILE *);
|
||||
size_t fwrite (const void *, size_t, size_t, FILE *);
|
||||
|
@@ -7,7 +7,8 @@ AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
|
||||
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp \
|
||||
curllib.dsw config-vms.h config-win32.h config-riscos.h config-mac.h \
|
||||
config.h.in ca-bundle.crt README.encoding README.memoryleak
|
||||
config.h.in ca-bundle.crt README.encoding README.memoryleak \
|
||||
makefile.dj config.dj
|
||||
|
||||
lib_LTLIBRARIES = libcurl.la
|
||||
|
||||
@@ -66,16 +67,29 @@ getpass.c netrc.c telnet.h getinfo.c getinfo.h transfer.c strequal.c \
|
||||
strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c \
|
||||
memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c strtok.h \
|
||||
connect.c connect.h llist.c llist.h hash.c hash.h multi.c \
|
||||
content_encoding.c content_encoding.h share.c share.h
|
||||
content_encoding.c content_encoding.h share.c share.h http_digest.c \
|
||||
md5.c md5.h http_digest.h http_negotiate.c http_negotiate.h \
|
||||
http_ntlm.c http_ntlm.h ca-bundle.h
|
||||
|
||||
noinst_HEADERS = setup.h transfer.h
|
||||
|
||||
BUILT_SOURCES = $(srcdir)/getdate.c $(srcdir)/ca-bundle.h
|
||||
|
||||
# Say $(srcdir), so GNU make does not report an ambiguity with the .y.c rule.
|
||||
$(srcdir)/getdate.c: getdate.y
|
||||
cd $(srcdir) && \
|
||||
$(YACC) $(YFLAGS) getdate.y; \
|
||||
mv -f y.tab.c getdate.c
|
||||
|
||||
$(srcdir)/ca-bundle.h: Makefile.in Makefile
|
||||
cd $(srcdir) && \
|
||||
echo "/* The file is generated automaticly */" > $@
|
||||
if CABUNDLE
|
||||
echo '#define CURL_CA_BUNDLE @CURL_CA_BUNDLE@' >> $@
|
||||
else
|
||||
echo '#undef CURL_CA_BUNDLE /* unknown */' >> $@
|
||||
endif
|
||||
|
||||
install-data-hook:
|
||||
@if test -n "@CURL_CA_BUNDLE@"; then \
|
||||
$(mkinstalldirs) `dirname $(DESTDIR)@CURL_CA_BUNDLE@`; \
|
||||
@@ -85,4 +99,4 @@ install-data-hook:
|
||||
# this hook is mainly for non-unix systems to build even if configure
|
||||
# isn't run
|
||||
dist-hook:
|
||||
cp $(srcdir)/ca-bundle.h.in $(distdir)/ca-bundle.h
|
||||
echo "/* ca bundle path set in here*/" > $(distdir)/ca-bundle.h
|
||||
|
@@ -35,15 +35,19 @@ COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
|
||||
libcurl_a_LIBRARIES = libcurl.a
|
||||
|
||||
libcurl_a_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c base64.c \
|
||||
file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h progress.h \
|
||||
cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.h sendf.h url.c dict.c \
|
||||
ftp.h if2ip.c speedcheck.c url.h dict.h getdate.c if2ip.h speedcheck.h \
|
||||
urldata.h transfer.c getdate.h ldap.c ssluse.c version.c transfer.h getenv.c \
|
||||
ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c \
|
||||
telnet.h getinfo.c strequal.c strequal.h easy.c security.h \
|
||||
security.c krb4.h krb4.c memdebug.h memdebug.c inet_ntoa_r.h http_chunks.h http_chunks.c \
|
||||
strtok.c connect.c hash.c llist.c multi.c share.c share.h\
|
||||
content_encoding.h content_encoding.c
|
||||
file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h \
|
||||
progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c \
|
||||
http.h sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h \
|
||||
dict.h getdate.c if2ip.h speedcheck.h urldata.h transfer.c getdate.h \
|
||||
ldap.c ssluse.c version.c transfer.h getenv.c \
|
||||
ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h \
|
||||
getpass.c netrc.c telnet.h getinfo.c strequal.c strequal.h easy.c \
|
||||
security.h security.c krb4.h krb4.c memdebug.h memdebug.c \
|
||||
inet_ntoa_r.h http_chunks.h http_chunks.c \
|
||||
strtok.c connect.c hash.c llist.c multi.c share.c share.h \
|
||||
content_encoding.h content_encoding.c http_digest.h http_digest.c \
|
||||
http_negotiate.c http_negotiate.h http_ntlm.c http_ntlm.h md5.h \
|
||||
md5.c
|
||||
|
||||
libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
|
||||
formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \
|
||||
@@ -51,7 +55,7 @@ libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
|
||||
getenv.o escape.o mprintf.o telnet.o getpass.o netrc.o getinfo.o \
|
||||
strequal.o easy.o security.o krb4.o memdebug.o http_chunks.o \
|
||||
strtok.o connect.o hash.o llist.o multi.o share.o \
|
||||
content_encoding.o
|
||||
content_encoding.o http_digest.o http_negotiate.o http_ntlm.o md5.o
|
||||
|
||||
LIBRARIES = $(libcurl_a_LIBRARIES)
|
||||
SOURCES = $(libcurl_a_SOURCES)
|
||||
|
@@ -202,7 +202,9 @@ X_OBJS= \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\llist.obj \
|
||||
$(DIROBJ)\share.obj \
|
||||
$(DIROBJ)\multi.obj
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\md5.obj
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
@@ -224,3 +226,6 @@ clean:
|
||||
-@erase $(DIROBJ)\*.obj
|
||||
-@erase vc60.idb
|
||||
-@erase vc60.pch
|
||||
|
||||
getdate.c: getdate.c.cvs
|
||||
copy getdate.c.cvs getdate.c
|
||||
|
@@ -17,7 +17,7 @@ Single-threaded
|
||||
|
||||
Build
|
||||
|
||||
Rebuild libcurl with -DMALLOCDEBUG (usually, rerunning configure with
|
||||
Rebuild libcurl with -DCURLDEBUG (usually, rerunning configure with
|
||||
--enable-debug fixes this). 'make clean' first, then 'make' so that all
|
||||
files actually are rebuilt properly. It will also make sense to build
|
||||
libcurl with the debug option (usually -g to the compiler) so that debugging
|
||||
|
24
lib/base64.c
24
lib/base64.c
@@ -42,7 +42,7 @@
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -220,6 +220,8 @@ int main(int argc, char **argv, char **envp)
|
||||
#ifdef TEST_DECODE
|
||||
/* decoding test harness. Read in a base64 string from stdin and write out the
|
||||
* length returned by Curl_base64_decode, followed by the decoded data itself
|
||||
*
|
||||
* gcc -DTEST_DECODE base64.c -o base64 mprintf.o memdebug.o
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -232,13 +234,31 @@ int main(int argc, char **argv, char **envp)
|
||||
int base64Len;
|
||||
unsigned char *data;
|
||||
int dataLen;
|
||||
int i, j;
|
||||
|
||||
base64 = (char *)suck(&base64Len);
|
||||
data = (unsigned char *)malloc(base64Len * 3/4 + 8);
|
||||
dataLen = Curl_base64_decode(base64, data);
|
||||
|
||||
fprintf(stderr, "%d\n", dataLen);
|
||||
fwrite(data,1,dataLen,stdout);
|
||||
|
||||
for(i=0; i < dataLen; i+=0x10) {
|
||||
printf("0x%02x: ", i);
|
||||
for(j=0; j < 0x10; j++)
|
||||
if((j+i) < dataLen)
|
||||
printf("%02x ", data[i+j]);
|
||||
else
|
||||
printf(" ");
|
||||
|
||||
printf(" | ");
|
||||
|
||||
for(j=0; j < 0x10; j++)
|
||||
if((j+i) < dataLen)
|
||||
printf("%c", isgraph(data[i+j])?data[i+j]:'.');
|
||||
else
|
||||
break;
|
||||
puts("");
|
||||
}
|
||||
|
||||
free(base64); free(data);
|
||||
return 0;
|
||||
|
92
lib/config.dj
Normal file
92
lib/config.dj
Normal file
@@ -0,0 +1,92 @@
|
||||
#ifndef _CURL_CONFIG_DJGPP_H
|
||||
#define _CURL_CONFIG_DJGPP_H
|
||||
|
||||
#define OS "djgpp"
|
||||
#define PACKAGE "curl"
|
||||
|
||||
#define CURL_CA_BUNDLE "/dev/env/CURL_CA_BUNDLE"
|
||||
|
||||
#if (DJGPP_MINOR >= 4)
|
||||
/* #define HAVE_DLOPEN 1 maybe not (DXE3) */
|
||||
#endif
|
||||
|
||||
#if 1 /* use ioctlsocket() via fsext'ed fcntl() */
|
||||
#define HAVE_O_NONBLOCK 1
|
||||
#else
|
||||
#define HAVE_IOCTLSOCKET 1
|
||||
#endif
|
||||
|
||||
#define HAVE_ALARM 1
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
#define HAVE_CLOSESOCKET 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
#define HAVE_GETHOSTBYADDR 1
|
||||
#define HAVE_GETHOSTNAME 1
|
||||
#define HAVE_GETPASS 1
|
||||
#define HAVE_GETSERVBYNAME 1
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
#define HAVE_INET_ADDR 1
|
||||
#define HAVE_INET_NTOA 1
|
||||
#define HAVE_IO_H 1
|
||||
#define HAVE_MALLOC_H 1
|
||||
#define HAVE_MEMORY_H 1
|
||||
#define HAVE_NETDB_H 1
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
#define HAVE_NET_IF_H 1
|
||||
#define HAVE_PERROR 1
|
||||
#define HAVE_SELECT 1
|
||||
#define HAVE_SETJMP_H 1
|
||||
#define HAVE_SETVBUF 1
|
||||
#define HAVE_SIGNAL 1
|
||||
#define HAVE_SIGACTION 1
|
||||
#define HAVE_SIGSETJMP 1
|
||||
#define HAVE_SOCKET 1
|
||||
#define HAVE_STRCASECMP 1
|
||||
#define HAVE_STRDUP 1
|
||||
#define HAVE_STRFTIME 1
|
||||
#define HAVE_STRICMP 1
|
||||
#define HAVE_STRSTR 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#define HAVE_TERMIOS_H 1
|
||||
#define HAVE_TIME_H 1
|
||||
#define HAVE_UNAME 1
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_VPRINTF 1
|
||||
|
||||
#define RETSIGTYPE void
|
||||
#define SIZEOF_LONG_DOUBLE 16
|
||||
#define SIZEOF_LONG_LONG 8
|
||||
#define STDC_HEADERS 1
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
#define BSD
|
||||
#define USE_ZLIB
|
||||
|
||||
/* #define MALLOCDEBUG */
|
||||
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H /* on cmd-line */
|
||||
#define HAVE_OPENSSL_X509_H 1
|
||||
#define HAVE_OPENSSL_SSL_H 1
|
||||
#define HAVE_OPENSSL_RSA_H 1
|
||||
#define HAVE_OPENSSL_PEM_H 1
|
||||
#define HAVE_OPENSSL_ERR_H 1
|
||||
#define HAVE_OPENSSL_CRYPTO_H 1
|
||||
#define HAVE_LIBSSL 1
|
||||
#define HAVE_LIBCRYPTO 1
|
||||
#define OPENSSL_NO_KRB5 1
|
||||
#endif
|
||||
|
||||
#define in_addr_t u_long
|
||||
#define socklen_t int
|
||||
#define ssize_t int
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tcp.h> /* Watt-32 API */
|
||||
|
||||
#undef word
|
||||
|
||||
#endif /* _CURL_CONFIG_DJGPP_H */
|
||||
|
@@ -77,7 +77,7 @@
|
||||
#include "if2ip.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
|
@@ -92,7 +92,7 @@ Example set of cookies:
|
||||
#include "strtok.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
|
@@ -389,6 +389,22 @@ SOURCE=.\url.h
|
||||
|
||||
SOURCE=.\urldata.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\http_digest.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\md5.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\http_digest.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\md5.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
|
@@ -44,7 +44,6 @@
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
@@ -46,7 +46,6 @@
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
23
lib/escape.c
23
lib/escape.c
@@ -33,7 +33,7 @@
|
||||
#include <string.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -79,6 +79,10 @@ char *curl_escape(const char *string, int length)
|
||||
return ns;
|
||||
}
|
||||
|
||||
#define ishex(in) ((in >= 'a' && in <= 'f') || \
|
||||
(in >= 'A' && in <= 'F') || \
|
||||
(in >= '0' && in <= '9'))
|
||||
|
||||
char *curl_unescape(const char *string, int length)
|
||||
{
|
||||
int alloc = (length?length:(int)strlen(string))+1;
|
||||
@@ -93,14 +97,20 @@ char *curl_unescape(const char *string, int length)
|
||||
|
||||
while(--alloc > 0) {
|
||||
in = *string;
|
||||
if('%' == in) {
|
||||
/* encoded part */
|
||||
if(sscanf(string+1, "%02X", &hex)) {
|
||||
if(('%' == in) && ishex(string[1]) && ishex(string[2])) {
|
||||
/* this is two hexadecimal digits following a '%' */
|
||||
char hexstr[3];
|
||||
char *ptr;
|
||||
hexstr[0] = string[1];
|
||||
hexstr[1] = string[2];
|
||||
hexstr[2] = 0;
|
||||
|
||||
hex = strtol(hexstr, &ptr, 16);
|
||||
|
||||
in = hex;
|
||||
string+=2;
|
||||
alloc-=2;
|
||||
}
|
||||
}
|
||||
|
||||
ns[index++] = in;
|
||||
string++;
|
||||
@@ -109,6 +119,9 @@ char *curl_unescape(const char *string, int length)
|
||||
return ns;
|
||||
}
|
||||
|
||||
/* For operating systems/environments that use different malloc/free
|
||||
ssystems for the app and for this library, we provide a free that uses
|
||||
the library's memory system */
|
||||
void curl_free(void *p)
|
||||
{
|
||||
free(p);
|
||||
|
@@ -48,7 +48,6 @@
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -88,7 +87,7 @@
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
|
@@ -124,7 +124,7 @@ Content-Disposition: form-data; name="FILECONTENT"
|
||||
#include "strequal.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
|
54
lib/ftp.c
54
lib/ftp.c
@@ -94,7 +94,7 @@
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -409,9 +409,9 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
|
||||
/* get some initial data into the ftp struct */
|
||||
ftp->bytecountp = &conn->bytecount;
|
||||
|
||||
/* no need to duplicate them, the data struct won't change */
|
||||
ftp->user = data->state.user;
|
||||
ftp->passwd = data->state.passwd;
|
||||
/* no need to duplicate them, this connectdata struct won't change */
|
||||
ftp->user = conn->user;
|
||||
ftp->passwd = conn->passwd;
|
||||
ftp->response_time = 3600; /* set default response time-out */
|
||||
|
||||
if (data->set.tunnel_thru_httpproxy) {
|
||||
@@ -512,7 +512,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
|
||||
/* we may need to issue a KAUTH here to have access to the files
|
||||
* do it if user supplied a password
|
||||
*/
|
||||
if(data->state.passwd && *data->state.passwd) {
|
||||
if(conn->passwd && *conn->passwd) {
|
||||
result = Curl_krb_kauth(conn);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -1184,7 +1184,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
return result;
|
||||
|
||||
if (ftpcode != 200) {
|
||||
failf(data, "Server does not grok %s", *modep);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@@ -1193,6 +1192,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
|
||||
if (!*modep) {
|
||||
sclose(portsock);
|
||||
failf(data, "PORT command attempts failed");
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
/* we set the secondary socket variable to this for now, it
|
||||
@@ -1930,10 +1930,16 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
if(dirlist && (ftpcode == 450)) {
|
||||
/* simply no matching files */
|
||||
ftp->no_transfer = TRUE; /* don't think we should download anything */
|
||||
}
|
||||
else {
|
||||
failf(data, "%s", buf+4);
|
||||
return CURLE_FTP_COULDNT_RETR_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* end of transfer */
|
||||
@@ -2055,7 +2061,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
||||
struct tm buffer;
|
||||
tm = (struct tm *)localtime_r(&data->info.filetime, &buffer);
|
||||
#else
|
||||
tm = localtime((unsigned long *)&data->info.filetime);
|
||||
tm = localtime(&data->info.filetime);
|
||||
#endif
|
||||
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
|
||||
strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n",
|
||||
@@ -2128,17 +2134,28 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
||||
|
||||
/* parse the URL path into separate path components */
|
||||
while((slash_pos=strchr(cur_pos, '/'))) {
|
||||
/* 1 or 0 to indicate absolute directory */
|
||||
bool absolute_dir = (cur_pos - conn->ppath > 0) && (path_part == 0);
|
||||
|
||||
/* seek out the next path component */
|
||||
if (0 == slash_pos-cur_pos) /* empty path component, like "x//y" */
|
||||
ftp->dirs[path_part] = strdup(""); /* empty string */
|
||||
else
|
||||
ftp->dirs[path_part] = curl_unescape(cur_pos,slash_pos-cur_pos);
|
||||
if (slash_pos-cur_pos) {
|
||||
/* we skip empty path components, like "x//y" since the FTP command CWD
|
||||
requires a parameter and a non-existant parameter a) doesn't work on
|
||||
many servers and b) has no effect on the others. */
|
||||
ftp->dirs[path_part] = curl_unescape(cur_pos - absolute_dir,
|
||||
slash_pos - cur_pos + absolute_dir);
|
||||
|
||||
if (!ftp->dirs[path_part]) { /* run out of memory ... */
|
||||
failf(data, "no memory");
|
||||
retcode = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cur_pos = slash_pos + 1; /* jump to the rest of the string */
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!retcode) {
|
||||
cur_pos = slash_pos + 1; /* jump to the rest of the string */
|
||||
if(++path_part >= (CURL_MAX_FTP_DIRDEPTH-1)) {
|
||||
/* too deep, we need the last entry to be kept NULL at all
|
||||
@@ -2180,17 +2197,20 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
||||
if(CURLE_OK == retcode) {
|
||||
if(connected)
|
||||
retcode = Curl_ftp_nextconnect(conn);
|
||||
else {
|
||||
if(ftp->no_transfer) {
|
||||
|
||||
if(retcode && (conn->secondarysocket >= 0)) {
|
||||
/* Failure detected, close the second socket if it was created already */
|
||||
sclose(conn->secondarysocket);
|
||||
conn->secondarysocket = -1;
|
||||
}
|
||||
|
||||
if(ftp->no_transfer)
|
||||
/* no data to transfer */
|
||||
retcode=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
}
|
||||
else {
|
||||
else if(!connected)
|
||||
/* since we didn't connect now, we want do_more to get called */
|
||||
conn->bits.do_more = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@
|
||||
#include <unixlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#endif
|
||||
|
||||
/* Make this the last #include */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
|
@@ -89,7 +89,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -99,7 +99,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
||||
char infp_fclose = 0;
|
||||
FILE *outfp;
|
||||
RETSIGTYPE (*sigint)();
|
||||
#ifndef __EMX__
|
||||
#ifdef SIGTSTP
|
||||
RETSIGTYPE (*sigtstp)();
|
||||
#endif
|
||||
size_t bytes_read;
|
||||
@@ -117,9 +117,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
||||
#endif
|
||||
|
||||
sigint = signal(SIGINT, SIG_IGN);
|
||||
/* 20000318 mgs
|
||||
* this is needed by the emx system, SIGTSTP is not a supported signal */
|
||||
#ifndef __EMX__
|
||||
#ifdef SIGTSTP
|
||||
sigtstp = signal(SIGTSTP, SIG_IGN);
|
||||
#endif
|
||||
|
||||
@@ -181,7 +179,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
||||
#endif
|
||||
|
||||
signal(SIGINT, sigint);
|
||||
#ifndef __EMX__
|
||||
#ifdef SIGTSTP
|
||||
signal(SIGTSTP, sigtstp);
|
||||
#endif
|
||||
|
||||
|
@@ -29,7 +29,7 @@
|
||||
#include "hash.h"
|
||||
#include "llist.h"
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
/* this must be the last include file */
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
27
lib/hostip.c
27
lib/hostip.c
@@ -74,7 +74,7 @@
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -192,7 +192,7 @@ hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
|
||||
hostcache_timestamp_remove);
|
||||
}
|
||||
|
||||
#if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST)
|
||||
#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
|
||||
/* Called from Curl_done() to check that there's no DNS cache entry with
|
||||
a non-zero counter left. */
|
||||
void Curl_scan_cache_used(void *user, void *ptr)
|
||||
@@ -252,9 +252,7 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
|
||||
return NULL;
|
||||
|
||||
if(data->share)
|
||||
{
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
}
|
||||
|
||||
/* See if its already in our dns cache */
|
||||
dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1);
|
||||
@@ -282,7 +280,7 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
|
||||
|
||||
dns->timestamp = now;
|
||||
dns->inuse++; /* mark entry as in-use */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
dns->entry_id = entry_id;
|
||||
#endif
|
||||
|
||||
@@ -297,14 +295,13 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
|
||||
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
||||
{
|
||||
if(data->share)
|
||||
{
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
}
|
||||
|
||||
dns->inuse--;
|
||||
|
||||
if(data->share)
|
||||
{
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -337,7 +334,7 @@ void Curl_freednsinfo(void *freethis)
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
/* These two are strictly for memory tracing and are using the same
|
||||
* style as the family otherwise present in memdebug.c. I put these ones
|
||||
* here since they require a bunch of struct types I didn't wanna include
|
||||
@@ -455,18 +452,22 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
|
||||
copy->h_aliases = (char**)bufptr;
|
||||
|
||||
/* Figure out how many aliases there are */
|
||||
for (i = 0; orig->h_aliases[i] != NULL; ++i);
|
||||
for (i = 0; orig->h_aliases && orig->h_aliases[i]; ++i);
|
||||
|
||||
/* Reserve room for the array */
|
||||
bufptr += (i + 1) * sizeof(char*);
|
||||
|
||||
/* Clone all known aliases */
|
||||
if(orig->h_aliases) {
|
||||
for(i = 0; (str = orig->h_aliases[i]); i++) {
|
||||
len = strlen(str) + 1;
|
||||
strncpy(bufptr, str, len);
|
||||
copy->h_aliases[i] = bufptr;
|
||||
bufptr += len;
|
||||
}
|
||||
}
|
||||
/* if(!orig->h_aliases) i was already set to 0 */
|
||||
|
||||
/* Terminate the alias list with a NULL */
|
||||
copy->h_aliases[i] = NULL;
|
||||
|
||||
@@ -627,7 +628,7 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
|
||||
step_size+=200;
|
||||
}
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
||||
#endif
|
||||
|
||||
@@ -677,7 +678,7 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
|
||||
if(!h) /* failure */
|
||||
res=1;
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
||||
#endif
|
||||
if(!res) {
|
||||
|
@@ -41,7 +41,7 @@ struct Curl_dns_entry {
|
||||
time_t timestamp;
|
||||
long inuse; /* use-counter, make very sure you decrease this
|
||||
when you're done using the address you received */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
char *entry_id;
|
||||
#endif
|
||||
};
|
||||
@@ -70,7 +70,7 @@ void Curl_freeaddrinfo(Curl_addrinfo *freeaddr);
|
||||
/* free cached name info */
|
||||
void Curl_freednsinfo(void *freethis);
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
void curl_freeaddrinfo(struct addrinfo *freethis,
|
||||
int line, const char *source);
|
||||
int curl_getaddrinfo(char *hostname, char *service,
|
||||
|
179
lib/http.c
179
lib/http.c
@@ -54,7 +54,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/resource.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -89,12 +88,15 @@
|
||||
#include "cookie.h"
|
||||
#include "strequal.h"
|
||||
#include "ssluse.h"
|
||||
#include "http_digest.h"
|
||||
#include "http_ntlm.h"
|
||||
#include "http_negotiate.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -190,6 +192,7 @@ CURLcode add_buffer_send(send_buffer *in,
|
||||
char *ptr;
|
||||
int size;
|
||||
struct HTTP *http = conn->proto.http;
|
||||
int sendsize;
|
||||
|
||||
/* The looping below is required since we use non-blocking sockets, but due
|
||||
to the circumstances we will just loop and try again and again etc */
|
||||
@@ -197,7 +200,28 @@ CURLcode add_buffer_send(send_buffer *in,
|
||||
ptr = in->buffer;
|
||||
size = in->size_used;
|
||||
|
||||
res = Curl_write(conn, sockfd, ptr, size, &amount);
|
||||
if(conn->protocol & PROT_HTTPS) {
|
||||
/* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
|
||||
when we speak HTTPS, as if only a fraction of it is sent now, this data
|
||||
needs to fit into the normal read-callback buffer later on and that
|
||||
buffer is using this size.
|
||||
*/
|
||||
|
||||
sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
|
||||
|
||||
/* OpenSSL is very picky and we must send the SAME buffer pointer to the
|
||||
library when we attempt to re-send this buffer. Sending the same data
|
||||
is not enough, we must use the exact same address. For this reason, we
|
||||
must copy the data to the uploadbuffer first, since that is the buffer
|
||||
we will be using if this send is retried later.
|
||||
*/
|
||||
memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
|
||||
ptr = conn->data->state.uploadbuffer;
|
||||
}
|
||||
else
|
||||
sendsize = size;
|
||||
|
||||
res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
|
||||
|
||||
if(CURLE_OK == res) {
|
||||
|
||||
@@ -213,7 +237,8 @@ CURLcode add_buffer_send(send_buffer *in,
|
||||
and wait until it might work again. */
|
||||
|
||||
size -= amount;
|
||||
ptr += amount;
|
||||
|
||||
ptr = in->buffer + amount;
|
||||
|
||||
/* backup the currently set pointers */
|
||||
http->backup.fread = conn->fread;
|
||||
@@ -591,11 +616,15 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
||||
conn->fread = data->set.fread; /* restore */
|
||||
conn->fread_in = data->set.in; /* restore */
|
||||
|
||||
if (http == NULL)
|
||||
return CURLE_OK;
|
||||
|
||||
if(http->send_buffer) {
|
||||
send_buffer *buff = http->send_buffer;
|
||||
|
||||
free(buff->buffer);
|
||||
free(buff);
|
||||
http->send_buffer = NULL; /* cleaer the pointer */
|
||||
}
|
||||
|
||||
if(HTTPREQ_POST_FORM == data->set.httpreq) {
|
||||
@@ -616,6 +645,25 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode Curl_output_basic(struct connectdata *conn)
|
||||
{
|
||||
char *authorization;
|
||||
struct SessionHandle *data=conn->data;
|
||||
|
||||
sprintf(data->state.buffer, "%s:%s", conn->user, conn->passwd);
|
||||
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
|
||||
&authorization) >= 0) {
|
||||
if(conn->allocptr.userpwd)
|
||||
free(conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012",
|
||||
authorization);
|
||||
free(authorization);
|
||||
}
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_http(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data=conn->data;
|
||||
@@ -627,6 +675,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
char *host = conn->name;
|
||||
const char *te = ""; /* tranfer-encoding */
|
||||
char *ptr;
|
||||
char *request;
|
||||
|
||||
if(!conn->proto.http) {
|
||||
/* Only allocate this struct if we don't already have it! */
|
||||
@@ -648,6 +697,13 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
data->set.httpreq = HTTPREQ_PUT;
|
||||
}
|
||||
|
||||
request = data->set.customrequest?
|
||||
data->set.customrequest:
|
||||
(data->set.no_body?(char *)"HEAD":
|
||||
((HTTPREQ_POST == data->set.httpreq) ||
|
||||
(HTTPREQ_POST_FORM == data->set.httpreq))?(char *)"POST":
|
||||
(HTTPREQ_PUT == data->set.httpreq)?(char *)"PUT":(char *)"GET");
|
||||
|
||||
/* The User-Agent string has been built in url.c already, because it might
|
||||
have been used in the proxy connect, but if we have got a header with
|
||||
the user-agent string specified, we erase the previously made string
|
||||
@@ -657,27 +713,50 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
conn->allocptr.uagent=NULL;
|
||||
}
|
||||
|
||||
if((conn->bits.user_passwd) && !checkheaders(data, "Authorization:")) {
|
||||
char *authorization;
|
||||
|
||||
/* To prevent the user+password to get sent to other than the original
|
||||
host due to a location-follow, we do some weirdo checks here */
|
||||
if(!data->state.this_is_a_follow ||
|
||||
!data->state.auth_host ||
|
||||
curl_strequal(data->state.auth_host, conn->hostname) ||
|
||||
data->set.http_disable_hostname_check_before_authentication) {
|
||||
sprintf(data->state.buffer, "%s:%s",
|
||||
data->state.user, data->state.passwd);
|
||||
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
|
||||
&authorization) >= 0) {
|
||||
if(conn->allocptr.userpwd)
|
||||
free(conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012",
|
||||
authorization);
|
||||
free(authorization);
|
||||
|
||||
#ifdef GSSAPI
|
||||
if((data->state.authwant == CURLAUTH_GSSNEGOTIATE) &&
|
||||
data->state.negotiate.context &&
|
||||
!GSS_ERROR(data->state.negotiate.status)) {
|
||||
result = Curl_output_negotiate(conn);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_SSLEAY
|
||||
if(data->state.authwant == CURLAUTH_NTLM) {
|
||||
result = Curl_output_ntlm(conn, FALSE);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if((data->state.authwant == CURLAUTH_DIGEST) &&
|
||||
data->state.digest.nonce) {
|
||||
result = Curl_output_digest(conn,
|
||||
(unsigned char *)request,
|
||||
(unsigned char *)ppath);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else if((data->state.authwant == CURLAUTH_BASIC) && /* Basic */
|
||||
conn->bits.user_passwd &&
|
||||
!checkheaders(data, "Authorization:")) {
|
||||
result = Curl_output_basic(conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if((data->change.referer) && !checkheaders(data, "Referer:")) {
|
||||
if(conn->allocptr.ref)
|
||||
free(conn->allocptr.ref);
|
||||
@@ -773,7 +852,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
(bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE));
|
||||
}
|
||||
|
||||
if (data->change.proxy && *data->change.proxy &&
|
||||
if (conn->bits.httpproxy &&
|
||||
!data->set.tunnel_thru_httpproxy &&
|
||||
!(conn->protocol&PROT_HTTPS)) {
|
||||
/* The path sent to the proxy is in fact the entire URL */
|
||||
@@ -888,13 +967,14 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
{
|
||||
/* Use 1.1 unless the use specificly asked for 1.0 */
|
||||
const char *httpstring=
|
||||
data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1";
|
||||
|
||||
send_buffer *req_buffer;
|
||||
struct curl_slist *headers=data->set.headers;
|
||||
size_t postsize;
|
||||
|
||||
/* initialize a dynamic send-buffer */
|
||||
req_buffer = add_buffer_init();
|
||||
@@ -902,7 +982,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
/* add the main request stuff */
|
||||
add_bufferf(req_buffer,
|
||||
"%s " /* GET/HEAD/POST/PUT */
|
||||
"%s HTTP/%s\r\n" /* path */
|
||||
"%s HTTP/%s\r\n" /* path + HTTP version */
|
||||
"%s" /* proxyuserpwd */
|
||||
"%s" /* userpwd */
|
||||
"%s" /* range */
|
||||
@@ -915,16 +995,12 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
"%s" /* referer */
|
||||
"%s",/* transfer-encoding */
|
||||
|
||||
data->set.customrequest?data->set.customrequest:
|
||||
(data->set.no_body?"HEAD":
|
||||
((HTTPREQ_POST == data->set.httpreq) ||
|
||||
(HTTPREQ_POST_FORM == data->set.httpreq))?"POST":
|
||||
(HTTPREQ_PUT == data->set.httpreq)?"PUT":"GET"),
|
||||
ppath, httpstring,
|
||||
(conn->bits.proxy_user_passwd &&
|
||||
conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"",
|
||||
(conn->bits.user_passwd && conn->allocptr.userpwd)?
|
||||
conn->allocptr.userpwd:"",
|
||||
request,
|
||||
ppath,
|
||||
httpstring,
|
||||
(conn->bits.httpproxy && conn->allocptr.proxyuserpwd)?
|
||||
conn->allocptr.proxyuserpwd:"",
|
||||
conn->allocptr.userpwd?conn->allocptr.userpwd:"",
|
||||
(conn->bits.use_range && conn->allocptr.rangeline)?
|
||||
conn->allocptr.rangeline:"",
|
||||
(data->set.useragent && *data->set.useragent && conn->allocptr.uagent)?
|
||||
@@ -1132,6 +1208,11 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
case HTTPREQ_POST:
|
||||
/* this is the simple POST, using x-www-form-urlencoded style */
|
||||
|
||||
/* store the size of the postfields */
|
||||
postsize = data->set.postfieldsize?
|
||||
data->set.postfieldsize:
|
||||
(data->set.postfields?strlen(data->set.postfields):0);
|
||||
|
||||
if(!conn->bits.upload_chunky) {
|
||||
/* We only set Content-Length and allow a custom Content-Length if
|
||||
we don't upload data chunked, as RFC2616 forbids us to set both
|
||||
@@ -1140,11 +1221,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
if(!checkheaders(data, "Content-Length:"))
|
||||
/* we allow replacing this header, although it isn't very wise to
|
||||
actually set your own */
|
||||
add_bufferf(req_buffer,
|
||||
"Content-Length: %d\r\n",
|
||||
data->set.postfieldsize?
|
||||
data->set.postfieldsize:
|
||||
(data->set.postfields?strlen(data->set.postfields):0) );
|
||||
add_bufferf(req_buffer, "Content-Length: %d\r\n", postsize);
|
||||
}
|
||||
|
||||
if(!checkheaders(data, "Content-Type:"))
|
||||
@@ -1153,12 +1230,28 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
|
||||
add_buffer(req_buffer, "\r\n", 2);
|
||||
|
||||
/* and here we setup the pointers to the actual data */
|
||||
if(data->set.postfields) {
|
||||
if(data->set.postfieldsize)
|
||||
http->postsize = data->set.postfieldsize;
|
||||
else
|
||||
http->postsize = strlen(data->set.postfields);
|
||||
|
||||
if(postsize < (100*1024)) {
|
||||
/* The post data is less than 100K, then append it to the header.
|
||||
This limit is no magic limit but only set to prevent really huge
|
||||
POSTs to get the data duplicated with malloc() and family. */
|
||||
|
||||
if(!conn->bits.upload_chunky)
|
||||
/* We're not sending it 'chunked', append it to the request
|
||||
already now to reduce the number if send() calls */
|
||||
add_buffer(req_buffer, data->set.postfields, postsize);
|
||||
else {
|
||||
/* Append the POST data chunky-style */
|
||||
add_bufferf(req_buffer, "%x\r\n", postsize);
|
||||
add_buffer(req_buffer, data->set.postfields, postsize);
|
||||
add_buffer(req_buffer, "\r\n0\r\n", 5); /* end of a chunked
|
||||
transfer stream */
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* A huge POST coming up, do data separate from the request */
|
||||
http->postsize = postsize;
|
||||
http->postdata = data->set.postfields;
|
||||
|
||||
http->sending = HTTPSEND_BODY;
|
||||
@@ -1169,6 +1262,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
/* set the upload size to the progress meter */
|
||||
Curl_pgrsSetUploadSize(data, http->postsize);
|
||||
}
|
||||
}
|
||||
else
|
||||
/* set the upload size to the progress meter */
|
||||
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
||||
@@ -1183,8 +1277,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
result =
|
||||
Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
|
||||
&http->readbytecount,
|
||||
conn->firstsocket,
|
||||
&http->writebytecount);
|
||||
http->postdata?conn->firstsocket:-1,
|
||||
http->postdata?&http->writebytecount:NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1205,8 +1299,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
}
|
||||
if(result)
|
||||
return result;
|
||||
} while (0); /* this is just a left-over from the multiple document download
|
||||
attempts */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
@@ -39,7 +39,7 @@
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
|
231
lib/http_digest.c
Normal file
231
lib/http_digest.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "strequal.h"
|
||||
|
||||
#include "md5.h"
|
||||
#include "http_digest.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
/* Test example header:
|
||||
|
||||
WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
|
||||
|
||||
*/
|
||||
|
||||
CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
char *header) /* rest of the www-authenticate:
|
||||
header */
|
||||
{
|
||||
bool more = TRUE;
|
||||
struct SessionHandle *data=conn->data;
|
||||
|
||||
/* skip initial whitespaces */
|
||||
while(*header && isspace((int)*header))
|
||||
header++;
|
||||
|
||||
if(checkprefix("Digest", header)) {
|
||||
header += strlen("Digest");
|
||||
|
||||
/* clear off any former leftovers and init to defaults */
|
||||
Curl_digest_cleanup(data);
|
||||
|
||||
while(more) {
|
||||
char value[32];
|
||||
char content[128];
|
||||
int totlen=0;
|
||||
|
||||
while(*header && isspace((int)*header))
|
||||
header++;
|
||||
|
||||
/* how big can these strings be? */
|
||||
if(2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
|
||||
value, content)) {
|
||||
if(strequal(value, "nonce")) {
|
||||
data->state.digest.nonce = strdup(content);
|
||||
}
|
||||
else if(strequal(value, "cnonce")) {
|
||||
data->state.digest.cnonce = strdup(content);
|
||||
}
|
||||
else if(strequal(value, "realm")) {
|
||||
data->state.digest.realm = strdup(content);
|
||||
}
|
||||
else if(strequal(value, "algorithm")) {
|
||||
if(strequal(content, "MD5-sess"))
|
||||
data->state.digest.algo = CURLDIGESTALGO_MD5SESS;
|
||||
/* else, remain using the default md5 */
|
||||
}
|
||||
else {
|
||||
/* unknown specifier, ignore it! */
|
||||
}
|
||||
totlen = strlen(value)+strlen(content)+3;
|
||||
}
|
||||
else
|
||||
break; /* we're done here */
|
||||
|
||||
header += totlen;
|
||||
if(',' == *header)
|
||||
/* allow the list to be comma-separated */
|
||||
header++;
|
||||
}
|
||||
|
||||
if(!data->state.digest.nonce)
|
||||
return CURLDIGEST_BAD;
|
||||
}
|
||||
else
|
||||
/* else not a digest, get out */
|
||||
return CURLDIGEST_NONE;
|
||||
|
||||
return CURLDIGEST_FINE;
|
||||
}
|
||||
|
||||
/* convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
|
||||
static void md5_to_ascii(unsigned char *source, /* 16 bytes */
|
||||
unsigned char *dest) /* 33 bytes */
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<16; i++)
|
||||
sprintf((char *)&dest[i*2], "%02x", source[i]);
|
||||
}
|
||||
|
||||
CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
unsigned char *request,
|
||||
unsigned char *uripath)
|
||||
{
|
||||
/* We have a Digest setup for this, use it!
|
||||
Now, to get all the details for this sorted out, I must urge you dear friend
|
||||
to read up on the RFC2617 section 3.2.2, */
|
||||
unsigned char md5buf[16]; /* 16 bytes/128 bits */
|
||||
unsigned char ha1[33]; /* 32 digits and 1 zero byte */
|
||||
unsigned char ha2[33];
|
||||
unsigned char request_digest[33];
|
||||
unsigned char *md5this;
|
||||
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
/*
|
||||
if the algorithm is "MD5" or unspecified (which then defaults to MD5):
|
||||
|
||||
A1 = unq(username-value) ":" unq(realm-value) ":" passwd
|
||||
|
||||
if the algorithm is "MD5-sess" then:
|
||||
|
||||
A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
|
||||
":" unq(nonce-value) ":" unq(cnonce-value)
|
||||
*/
|
||||
if(data->state.digest.algo == CURLDIGESTALGO_MD5SESS) {
|
||||
md5this = (unsigned char *)
|
||||
aprintf("%s:%s:%s:%s:%s",
|
||||
conn->user,
|
||||
data->state.digest.realm,
|
||||
conn->passwd,
|
||||
data->state.digest.nonce,
|
||||
data->state.digest.cnonce);
|
||||
}
|
||||
else {
|
||||
md5this = (unsigned char *)
|
||||
aprintf("%s:%s:%s",
|
||||
conn->user,
|
||||
data->state.digest.realm,
|
||||
conn->passwd);
|
||||
}
|
||||
Curl_md5it(md5buf, md5this);
|
||||
free(md5this); /* free this again */
|
||||
md5_to_ascii(md5buf, ha1);
|
||||
|
||||
/*
|
||||
A2 = Method ":" digest-uri-value
|
||||
|
||||
(The "Method" value is the HTTP request method as specified in section
|
||||
5.1.1 of RFC 2616)
|
||||
*/
|
||||
|
||||
md5this = (unsigned char *)aprintf("%s:%s", request, uripath);
|
||||
Curl_md5it(md5buf, md5this);
|
||||
free(md5this); /* free this again */
|
||||
md5_to_ascii(md5buf, ha2);
|
||||
|
||||
md5this = (unsigned char *)aprintf("%s:%s:%s", ha1, data->state.digest.nonce,
|
||||
ha2);
|
||||
Curl_md5it(md5buf, md5this);
|
||||
free(md5this); /* free this again */
|
||||
md5_to_ascii(md5buf, request_digest);
|
||||
|
||||
/* for test case 64 (snooped from a Mozilla 1.3a request)
|
||||
|
||||
Authorization: Digest username="testuser", realm="testrealm", \
|
||||
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
|
||||
*/
|
||||
|
||||
conn->allocptr.userpwd =
|
||||
aprintf( "Authorization: Digest "
|
||||
"username=\"%s\", "
|
||||
"realm=\"%s\", "
|
||||
"nonce=\"%s\", "
|
||||
"uri=\"%s\", "
|
||||
"response=\"%s\"\r\n",
|
||||
conn->user,
|
||||
data->state.digest.realm,
|
||||
data->state.digest.nonce,
|
||||
uripath, /* this is the PATH part of the URL */
|
||||
request_digest );
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_digest_cleanup(struct SessionHandle *data)
|
||||
{
|
||||
if(data->state.digest.nonce)
|
||||
free(data->state.digest.nonce);
|
||||
data->state.digest.nonce = NULL;
|
||||
|
||||
if(data->state.digest.cnonce)
|
||||
free(data->state.digest.cnonce);
|
||||
data->state.digest.cnonce = NULL;
|
||||
|
||||
if(data->state.digest.realm)
|
||||
free(data->state.digest.realm);
|
||||
data->state.digest.realm = NULL;
|
||||
|
||||
data->state.digest.algo = CURLDIGESTALGO_MD5; /* default algorithm */
|
||||
}
|
||||
|
||||
#endif
|
48
lib/http_digest.h
Normal file
48
lib/http_digest.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef __HTTP_DIGEST_H
|
||||
#define __HTTP_DIGEST_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
CURLDIGEST_NONE, /* not a digest */
|
||||
CURLDIGEST_BAD, /* a digest, but one we don't like */
|
||||
CURLDIGEST_FINE, /* a digest we act on */
|
||||
|
||||
CURLDIGEST_LAST /* last entry in this enum, don't use */
|
||||
} CURLdigest;
|
||||
|
||||
enum {
|
||||
CURLDIGESTALGO_MD5,
|
||||
CURLDIGESTALGO_MD5SESS
|
||||
};
|
||||
|
||||
/* this is for digest header input */
|
||||
CURLdigest Curl_input_digest(struct connectdata *conn, char *header);
|
||||
|
||||
/* this is for creating digest header output */
|
||||
CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
unsigned char *request,
|
||||
unsigned char *uripath);
|
||||
void Curl_digest_cleanup(struct SessionHandle *data);
|
||||
|
||||
#endif
|
216
lib/http_negotiate.c
Normal file
216
lib/http_negotiate.c
Normal file
@@ -0,0 +1,216 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef GSSAPI
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "strequal.h"
|
||||
#include "base64.h"
|
||||
#include "http_negotiate.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
static int
|
||||
get_gss_name(struct connectdata *conn, gss_name_t *server)
|
||||
{
|
||||
OM_uint32 major_status, minor_status;
|
||||
gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
|
||||
char name[2048];
|
||||
|
||||
/* GSSAPI implementation by Globus (known as GSI) requires the name to be
|
||||
of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead
|
||||
of at-sign). Also GSI servers are often identified as 'host' not 'khttp'.
|
||||
Change following lines if you want to use GSI */
|
||||
token.length = strlen("khttp@") + strlen(conn->hostname) + 1;
|
||||
if (token.length + 1 > sizeof(name))
|
||||
return EMSGSIZE;
|
||||
sprintf(name, "khttp@%s", conn->hostname);
|
||||
|
||||
token.value = (void *) name;
|
||||
major_status = gss_import_name(&minor_status,
|
||||
&token,
|
||||
GSS_C_NT_HOSTBASED_SERVICE,
|
||||
server);
|
||||
return GSS_ERROR(major_status) ? -1 : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
log_gss_error(struct connectdata *conn, OM_uint32 error_status, char *prefix)
|
||||
{
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
OM_uint32 msg_ctx = 0;
|
||||
gss_buffer_desc status_string;
|
||||
char buf[1024];
|
||||
size_t len;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s", prefix);
|
||||
len = strlen(buf);
|
||||
do {
|
||||
maj_stat = gss_display_status (&min_stat,
|
||||
error_status,
|
||||
GSS_C_MECH_CODE,
|
||||
GSS_C_NO_OID,
|
||||
&msg_ctx,
|
||||
&status_string);
|
||||
if (sizeof(buf) > len + status_string.length + 1) {
|
||||
sprintf(buf + len, ": %s", (char*) status_string.value);
|
||||
len += status_string.length;
|
||||
}
|
||||
gss_release_buffer(&min_stat, &status_string);
|
||||
} while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
|
||||
|
||||
infof(conn->data, buf);
|
||||
}
|
||||
|
||||
int Curl_input_negotiate(struct connectdata *conn, char *header)
|
||||
{
|
||||
struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
|
||||
OM_uint32 major_status, minor_status, minor_status2;
|
||||
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
while(*header && isspace((int)*header))
|
||||
header++;
|
||||
if(!checkprefix("GSS-Negotiate", header))
|
||||
return -1;
|
||||
|
||||
if (neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
|
||||
/* We finished succesfully our part of authentication, but server
|
||||
* rejected it (since we're again here). Exit with an error since we
|
||||
* can't invent anything better */
|
||||
Curl_cleanup_negotiate(conn->data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (neg_ctx->server_name == NULL &&
|
||||
(ret = get_gss_name(conn, &neg_ctx->server_name)))
|
||||
return ret;
|
||||
|
||||
header += strlen("GSS-Negotiate");
|
||||
while(*header && isspace((int)*header))
|
||||
header++;
|
||||
|
||||
len = strlen(header);
|
||||
if (len > 0) {
|
||||
int rawlen;
|
||||
input_token.length = (len+3)/4 * 3;
|
||||
input_token.value = malloc(input_token.length);
|
||||
if (input_token.value == NULL)
|
||||
return ENOMEM;
|
||||
rawlen = Curl_base64_decode(header, input_token.value);
|
||||
if (rawlen < 0)
|
||||
return -1;
|
||||
input_token.length = rawlen;
|
||||
}
|
||||
|
||||
major_status = gss_init_sec_context(&minor_status,
|
||||
GSS_C_NO_CREDENTIAL,
|
||||
&neg_ctx->context,
|
||||
neg_ctx->server_name,
|
||||
GSS_C_NO_OID,
|
||||
GSS_C_DELEG_FLAG,
|
||||
0,
|
||||
GSS_C_NO_CHANNEL_BINDINGS,
|
||||
&input_token,
|
||||
NULL,
|
||||
&output_token,
|
||||
NULL,
|
||||
NULL);
|
||||
if (input_token.length > 0)
|
||||
gss_release_buffer(&minor_status2, &input_token);
|
||||
neg_ctx->status = major_status;
|
||||
if (GSS_ERROR(major_status)) {
|
||||
/* Curl_cleanup_negotiate(conn->data) ??? */
|
||||
log_gss_error(conn, minor_status,
|
||||
(char *)"gss_init_sec_context() failed: ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (output_token.length == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
neg_ctx->output_token = output_token;
|
||||
/* conn->bits.close = FALSE; */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
CURLcode Curl_output_negotiate(struct connectdata *conn)
|
||||
{
|
||||
struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
|
||||
OM_uint32 minor_status;
|
||||
char *encoded = NULL;
|
||||
int len = Curl_base64_encode(neg_ctx->output_token.value,
|
||||
neg_ctx->output_token.length,
|
||||
&encoded);
|
||||
if (len < 0)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
conn->allocptr.userpwd =
|
||||
aprintf("Authorization: GSS-Negotiate %s\r\n", encoded);
|
||||
free(encoded);
|
||||
gss_release_buffer(&minor_status, &neg_ctx->output_token);
|
||||
return (conn->allocptr.userpwd == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_cleanup_negotiate(struct SessionHandle *data)
|
||||
{
|
||||
OM_uint32 minor_status;
|
||||
struct negotiatedata *neg_ctx = &data->state.negotiate;
|
||||
|
||||
if (neg_ctx->context != GSS_C_NO_CONTEXT)
|
||||
gss_delete_sec_context(&minor_status, &neg_ctx->context, GSS_C_NO_BUFFER);
|
||||
|
||||
if (neg_ctx->output_token.length != 0)
|
||||
gss_release_buffer(&minor_status, &neg_ctx->output_token);
|
||||
|
||||
if (neg_ctx->server_name != GSS_C_NO_NAME)
|
||||
gss_release_name(&minor_status, &neg_ctx->server_name);
|
||||
|
||||
memset(neg_ctx, 0, sizeof(*neg_ctx));
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
39
lib/http_negotiate.h
Normal file
39
lib/http_negotiate.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef __HTTP_NEGOTIATE_H
|
||||
#define __HTTP_NEGOTIATE_H
|
||||
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef GSSAPI
|
||||
|
||||
/* this is for Negotiate header input */
|
||||
int Curl_input_negotiate(struct connectdata *conn, char *header);
|
||||
|
||||
/* this is for creating Negotiate header output */
|
||||
CURLcode Curl_output_negotiate(struct connectdata *conn);
|
||||
|
||||
void Curl_cleanup_negotiate(struct SessionHandle *data);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
571
lib/http_ntlm.c
Normal file
571
lib/http_ntlm.c
Normal file
@@ -0,0 +1,571 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
#include "setup.h"
|
||||
|
||||
/* NTLM details:
|
||||
|
||||
http://davenport.sourceforge.net/ntlm.html
|
||||
http://www.innovation.ch/java/ntlm.html
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
#ifdef USE_SSLEAY
|
||||
/* We need OpenSSL for the crypto lib to provide us with MD4 and DES */
|
||||
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "strequal.h"
|
||||
#include "base64.h"
|
||||
#include "http_ntlm.h"
|
||||
#include "url.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include <openssl/des.h>
|
||||
#include <openssl/md4.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907001L
|
||||
#define DES_key_schedule des_key_schedule
|
||||
#define DES_cblock des_cblock
|
||||
#define DES_set_odd_parity des_set_odd_parity
|
||||
#define DES_set_key des_set_key
|
||||
#define DES_ecb_encrypt des_ecb_encrypt
|
||||
|
||||
/* This is how things were done in the old days */#define DESKEY(x) x
|
||||
#define DESKEY(x) x
|
||||
#define DESKEYARG(x) x
|
||||
#else
|
||||
/* Modern version */
|
||||
#define DESKEYARG(x) *x
|
||||
#define DESKEY(x) &x
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
/* Define this to make the type-3 message include the NT response message */
|
||||
#undef USE_NTRESPONSES
|
||||
|
||||
/*
|
||||
(*) = A "security buffer" is a triplet consisting of two shorts and one
|
||||
long:
|
||||
|
||||
1. a 'short' containing the length of the buffer in bytes
|
||||
2. a 'short' containing the allocated space for the buffer in bytes
|
||||
3. a 'long' containing the offset to the start of the buffer from the
|
||||
beginning of the NTLM message, in bytes.
|
||||
*/
|
||||
|
||||
|
||||
CURLntlm Curl_input_ntlm(struct connectdata *conn,
|
||||
bool proxy, /* if proxy or not */
|
||||
char *header) /* rest of the www-authenticate:
|
||||
header */
|
||||
{
|
||||
/* point to the correct struct with this */
|
||||
struct ntlmdata *ntlm;
|
||||
|
||||
ntlm = proxy?&conn->proxyntlm:&conn->ntlm;
|
||||
|
||||
/* skip initial whitespaces */
|
||||
while(*header && isspace((int)*header))
|
||||
header++;
|
||||
|
||||
if(checkprefix("NTLM", header)) {
|
||||
unsigned char buffer[256];
|
||||
header += strlen("NTLM");
|
||||
|
||||
while(*header && isspace((int)*header))
|
||||
header++;
|
||||
|
||||
if(*header) {
|
||||
/* We got a type-2 message here:
|
||||
|
||||
Index Description Content
|
||||
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||
(0x4e544c4d53535000)
|
||||
8 NTLM Message Type long (0x02000000)
|
||||
12 Target Name security buffer(*)
|
||||
20 Flags long
|
||||
24 Challenge 8 bytes
|
||||
(32) Context (optional) 8 bytes (two consecutive longs)
|
||||
(40) Target Information (optional) security buffer(*)
|
||||
32 (48) start of data block
|
||||
*/
|
||||
|
||||
int size = Curl_base64_decode(header, buffer);
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
|
||||
|
||||
if(size >= 48)
|
||||
/* the nonce of interest is index [24 .. 31], 8 bytes */
|
||||
memcpy(ntlm->nonce, &buffer[24], 8);
|
||||
|
||||
/* at index decimal 20, there's a 32bit NTLM flag field */
|
||||
|
||||
}
|
||||
else {
|
||||
if(ntlm->state >= NTLMSTATE_TYPE1)
|
||||
return CURLNTLM_BAD;
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
|
||||
}
|
||||
}
|
||||
return CURLNTLM_FINE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
|
||||
* key schedule ks is also set.
|
||||
*/
|
||||
static void setup_des_key(unsigned char *key_56,
|
||||
DES_key_schedule DESKEYARG(ks))
|
||||
{
|
||||
DES_cblock key;
|
||||
|
||||
key[0] = key_56[0];
|
||||
key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
|
||||
key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
|
||||
key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
|
||||
key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
|
||||
key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
|
||||
key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
|
||||
key[7] = (key_56[6] << 1) & 0xFF;
|
||||
|
||||
DES_set_odd_parity(&key);
|
||||
DES_set_key(&key, ks);
|
||||
}
|
||||
|
||||
/*
|
||||
* takes a 21 byte array and treats it as 3 56-bit DES keys. The
|
||||
* 8 byte plaintext is encrypted with each key and the resulting 24
|
||||
* bytes are stored in the results array.
|
||||
*/
|
||||
static void calc_resp(unsigned char *keys,
|
||||
unsigned char *plaintext,
|
||||
unsigned char *results)
|
||||
{
|
||||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(keys, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
setup_des_key(keys+7, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8),
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
setup_des_key(keys+14, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up lanmanager and nt hashed passwords
|
||||
*/
|
||||
static void mkhash(char *password,
|
||||
unsigned char *nonce, /* 8 bytes */
|
||||
unsigned char *lmresp /* must fit 0x18 bytes */
|
||||
#ifdef USE_NTRESPONSES
|
||||
, unsigned char *ntresp /* must fit 0x18 bytes */
|
||||
#endif
|
||||
)
|
||||
{
|
||||
unsigned char lmbuffer[21];
|
||||
#ifdef USE_NTRESPONSES
|
||||
unsigned char ntbuffer[21];
|
||||
#endif
|
||||
unsigned char *pw;
|
||||
static const unsigned char magic[] = {
|
||||
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25
|
||||
};
|
||||
int i;
|
||||
int len = strlen(password);
|
||||
|
||||
/* make it fit at least 14 bytes */
|
||||
pw = malloc(len<7?14:len*2);
|
||||
if(!pw)
|
||||
return; /* this will lead to a badly generated package */
|
||||
|
||||
if (len > 14)
|
||||
len = 14;
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
pw[i] = toupper(password[i]);
|
||||
|
||||
for (; i<14; i++)
|
||||
pw[i] = 0;
|
||||
|
||||
{
|
||||
/* create LanManager hashed password */
|
||||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(pw, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
setup_des_key(pw+7, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
memset(lmbuffer+16, 0, 5);
|
||||
}
|
||||
/* create LM responses */
|
||||
calc_resp(lmbuffer, nonce, lmresp);
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
{
|
||||
/* create NT hashed password */
|
||||
MD4_CTX MD4;
|
||||
|
||||
len = strlen(password);
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
pw[2*i] = password[i];
|
||||
pw[2*i+1] = 0;
|
||||
}
|
||||
|
||||
MD4_Init(&MD4);
|
||||
MD4_Update(&MD4, pw, 2*len);
|
||||
MD4_Final(ntbuffer, &MD4);
|
||||
|
||||
memset(ntbuffer+16, 0, 8);
|
||||
}
|
||||
|
||||
calc_resp(ntbuffer, nonce, ntresp);
|
||||
#endif
|
||||
|
||||
free(pw);
|
||||
}
|
||||
|
||||
#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8)
|
||||
#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
|
||||
(((x) >>16)&0xff), ((x)>>24)
|
||||
|
||||
/* this is for creating ntlm header output */
|
||||
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
bool proxy)
|
||||
{
|
||||
const char *domain=""; /* empty */
|
||||
const char *host=""; /* empty */
|
||||
int domlen=strlen(domain);
|
||||
int hostlen = strlen(host);
|
||||
int hostoff; /* host name offset */
|
||||
int domoff; /* domain name offset */
|
||||
int size;
|
||||
char *base64=NULL;
|
||||
unsigned char ntlmbuf[256]; /* enough, unless the host/domain is very long */
|
||||
|
||||
/* point to the address of the pointer that holds the string to sent to the
|
||||
server, which is for a plain host or for a HTTP proxy */
|
||||
char **allocuserpwd;
|
||||
|
||||
/* point to the name and password for this */
|
||||
char *userp;
|
||||
char *passwdp;
|
||||
/* point to the correct struct with this */
|
||||
struct ntlmdata *ntlm;
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
ntlm = &conn->proxyntlm;
|
||||
}
|
||||
else {
|
||||
allocuserpwd = &conn->allocptr.userpwd;
|
||||
userp = conn->user;
|
||||
passwdp = conn->passwd;
|
||||
ntlm = &conn->ntlm;
|
||||
}
|
||||
|
||||
switch(ntlm->state) {
|
||||
case NTLMSTATE_TYPE1:
|
||||
default: /* for the weird cases we (re)start here */
|
||||
hostoff = 32;
|
||||
domoff = hostoff + hostlen;
|
||||
|
||||
/* Create and send a type-1 message:
|
||||
|
||||
Index Description Content
|
||||
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||
(0x4e544c4d53535000)
|
||||
8 NTLM Message Type long (0x01000000)
|
||||
12 Flags long
|
||||
16 Supplied Domain security buffer(*)
|
||||
24 Supplied Workstation security buffer(*)
|
||||
32 start of data block
|
||||
|
||||
*/
|
||||
|
||||
snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
|
||||
"\x01%c%c%c" /* 32-bit type = 1 */
|
||||
"%c%c%c%c" /* 32-bit NTLM flag field */
|
||||
"%c%c" /* domain length */
|
||||
"%c%c" /* domain allocated space */
|
||||
"%c%c" /* domain name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host allocated space */
|
||||
"%c%c" /* host name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%s" /* host name */
|
||||
"%s", /* domain string */
|
||||
0, /* trailing zero */
|
||||
0,0,0, /* part of type-1 long */
|
||||
|
||||
LONGQUARTET(
|
||||
NTLMFLAG_NEGOTIATE_OEM| /* 2 */
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */
|
||||
/* equals 0x0202 */
|
||||
),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domoff),
|
||||
0,0,
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostoff),
|
||||
0,0,
|
||||
host, domain);
|
||||
|
||||
/* initial packet length */
|
||||
size = 32 + hostlen + domlen;
|
||||
|
||||
/* now keeper of the base64 encoded package size */
|
||||
size = Curl_base64_encode(ntlmbuf, size, &base64);
|
||||
|
||||
if(size >0 ) {
|
||||
Curl_safefree(*allocuserpwd);
|
||||
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
|
||||
proxy?"Proxy-":"",
|
||||
base64);
|
||||
free(base64);
|
||||
}
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
||||
|
||||
break;
|
||||
|
||||
case NTLMSTATE_TYPE2:
|
||||
/* We received the type-2 already, create a type-3 message:
|
||||
|
||||
Index Description Content
|
||||
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||
(0x4e544c4d53535000)
|
||||
8 NTLM Message Type long (0x03000000)
|
||||
12 LM/LMv2 Response security buffer(*)
|
||||
20 NTLM/NTLMv2 Response security buffer(*)
|
||||
28 Domain Name security buffer(*)
|
||||
36 User Name security buffer(*)
|
||||
44 Workstation Name security buffer(*)
|
||||
(52) Session Key (optional) security buffer(*)
|
||||
(60) Flags (optional) long
|
||||
52 (64) start of data block
|
||||
|
||||
*/
|
||||
|
||||
{
|
||||
int lmrespoff;
|
||||
int ntrespoff;
|
||||
int useroff;
|
||||
unsigned char lmresp[0x18]; /* fixed-size */
|
||||
#ifdef USE_NTRESPONSES
|
||||
unsigned char ntresp[0x18]; /* fixed-size */
|
||||
#endif
|
||||
const char *user;
|
||||
int userlen;
|
||||
|
||||
user = strchr(userp, '\\');
|
||||
if(!user)
|
||||
user = strchr(userp, '/');
|
||||
|
||||
if (user) {
|
||||
domain = userp;
|
||||
domlen = user - domain;
|
||||
user++;
|
||||
}
|
||||
else
|
||||
user = userp;
|
||||
userlen = strlen(user);
|
||||
|
||||
mkhash(passwdp, &ntlm->nonce[0], lmresp
|
||||
#ifdef USE_NTRESPONSES
|
||||
, ntresp
|
||||
#endif
|
||||
);
|
||||
|
||||
domoff = 64; /* always */
|
||||
useroff = domoff + domlen;
|
||||
hostoff = useroff + userlen;
|
||||
lmrespoff = hostoff + hostlen;
|
||||
ntrespoff = lmrespoff + 0x18;
|
||||
|
||||
/* Create the big type-3 message binary blob */
|
||||
size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
|
||||
"NTLMSSP%c"
|
||||
"\x03%c%c%c" /* type-3, 32 bits */
|
||||
|
||||
"%c%c%c%c" /* LanManager length + allocated space */
|
||||
"%c%c" /* LanManager offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* NT-response length */
|
||||
"%c%c" /* NT-response allocated space */
|
||||
"%c%c" /* NT-response offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* domain length */
|
||||
"%c%c" /* domain allocated space */
|
||||
"%c%c" /* domain name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* user length */
|
||||
"%c%c" /* user allocated space */
|
||||
"%c%c" /* user offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host allocated space */
|
||||
"%c%c" /* host offset */
|
||||
"%c%c%c%c%c%c" /* 6 zeroes */
|
||||
|
||||
"\xff\xff" /* message length */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"\x01\x82" /* flags */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
/* domain string */
|
||||
/* user string */
|
||||
/* host string */
|
||||
/* LanManager response */
|
||||
/* NT response */
|
||||
,
|
||||
0, /* zero termination */
|
||||
0,0,0, /* type-3 long, the 24 upper bits */
|
||||
|
||||
SHORTPAIR(0x18), /* LanManager response length, twice */
|
||||
SHORTPAIR(0x18),
|
||||
SHORTPAIR(lmrespoff),
|
||||
0x0, 0x0,
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
SHORTPAIR(0x18), /* NT-response length, twice */
|
||||
SHORTPAIR(0x18),
|
||||
#else
|
||||
0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
#endif
|
||||
SHORTPAIR(ntrespoff),
|
||||
0x0, 0x0,
|
||||
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domoff),
|
||||
0x0, 0x0,
|
||||
|
||||
SHORTPAIR(userlen),
|
||||
SHORTPAIR(userlen),
|
||||
SHORTPAIR(useroff),
|
||||
0x0, 0x0,
|
||||
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostoff),
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
0x0, 0x0,
|
||||
|
||||
0x0, 0x0);
|
||||
|
||||
/* size is now 64 */
|
||||
size=64;
|
||||
ntlmbuf[62]=ntlmbuf[63]=0;
|
||||
|
||||
memcpy(&ntlmbuf[size], domain, domlen);
|
||||
size += domlen;
|
||||
|
||||
memcpy(&ntlmbuf[size], user, userlen);
|
||||
size += userlen;
|
||||
|
||||
/* we append the binary hashes to the end of the blob */
|
||||
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
|
||||
memcpy(&ntlmbuf[size], lmresp, 0x18);
|
||||
size += 0x18;
|
||||
}
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
|
||||
memcpy(&ntlmbuf[size], ntresp, 0x18);
|
||||
size += 0x18;
|
||||
}
|
||||
#endif
|
||||
|
||||
ntlmbuf[56] = size & 0xff;
|
||||
ntlmbuf[57] = size >> 8;
|
||||
|
||||
/* convert the binary blob into base64 */
|
||||
size = Curl_base64_encode(ntlmbuf, size, &base64);
|
||||
|
||||
if(size >0 ) {
|
||||
Curl_safefree(*allocuserpwd);
|
||||
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
|
||||
proxy?"Proxy-":"",
|
||||
base64);
|
||||
free(base64);
|
||||
}
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case NTLMSTATE_TYPE3:
|
||||
/* connection is already authenticated,
|
||||
* don't send a header in future requests */
|
||||
if(*allocuserpwd) {
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd=NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif /* USE_SSLEAY */
|
||||
#endif /* !CURL_DISABLE_HTTP */
|
143
lib/http_ntlm.h
Normal file
143
lib/http_ntlm.h
Normal file
@@ -0,0 +1,143 @@
|
||||
#ifndef __HTTP_NTLM_H
|
||||
#define __HTTP_NTLM_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
CURLNTLM_NONE, /* not a ntlm */
|
||||
CURLNTLM_BAD, /* an ntlm, but one we don't like */
|
||||
CURLNTLM_FIRST, /* the first 401-reply we got with NTLM */
|
||||
CURLNTLM_FINE, /* an ntlm we act on */
|
||||
|
||||
CURLNTLM_LAST /* last entry in this enum, don't use */
|
||||
} CURLntlm;
|
||||
|
||||
/* this is for ntlm header input */
|
||||
CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
|
||||
|
||||
/* this is for creating ntlm header output */
|
||||
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_ntlm_cleanup(struct SessionHandle *data);
|
||||
|
||||
|
||||
/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0)
|
||||
/* Indicates that Unicode strings are supported for use in security buffer
|
||||
data. */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_OEM (1<<1)
|
||||
/* Indicates that OEM strings are supported for use in security buffer data. */
|
||||
|
||||
#define NTLMFLAG_REQUEST_TARGET (1<<2)
|
||||
/* Requests that the server's authentication realm be included in the Type 2
|
||||
message. */
|
||||
|
||||
/* unknown (1<<3) */
|
||||
#define NTLMFLAG_NEGOTIATE_SIGN (1<<4)
|
||||
/* Specifies that authenticated communication between the client and server
|
||||
should carry a digital signature (message integrity). */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_SEAL (1<<5)
|
||||
/* Specifies that authenticated communication between the client and server
|
||||
should be encrypted (message confidentiality). */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE (1<<6)
|
||||
/* unknown purpose */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_LM_KEY (1<<7)
|
||||
/* Indicates that the LAN Manager session key should be used for signing and
|
||||
sealing authenticated communications. */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_NETWARE (1<<8)
|
||||
/* unknown purpose */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_NTLM_KEY (1<<9)
|
||||
/* Indicates that NTLM authentication is being used. */
|
||||
|
||||
/* unknown (1<<10) */
|
||||
/* unknown (1<<11) */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED (1<<12)
|
||||
/* Sent by the client in the Type 1 message to indicate that a desired
|
||||
authentication realm is included in the message. */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED (1<<13)
|
||||
/* Sent by the client in the Type 1 message to indicate that the client
|
||||
workstation's name is included in the message. */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_LOCAL_CALL (1<<14)
|
||||
/* Sent by the server to indicate that the server and client are on the same
|
||||
machine. Implies that the client may use a pre-established local security
|
||||
context rather than responding to the challenge. */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN (1<<15)
|
||||
/* Indicates that authenticated communication between the client and server
|
||||
should be signed with a "dummy" signature. */
|
||||
|
||||
#define NTLMFLAG_TARGET_TYPE_DOMAIN (1<<16)
|
||||
/* Sent by the server in the Type 2 message to indicate that the target
|
||||
authentication realm is a domain. */
|
||||
|
||||
#define NTLMFLAG_TARGET_TYPE_SERVER (1<<17)
|
||||
/* Sent by the server in the Type 2 message to indicate that the target
|
||||
authentication realm is a server. */
|
||||
|
||||
#define NTLMFLAG_TARGET_TYPE_SHARE (1<<18)
|
||||
/* Sent by the server in the Type 2 message to indicate that the target
|
||||
authentication realm is a share. Presumably, this is for share-level
|
||||
authentication. Usage is unclear. */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_NTLM2_KEY (1<<19)
|
||||
/* Indicates that the NTLM2 signing and sealing scheme should be used for
|
||||
protecting authenticated communications. */
|
||||
|
||||
#define NTLMFLAG_REQUEST_INIT_RESPONSE (1<<20)
|
||||
/* unknown purpose */
|
||||
|
||||
#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE (1<<21)
|
||||
/* unknown purpose */
|
||||
|
||||
#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY (1<<22)
|
||||
/* unknown purpose */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_TARGET_INFO (1<<23)
|
||||
/* Sent by the server in the Type 2 message to indicate that it is including a
|
||||
Target Information block in the message. */
|
||||
|
||||
/* unknown (1<24) */
|
||||
/* unknown (1<25) */
|
||||
/* unknown (1<26) */
|
||||
/* unknown (1<27) */
|
||||
/* unknown (1<28) */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_128 (1<<29)
|
||||
/* Indicates that 128-bit encryption is supported. */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE (1<<30)
|
||||
/* unknown purpose */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_56 (1<<31)
|
||||
/* Indicates that 56-bit encryption is supported. */
|
||||
#endif
|
@@ -73,10 +73,14 @@
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
#ifdef DJGPP
|
||||
#define IOCTL_3_ARGS
|
||||
#endif
|
||||
|
||||
#define SYS_ERROR -1
|
||||
|
||||
char *Curl_if2ip(char *interface, char *buf, int buf_size)
|
||||
|
@@ -64,7 +64,7 @@
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -322,7 +322,7 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
|
||||
|
||||
save = Curl_set_command_prot(conn, prot_private);
|
||||
|
||||
result = Curl_ftpsendf(conn, "SITE KAUTH %s", conn->data->state.user);
|
||||
result = Curl_ftpsendf(conn, "SITE KAUTH %s", conn->user);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
@@ -363,7 +363,7 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
|
||||
for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
|
||||
*p = 0;
|
||||
|
||||
des_string_to_key (conn->data->state.passwd, &key);
|
||||
des_string_to_key (conn->passwd, &key);
|
||||
des_key_sched(&key, schedule);
|
||||
|
||||
des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat,
|
||||
|
@@ -74,7 +74,7 @@ static void DynaOpen(void)
|
||||
* liblber.so automatically, but since it does not we will
|
||||
* handle it here by opening liblber.so as global.
|
||||
*/
|
||||
dlopen("liblber.so",
|
||||
liblber = dlopen("liblber.so",
|
||||
#ifdef RTLD_LAZY_GLOBAL /* It turns out some systems use this: */
|
||||
RTLD_LAZY_GLOBAL
|
||||
#else
|
||||
@@ -178,8 +178,8 @@ CURLcode Curl_ldap(struct connectdata *conn)
|
||||
status = CURLE_COULDNT_CONNECT;
|
||||
} else {
|
||||
rc = ldap_simple_bind_s(server,
|
||||
conn->bits.user_passwd?data->state.user:NULL,
|
||||
conn->bits.user_passwd?data->state.passwd:NULL);
|
||||
conn->bits.user_passwd?conn->user:NULL,
|
||||
conn->bits.user_passwd?conn->passwd:NULL);
|
||||
if (rc != 0) {
|
||||
failf(data, "LDAP: %s", ldap_err2string(rc));
|
||||
status = CURLE_LDAP_CANNOT_BIND;
|
||||
|
@@ -28,7 +28,7 @@
|
||||
|
||||
#include "llist.h"
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
/* this must be the last include file */
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
157
lib/makefile.dj
Normal file
157
lib/makefile.dj
Normal file
@@ -0,0 +1,157 @@
|
||||
#
|
||||
# Adapted for djgpp2 / Watt-32 / DOS by
|
||||
# Gisle Vanem <giva@bgnett.no>
|
||||
#
|
||||
|
||||
DEPEND_PREREQ = config.h getdate.c
|
||||
|
||||
include ../packages/DOS/common.dj
|
||||
|
||||
ifeq ($(USE_SSL),1)
|
||||
CFLAGS += -I$(OPENSSL_ROOT)
|
||||
endif
|
||||
|
||||
SOURCES = base64.c connect.c content_.c cookie.c dict.c \
|
||||
easy.c escape.c file.c formdata.c ftp.c \
|
||||
getdate.c getenv.c getinfo.c getpass.c hash.c \
|
||||
hostip.c http.c http_chu.c if2ip.c krb4.c \
|
||||
ldap.c llist.c memdebug.c mprintf.c multi.c \
|
||||
netrc.c progress.c security.c sendf.c share.c \
|
||||
speedche.c ssluse.c strequal.c strtok.c telnet.c \
|
||||
timeval.c transfer.c url.c version.c
|
||||
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
CURL_LIB = libcurl.a
|
||||
|
||||
all: config.h $(CURL_LIB)
|
||||
|
||||
$(CURL_LIB): $(OBJECTS)
|
||||
ar rs $@ $?
|
||||
|
||||
config.h: config.dj
|
||||
@echo '#include "./config.dj"' > $@
|
||||
|
||||
getdate.c: getdate.y
|
||||
$(YACC) -o $@ $^
|
||||
|
||||
clean:
|
||||
- rm -f $(OBJECTS) $(CURL_LIB) Makefile.bak config.h getdate.c
|
||||
|
||||
# DO NOT DELETE THIS LINE
|
||||
base64.o: base64.c setup.h config.h config.dj ../include/curl/mprintf.h \
|
||||
base64.h
|
||||
connect.o: connect.c setup.h config.h config.dj urldata.h cookie.h \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h sendf.h if2ip.h
|
||||
content_.o: content_.c setup.h config.h config.dj
|
||||
cookie.o: cookie.c setup.h config.h config.dj cookie.h \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h getdate.h strequal.h strtok.h
|
||||
dict.o: dict.c setup.h config.h config.dj urldata.h cookie.h \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h transfer.h sendf.h progress.h strequal.h \
|
||||
../include/curl/mprintf.h
|
||||
easy.o: easy.c setup.h config.h config.dj strequal.h urldata.h cookie.h \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h transfer.h ssluse.h url.h getinfo.h \
|
||||
../include/curl/mprintf.h
|
||||
escape.o: escape.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h
|
||||
file.o: file.c setup.h config.h config.dj urldata.h cookie.h \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h progress.h sendf.h escape.h ../include/curl/mprintf.h
|
||||
formdata.o: formdata.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||
formdata.h strequal.h
|
||||
ftp.o: ftp.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||
llist.h sendf.h if2ip.h progress.h transfer.h escape.h http.h ftp.h \
|
||||
strequal.h ssluse.h connect.h ../include/curl/mprintf.h
|
||||
getdate.o: getdate.c setup.h config.h config.dj getdate.h
|
||||
getenv.o: getenv.c setup.h config.h config.dj
|
||||
getinfo.o: getinfo.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||
llist.h
|
||||
getpass.o: getpass.c setup.h config.h config.dj
|
||||
hash.o: hash.c setup.h config.h config.dj hash.h llist.h
|
||||
hostip.o: hostip.c setup.h config.h config.dj urldata.h cookie.h \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h sendf.h share.h ../include/curl/mprintf.h
|
||||
http.o: http.c setup.h config.h config.dj urldata.h cookie.h \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h transfer.h sendf.h progress.h base64.h strequal.h \
|
||||
ssluse.h ../include/curl/mprintf.h
|
||||
http_chu.o: http_chu.c setup.h config.h config.dj urldata.h cookie.h \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h sendf.h content_encoding.h ../include/curl/mprintf.h
|
||||
if2ip.o: if2ip.c setup.h config.h config.dj
|
||||
krb4.o: krb4.c setup.h config.h config.dj
|
||||
ldap.o: ldap.c setup.h config.h config.dj urldata.h cookie.h \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h sendf.h escape.h transfer.h ../include/curl/mprintf.h
|
||||
llist.o: llist.c setup.h config.h config.dj llist.h
|
||||
memdebug.o: memdebug.c
|
||||
mprintf.o: mprintf.c setup.h config.h config.dj
|
||||
multi.o: multi.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||
llist.h transfer.h url.h connect.h progress.h
|
||||
netrc.o: netrc.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||
strequal.h strtok.h
|
||||
progress.o: progress.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||
llist.h sendf.h progress.h ../include/curl/mprintf.h
|
||||
security.o: security.c setup.h config.h config.dj
|
||||
sendf.o: sendf.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||
llist.h sendf.h connect.h ../include/curl/mprintf.h
|
||||
share.o: share.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||
llist.h share.h
|
||||
speedche.o: speedche.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||
llist.h sendf.h speedcheck.h
|
||||
ssluse.o: ssluse.c setup.h config.h config.dj urldata.h cookie.h \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h sendf.h url.h
|
||||
strequal.o: strequal.c setup.h config.h config.dj
|
||||
strtok.o: strtok.c setup.h config.h config.dj
|
||||
telnet.o: telnet.c setup.h config.h config.dj urldata.h cookie.h \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h transfer.h sendf.h ../include/curl/mprintf.h \
|
||||
arpa_telnet.h
|
||||
timeval.o: timeval.c timeval.h setup.h config.h config.dj
|
||||
transfer.o: transfer.c setup.h config.h config.dj strequal.h urldata.h \
|
||||
cookie.h ../include/curl/curl.h ../include/curl/types.h \
|
||||
../include/curl/easy.h ../include/curl/multi.h formdata.h timeval.h \
|
||||
http_chunks.h hostip.h hash.h llist.h netrc.h content_encoding.h \
|
||||
transfer.h sendf.h speedcheck.h getpass.h progress.h getdate.h http.h \
|
||||
url.h getinfo.h ssluse.h ../include/curl/mprintf.h
|
||||
url.o: url.c setup.h config.h config.dj urldata.h cookie.h \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h netrc.h base64.h ssluse.h if2ip.h transfer.h sendf.h \
|
||||
getpass.h progress.h strequal.h escape.h strtok.h share.h \
|
||||
content_encoding.h ftp.h dict.h telnet.h http.h file.h ldap.h url.h \
|
||||
connect.h ca-bundle.h ../include/curl/mprintf.h
|
||||
version.o: version.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||
llist.h
|
356
lib/md5.c
Normal file
356
lib/md5.c
Normal file
@@ -0,0 +1,356 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef USE_SSLEAY
|
||||
/* This code segment is only used if OpenSSL is not provided, as if it is
|
||||
we use the MD5-function provided there instead. No good duplicating
|
||||
code! */
|
||||
|
||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* UINT4 defines a four byte word */
|
||||
typedef unsigned long int UINT4;
|
||||
|
||||
/* MD5 context. */
|
||||
struct md5_ctx {
|
||||
UINT4 state[4]; /* state (ABCD) */
|
||||
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
unsigned char buffer[64]; /* input buffer */
|
||||
};
|
||||
|
||||
typedef struct md5_ctx MD5_CTX;
|
||||
|
||||
static void MD5_Init(struct md5_ctx *);
|
||||
static void MD5_Update(struct md5_ctx *, unsigned char *, unsigned int);
|
||||
static void MD5_Final(unsigned char [16], struct md5_ctx *);
|
||||
|
||||
/* Constants for MD5Transform routine.
|
||||
*/
|
||||
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
|
||||
static void MD5Transform(UINT4 [4], unsigned char [64]);
|
||||
static void Encode(unsigned char *, UINT4 *, unsigned int);
|
||||
static void Decode(UINT4 *, unsigned char *, unsigned int);
|
||||
|
||||
#define MD5_memcpy(dst,src,len) memcpy(dst,src,len)
|
||||
#define MD5_memset(dst,val,len) memset(dst,val,len)
|
||||
|
||||
static unsigned char PADDING[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* F, G, H and I are basic MD5 functions.
|
||||
*/
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits.
|
||||
*/
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
Rotation is separate from addition to prevent recomputation.
|
||||
*/
|
||||
#define FF(a, b, c, d, x, s, ac) { \
|
||||
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) { \
|
||||
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) { \
|
||||
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) { \
|
||||
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
/* MD5 initialization. Begins an MD5 operation, writing a new context.
|
||||
*/
|
||||
static void MD5_Init (context)
|
||||
struct md5_ctx *context; /* context */
|
||||
{
|
||||
context->count[0] = context->count[1] = 0;
|
||||
/* Load magic initialization constants.
|
||||
*/
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xefcdab89;
|
||||
context->state[2] = 0x98badcfe;
|
||||
context->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
/* MD5 block update operation. Continues an MD5 message-digest
|
||||
operation, processing another message block, and updating the
|
||||
context.
|
||||
*/
|
||||
static void MD5_Update (context, input, inputLen)
|
||||
struct md5_ctx *context; /* context */
|
||||
unsigned char *input; /* input block */
|
||||
unsigned int inputLen; /* length of input block */
|
||||
{
|
||||
unsigned int i, index, partLen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
|
||||
|
||||
/* Update number of bits */
|
||||
if ((context->count[0] += ((UINT4)inputLen << 3))
|
||||
< ((UINT4)inputLen << 3))
|
||||
context->count[1]++;
|
||||
context->count[1] += ((UINT4)inputLen >> 29);
|
||||
|
||||
partLen = 64 - index;
|
||||
|
||||
/* Transform as many times as possible. */
|
||||
if (inputLen >= partLen) {
|
||||
MD5_memcpy((void *)&context->buffer[index], (void *)input, partLen);
|
||||
MD5Transform(context->state, context->buffer);
|
||||
|
||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||
MD5Transform(context->state, &input[i]);
|
||||
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
i = 0;
|
||||
|
||||
/* Buffer remaining input */
|
||||
MD5_memcpy((void *)&context->buffer[index], (void *)&input[i],
|
||||
inputLen-i);
|
||||
}
|
||||
|
||||
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||
the message digest and zeroizing the context.
|
||||
*/
|
||||
static void MD5_Final (digest, context)
|
||||
unsigned char digest[16]; /* message digest */
|
||||
struct md5_ctx *context; /* context */
|
||||
{
|
||||
unsigned char bits[8];
|
||||
unsigned int index, padLen;
|
||||
|
||||
/* Save number of bits */
|
||||
Encode (bits, context->count, 8);
|
||||
|
||||
/* Pad out to 56 mod 64. */
|
||||
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
|
||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
MD5_Update (context, PADDING, padLen);
|
||||
|
||||
/* Append length (before padding) */
|
||||
MD5_Update (context, bits, 8);
|
||||
|
||||
/* Store state in digest */
|
||||
Encode (digest, context->state, 16);
|
||||
|
||||
/* Zeroize sensitive information. */
|
||||
MD5_memset ((void *)context, 0, sizeof (*context));
|
||||
}
|
||||
|
||||
/* MD5 basic transformation. Transforms state based on block. */
|
||||
static void MD5Transform (state, block)
|
||||
UINT4 state[4];
|
||||
unsigned char block[64];
|
||||
{
|
||||
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
|
||||
Decode (x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
/* Zeroize sensitive information. */
|
||||
MD5_memset ((void *)x, 0, sizeof (x));
|
||||
}
|
||||
|
||||
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
|
||||
a multiple of 4.
|
||||
*/
|
||||
static void Encode (unsigned char *output,
|
||||
UINT4 *input,
|
||||
unsigned int len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = (unsigned char)(input[i] & 0xff);
|
||||
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
|
||||
a multiple of 4.
|
||||
*/
|
||||
static void Decode (UINT4 *output,
|
||||
unsigned char *input,
|
||||
unsigned int len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
|
||||
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
#else
|
||||
/* If OpenSSL is present */
|
||||
#include <openssl/md5.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
|
||||
void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
|
||||
unsigned char *input)
|
||||
{
|
||||
MD5_CTX ctx;
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, input, strlen((char *)input));
|
||||
MD5_Final(outbuffer, &ctx);
|
||||
}
|
@@ -1,31 +1,29 @@
|
||||
#ifndef __CA_BUNDLE_H
|
||||
#define __CA_BUNDLE_H
|
||||
/*****************************************************************************
|
||||
#ifndef __MD5_H
|
||||
#define __MD5_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2003, 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.
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the MPL or the MIT/X-derivate
|
||||
* licenses. You may pick one of these licenses.
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
***************************************************************************/
|
||||
|
||||
void Curl_md5it(unsigned char *output,
|
||||
unsigned char *input);
|
||||
|
||||
#ifndef CURL_CA_BUNDLE
|
||||
/* Set this to the full path file name of the ca cert bundle */
|
||||
#undef CURL_CA_BUNDLE
|
||||
#endif
|
||||
|
||||
#endif /* __CA_BUNDLE_H */
|
@@ -1,4 +1,4 @@
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -220,4 +220,4 @@ int curl_fclose(FILE *file, int line, const char *source)
|
||||
#ifdef VMS
|
||||
int VOID_VAR_MEMDEBUG;
|
||||
#endif
|
||||
#endif /* MALLOCDEBUG */
|
||||
#endif /* CURLDEBUG */
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
|
@@ -48,7 +48,7 @@
|
||||
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
|
12
lib/multi.c
12
lib/multi.c
@@ -31,6 +31,9 @@
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
@@ -41,7 +44,7 @@
|
||||
#include "progress.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -299,7 +302,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
||||
easy=multi->easy.next;
|
||||
while(easy) {
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
fprintf(stderr, "HANDLE %p: State: %x\n",
|
||||
(char *)easy, easy->state);
|
||||
#endif
|
||||
@@ -437,8 +440,9 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
||||
|
||||
/* When we follow redirects, must to go back to the CONNECT state */
|
||||
if(easy->easy_conn->newurl) {
|
||||
easy->result = Curl_follow(easy->easy_handle,
|
||||
strdup(easy->easy_conn->newurl));
|
||||
char *newurl = easy->easy_conn->newurl;
|
||||
easy->easy_conn->newurl = NULL;
|
||||
easy->result = Curl_follow(easy->easy_handle, newurl);
|
||||
if(CURLE_OK == easy->result) {
|
||||
easy->state = CURLM_STATE_CONNECT;
|
||||
result = CURLM_CALL_MULTI_PERFORM;
|
||||
|
@@ -46,7 +46,7 @@
|
||||
#include "strtok.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -119,7 +119,7 @@ int Curl_parsenetrc(char *host,
|
||||
|
||||
sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC);
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
{
|
||||
/* This is a hack to allow testing.
|
||||
* If compiled with --enable-debug and CURL_DEBUG_NETRC is defined,
|
||||
@@ -141,7 +141,7 @@ int Curl_parsenetrc(char *host,
|
||||
free(override);
|
||||
}
|
||||
}
|
||||
#endif /* MALLOCDEBUG */
|
||||
#endif /* CURLDEBUG */
|
||||
|
||||
file = fopen(netrcbuffer, "r");
|
||||
if(file) {
|
||||
|
@@ -60,7 +60,7 @@
|
||||
#include "ftp.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
|
40
lib/sendf.c
40
lib/sendf.c
@@ -56,7 +56,7 @@
|
||||
#endif
|
||||
#include <string.h>
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -94,7 +94,6 @@ struct curl_slist *curl_slist_append(struct curl_slist *list,
|
||||
new_item->data = strdup(data);
|
||||
}
|
||||
if (new_item == NULL || new_item->data == NULL) {
|
||||
fprintf(stderr, "Cannot allocate memory for QUOTE list.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -229,6 +228,7 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
||||
ssize_t *written)
|
||||
{
|
||||
ssize_t bytes_written;
|
||||
CURLcode retcode;
|
||||
(void)conn;
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
@@ -244,13 +244,28 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
||||
switch(err) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
/* this is basicly the EWOULDBLOCK equivalent */
|
||||
/* The operation did not complete; the same TLS/SSL I/O function
|
||||
should be called again later. This is basicly an EWOULDBLOCK
|
||||
equivalent. */
|
||||
*written = 0;
|
||||
return CURLE_OK;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n",
|
||||
Curl_ourerrno());
|
||||
return CURLE_SEND_ERROR;
|
||||
case SSL_ERROR_SSL:
|
||||
{
|
||||
/* A failure in the SSL library occurred, usually a
|
||||
protocol error. The OpenSSL error queue contains more
|
||||
information on the error. */
|
||||
char error_buffer[120]; /* OpenSSL documents that this must be at least
|
||||
120 bytes long. */
|
||||
int sslerror = ERR_get_error();
|
||||
failf(conn->data, "SSL_write() error: %s\n",
|
||||
ERR_error_string(sslerror, error_buffer));
|
||||
return CURLE_SEND_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* a true error */
|
||||
failf(conn->data, "SSL_write() return error %d\n", err);
|
||||
@@ -271,27 +286,30 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
||||
}
|
||||
if(-1 == bytes_written) {
|
||||
int err = Curl_ourerrno();
|
||||
#ifdef WIN32
|
||||
if(WSAEWOULDBLOCK == err)
|
||||
|
||||
if(
|
||||
#ifdef WSAEWOULDBLOCK
|
||||
/* This is how Windows does it */
|
||||
(WSAEWOULDBLOCK == err)
|
||||
#else
|
||||
/* As pointed out by Christophe Demory on March 11 2003, errno
|
||||
may be EWOULDBLOCK or on some systems EAGAIN when it returned
|
||||
due to its inability to send off data without blocking. We
|
||||
therefor treat both error codes the same here */
|
||||
if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
|
||||
(EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
|
||||
#endif
|
||||
{
|
||||
)
|
||||
/* this is just a case of EWOULDBLOCK */
|
||||
*written=0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
bytes_written=0;
|
||||
}
|
||||
#ifdef USE_SSLEAY
|
||||
}
|
||||
#endif
|
||||
|
||||
*written = bytes_written;
|
||||
return (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
|
||||
retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/* client_write() sends data to the write callback(s)
|
||||
|
24
lib/setup.h
24
lib/setup.h
@@ -135,20 +135,40 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
|
||||
#define HAVE_ALARM
|
||||
#endif
|
||||
|
||||
#define PATH_CHAR ";"
|
||||
#define DIR_CHAR "\\"
|
||||
#define DOT_CHAR "_"
|
||||
|
||||
#else
|
||||
|
||||
#ifdef DJGPP
|
||||
#define sclose(x) close_s(x)
|
||||
#define sread(x,y,z) read_s(x,y,z)
|
||||
#define swrite(x,y,z) write_s(x,y,z)
|
||||
#define select(n,r,w,x,t) select_s(n,r,w,x,t)
|
||||
#define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z))
|
||||
#define IOCTL_3_ARGS
|
||||
#include <tcp.h>
|
||||
#ifdef word
|
||||
#undef word
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define sclose(x) close(x)
|
||||
#define sread(x,y,z) recv(x,y,z,0)
|
||||
#define swrite(x,y,z) send(x,y,z,0)
|
||||
#define HAVE_ALARM
|
||||
|
||||
#define PATH_CHAR ":"
|
||||
#endif
|
||||
|
||||
#define DIR_CHAR "/"
|
||||
#define DOT_CHAR "."
|
||||
|
||||
#ifdef DJGPP
|
||||
#undef DOT_CHAR
|
||||
#define DOT_CHAR "_"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRCASECMP
|
||||
/* this is for "-ansi -Wall -pedantic" to stop complaining! */
|
||||
extern int (strcasecmp)(const char *s1, const char *s2);
|
||||
|
@@ -24,12 +24,13 @@
|
||||
#include "setup.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "share.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
|
23
lib/ssluse.c
23
lib/ssluse.c
@@ -46,7 +46,7 @@
|
||||
#include <openssl/rand.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -786,6 +786,16 @@ Curl_SSLConnect(struct connectdata *conn)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* OpenSSL contains code to work-around lots of bugs and flaws in various
|
||||
SSL-implementations. SSL_CTX_set_options() is used to enabled those
|
||||
work-arounds. The man page for this option states that SSL_OP_ALL enables
|
||||
ll the work-arounds and that "It is usually safe to use SSL_OP_ALL to
|
||||
enable the bug workaround options if compatibility with somewhat broken
|
||||
implementations is desired."
|
||||
|
||||
*/
|
||||
SSL_CTX_set_options(conn->ssl.ctx, SSL_OP_ALL);
|
||||
|
||||
if(data->set.cert) {
|
||||
if (!cert_stuff(conn,
|
||||
data->set.cert,
|
||||
@@ -805,7 +815,7 @@ Curl_SSLConnect(struct connectdata *conn)
|
||||
}
|
||||
}
|
||||
|
||||
if(data->set.ssl.verifypeer){
|
||||
if(data->set.ssl.verifypeer) {
|
||||
SSL_CTX_set_verify(conn->ssl.ctx,
|
||||
SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
|
||||
SSL_VERIFY_CLIENT_ONCE,
|
||||
@@ -821,6 +831,15 @@ Curl_SSLConnect(struct connectdata *conn)
|
||||
else
|
||||
SSL_CTX_set_verify(conn->ssl.ctx, SSL_VERIFY_NONE, cert_verify_callback);
|
||||
|
||||
/* give application a chance to interfere with SSL set up. */
|
||||
if (data->set.ssl.fsslctx) {
|
||||
retcode = (*data->set.ssl.fsslctx)(data, conn->ssl.ctx,
|
||||
data->set.ssl.fsslctxp);
|
||||
if (retcode) {
|
||||
failf(data,"error signaled by ssl ctx callback");
|
||||
return retcode;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lets make an SSL structure */
|
||||
conn->ssl.handle = SSL_new (conn->ssl.ctx);
|
||||
|
@@ -45,7 +45,6 @@
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -84,7 +83,7 @@
|
||||
#include "arpa_telnet.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -756,7 +755,7 @@ static int check_telnet_options(struct connectdata *conn)
|
||||
if(conn->bits.user_passwd)
|
||||
{
|
||||
char *buf = malloc(256);
|
||||
sprintf(buf, "USER,%s", data->state.user);
|
||||
sprintf(buf, "USER,%s", conn->user);
|
||||
tn->telnet_vars = curl_slist_append(tn->telnet_vars, buf);
|
||||
|
||||
tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
|
||||
|
351
lib/transfer.c
351
lib/transfer.c
@@ -46,7 +46,6 @@
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -95,12 +94,15 @@
|
||||
#include "url.h"
|
||||
#include "getinfo.h"
|
||||
#include "ssluse.h"
|
||||
#include "http_digest.h"
|
||||
#include "http_ntlm.h"
|
||||
#include "http_negotiate.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -284,6 +286,9 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
/* header line within buffer loop */
|
||||
do {
|
||||
int hbufp_index;
|
||||
int rest_length;
|
||||
int full_length;
|
||||
int writetype;
|
||||
|
||||
/* str_start is start of line within buf */
|
||||
k->str_start = k->str;
|
||||
@@ -325,22 +330,24 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
break; /* read more and try again */
|
||||
}
|
||||
|
||||
/* decrease the size of the remaining buffer */
|
||||
nread -= (k->end_ptr - k->str)+1;
|
||||
/* decrease the size of the remaining (supposed) header line */
|
||||
rest_length = (k->end_ptr - k->str)+1;
|
||||
nread -= rest_length;
|
||||
|
||||
k->str = k->end_ptr + 1; /* move past new line */
|
||||
|
||||
full_length = k->str - k->str_start;
|
||||
|
||||
/*
|
||||
* We're about to copy a chunk of data to the end of the
|
||||
* already received header. We make sure that the full string
|
||||
* fit in the allocated header buffer, or else we enlarge
|
||||
* it.
|
||||
*/
|
||||
if (k->hbuflen + (k->str - k->str_start) >=
|
||||
if (k->hbuflen + full_length >=
|
||||
data->state.headersize) {
|
||||
char *newbuff;
|
||||
long newsize=MAX((k->hbuflen+
|
||||
(k->str-k->str_start))*3/2,
|
||||
long newsize=MAX((k->hbuflen+full_length)*3/2,
|
||||
data->state.headersize*2);
|
||||
hbufp_index = k->hbufp - data->state.headerbuff;
|
||||
newbuff = (char *)realloc(data->state.headerbuff, newsize);
|
||||
@@ -354,10 +361,11 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* copy to end of line */
|
||||
strncpy (k->hbufp, k->str_start, k->str - k->str_start);
|
||||
k->hbufp += k->str - k->str_start;
|
||||
k->hbuflen += k->str - k->str_start;
|
||||
strncpy (k->hbufp, k->str_start, full_length);
|
||||
k->hbufp += full_length;
|
||||
k->hbuflen += full_length;
|
||||
*k->hbufp = 0;
|
||||
k->end_ptr = k->hbufp;
|
||||
|
||||
k->p = data->state.headerbuff;
|
||||
|
||||
@@ -371,7 +379,14 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
!checkhttpprefix(data, data->state.headerbuff)) {
|
||||
/* this is not the beginning of a HTTP first header line */
|
||||
k->header = FALSE;
|
||||
if(nread)
|
||||
/* since there's more, this is a partial bad header */
|
||||
k->badheader = HEADER_PARTHEADER;
|
||||
else {
|
||||
/* this was all we read so its all a bad header */
|
||||
k->badheader = HEADER_ALLBAD;
|
||||
nread = rest_length;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -421,13 +436,13 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
|
||||
/* now, only output this if the header AND body are requested:
|
||||
*/
|
||||
k->writetype = CLIENTWRITE_HEADER;
|
||||
writetype = CLIENTWRITE_HEADER;
|
||||
if (data->set.http_include_header)
|
||||
k->writetype |= CLIENTWRITE_BODY;
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
|
||||
headerlen = k->p - data->state.headerbuff;
|
||||
|
||||
result = Curl_client_write(data, k->writetype,
|
||||
result = Curl_client_write(data, writetype,
|
||||
data->state.headerbuff,
|
||||
headerlen);
|
||||
if(result)
|
||||
@@ -445,11 +460,16 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
*/
|
||||
if(data->set.no_body)
|
||||
stop_reading = TRUE;
|
||||
else if(!conn->bits.close) {
|
||||
/* If this is not the last request before a close, we must
|
||||
set the maximum download size to the size of the
|
||||
expected document or else, we won't know when to stop
|
||||
reading! */
|
||||
else {
|
||||
/* If we know the expected size of this document, we set the
|
||||
maximum download size to the size of the expected
|
||||
document or else, we won't know when to stop reading!
|
||||
|
||||
Note that we set the download maximum even if we read a
|
||||
"Connection: close" header, to make sure that
|
||||
"Content-Length: 0" still prevents us from attempting to
|
||||
read the (missing) response-body.
|
||||
*/
|
||||
if(-1 != conn->size)
|
||||
conn->maxdownload = conn->size;
|
||||
}
|
||||
@@ -519,7 +539,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
/* If we have been told to fail hard on HTTP-errors,
|
||||
here is the check for that: */
|
||||
/* serious error, go home! */
|
||||
failf (data, "The requested file was not found");
|
||||
failf (data, "The requested URL returned error: %d",
|
||||
k->httpcode);
|
||||
return CURLE_HTTP_RETURNED_ERROR;
|
||||
}
|
||||
|
||||
@@ -701,9 +722,93 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
if(data->set.get_filetime)
|
||||
data->info.filetime = k->timeofdoc;
|
||||
}
|
||||
else if(checkprefix("WWW-Authenticate:", k->p) &&
|
||||
(401 == k->httpcode)) {
|
||||
/*
|
||||
* This page requires authentication
|
||||
*/
|
||||
char *start = k->p+strlen("WWW-Authenticate:");
|
||||
|
||||
/* pass all white spaces */
|
||||
while(*start && isspace((int)*start))
|
||||
start++;
|
||||
|
||||
#ifdef GSSAPI
|
||||
if (checkprefix("GSS-Negotiate", start)) {
|
||||
if(data->state.authwant == CURLAUTH_GSSNEGOTIATE) {
|
||||
/* if exactly this is wanted, go */
|
||||
int neg = Curl_input_negotiate(conn, start);
|
||||
if (neg == 0)
|
||||
conn->newurl = strdup(data->change.url);
|
||||
}
|
||||
else
|
||||
if(data->state.authwant & CURLAUTH_GSSNEGOTIATE)
|
||||
data->state.authavail |= CURLAUTH_GSSNEGOTIATE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_SSLEAY
|
||||
/* NTLM support requires the SSL crypto libs */
|
||||
if(checkprefix("NTLM", start)) {
|
||||
if(data->state.authwant == CURLAUTH_NTLM) {
|
||||
/* NTLM authentication is activated */
|
||||
CURLntlm ntlm =
|
||||
Curl_input_ntlm(conn, FALSE, start);
|
||||
|
||||
if(CURLNTLM_BAD != ntlm)
|
||||
conn->newurl = strdup(data->change.url); /* clone string */
|
||||
else
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
}
|
||||
else
|
||||
if(data->state.authwant & CURLAUTH_NTLM)
|
||||
data->state.authavail |= CURLAUTH_NTLM;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if(checkprefix("Digest", start)) {
|
||||
if(data->state.authwant == CURLAUTH_DIGEST) {
|
||||
/* Digest authentication is activated */
|
||||
CURLdigest dig = CURLDIGEST_BAD;
|
||||
|
||||
if(data->state.digest.nonce)
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
else
|
||||
dig = Curl_input_digest(conn, start);
|
||||
|
||||
if(CURLDIGEST_FINE == dig)
|
||||
/* We act on it. Store our new url, which happens to be
|
||||
the same one we already use! */
|
||||
conn->newurl = strdup(data->change.url); /* clone string */
|
||||
}
|
||||
else
|
||||
if(data->state.authwant & CURLAUTH_DIGEST) {
|
||||
/* We don't know if Digest is what we're gonna use, but we
|
||||
call this function anyway to store the digest data that
|
||||
is provided on this line, to skip the extra round-trip
|
||||
we need to do otherwise. We must sure to free this
|
||||
data! */
|
||||
Curl_input_digest(conn, start);
|
||||
data->state.authavail |= CURLAUTH_DIGEST;
|
||||
}
|
||||
}
|
||||
else if(checkprefix("Basic", start)) {
|
||||
if((data->state.authwant == CURLAUTH_BASIC) &&
|
||||
(k->httpcode == 401)) {
|
||||
/* We asked for Basic authentication but got a 401 back
|
||||
anyway, which basicly means our name+password isn't
|
||||
valid. */
|
||||
data->state.authavail = CURLAUTH_NONE;
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
}
|
||||
else if(data->state.authwant & CURLAUTH_BASIC) {
|
||||
data->state.authavail |= CURLAUTH_BASIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((k->httpcode >= 300 && k->httpcode < 400) &&
|
||||
(data->set.http_follow_location) &&
|
||||
checkprefix("Location:", k->p)) {
|
||||
if(data->set.http_follow_location) {
|
||||
/* this is the URL that the server advices us to get instead */
|
||||
char *ptr;
|
||||
char *start=k->p;
|
||||
@@ -715,11 +820,17 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
white spaces after the "Location:" keyword. */
|
||||
while(*start && isspace((int)*start ))
|
||||
start++;
|
||||
ptr = start; /* start scanning here */
|
||||
|
||||
/* scan through the string to find the end */
|
||||
while(*ptr && !isspace((int)*ptr))
|
||||
/* Scan through the string from the end to find the last
|
||||
non-space. k->end_ptr points to the actual terminating zero
|
||||
letter, move pointer one letter back and start from
|
||||
there. This logic strips off trailing whitespace, but keeps
|
||||
any embedded whitespace. */
|
||||
ptr = k->end_ptr-1;
|
||||
while((ptr>=start) && isspace((int)*ptr))
|
||||
ptr--;
|
||||
ptr++;
|
||||
|
||||
backup = *ptr; /* store the ending letter */
|
||||
if(ptr != start) {
|
||||
*ptr = '\0'; /* zero terminate */
|
||||
@@ -727,21 +838,28 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
*ptr = backup; /* restore ending letter */
|
||||
}
|
||||
}
|
||||
#if 0 /* for consideration */
|
||||
else {
|
||||
/* This is a Location: but we have not been instructed to
|
||||
follow it */
|
||||
infof(data, "We ignore this location header as instructed\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* End of header-checks. Write them to the client.
|
||||
*/
|
||||
|
||||
k->writetype = CLIENTWRITE_HEADER;
|
||||
writetype = CLIENTWRITE_HEADER;
|
||||
if (data->set.http_include_header)
|
||||
k->writetype |= CLIENTWRITE_BODY;
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
|
||||
if(data->set.verbose)
|
||||
Curl_debug(data, CURLINFO_HEADER_IN,
|
||||
k->p, k->hbuflen);
|
||||
|
||||
result = Curl_client_write(data, k->writetype, k->p,
|
||||
k->hbuflen);
|
||||
result = Curl_client_write(data, writetype, k->p, k->hbuflen);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -774,15 +892,41 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
write a piece of the body */
|
||||
if(conn->protocol&PROT_HTTP) {
|
||||
/* HTTP-only checks */
|
||||
|
||||
if(data->state.authavail) {
|
||||
if(data->state.authavail & CURLAUTH_GSSNEGOTIATE)
|
||||
data->state.authwant = CURLAUTH_GSSNEGOTIATE;
|
||||
else if(data->state.authavail & CURLAUTH_DIGEST)
|
||||
data->state.authwant = CURLAUTH_DIGEST;
|
||||
else if(data->state.authavail & CURLAUTH_NTLM)
|
||||
data->state.authwant = CURLAUTH_NTLM;
|
||||
else if(data->state.authavail & CURLAUTH_BASIC)
|
||||
data->state.authwant = CURLAUTH_BASIC;
|
||||
else
|
||||
data->state.authwant = CURLAUTH_NONE; /* none */
|
||||
|
||||
if(data->state.authwant)
|
||||
conn->newurl = strdup(data->change.url); /* clone string */
|
||||
|
||||
data->state.authavail = CURLAUTH_NONE; /* clear it here */
|
||||
}
|
||||
|
||||
if (conn->newurl) {
|
||||
/* abort after the headers if "follow Location" is set */
|
||||
infof (data, "Follow to new URL: %s\n", conn->newurl);
|
||||
if(conn->bits.close) {
|
||||
/* Abort after the headers if "follow Location" is set
|
||||
and we're set to close anyway. */
|
||||
k->keepon &= ~KEEP_READ;
|
||||
FD_ZERO(&k->rkeepfd);
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
else if (conn->resume_from &&
|
||||
/* We have a new url to load, but since we want to be able
|
||||
to re-use this connection properly, we read the full
|
||||
response in "ignore more" */
|
||||
k->ignorebody = TRUE;
|
||||
infof(data, "Ignoring the response-body\n");
|
||||
}
|
||||
if (conn->resume_from &&
|
||||
!k->content_range &&
|
||||
(data->set.httpreq==HTTPREQ_GET)) {
|
||||
/* we wanted to resume a download, although the server
|
||||
@@ -883,7 +1027,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
if(!conn->bits.chunk && (nread || k->badheader)) {
|
||||
/* If this is chunky transfer, it was already written */
|
||||
|
||||
if(k->badheader) {
|
||||
if(k->badheader && !k->ignorebody) {
|
||||
/* we parsed a piece of data wrongly assuming it was a header
|
||||
and now we output it as body instead */
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
@@ -904,6 +1048,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
Content-Encoding header. See Curl_readwrite_init; the
|
||||
memset() call initializes k->content_encoding to zero.
|
||||
08/28/02 jhrg */
|
||||
if(!k->ignorebody)
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
|
||||
nread);
|
||||
#ifdef HAVE_LIBZ
|
||||
@@ -1186,6 +1331,7 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
|
||||
k->maxfd = (conn->sockfd>conn->writesockfd?
|
||||
conn->sockfd:conn->writesockfd)+1;
|
||||
k->hbufp = data->state.headerbuff;
|
||||
k->ignorebody=FALSE;
|
||||
|
||||
Curl_pgrsTime(data, TIMER_PRETRANSFER);
|
||||
Curl_speedinit(data);
|
||||
@@ -1355,6 +1501,10 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
|
||||
data->state.this_is_a_follow = FALSE; /* reset this */
|
||||
data->state.errorbuf = FALSE; /* no error has occurred */
|
||||
|
||||
/* set preferred authentication, default to basic */
|
||||
data->state.authwant = data->set.httpauth?data->set.httpauth:CURLAUTH_BASIC;
|
||||
data->state.authavail = CURLAUTH_NONE; /* nothing so far */
|
||||
|
||||
/* If there was a list of cookie files to read and we haven't done it before,
|
||||
do it now! */
|
||||
if(data->change.cookielist) {
|
||||
@@ -1401,6 +1551,60 @@ CURLcode Curl_posttransfer(struct SessionHandle *data)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static int strlen_url(char *url)
|
||||
{
|
||||
char *ptr;
|
||||
int newlen=0;
|
||||
bool left=TRUE; /* left side of the ? */
|
||||
|
||||
for(ptr=url; *ptr; ptr++) {
|
||||
switch(*ptr) {
|
||||
case '?':
|
||||
left=FALSE;
|
||||
default:
|
||||
newlen++;
|
||||
break;
|
||||
case ' ':
|
||||
if(left)
|
||||
newlen+=3;
|
||||
else
|
||||
newlen++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return newlen;
|
||||
}
|
||||
|
||||
static void strcpy_url(char *output, char *url)
|
||||
{
|
||||
/* we must add this with whitespace-replacing */
|
||||
bool left=TRUE;
|
||||
char *iptr;
|
||||
char *optr = output;
|
||||
for(iptr = url; /* read from here */
|
||||
*iptr; /* until zero byte */
|
||||
iptr++) {
|
||||
switch(*iptr) {
|
||||
case '?':
|
||||
left=FALSE;
|
||||
default:
|
||||
*optr++=*iptr;
|
||||
break;
|
||||
case ' ':
|
||||
if(left) {
|
||||
*optr++='%'; /* add a '%' */
|
||||
*optr++='2'; /* add a '2' */
|
||||
*optr++='0'; /* add a '0' */
|
||||
}
|
||||
else
|
||||
*optr++='+'; /* add a '+' here */
|
||||
break;
|
||||
}
|
||||
}
|
||||
*optr=0; /* zero terminate output buffer */
|
||||
|
||||
}
|
||||
|
||||
CURLcode Curl_follow(struct SessionHandle *data,
|
||||
char *newurl) /* this 'newurl' is the Location: string,
|
||||
and it must be malloc()ed before passed
|
||||
@@ -1409,6 +1613,8 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
||||
/* Location: redirect */
|
||||
char prot[16]; /* URL protocol string storage */
|
||||
char letter; /* used for a silly sscanf */
|
||||
int newlen;
|
||||
char *newest;
|
||||
|
||||
if (data->set.maxredirs &&
|
||||
(data->set.followlocation >= data->set.maxredirs)) {
|
||||
@@ -1445,9 +1651,9 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
||||
*/
|
||||
char *protsep;
|
||||
char *pathsep;
|
||||
char *newest;
|
||||
|
||||
char *useurl = newurl;
|
||||
int urllen;
|
||||
|
||||
/* we must make our own copy of the URL to play with, as it may
|
||||
point to read-only data */
|
||||
@@ -1520,42 +1726,79 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
||||
*pathsep=0;
|
||||
}
|
||||
|
||||
newest=(char *)malloc( strlen(url_clone) +
|
||||
1 + /* possible slash */
|
||||
strlen(useurl) + 1/* zero byte */);
|
||||
/* If the new part contains a space, this is a mighty stupid redirect
|
||||
but we still make an effort to do "right". To the left of a '?'
|
||||
letter we replace each space with %20 while it is replaced with '+'
|
||||
on the right side of the '?' letter.
|
||||
*/
|
||||
newlen = strlen_url(useurl);
|
||||
|
||||
urllen = strlen(url_clone);
|
||||
|
||||
newest=(char *)malloc( urllen + 1 + /* possible slash */
|
||||
newlen + 1 /* zero byte */);
|
||||
|
||||
if(!newest)
|
||||
return CURLE_OUT_OF_MEMORY; /* go out from this */
|
||||
|
||||
sprintf(newest, "%s%s%s", url_clone,
|
||||
(('/' == useurl[0]) || (protsep && !*protsep))?"":"/",
|
||||
useurl);
|
||||
/* copy over the root url part */
|
||||
memcpy(newest, url_clone, urllen);
|
||||
|
||||
/* check if we need to append a slash */
|
||||
if(('/' == useurl[0]) || (protsep && !*protsep))
|
||||
;
|
||||
else
|
||||
newest[urllen++]='/';
|
||||
|
||||
/* then append the new piece on the right side */
|
||||
strcpy_url(&newest[urllen], useurl);
|
||||
|
||||
free(newurl); /* newurl is the allocated pointer */
|
||||
free(url_clone);
|
||||
newurl = newest;
|
||||
}
|
||||
else
|
||||
else {
|
||||
/* This is an absolute URL, don't allow the custom port number */
|
||||
data->state.allow_port = FALSE;
|
||||
|
||||
if(strchr(newurl, ' ')) {
|
||||
/* This new URL contains at least one space, this is a mighty stupid
|
||||
redirect but we still make an effort to do "right". */
|
||||
newlen = strlen_url(newurl);
|
||||
|
||||
newest = malloc(newlen+1); /* get memory for this */
|
||||
if(newest) {
|
||||
strcpy_url(newest, newurl); /* create a space-free URL */
|
||||
|
||||
free(newurl); /* that was no good */
|
||||
newurl = newest; /* use this instead now */
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(data->change.url_alloc)
|
||||
free(data->change.url);
|
||||
else
|
||||
data->change.url_alloc = TRUE; /* the URL is allocated */
|
||||
|
||||
/* TBD: set the URL with curl_setopt() */
|
||||
data->change.url = newurl;
|
||||
newurl = NULL; /* don't free! */
|
||||
|
||||
infof(data, "Follows Location: to new URL: '%s'\n", data->change.url);
|
||||
infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
|
||||
|
||||
/*
|
||||
* We get here when the HTTP code is 300-399. We need to perform
|
||||
* We get here when the HTTP code is 300-399 (and 401). We need to perform
|
||||
* differently based on exactly what return code there was.
|
||||
* Discussed on the curl mailing list and posted about on the 26th
|
||||
* of January 2001.
|
||||
*
|
||||
* News from 7.10.6: we can also get here on a 401, in case we act on a
|
||||
* HTTP authentication scheme other than Basic.
|
||||
*/
|
||||
switch(data->info.httpcode) {
|
||||
case 401:
|
||||
/* Act on an authentication, we keep on moving and do the Authorization:
|
||||
XXXX header in the HTTP request code snippet */
|
||||
break;
|
||||
case 300: /* Multiple Choices */
|
||||
case 306: /* Not used */
|
||||
case 307: /* Temporary Redirect */
|
||||
@@ -1653,9 +1896,29 @@ CURLcode Curl_perform(struct SessionHandle *data)
|
||||
* performed after this do-while loop.
|
||||
*/
|
||||
|
||||
do {
|
||||
int urlchanged = FALSE;
|
||||
do {
|
||||
Curl_pgrsTime(data, TIMER_STARTSINGLE);
|
||||
data->change.url_changed = FALSE;
|
||||
res = Curl_connect(data, &conn);
|
||||
|
||||
/* If a callback (or something) has altered the URL we should use within
|
||||
the Curl_connect(), we detect it here and act as if we are redirected
|
||||
to the new URL */
|
||||
urlchanged = data->change.url_changed;
|
||||
if ((CURLE_OK == res) && urlchanged) {
|
||||
char *newurl;
|
||||
res = Curl_done(conn);
|
||||
if(CURLE_OK == res) {
|
||||
newurl = strdup(data->change.url);
|
||||
res = Curl_follow(data, newurl);
|
||||
if(res)
|
||||
free(newurl);
|
||||
}
|
||||
}
|
||||
} while (urlchanged && res == CURLE_OK) ;
|
||||
|
||||
if(res == CURLE_OK) {
|
||||
res = Curl_do(&conn);
|
||||
|
||||
|
257
lib/url.c
257
lib/url.c
@@ -45,7 +45,6 @@
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -107,6 +106,8 @@
|
||||
#include "strtok.h"
|
||||
#include "share.h"
|
||||
#include "content_encoding.h"
|
||||
#include "http_digest.h"
|
||||
#include "http_negotiate.h"
|
||||
|
||||
/* And now for the protocols */
|
||||
#include "ftp.h"
|
||||
@@ -133,7 +134,7 @@
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
@@ -165,6 +166,11 @@ RETSIGTYPE alarmfunc(int signal)
|
||||
}
|
||||
#endif
|
||||
|
||||
void Curl_safefree(void *ptr)
|
||||
{
|
||||
if(ptr)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the internal function curl_easy_cleanup() calls. This should
|
||||
@@ -192,11 +198,8 @@ CURLcode Curl_close(struct SessionHandle *data)
|
||||
if(data->change.cookielist) /* clean up list if any */
|
||||
curl_slist_free_all(data->change.cookielist);
|
||||
|
||||
if(data->state.auth_host)
|
||||
free(data->state.auth_host);
|
||||
|
||||
if(data->state.scratch)
|
||||
free(data->state.scratch);
|
||||
Curl_safefree(data->state.auth_host);
|
||||
Curl_safefree(data->state.scratch);
|
||||
|
||||
if(data->change.proxy_alloc)
|
||||
free(data->change.proxy);
|
||||
@@ -207,8 +210,7 @@ CURLcode Curl_close(struct SessionHandle *data)
|
||||
if(data->change.url_alloc)
|
||||
free(data->change.url);
|
||||
|
||||
if(data->state.headerbuff)
|
||||
free(data->state.headerbuff);
|
||||
Curl_safefree(data->state.headerbuff);
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
if(data->set.cookiejar) {
|
||||
@@ -223,8 +225,9 @@ CURLcode Curl_close(struct SessionHandle *data)
|
||||
/* free the connection cache */
|
||||
free(data->state.connects);
|
||||
|
||||
if(data->info.contenttype)
|
||||
free(data->info.contenttype);
|
||||
Curl_safefree(data->info.contenttype);
|
||||
|
||||
Curl_digest_cleanup(data);
|
||||
|
||||
free(data);
|
||||
return CURLE_OK;
|
||||
@@ -719,6 +722,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||
}
|
||||
data->set.set_url = va_arg(param, char *);
|
||||
data->change.url = data->set.set_url;
|
||||
data->change.url_changed = TRUE;
|
||||
break;
|
||||
case CURLOPT_PORT:
|
||||
/*
|
||||
@@ -838,6 +842,26 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||
data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
|
||||
break;
|
||||
|
||||
case CURLOPT_HTTPAUTH:
|
||||
/*
|
||||
* Set HTTP Authentication type BITMASK.
|
||||
*/
|
||||
{
|
||||
long auth = va_arg(param, long);
|
||||
/* switch off bits we can't support */
|
||||
#ifndef USE_SSLEAY
|
||||
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
|
||||
#endif
|
||||
#ifndef GSSAPI
|
||||
auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
|
||||
#endif
|
||||
if(!auth)
|
||||
return CURLE_FAILED_INIT; /* no supported types left! */
|
||||
|
||||
data->set.httpauth = auth;
|
||||
}
|
||||
break;
|
||||
|
||||
case CURLOPT_USERPWD:
|
||||
/*
|
||||
* user:password to use in the operation
|
||||
@@ -1067,6 +1091,18 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||
*/
|
||||
data->set.ssl.verifyhost = va_arg(param, long);
|
||||
break;
|
||||
case CURLOPT_SSL_CTX_FUNCTION:
|
||||
/*
|
||||
* Set a SSL_CTX callback
|
||||
*/
|
||||
data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
|
||||
break;
|
||||
case CURLOPT_SSL_CTX_DATA:
|
||||
/*
|
||||
* Set a SSL_CTX callback parameter pointer
|
||||
*/
|
||||
data->set.ssl.fsslctxp = va_arg(param, void *);
|
||||
break;
|
||||
case CURLOPT_CAINFO:
|
||||
/*
|
||||
* Set CA info for SSL connection. Specify file name of the CA certificate
|
||||
@@ -1196,14 +1232,9 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
||||
/* This is set if protocol-specific cleanups should be made */
|
||||
conn->curl_disconnect(conn);
|
||||
|
||||
if(conn->proto.generic)
|
||||
free(conn->proto.generic);
|
||||
|
||||
if(conn->newurl)
|
||||
free(conn->newurl);
|
||||
|
||||
if(conn->path) /* the URL path part */
|
||||
free(conn->path);
|
||||
Curl_safefree(conn->proto.generic);
|
||||
Curl_safefree(conn->newurl);
|
||||
Curl_safefree(conn->path); /* the URL path part */
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
Curl_SSL_Close(conn);
|
||||
@@ -1215,27 +1246,20 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
||||
if(-1 != conn->firstsocket)
|
||||
sclose(conn->firstsocket);
|
||||
|
||||
if(conn->allocptr.proxyuserpwd)
|
||||
free(conn->allocptr.proxyuserpwd);
|
||||
if(conn->allocptr.uagent)
|
||||
free(conn->allocptr.uagent);
|
||||
if(conn->allocptr.userpwd)
|
||||
free(conn->allocptr.userpwd);
|
||||
if(conn->allocptr.accept_encoding)
|
||||
free(conn->allocptr.accept_encoding);
|
||||
if(conn->allocptr.rangeline)
|
||||
free(conn->allocptr.rangeline);
|
||||
if(conn->allocptr.ref)
|
||||
free(conn->allocptr.ref);
|
||||
if(conn->allocptr.cookie)
|
||||
free(conn->allocptr.cookie);
|
||||
if(conn->allocptr.host)
|
||||
free(conn->allocptr.host);
|
||||
if(conn->allocptr.cookiehost)
|
||||
free(conn->allocptr.cookiehost);
|
||||
|
||||
if(conn->proxyhost)
|
||||
free(conn->proxyhost);
|
||||
Curl_safefree(conn->user);
|
||||
Curl_safefree(conn->passwd);
|
||||
Curl_safefree(conn->proxyuser);
|
||||
Curl_safefree(conn->proxypasswd);
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
Curl_safefree(conn->allocptr.uagent);
|
||||
Curl_safefree(conn->allocptr.userpwd);
|
||||
Curl_safefree(conn->allocptr.accept_encoding);
|
||||
Curl_safefree(conn->allocptr.rangeline);
|
||||
Curl_safefree(conn->allocptr.ref);
|
||||
Curl_safefree(conn->allocptr.cookie);
|
||||
Curl_safefree(conn->allocptr.host);
|
||||
Curl_safefree(conn->allocptr.cookiehost);
|
||||
Curl_safefree(conn->proxyhost);
|
||||
|
||||
Curl_free_ssl_config(&conn->ssl_config);
|
||||
|
||||
@@ -1318,11 +1342,13 @@ ConnectionExists(struct SessionHandle *data,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(needle->protocol & PROT_FTP) {
|
||||
/* This is FTP, verify that we're using the same name and
|
||||
password as well */
|
||||
if(!strequal(needle->data->state.user, check->proto.ftp->user) ||
|
||||
!strequal(needle->data->state.passwd, check->proto.ftp->passwd)) {
|
||||
if((needle->protocol & PROT_FTP) ||
|
||||
((needle->protocol & PROT_HTTP) &&
|
||||
(needle->data->state.authwant==CURLAUTH_NTLM))) {
|
||||
/* This is FTP or HTTP+NTLM, verify that we're using the same name
|
||||
and password as well */
|
||||
if(!strequal(needle->user, check->user) ||
|
||||
!strequal(needle->passwd, check->passwd)) {
|
||||
/* one of them was different */
|
||||
continue;
|
||||
}
|
||||
@@ -1535,7 +1561,7 @@ static int handleSock5Proxy(
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((socksreq[0] != 5) || /* version */
|
||||
if ((socksreq[0] != 1) || /* version */
|
||||
(socksreq[1] != 0)) { /* status */
|
||||
failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
|
||||
socksreq[0], socksreq[1]);
|
||||
@@ -1678,8 +1704,8 @@ static CURLcode ConnectPlease(struct connectdata *conn,
|
||||
#endif
|
||||
|
||||
if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
|
||||
return handleSock5Proxy(conn->data->state.proxyuser,
|
||||
conn->data->state.proxypasswd,
|
||||
return handleSock5Proxy(conn->proxyuser,
|
||||
conn->proxypasswd,
|
||||
conn,
|
||||
conn->firstsocket) ?
|
||||
CURLE_COULDNT_CONNECT : CURLE_OK;
|
||||
@@ -1803,6 +1829,11 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
unsigned int prev_alarm=0;
|
||||
#endif
|
||||
char endbracket;
|
||||
char user[MAX_CURL_USER_LENGTH];
|
||||
char passwd[MAX_CURL_PASSWORD_LENGTH];
|
||||
bool passwdgiven=FALSE; /* set TRUE if an application-provided password has
|
||||
been set */
|
||||
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction keep_sigact; /* store the old struct here */
|
||||
@@ -2016,29 +2047,36 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
* Take care of proxy authentication stuff
|
||||
*************************************************************/
|
||||
if(conn->bits.proxy_user_passwd) {
|
||||
data->state.proxyuser[0] =0;
|
||||
data->state.proxypasswd[0]=0;
|
||||
char proxyuser[MAX_CURL_USER_LENGTH]="";
|
||||
char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
|
||||
|
||||
if(*data->set.proxyuserpwd != ':') {
|
||||
/* the name is given, get user+password */
|
||||
sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]",
|
||||
data->state.proxyuser, data->state.proxypasswd);
|
||||
proxyuser, proxypasswd);
|
||||
}
|
||||
else
|
||||
/* no name given, get the password only */
|
||||
sscanf(data->set.proxyuserpwd+1, "%127[^\n]", data->state.proxypasswd);
|
||||
sscanf(data->set.proxyuserpwd+1, "%127[^\n]", proxypasswd);
|
||||
|
||||
/* check for password, if no ask for one */
|
||||
if( !data->state.proxypasswd[0] ) {
|
||||
if( !proxypasswd[0] ) {
|
||||
if(data->set.fpasswd( data->set.passwd_client,
|
||||
"proxy password:",
|
||||
data->state.proxypasswd,
|
||||
sizeof(data->state.proxypasswd))) {
|
||||
proxypasswd,
|
||||
sizeof(proxypasswd))) {
|
||||
failf(data, "Bad password from password callback");
|
||||
return CURLE_BAD_PASSWORD_ENTERED;
|
||||
}
|
||||
}
|
||||
|
||||
conn->proxyuser = strdup(proxyuser);
|
||||
if(!conn->proxyuser)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
conn->proxypasswd = strdup(proxypasswd);
|
||||
if(!conn->proxypasswd)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
@@ -2048,7 +2086,6 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
conn->ppath = conn->path;
|
||||
conn->hostname = conn->name;
|
||||
|
||||
|
||||
/*************************************************************
|
||||
* Detect what (if any) proxy to use
|
||||
*************************************************************/
|
||||
@@ -2149,6 +2186,45 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
|
||||
if(proxy && *proxy) {
|
||||
/* we have a proxy here to set */
|
||||
char *ptr;
|
||||
char user[MAX_CURL_USER_LENGTH];
|
||||
char passwd[MAX_CURL_PASSWORD_LENGTH];
|
||||
|
||||
/* skip the possible protocol piece */
|
||||
ptr=strstr(proxy, "://");
|
||||
if(ptr)
|
||||
ptr += 3;
|
||||
else
|
||||
ptr = proxy;
|
||||
|
||||
/* check for an @-letter */
|
||||
ptr = strchr(ptr, '@');
|
||||
if(ptr && (2 == sscanf(proxy, "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
|
||||
"%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
|
||||
user, passwd))) {
|
||||
/* found user and password, rip them out */
|
||||
if(conn->proxyuser)
|
||||
free(conn->proxyuser);
|
||||
conn->proxyuser = strdup(user);
|
||||
|
||||
if(!conn->proxyuser)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(conn->proxypasswd)
|
||||
free(conn->proxypasswd);
|
||||
conn->proxypasswd = strdup(passwd);
|
||||
|
||||
if(!conn->proxypasswd)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
conn->bits.proxy_user_passwd = TRUE; /* enable it */
|
||||
|
||||
ptr = strdup(ptr+1);
|
||||
free(proxy); /* free the former data */
|
||||
proxy = ptr; /* now use this instead */
|
||||
}
|
||||
|
||||
|
||||
data->change.proxy = proxy;
|
||||
data->change.proxy_alloc=TRUE; /* this needs to be freed later */
|
||||
conn->bits.httpproxy = TRUE;
|
||||
@@ -2526,8 +2602,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
*
|
||||
* 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->user - non-zero length if defined
|
||||
* conn->passwd - ditto
|
||||
* conn->hostname - remove user name and password
|
||||
*/
|
||||
|
||||
@@ -2538,8 +2614,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
* 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;
|
||||
user[0] =0; /* to make everything well-defined */
|
||||
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
|
||||
@@ -2566,31 +2642,31 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
if(*userpass != ':') {
|
||||
/* the name is given, get user+password */
|
||||
sscanf(userpass, "%127[^:@]:%127[^@]",
|
||||
data->state.user, data->state.passwd);
|
||||
user, passwd);
|
||||
}
|
||||
else
|
||||
/* no name given, get the password only */
|
||||
sscanf(userpass, ":%127[^@]", data->state.passwd);
|
||||
sscanf(userpass, ":%127[^@]", 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(user[0]) {
|
||||
char *newname=curl_unescape(user, 0);
|
||||
if(strlen(newname) < sizeof(user)) {
|
||||
strcpy(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]) {
|
||||
if (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);
|
||||
char *newpasswd=curl_unescape(passwd, 0);
|
||||
if(strlen(newpasswd) < sizeof(passwd)) {
|
||||
strcpy(passwd, newpasswd);
|
||||
}
|
||||
free(newpasswd);
|
||||
|
||||
/* we have set the password */
|
||||
data->state.passwdgiven = TRUE;
|
||||
passwdgiven = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2609,35 +2685,35 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
if(*data->set.userpwd != ':') {
|
||||
/* the name is given, get user+password */
|
||||
sscanf(data->set.userpwd, "%127[^:]:%127[^\n]",
|
||||
data->state.user, data->state.passwd);
|
||||
user, passwd);
|
||||
if(strchr(data->set.userpwd, ':'))
|
||||
/* a colon means the password was given, even if blank */
|
||||
data->state.passwdgiven = TRUE;
|
||||
passwdgiven = TRUE;
|
||||
}
|
||||
else
|
||||
/* no name given, starts with a colon, get the password only */
|
||||
sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd);
|
||||
sscanf(data->set.userpwd+1, "%127[^\n]", passwd);
|
||||
}
|
||||
|
||||
if ((data->set.use_netrc != CURL_NETRC_IGNORED) &&
|
||||
!data->state.passwdgiven) { /* need passwd */
|
||||
!passwdgiven) { /* need passwd */
|
||||
if(Curl_parsenetrc(conn->hostname,
|
||||
data->state.user,
|
||||
data->state.passwd)) {
|
||||
user,
|
||||
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 */
|
||||
data->state.passwdgiven = TRUE;
|
||||
passwdgiven = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we have a user but no password, ask for one */
|
||||
if(conn->bits.user_passwd && !data->state.passwdgiven ) {
|
||||
if(conn->bits.user_passwd && !passwdgiven ) {
|
||||
if(data->set.fpasswd(data->set.passwd_client,
|
||||
"password:", data->state.passwd,
|
||||
sizeof(data->state.passwd)))
|
||||
"password:", passwd,
|
||||
sizeof(passwd)))
|
||||
return CURLE_BAD_PASSWORD_ENTERED;
|
||||
}
|
||||
|
||||
@@ -2646,14 +2722,18 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
/* If our protocol needs a password and we have none, use the defaults */
|
||||
if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) &&
|
||||
!conn->bits.user_passwd &&
|
||||
!data->state.passwdgiven) {
|
||||
!passwdgiven) {
|
||||
|
||||
strcpy(data->state.user, CURL_DEFAULT_USER);
|
||||
strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
|
||||
strcpy(user, CURL_DEFAULT_USER);
|
||||
strcpy(passwd, CURL_DEFAULT_PASSWORD);
|
||||
|
||||
/* This is the default password, so DON'T set conn->bits.user_passwd */
|
||||
}
|
||||
|
||||
/* store user + password */
|
||||
conn->user = strdup(user);
|
||||
conn->passwd = strdup(passwd);
|
||||
|
||||
/*************************************************************
|
||||
* Check the current list of connections to see if we can
|
||||
* re-use an already existing one or if we have to create a
|
||||
@@ -2713,6 +2793,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
otherwise */
|
||||
conn->maxdownload = -1; /* might have been used previously! */
|
||||
|
||||
free(old_conn->user);
|
||||
free(old_conn->passwd);
|
||||
|
||||
free(old_conn); /* we don't need this anymore */
|
||||
|
||||
/*
|
||||
@@ -2817,6 +2900,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
if(conn->bits.reuse) {
|
||||
/* re-used connection, no resolving is necessary */
|
||||
hostaddr = NULL;
|
||||
conn->connect_addr = NULL; /* we don't connect now so we don't have any
|
||||
fresh connect_addr struct to point to */
|
||||
}
|
||||
else if(!data->change.proxy || !*data->change.proxy) {
|
||||
/* If not connecting via a proxy, extract the port from the URL, if it is
|
||||
@@ -2893,7 +2978,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
if(conn->bits.proxy_user_passwd) {
|
||||
char *authorization;
|
||||
snprintf(data->state.buffer, BUFSIZE, "%s:%s",
|
||||
data->state.proxyuser, data->state.proxypasswd);
|
||||
conn->proxyuser, conn->proxypasswd);
|
||||
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
|
||||
&authorization) >= 0) {
|
||||
if(conn->allocptr.proxyuserpwd)
|
||||
@@ -3013,7 +3098,7 @@ CURLcode Curl_done(struct connectdata *conn)
|
||||
if(conn->connect_addr)
|
||||
Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */
|
||||
|
||||
#if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST)
|
||||
#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
|
||||
/* scan for DNS cache entries still marked as in use */
|
||||
Curl_hash_apply(data->hostcache,
|
||||
NULL, Curl_scan_cache_used);
|
||||
|
@@ -42,4 +42,5 @@ bool Curl_ssl_config_matches(struct ssl_config_data* data,
|
||||
bool Curl_clone_ssl_config(struct ssl_config_data* source,
|
||||
struct ssl_config_data* dest);
|
||||
void Curl_free_ssl_config(struct ssl_config_data* sslc);
|
||||
void Curl_safefree(void *ptr);
|
||||
#endif
|
||||
|
@@ -83,7 +83,11 @@
|
||||
#include "hash.h"
|
||||
|
||||
#ifdef HAVE_ZLIB_H
|
||||
#include <zlib.h> /* for content-encoding 08/28/02 jhrg */
|
||||
#include <zlib.h> /* for content-encoding */
|
||||
#endif
|
||||
|
||||
#ifdef GSSAPI
|
||||
#include <gssapi.h>
|
||||
#endif
|
||||
|
||||
/* Download buffer size, keep it fairly big for speed reasons */
|
||||
@@ -141,6 +145,8 @@ struct ssl_config_data {
|
||||
char *egdsocket; /* path to file containing the EGD daemon socket */
|
||||
char *cipher_list; /* list of ciphers to use */
|
||||
long numsessions; /* SSL session id cache size */
|
||||
curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
|
||||
void *fsslctxp; /*parameter for call back */
|
||||
};
|
||||
|
||||
/* information stored about one single SSL session */
|
||||
@@ -152,6 +158,36 @@ struct curl_ssl_session {
|
||||
struct ssl_config_data ssl_config; /* setup for this session */
|
||||
};
|
||||
|
||||
/* Struct used for Digest challenge-response authentication */
|
||||
struct digestdata {
|
||||
char *nonce;
|
||||
char *cnonce;
|
||||
char *realm;
|
||||
int algo;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
NTLMSTATE_NONE,
|
||||
NTLMSTATE_TYPE1,
|
||||
NTLMSTATE_TYPE2,
|
||||
NTLMSTATE_TYPE3,
|
||||
NTLMSTATE_LAST
|
||||
} curlntlm;
|
||||
|
||||
/* Struct used for Digest challenge-response authentication */
|
||||
struct ntlmdata {
|
||||
curlntlm state;
|
||||
unsigned char nonce[8];
|
||||
};
|
||||
|
||||
#ifdef GSSAPI
|
||||
struct negotiatedata {
|
||||
OM_uint32 status;
|
||||
gss_ctx_id_t context;
|
||||
gss_name_t server_name;
|
||||
gss_buffer_desc output_token;
|
||||
};
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* HTTP unique setup
|
||||
@@ -306,7 +342,6 @@ struct Curl_transfer_keeper {
|
||||
/* for the low speed checks: */
|
||||
time_t timeofdoc;
|
||||
long bodywrites;
|
||||
int writetype;
|
||||
|
||||
char *buf;
|
||||
char *uploadbuf;
|
||||
@@ -325,8 +360,9 @@ struct Curl_transfer_keeper {
|
||||
|
||||
bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
|
||||
and we're uploading the last chunk */
|
||||
};
|
||||
|
||||
bool ignorebody; /* we read a response-body but we ignore it! */
|
||||
};
|
||||
|
||||
/*
|
||||
* The connectdata struct contains all fields and variables that should be
|
||||
@@ -377,6 +413,12 @@ struct connectdata {
|
||||
|
||||
char *proxyhost; /* name of the http proxy host */
|
||||
|
||||
char *user; /* user name string, allocated */
|
||||
char *passwd; /* password string, allocated */
|
||||
|
||||
char *proxyuser; /* proxy user name string, allocated */
|
||||
char *proxypasswd; /* proxy password string, allocated */
|
||||
|
||||
struct timeval now; /* "current" time */
|
||||
struct timeval created; /* creation time */
|
||||
int firstsocket; /* the main socket to use */
|
||||
@@ -432,7 +474,7 @@ struct connectdata {
|
||||
struct dynamically_allocated_data {
|
||||
char *proxyuserpwd; /* free later if not NULL! */
|
||||
char *uagent; /* free later if not NULL! */
|
||||
char *accept_encoding; /* free later if not NULL! 08/28/02 jhrg */
|
||||
char *accept_encoding; /* free later if not NULL! */
|
||||
char *userpwd; /* free later if not NULL! */
|
||||
char *rangeline; /* free later if not NULL! */
|
||||
char *ref; /* free later if not NULL! */
|
||||
@@ -491,9 +533,14 @@ struct connectdata {
|
||||
|
||||
curl_read_callback fread; /* function that reads the input */
|
||||
void *fread_in; /* pointer to pass to the fread() above */
|
||||
|
||||
struct ntlmdata ntlm; /* NTLM differs from other authentication schemes
|
||||
because it authenticates connections, not
|
||||
single requests! */
|
||||
struct ntlmdata proxyntlm; /* NTLM data for proxy */
|
||||
};
|
||||
|
||||
/* The end of connectdata. 08/27/02 jhrg */
|
||||
/* The end of connectdata. */
|
||||
|
||||
/*
|
||||
* Struct to keep statistical and informational data.
|
||||
@@ -501,7 +548,7 @@ struct connectdata {
|
||||
struct PureInfo {
|
||||
int httpcode;
|
||||
int httpversion;
|
||||
long filetime; /* If requested, this is might get set. Set to -1 if
|
||||
time_t filetime; /* If requested, this is might get set. Set to -1 if
|
||||
the time was unretrievable */
|
||||
long header_size; /* size of read header(s) in bytes */
|
||||
long request_size; /* the amount of bytes sent in the request(s) */
|
||||
@@ -564,6 +611,8 @@ typedef enum {
|
||||
* Session-data MUST be put in the connectdata struct and here. */
|
||||
#define MAX_CURL_USER_LENGTH 256
|
||||
#define MAX_CURL_PASSWORD_LENGTH 256
|
||||
#define MAX_CURL_USER_LENGTH_TXT "255"
|
||||
#define MAX_CURL_PASSWORD_LENGTH_TXT "255"
|
||||
|
||||
struct UrlState {
|
||||
enum {
|
||||
@@ -573,14 +622,6 @@ struct UrlState {
|
||||
} used_interface;
|
||||
|
||||
/* buffers to store authentication data in, as parsed from input options */
|
||||
char user[MAX_CURL_USER_LENGTH];
|
||||
char passwd[MAX_CURL_PASSWORD_LENGTH];
|
||||
char proxyuser[MAX_CURL_USER_LENGTH];
|
||||
char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
|
||||
|
||||
bool passwdgiven; /* set TRUE if an application-provided password has been
|
||||
set */
|
||||
|
||||
struct timeval keeps_speed; /* for the progress meter really */
|
||||
|
||||
/* 'connects' will be an allocated array with pointers. If the pointer is
|
||||
@@ -617,6 +658,15 @@ struct UrlState {
|
||||
#endif
|
||||
bool allow_port; /* Is set.use_port allowed to take effect or not. This
|
||||
is always set TRUE when curl_easy_perform() is called. */
|
||||
|
||||
struct digestdata digest;
|
||||
|
||||
#ifdef GSSAPI
|
||||
struct negotiatedata negotiate;
|
||||
#endif
|
||||
|
||||
long authwant; /* inherited from what the user set with CURLOPT_HTTPAUTH */
|
||||
long authavail; /* what the server reports */
|
||||
};
|
||||
|
||||
|
||||
@@ -630,6 +680,10 @@ struct UrlState {
|
||||
struct DynamicStatic {
|
||||
char *url; /* work URL, copied from UserDefined */
|
||||
bool url_alloc; /* URL string is malloc()'ed */
|
||||
bool url_changed; /* set on CURL_OPT_URL, used to detect if the URL was
|
||||
changed after the connect phase, as we allow callback
|
||||
to change it and if so, we reconnect to use the new
|
||||
URL instead */
|
||||
char *proxy; /* work proxy, copied from UserDefined */
|
||||
bool proxy_alloc; /* http proxy string is malloc()'ed */
|
||||
char *referer; /* referer string */
|
||||
@@ -661,6 +715,7 @@ struct UserDefined {
|
||||
char *set_proxy; /* proxy to use */
|
||||
long use_port; /* which port to use (when not using default) */
|
||||
char *userpwd; /* <user:password>, if used */
|
||||
long httpauth; /* what kind of HTTP authentication to use (bitmask) */
|
||||
char *set_range; /* range, if used. See README for detailed specification
|
||||
on this syntax. */
|
||||
long followlocation; /* as in HTTP Location: */
|
||||
|
@@ -114,6 +114,10 @@ char *curl_version(void)
|
||||
sprintf(ptr, " zlib/%s", zlibVersion());
|
||||
ptr += strlen(ptr);
|
||||
#endif
|
||||
#ifdef GSSAPI
|
||||
sprintf(ptr, " GSS");
|
||||
ptr += strlen(ptr);
|
||||
#endif
|
||||
|
||||
return version;
|
||||
}
|
||||
@@ -168,9 +172,16 @@ static curl_version_info_data version_info = {
|
||||
#endif
|
||||
#ifdef USE_SSLEAY
|
||||
| CURL_VERSION_SSL
|
||||
| CURL_VERSION_NTLM /* since this requires OpenSSL */
|
||||
#endif
|
||||
#ifdef HAVE_LIBZ
|
||||
| CURL_VERSION_LIBZ
|
||||
#endif
|
||||
#ifdef GSSAPI
|
||||
| CURL_VERSION_GSSNEGOTIATE
|
||||
#endif
|
||||
#ifdef CURLDEBUG
|
||||
| CURL_VERSION_DEBUG
|
||||
#endif
|
||||
,
|
||||
NULL, /* ssl_version */
|
||||
|
5
maketgz
5
maketgz
@@ -134,3 +134,8 @@ echo ""
|
||||
ls -l $targz $bzip2 $zip
|
||||
|
||||
md5sum $targz $bzip2 $zip
|
||||
|
||||
echo "Run these commands:"
|
||||
echo "gpg -b -a $targz"
|
||||
echo "gpg -b -a $bzip2"
|
||||
echo "gpg -b -a $zip"
|
||||
|
2
packages/DOS/.cvsignore
Normal file
2
packages/DOS/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
1
packages/DOS/Makefile.am
Normal file
1
packages/DOS/Makefile.am
Normal file
@@ -0,0 +1 @@
|
||||
EXTRA_DIST = README common.dj
|
4
packages/DOS/README
Normal file
4
packages/DOS/README
Normal file
@@ -0,0 +1,4 @@
|
||||
Gisle Vanem made curl build fine on DOS (and MingW) with djgpp, OpenSSL and his
|
||||
Watt-32 stack.
|
||||
|
||||
'make djgpp' in the root curl dir should build it fine.
|
56
packages/DOS/common.dj
Normal file
56
packages/DOS/common.dj
Normal file
@@ -0,0 +1,56 @@
|
||||
#
|
||||
# Common defines for curl (djgpp/Watt-32)
|
||||
#
|
||||
# Assumes you've unpacked cURL with short-file names
|
||||
# I.e use "set LFN=n" before untaring on Win9x/XP.
|
||||
# Requires sed, yacc, rm and the usual stuff.
|
||||
#
|
||||
|
||||
.SUFFIXES: .exe .y
|
||||
|
||||
MAKEFILE = Makefile.dj
|
||||
|
||||
#
|
||||
# OpenSSL is available from www.openssl.org and builds okay
|
||||
# with djgpp/Watt-32. Set to 0 if you don't need https URLs
|
||||
# (reduces curl.exe with approx 700 kB)
|
||||
#
|
||||
USE_SSL = 1
|
||||
|
||||
default: all
|
||||
|
||||
#
|
||||
# Root directory for Waterloo tcp/ip. WATT_ROOT should be set
|
||||
# during Watt-32 install.
|
||||
#
|
||||
WATT32_ROOT = $(subst \,/,$(WATT_ROOT))
|
||||
OPENSSL_ROOT = /net/openssl.098
|
||||
ZLIB_ROOT = $(DJDIR)/contrib/zlib
|
||||
|
||||
CC = gcc
|
||||
YACC = bison -y
|
||||
|
||||
CFLAGS = -g -O2 -I. -I../include -Wall -DHAVE_CONFIG_H
|
||||
|
||||
ifeq ($(USE_SSL),1)
|
||||
CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H
|
||||
endif
|
||||
|
||||
#
|
||||
# Generated dependencies; Due to some hacks in gcc 2.95+ and djgpp 2.03
|
||||
# we must prevent "$(DJDIR)/bin/../include/sys/version.h" from beeing
|
||||
# included in dependency output (or else this makefile cannot be used on
|
||||
# another machine). We therefore use a special 'specs' file during
|
||||
# pre-processing.
|
||||
#
|
||||
MM_SPECS = $(TMPDIR)/specs
|
||||
|
||||
depend: $(DEPEND_PREREQ)
|
||||
@echo Generating dependencies..
|
||||
@copy $(MAKEFILE) Makefile.bak
|
||||
@echo "*cpp: %(cpp_cpu) %{posix:-D_POSIX_SOURCE} -remap" > $(MM_SPECS)
|
||||
sed -e "/^# DO NOT DELETE THIS LINE/,$$d" < Makefile.bak > $(MAKEFILE)
|
||||
echo "# DO NOT DELETE THIS LINE" >> $(MAKEFILE)
|
||||
$(CC) -MM -specs=$(MM_SPECS) $(CFLAGS) $(SOURCES) >> $(MAKEFILE)
|
||||
rm -f $(MM_SPECS)
|
||||
|
@@ -1,3 +1,3 @@
|
||||
SUBDIRS = Win32 Linux Solaris EPM
|
||||
SUBDIRS = Win32 Linux Solaris EPM DOS
|
||||
|
||||
EXTRA_DIST = README
|
||||
|
@@ -11,6 +11,14 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||
|
||||
bin_PROGRAMS = curl #memtest
|
||||
|
||||
if HAVE_LIBZ
|
||||
# libz available, attempt to compress the help data
|
||||
MKHELPOPT=-c
|
||||
else
|
||||
# no libz, don't try to compress
|
||||
MKHELPOPT=
|
||||
endif
|
||||
|
||||
#memtest_SOURCES = memtest.c
|
||||
#memtest_LDADD = $(top_srcdir)/lib/libcurl.la
|
||||
|
||||
@@ -24,7 +32,7 @@ BUILT_SOURCES = hugehelp.c
|
||||
CLEANFILES = hugehelp.c
|
||||
NROFF=@NROFF@
|
||||
|
||||
EXTRA_DIST = mkhelp.pl curlmsg.msg \
|
||||
EXTRA_DIST = mkhelp.pl curlmsg.msg makefile.dj \
|
||||
Makefile.vc6 Makefile.b32 Makefile.m32 Makefile.riscos config.h.in \
|
||||
macos/curl.mcp.xml.sit.hqx \
|
||||
macos/MACINSTALL.TXT \
|
||||
@@ -38,4 +46,4 @@ MKHELP=$(top_srcdir)/src/mkhelp.pl
|
||||
# This generates the hugehelp.c file
|
||||
hugehelp.c: $(README) $(MANPAGE) mkhelp.pl
|
||||
rm -f hugehelp.c
|
||||
$(NROFF) -man $(MANPAGE) | $(PERL) $(MKHELP) $(README) > hugehelp.c
|
||||
$(NROFF) -man $(MANPAGE) | $(PERL) -s $(MKHELP) $(MKHELPOPT) $(README) > hugehelp.c
|
||||
|
@@ -22,7 +22,7 @@ ZLIB_PATH = ../../zlib-1.1.4
|
||||
########################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
INCLUDES = -I. -I.. -I../include
|
||||
INCLUDES = -I. -I.. -I../include -I$(ZLIB_PATH)
|
||||
CFLAGS = -g -O2 -DMINGW32
|
||||
ifdef SSL
|
||||
CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H
|
||||
@@ -41,13 +41,10 @@ else
|
||||
curl_DEPENDENCIES = ../lib/libcurl.a
|
||||
curl_LDADD = -L../lib -lcurl
|
||||
endif
|
||||
curl_LDADD += -lwsock32 -lws2_32 -lwinmm
|
||||
curl_LDADD += -lwsock32 -lws2_32 -lwinmm -L$(ZLIB_PATH) -lz
|
||||
ifdef SSL
|
||||
curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32
|
||||
endif
|
||||
ifdef ZLIB
|
||||
curl_LDADD += -L$(ZLIB_PATH) -lz
|
||||
endif
|
||||
|
||||
PROGRAMS = $(curl_PROGRAMS)
|
||||
SOURCES = $(curl_SOURCES)
|
||||
|
@@ -101,3 +101,5 @@ clean:
|
||||
distrib: clean
|
||||
-@erase $(PROGRAM_NAME)
|
||||
|
||||
hugehelp.c: hugehelp.c.cvs
|
||||
copy hugehelp.c.cvs hugehelp.c
|
||||
|
@@ -29,12 +29,17 @@
|
||||
/* Define if you have the <sys/poll.h> header file */
|
||||
#undef HAVE_SYS_POLL_H
|
||||
|
||||
/* Define if you have the `setvbuf' function. */
|
||||
#undef HAVE_SETVBUF
|
||||
|
||||
/* Define if you have the `poll' function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
/* Define if you can write to argc[] strings */
|
||||
#undef HAVE_WRITABLE_ARGV
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#undef HAVE_TIME_H
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#undef TIME_WITH_SYS_TIME
|
||||
|
316
src/main.c
316
src/main.c
@@ -50,6 +50,19 @@
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
/* We can include both fine */
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
#else
|
||||
# include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#ifdef HAVE_IO_H /* typical win32 habit */
|
||||
@@ -78,13 +91,30 @@
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
/* this is low-level hard-hacking memory leak tracking shit */
|
||||
#ifdef CURLDEBUG
|
||||
/* This is low-level hard-hacking memory leak tracking and similar. Using
|
||||
the library level code from this client-side is ugly, but we do this
|
||||
anyway for convenience. */
|
||||
#include "../lib/memdebug.h"
|
||||
#endif
|
||||
|
||||
#define DEFAULT_MAXREDIRS 50L
|
||||
|
||||
#ifdef __DJGPP__
|
||||
void *xmalloc(size_t);
|
||||
char *msdosify(char *);
|
||||
char *rename_if_dos_device_name(char *);
|
||||
void xfree(void *);
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
struct pollfd {
|
||||
int fd;
|
||||
int events; /* in param: what to poll for */
|
||||
int revents; /* out param: what events occured */
|
||||
};
|
||||
int poll (struct pollfd *, int, int);
|
||||
#endif /* __DJGPP__ */
|
||||
|
||||
#ifndef __cplusplus /* (rabe) */
|
||||
#ifndef typedef_bool
|
||||
typedef char bool;
|
||||
@@ -314,7 +344,8 @@ static void helpf(const char *fmt, ...)
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
fprintf(stderr, "curl: try 'curl --help' for more information\n");
|
||||
fprintf(stderr, "curl: try 'curl --help' or "
|
||||
"'curl --manual' for more information\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -338,14 +369,18 @@ static void help(void)
|
||||
"Options: (H) means HTTP/HTTPS only, (F) means FTP only\n"
|
||||
" -a/--append Append to target file when uploading (F)\n"
|
||||
" -A/--user-agent <string> User-Agent to send to server (H)\n"
|
||||
" --anyauth Tell curl to choose authentication method (H)\n"
|
||||
" -b/--cookie <name=string/file> Cookie string or file to read cookies from (H)\n"
|
||||
" --basic Enable HTTP Basic Authentication (H)\n"
|
||||
" -B/--use-ascii Use ASCII/text transfer\n",
|
||||
curl_version());
|
||||
puts(" -c/--cookie-jar <file> Write all cookies to this file after operation (H)\n"
|
||||
" -C/--continue-at <offset> Specify absolute resume offset\n"
|
||||
" -d/--data <data> HTTP POST data (H)\n"
|
||||
" --data-ascii <data> HTTP POST ASCII data (H)\n"
|
||||
" --data-binary <data> HTTP POST binary data (H)");
|
||||
" --data-binary <data> HTTP POST binary data (H)\n"
|
||||
" --negotiate Enable HTTP Negotiate Authentication (H - req GSS-lib)\n"
|
||||
" --digest Enable HTTP Digest Authentication (H)");
|
||||
puts(" --disable-eprt Prevents curl from using EPRT or LPRT (F)\n"
|
||||
" --disable-epsv Prevents curl from using EPSV (F)\n"
|
||||
" -D/--dump-header <file> Write the headers to this file\n"
|
||||
@@ -390,7 +425,8 @@ static void help(void)
|
||||
" -M/--manual Display huge help text\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");
|
||||
" --ntlm Enable HTTP NTLM authentication (H)");
|
||||
puts(" -N/--no-buffer Disables the buffering of the output stream");
|
||||
puts(" -o/--output <file> Write output to <file> instead of stdout\n"
|
||||
" -O/--remote-name Write output to a file named as the remote file\n"
|
||||
" -p/--proxytunnel Perform non-HTTP services through a HTTP proxy\n"
|
||||
@@ -412,6 +448,9 @@ static void help(void)
|
||||
" -U/--proxy-user <user[:password]> Specify Proxy authentication\n"
|
||||
" -v/--verbose Makes the operation more talkative\n"
|
||||
" -V/--version Outputs version number then quits");
|
||||
#ifdef __DJGPP__
|
||||
puts(" --wdebug Turns on WATT-32 debugging under DJGPP");
|
||||
#endif
|
||||
puts(" -w/--write-out [format] What to output after completion\n"
|
||||
" -x/--proxy <host[:port]> Use proxy. (Default port is 1080)\n"
|
||||
" --random-file <file> File to use for reading random data from (SSL)\n"
|
||||
@@ -443,6 +482,7 @@ struct Configurable {
|
||||
char *cookiefile; /* read from this file */
|
||||
bool cookiesession; /* new session? */
|
||||
bool encoding; /* Accept-Encoding please */
|
||||
long authtype; /* auth bitmask */
|
||||
bool use_resume;
|
||||
bool resume_from_current;
|
||||
bool disable_epsv;
|
||||
@@ -536,6 +576,9 @@ struct Configurable {
|
||||
size_t lastrecvsize;
|
||||
};
|
||||
|
||||
/* global variable to hold info about libcurl */
|
||||
static curl_version_info_data *curlinfo;
|
||||
|
||||
static int parseconfig(const char *filename,
|
||||
struct Configurable *config);
|
||||
static char *my_get_line(FILE *fp);
|
||||
@@ -1034,6 +1077,14 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
{"5h", "trace-ascii", TRUE},
|
||||
{"5i", "limit-rate", TRUE},
|
||||
{"5j", "compressed", FALSE}, /* might take an arg someday */
|
||||
{"5k", "digest", FALSE},
|
||||
{"5l", "negotiate", FALSE},
|
||||
{"5m", "ntlm", FALSE},
|
||||
{"5n", "basic", FALSE},
|
||||
{"5o", "anyauth", FALSE},
|
||||
#ifdef __DJGPP__
|
||||
{"5p", "wdebug", FALSE},
|
||||
#endif
|
||||
{"0", "http1.0", FALSE},
|
||||
{"1", "tlsv1", FALSE},
|
||||
{"2", "sslv2", FALSE},
|
||||
@@ -1258,6 +1309,32 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
config->encoding ^= TRUE;
|
||||
break;
|
||||
|
||||
case 'k': /* --digest */
|
||||
config->authtype = CURLAUTH_DIGEST;
|
||||
break;
|
||||
|
||||
case 'l': /* --negotiate */
|
||||
config->authtype = CURLAUTH_GSSNEGOTIATE;
|
||||
break;
|
||||
|
||||
case 'm': /* --ntlm */
|
||||
config->authtype = CURLAUTH_NTLM;
|
||||
break;
|
||||
|
||||
case 'n': /* --basic for completeness */
|
||||
config->authtype = CURLAUTH_BASIC;
|
||||
break;
|
||||
|
||||
case 'o': /* --anyauth, let libcurl pick it */
|
||||
config->authtype = CURLAUTH_ANY;
|
||||
break;
|
||||
|
||||
#ifdef __DJGPP__
|
||||
case 'p': /* --wdebug */
|
||||
dbug_init();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: /* the URL! */
|
||||
{
|
||||
struct getout *url;
|
||||
@@ -1673,7 +1750,40 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
config->conf ^= CONF_VERBOSE; /* talk a lot */
|
||||
break;
|
||||
case 'V':
|
||||
{
|
||||
const char **proto;
|
||||
|
||||
printf(CURL_ID "%s\n", curl_version());
|
||||
if (curlinfo->protocols) {
|
||||
printf("Protocols: ");
|
||||
for (proto=curlinfo->protocols; *proto; ++proto) {
|
||||
printf("%s ", *proto);
|
||||
}
|
||||
puts(""); /* newline */
|
||||
}
|
||||
if(curlinfo->features) {
|
||||
unsigned int i;
|
||||
struct feat {
|
||||
const char *name;
|
||||
int bitmask;
|
||||
};
|
||||
struct feat feats[] = {
|
||||
{"IPv6", CURL_VERSION_IPV6},
|
||||
{"krb4", CURL_VERSION_KERBEROS4},
|
||||
{"SSL", CURL_VERSION_SSL},
|
||||
{"libz", CURL_VERSION_LIBZ},
|
||||
{"NTLM", CURL_VERSION_NTLM},
|
||||
{"GSS-Negotiate", CURL_VERSION_GSSNEGOTIATE},
|
||||
{"Debug", CURL_VERSION_DEBUG}
|
||||
};
|
||||
printf("Features: ");
|
||||
for(i=0; i<sizeof(feats)/sizeof(feats[0]); i++) {
|
||||
if(curlinfo->features & feats[i].bitmask)
|
||||
printf("%s ", feats[i].name);
|
||||
}
|
||||
puts(""); /* newline */
|
||||
}
|
||||
}
|
||||
return PARAM_HELP_REQUESTED;
|
||||
case 'w':
|
||||
/* get the output string */
|
||||
@@ -1791,7 +1901,7 @@ static int parseconfig(const char *filename,
|
||||
|
||||
filename = filebuffer;
|
||||
}
|
||||
free(home); /* we've used it, now free it */
|
||||
curl_free(home); /* we've used it, now free it */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1974,6 +2084,7 @@ struct OutStruct {
|
||||
|
||||
int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
int rc;
|
||||
struct OutStruct *out=(struct OutStruct *)stream;
|
||||
struct Configurable *config = out->config;
|
||||
if(out && !out->stream) {
|
||||
@@ -1981,12 +2092,6 @@ int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
out->stream=fopen(out->filename, "wb");
|
||||
if(!out->stream)
|
||||
return -1; /* failure */
|
||||
if(config->nobuffer) {
|
||||
/* disable output buffering */
|
||||
#ifdef HAVE_SETVBUF
|
||||
setvbuf(out->stream, NULL, _IONBF, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(config->recvpersecond) {
|
||||
@@ -2009,7 +2114,13 @@ int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
config->lastrecvtime = now;
|
||||
}
|
||||
|
||||
return fwrite(buffer, size, nmemb, out->stream);
|
||||
rc = fwrite(buffer, size, nmemb, out->stream);
|
||||
|
||||
if(config->nobuffer)
|
||||
/* disable output buffering */
|
||||
fflush(out->stream);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct InStruct {
|
||||
@@ -2058,11 +2169,10 @@ int my_fread(void *buffer, size_t size, size_t nmemb, void *userp)
|
||||
|
||||
struct ProgressData {
|
||||
int calls;
|
||||
double total;
|
||||
double prev;
|
||||
double point;
|
||||
int width;
|
||||
FILE *out; /* where to write everything to */
|
||||
int initial_size;
|
||||
};
|
||||
|
||||
int myprogress (void *clientp,
|
||||
@@ -2084,22 +2194,21 @@ int myprogress (void *clientp,
|
||||
int i;
|
||||
|
||||
struct ProgressData *bar = (struct ProgressData *)clientp;
|
||||
double total = dltotal + ultotal;
|
||||
|
||||
bar->point = dlnow + ulnow; /* we've come this far */
|
||||
double total = dltotal + ultotal + bar->initial_size;
|
||||
double point = dlnow + ulnow + bar->initial_size; /* we've come this far */
|
||||
|
||||
bar->calls++; /* simply count invokes */
|
||||
|
||||
if(0 == total) {
|
||||
int prevblock = (int)bar->prev / 1024;
|
||||
int thisblock = (int)bar->point / 1024;
|
||||
int thisblock = (int)point / 1024;
|
||||
while ( thisblock > prevblock ) {
|
||||
fprintf( bar->out, "#" );
|
||||
prevblock++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
frac = bar->point / total;
|
||||
frac = point / total;
|
||||
percent = frac * 100.0f;
|
||||
barwidth = bar->width - 7;
|
||||
num = (int) (((double)barwidth) * frac);
|
||||
@@ -2112,7 +2221,7 @@ int myprogress (void *clientp,
|
||||
sprintf( outline, format, line, percent );
|
||||
fprintf( bar->out, "\r%s", outline );
|
||||
}
|
||||
bar->prev = bar->point;
|
||||
bar->prev = point;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2129,6 +2238,12 @@ void progressbarinit(struct ProgressData *bar,
|
||||
|
||||
memset(bar, 0, sizeof(struct ProgressData));
|
||||
|
||||
/* pass this through to progress function so
|
||||
* it can display progress towards total file
|
||||
* not just the part that's left. (21-may-03, dbyron) */
|
||||
if (config->use_resume)
|
||||
bar->initial_size = config->resume_from;
|
||||
|
||||
/* TODO: get terminal width through ansi escapes or something similar.
|
||||
try to update width when xterm is resized... - 19990617 larsa */
|
||||
#ifndef __EMX__
|
||||
@@ -2138,7 +2253,7 @@ void progressbarinit(struct ProgressData *bar,
|
||||
colp = curl_getenv("COLUMNS");
|
||||
if (colp != NULL) {
|
||||
bar->width = atoi(colp);
|
||||
free(colp);
|
||||
curl_free(colp);
|
||||
}
|
||||
else
|
||||
bar->width = 79;
|
||||
@@ -2313,11 +2428,8 @@ void free_config_fields(struct Configurable *config)
|
||||
static void FindWin32CACert(struct Configurable *config,
|
||||
const char *bundle_file)
|
||||
{
|
||||
curl_version_info_data *info;
|
||||
info = curl_version_info(CURLVERSION_NOW);
|
||||
|
||||
/* only check for cert file if "we" support SSL */
|
||||
if(info->features & CURL_VERSION_SSL) {
|
||||
if(curlinfo->features & CURL_VERSION_SSL) {
|
||||
DWORD buflen;
|
||||
char *ptr = NULL;
|
||||
char *retval = (char *) malloc(sizeof (TCHAR) * (MAX_PATH + 1));
|
||||
@@ -2369,15 +2481,18 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
int i;
|
||||
|
||||
char *env;
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
/* this sends all memory debug messages to a logfile named memdump */
|
||||
env = curl_getenv("CURL_MEMDEBUG");
|
||||
if(env) {
|
||||
free(env);
|
||||
curl_free(env);
|
||||
curl_memdebug("memdump");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* we get libcurl info right away */
|
||||
curlinfo = curl_version_info(CURLVERSION_NOW);
|
||||
|
||||
errorbuffer[0]=0; /* prevent junk from being output */
|
||||
|
||||
main_init(); /* inits */
|
||||
@@ -2488,7 +2603,7 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
env = curl_getenv("CURL_CA_BUNDLE");
|
||||
if(env) {
|
||||
GetStr(&config->cacert, env);
|
||||
free(env);
|
||||
curl_free(env);
|
||||
}
|
||||
#if defined(WIN32) && !defined(__CYGWIN32__)
|
||||
else
|
||||
@@ -2562,7 +2677,9 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
if(!config->globoff) {
|
||||
/* Unless explicitly shut off, we expand '{...}' and '[...]' expressions
|
||||
and return total number of URLs in pattern set */
|
||||
res = glob_url(&urls, url, &urlnum);
|
||||
res = glob_url(&urls, url, &urlnum,
|
||||
config->showerror?
|
||||
(config->errors?config->errors:stderr):NULL);
|
||||
if(res != CURLE_OK)
|
||||
return res;
|
||||
}
|
||||
@@ -2576,7 +2693,7 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
separator = 1;
|
||||
}
|
||||
for(i = 0;
|
||||
(url = urls?next_url(urls):(i?NULL:strdup(url)));
|
||||
(url = urls?glob_next_url(urls):(i?NULL:strdup(url)));
|
||||
i++) {
|
||||
char *outfile;
|
||||
outfile = outfiles?strdup(outfiles):NULL;
|
||||
@@ -2602,11 +2719,21 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
helpf("Remote file name has no length!\n");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
#if defined(__DJGPP__)
|
||||
{
|
||||
/* This is for DOS, and then we do some major replacing of
|
||||
bad characters in the file name before using it */
|
||||
char *file1=xmalloc(PATH_MAX);
|
||||
strcpy(file1, msdosify(outfile));
|
||||
strcpy(outfile, rename_if_dos_device_name(file1));
|
||||
xfree(file1);
|
||||
}
|
||||
#endif /* __DJGPP__ */
|
||||
}
|
||||
else if(urls) {
|
||||
/* fill '#1' ... '#9' terms from URL pattern */
|
||||
char *storefile = outfile;
|
||||
outfile = match_url(storefile, urls);
|
||||
outfile = glob_match_url(storefile, urls);
|
||||
free(storefile);
|
||||
}
|
||||
|
||||
@@ -2775,11 +2902,11 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
if(!config->errors)
|
||||
config->errors = stderr;
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN32__)
|
||||
#ifdef O_BINARY
|
||||
if(!outfile && !(config->conf & CONF_GETTEXT)) {
|
||||
/* We get the output to stdout and we have not got the ASCII/text flag,
|
||||
then set stdout to be binary */
|
||||
setmode( 1, O_BINARY );
|
||||
setmode( fileno(stdout), O_BINARY );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2942,6 +3069,10 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
/* disable it */
|
||||
curl_easy_setopt(curl, CURLOPT_FTP_USE_EPRT, FALSE);
|
||||
|
||||
/* new in libcurl 7.10.6 (default is Basic) */
|
||||
if(config->authtype)
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, config->authtype);
|
||||
|
||||
/* new in curl 7.9.7 */
|
||||
if(config->trace_dump) {
|
||||
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
@@ -3076,7 +3207,6 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int res;
|
||||
@@ -3207,3 +3337,119 @@ static int create_dir_hierarchy(char *outfile)
|
||||
return result; /* 0 is fine, -1 is badness */
|
||||
}
|
||||
|
||||
#ifdef __DJGPP__
|
||||
/* The following functions are taken with modification from the DJGPP
|
||||
* port of tar 1.12. They use algorithms originally from DJTAR. */
|
||||
|
||||
char *
|
||||
msdosify (char *file_name)
|
||||
{
|
||||
static char dos_name[PATH_MAX];
|
||||
static char illegal_chars_dos[] = ".+, ;=[]|<>\\\":?*";
|
||||
static char *illegal_chars_w95 = &illegal_chars_dos[8];
|
||||
int idx, dot_idx;
|
||||
char *s = file_name, *d = dos_name;
|
||||
char *illegal_aliens = illegal_chars_dos;
|
||||
size_t len = sizeof (illegal_chars_dos) - 1;
|
||||
int lfn = 0;
|
||||
|
||||
/* Support for Windows 9X VFAT systems, when available. */
|
||||
if (_use_lfn (file_name))
|
||||
lfn = 1;
|
||||
if (lfn) {
|
||||
illegal_aliens = illegal_chars_w95;
|
||||
len -= (illegal_chars_w95 - illegal_chars_dos);
|
||||
}
|
||||
|
||||
/* Get past the drive letter, if any. */
|
||||
if (s[0] >= 'A' && s[0] <= 'z' && s[1] == ':') {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
for (idx = 0, dot_idx = -1; *s; s++, d++) {
|
||||
if (memchr (illegal_aliens, *s, len)) {
|
||||
/* Dots are special: DOS doesn't allow them as the leading character,
|
||||
and a file name cannot have more than a single dot. We leave the
|
||||
first non-leading dot alone, unless it comes too close to the
|
||||
beginning of the name: we want sh.lex.c to become sh_lex.c, not
|
||||
sh.lex-c. */
|
||||
if (*s == '.') {
|
||||
if (idx == 0 && (s[1] == '/' || (s[1] == '.' && s[2] == '/'))) {
|
||||
/* Copy "./" and "../" verbatim. */
|
||||
*d++ = *s++;
|
||||
if (*s == '.')
|
||||
*d++ = *s++;
|
||||
*d = *s;
|
||||
}
|
||||
else if (idx == 0)
|
||||
*d = '_';
|
||||
else if (dot_idx >= 0) {
|
||||
if (dot_idx < 5) { /* 5 is a heuristic ad-hoc'ery */
|
||||
d[dot_idx - idx] = '_'; /* replace previous dot */
|
||||
*d = '.';
|
||||
}
|
||||
else
|
||||
*d = '-';
|
||||
}
|
||||
else
|
||||
*d = '.';
|
||||
|
||||
if (*s == '.')
|
||||
dot_idx = idx;
|
||||
}
|
||||
else if (*s == '+' && s[1] == '+') {
|
||||
if (idx - 2 == dot_idx) { /* .c++, .h++ etc. */
|
||||
*d++ = 'x';
|
||||
*d = 'x';
|
||||
}
|
||||
else {
|
||||
/* libg++ etc. */
|
||||
memcpy (d, "plus", 4);
|
||||
d += 3;
|
||||
}
|
||||
s++;
|
||||
idx++;
|
||||
}
|
||||
else
|
||||
*d = '_';
|
||||
}
|
||||
else
|
||||
*d = *s;
|
||||
if (*s == '/') {
|
||||
idx = 0;
|
||||
dot_idx = -1;
|
||||
}
|
||||
else
|
||||
idx++;
|
||||
}
|
||||
|
||||
*d = '\0';
|
||||
return dos_name;
|
||||
}
|
||||
|
||||
char *
|
||||
rename_if_dos_device_name (char *file_name)
|
||||
{
|
||||
/* We could have a file whose name is a device on MS-DOS. Trying to
|
||||
* retrieve such a file would fail at best and wedge us at worst. We need
|
||||
* to rename such files. */
|
||||
extern char *basename (const char *);
|
||||
char *base;
|
||||
struct stat st_buf;
|
||||
char fname[PATH_MAX];
|
||||
|
||||
strcpy (fname, file_name);
|
||||
base = basename (fname);
|
||||
if (((stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) {
|
||||
size_t blen = strlen (base);
|
||||
|
||||
/* Prepend a '_'. */
|
||||
memmove (base + 1, base, blen + 1);
|
||||
base[0] = '_';
|
||||
strcpy (file_name, fname);
|
||||
}
|
||||
return file_name;
|
||||
}
|
||||
|
||||
#endif /* __DJGPP__ */
|
||||
|
48
src/makefile.dj
Normal file
48
src/makefile.dj
Normal file
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# Adapted for djgpp2 / Watt-32 / DOS by
|
||||
# Gisle Vanem <giva@bgnett.no>
|
||||
#
|
||||
|
||||
DEPEND_PREREQ = config.h
|
||||
|
||||
include ../packages/DOS/common.dj
|
||||
|
||||
ifeq ($(USE_SSL),1)
|
||||
EX_LIBS = $(OPENSSL_ROOT)/lib/libssl.a $(OPENSSL_ROOT)/lib/libcrypt.a
|
||||
endif
|
||||
|
||||
EX_LIBS += $(WATT32_ROOT)/lib/libwatt.a $(ZLIB_ROOT)/libz.a
|
||||
|
||||
BIN = ../curl.exe
|
||||
SOURCES = hugehelp.c main.c urlglob.c writeenv.c writeout.c
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
all: config.h $(BIN)
|
||||
|
||||
$(BIN): $(OBJECTS) ../lib/libcurl.a
|
||||
$(CC) -o $@ $^ $(EX_LIBS)
|
||||
|
||||
config.h:
|
||||
@echo '#include "../lib/config.dj"' > $@
|
||||
|
||||
hugehelp.c: ../docs/curl.1
|
||||
groff -man $^ | perl mkhelp.pl ../readme > $@
|
||||
|
||||
clean:
|
||||
- rm -f $(OBJECTS) Makefile.bak config.h
|
||||
|
||||
vclean: clean
|
||||
- rm -f $(BIN) hugehelp.c
|
||||
|
||||
# DO NOT DELETE THIS LINE
|
||||
hugehelp.o: hugehelp.c
|
||||
main.o: main.c setup.h config.h ../lib/config.dj ../include/curl/curl.h \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||
../include/curl/mprintf.h urlglob.h writeout.h version.h
|
||||
urlglob.o: urlglob.c setup.h config.h ../lib/config.dj \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h urlglob.h
|
||||
writeenv.o: writeenv.c setup.h config.h ../lib/config.dj
|
||||
writeout.o: writeout.c setup.h config.h ../lib/config.dj \
|
||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
||||
../include/curl/multi.h ../include/curl/mprintf.h writeout.h
|
169
src/mkhelp.pl
169
src/mkhelp.pl
@@ -6,10 +6,10 @@
|
||||
# THEY DON'T FIT ME :-)
|
||||
|
||||
# Get readme file as parameter:
|
||||
$README = $ARGV[0];
|
||||
my $README = $ARGV[0];
|
||||
|
||||
if($README eq "") {
|
||||
print "usage: mkreadme.pl <README>\n";
|
||||
print "usage: mkreadme.pl [-c] <README> < manpage\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -20,54 +20,163 @@ push @out, " / __| | | | |_) | | \n";
|
||||
push @out, " | (__| |_| | _ <| |___ \n";
|
||||
push @out, " \\___|\\___/|_| \\_\\_____|\n";
|
||||
|
||||
$head=0;
|
||||
loop:
|
||||
while (<STDIN>) {
|
||||
$line = $_;
|
||||
my $line = $_;
|
||||
|
||||
# this kind should be removed first:
|
||||
$line =~ s/_//g;
|
||||
# this should be removed:
|
||||
$line =~ s/(.|_)//g;
|
||||
|
||||
# then this:
|
||||
$line =~ s/.//g;
|
||||
|
||||
if($line =~ /^curl/i) {
|
||||
# cut off the page headers
|
||||
$head=1;
|
||||
next loop;
|
||||
if($line =~ /^([ \t]*\n|curl)/i) {
|
||||
# cut off headers and empty lines
|
||||
$wline++; # count number of cut off lines
|
||||
next;
|
||||
}
|
||||
|
||||
if($line =~ /^[ \t]*\n/) {
|
||||
$wline++;
|
||||
# we only make one empty line max
|
||||
next loop;
|
||||
my $text = $line;
|
||||
$text =~ s/^\s+//g; # cut off preceeding...
|
||||
$text =~ s/\s+$//g; # and trailing whitespaces
|
||||
|
||||
$tlen = length($text);
|
||||
|
||||
if($wline && ($olen == $tlen)) {
|
||||
# if the previous line with contents was exactly as long as
|
||||
# this line, then we ignore the newlines!
|
||||
|
||||
# We do this magic because a header may abort a paragraph at
|
||||
# any line, but we don't want that to be noticed in the output
|
||||
# here
|
||||
$wline=0;
|
||||
}
|
||||
$olen = $tlen;
|
||||
|
||||
if($wline) {
|
||||
# we only make one empty line max
|
||||
$wline = 0;
|
||||
if(!$head) {
|
||||
push @out, "\n";
|
||||
}
|
||||
$head =0;
|
||||
}
|
||||
push @out, $line;
|
||||
}
|
||||
push @out, "\n"; # just an extra newline
|
||||
|
||||
open(READ, "<$README") ||
|
||||
die "couldn't read the README infile";
|
||||
die "couldn't read the README infile $README";
|
||||
|
||||
while(<READ>) {
|
||||
push @out, $_;
|
||||
}
|
||||
close(READ);
|
||||
|
||||
# if compressed
|
||||
if($c) {
|
||||
my @test = `gzip --version 2>&1`;
|
||||
if($test[0] =~ /gzip/) {
|
||||
open(GZIP, "|gzip -9 >dumpit.gz") ||
|
||||
die "can't run gzip, try without -c";
|
||||
binmode GZIP;
|
||||
for(@out) {
|
||||
print GZIP $_;
|
||||
$gzip += length($_);
|
||||
}
|
||||
close(GZIP);
|
||||
|
||||
print "/* NEVER EVER edit this manually, fix the mkhelp script instead! */\n"
|
||||
open(GZIP, "<dumpit.gz");
|
||||
binmode GZIP;
|
||||
while(<GZIP>) {
|
||||
push @gzip, $_;
|
||||
$gzipped += length($_);
|
||||
}
|
||||
close(GZIP);
|
||||
|
||||
unlink("dumpit.gz");
|
||||
}
|
||||
else {
|
||||
# no gzip, no compression!
|
||||
undef $c;
|
||||
print STDERR "MEEEP: Couldn't find gzip, disable compression\n";
|
||||
}
|
||||
}
|
||||
|
||||
$now = localtime;
|
||||
print <<HEAD
|
||||
/*
|
||||
* NEVER EVER edit this manually, fix the mkhelp.pl script instead!
|
||||
* Generation time: $now
|
||||
*/
|
||||
#include <stdio.h>
|
||||
HEAD
|
||||
;
|
||||
if($c) {
|
||||
print <<HEAD
|
||||
#include <zlib.h>
|
||||
static const unsigned char hugehelpgz[] = {
|
||||
/* This mumbo-jumbo is the huge help text compressed with gzip.
|
||||
Thanks to this operation, the size of this data shrunk from $gzip
|
||||
to $gzipped bytes. You can disable the use of compressed help
|
||||
texts by NOT passing -c to the mkhelp.pl tool. */
|
||||
HEAD
|
||||
;
|
||||
print "#include <stdio.h>\n";
|
||||
print "void hugehelp(void)\n";
|
||||
print "{\n";
|
||||
print "puts (\n";
|
||||
my $c=0;
|
||||
print " ";
|
||||
for(@gzip) {
|
||||
my @all=split(//, $_);
|
||||
for(@all) {
|
||||
my $num=ord($_);
|
||||
printf("0x%02x, ", 0+$num);
|
||||
if(++$c>11) {
|
||||
print "\n ";
|
||||
$c=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
print "\n};\n";
|
||||
|
||||
print <<EOF
|
||||
/* Decompress and send to stdout a gzip-compressed buffer */
|
||||
void hugehelp(void)
|
||||
{
|
||||
unsigned char buf[0x10000];
|
||||
int status,headerlen;
|
||||
z_stream z;
|
||||
|
||||
/* Make sure no gzip options are set */
|
||||
if (hugehelpgz[3] & 0xfe)
|
||||
return;
|
||||
|
||||
headerlen = 10;
|
||||
z.avail_in = sizeof(hugehelpgz) - headerlen;
|
||||
z.next_in = (unsigned char *)hugehelpgz + headerlen;
|
||||
z.zalloc = (alloc_func)Z_NULL;
|
||||
z.zfree = (free_func)Z_NULL;
|
||||
z.opaque = 0;
|
||||
|
||||
if (inflateInit2(&z, -MAX_WBITS) != Z_OK)
|
||||
return;
|
||||
|
||||
for (;;) {
|
||||
z.avail_out = (int)sizeof(buf);
|
||||
z.next_out = buf;
|
||||
status = inflate(&z, Z_SYNC_FLUSH);
|
||||
if (status == Z_OK || status == Z_STREAM_END) {
|
||||
fwrite(buf, sizeof(buf) - z.avail_out, 1, stdout);
|
||||
if (status == Z_STREAM_END)
|
||||
break;
|
||||
} else
|
||||
break; /* Error */
|
||||
}
|
||||
inflateEnd(&z);
|
||||
}
|
||||
EOF
|
||||
;
|
||||
exit;
|
||||
}
|
||||
else {
|
||||
print <<HEAD
|
||||
void hugehelp(void)
|
||||
{
|
||||
fputs(
|
||||
HEAD
|
||||
;
|
||||
}
|
||||
|
||||
$outsize=0;
|
||||
for(@out) {
|
||||
@@ -82,13 +191,13 @@ for(@out) {
|
||||
|
||||
# gcc 2.96 claims ISO C89 only is required to support 509 letter strings
|
||||
if($outsize > 500) {
|
||||
# terminate and make another puts() call here
|
||||
print ");\n puts(\n";
|
||||
# terminate and make another fputs() call here
|
||||
print ", stdout);\n fputs(\n";
|
||||
$outsize=length($new)+1;
|
||||
}
|
||||
printf("\"%s\\n\"\n", $new);
|
||||
|
||||
}
|
||||
|
||||
print " ) ;\n}\n"
|
||||
print ", stdout) ;\n}\n"
|
||||
|
||||
|
17
src/setup.h
17
src/setup.h
@@ -66,7 +66,6 @@ int fileno( FILE *stream);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define PATH_CHAR ";"
|
||||
#define DIR_CHAR "\\"
|
||||
#define DOT_CHAR "_"
|
||||
#else
|
||||
@@ -74,17 +73,25 @@ int fileno( FILE *stream);
|
||||
/* 20000318 mgs
|
||||
* OS/2 supports leading dots in filenames if the volume is formatted
|
||||
* with JFS or HPFS. */
|
||||
#define PATH_CHAR ";"
|
||||
#define DIR_CHAR "\\"
|
||||
#define DOT_CHAR "."
|
||||
#else
|
||||
|
||||
#define PATH_CHAR ":"
|
||||
#ifdef DJGPP
|
||||
#include <tcp.h>
|
||||
#ifdef word
|
||||
#undef word
|
||||
#endif
|
||||
#define DIR_CHAR "/"
|
||||
#define DOT_CHAR "_"
|
||||
#else
|
||||
|
||||
#define DIR_CHAR "/"
|
||||
#define DOT_CHAR "."
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif /* !DJGPP */
|
||||
#endif /* !__EMX__ */
|
||||
#endif /* !WIN32 */
|
||||
|
||||
#ifdef __riscos__
|
||||
#define USE_ENVIRONMENT
|
||||
|
@@ -29,12 +29,18 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "urlglob.h"
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
#include "../lib/memdebug.h"
|
||||
#endif
|
||||
|
||||
char globerrormsg[80]; /* nasty global error message buffer for globbing */
|
||||
typedef enum {
|
||||
GLOB_OK,
|
||||
GLOB_ERROR
|
||||
@@ -46,12 +52,12 @@ typedef enum {
|
||||
* Input a full globbed string, set the forth argument to the amount of
|
||||
* strings we get out of this. Return GlobCode.
|
||||
*/
|
||||
GlobCode glob_word(URLGlob *, /* object anchor */
|
||||
static GlobCode glob_word(URLGlob *, /* object anchor */
|
||||
char *, /* globbed string */
|
||||
int, /* position */
|
||||
int *); /* returned number of strings */
|
||||
|
||||
GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
static GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
{
|
||||
/* processes a set expression with the point behind the opening '{'
|
||||
','-separated elements are collected until the next closing '}'
|
||||
@@ -70,12 +76,14 @@ GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
while (1) {
|
||||
switch (*pattern) {
|
||||
case '\0': /* URL ended while set was still open */
|
||||
/*printf("error: unmatched brace at pos %d\n", pos);*/
|
||||
snprintf(globerrormsg, sizeof(globerrormsg),
|
||||
"unmatched brace at pos %d\n", pos);
|
||||
return GLOB_ERROR;
|
||||
|
||||
case '{':
|
||||
case '[': /* no nested expressions at this time */
|
||||
/*printf("error: nested braces not supported %d\n", pos);*/
|
||||
snprintf(globerrormsg, sizeof(globerrormsg),
|
||||
"nested braces not supported at pos %d\n", pos);
|
||||
return GLOB_ERROR;
|
||||
|
||||
case ',':
|
||||
@@ -85,7 +93,7 @@ GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
realloc(pat->content.Set.elements,
|
||||
(pat->content.Set.size + 1) * sizeof(char*));
|
||||
if (!pat->content.Set.elements) {
|
||||
/*printf("out of memory in set pattern\n");*/
|
||||
snprintf(globerrormsg, sizeof(globerrormsg), "out of memory");
|
||||
return GLOB_ERROR;
|
||||
}
|
||||
pat->content.Set.elements[pat->content.Set.size] =
|
||||
@@ -110,12 +118,14 @@ GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
break;
|
||||
|
||||
case ']': /* illegal closing bracket */
|
||||
/*printf("error: illegal pattern at pos %d\n", pos);*/
|
||||
snprintf(globerrormsg, sizeof(globerrormsg),
|
||||
"illegal pattern at pos %d\n", pos);
|
||||
return GLOB_ERROR;
|
||||
|
||||
case '\\': /* escaped character, skip '\' */
|
||||
if (*(buf+1) == '\0') { /* but no escaping of '\0'! */
|
||||
/*printf("error: illegal pattern at pos %d\n", pos); */
|
||||
snprintf(globerrormsg, sizeof(globerrormsg),
|
||||
"illegal pattern at pos %d\n", pos);
|
||||
return GLOB_ERROR;
|
||||
}
|
||||
++pattern;
|
||||
@@ -126,10 +136,11 @@ GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
snprintf(globerrormsg, sizeof(globerrormsg), "malformatted pattern");
|
||||
return GLOB_ERROR;
|
||||
}
|
||||
|
||||
GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
static GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
{
|
||||
/* processes a range expression with the point behind the opening '['
|
||||
- char range: e.g. "a-z]", "B-Q]"
|
||||
@@ -152,10 +163,8 @@ GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
pat->content.CharRange.min_c >= pat->content.CharRange.max_c ||
|
||||
pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') {
|
||||
/* the pattern is not well-formed */
|
||||
#if 0
|
||||
printf("error: illegal pattern or range specification after pos %d\n",
|
||||
pos);
|
||||
#endif
|
||||
snprintf(globerrormsg, sizeof(globerrormsg),
|
||||
"illegal pattern or range specification after pos %d\n", pos);
|
||||
return GLOB_ERROR;
|
||||
}
|
||||
pat->content.CharRange.ptr_c = pat->content.CharRange.min_c;
|
||||
@@ -180,10 +189,9 @@ GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
&pat->content.NumRange.max_n) != 2 ||
|
||||
pat->content.NumRange.min_n >= pat->content.NumRange.max_n) {
|
||||
/* the pattern is not well-formed */
|
||||
#if 0
|
||||
printf("error: illegal pattern or range specification after pos %d\n",
|
||||
snprintf(globerrormsg, sizeof(globerrormsg),
|
||||
"error: illegal pattern or range specification after pos %d\n",
|
||||
pos);
|
||||
#endif
|
||||
return GLOB_ERROR;
|
||||
}
|
||||
if (*pattern == '0') { /* leading zero specified */
|
||||
@@ -193,7 +201,13 @@ GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
instances of this pattern */
|
||||
}
|
||||
pat->content.NumRange.ptr_n = pat->content.NumRange.min_n;
|
||||
c = (char*)(strchr(pattern, ']') + 1); /* continue after next ']' */
|
||||
c = (char*)strchr(pattern, ']'); /* continue after next ']' */
|
||||
if(c)
|
||||
c++;
|
||||
else {
|
||||
snprintf(globerrormsg, sizeof(globerrormsg), "missing ']'");
|
||||
return GLOB_ERROR; /* missing ']' */
|
||||
}
|
||||
|
||||
/* always check for a literal (may be "") between patterns */
|
||||
|
||||
@@ -206,12 +220,12 @@ GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
|
||||
return GLOB_OK;
|
||||
}
|
||||
/*printf("error: illegal character in range specification at pos %d\n",
|
||||
pos);*/
|
||||
snprintf(globerrormsg, sizeof(globerrormsg),
|
||||
"illegal character in range specification at pos %d\n", pos);
|
||||
return GLOB_ERROR;
|
||||
}
|
||||
|
||||
GlobCode glob_word(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
static GlobCode glob_word(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
{
|
||||
/* processes a literal string component of a URL
|
||||
special characters '{' and '[' branch to set/range processing functions
|
||||
@@ -261,7 +275,7 @@ GlobCode glob_word(URLGlob *glob, char *pattern, int pos, int *amount)
|
||||
return GLOB_ERROR; /* something got wrong */
|
||||
}
|
||||
|
||||
int glob_url(URLGlob** glob, char* url, int *urlnum)
|
||||
int glob_url(URLGlob** glob, char* url, int *urlnum, FILE *error)
|
||||
{
|
||||
/*
|
||||
* We can deal with any-size, just make a buffer with the same length
|
||||
@@ -271,12 +285,15 @@ int glob_url(URLGlob** glob, char* url, int *urlnum)
|
||||
int amount;
|
||||
char *glob_buffer=(char *)malloc(strlen(url)+1);
|
||||
|
||||
if(NULL == glob_buffer)
|
||||
if(NULL == glob_buffer) {
|
||||
snprintf(globerrormsg, sizeof(globerrormsg), "out of memory");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
glob_expand = (URLGlob*)malloc(sizeof(URLGlob));
|
||||
if(NULL == glob_expand) {
|
||||
free(glob_buffer);
|
||||
snprintf(globerrormsg, sizeof(globerrormsg), "out of memory");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
glob_expand->size = 0;
|
||||
@@ -291,6 +308,12 @@ int glob_url(URLGlob** glob, char* url, int *urlnum)
|
||||
free(glob_expand);
|
||||
glob_expand = NULL;
|
||||
*urlnum = 1;
|
||||
if(error && globerrormsg[0]) {
|
||||
/* send error description to the error-stream */
|
||||
fprintf(error, "curl: (%d) [globbing] %s\n",
|
||||
CURLE_URL_MALFORMAT, globerrormsg);
|
||||
}
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
*glob = glob_expand;
|
||||
@@ -317,7 +340,7 @@ void glob_cleanup(URLGlob* glob)
|
||||
free(glob);
|
||||
}
|
||||
|
||||
char *next_url(URLGlob *glob)
|
||||
char *glob_next_url(URLGlob *glob)
|
||||
{
|
||||
char *buf = glob->glob_buffer;
|
||||
URLPattern *pat;
|
||||
@@ -393,7 +416,7 @@ char *next_url(URLGlob *glob)
|
||||
return strdup(glob->glob_buffer);
|
||||
}
|
||||
|
||||
char *match_url(char *filename, URLGlob *glob)
|
||||
char *glob_match_url(char *filename, URLGlob *glob)
|
||||
{
|
||||
char *target;
|
||||
URLPattern pat;
|
||||
|
@@ -53,9 +53,9 @@ typedef struct {
|
||||
char beenhere;
|
||||
} URLGlob;
|
||||
|
||||
int glob_url(URLGlob**, char*, int *);
|
||||
char* next_url(URLGlob*);
|
||||
char* match_url(char*, URLGlob *);
|
||||
int glob_url(URLGlob**, char*, int *, FILE *);
|
||||
char* glob_next_url(URLGlob*);
|
||||
char* glob_match_url(char*, URLGlob *);
|
||||
void glob_cleanup(URLGlob* glob);
|
||||
|
||||
#endif
|
||||
|
@@ -1,3 +1,3 @@
|
||||
#define CURL_NAME "curl"
|
||||
#define CURL_VERSION "7.10.5"
|
||||
#define CURL_VERSION "7.10.6"
|
||||
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
||||
|
26
testcurl.sh
26
testcurl.sh
@@ -106,10 +106,30 @@ fi
|
||||
cd curl
|
||||
|
||||
echo "testcurl: update from CVS"
|
||||
# update quietly to the latest CVS
|
||||
cvs -Q up -dP 2>&1
|
||||
|
||||
cvsstat=$?
|
||||
cvsup() {
|
||||
# update quietly to the latest CVS
|
||||
echo "testcurl: run cvs up"
|
||||
cvs -Q up -dP 2>&1
|
||||
|
||||
cvsstat=$?
|
||||
|
||||
# return (1 - RETURNVALUE) so that errors return 0 while goodness
|
||||
# returns 1
|
||||
return `expr 1 - $cvsstat`
|
||||
}
|
||||
|
||||
att="0"
|
||||
while cvsup; do
|
||||
att=`expr $att + 1`
|
||||
echo "testcurl: failed CVS update attempt number $att."
|
||||
if [ $att -gt 10 ]; then
|
||||
cvsstat="111"
|
||||
break # get out of the loop
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "testcurl: cvs returned: $cvsstat"
|
||||
|
||||
if [ "$cvsstat" -ne "0" ]; then
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user