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
|
curl-config
|
||||||
autom4te.cache
|
autom4te.cache
|
||||||
depcomp
|
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.
|
CHANGES.$year contains changes for the particular year.
|
||||||
|
|
||||||
tests/memanalyze.pl
|
tests/memanalyze.pl
|
||||||
is for analyzing the output generated by curl if -DMALLOCDEBUG
|
is for analyzing the output generated by curl if -DCURLDEBUG
|
||||||
is used when compiling
|
is used when compiling (run configure with --enable-debug)
|
||||||
|
|
||||||
buildconf builds the makefiles and configure stuff
|
buildconf builds the makefiles and configure stuff
|
||||||
|
|
||||||
|
14
Makefile.am
14
Makefile.am
@@ -4,12 +4,13 @@
|
|||||||
|
|
||||||
AUTOMAKE_OPTIONS = foreign
|
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
|
curl-config.in build_vms.com curl-style.el sample.emacs testcurl.sh
|
||||||
|
|
||||||
bin_SCRIPTS = curl-config
|
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:
|
# create a root makefile in the distribution:
|
||||||
dist-hook:
|
dist-hook:
|
||||||
@@ -25,10 +26,10 @@ pdf:
|
|||||||
check: test
|
check: test
|
||||||
|
|
||||||
test:
|
test:
|
||||||
@(cd tests; $(MAKE) quiet-test)
|
@(cd tests; $(MAKE) all quiet-test)
|
||||||
|
|
||||||
test-full:
|
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
|
# 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
|
# resulting .tar.bz2 file will end up at packages/Win32/cygwin
|
||||||
cygwinbin:
|
cygwinbin:
|
||||||
$(MAKE) -C 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
|
cd ..\src
|
||||||
nmake -f Makefile.vc6
|
nmake -f Makefile.vc6
|
||||||
|
|
||||||
|
djgpp:
|
||||||
|
make -C lib -f Makefile.dj
|
||||||
|
make -C src -f Makefile.dj
|
||||||
|
|
||||||
cygwin:
|
cygwin:
|
||||||
./configure
|
./configure
|
||||||
make
|
make
|
||||||
|
8
README
8
README
@@ -49,15 +49,15 @@ CVS
|
|||||||
|
|
||||||
To download the very latest source off the CVS server do this:
|
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)
|
(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!)
|
(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])
|
terms of the curl license; see COPYING for more details])
|
||||||
|
|
||||||
AC_CONFIG_SRCDIR([lib/urldata.h])
|
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
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
AC_PATH_PROG( SED, sed, , $PATH:/usr/bin:/usr/local/bin)
|
AC_PATH_PROG( SED, sed, , $PATH:/usr/bin:/usr/local/bin)
|
||||||
@@ -454,6 +454,63 @@ else
|
|||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
fi
|
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 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 openssl installation we can use. I *believe* this is what we are
|
||||||
dnl expected to do on really recent Redhat Linux hosts.
|
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.
|
dnl Default to compiler & linker defaults for SSL files & libraries.
|
||||||
OPT_SSL=off
|
OPT_SSL=off
|
||||||
|
dnl Default to no CA bundle
|
||||||
|
ca="no"
|
||||||
AC_ARG_WITH(ssl,dnl
|
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([--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]),
|
AC_HELP_STRING([--without-ssl], [disable SSL]),
|
||||||
@@ -569,13 +628,29 @@ else
|
|||||||
|
|
||||||
AC_SUBST(OPENSSL_ENABLED)
|
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
|
fi
|
||||||
|
|
||||||
if test X"$OPT_SSL" != Xoff &&
|
if test "x$ca" != "xno"; then
|
||||||
test "$OPENSSL_ENABLED" != "1"; then
|
CURL_CA_BUNDLE='"'$ca'"'
|
||||||
AC_MSG_ERROR([OpenSSL libs and/or directories were not found where specified!])
|
AC_SUBST(CURL_CA_BUNDLE)
|
||||||
fi
|
fi
|
||||||
|
AC_MSG_RESULT([$ca])
|
||||||
|
|
||||||
dnl these can only exist if openssl exists
|
dnl these can only exist if openssl exists
|
||||||
|
|
||||||
@@ -585,6 +660,15 @@ else
|
|||||||
|
|
||||||
fi
|
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 **********************************************************************
|
||||||
dnl Check for the presence of ZLIB libraries and headers
|
dnl Check for the presence of ZLIB libraries and headers
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
@@ -627,6 +711,9 @@ case "$OPT_ZLIB" in
|
|||||||
;;
|
;;
|
||||||
esac
|
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
|
dnl Default is to try the thread-safe versions of a few functions
|
||||||
OPT_THREAD=on
|
OPT_THREAD=on
|
||||||
|
|
||||||
@@ -774,7 +861,6 @@ AC_CHECK_FUNCS( socket \
|
|||||||
tcgetattr \
|
tcgetattr \
|
||||||
perror \
|
perror \
|
||||||
closesocket \
|
closesocket \
|
||||||
setvbuf \
|
|
||||||
sigaction \
|
sigaction \
|
||||||
signal \
|
signal \
|
||||||
getpass_r \
|
getpass_r \
|
||||||
@@ -822,36 +908,6 @@ AC_PATH_PROGS( NROFF, gnroff nroff, ,
|
|||||||
$PATH:/usr/bin/:/usr/local/bin )
|
$PATH:/usr/bin/:/usr/local/bin )
|
||||||
AC_SUBST(NROFF)
|
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
|
AC_PROG_YACC
|
||||||
|
|
||||||
dnl AC_PATH_PROG( RANLIB, ranlib, /usr/bin/ranlib,
|
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)
|
*) AC_MSG_RESULT(yes)
|
||||||
|
|
||||||
CPPFLAGS="$CPPFLAGS -DMALLOCDEBUG"
|
CPPFLAGS="$CPPFLAGS -DCURLDEBUG"
|
||||||
CFLAGS="$CFLAGS -g"
|
CFLAGS="$CFLAGS -g"
|
||||||
if test "$GCC" = "yes"; then
|
if test "$GCC" = "yes"; then
|
||||||
CFLAGS="$CFLAGS -W -Wall -Wwrite-strings -pedantic -Wundef -Wpointer-arith -Wnested-externs"
|
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.spec \
|
||||||
packages/Linux/RPM/curl-ssl.spec \
|
packages/Linux/RPM/curl-ssl.spec \
|
||||||
packages/Solaris/Makefile \
|
packages/Solaris/Makefile \
|
||||||
|
packages/DOS/Makefile \
|
||||||
packages/EPM/curl.list \
|
packages/EPM/curl.list \
|
||||||
packages/EPM/Makefile \
|
packages/EPM/Makefile \
|
||||||
curl-config
|
curl-config
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
(setq tab-width 8
|
(setq tab-width 8
|
||||||
indent-tabs-mode nil ; Use spaces. Not tabs.
|
indent-tabs-mode nil ; Use spaces. Not tabs.
|
||||||
comment-column 40
|
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
|
;; keybindings for C, C++, and Objective-C. We can put these in
|
||||||
;; c-mode-base-map because of inheritance ...
|
;; 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?
|
4.9. Curl can't authenticate to the server that requires NTLM?
|
||||||
|
|
||||||
NTLM is a Microsoft proprietary protocol. Unfortunately, curl does not
|
This is supported in curl 7.10.6 or later. No earlier curl version knows
|
||||||
currently support that. Proprietary formats are evil. You should not use
|
of this magic.
|
||||||
such ones.
|
|
||||||
|
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!
|
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
|
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
|
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
|
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
|
libraries that use it. It should be possible for everyone to use libcurl or
|
||||||
possible for everyone to use libcurl or curl in their projects, no matter
|
curl in their projects, no matter what license they already have in use.
|
||||||
what license they already have in use.
|
|
||||||
|
@@ -17,27 +17,30 @@ Misc
|
|||||||
- progress bar/time specs while downloading
|
- progress bar/time specs while downloading
|
||||||
- "standard" proxy environment variables support
|
- "standard" proxy environment variables support
|
||||||
- config file support
|
- config file support
|
||||||
- compiles on win32 (reported built on 29 operating systems)
|
- compiles on win32 (reported builds on 40+ operating systems)
|
||||||
- redirectable stderr
|
- redirectable stderr
|
||||||
- use selected network interface for outgoing traffic
|
- selectable network interface for outgoing traffic
|
||||||
- IPv6 support
|
- IPv6 support
|
||||||
- persistant connections
|
- persistant connections
|
||||||
|
- socks5 support
|
||||||
|
- supports user name + password in proxy environment variables
|
||||||
|
- operations through proxy "tunnel" (using CONNECT)
|
||||||
|
|
||||||
HTTP
|
HTTP
|
||||||
- HTTP/1.1 compliant
|
- HTTP/1.1 compliant (optionally uses 1.0)
|
||||||
- GET
|
- GET
|
||||||
- PUT
|
- PUT
|
||||||
- HEAD
|
- HEAD
|
||||||
- POST
|
- POST
|
||||||
- multipart POST
|
- multipart formpost (RFC1867-style)
|
||||||
- authentication
|
- authentication (Basic, Digest, NTLM(*1), GSS-Negotiate(*3))
|
||||||
- resume (both GET and PUT)
|
- resume (both GET and PUT)
|
||||||
- follow redirects
|
- follow redirects
|
||||||
- maximum amount of redirects to follow
|
- maximum amount of redirects to follow
|
||||||
- custom HTTP request
|
- custom HTTP request
|
||||||
- cookie get/send fully parsed
|
- cookie get/send fully parsed
|
||||||
- understands the netscape cookie file format
|
- reads/writes the netscape cookie file format
|
||||||
- custom headers (that can replace/remove internally generated headers)
|
- custom headers (replace/remove internally generated headers)
|
||||||
- custom user-agent string
|
- custom user-agent string
|
||||||
- custom referer string
|
- custom referer string
|
||||||
- range
|
- range
|
||||||
@@ -45,12 +48,16 @@ HTTP
|
|||||||
- time conditions
|
- time conditions
|
||||||
- via http-proxy
|
- via http-proxy
|
||||||
- retrieve file modification date
|
- retrieve file modification date
|
||||||
|
- Content-Encoding support for deflate and gzip
|
||||||
|
- "Transfer-Encoding: chunked" support for "uploads"
|
||||||
|
|
||||||
HTTPS (*1)
|
HTTPS (*1)
|
||||||
- (all the HTTP features)
|
- (all the HTTP features)
|
||||||
- using certificates
|
- using certificates
|
||||||
- verify server certificate
|
- verify server certificate
|
||||||
- via http-proxy
|
- via http-proxy
|
||||||
|
- select desired encryption
|
||||||
|
- force usage of a specific SSL version (SSLv2, SSLv3 or TLSv1)
|
||||||
|
|
||||||
FTP
|
FTP
|
||||||
- download
|
- download
|
||||||
@@ -92,3 +99,4 @@ FILE
|
|||||||
|
|
||||||
*1 = requires OpenSSL
|
*1 = requires OpenSSL
|
||||||
*2 = requires OpenLDAP
|
*2 = requires OpenLDAP
|
||||||
|
*3 = requires a GSSAPI-compliant library, such as Heimdal or similar.
|
||||||
|
@@ -448,6 +448,7 @@ PORTS
|
|||||||
- StrongARM NetBSD 1.4.1
|
- StrongARM NetBSD 1.4.1
|
||||||
- Ultrix 4.3a
|
- Ultrix 4.3a
|
||||||
- i386 BeOS
|
- i386 BeOS
|
||||||
|
- i386 DOS
|
||||||
- i386 FreeBSD
|
- i386 FreeBSD
|
||||||
- i386 HURD
|
- i386 HURD
|
||||||
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4
|
- 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
|
changelog of the current development status, as one or more of these problems
|
||||||
may have been fixed since this was written!
|
may have been fixed since this was written!
|
||||||
|
|
||||||
|
* 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
|
* 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.
|
struct. It has been reported to work on AIX 5.1 though.
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@ SIMPLE USAGE
|
|||||||
|
|
||||||
curl http://www.netscape.com/
|
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
|
curl ftp://ftp.funet.fi/README
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ SIMPLE USAGE
|
|||||||
|
|
||||||
curl http://www.weirdserver.com:8000/
|
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/
|
curl ftp://cool.haxx.se/
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ PDFPAGES = \
|
|||||||
|
|
||||||
SUBDIRS = examples libcurl
|
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 \
|
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS \
|
||||||
VERSIONS KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) \
|
VERSIONS KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) \
|
||||||
HISTORY INSTALL libcurl-the-guide $(PDFPAGES)
|
HISTORY INSTALL libcurl-the-guide $(PDFPAGES)
|
||||||
|
@@ -13,8 +13,8 @@ README.win32
|
|||||||
are win32-based.
|
are win32-based.
|
||||||
|
|
||||||
The unix-style man pages are tricky to read on windows, so therefore are all
|
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
|
those pages converted to HTML as well as pdf, and included in the release
|
||||||
release archives.
|
archives.
|
||||||
|
|
||||||
The main curl.1 man page is also "built-in" in the command line tool. Use a
|
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:
|
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>
|
- Dan Fandrich <dan@coneharvesters.com>
|
||||||
- Jean-Philippe Barrette-LaPierre <jpb@rrette.com>
|
- Jean-Philippe Barrette-LaPierre <jpb@rrette.com>
|
||||||
- Richard Bramante <RBramante@on.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
|
know what cookies that are received. Pushing interface that calls a
|
||||||
callback on each received cookie? Querying interface that asks about
|
callback on each received cookie? Querying interface that asks about
|
||||||
existing cookies? We probably need both. Enable applications to modify
|
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.
|
* 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
|
requested. That is, the download should not even begin but be aborted
|
||||||
immediately.
|
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
|
LIBCURL - multi interface
|
||||||
|
|
||||||
* Make sure we don't ever loop because of non-blocking sockets return
|
* Make sure we don't ever loop because of non-blocking sockets return
|
||||||
@@ -76,55 +72,21 @@ TODO
|
|||||||
* Make CURLOPT_FTPPORT support an additional port number on the IP/if/name,
|
* Make CURLOPT_FTPPORT support an additional port number on the IP/if/name,
|
||||||
like "blabla:[port]" or possibly even "blabla:[portfirst]-[portsecond]".
|
like "blabla:[port]" or possibly even "blabla:[portfirst]-[portsecond]".
|
||||||
|
|
||||||
* FTP ASCII upload does not follow RFC959 section 3.1.1.1: "The sender
|
* FTP ASCII transfers do not follow RFC959. They don't convert the data
|
||||||
converts the data from an internal character representation to the standard
|
accordingly.
|
||||||
8-bit NVT-ASCII representation (see the Telnet specification). The
|
|
||||||
receiver will convert the data from the standard form to his own internal
|
|
||||||
form."
|
|
||||||
|
|
||||||
* Since USERPWD always override the user and password specified in URLs, we
|
* Since USERPWD always override the user and password specified in URLs, we
|
||||||
might need another way to specify user+password for anonymous ftp logins.
|
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
|
* 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,
|
according to the specs written in draft-murray-auth-ftp-ssl-11.txt,
|
||||||
"Securing FTP with TLS"
|
"Securing FTP with TLS", valid until September 27th 2003.
|
||||||
|
http://curl.haxx.se/rfc/draft-murray-auth-ftp-ssl-11.txt
|
||||||
* --disable-epsv exists, but for active connections we have no --disable-eprt
|
|
||||||
(or even --disable-lprt).
|
|
||||||
|
|
||||||
HTTP
|
HTTP
|
||||||
|
|
||||||
* If the "body" of the POST is < MSS it really aught to be sent along with
|
* Digest, NTLM and GSS-Negotiate support for HTTP proxies. They all work
|
||||||
the headers. More generally, if the last chunk of the POST body is < MSS,
|
on direct-connections to the server.
|
||||||
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.
|
|
||||||
|
|
||||||
* Pipelining. Sending multiple requests before the previous one(s) are done.
|
* Pipelining. Sending multiple requests before the previous one(s) are done.
|
||||||
This could possibly be implemented using the multi interface to queue
|
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
|
.\" nroff -man curl.1
|
||||||
.\" Written by Daniel Stenberg
|
.\" 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
|
.SH NAME
|
||||||
curl \- transfer a URL
|
curl \- transfer a URL
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -10,14 +10,18 @@ curl \- transfer a URL
|
|||||||
.I [URL...]
|
.I [URL...]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B curl
|
.B curl
|
||||||
is a client to get documents/files from or send documents to a server, using
|
is a tool to transfer data from or to a server, using one of the supported
|
||||||
any of the supported protocols (HTTP, HTTPS, FTP, GOPHER, DICT, TELNET, LDAP
|
protocols (HTTP, HTTPS, FTP, FTPS, GOPHER, DICT, TELNET, LDAP or FILE). The
|
||||||
or FILE). The command is designed to work without user interaction or any kind
|
command is designed to work without user interaction.
|
||||||
of interactivity.
|
|
||||||
|
|
||||||
curl offers a busload of useful tricks like proxy support, user
|
curl offers a busload of useful tricks like proxy support, user
|
||||||
authentication, ftp upload, HTTP post, SSL (https:) connections, cookies, file
|
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
|
.SH URL
|
||||||
The URL syntax is protocol dependent. You'll find a detailed description in
|
The URL syntax is protocol dependent. You'll find a detailed description in
|
||||||
RFC 2396.
|
RFC 2396.
|
||||||
@@ -48,10 +52,8 @@ specified on a single command line and cannot be used between separate curl
|
|||||||
invokes.
|
invokes.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.IP "-a/--append"
|
.IP "-a/--append"
|
||||||
(FTP)
|
(FTP) When used in an FTP upload, this will tell curl to append to the target
|
||||||
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.
|
||||||
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.
|
If this option is used twice, the second one will disable append mode again.
|
||||||
.IP "-A/--user-agent <agent string>"
|
.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
|
If this option is set more than once, the last one will be the one that's
|
||||||
used.
|
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>"
|
.IP "-b/--cookie <name=data>"
|
||||||
(HTTP)
|
(HTTP)
|
||||||
Pass the data to the HTTP server as a cookie. It is supposedly the
|
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.
|
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.
|
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>"
|
.IP "--ciphers <list of ciphers>"
|
||||||
(SSL) Specifies which ciphers to use in the connection. The 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:
|
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.
|
If this option is used several times, the last one will override the others.
|
||||||
.IP "--compressed"
|
.IP "--compressed"
|
||||||
(HTTP) Request a compressed response using the deflate or gzip
|
(HTTP) Request a compressed response using one of the algorithms libcurl
|
||||||
algorithms and return the uncompressed document. If this option is used
|
supports, and return the uncompressed document. If this option is used and
|
||||||
and the server sends an unsupported encoding, Curl will report an error.
|
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>"
|
.IP "--connect-timeout <seconds>"
|
||||||
Maximum time in seconds that you allow the connection to the server to take.
|
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
|
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
|
If this option is used several times, the ones following the first will
|
||||||
append data.
|
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"
|
.IP "--disable-epsv"
|
||||||
(FTP) Tell curl to disable the use of the EPSV command when doing passive FTP
|
(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.
|
but with this option, it will not try using EPSV.
|
||||||
|
|
||||||
If this option is used several times, each occurrence will toggle this on/off.
|
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
|
(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
|
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,
|
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
|
headers from all requested pages will be shown. If authentication is used,
|
||||||
making a HTTP POST, curl will automatically switch to GET after the initial
|
curl will only send its credentials to the initial host, so if a redirect
|
||||||
POST has been done.
|
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.
|
If this option is used twice, the second will again disable location following.
|
||||||
.IP "-m/--max-time <seconds>"
|
.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"
|
.B "machine host.domain.com login myself password secret"
|
||||||
|
|
||||||
If this option is used twice, the second will again disable netrc usage.
|
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"
|
.IP "-N/--no-buffer"
|
||||||
Disables the buffering of the output stream. In normal work situations, curl
|
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
|
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.
|
Using this option will disable that buffering.
|
||||||
|
|
||||||
If this option is used twice, the second will again switch on 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>"
|
.IP "-o/--output <file>"
|
||||||
Write output to <file> instead of stdout. If you are using {} or [] to fetch
|
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>
|
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.
|
See also the --create-dirs option to create the local directories dynamically.
|
||||||
.IP "-O/--remote-name"
|
.IP "-O/--remote-name"
|
||||||
Write output to a local file named like the remote file we get. (Only
|
Write output to a local file named like the remote file we get. (Only the file
|
||||||
the file part of the remote file is used, the path is cut off.)
|
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.
|
You may use this option as many times as you have number of URLs.
|
||||||
.IP "-p/--proxytunnel"
|
.IP "-p/--proxytunnel"
|
||||||
@@ -596,7 +671,7 @@ descriptive information, to the given output file. Use "-" as filename to have
|
|||||||
the output sent to stdout.
|
the output sent to stdout.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used. (Added in
|
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>"
|
.IP "--trace-ascii <file>"
|
||||||
Enables a full trace dump of all incoming and outgoing data, including
|
Enables a full trace dump of all incoming and outgoing data, including
|
||||||
descriptive information, to the given output file. Use "-" as filename to have
|
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.
|
read for untrained humans.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used. (Added in
|
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>"
|
.IP "-u/--user <user:password>"
|
||||||
Specify user and password to use when fetching. Read the MANUAL for detailed
|
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
|
examples of how to use this. If no password is specified, curl will ask for it
|
||||||
interactively.
|
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.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "-U/--proxy-user <user:password>"
|
.IP "-U/--proxy-user <user:password>"
|
||||||
Specify user and password to use for Proxy authentication. If no
|
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.
|
If this option is used twice, the second will again disable verbose.
|
||||||
.IP "-V/--version"
|
.IP "-V/--version"
|
||||||
Displays the full version of curl, libcurl and other 3rd party libraries
|
Displays information about curl and the libcurl version it uses.
|
||||||
linked with the executable.
|
|
||||||
|
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>"
|
.IP "-w/--write-out <format>"
|
||||||
Defines what to display after a completed and successful operation. The 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
|
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 \
|
multithread.c getinmemory.c ftpupload.c httpput.c \
|
||||||
simplessl.c ftpgetresp.c http-post.c post-callback.c \
|
simplessl.c ftpgetresp.c http-post.c post-callback.c \
|
||||||
multi-app.c multi-double.c multi-single.c multi-post.c \
|
multi-app.c multi-double.c multi-single.c multi-post.c \
|
||||||
fopen.c simplepost.c
|
fopen.c simplepost.c makefile.dj
|
||||||
|
|
||||||
all:
|
all:
|
||||||
@echo "done"
|
@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;
|
FILE *headerfile;
|
||||||
|
|
||||||
const char *pCertFile = "testcert.pem";
|
const char *pCertFile = "testcert.pem";
|
||||||
const char *pCACertFile="cacert.pem"
|
const char *pCACertFile="cacert.pem";
|
||||||
|
|
||||||
const char *pKeyName;
|
const char *pKeyName;
|
||||||
const char *pKeyType;
|
const char *pKeyType;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
.\" nroff -man [file]
|
.\" nroff -man [file]
|
||||||
.\" $Id$
|
.\" $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
|
.SH NAME
|
||||||
curl_easy_setopt - set options for a curl easy handle
|
curl_easy_setopt - set options for a curl easy handle
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -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
|
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)
|
cannot be guaranteed to actually get the given size. (Added in 7.10)
|
||||||
.PP
|
.PP
|
||||||
.SH NAMES and PASSWORDS OPTIONS
|
.SH NAMES and PASSWORDS OPTIONS (Authentication)
|
||||||
.TP 0.4i
|
.TP 0.4i
|
||||||
.B CURLOPT_NETRC
|
.B CURLOPT_NETRC
|
||||||
This parameter controls the preference of libcurl between using user names and
|
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
|
When using HTTP and CURLOPT_FOLLOWLOCATION, libcurl might perform several
|
||||||
requests to possibly different hosts. libcurl will only send this user and
|
requests to possibly different hosts. libcurl will only send this user and
|
||||||
password information to hosts using the initial host name, so if libcurl
|
password information to hosts using the initial host name (unless
|
||||||
follows locations to other hosts it will not send the user and password to
|
CURLOPT_UNRESTRICTED_AUTH is set), so if libcurl follows locations to other
|
||||||
those. This is enforced to prevent accidental information leakage.
|
hosts it will not send the user and password to those. This is enforced to
|
||||||
|
prevent accidental information leakage.
|
||||||
.TP
|
.TP
|
||||||
.B CURLOPT_PROXYUSERPWD
|
.B CURLOPT_PROXYUSERPWD
|
||||||
Pass a char * as parameter, which should be [user name]:[password] to use for
|
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
|
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
|
prompted for it. \fICURLOPT_PASSWDFUNCTION\fP can be used to set your own
|
||||||
prompt function.
|
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
|
.PP
|
||||||
.SH HTTP OPTIONS
|
.SH HTTP OPTIONS
|
||||||
.TP 0.4i
|
.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
|
result in strange bugs because the server will most likely ignore part
|
||||||
of the headers you specified.
|
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
|
\fBNOTE:\fPThe most commonly replaced headers have "shortcuts" in the options
|
||||||
CURLOPT_COOKIE, CURLOPT_USERAGENT and CURLOPT_REFERER.
|
CURLOPT_COOKIE, CURLOPT_USERAGENT and CURLOPT_REFERER.
|
||||||
.TP
|
.TP
|
||||||
@@ -615,9 +664,18 @@ want the transfer to start from.
|
|||||||
.TP
|
.TP
|
||||||
.B CURLOPT_CUSTOMREQUEST
|
.B CURLOPT_CUSTOMREQUEST
|
||||||
Pass a pointer to a zero terminated string as parameter. It will be user
|
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
|
instead of GET or HEAD when doing a HTTP request, or instead of LIST or NLST
|
||||||
DELETE or other more or less obscure HTTP requests. Don't do this at will,
|
when doing an ftp directory listing. This is useful for doing DELETE or other
|
||||||
make sure your server supports the command first.
|
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
|
.TP
|
||||||
.B CURLOPT_FILETIME
|
.B CURLOPT_FILETIME
|
||||||
Pass a long. If it is a non-zero value, libcurl will attempt to get the
|
Pass a long. If it is a non-zero value, libcurl will attempt to get the
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
.\" nroff -man [file]
|
.\" nroff -man [file]
|
||||||
.\" $Id$
|
.\" $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
|
.SH NAME
|
||||||
curl_slist_append - add a string to an slist
|
curl_slist_append - add a string to an slist
|
||||||
.SH SYNOPSIS
|
.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
|
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
|
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
|
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.
|
The list should be freed again (after usage) with \fBcurl_slist_free_all()\fP.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
.\" nroff -man [file]
|
.\" nroff -man [file]
|
||||||
.\" $Id$
|
.\" $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
|
.SH NAME
|
||||||
curl_version_info - returns run-time libcurl version info
|
curl_version_info - returns run-time libcurl version info
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -69,6 +69,16 @@ supports SSL (HTTPS/FTPS)
|
|||||||
.TP
|
.TP
|
||||||
.B CURL_VERSION_LIBZ
|
.B CURL_VERSION_LIBZ
|
||||||
supports HTTP deflate using 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
|
.PP
|
||||||
\fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
|
\fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
|
||||||
has no SSL support, this is NULL.
|
has no SSL support, this is NULL.
|
||||||
@@ -83,8 +93,6 @@ libcurl has no libz support, this is NULL.
|
|||||||
names protocols that libcurl supports (using lowercase letters). The protocol
|
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
|
names are the same as would be used in URLs. The array is terminated by a NULL
|
||||||
entry.
|
entry.
|
||||||
|
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to a curl_version_info_data struct.
|
A pointer to a curl_version_info_data struct.
|
||||||
.SH "SEE ALSO"
|
.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
|
... style and point the compiler's include path to the directory holding the
|
||||||
curl subdirectory. It makes it more likely to survive future modifications.
|
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$
|
* $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>
|
#include <stdio.h>
|
||||||
/* The include stuff here is mainly for time_t! */
|
|
||||||
|
/* The include stuff here below is mainly for time_t! */
|
||||||
#ifdef vms
|
#ifdef vms
|
||||||
# include <types.h>
|
# include <types.h>
|
||||||
# include <time.h>
|
# include <time.h>
|
||||||
#else
|
#else
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
# ifdef TIME_WITH_SYS_TIME
|
|
||||||
# include <sys/time.h>
|
|
||||||
# include <time.h>
|
# include <time.h>
|
||||||
# else
|
|
||||||
# ifdef HAVE_SYS_TIME_H
|
|
||||||
# include <sys/time.h>
|
|
||||||
# else
|
|
||||||
# include <time.h>
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#endif /* defined (vms) */
|
#endif /* defined (vms) */
|
||||||
|
|
||||||
#ifndef TRUE
|
#ifndef TRUE
|
||||||
@@ -55,8 +71,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* stupid #define trick to preserve functionality with older code, but
|
/* silly trick to preserve functionality with older code, but making it use
|
||||||
making it use our name space for the future */
|
our name space for the future */
|
||||||
#define HttpPost curl_httppost
|
#define HttpPost curl_httppost
|
||||||
|
|
||||||
struct curl_httppost {
|
struct curl_httppost {
|
||||||
@@ -65,15 +81,13 @@ struct curl_httppost {
|
|||||||
long namelength; /* length of name length */
|
long namelength; /* length of name length */
|
||||||
char *contents; /* pointer to allocated data contents */
|
char *contents; /* pointer to allocated data contents */
|
||||||
long contentslength; /* length of contents field */
|
long contentslength; /* length of contents field */
|
||||||
|
|
||||||
/* CMC: Added support for buffer uploads */
|
|
||||||
char *buffer; /* pointer to allocated buffer contents */
|
char *buffer; /* pointer to allocated buffer contents */
|
||||||
long bufferlength; /* length of buffer field */
|
long bufferlength; /* length of buffer field */
|
||||||
|
|
||||||
char *contenttype; /* Content-Type */
|
char *contenttype; /* Content-Type */
|
||||||
struct curl_slist* contentheader; /* list of extra headers for this form */
|
struct curl_slist* contentheader; /* list of extra headers for this form */
|
||||||
struct curl_httppost *more; /* if one field name has more than one file, this
|
struct curl_httppost *more; /* if one field name has more than one
|
||||||
link should link to following files */
|
file, this link should link to following
|
||||||
|
files */
|
||||||
long flags; /* as defined below */
|
long flags; /* as defined below */
|
||||||
#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
|
#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
|
||||||
#define HTTPPOST_READFILE (1<<1) /* 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 */
|
do not free in formfree */
|
||||||
#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
|
#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
|
||||||
do not free in formfree */
|
do not free in formfree */
|
||||||
|
|
||||||
/* CMC: Added support for buffer uploads */
|
|
||||||
#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
|
#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
|
||||||
#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
|
#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
|
||||||
|
|
||||||
char *showfilename; /* The file name to show. If not set, the actual
|
char *showfilename; /* The file name to show. If not set, the
|
||||||
file name will be used (if this is a file part) */
|
actual file name will be used (if this
|
||||||
|
is a file part) */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*curl_progress_callback)(void *clientp,
|
typedef int (*curl_progress_callback)(void *clientp,
|
||||||
@@ -130,7 +143,7 @@ typedef int (*curl_debug_callback)
|
|||||||
curl_infotype type, /* what kind of data */
|
curl_infotype type, /* what kind of data */
|
||||||
char *data, /* points to the data */
|
char *data, /* points to the data */
|
||||||
size_t size, /* size of the data pointed to */
|
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
|
/* All possible error codes from all sorts of curl functions. Future versions
|
||||||
may return other values, stay prepared.
|
may return other values, stay prepared.
|
||||||
@@ -207,6 +220,11 @@ typedef enum {
|
|||||||
CURL_LAST /* never use! */
|
CURL_LAST /* never use! */
|
||||||
} CURLcode;
|
} 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 */
|
/* Make a spelling correction for the operation timed-out define */
|
||||||
#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
|
#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
|
||||||
#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
|
#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
|
||||||
@@ -217,6 +235,14 @@ typedef enum {
|
|||||||
CURLPROXY_SOCKS5 = 5
|
CURLPROXY_SOCKS5 = 5
|
||||||
} curl_proxytype;
|
} 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
|
/* 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
|
is no longer used by libcurl but is instead #defined here only to not
|
||||||
make programs break */
|
make programs break */
|
||||||
@@ -266,6 +292,12 @@ typedef enum {
|
|||||||
#define CINIT(name,type,number) CURLOPT_/**/name = type + number
|
#define CINIT(name,type,number) CURLOPT_/**/name = type + number
|
||||||
#endif
|
#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 {
|
typedef enum {
|
||||||
CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/
|
CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/
|
||||||
|
|
||||||
@@ -275,24 +307,19 @@ typedef enum {
|
|||||||
/* The full URL to get/put */
|
/* The full URL to get/put */
|
||||||
CINIT(URL, OBJECTPOINT, 2),
|
CINIT(URL, OBJECTPOINT, 2),
|
||||||
|
|
||||||
/* Port number to connect to, if other than default. Specify the CONF_PORT
|
/* Port number to connect to, if other than default. */
|
||||||
flag in the CURLOPT_FLAGS to activate this */
|
|
||||||
CINIT(PORT, LONG, 3),
|
CINIT(PORT, LONG, 3),
|
||||||
|
|
||||||
/* Name of proxy to use. Specify the CONF_PROXY flag in the CURLOPT_FLAGS to
|
/* Name of proxy to use. */
|
||||||
activate this */
|
|
||||||
CINIT(PROXY, OBJECTPOINT, 4),
|
CINIT(PROXY, OBJECTPOINT, 4),
|
||||||
|
|
||||||
/* Name and password to use when fetching. Specify the CONF_USERPWD flag in
|
/* "name:password" to use when fetching. */
|
||||||
the CURLOPT_FLAGS to activate this */
|
|
||||||
CINIT(USERPWD, OBJECTPOINT, 5),
|
CINIT(USERPWD, OBJECTPOINT, 5),
|
||||||
|
|
||||||
/* Name and password to use with Proxy. Specify the CONF_PROXYUSERPWD
|
/* "name:password" to use with proxy. */
|
||||||
flag in the CURLOPT_FLAGS to activate this */
|
|
||||||
CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
|
CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
|
||||||
|
|
||||||
/* Range to get, specified as an ASCII string. Specify the CONF_RANGE flag
|
/* Range to get, specified as an ASCII string. */
|
||||||
in the CURLOPT_FLAGS to activate this */
|
|
||||||
CINIT(RANGE, OBJECTPOINT, 7),
|
CINIT(RANGE, OBJECTPOINT, 7),
|
||||||
|
|
||||||
/* not used */
|
/* not used */
|
||||||
@@ -413,7 +440,6 @@ typedef enum {
|
|||||||
as described elsewhere. */
|
as described elsewhere. */
|
||||||
CINIT(WRITEINFO, OBJECTPOINT, 40),
|
CINIT(WRITEINFO, OBJECTPOINT, 40),
|
||||||
|
|
||||||
/* Previous FLAG bits */
|
|
||||||
CINIT(VERBOSE, LONG, 41), /* talk a lot */
|
CINIT(VERBOSE, LONG, 41), /* talk a lot */
|
||||||
CINIT(HEADER, LONG, 42), /* throw the header out too */
|
CINIT(HEADER, LONG, 42), /* throw the header out too */
|
||||||
CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
|
CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
|
||||||
@@ -629,6 +655,20 @@ typedef enum {
|
|||||||
attempted before the good old traditional PORT command. */
|
attempted before the good old traditional PORT command. */
|
||||||
CINIT(FTP_USE_EPRT, LONG, 106),
|
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 */
|
CURLOPT_LASTENTRY /* the last unused */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
@@ -697,9 +737,9 @@ typedef enum {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* These functions are in the libcurl, they're here for portable reasons and
|
/* These functions are in libcurl, they're here for portable reasons and they
|
||||||
they are used by the 'curl' client. They really should be moved to some kind
|
are used by the 'curl' client. They really should be moved to some kind of
|
||||||
of "portability library" since it has nothing to do with file transfers and
|
"portability library" since it has nothing to do with file transfers and
|
||||||
might be usable to other programs...
|
might be usable to other programs...
|
||||||
|
|
||||||
NOTE: they return TRUE if the strings match *case insensitively*.
|
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_strequal)(const char *s1, const char *s2);
|
||||||
extern int (curl_strnequal)(const char *s1, const char *s2, size_t n);
|
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 **,
|
int curl_formparse(char *, struct curl_httppost **,
|
||||||
struct curl_httppost **_post);
|
struct curl_httppost **_post);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* name is uppercase CURLFORM_<name> */
|
/* name is uppercase CURLFORM_<name> */
|
||||||
#ifdef CFINIT
|
#ifdef CFINIT
|
||||||
@@ -788,47 +831,122 @@ typedef enum {
|
|||||||
CURL_FORMADD_LAST /* last */
|
CURL_FORMADD_LAST /* last */
|
||||||
} CURLFORMcode;
|
} 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,
|
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||||
struct curl_httppost **last_post,
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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) */
|
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
||||||
struct curl_slist {
|
struct curl_slist {
|
||||||
char *data;
|
char *data;
|
||||||
struct curl_slist *next;
|
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 *);
|
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 *);
|
void curl_slist_free_all(struct curl_slist *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -996,8 +1114,18 @@ typedef struct {
|
|||||||
#define CURL_VERSION_KERBEROS4 (1<<1)
|
#define CURL_VERSION_KERBEROS4 (1<<1)
|
||||||
#define CURL_VERSION_SSL (1<<2)
|
#define CURL_VERSION_SSL (1<<2)
|
||||||
#define CURL_VERSION_LIBZ (1<<3)
|
#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);
|
curl_version_info_data *curl_version_info(CURLversion);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -45,11 +45,23 @@
|
|||||||
file descriptors simultaneous easily.
|
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__)
|
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
#else
|
#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>
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@@ -23,9 +23,7 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
size_t fread (void *, size_t, size_t, FILE *);
|
size_t fread (void *, size_t, size_t, FILE *);
|
||||||
size_t fwrite (const 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 \
|
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
|
||||||
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp \
|
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp \
|
||||||
curllib.dsw config-vms.h config-win32.h config-riscos.h config-mac.h \
|
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
|
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 \
|
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 \
|
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 \
|
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
|
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.
|
# Say $(srcdir), so GNU make does not report an ambiguity with the .y.c rule.
|
||||||
$(srcdir)/getdate.c: getdate.y
|
$(srcdir)/getdate.c: getdate.y
|
||||||
cd $(srcdir) && \
|
cd $(srcdir) && \
|
||||||
$(YACC) $(YFLAGS) getdate.y; \
|
$(YACC) $(YFLAGS) getdate.y; \
|
||||||
mv -f y.tab.c getdate.c
|
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:
|
install-data-hook:
|
||||||
@if test -n "@CURL_CA_BUNDLE@"; then \
|
@if test -n "@CURL_CA_BUNDLE@"; then \
|
||||||
$(mkinstalldirs) `dirname $(DESTDIR)@CURL_CA_BUNDLE@`; \
|
$(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
|
# this hook is mainly for non-unix systems to build even if configure
|
||||||
# isn't run
|
# isn't run
|
||||||
dist-hook:
|
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_LIBRARIES = libcurl.a
|
||||||
|
|
||||||
libcurl_a_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c base64.c \
|
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 \
|
file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h \
|
||||||
cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.h sendf.h url.c dict.c \
|
progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c \
|
||||||
ftp.h if2ip.c speedcheck.c url.h dict.h getdate.c if2ip.h speedcheck.h \
|
http.h sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h \
|
||||||
urldata.h transfer.c getdate.h ldap.c ssluse.c version.c transfer.h getenv.c \
|
dict.h getdate.c if2ip.h speedcheck.h urldata.h transfer.c getdate.h \
|
||||||
ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c \
|
ldap.c ssluse.c version.c transfer.h getenv.c \
|
||||||
telnet.h getinfo.c strequal.c strequal.h easy.c security.h \
|
ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h \
|
||||||
security.c krb4.h krb4.c memdebug.h memdebug.c inet_ntoa_r.h http_chunks.h http_chunks.c \
|
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 \
|
strtok.c connect.c hash.c llist.c multi.c share.c share.h \
|
||||||
content_encoding.h content_encoding.c
|
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 \
|
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 \
|
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 \
|
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 \
|
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 \
|
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)
|
LIBRARIES = $(libcurl_a_LIBRARIES)
|
||||||
SOURCES = $(libcurl_a_SOURCES)
|
SOURCES = $(libcurl_a_SOURCES)
|
||||||
|
@@ -202,7 +202,9 @@ X_OBJS= \
|
|||||||
$(DIROBJ)\hash.obj \
|
$(DIROBJ)\hash.obj \
|
||||||
$(DIROBJ)\llist.obj \
|
$(DIROBJ)\llist.obj \
|
||||||
$(DIROBJ)\share.obj \
|
$(DIROBJ)\share.obj \
|
||||||
$(DIROBJ)\multi.obj
|
$(DIROBJ)\multi.obj \
|
||||||
|
$(DIROBJ)\http_digest.obj \
|
||||||
|
$(DIROBJ)\md5.obj
|
||||||
|
|
||||||
all : $(TARGET)
|
all : $(TARGET)
|
||||||
|
|
||||||
@@ -224,3 +226,6 @@ clean:
|
|||||||
-@erase $(DIROBJ)\*.obj
|
-@erase $(DIROBJ)\*.obj
|
||||||
-@erase vc60.idb
|
-@erase vc60.idb
|
||||||
-@erase vc60.pch
|
-@erase vc60.pch
|
||||||
|
|
||||||
|
getdate.c: getdate.c.cvs
|
||||||
|
copy getdate.c.cvs getdate.c
|
||||||
|
@@ -17,7 +17,7 @@ Single-threaded
|
|||||||
|
|
||||||
Build
|
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
|
--enable-debug fixes this). 'make clean' first, then 'make' so that all
|
||||||
files actually are rebuilt properly. It will also make sense to build
|
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
|
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"
|
#include "base64.h"
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -220,6 +220,8 @@ int main(int argc, char **argv, char **envp)
|
|||||||
#ifdef TEST_DECODE
|
#ifdef TEST_DECODE
|
||||||
/* decoding test harness. Read in a base64 string from stdin and write out the
|
/* 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
|
* 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>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -232,13 +234,31 @@ int main(int argc, char **argv, char **envp)
|
|||||||
int base64Len;
|
int base64Len;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int dataLen;
|
int dataLen;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
base64 = (char *)suck(&base64Len);
|
base64 = (char *)suck(&base64Len);
|
||||||
data = (unsigned char *)malloc(base64Len * 3/4 + 8);
|
data = (unsigned char *)malloc(base64Len * 3/4 + 8);
|
||||||
dataLen = Curl_base64_decode(base64, data);
|
dataLen = Curl_base64_decode(base64, data);
|
||||||
|
|
||||||
fprintf(stderr, "%d\n", dataLen);
|
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);
|
free(base64); free(data);
|
||||||
return 0;
|
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"
|
#include "if2ip.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -92,7 +92,7 @@ Example set of cookies:
|
|||||||
#include "strtok.h"
|
#include "strtok.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -389,6 +389,22 @@ SOURCE=.\url.h
|
|||||||
|
|
||||||
SOURCE=.\urldata.h
|
SOURCE=.\urldata.h
|
||||||
# End Source File
|
# 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
|
# End Group
|
||||||
# Begin Group "Resource Files"
|
# Begin Group "Resource Files"
|
||||||
|
|
||||||
|
@@ -44,7 +44,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -46,7 +46,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
23
lib/escape.c
23
lib/escape.c
@@ -33,7 +33,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -79,6 +79,10 @@ char *curl_escape(const char *string, int length)
|
|||||||
return ns;
|
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)
|
char *curl_unescape(const char *string, int length)
|
||||||
{
|
{
|
||||||
int alloc = (length?length:(int)strlen(string))+1;
|
int alloc = (length?length:(int)strlen(string))+1;
|
||||||
@@ -93,14 +97,20 @@ char *curl_unescape(const char *string, int length)
|
|||||||
|
|
||||||
while(--alloc > 0) {
|
while(--alloc > 0) {
|
||||||
in = *string;
|
in = *string;
|
||||||
if('%' == in) {
|
if(('%' == in) && ishex(string[1]) && ishex(string[2])) {
|
||||||
/* encoded part */
|
/* this is two hexadecimal digits following a '%' */
|
||||||
if(sscanf(string+1, "%02X", &hex)) {
|
char hexstr[3];
|
||||||
|
char *ptr;
|
||||||
|
hexstr[0] = string[1];
|
||||||
|
hexstr[1] = string[2];
|
||||||
|
hexstr[2] = 0;
|
||||||
|
|
||||||
|
hex = strtol(hexstr, &ptr, 16);
|
||||||
|
|
||||||
in = hex;
|
in = hex;
|
||||||
string+=2;
|
string+=2;
|
||||||
alloc-=2;
|
alloc-=2;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ns[index++] = in;
|
ns[index++] = in;
|
||||||
string++;
|
string++;
|
||||||
@@ -109,6 +119,9 @@ char *curl_unescape(const char *string, int length)
|
|||||||
return ns;
|
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)
|
void curl_free(void *p)
|
||||||
{
|
{
|
||||||
free(p);
|
free(p);
|
||||||
|
@@ -48,7 +48,6 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -88,7 +87,7 @@
|
|||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -124,7 +124,7 @@ Content-Disposition: form-data; name="FILECONTENT"
|
|||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
54
lib/ftp.c
54
lib/ftp.c
@@ -94,7 +94,7 @@
|
|||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -409,9 +409,9 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
|
|||||||
/* get some initial data into the ftp struct */
|
/* get some initial data into the ftp struct */
|
||||||
ftp->bytecountp = &conn->bytecount;
|
ftp->bytecountp = &conn->bytecount;
|
||||||
|
|
||||||
/* no need to duplicate them, the data struct won't change */
|
/* no need to duplicate them, this connectdata struct won't change */
|
||||||
ftp->user = data->state.user;
|
ftp->user = conn->user;
|
||||||
ftp->passwd = data->state.passwd;
|
ftp->passwd = conn->passwd;
|
||||||
ftp->response_time = 3600; /* set default response time-out */
|
ftp->response_time = 3600; /* set default response time-out */
|
||||||
|
|
||||||
if (data->set.tunnel_thru_httpproxy) {
|
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
|
/* we may need to issue a KAUTH here to have access to the files
|
||||||
* do it if user supplied a password
|
* do it if user supplied a password
|
||||||
*/
|
*/
|
||||||
if(data->state.passwd && *data->state.passwd) {
|
if(conn->passwd && *conn->passwd) {
|
||||||
result = Curl_krb_kauth(conn);
|
result = Curl_krb_kauth(conn);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
@@ -1184,7 +1184,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (ftpcode != 200) {
|
if (ftpcode != 200) {
|
||||||
failf(data, "Server does not grok %s", *modep);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1193,6 +1192,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
|
|
||||||
if (!*modep) {
|
if (!*modep) {
|
||||||
sclose(portsock);
|
sclose(portsock);
|
||||||
|
failf(data, "PORT command attempts failed");
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
/* we set the secondary socket variable to this for now, it
|
/* we set the secondary socket variable to this for now, it
|
||||||
@@ -1930,10 +1930,16 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
|||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if(dirlist && (ftpcode == 450)) {
|
||||||
|
/* simply no matching files */
|
||||||
|
ftp->no_transfer = TRUE; /* don't think we should download anything */
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
failf(data, "%s", buf+4);
|
failf(data, "%s", buf+4);
|
||||||
return CURLE_FTP_COULDNT_RETR_FILE;
|
return CURLE_FTP_COULDNT_RETR_FILE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
/* end of transfer */
|
/* end of transfer */
|
||||||
@@ -2055,7 +2061,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
|||||||
struct tm buffer;
|
struct tm buffer;
|
||||||
tm = (struct tm *)localtime_r(&data->info.filetime, &buffer);
|
tm = (struct tm *)localtime_r(&data->info.filetime, &buffer);
|
||||||
#else
|
#else
|
||||||
tm = localtime((unsigned long *)&data->info.filetime);
|
tm = localtime(&data->info.filetime);
|
||||||
#endif
|
#endif
|
||||||
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
|
/* 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",
|
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 */
|
/* parse the URL path into separate path components */
|
||||||
while((slash_pos=strchr(cur_pos, '/'))) {
|
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 */
|
/* seek out the next path component */
|
||||||
if (0 == slash_pos-cur_pos) /* empty path component, like "x//y" */
|
if (slash_pos-cur_pos) {
|
||||||
ftp->dirs[path_part] = strdup(""); /* empty string */
|
/* we skip empty path components, like "x//y" since the FTP command CWD
|
||||||
else
|
requires a parameter and a non-existant parameter a) doesn't work on
|
||||||
ftp->dirs[path_part] = curl_unescape(cur_pos,slash_pos-cur_pos);
|
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 ... */
|
if (!ftp->dirs[path_part]) { /* run out of memory ... */
|
||||||
failf(data, "no memory");
|
failf(data, "no memory");
|
||||||
retcode = CURLE_OUT_OF_MEMORY;
|
retcode = CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
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 */
|
cur_pos = slash_pos + 1; /* jump to the rest of the string */
|
||||||
if(++path_part >= (CURL_MAX_FTP_DIRDEPTH-1)) {
|
if(++path_part >= (CURL_MAX_FTP_DIRDEPTH-1)) {
|
||||||
/* too deep, we need the last entry to be kept NULL at all
|
/* 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(CURLE_OK == retcode) {
|
||||||
if(connected)
|
if(connected)
|
||||||
retcode = Curl_ftp_nextconnect(conn);
|
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 */
|
/* no data to transfer */
|
||||||
retcode=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
retcode=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||||
}
|
else if(!connected)
|
||||||
else {
|
|
||||||
/* since we didn't connect now, we want do_more to get called */
|
/* since we didn't connect now, we want do_more to get called */
|
||||||
conn->bits.do_more = TRUE;
|
conn->bits.do_more = TRUE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
@@ -35,7 +35,7 @@
|
|||||||
#include <unixlib.h>
|
#include <unixlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Make this the last #include */
|
/* Make this the last #include */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#else
|
#else
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@@ -89,7 +89,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
|||||||
char infp_fclose = 0;
|
char infp_fclose = 0;
|
||||||
FILE *outfp;
|
FILE *outfp;
|
||||||
RETSIGTYPE (*sigint)();
|
RETSIGTYPE (*sigint)();
|
||||||
#ifndef __EMX__
|
#ifdef SIGTSTP
|
||||||
RETSIGTYPE (*sigtstp)();
|
RETSIGTYPE (*sigtstp)();
|
||||||
#endif
|
#endif
|
||||||
size_t bytes_read;
|
size_t bytes_read;
|
||||||
@@ -117,9 +117,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
sigint = signal(SIGINT, SIG_IGN);
|
sigint = signal(SIGINT, SIG_IGN);
|
||||||
/* 20000318 mgs
|
#ifdef SIGTSTP
|
||||||
* this is needed by the emx system, SIGTSTP is not a supported signal */
|
|
||||||
#ifndef __EMX__
|
|
||||||
sigtstp = signal(SIGTSTP, SIG_IGN);
|
sigtstp = signal(SIGTSTP, SIG_IGN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -181,7 +179,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
signal(SIGINT, sigint);
|
signal(SIGINT, sigint);
|
||||||
#ifndef __EMX__
|
#ifdef SIGTSTP
|
||||||
signal(SIGTSTP, sigtstp);
|
signal(SIGTSTP, sigtstp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -29,7 +29,7 @@
|
|||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "llist.h"
|
#include "llist.h"
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
/* this must be the last include file */
|
/* this must be the last include file */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
27
lib/hostip.c
27
lib/hostip.c
@@ -74,7 +74,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
|
|||||||
hostcache_timestamp_remove);
|
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
|
/* Called from Curl_done() to check that there's no DNS cache entry with
|
||||||
a non-zero counter left. */
|
a non-zero counter left. */
|
||||||
void Curl_scan_cache_used(void *user, void *ptr)
|
void Curl_scan_cache_used(void *user, void *ptr)
|
||||||
@@ -252,9 +252,7 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(data->share)
|
if(data->share)
|
||||||
{
|
|
||||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||||
}
|
|
||||||
|
|
||||||
/* See if its already in our dns cache */
|
/* See if its already in our dns cache */
|
||||||
dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1);
|
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->timestamp = now;
|
||||||
dns->inuse++; /* mark entry as in-use */
|
dns->inuse++; /* mark entry as in-use */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
dns->entry_id = entry_id;
|
dns->entry_id = entry_id;
|
||||||
#endif
|
#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)
|
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
||||||
{
|
{
|
||||||
if(data->share)
|
if(data->share)
|
||||||
{
|
|
||||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||||
}
|
|
||||||
dns->inuse--;
|
dns->inuse--;
|
||||||
|
|
||||||
if(data->share)
|
if(data->share)
|
||||||
{
|
|
||||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -337,7 +334,7 @@ void Curl_freednsinfo(void *freethis)
|
|||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
/* These two are strictly for memory tracing and are using the same
|
/* 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
|
* 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
|
* 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;
|
copy->h_aliases = (char**)bufptr;
|
||||||
|
|
||||||
/* Figure out how many aliases there are */
|
/* 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 */
|
/* Reserve room for the array */
|
||||||
bufptr += (i + 1) * sizeof(char*);
|
bufptr += (i + 1) * sizeof(char*);
|
||||||
|
|
||||||
/* Clone all known aliases */
|
/* Clone all known aliases */
|
||||||
|
if(orig->h_aliases) {
|
||||||
for(i = 0; (str = orig->h_aliases[i]); i++) {
|
for(i = 0; (str = orig->h_aliases[i]); i++) {
|
||||||
len = strlen(str) + 1;
|
len = strlen(str) + 1;
|
||||||
strncpy(bufptr, str, len);
|
strncpy(bufptr, str, len);
|
||||||
copy->h_aliases[i] = bufptr;
|
copy->h_aliases[i] = bufptr;
|
||||||
bufptr += len;
|
bufptr += len;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/* if(!orig->h_aliases) i was already set to 0 */
|
||||||
|
|
||||||
/* Terminate the alias list with a NULL */
|
/* Terminate the alias list with a NULL */
|
||||||
copy->h_aliases[i] = NULL;
|
copy->h_aliases[i] = NULL;
|
||||||
|
|
||||||
@@ -627,7 +628,7 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
|
|||||||
step_size+=200;
|
step_size+=200;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -677,7 +678,7 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
|
|||||||
if(!h) /* failure */
|
if(!h) /* failure */
|
||||||
res=1;
|
res=1;
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
||||||
#endif
|
#endif
|
||||||
if(!res) {
|
if(!res) {
|
||||||
|
@@ -41,7 +41,7 @@ struct Curl_dns_entry {
|
|||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
long inuse; /* use-counter, make very sure you decrease this
|
long inuse; /* use-counter, make very sure you decrease this
|
||||||
when you're done using the address you received */
|
when you're done using the address you received */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
char *entry_id;
|
char *entry_id;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -70,7 +70,7 @@ void Curl_freeaddrinfo(Curl_addrinfo *freeaddr);
|
|||||||
/* free cached name info */
|
/* free cached name info */
|
||||||
void Curl_freednsinfo(void *freethis);
|
void Curl_freednsinfo(void *freethis);
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
void curl_freeaddrinfo(struct addrinfo *freethis,
|
void curl_freeaddrinfo(struct addrinfo *freethis,
|
||||||
int line, const char *source);
|
int line, const char *source);
|
||||||
int curl_getaddrinfo(char *hostname, char *service,
|
int curl_getaddrinfo(char *hostname, char *service,
|
||||||
|
179
lib/http.c
179
lib/http.c
@@ -54,7 +54,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -89,12 +88,15 @@
|
|||||||
#include "cookie.h"
|
#include "cookie.h"
|
||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
#include "ssluse.h"
|
#include "ssluse.h"
|
||||||
|
#include "http_digest.h"
|
||||||
|
#include "http_ntlm.h"
|
||||||
|
#include "http_negotiate.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -190,6 +192,7 @@ CURLcode add_buffer_send(send_buffer *in,
|
|||||||
char *ptr;
|
char *ptr;
|
||||||
int size;
|
int size;
|
||||||
struct HTTP *http = conn->proto.http;
|
struct HTTP *http = conn->proto.http;
|
||||||
|
int sendsize;
|
||||||
|
|
||||||
/* The looping below is required since we use non-blocking sockets, but due
|
/* 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 */
|
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;
|
ptr = in->buffer;
|
||||||
size = in->size_used;
|
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) {
|
if(CURLE_OK == res) {
|
||||||
|
|
||||||
@@ -213,7 +237,8 @@ CURLcode add_buffer_send(send_buffer *in,
|
|||||||
and wait until it might work again. */
|
and wait until it might work again. */
|
||||||
|
|
||||||
size -= amount;
|
size -= amount;
|
||||||
ptr += amount;
|
|
||||||
|
ptr = in->buffer + amount;
|
||||||
|
|
||||||
/* backup the currently set pointers */
|
/* backup the currently set pointers */
|
||||||
http->backup.fread = conn->fread;
|
http->backup.fread = conn->fread;
|
||||||
@@ -591,11 +616,15 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
|||||||
conn->fread = data->set.fread; /* restore */
|
conn->fread = data->set.fread; /* restore */
|
||||||
conn->fread_in = data->set.in; /* restore */
|
conn->fread_in = data->set.in; /* restore */
|
||||||
|
|
||||||
|
if (http == NULL)
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
if(http->send_buffer) {
|
if(http->send_buffer) {
|
||||||
send_buffer *buff = http->send_buffer;
|
send_buffer *buff = http->send_buffer;
|
||||||
|
|
||||||
free(buff->buffer);
|
free(buff->buffer);
|
||||||
free(buff);
|
free(buff);
|
||||||
|
http->send_buffer = NULL; /* cleaer the pointer */
|
||||||
}
|
}
|
||||||
|
|
||||||
if(HTTPREQ_POST_FORM == data->set.httpreq) {
|
if(HTTPREQ_POST_FORM == data->set.httpreq) {
|
||||||
@@ -616,6 +645,25 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
|||||||
return CURLE_OK;
|
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)
|
CURLcode Curl_http(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data=conn->data;
|
struct SessionHandle *data=conn->data;
|
||||||
@@ -627,6 +675,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
char *host = conn->name;
|
char *host = conn->name;
|
||||||
const char *te = ""; /* tranfer-encoding */
|
const char *te = ""; /* tranfer-encoding */
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
char *request;
|
||||||
|
|
||||||
if(!conn->proto.http) {
|
if(!conn->proto.http) {
|
||||||
/* Only allocate this struct if we don't already have it! */
|
/* 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;
|
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
|
/* 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
|
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
|
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;
|
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
|
/* 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 */
|
host due to a location-follow, we do some weirdo checks here */
|
||||||
if(!data->state.this_is_a_follow ||
|
if(!data->state.this_is_a_follow ||
|
||||||
!data->state.auth_host ||
|
!data->state.auth_host ||
|
||||||
curl_strequal(data->state.auth_host, conn->hostname) ||
|
curl_strequal(data->state.auth_host, conn->hostname) ||
|
||||||
data->set.http_disable_hostname_check_before_authentication) {
|
data->set.http_disable_hostname_check_before_authentication) {
|
||||||
sprintf(data->state.buffer, "%s:%s",
|
|
||||||
data->state.user, data->state.passwd);
|
#ifdef GSSAPI
|
||||||
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
|
if((data->state.authwant == CURLAUTH_GSSNEGOTIATE) &&
|
||||||
&authorization) >= 0) {
|
data->state.negotiate.context &&
|
||||||
if(conn->allocptr.userpwd)
|
!GSS_ERROR(data->state.negotiate.status)) {
|
||||||
free(conn->allocptr.userpwd);
|
result = Curl_output_negotiate(conn);
|
||||||
conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012",
|
if (result)
|
||||||
authorization);
|
return result;
|
||||||
free(authorization);
|
}
|
||||||
|
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((data->change.referer) && !checkheaders(data, "Referer:")) {
|
||||||
if(conn->allocptr.ref)
|
if(conn->allocptr.ref)
|
||||||
free(conn->allocptr.ref);
|
free(conn->allocptr.ref);
|
||||||
@@ -773,7 +852,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
(bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE));
|
(bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->change.proxy && *data->change.proxy &&
|
if (conn->bits.httpproxy &&
|
||||||
!data->set.tunnel_thru_httpproxy &&
|
!data->set.tunnel_thru_httpproxy &&
|
||||||
!(conn->protocol&PROT_HTTPS)) {
|
!(conn->protocol&PROT_HTTPS)) {
|
||||||
/* The path sent to the proxy is in fact the entire URL */
|
/* 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 */
|
/* Use 1.1 unless the use specificly asked for 1.0 */
|
||||||
const char *httpstring=
|
const char *httpstring=
|
||||||
data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1";
|
data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1";
|
||||||
|
|
||||||
send_buffer *req_buffer;
|
send_buffer *req_buffer;
|
||||||
struct curl_slist *headers=data->set.headers;
|
struct curl_slist *headers=data->set.headers;
|
||||||
|
size_t postsize;
|
||||||
|
|
||||||
/* initialize a dynamic send-buffer */
|
/* initialize a dynamic send-buffer */
|
||||||
req_buffer = add_buffer_init();
|
req_buffer = add_buffer_init();
|
||||||
@@ -902,7 +982,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
/* add the main request stuff */
|
/* add the main request stuff */
|
||||||
add_bufferf(req_buffer,
|
add_bufferf(req_buffer,
|
||||||
"%s " /* GET/HEAD/POST/PUT */
|
"%s " /* GET/HEAD/POST/PUT */
|
||||||
"%s HTTP/%s\r\n" /* path */
|
"%s HTTP/%s\r\n" /* path + HTTP version */
|
||||||
"%s" /* proxyuserpwd */
|
"%s" /* proxyuserpwd */
|
||||||
"%s" /* userpwd */
|
"%s" /* userpwd */
|
||||||
"%s" /* range */
|
"%s" /* range */
|
||||||
@@ -915,16 +995,12 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
"%s" /* referer */
|
"%s" /* referer */
|
||||||
"%s",/* transfer-encoding */
|
"%s",/* transfer-encoding */
|
||||||
|
|
||||||
data->set.customrequest?data->set.customrequest:
|
request,
|
||||||
(data->set.no_body?"HEAD":
|
ppath,
|
||||||
((HTTPREQ_POST == data->set.httpreq) ||
|
httpstring,
|
||||||
(HTTPREQ_POST_FORM == data->set.httpreq))?"POST":
|
(conn->bits.httpproxy && conn->allocptr.proxyuserpwd)?
|
||||||
(HTTPREQ_PUT == data->set.httpreq)?"PUT":"GET"),
|
conn->allocptr.proxyuserpwd:"",
|
||||||
ppath, httpstring,
|
conn->allocptr.userpwd?conn->allocptr.userpwd:"",
|
||||||
(conn->bits.proxy_user_passwd &&
|
|
||||||
conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"",
|
|
||||||
(conn->bits.user_passwd && conn->allocptr.userpwd)?
|
|
||||||
conn->allocptr.userpwd:"",
|
|
||||||
(conn->bits.use_range && conn->allocptr.rangeline)?
|
(conn->bits.use_range && conn->allocptr.rangeline)?
|
||||||
conn->allocptr.rangeline:"",
|
conn->allocptr.rangeline:"",
|
||||||
(data->set.useragent && *data->set.useragent && conn->allocptr.uagent)?
|
(data->set.useragent && *data->set.useragent && conn->allocptr.uagent)?
|
||||||
@@ -1132,6 +1208,11 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
case HTTPREQ_POST:
|
case HTTPREQ_POST:
|
||||||
/* this is the simple POST, using x-www-form-urlencoded style */
|
/* 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) {
|
if(!conn->bits.upload_chunky) {
|
||||||
/* We only set Content-Length and allow a custom Content-Length if
|
/* 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
|
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:"))
|
if(!checkheaders(data, "Content-Length:"))
|
||||||
/* we allow replacing this header, although it isn't very wise to
|
/* we allow replacing this header, although it isn't very wise to
|
||||||
actually set your own */
|
actually set your own */
|
||||||
add_bufferf(req_buffer,
|
add_bufferf(req_buffer, "Content-Length: %d\r\n", postsize);
|
||||||
"Content-Length: %d\r\n",
|
|
||||||
data->set.postfieldsize?
|
|
||||||
data->set.postfieldsize:
|
|
||||||
(data->set.postfields?strlen(data->set.postfields):0) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!checkheaders(data, "Content-Type:"))
|
if(!checkheaders(data, "Content-Type:"))
|
||||||
@@ -1153,12 +1230,28 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
|
|
||||||
add_buffer(req_buffer, "\r\n", 2);
|
add_buffer(req_buffer, "\r\n", 2);
|
||||||
|
|
||||||
/* and here we setup the pointers to the actual data */
|
|
||||||
if(data->set.postfields) {
|
if(data->set.postfields) {
|
||||||
if(data->set.postfieldsize)
|
|
||||||
http->postsize = data->set.postfieldsize;
|
if(postsize < (100*1024)) {
|
||||||
else
|
/* The post data is less than 100K, then append it to the header.
|
||||||
http->postsize = strlen(data->set.postfields);
|
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->postdata = data->set.postfields;
|
||||||
|
|
||||||
http->sending = HTTPSEND_BODY;
|
http->sending = HTTPSEND_BODY;
|
||||||
@@ -1169,6 +1262,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
/* set the upload size to the progress meter */
|
/* set the upload size to the progress meter */
|
||||||
Curl_pgrsSetUploadSize(data, http->postsize);
|
Curl_pgrsSetUploadSize(data, http->postsize);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
/* set the upload size to the progress meter */
|
/* set the upload size to the progress meter */
|
||||||
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
||||||
@@ -1183,8 +1277,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
result =
|
result =
|
||||||
Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
|
Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
|
||||||
&http->readbytecount,
|
&http->readbytecount,
|
||||||
conn->firstsocket,
|
http->postdata?conn->firstsocket:-1,
|
||||||
&http->writebytecount);
|
http->postdata?&http->writebytecount:NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1205,8 +1299,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
} while (0); /* this is just a left-over from the multiple document download
|
}
|
||||||
attempts */
|
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
@@ -39,7 +39,7 @@
|
|||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DJGPP
|
||||||
|
#define IOCTL_3_ARGS
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SYS_ERROR -1
|
#define SYS_ERROR -1
|
||||||
|
|
||||||
char *Curl_if2ip(char *interface, char *buf, int buf_size)
|
char *Curl_if2ip(char *interface, char *buf, int buf_size)
|
||||||
|
@@ -64,7 +64,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
|
|||||||
|
|
||||||
save = Curl_set_command_prot(conn, prot_private);
|
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)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
@@ -363,7 +363,7 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
|
|||||||
for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
|
for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
||||||
des_string_to_key (conn->data->state.passwd, &key);
|
des_string_to_key (conn->passwd, &key);
|
||||||
des_key_sched(&key, schedule);
|
des_key_sched(&key, schedule);
|
||||||
|
|
||||||
des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat,
|
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
|
* liblber.so automatically, but since it does not we will
|
||||||
* handle it here by opening liblber.so as global.
|
* 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: */
|
#ifdef RTLD_LAZY_GLOBAL /* It turns out some systems use this: */
|
||||||
RTLD_LAZY_GLOBAL
|
RTLD_LAZY_GLOBAL
|
||||||
#else
|
#else
|
||||||
@@ -178,8 +178,8 @@ CURLcode Curl_ldap(struct connectdata *conn)
|
|||||||
status = CURLE_COULDNT_CONNECT;
|
status = CURLE_COULDNT_CONNECT;
|
||||||
} else {
|
} else {
|
||||||
rc = ldap_simple_bind_s(server,
|
rc = ldap_simple_bind_s(server,
|
||||||
conn->bits.user_passwd?data->state.user:NULL,
|
conn->bits.user_passwd?conn->user:NULL,
|
||||||
conn->bits.user_passwd?data->state.passwd:NULL);
|
conn->bits.user_passwd?conn->passwd:NULL);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
failf(data, "LDAP: %s", ldap_err2string(rc));
|
failf(data, "LDAP: %s", ldap_err2string(rc));
|
||||||
status = CURLE_LDAP_CANNOT_BIND;
|
status = CURLE_LDAP_CANNOT_BIND;
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#include "llist.h"
|
#include "llist.h"
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
/* this must be the last include file */
|
/* this must be the last include file */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#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
|
#ifndef __MD5_H
|
||||||
#define __CA_BUNDLE_H
|
#define __MD5_H
|
||||||
/*****************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* 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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
* 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
|
* 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
|
* 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
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
* licenses. You may pick one of these licenses.
|
|
||||||
*
|
*
|
||||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
* KIND, either express or implied.
|
* KIND, either express or implied.
|
||||||
*
|
*
|
||||||
* $Id$
|
* $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
|
||||||
|
|
||||||
#endif /* __CA_BUNDLE_H */
|
|
@@ -1,4 +1,4 @@
|
|||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
@@ -220,4 +220,4 @@ int curl_fclose(FILE *file, int line, const char *source)
|
|||||||
#ifdef VMS
|
#ifdef VMS
|
||||||
int VOID_VAR_MEMDEBUG;
|
int VOID_VAR_MEMDEBUG;
|
||||||
#endif
|
#endif
|
||||||
#endif /* MALLOCDEBUG */
|
#endif /* CURLDEBUG */
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
|
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
12
lib/multi.c
12
lib/multi.c
@@ -31,6 +31,9 @@
|
|||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
@@ -41,7 +44,7 @@
|
|||||||
#include "progress.h"
|
#include "progress.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -299,7 +302,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
easy=multi->easy.next;
|
easy=multi->easy.next;
|
||||||
while(easy) {
|
while(easy) {
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
fprintf(stderr, "HANDLE %p: State: %x\n",
|
fprintf(stderr, "HANDLE %p: State: %x\n",
|
||||||
(char *)easy, easy->state);
|
(char *)easy, easy->state);
|
||||||
#endif
|
#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 */
|
/* When we follow redirects, must to go back to the CONNECT state */
|
||||||
if(easy->easy_conn->newurl) {
|
if(easy->easy_conn->newurl) {
|
||||||
easy->result = Curl_follow(easy->easy_handle,
|
char *newurl = easy->easy_conn->newurl;
|
||||||
strdup(easy->easy_conn->newurl));
|
easy->easy_conn->newurl = NULL;
|
||||||
|
easy->result = Curl_follow(easy->easy_handle, newurl);
|
||||||
if(CURLE_OK == easy->result) {
|
if(CURLE_OK == easy->result) {
|
||||||
easy->state = CURLM_STATE_CONNECT;
|
easy->state = CURLM_STATE_CONNECT;
|
||||||
result = CURLM_CALL_MULTI_PERFORM;
|
result = CURLM_CALL_MULTI_PERFORM;
|
||||||
|
@@ -46,7 +46,7 @@
|
|||||||
#include "strtok.h"
|
#include "strtok.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ int Curl_parsenetrc(char *host,
|
|||||||
|
|
||||||
sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC);
|
sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC);
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
{
|
{
|
||||||
/* This is a hack to allow testing.
|
/* This is a hack to allow testing.
|
||||||
* If compiled with --enable-debug and CURL_DEBUG_NETRC is defined,
|
* If compiled with --enable-debug and CURL_DEBUG_NETRC is defined,
|
||||||
@@ -141,7 +141,7 @@ int Curl_parsenetrc(char *host,
|
|||||||
free(override);
|
free(override);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* MALLOCDEBUG */
|
#endif /* CURLDEBUG */
|
||||||
|
|
||||||
file = fopen(netrcbuffer, "r");
|
file = fopen(netrcbuffer, "r");
|
||||||
if(file) {
|
if(file) {
|
||||||
|
@@ -60,7 +60,7 @@
|
|||||||
#include "ftp.h"
|
#include "ftp.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
40
lib/sendf.c
40
lib/sendf.c
@@ -56,7 +56,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -94,7 +94,6 @@ struct curl_slist *curl_slist_append(struct curl_slist *list,
|
|||||||
new_item->data = strdup(data);
|
new_item->data = strdup(data);
|
||||||
}
|
}
|
||||||
if (new_item == NULL || new_item->data == NULL) {
|
if (new_item == NULL || new_item->data == NULL) {
|
||||||
fprintf(stderr, "Cannot allocate memory for QUOTE list.\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,6 +228,7 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
|||||||
ssize_t *written)
|
ssize_t *written)
|
||||||
{
|
{
|
||||||
ssize_t bytes_written;
|
ssize_t bytes_written;
|
||||||
|
CURLcode retcode;
|
||||||
(void)conn;
|
(void)conn;
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
@@ -244,13 +244,28 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
|||||||
switch(err) {
|
switch(err) {
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
case SSL_ERROR_WANT_WRITE:
|
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;
|
*written = 0;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n",
|
failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n",
|
||||||
Curl_ourerrno());
|
Curl_ourerrno());
|
||||||
return CURLE_SEND_ERROR;
|
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 */
|
/* a true error */
|
||||||
failf(conn->data, "SSL_write() return error %d\n", err);
|
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) {
|
if(-1 == bytes_written) {
|
||||||
int err = Curl_ourerrno();
|
int err = Curl_ourerrno();
|
||||||
#ifdef WIN32
|
|
||||||
if(WSAEWOULDBLOCK == err)
|
if(
|
||||||
|
#ifdef WSAEWOULDBLOCK
|
||||||
|
/* This is how Windows does it */
|
||||||
|
(WSAEWOULDBLOCK == err)
|
||||||
#else
|
#else
|
||||||
/* As pointed out by Christophe Demory on March 11 2003, errno
|
/* As pointed out by Christophe Demory on March 11 2003, errno
|
||||||
may be EWOULDBLOCK or on some systems EAGAIN when it returned
|
may be EWOULDBLOCK or on some systems EAGAIN when it returned
|
||||||
due to its inability to send off data without blocking. We
|
due to its inability to send off data without blocking. We
|
||||||
therefor treat both error codes the same here */
|
therefor treat both error codes the same here */
|
||||||
if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
|
(EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
|
||||||
#endif
|
#endif
|
||||||
{
|
)
|
||||||
/* this is just a case of EWOULDBLOCK */
|
/* this is just a case of EWOULDBLOCK */
|
||||||
*written=0;
|
bytes_written=0;
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*written = bytes_written;
|
*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)
|
/* 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
|
#define HAVE_ALARM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PATH_CHAR ";"
|
|
||||||
#define DIR_CHAR "\\"
|
#define DIR_CHAR "\\"
|
||||||
#define DOT_CHAR "_"
|
#define DOT_CHAR "_"
|
||||||
|
|
||||||
#else
|
#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 sclose(x) close(x)
|
||||||
#define sread(x,y,z) recv(x,y,z,0)
|
#define sread(x,y,z) recv(x,y,z,0)
|
||||||
#define swrite(x,y,z) send(x,y,z,0)
|
#define swrite(x,y,z) send(x,y,z,0)
|
||||||
#define HAVE_ALARM
|
#define HAVE_ALARM
|
||||||
|
|
||||||
#define PATH_CHAR ":"
|
#endif
|
||||||
|
|
||||||
#define DIR_CHAR "/"
|
#define DIR_CHAR "/"
|
||||||
#define DOT_CHAR "."
|
#define DOT_CHAR "."
|
||||||
|
|
||||||
|
#ifdef DJGPP
|
||||||
|
#undef DOT_CHAR
|
||||||
|
#define DOT_CHAR "_"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_STRCASECMP
|
#ifdef HAVE_STRCASECMP
|
||||||
/* this is for "-ansi -Wall -pedantic" to stop complaining! */
|
/* this is for "-ansi -Wall -pedantic" to stop complaining! */
|
||||||
extern int (strcasecmp)(const char *s1, const char *s2);
|
extern int (strcasecmp)(const char *s1, const char *s2);
|
||||||
|
@@ -24,12 +24,13 @@
|
|||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include "share.h"
|
#include "share.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
21
lib/ssluse.c
21
lib/ssluse.c
@@ -46,7 +46,7 @@
|
|||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -786,6 +786,16 @@ Curl_SSLConnect(struct connectdata *conn)
|
|||||||
return CURLE_OUT_OF_MEMORY;
|
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(data->set.cert) {
|
||||||
if (!cert_stuff(conn,
|
if (!cert_stuff(conn,
|
||||||
data->set.cert,
|
data->set.cert,
|
||||||
@@ -821,6 +831,15 @@ Curl_SSLConnect(struct connectdata *conn)
|
|||||||
else
|
else
|
||||||
SSL_CTX_set_verify(conn->ssl.ctx, SSL_VERIFY_NONE, cert_verify_callback);
|
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 */
|
/* Lets make an SSL structure */
|
||||||
conn->ssl.handle = SSL_new (conn->ssl.ctx);
|
conn->ssl.handle = SSL_new (conn->ssl.ctx);
|
||||||
|
@@ -45,7 +45,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -84,7 +83,7 @@
|
|||||||
#include "arpa_telnet.h"
|
#include "arpa_telnet.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -756,7 +755,7 @@ static int check_telnet_options(struct connectdata *conn)
|
|||||||
if(conn->bits.user_passwd)
|
if(conn->bits.user_passwd)
|
||||||
{
|
{
|
||||||
char *buf = malloc(256);
|
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->telnet_vars = curl_slist_append(tn->telnet_vars, buf);
|
||||||
|
|
||||||
tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
|
tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
|
||||||
|
351
lib/transfer.c
351
lib/transfer.c
@@ -46,7 +46,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -95,12 +94,15 @@
|
|||||||
#include "url.h"
|
#include "url.h"
|
||||||
#include "getinfo.h"
|
#include "getinfo.h"
|
||||||
#include "ssluse.h"
|
#include "ssluse.h"
|
||||||
|
#include "http_digest.h"
|
||||||
|
#include "http_ntlm.h"
|
||||||
|
#include "http_negotiate.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -284,6 +286,9 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
/* header line within buffer loop */
|
/* header line within buffer loop */
|
||||||
do {
|
do {
|
||||||
int hbufp_index;
|
int hbufp_index;
|
||||||
|
int rest_length;
|
||||||
|
int full_length;
|
||||||
|
int writetype;
|
||||||
|
|
||||||
/* str_start is start of line within buf */
|
/* str_start is start of line within buf */
|
||||||
k->str_start = k->str;
|
k->str_start = k->str;
|
||||||
@@ -325,22 +330,24 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
break; /* read more and try again */
|
break; /* read more and try again */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decrease the size of the remaining buffer */
|
/* decrease the size of the remaining (supposed) header line */
|
||||||
nread -= (k->end_ptr - k->str)+1;
|
rest_length = (k->end_ptr - k->str)+1;
|
||||||
|
nread -= rest_length;
|
||||||
|
|
||||||
k->str = k->end_ptr + 1; /* move past new line */
|
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
|
* We're about to copy a chunk of data to the end of the
|
||||||
* already received header. We make sure that the full string
|
* already received header. We make sure that the full string
|
||||||
* fit in the allocated header buffer, or else we enlarge
|
* fit in the allocated header buffer, or else we enlarge
|
||||||
* it.
|
* it.
|
||||||
*/
|
*/
|
||||||
if (k->hbuflen + (k->str - k->str_start) >=
|
if (k->hbuflen + full_length >=
|
||||||
data->state.headersize) {
|
data->state.headersize) {
|
||||||
char *newbuff;
|
char *newbuff;
|
||||||
long newsize=MAX((k->hbuflen+
|
long newsize=MAX((k->hbuflen+full_length)*3/2,
|
||||||
(k->str-k->str_start))*3/2,
|
|
||||||
data->state.headersize*2);
|
data->state.headersize*2);
|
||||||
hbufp_index = k->hbufp - data->state.headerbuff;
|
hbufp_index = k->hbufp - data->state.headerbuff;
|
||||||
newbuff = (char *)realloc(data->state.headerbuff, newsize);
|
newbuff = (char *)realloc(data->state.headerbuff, newsize);
|
||||||
@@ -354,10 +361,11 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copy to end of line */
|
/* copy to end of line */
|
||||||
strncpy (k->hbufp, k->str_start, k->str - k->str_start);
|
strncpy (k->hbufp, k->str_start, full_length);
|
||||||
k->hbufp += k->str - k->str_start;
|
k->hbufp += full_length;
|
||||||
k->hbuflen += k->str - k->str_start;
|
k->hbuflen += full_length;
|
||||||
*k->hbufp = 0;
|
*k->hbufp = 0;
|
||||||
|
k->end_ptr = k->hbufp;
|
||||||
|
|
||||||
k->p = data->state.headerbuff;
|
k->p = data->state.headerbuff;
|
||||||
|
|
||||||
@@ -371,7 +379,14 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
!checkhttpprefix(data, data->state.headerbuff)) {
|
!checkhttpprefix(data, data->state.headerbuff)) {
|
||||||
/* this is not the beginning of a HTTP first header line */
|
/* this is not the beginning of a HTTP first header line */
|
||||||
k->header = FALSE;
|
k->header = FALSE;
|
||||||
|
if(nread)
|
||||||
|
/* since there's more, this is a partial bad header */
|
||||||
k->badheader = HEADER_PARTHEADER;
|
k->badheader = HEADER_PARTHEADER;
|
||||||
|
else {
|
||||||
|
/* this was all we read so its all a bad header */
|
||||||
|
k->badheader = HEADER_ALLBAD;
|
||||||
|
nread = rest_length;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,13 +436,13 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
|
|
||||||
/* now, only output this if the header AND body are requested:
|
/* now, only output this if the header AND body are requested:
|
||||||
*/
|
*/
|
||||||
k->writetype = CLIENTWRITE_HEADER;
|
writetype = CLIENTWRITE_HEADER;
|
||||||
if (data->set.http_include_header)
|
if (data->set.http_include_header)
|
||||||
k->writetype |= CLIENTWRITE_BODY;
|
writetype |= CLIENTWRITE_BODY;
|
||||||
|
|
||||||
headerlen = k->p - data->state.headerbuff;
|
headerlen = k->p - data->state.headerbuff;
|
||||||
|
|
||||||
result = Curl_client_write(data, k->writetype,
|
result = Curl_client_write(data, writetype,
|
||||||
data->state.headerbuff,
|
data->state.headerbuff,
|
||||||
headerlen);
|
headerlen);
|
||||||
if(result)
|
if(result)
|
||||||
@@ -445,11 +460,16 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
*/
|
*/
|
||||||
if(data->set.no_body)
|
if(data->set.no_body)
|
||||||
stop_reading = TRUE;
|
stop_reading = TRUE;
|
||||||
else if(!conn->bits.close) {
|
else {
|
||||||
/* If this is not the last request before a close, we must
|
/* If we know the expected size of this document, we set the
|
||||||
set the maximum download size to the size of the
|
maximum download size to the size of the expected
|
||||||
expected document or else, we won't know when to stop
|
document or else, we won't know when to stop reading!
|
||||||
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)
|
if(-1 != conn->size)
|
||||||
conn->maxdownload = 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,
|
/* If we have been told to fail hard on HTTP-errors,
|
||||||
here is the check for that: */
|
here is the check for that: */
|
||||||
/* serious error, go home! */
|
/* 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;
|
return CURLE_HTTP_RETURNED_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,9 +722,93 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
if(data->set.get_filetime)
|
if(data->set.get_filetime)
|
||||||
data->info.filetime = k->timeofdoc;
|
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) &&
|
else if ((k->httpcode >= 300 && k->httpcode < 400) &&
|
||||||
(data->set.http_follow_location) &&
|
|
||||||
checkprefix("Location:", k->p)) {
|
checkprefix("Location:", k->p)) {
|
||||||
|
if(data->set.http_follow_location) {
|
||||||
/* this is the URL that the server advices us to get instead */
|
/* this is the URL that the server advices us to get instead */
|
||||||
char *ptr;
|
char *ptr;
|
||||||
char *start=k->p;
|
char *start=k->p;
|
||||||
@@ -715,11 +820,17 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
white spaces after the "Location:" keyword. */
|
white spaces after the "Location:" keyword. */
|
||||||
while(*start && isspace((int)*start ))
|
while(*start && isspace((int)*start ))
|
||||||
start++;
|
start++;
|
||||||
ptr = start; /* start scanning here */
|
|
||||||
|
|
||||||
/* scan through the string to find the end */
|
/* Scan through the string from the end to find the last
|
||||||
while(*ptr && !isspace((int)*ptr))
|
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++;
|
ptr++;
|
||||||
|
|
||||||
backup = *ptr; /* store the ending letter */
|
backup = *ptr; /* store the ending letter */
|
||||||
if(ptr != start) {
|
if(ptr != start) {
|
||||||
*ptr = '\0'; /* zero terminate */
|
*ptr = '\0'; /* zero terminate */
|
||||||
@@ -727,21 +838,28 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
*ptr = backup; /* restore ending letter */
|
*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.
|
* End of header-checks. Write them to the client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
k->writetype = CLIENTWRITE_HEADER;
|
writetype = CLIENTWRITE_HEADER;
|
||||||
if (data->set.http_include_header)
|
if (data->set.http_include_header)
|
||||||
k->writetype |= CLIENTWRITE_BODY;
|
writetype |= CLIENTWRITE_BODY;
|
||||||
|
|
||||||
if(data->set.verbose)
|
if(data->set.verbose)
|
||||||
Curl_debug(data, CURLINFO_HEADER_IN,
|
Curl_debug(data, CURLINFO_HEADER_IN,
|
||||||
k->p, k->hbuflen);
|
k->p, k->hbuflen);
|
||||||
|
|
||||||
result = Curl_client_write(data, k->writetype, k->p,
|
result = Curl_client_write(data, writetype, k->p, k->hbuflen);
|
||||||
k->hbuflen);
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -774,15 +892,41 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
write a piece of the body */
|
write a piece of the body */
|
||||||
if(conn->protocol&PROT_HTTP) {
|
if(conn->protocol&PROT_HTTP) {
|
||||||
/* HTTP-only checks */
|
/* 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) {
|
if (conn->newurl) {
|
||||||
/* abort after the headers if "follow Location" is set */
|
if(conn->bits.close) {
|
||||||
infof (data, "Follow to new URL: %s\n", conn->newurl);
|
/* Abort after the headers if "follow Location" is set
|
||||||
|
and we're set to close anyway. */
|
||||||
k->keepon &= ~KEEP_READ;
|
k->keepon &= ~KEEP_READ;
|
||||||
FD_ZERO(&k->rkeepfd);
|
FD_ZERO(&k->rkeepfd);
|
||||||
*done = TRUE;
|
*done = TRUE;
|
||||||
return CURLE_OK;
|
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 &&
|
!k->content_range &&
|
||||||
(data->set.httpreq==HTTPREQ_GET)) {
|
(data->set.httpreq==HTTPREQ_GET)) {
|
||||||
/* we wanted to resume a download, although the server
|
/* 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(!conn->bits.chunk && (nread || k->badheader)) {
|
||||||
/* If this is chunky transfer, it was already written */
|
/* 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
|
/* we parsed a piece of data wrongly assuming it was a header
|
||||||
and now we output it as body instead */
|
and now we output it as body instead */
|
||||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
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
|
Content-Encoding header. See Curl_readwrite_init; the
|
||||||
memset() call initializes k->content_encoding to zero.
|
memset() call initializes k->content_encoding to zero.
|
||||||
08/28/02 jhrg */
|
08/28/02 jhrg */
|
||||||
|
if(!k->ignorebody)
|
||||||
result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
|
result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
|
||||||
nread);
|
nread);
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
@@ -1186,6 +1331,7 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
|
|||||||
k->maxfd = (conn->sockfd>conn->writesockfd?
|
k->maxfd = (conn->sockfd>conn->writesockfd?
|
||||||
conn->sockfd:conn->writesockfd)+1;
|
conn->sockfd:conn->writesockfd)+1;
|
||||||
k->hbufp = data->state.headerbuff;
|
k->hbufp = data->state.headerbuff;
|
||||||
|
k->ignorebody=FALSE;
|
||||||
|
|
||||||
Curl_pgrsTime(data, TIMER_PRETRANSFER);
|
Curl_pgrsTime(data, TIMER_PRETRANSFER);
|
||||||
Curl_speedinit(data);
|
Curl_speedinit(data);
|
||||||
@@ -1355,6 +1501,10 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
|
|||||||
data->state.this_is_a_follow = FALSE; /* reset this */
|
data->state.this_is_a_follow = FALSE; /* reset this */
|
||||||
data->state.errorbuf = FALSE; /* no error has occurred */
|
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,
|
/* If there was a list of cookie files to read and we haven't done it before,
|
||||||
do it now! */
|
do it now! */
|
||||||
if(data->change.cookielist) {
|
if(data->change.cookielist) {
|
||||||
@@ -1401,6 +1551,60 @@ CURLcode Curl_posttransfer(struct SessionHandle *data)
|
|||||||
return CURLE_OK;
|
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,
|
CURLcode Curl_follow(struct SessionHandle *data,
|
||||||
char *newurl) /* this 'newurl' is the Location: string,
|
char *newurl) /* this 'newurl' is the Location: string,
|
||||||
and it must be malloc()ed before passed
|
and it must be malloc()ed before passed
|
||||||
@@ -1409,6 +1613,8 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
|||||||
/* Location: redirect */
|
/* Location: redirect */
|
||||||
char prot[16]; /* URL protocol string storage */
|
char prot[16]; /* URL protocol string storage */
|
||||||
char letter; /* used for a silly sscanf */
|
char letter; /* used for a silly sscanf */
|
||||||
|
int newlen;
|
||||||
|
char *newest;
|
||||||
|
|
||||||
if (data->set.maxredirs &&
|
if (data->set.maxredirs &&
|
||||||
(data->set.followlocation >= data->set.maxredirs)) {
|
(data->set.followlocation >= data->set.maxredirs)) {
|
||||||
@@ -1445,9 +1651,9 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
|||||||
*/
|
*/
|
||||||
char *protsep;
|
char *protsep;
|
||||||
char *pathsep;
|
char *pathsep;
|
||||||
char *newest;
|
|
||||||
|
|
||||||
char *useurl = newurl;
|
char *useurl = newurl;
|
||||||
|
int urllen;
|
||||||
|
|
||||||
/* we must make our own copy of the URL to play with, as it may
|
/* we must make our own copy of the URL to play with, as it may
|
||||||
point to read-only data */
|
point to read-only data */
|
||||||
@@ -1520,42 +1726,79 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
|||||||
*pathsep=0;
|
*pathsep=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
newest=(char *)malloc( strlen(url_clone) +
|
/* If the new part contains a space, this is a mighty stupid redirect
|
||||||
1 + /* possible slash */
|
but we still make an effort to do "right". To the left of a '?'
|
||||||
strlen(useurl) + 1/* zero byte */);
|
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)
|
if(!newest)
|
||||||
return CURLE_OUT_OF_MEMORY; /* go out from this */
|
return CURLE_OUT_OF_MEMORY; /* go out from this */
|
||||||
|
|
||||||
sprintf(newest, "%s%s%s", url_clone,
|
/* copy over the root url part */
|
||||||
(('/' == useurl[0]) || (protsep && !*protsep))?"":"/",
|
memcpy(newest, url_clone, urllen);
|
||||||
useurl);
|
|
||||||
|
/* 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(newurl); /* newurl is the allocated pointer */
|
||||||
free(url_clone);
|
free(url_clone);
|
||||||
newurl = newest;
|
newurl = newest;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
/* This is an absolute URL, don't allow the custom port number */
|
/* This is an absolute URL, don't allow the custom port number */
|
||||||
data->state.allow_port = FALSE;
|
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)
|
if(data->change.url_alloc)
|
||||||
free(data->change.url);
|
free(data->change.url);
|
||||||
else
|
else
|
||||||
data->change.url_alloc = TRUE; /* the URL is allocated */
|
data->change.url_alloc = TRUE; /* the URL is allocated */
|
||||||
|
|
||||||
/* TBD: set the URL with curl_setopt() */
|
|
||||||
data->change.url = newurl;
|
data->change.url = newurl;
|
||||||
newurl = NULL; /* don't free! */
|
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.
|
* 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) {
|
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 300: /* Multiple Choices */
|
||||||
case 306: /* Not used */
|
case 306: /* Not used */
|
||||||
case 307: /* Temporary Redirect */
|
case 307: /* Temporary Redirect */
|
||||||
@@ -1653,9 +1896,29 @@ CURLcode Curl_perform(struct SessionHandle *data)
|
|||||||
* performed after this do-while loop.
|
* performed after this do-while loop.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
do {
|
||||||
|
int urlchanged = FALSE;
|
||||||
do {
|
do {
|
||||||
Curl_pgrsTime(data, TIMER_STARTSINGLE);
|
Curl_pgrsTime(data, TIMER_STARTSINGLE);
|
||||||
|
data->change.url_changed = FALSE;
|
||||||
res = Curl_connect(data, &conn);
|
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) {
|
if(res == CURLE_OK) {
|
||||||
res = Curl_do(&conn);
|
res = Curl_do(&conn);
|
||||||
|
|
||||||
|
257
lib/url.c
257
lib/url.c
@@ -45,7 +45,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -107,6 +106,8 @@
|
|||||||
#include "strtok.h"
|
#include "strtok.h"
|
||||||
#include "share.h"
|
#include "share.h"
|
||||||
#include "content_encoding.h"
|
#include "content_encoding.h"
|
||||||
|
#include "http_digest.h"
|
||||||
|
#include "http_negotiate.h"
|
||||||
|
|
||||||
/* And now for the protocols */
|
/* And now for the protocols */
|
||||||
#include "ftp.h"
|
#include "ftp.h"
|
||||||
@@ -133,7 +134,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -165,6 +166,11 @@ RETSIGTYPE alarmfunc(int signal)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void Curl_safefree(void *ptr)
|
||||||
|
{
|
||||||
|
if(ptr)
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the internal function curl_easy_cleanup() calls. This should
|
* 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 */
|
if(data->change.cookielist) /* clean up list if any */
|
||||||
curl_slist_free_all(data->change.cookielist);
|
curl_slist_free_all(data->change.cookielist);
|
||||||
|
|
||||||
if(data->state.auth_host)
|
Curl_safefree(data->state.auth_host);
|
||||||
free(data->state.auth_host);
|
Curl_safefree(data->state.scratch);
|
||||||
|
|
||||||
if(data->state.scratch)
|
|
||||||
free(data->state.scratch);
|
|
||||||
|
|
||||||
if(data->change.proxy_alloc)
|
if(data->change.proxy_alloc)
|
||||||
free(data->change.proxy);
|
free(data->change.proxy);
|
||||||
@@ -207,8 +210,7 @@ CURLcode Curl_close(struct SessionHandle *data)
|
|||||||
if(data->change.url_alloc)
|
if(data->change.url_alloc)
|
||||||
free(data->change.url);
|
free(data->change.url);
|
||||||
|
|
||||||
if(data->state.headerbuff)
|
Curl_safefree(data->state.headerbuff);
|
||||||
free(data->state.headerbuff);
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_HTTP
|
#ifndef CURL_DISABLE_HTTP
|
||||||
if(data->set.cookiejar) {
|
if(data->set.cookiejar) {
|
||||||
@@ -223,8 +225,9 @@ CURLcode Curl_close(struct SessionHandle *data)
|
|||||||
/* free the connection cache */
|
/* free the connection cache */
|
||||||
free(data->state.connects);
|
free(data->state.connects);
|
||||||
|
|
||||||
if(data->info.contenttype)
|
Curl_safefree(data->info.contenttype);
|
||||||
free(data->info.contenttype);
|
|
||||||
|
Curl_digest_cleanup(data);
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@@ -719,6 +722,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
|||||||
}
|
}
|
||||||
data->set.set_url = va_arg(param, char *);
|
data->set.set_url = va_arg(param, char *);
|
||||||
data->change.url = data->set.set_url;
|
data->change.url = data->set.set_url;
|
||||||
|
data->change.url_changed = TRUE;
|
||||||
break;
|
break;
|
||||||
case CURLOPT_PORT:
|
case CURLOPT_PORT:
|
||||||
/*
|
/*
|
||||||
@@ -838,6 +842,26 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
|||||||
data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
|
data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
|
||||||
break;
|
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:
|
case CURLOPT_USERPWD:
|
||||||
/*
|
/*
|
||||||
* user:password to use in the operation
|
* 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);
|
data->set.ssl.verifyhost = va_arg(param, long);
|
||||||
break;
|
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:
|
case CURLOPT_CAINFO:
|
||||||
/*
|
/*
|
||||||
* Set CA info for SSL connection. Specify file name of the CA certificate
|
* Set CA info for SSL connection. Specify file name of the CA certificate
|
||||||
@@ -1196,14 +1232,9 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
|||||||
/* This is set if protocol-specific cleanups should be made */
|
/* This is set if protocol-specific cleanups should be made */
|
||||||
conn->curl_disconnect(conn);
|
conn->curl_disconnect(conn);
|
||||||
|
|
||||||
if(conn->proto.generic)
|
Curl_safefree(conn->proto.generic);
|
||||||
free(conn->proto.generic);
|
Curl_safefree(conn->newurl);
|
||||||
|
Curl_safefree(conn->path); /* the URL path part */
|
||||||
if(conn->newurl)
|
|
||||||
free(conn->newurl);
|
|
||||||
|
|
||||||
if(conn->path) /* the URL path part */
|
|
||||||
free(conn->path);
|
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
Curl_SSL_Close(conn);
|
Curl_SSL_Close(conn);
|
||||||
@@ -1215,27 +1246,20 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
|||||||
if(-1 != conn->firstsocket)
|
if(-1 != conn->firstsocket)
|
||||||
sclose(conn->firstsocket);
|
sclose(conn->firstsocket);
|
||||||
|
|
||||||
if(conn->allocptr.proxyuserpwd)
|
Curl_safefree(conn->user);
|
||||||
free(conn->allocptr.proxyuserpwd);
|
Curl_safefree(conn->passwd);
|
||||||
if(conn->allocptr.uagent)
|
Curl_safefree(conn->proxyuser);
|
||||||
free(conn->allocptr.uagent);
|
Curl_safefree(conn->proxypasswd);
|
||||||
if(conn->allocptr.userpwd)
|
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||||
free(conn->allocptr.userpwd);
|
Curl_safefree(conn->allocptr.uagent);
|
||||||
if(conn->allocptr.accept_encoding)
|
Curl_safefree(conn->allocptr.userpwd);
|
||||||
free(conn->allocptr.accept_encoding);
|
Curl_safefree(conn->allocptr.accept_encoding);
|
||||||
if(conn->allocptr.rangeline)
|
Curl_safefree(conn->allocptr.rangeline);
|
||||||
free(conn->allocptr.rangeline);
|
Curl_safefree(conn->allocptr.ref);
|
||||||
if(conn->allocptr.ref)
|
Curl_safefree(conn->allocptr.cookie);
|
||||||
free(conn->allocptr.ref);
|
Curl_safefree(conn->allocptr.host);
|
||||||
if(conn->allocptr.cookie)
|
Curl_safefree(conn->allocptr.cookiehost);
|
||||||
free(conn->allocptr.cookie);
|
Curl_safefree(conn->proxyhost);
|
||||||
if(conn->allocptr.host)
|
|
||||||
free(conn->allocptr.host);
|
|
||||||
if(conn->allocptr.cookiehost)
|
|
||||||
free(conn->allocptr.cookiehost);
|
|
||||||
|
|
||||||
if(conn->proxyhost)
|
|
||||||
free(conn->proxyhost);
|
|
||||||
|
|
||||||
Curl_free_ssl_config(&conn->ssl_config);
|
Curl_free_ssl_config(&conn->ssl_config);
|
||||||
|
|
||||||
@@ -1318,11 +1342,13 @@ ConnectionExists(struct SessionHandle *data,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(needle->protocol & PROT_FTP) {
|
if((needle->protocol & PROT_FTP) ||
|
||||||
/* This is FTP, verify that we're using the same name and
|
((needle->protocol & PROT_HTTP) &&
|
||||||
password as well */
|
(needle->data->state.authwant==CURLAUTH_NTLM))) {
|
||||||
if(!strequal(needle->data->state.user, check->proto.ftp->user) ||
|
/* This is FTP or HTTP+NTLM, verify that we're using the same name
|
||||||
!strequal(needle->data->state.passwd, check->proto.ftp->passwd)) {
|
and password as well */
|
||||||
|
if(!strequal(needle->user, check->user) ||
|
||||||
|
!strequal(needle->passwd, check->passwd)) {
|
||||||
/* one of them was different */
|
/* one of them was different */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1535,7 +1561,7 @@ static int handleSock5Proxy(
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((socksreq[0] != 5) || /* version */
|
if ((socksreq[0] != 1) || /* version */
|
||||||
(socksreq[1] != 0)) { /* status */
|
(socksreq[1] != 0)) { /* status */
|
||||||
failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
|
failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
|
||||||
socksreq[0], socksreq[1]);
|
socksreq[0], socksreq[1]);
|
||||||
@@ -1678,8 +1704,8 @@ static CURLcode ConnectPlease(struct connectdata *conn,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
|
if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
|
||||||
return handleSock5Proxy(conn->data->state.proxyuser,
|
return handleSock5Proxy(conn->proxyuser,
|
||||||
conn->data->state.proxypasswd,
|
conn->proxypasswd,
|
||||||
conn,
|
conn,
|
||||||
conn->firstsocket) ?
|
conn->firstsocket) ?
|
||||||
CURLE_COULDNT_CONNECT : CURLE_OK;
|
CURLE_COULDNT_CONNECT : CURLE_OK;
|
||||||
@@ -1803,6 +1829,11 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
unsigned int prev_alarm=0;
|
unsigned int prev_alarm=0;
|
||||||
#endif
|
#endif
|
||||||
char endbracket;
|
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
|
#ifdef HAVE_SIGACTION
|
||||||
struct sigaction keep_sigact; /* store the old struct here */
|
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
|
* Take care of proxy authentication stuff
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
if(conn->bits.proxy_user_passwd) {
|
if(conn->bits.proxy_user_passwd) {
|
||||||
data->state.proxyuser[0] =0;
|
char proxyuser[MAX_CURL_USER_LENGTH]="";
|
||||||
data->state.proxypasswd[0]=0;
|
char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
|
||||||
|
|
||||||
if(*data->set.proxyuserpwd != ':') {
|
if(*data->set.proxyuserpwd != ':') {
|
||||||
/* the name is given, get user+password */
|
/* the name is given, get user+password */
|
||||||
sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]",
|
sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]",
|
||||||
data->state.proxyuser, data->state.proxypasswd);
|
proxyuser, proxypasswd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* no name given, get the password only */
|
/* 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 */
|
/* check for password, if no ask for one */
|
||||||
if( !data->state.proxypasswd[0] ) {
|
if( !proxypasswd[0] ) {
|
||||||
if(data->set.fpasswd( data->set.passwd_client,
|
if(data->set.fpasswd( data->set.passwd_client,
|
||||||
"proxy password:",
|
"proxy password:",
|
||||||
data->state.proxypasswd,
|
proxypasswd,
|
||||||
sizeof(data->state.proxypasswd))) {
|
sizeof(proxypasswd))) {
|
||||||
failf(data, "Bad password from password callback");
|
failf(data, "Bad password from password callback");
|
||||||
return CURLE_BAD_PASSWORD_ENTERED;
|
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->ppath = conn->path;
|
||||||
conn->hostname = conn->name;
|
conn->hostname = conn->name;
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Detect what (if any) proxy to use
|
* Detect what (if any) proxy to use
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
@@ -2149,6 +2186,45 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
|
|
||||||
if(proxy && *proxy) {
|
if(proxy && *proxy) {
|
||||||
/* we have a proxy here to set */
|
/* 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 = proxy;
|
||||||
data->change.proxy_alloc=TRUE; /* this needs to be freed later */
|
data->change.proxy_alloc=TRUE; /* this needs to be freed later */
|
||||||
conn->bits.httpproxy = TRUE;
|
conn->bits.httpproxy = TRUE;
|
||||||
@@ -2526,8 +2602,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
*
|
*
|
||||||
* Outputs: (almost :- all currently undefined)
|
* Outputs: (almost :- all currently undefined)
|
||||||
* conn->bits.user_passwd - non-zero if non-default passwords exist
|
* conn->bits.user_passwd - non-zero if non-default passwords exist
|
||||||
* conn->state.user - non-zero length if defined
|
* conn->user - non-zero length if defined
|
||||||
* conn->state.passwd - ditto
|
* conn->passwd - ditto
|
||||||
* conn->hostname - remove user name and password
|
* 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.
|
* We need somewhere to put the embedded details, so do that first.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
data->state.user[0] =0; /* to make everything well-defined */
|
user[0] =0; /* to make everything well-defined */
|
||||||
data->state.passwd[0]=0;
|
passwd[0]=0;
|
||||||
|
|
||||||
if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
|
if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
|
||||||
/* This is a FTP or HTTP URL, we will now try to extract the possible
|
/* 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 != ':') {
|
if(*userpass != ':') {
|
||||||
/* the name is given, get user+password */
|
/* the name is given, get user+password */
|
||||||
sscanf(userpass, "%127[^:@]:%127[^@]",
|
sscanf(userpass, "%127[^:@]:%127[^@]",
|
||||||
data->state.user, data->state.passwd);
|
user, passwd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* no name given, get the password only */
|
/* no name given, get the password only */
|
||||||
sscanf(userpass, ":%127[^@]", data->state.passwd);
|
sscanf(userpass, ":%127[^@]", passwd);
|
||||||
|
|
||||||
if(data->state.user[0]) {
|
if(user[0]) {
|
||||||
char *newname=curl_unescape(data->state.user, 0);
|
char *newname=curl_unescape(user, 0);
|
||||||
if(strlen(newname) < sizeof(data->state.user)) {
|
if(strlen(newname) < sizeof(user)) {
|
||||||
strcpy(data->state.user, newname);
|
strcpy(user, newname);
|
||||||
}
|
}
|
||||||
/* if the new name is longer than accepted, then just use
|
/* if the new name is longer than accepted, then just use
|
||||||
the unconverted name, it'll be wrong but what the heck */
|
the unconverted name, it'll be wrong but what the heck */
|
||||||
free(newname);
|
free(newname);
|
||||||
}
|
}
|
||||||
if (data->state.passwd[0]) {
|
if (passwd[0]) {
|
||||||
/* we have a password found in the URL, decode it! */
|
/* we have a password found in the URL, decode it! */
|
||||||
char *newpasswd=curl_unescape(data->state.passwd, 0);
|
char *newpasswd=curl_unescape(passwd, 0);
|
||||||
if(strlen(newpasswd) < sizeof(data->state.passwd)) {
|
if(strlen(newpasswd) < sizeof(passwd)) {
|
||||||
strcpy(data->state.passwd, newpasswd);
|
strcpy(passwd, newpasswd);
|
||||||
}
|
}
|
||||||
free(newpasswd);
|
free(newpasswd);
|
||||||
|
|
||||||
/* we have set the password */
|
/* 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 != ':') {
|
if(*data->set.userpwd != ':') {
|
||||||
/* the name is given, get user+password */
|
/* the name is given, get user+password */
|
||||||
sscanf(data->set.userpwd, "%127[^:]:%127[^\n]",
|
sscanf(data->set.userpwd, "%127[^:]:%127[^\n]",
|
||||||
data->state.user, data->state.passwd);
|
user, passwd);
|
||||||
if(strchr(data->set.userpwd, ':'))
|
if(strchr(data->set.userpwd, ':'))
|
||||||
/* a colon means the password was given, even if blank */
|
/* a colon means the password was given, even if blank */
|
||||||
data->state.passwdgiven = TRUE;
|
passwdgiven = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* no name given, starts with a colon, get the password only */
|
/* 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) &&
|
if ((data->set.use_netrc != CURL_NETRC_IGNORED) &&
|
||||||
!data->state.passwdgiven) { /* need passwd */
|
!passwdgiven) { /* need passwd */
|
||||||
if(Curl_parsenetrc(conn->hostname,
|
if(Curl_parsenetrc(conn->hostname,
|
||||||
data->state.user,
|
user,
|
||||||
data->state.passwd)) {
|
passwd)) {
|
||||||
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
|
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
|
||||||
conn->hostname);
|
conn->hostname);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
conn->bits.user_passwd = 1; /* enable user+password */
|
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 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,
|
if(data->set.fpasswd(data->set.passwd_client,
|
||||||
"password:", data->state.passwd,
|
"password:", passwd,
|
||||||
sizeof(data->state.passwd)))
|
sizeof(passwd)))
|
||||||
return CURLE_BAD_PASSWORD_ENTERED;
|
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 our protocol needs a password and we have none, use the defaults */
|
||||||
if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) &&
|
if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) &&
|
||||||
!conn->bits.user_passwd &&
|
!conn->bits.user_passwd &&
|
||||||
!data->state.passwdgiven) {
|
!passwdgiven) {
|
||||||
|
|
||||||
strcpy(data->state.user, CURL_DEFAULT_USER);
|
strcpy(user, CURL_DEFAULT_USER);
|
||||||
strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
|
strcpy(passwd, CURL_DEFAULT_PASSWORD);
|
||||||
|
|
||||||
/* This is the default password, so DON'T set conn->bits.user_passwd */
|
/* 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
|
* Check the current list of connections to see if we can
|
||||||
* re-use an already existing one or if we have to create a
|
* re-use an already existing one or if we have to create a
|
||||||
@@ -2713,6 +2793,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
otherwise */
|
otherwise */
|
||||||
conn->maxdownload = -1; /* might have been used previously! */
|
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 */
|
free(old_conn); /* we don't need this anymore */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2817,6 +2900,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
if(conn->bits.reuse) {
|
if(conn->bits.reuse) {
|
||||||
/* re-used connection, no resolving is necessary */
|
/* re-used connection, no resolving is necessary */
|
||||||
hostaddr = NULL;
|
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) {
|
else if(!data->change.proxy || !*data->change.proxy) {
|
||||||
/* If not connecting via a proxy, extract the port from the URL, if it is
|
/* 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) {
|
if(conn->bits.proxy_user_passwd) {
|
||||||
char *authorization;
|
char *authorization;
|
||||||
snprintf(data->state.buffer, BUFSIZE, "%s:%s",
|
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),
|
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
|
||||||
&authorization) >= 0) {
|
&authorization) >= 0) {
|
||||||
if(conn->allocptr.proxyuserpwd)
|
if(conn->allocptr.proxyuserpwd)
|
||||||
@@ -3013,7 +3098,7 @@ CURLcode Curl_done(struct connectdata *conn)
|
|||||||
if(conn->connect_addr)
|
if(conn->connect_addr)
|
||||||
Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */
|
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 */
|
/* scan for DNS cache entries still marked as in use */
|
||||||
Curl_hash_apply(data->hostcache,
|
Curl_hash_apply(data->hostcache,
|
||||||
NULL, Curl_scan_cache_used);
|
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,
|
bool Curl_clone_ssl_config(struct ssl_config_data* source,
|
||||||
struct ssl_config_data* dest);
|
struct ssl_config_data* dest);
|
||||||
void Curl_free_ssl_config(struct ssl_config_data* sslc);
|
void Curl_free_ssl_config(struct ssl_config_data* sslc);
|
||||||
|
void Curl_safefree(void *ptr);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -83,7 +83,11 @@
|
|||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
#ifdef HAVE_ZLIB_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
|
#endif
|
||||||
|
|
||||||
/* Download buffer size, keep it fairly big for speed reasons */
|
/* 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 *egdsocket; /* path to file containing the EGD daemon socket */
|
||||||
char *cipher_list; /* list of ciphers to use */
|
char *cipher_list; /* list of ciphers to use */
|
||||||
long numsessions; /* SSL session id cache size */
|
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 */
|
/* 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 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
|
* HTTP unique setup
|
||||||
@@ -306,7 +342,6 @@ struct Curl_transfer_keeper {
|
|||||||
/* for the low speed checks: */
|
/* for the low speed checks: */
|
||||||
time_t timeofdoc;
|
time_t timeofdoc;
|
||||||
long bodywrites;
|
long bodywrites;
|
||||||
int writetype;
|
|
||||||
|
|
||||||
char *buf;
|
char *buf;
|
||||||
char *uploadbuf;
|
char *uploadbuf;
|
||||||
@@ -325,8 +360,9 @@ struct Curl_transfer_keeper {
|
|||||||
|
|
||||||
bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
|
bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
|
||||||
and we're uploading the last chunk */
|
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
|
* 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 *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 now; /* "current" time */
|
||||||
struct timeval created; /* creation time */
|
struct timeval created; /* creation time */
|
||||||
int firstsocket; /* the main socket to use */
|
int firstsocket; /* the main socket to use */
|
||||||
@@ -432,7 +474,7 @@ struct connectdata {
|
|||||||
struct dynamically_allocated_data {
|
struct dynamically_allocated_data {
|
||||||
char *proxyuserpwd; /* free later if not NULL! */
|
char *proxyuserpwd; /* free later if not NULL! */
|
||||||
char *uagent; /* 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 *userpwd; /* free later if not NULL! */
|
||||||
char *rangeline; /* free later if not NULL! */
|
char *rangeline; /* free later if not NULL! */
|
||||||
char *ref; /* 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 */
|
curl_read_callback fread; /* function that reads the input */
|
||||||
void *fread_in; /* pointer to pass to the fread() above */
|
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.
|
* Struct to keep statistical and informational data.
|
||||||
@@ -501,7 +548,7 @@ struct connectdata {
|
|||||||
struct PureInfo {
|
struct PureInfo {
|
||||||
int httpcode;
|
int httpcode;
|
||||||
int httpversion;
|
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 */
|
the time was unretrievable */
|
||||||
long header_size; /* size of read header(s) in bytes */
|
long header_size; /* size of read header(s) in bytes */
|
||||||
long request_size; /* the amount of bytes sent in the request(s) */
|
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. */
|
* Session-data MUST be put in the connectdata struct and here. */
|
||||||
#define MAX_CURL_USER_LENGTH 256
|
#define MAX_CURL_USER_LENGTH 256
|
||||||
#define MAX_CURL_PASSWORD_LENGTH 256
|
#define MAX_CURL_PASSWORD_LENGTH 256
|
||||||
|
#define MAX_CURL_USER_LENGTH_TXT "255"
|
||||||
|
#define MAX_CURL_PASSWORD_LENGTH_TXT "255"
|
||||||
|
|
||||||
struct UrlState {
|
struct UrlState {
|
||||||
enum {
|
enum {
|
||||||
@@ -573,14 +622,6 @@ struct UrlState {
|
|||||||
} used_interface;
|
} used_interface;
|
||||||
|
|
||||||
/* buffers to store authentication data in, as parsed from input options */
|
/* 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 */
|
struct timeval keeps_speed; /* for the progress meter really */
|
||||||
|
|
||||||
/* 'connects' will be an allocated array with pointers. If the pointer is
|
/* 'connects' will be an allocated array with pointers. If the pointer is
|
||||||
@@ -617,6 +658,15 @@ struct UrlState {
|
|||||||
#endif
|
#endif
|
||||||
bool allow_port; /* Is set.use_port allowed to take effect or not. This
|
bool allow_port; /* Is set.use_port allowed to take effect or not. This
|
||||||
is always set TRUE when curl_easy_perform() is called. */
|
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 {
|
struct DynamicStatic {
|
||||||
char *url; /* work URL, copied from UserDefined */
|
char *url; /* work URL, copied from UserDefined */
|
||||||
bool url_alloc; /* URL string is malloc()'ed */
|
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 */
|
char *proxy; /* work proxy, copied from UserDefined */
|
||||||
bool proxy_alloc; /* http proxy string is malloc()'ed */
|
bool proxy_alloc; /* http proxy string is malloc()'ed */
|
||||||
char *referer; /* referer string */
|
char *referer; /* referer string */
|
||||||
@@ -661,6 +715,7 @@ struct UserDefined {
|
|||||||
char *set_proxy; /* proxy to use */
|
char *set_proxy; /* proxy to use */
|
||||||
long use_port; /* which port to use (when not using default) */
|
long use_port; /* which port to use (when not using default) */
|
||||||
char *userpwd; /* <user:password>, if used */
|
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
|
char *set_range; /* range, if used. See README for detailed specification
|
||||||
on this syntax. */
|
on this syntax. */
|
||||||
long followlocation; /* as in HTTP Location: */
|
long followlocation; /* as in HTTP Location: */
|
||||||
|
@@ -114,6 +114,10 @@ char *curl_version(void)
|
|||||||
sprintf(ptr, " zlib/%s", zlibVersion());
|
sprintf(ptr, " zlib/%s", zlibVersion());
|
||||||
ptr += strlen(ptr);
|
ptr += strlen(ptr);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef GSSAPI
|
||||||
|
sprintf(ptr, " GSS");
|
||||||
|
ptr += strlen(ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
@@ -168,9 +172,16 @@ static curl_version_info_data version_info = {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
| CURL_VERSION_SSL
|
| CURL_VERSION_SSL
|
||||||
|
| CURL_VERSION_NTLM /* since this requires OpenSSL */
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
| CURL_VERSION_LIBZ
|
| CURL_VERSION_LIBZ
|
||||||
|
#endif
|
||||||
|
#ifdef GSSAPI
|
||||||
|
| CURL_VERSION_GSSNEGOTIATE
|
||||||
|
#endif
|
||||||
|
#ifdef CURLDEBUG
|
||||||
|
| CURL_VERSION_DEBUG
|
||||||
#endif
|
#endif
|
||||||
,
|
,
|
||||||
NULL, /* ssl_version */
|
NULL, /* ssl_version */
|
||||||
|
5
maketgz
5
maketgz
@@ -134,3 +134,8 @@ echo ""
|
|||||||
ls -l $targz $bzip2 $zip
|
ls -l $targz $bzip2 $zip
|
||||||
|
|
||||||
md5sum $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
|
EXTRA_DIST = README
|
||||||
|
@@ -11,6 +11,14 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/src -I$(top_srcdir)/src
|
|||||||
|
|
||||||
bin_PROGRAMS = curl #memtest
|
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_SOURCES = memtest.c
|
||||||
#memtest_LDADD = $(top_srcdir)/lib/libcurl.la
|
#memtest_LDADD = $(top_srcdir)/lib/libcurl.la
|
||||||
|
|
||||||
@@ -24,7 +32,7 @@ BUILT_SOURCES = hugehelp.c
|
|||||||
CLEANFILES = hugehelp.c
|
CLEANFILES = hugehelp.c
|
||||||
NROFF=@NROFF@
|
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 \
|
Makefile.vc6 Makefile.b32 Makefile.m32 Makefile.riscos config.h.in \
|
||||||
macos/curl.mcp.xml.sit.hqx \
|
macos/curl.mcp.xml.sit.hqx \
|
||||||
macos/MACINSTALL.TXT \
|
macos/MACINSTALL.TXT \
|
||||||
@@ -38,4 +46,4 @@ MKHELP=$(top_srcdir)/src/mkhelp.pl
|
|||||||
# This generates the hugehelp.c file
|
# This generates the hugehelp.c file
|
||||||
hugehelp.c: $(README) $(MANPAGE) mkhelp.pl
|
hugehelp.c: $(README) $(MANPAGE) mkhelp.pl
|
||||||
rm -f hugehelp.c
|
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!
|
## Nothing more to do below this line!
|
||||||
|
|
||||||
INCLUDES = -I. -I.. -I../include
|
INCLUDES = -I. -I.. -I../include -I$(ZLIB_PATH)
|
||||||
CFLAGS = -g -O2 -DMINGW32
|
CFLAGS = -g -O2 -DMINGW32
|
||||||
ifdef SSL
|
ifdef SSL
|
||||||
CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H
|
CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H
|
||||||
@@ -41,13 +41,10 @@ else
|
|||||||
curl_DEPENDENCIES = ../lib/libcurl.a
|
curl_DEPENDENCIES = ../lib/libcurl.a
|
||||||
curl_LDADD = -L../lib -lcurl
|
curl_LDADD = -L../lib -lcurl
|
||||||
endif
|
endif
|
||||||
curl_LDADD += -lwsock32 -lws2_32 -lwinmm
|
curl_LDADD += -lwsock32 -lws2_32 -lwinmm -L$(ZLIB_PATH) -lz
|
||||||
ifdef SSL
|
ifdef SSL
|
||||||
curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32
|
curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32
|
||||||
endif
|
endif
|
||||||
ifdef ZLIB
|
|
||||||
curl_LDADD += -L$(ZLIB_PATH) -lz
|
|
||||||
endif
|
|
||||||
|
|
||||||
PROGRAMS = $(curl_PROGRAMS)
|
PROGRAMS = $(curl_PROGRAMS)
|
||||||
SOURCES = $(curl_SOURCES)
|
SOURCES = $(curl_SOURCES)
|
||||||
|
@@ -101,3 +101,5 @@ clean:
|
|||||||
distrib: clean
|
distrib: clean
|
||||||
-@erase $(PROGRAM_NAME)
|
-@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 */
|
/* Define if you have the <sys/poll.h> header file */
|
||||||
#undef HAVE_SYS_POLL_H
|
#undef HAVE_SYS_POLL_H
|
||||||
|
|
||||||
/* Define if you have the `setvbuf' function. */
|
|
||||||
#undef HAVE_SETVBUF
|
|
||||||
|
|
||||||
/* Define if you have the `poll' function. */
|
/* Define if you have the `poll' function. */
|
||||||
#undef HAVE_POLL
|
#undef HAVE_POLL
|
||||||
|
|
||||||
/* Define if you can write to argc[] strings */
|
/* Define if you can write to argc[] strings */
|
||||||
#undef HAVE_WRITABLE_ARGV
|
#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>
|
#include <winsock.h>
|
||||||
#endif
|
#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"
|
#include "version.h"
|
||||||
|
|
||||||
#ifdef HAVE_IO_H /* typical win32 habit */
|
#ifdef HAVE_IO_H /* typical win32 habit */
|
||||||
@@ -78,13 +91,30 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
/* this is low-level hard-hacking memory leak tracking shit */
|
/* 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"
|
#include "../lib/memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_MAXREDIRS 50L
|
#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 __cplusplus /* (rabe) */
|
||||||
#ifndef typedef_bool
|
#ifndef typedef_bool
|
||||||
typedef char bool;
|
typedef char bool;
|
||||||
@@ -314,7 +344,8 @@ static void helpf(const char *fmt, ...)
|
|||||||
vfprintf(stderr, fmt, ap);
|
vfprintf(stderr, fmt, ap);
|
||||||
va_end(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"
|
"Options: (H) means HTTP/HTTPS only, (F) means FTP only\n"
|
||||||
" -a/--append Append to target file when uploading (F)\n"
|
" -a/--append Append to target file when uploading (F)\n"
|
||||||
" -A/--user-agent <string> User-Agent to send to server (H)\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"
|
" -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",
|
" -B/--use-ascii Use ASCII/text transfer\n",
|
||||||
curl_version());
|
curl_version());
|
||||||
puts(" -c/--cookie-jar <file> Write all cookies to this file after operation (H)\n"
|
puts(" -c/--cookie-jar <file> Write all cookies to this file after operation (H)\n"
|
||||||
" -C/--continue-at <offset> Specify absolute resume offset\n"
|
" -C/--continue-at <offset> Specify absolute resume offset\n"
|
||||||
" -d/--data <data> HTTP POST data (H)\n"
|
" -d/--data <data> HTTP POST data (H)\n"
|
||||||
" --data-ascii <data> HTTP POST ASCII 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"
|
puts(" --disable-eprt Prevents curl from using EPRT or LPRT (F)\n"
|
||||||
" --disable-epsv Prevents curl from using EPSV (F)\n"
|
" --disable-epsv Prevents curl from using EPSV (F)\n"
|
||||||
" -D/--dump-header <file> Write the headers to this file\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"
|
" -M/--manual Display huge help text\n"
|
||||||
" -n/--netrc Must read .netrc for user name and password\n"
|
" -n/--netrc Must read .netrc for user name and password\n"
|
||||||
" --netrc-optional Use either .netrc or URL; overrides -n\n"
|
" --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"
|
puts(" -o/--output <file> Write output to <file> instead of stdout\n"
|
||||||
" -O/--remote-name Write output to a file named as the remote file\n"
|
" -O/--remote-name Write output to a file named as the remote file\n"
|
||||||
" -p/--proxytunnel Perform non-HTTP services through a HTTP proxy\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"
|
" -U/--proxy-user <user[:password]> Specify Proxy authentication\n"
|
||||||
" -v/--verbose Makes the operation more talkative\n"
|
" -v/--verbose Makes the operation more talkative\n"
|
||||||
" -V/--version Outputs version number then quits");
|
" -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"
|
puts(" -w/--write-out [format] What to output after completion\n"
|
||||||
" -x/--proxy <host[:port]> Use proxy. (Default port is 1080)\n"
|
" -x/--proxy <host[:port]> Use proxy. (Default port is 1080)\n"
|
||||||
" --random-file <file> File to use for reading random data from (SSL)\n"
|
" --random-file <file> File to use for reading random data from (SSL)\n"
|
||||||
@@ -443,6 +482,7 @@ struct Configurable {
|
|||||||
char *cookiefile; /* read from this file */
|
char *cookiefile; /* read from this file */
|
||||||
bool cookiesession; /* new session? */
|
bool cookiesession; /* new session? */
|
||||||
bool encoding; /* Accept-Encoding please */
|
bool encoding; /* Accept-Encoding please */
|
||||||
|
long authtype; /* auth bitmask */
|
||||||
bool use_resume;
|
bool use_resume;
|
||||||
bool resume_from_current;
|
bool resume_from_current;
|
||||||
bool disable_epsv;
|
bool disable_epsv;
|
||||||
@@ -536,6 +576,9 @@ struct Configurable {
|
|||||||
size_t lastrecvsize;
|
size_t lastrecvsize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* global variable to hold info about libcurl */
|
||||||
|
static curl_version_info_data *curlinfo;
|
||||||
|
|
||||||
static int parseconfig(const char *filename,
|
static int parseconfig(const char *filename,
|
||||||
struct Configurable *config);
|
struct Configurable *config);
|
||||||
static char *my_get_line(FILE *fp);
|
static char *my_get_line(FILE *fp);
|
||||||
@@ -1034,6 +1077,14 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
{"5h", "trace-ascii", TRUE},
|
{"5h", "trace-ascii", TRUE},
|
||||||
{"5i", "limit-rate", TRUE},
|
{"5i", "limit-rate", TRUE},
|
||||||
{"5j", "compressed", FALSE}, /* might take an arg someday */
|
{"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},
|
{"0", "http1.0", FALSE},
|
||||||
{"1", "tlsv1", FALSE},
|
{"1", "tlsv1", FALSE},
|
||||||
{"2", "sslv2", FALSE},
|
{"2", "sslv2", FALSE},
|
||||||
@@ -1258,6 +1309,32 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
config->encoding ^= TRUE;
|
config->encoding ^= TRUE;
|
||||||
break;
|
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! */
|
default: /* the URL! */
|
||||||
{
|
{
|
||||||
struct getout *url;
|
struct getout *url;
|
||||||
@@ -1673,7 +1750,40 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
config->conf ^= CONF_VERBOSE; /* talk a lot */
|
config->conf ^= CONF_VERBOSE; /* talk a lot */
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
|
{
|
||||||
|
const char **proto;
|
||||||
|
|
||||||
printf(CURL_ID "%s\n", curl_version());
|
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;
|
return PARAM_HELP_REQUESTED;
|
||||||
case 'w':
|
case 'w':
|
||||||
/* get the output string */
|
/* get the output string */
|
||||||
@@ -1791,7 +1901,7 @@ static int parseconfig(const char *filename,
|
|||||||
|
|
||||||
filename = filebuffer;
|
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 my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
struct OutStruct *out=(struct OutStruct *)stream;
|
struct OutStruct *out=(struct OutStruct *)stream;
|
||||||
struct Configurable *config = out->config;
|
struct Configurable *config = out->config;
|
||||||
if(out && !out->stream) {
|
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");
|
out->stream=fopen(out->filename, "wb");
|
||||||
if(!out->stream)
|
if(!out->stream)
|
||||||
return -1; /* failure */
|
return -1; /* failure */
|
||||||
if(config->nobuffer) {
|
|
||||||
/* disable output buffering */
|
|
||||||
#ifdef HAVE_SETVBUF
|
|
||||||
setvbuf(out->stream, NULL, _IONBF, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(config->recvpersecond) {
|
if(config->recvpersecond) {
|
||||||
@@ -2009,7 +2114,13 @@ int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
|
|||||||
config->lastrecvtime = now;
|
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 {
|
struct InStruct {
|
||||||
@@ -2058,11 +2169,10 @@ int my_fread(void *buffer, size_t size, size_t nmemb, void *userp)
|
|||||||
|
|
||||||
struct ProgressData {
|
struct ProgressData {
|
||||||
int calls;
|
int calls;
|
||||||
double total;
|
|
||||||
double prev;
|
double prev;
|
||||||
double point;
|
|
||||||
int width;
|
int width;
|
||||||
FILE *out; /* where to write everything to */
|
FILE *out; /* where to write everything to */
|
||||||
|
int initial_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
int myprogress (void *clientp,
|
int myprogress (void *clientp,
|
||||||
@@ -2084,22 +2194,21 @@ int myprogress (void *clientp,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
struct ProgressData *bar = (struct ProgressData *)clientp;
|
struct ProgressData *bar = (struct ProgressData *)clientp;
|
||||||
double total = dltotal + ultotal;
|
double total = dltotal + ultotal + bar->initial_size;
|
||||||
|
double point = dlnow + ulnow + bar->initial_size; /* we've come this far */
|
||||||
bar->point = dlnow + ulnow; /* we've come this far */
|
|
||||||
|
|
||||||
bar->calls++; /* simply count invokes */
|
bar->calls++; /* simply count invokes */
|
||||||
|
|
||||||
if(0 == total) {
|
if(0 == total) {
|
||||||
int prevblock = (int)bar->prev / 1024;
|
int prevblock = (int)bar->prev / 1024;
|
||||||
int thisblock = (int)bar->point / 1024;
|
int thisblock = (int)point / 1024;
|
||||||
while ( thisblock > prevblock ) {
|
while ( thisblock > prevblock ) {
|
||||||
fprintf( bar->out, "#" );
|
fprintf( bar->out, "#" );
|
||||||
prevblock++;
|
prevblock++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
frac = bar->point / total;
|
frac = point / total;
|
||||||
percent = frac * 100.0f;
|
percent = frac * 100.0f;
|
||||||
barwidth = bar->width - 7;
|
barwidth = bar->width - 7;
|
||||||
num = (int) (((double)barwidth) * frac);
|
num = (int) (((double)barwidth) * frac);
|
||||||
@@ -2112,7 +2221,7 @@ int myprogress (void *clientp,
|
|||||||
sprintf( outline, format, line, percent );
|
sprintf( outline, format, line, percent );
|
||||||
fprintf( bar->out, "\r%s", outline );
|
fprintf( bar->out, "\r%s", outline );
|
||||||
}
|
}
|
||||||
bar->prev = bar->point;
|
bar->prev = point;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2129,6 +2238,12 @@ void progressbarinit(struct ProgressData *bar,
|
|||||||
|
|
||||||
memset(bar, 0, sizeof(struct ProgressData));
|
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.
|
/* TODO: get terminal width through ansi escapes or something similar.
|
||||||
try to update width when xterm is resized... - 19990617 larsa */
|
try to update width when xterm is resized... - 19990617 larsa */
|
||||||
#ifndef __EMX__
|
#ifndef __EMX__
|
||||||
@@ -2138,7 +2253,7 @@ void progressbarinit(struct ProgressData *bar,
|
|||||||
colp = curl_getenv("COLUMNS");
|
colp = curl_getenv("COLUMNS");
|
||||||
if (colp != NULL) {
|
if (colp != NULL) {
|
||||||
bar->width = atoi(colp);
|
bar->width = atoi(colp);
|
||||||
free(colp);
|
curl_free(colp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bar->width = 79;
|
bar->width = 79;
|
||||||
@@ -2313,11 +2428,8 @@ void free_config_fields(struct Configurable *config)
|
|||||||
static void FindWin32CACert(struct Configurable *config,
|
static void FindWin32CACert(struct Configurable *config,
|
||||||
const char *bundle_file)
|
const char *bundle_file)
|
||||||
{
|
{
|
||||||
curl_version_info_data *info;
|
|
||||||
info = curl_version_info(CURLVERSION_NOW);
|
|
||||||
|
|
||||||
/* only check for cert file if "we" support SSL */
|
/* only check for cert file if "we" support SSL */
|
||||||
if(info->features & CURL_VERSION_SSL) {
|
if(curlinfo->features & CURL_VERSION_SSL) {
|
||||||
DWORD buflen;
|
DWORD buflen;
|
||||||
char *ptr = NULL;
|
char *ptr = NULL;
|
||||||
char *retval = (char *) malloc(sizeof (TCHAR) * (MAX_PATH + 1));
|
char *retval = (char *) malloc(sizeof (TCHAR) * (MAX_PATH + 1));
|
||||||
@@ -2369,15 +2481,18 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
char *env;
|
char *env;
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef CURLDEBUG
|
||||||
/* this sends all memory debug messages to a logfile named memdump */
|
/* this sends all memory debug messages to a logfile named memdump */
|
||||||
env = curl_getenv("CURL_MEMDEBUG");
|
env = curl_getenv("CURL_MEMDEBUG");
|
||||||
if(env) {
|
if(env) {
|
||||||
free(env);
|
curl_free(env);
|
||||||
curl_memdebug("memdump");
|
curl_memdebug("memdump");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* we get libcurl info right away */
|
||||||
|
curlinfo = curl_version_info(CURLVERSION_NOW);
|
||||||
|
|
||||||
errorbuffer[0]=0; /* prevent junk from being output */
|
errorbuffer[0]=0; /* prevent junk from being output */
|
||||||
|
|
||||||
main_init(); /* inits */
|
main_init(); /* inits */
|
||||||
@@ -2488,7 +2603,7 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
env = curl_getenv("CURL_CA_BUNDLE");
|
env = curl_getenv("CURL_CA_BUNDLE");
|
||||||
if(env) {
|
if(env) {
|
||||||
GetStr(&config->cacert, env);
|
GetStr(&config->cacert, env);
|
||||||
free(env);
|
curl_free(env);
|
||||||
}
|
}
|
||||||
#if defined(WIN32) && !defined(__CYGWIN32__)
|
#if defined(WIN32) && !defined(__CYGWIN32__)
|
||||||
else
|
else
|
||||||
@@ -2562,7 +2677,9 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
if(!config->globoff) {
|
if(!config->globoff) {
|
||||||
/* Unless explicitly shut off, we expand '{...}' and '[...]' expressions
|
/* Unless explicitly shut off, we expand '{...}' and '[...]' expressions
|
||||||
and return total number of URLs in pattern set */
|
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)
|
if(res != CURLE_OK)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -2576,7 +2693,7 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
separator = 1;
|
separator = 1;
|
||||||
}
|
}
|
||||||
for(i = 0;
|
for(i = 0;
|
||||||
(url = urls?next_url(urls):(i?NULL:strdup(url)));
|
(url = urls?glob_next_url(urls):(i?NULL:strdup(url)));
|
||||||
i++) {
|
i++) {
|
||||||
char *outfile;
|
char *outfile;
|
||||||
outfile = outfiles?strdup(outfiles):NULL;
|
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");
|
helpf("Remote file name has no length!\n");
|
||||||
return CURLE_WRITE_ERROR;
|
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) {
|
else if(urls) {
|
||||||
/* fill '#1' ... '#9' terms from URL pattern */
|
/* fill '#1' ... '#9' terms from URL pattern */
|
||||||
char *storefile = outfile;
|
char *storefile = outfile;
|
||||||
outfile = match_url(storefile, urls);
|
outfile = glob_match_url(storefile, urls);
|
||||||
free(storefile);
|
free(storefile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2775,11 +2902,11 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
if(!config->errors)
|
if(!config->errors)
|
||||||
config->errors = stderr;
|
config->errors = stderr;
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__CYGWIN32__)
|
#ifdef O_BINARY
|
||||||
if(!outfile && !(config->conf & CONF_GETTEXT)) {
|
if(!outfile && !(config->conf & CONF_GETTEXT)) {
|
||||||
/* We get the output to stdout and we have not got the ASCII/text flag,
|
/* We get the output to stdout and we have not got the ASCII/text flag,
|
||||||
then set stdout to be binary */
|
then set stdout to be binary */
|
||||||
setmode( 1, O_BINARY );
|
setmode( fileno(stdout), O_BINARY );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2942,6 +3069,10 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
/* disable it */
|
/* disable it */
|
||||||
curl_easy_setopt(curl, CURLOPT_FTP_USE_EPRT, FALSE);
|
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 */
|
/* new in curl 7.9.7 */
|
||||||
if(config->trace_dump) {
|
if(config->trace_dump) {
|
||||||
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
|
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||||
@@ -3076,7 +3207,6 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
@@ -3207,3 +3337,119 @@ static int create_dir_hierarchy(char *outfile)
|
|||||||
return result; /* 0 is fine, -1 is badness */
|
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
|
173
src/mkhelp.pl
173
src/mkhelp.pl
@@ -6,10 +6,10 @@
|
|||||||
# THEY DON'T FIT ME :-)
|
# THEY DON'T FIT ME :-)
|
||||||
|
|
||||||
# Get readme file as parameter:
|
# Get readme file as parameter:
|
||||||
$README = $ARGV[0];
|
my $README = $ARGV[0];
|
||||||
|
|
||||||
if($README eq "") {
|
if($README eq "") {
|
||||||
print "usage: mkreadme.pl <README>\n";
|
print "usage: mkreadme.pl [-c] <README> < manpage\n";
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,54 +20,163 @@ push @out, " / __| | | | |_) | | \n";
|
|||||||
push @out, " | (__| |_| | _ <| |___ \n";
|
push @out, " | (__| |_| | _ <| |___ \n";
|
||||||
push @out, " \\___|\\___/|_| \\_\\_____|\n";
|
push @out, " \\___|\\___/|_| \\_\\_____|\n";
|
||||||
|
|
||||||
$head=0;
|
|
||||||
loop:
|
|
||||||
while (<STDIN>) {
|
while (<STDIN>) {
|
||||||
$line = $_;
|
my $line = $_;
|
||||||
|
|
||||||
# this kind should be removed first:
|
# this should be removed:
|
||||||
$line =~ s/_//g;
|
$line =~ s/(.|_)//g;
|
||||||
|
|
||||||
# then this:
|
if($line =~ /^([ \t]*\n|curl)/i) {
|
||||||
$line =~ s/.//g;
|
# cut off headers and empty lines
|
||||||
|
$wline++; # count number of cut off lines
|
||||||
if($line =~ /^curl/i) {
|
next;
|
||||||
# cut off the page headers
|
|
||||||
$head=1;
|
|
||||||
next loop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($line =~ /^[ \t]*\n/) {
|
my $text = $line;
|
||||||
$wline++;
|
$text =~ s/^\s+//g; # cut off preceeding...
|
||||||
# we only make one empty line max
|
$text =~ s/\s+$//g; # and trailing whitespaces
|
||||||
next loop;
|
|
||||||
}
|
$tlen = length($text);
|
||||||
if($wline) {
|
|
||||||
|
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;
|
$wline=0;
|
||||||
if(!$head) {
|
|
||||||
push @out, "\n";
|
|
||||||
}
|
}
|
||||||
$head =0;
|
$olen = $tlen;
|
||||||
|
|
||||||
|
if($wline) {
|
||||||
|
# we only make one empty line max
|
||||||
|
$wline = 0;
|
||||||
|
push @out, "\n";
|
||||||
}
|
}
|
||||||
push @out, $line;
|
push @out, $line;
|
||||||
}
|
}
|
||||||
push @out, "\n"; # just an extra newline
|
push @out, "\n"; # just an extra newline
|
||||||
|
|
||||||
open(READ, "<$README") ||
|
open(READ, "<$README") ||
|
||||||
die "couldn't read the README infile";
|
die "couldn't read the README infile $README";
|
||||||
|
|
||||||
while(<READ>) {
|
while(<READ>) {
|
||||||
push @out, $_;
|
push @out, $_;
|
||||||
}
|
}
|
||||||
close(READ);
|
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
|
||||||
;
|
;
|
||||||
print "#include <stdio.h>\n";
|
if($c) {
|
||||||
print "void hugehelp(void)\n";
|
print <<HEAD
|
||||||
print "{\n";
|
#include <zlib.h>
|
||||||
print "puts (\n";
|
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
|
||||||
|
;
|
||||||
|
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;
|
$outsize=0;
|
||||||
for(@out) {
|
for(@out) {
|
||||||
@@ -82,13 +191,13 @@ for(@out) {
|
|||||||
|
|
||||||
# gcc 2.96 claims ISO C89 only is required to support 509 letter strings
|
# gcc 2.96 claims ISO C89 only is required to support 509 letter strings
|
||||||
if($outsize > 500) {
|
if($outsize > 500) {
|
||||||
# terminate and make another puts() call here
|
# terminate and make another fputs() call here
|
||||||
print ");\n puts(\n";
|
print ", stdout);\n fputs(\n";
|
||||||
$outsize=length($new)+1;
|
$outsize=length($new)+1;
|
||||||
}
|
}
|
||||||
printf("\"%s\\n\"\n", $new);
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define PATH_CHAR ";"
|
|
||||||
#define DIR_CHAR "\\"
|
#define DIR_CHAR "\\"
|
||||||
#define DOT_CHAR "_"
|
#define DOT_CHAR "_"
|
||||||
#else
|
#else
|
||||||
@@ -74,17 +73,25 @@ int fileno( FILE *stream);
|
|||||||
/* 20000318 mgs
|
/* 20000318 mgs
|
||||||
* OS/2 supports leading dots in filenames if the volume is formatted
|
* OS/2 supports leading dots in filenames if the volume is formatted
|
||||||
* with JFS or HPFS. */
|
* with JFS or HPFS. */
|
||||||
#define PATH_CHAR ";"
|
|
||||||
#define DIR_CHAR "\\"
|
#define DIR_CHAR "\\"
|
||||||
#define DOT_CHAR "."
|
#define DOT_CHAR "."
|
||||||
#else
|
#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 DIR_CHAR "/"
|
||||||
#define DOT_CHAR "."
|
#define DOT_CHAR "."
|
||||||
|
|
||||||
#endif
|
#endif /* !DJGPP */
|
||||||
#endif
|
#endif /* !__EMX__ */
|
||||||
|
#endif /* !WIN32 */
|
||||||
|
|
||||||
#ifdef __riscos__
|
#ifdef __riscos__
|
||||||
#define USE_ENVIRONMENT
|
#define USE_ENVIRONMENT
|
||||||
|
@@ -29,12 +29,18 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */
|
||||||
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
#include "urlglob.h"
|
#include "urlglob.h"
|
||||||
|
|
||||||
#ifdef MALLOCDEBUG
|
|
||||||
|
#ifdef CURLDEBUG
|
||||||
#include "../lib/memdebug.h"
|
#include "../lib/memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
char globerrormsg[80]; /* nasty global error message buffer for globbing */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GLOB_OK,
|
GLOB_OK,
|
||||||
GLOB_ERROR
|
GLOB_ERROR
|
||||||
@@ -46,12 +52,12 @@ typedef enum {
|
|||||||
* Input a full globbed string, set the forth argument to the amount of
|
* Input a full globbed string, set the forth argument to the amount of
|
||||||
* strings we get out of this. Return GlobCode.
|
* strings we get out of this. Return GlobCode.
|
||||||
*/
|
*/
|
||||||
GlobCode glob_word(URLGlob *, /* object anchor */
|
static GlobCode glob_word(URLGlob *, /* object anchor */
|
||||||
char *, /* globbed string */
|
char *, /* globbed string */
|
||||||
int, /* position */
|
int, /* position */
|
||||||
int *); /* returned number of strings */
|
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 '{'
|
/* processes a set expression with the point behind the opening '{'
|
||||||
','-separated elements are collected until the next closing '}'
|
','-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) {
|
while (1) {
|
||||||
switch (*pattern) {
|
switch (*pattern) {
|
||||||
case '\0': /* URL ended while set was still open */
|
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;
|
return GLOB_ERROR;
|
||||||
|
|
||||||
case '{':
|
case '{':
|
||||||
case '[': /* no nested expressions at this time */
|
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;
|
return GLOB_ERROR;
|
||||||
|
|
||||||
case ',':
|
case ',':
|
||||||
@@ -85,7 +93,7 @@ GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
|
|||||||
realloc(pat->content.Set.elements,
|
realloc(pat->content.Set.elements,
|
||||||
(pat->content.Set.size + 1) * sizeof(char*));
|
(pat->content.Set.size + 1) * sizeof(char*));
|
||||||
if (!pat->content.Set.elements) {
|
if (!pat->content.Set.elements) {
|
||||||
/*printf("out of memory in set pattern\n");*/
|
snprintf(globerrormsg, sizeof(globerrormsg), "out of memory");
|
||||||
return GLOB_ERROR;
|
return GLOB_ERROR;
|
||||||
}
|
}
|
||||||
pat->content.Set.elements[pat->content.Set.size] =
|
pat->content.Set.elements[pat->content.Set.size] =
|
||||||
@@ -110,12 +118,14 @@ GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ']': /* illegal closing bracket */
|
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;
|
return GLOB_ERROR;
|
||||||
|
|
||||||
case '\\': /* escaped character, skip '\' */
|
case '\\': /* escaped character, skip '\' */
|
||||||
if (*(buf+1) == '\0') { /* but no escaping of '\0'! */
|
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;
|
return GLOB_ERROR;
|
||||||
}
|
}
|
||||||
++pattern;
|
++pattern;
|
||||||
@@ -126,10 +136,11 @@ GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
|
|||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
snprintf(globerrormsg, sizeof(globerrormsg), "malformatted pattern");
|
||||||
return GLOB_ERROR;
|
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 '['
|
/* processes a range expression with the point behind the opening '['
|
||||||
- char range: e.g. "a-z]", "B-Q]"
|
- 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.min_c >= pat->content.CharRange.max_c ||
|
||||||
pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') {
|
pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') {
|
||||||
/* the pattern is not well-formed */
|
/* the pattern is not well-formed */
|
||||||
#if 0
|
snprintf(globerrormsg, sizeof(globerrormsg),
|
||||||
printf("error: illegal pattern or range specification after pos %d\n",
|
"illegal pattern or range specification after pos %d\n", pos);
|
||||||
pos);
|
|
||||||
#endif
|
|
||||||
return GLOB_ERROR;
|
return GLOB_ERROR;
|
||||||
}
|
}
|
||||||
pat->content.CharRange.ptr_c = pat->content.CharRange.min_c;
|
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.max_n) != 2 ||
|
||||||
pat->content.NumRange.min_n >= pat->content.NumRange.max_n) {
|
pat->content.NumRange.min_n >= pat->content.NumRange.max_n) {
|
||||||
/* the pattern is not well-formed */
|
/* the pattern is not well-formed */
|
||||||
#if 0
|
snprintf(globerrormsg, sizeof(globerrormsg),
|
||||||
printf("error: illegal pattern or range specification after pos %d\n",
|
"error: illegal pattern or range specification after pos %d\n",
|
||||||
pos);
|
pos);
|
||||||
#endif
|
|
||||||
return GLOB_ERROR;
|
return GLOB_ERROR;
|
||||||
}
|
}
|
||||||
if (*pattern == '0') { /* leading zero specified */
|
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 */
|
instances of this pattern */
|
||||||
}
|
}
|
||||||
pat->content.NumRange.ptr_n = pat->content.NumRange.min_n;
|
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 */
|
/* 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;
|
return GLOB_OK;
|
||||||
}
|
}
|
||||||
/*printf("error: illegal character in range specification at pos %d\n",
|
snprintf(globerrormsg, sizeof(globerrormsg),
|
||||||
pos);*/
|
"illegal character in range specification at pos %d\n", pos);
|
||||||
return GLOB_ERROR;
|
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
|
/* processes a literal string component of a URL
|
||||||
special characters '{' and '[' branch to set/range processing functions
|
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 */
|
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
|
* 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;
|
int amount;
|
||||||
char *glob_buffer=(char *)malloc(strlen(url)+1);
|
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;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
glob_expand = (URLGlob*)malloc(sizeof(URLGlob));
|
glob_expand = (URLGlob*)malloc(sizeof(URLGlob));
|
||||||
if(NULL == glob_expand) {
|
if(NULL == glob_expand) {
|
||||||
free(glob_buffer);
|
free(glob_buffer);
|
||||||
|
snprintf(globerrormsg, sizeof(globerrormsg), "out of memory");
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
glob_expand->size = 0;
|
glob_expand->size = 0;
|
||||||
@@ -291,6 +308,12 @@ int glob_url(URLGlob** glob, char* url, int *urlnum)
|
|||||||
free(glob_expand);
|
free(glob_expand);
|
||||||
glob_expand = NULL;
|
glob_expand = NULL;
|
||||||
*urlnum = 1;
|
*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;
|
*glob = glob_expand;
|
||||||
@@ -317,7 +340,7 @@ void glob_cleanup(URLGlob* glob)
|
|||||||
free(glob);
|
free(glob);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *next_url(URLGlob *glob)
|
char *glob_next_url(URLGlob *glob)
|
||||||
{
|
{
|
||||||
char *buf = glob->glob_buffer;
|
char *buf = glob->glob_buffer;
|
||||||
URLPattern *pat;
|
URLPattern *pat;
|
||||||
@@ -393,7 +416,7 @@ char *next_url(URLGlob *glob)
|
|||||||
return strdup(glob->glob_buffer);
|
return strdup(glob->glob_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *match_url(char *filename, URLGlob *glob)
|
char *glob_match_url(char *filename, URLGlob *glob)
|
||||||
{
|
{
|
||||||
char *target;
|
char *target;
|
||||||
URLPattern pat;
|
URLPattern pat;
|
||||||
|
@@ -53,9 +53,9 @@ typedef struct {
|
|||||||
char beenhere;
|
char beenhere;
|
||||||
} URLGlob;
|
} URLGlob;
|
||||||
|
|
||||||
int glob_url(URLGlob**, char*, int *);
|
int glob_url(URLGlob**, char*, int *, FILE *);
|
||||||
char* next_url(URLGlob*);
|
char* glob_next_url(URLGlob*);
|
||||||
char* match_url(char*, URLGlob *);
|
char* glob_match_url(char*, URLGlob *);
|
||||||
void glob_cleanup(URLGlob* glob);
|
void glob_cleanup(URLGlob* glob);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
#define CURL_NAME "curl"
|
#define CURL_NAME "curl"
|
||||||
#define CURL_VERSION "7.10.5"
|
#define CURL_VERSION "7.10.6"
|
||||||
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
||||||
|
20
testcurl.sh
20
testcurl.sh
@@ -106,10 +106,30 @@ fi
|
|||||||
cd curl
|
cd curl
|
||||||
|
|
||||||
echo "testcurl: update from CVS"
|
echo "testcurl: update from CVS"
|
||||||
|
|
||||||
|
cvsup() {
|
||||||
# update quietly to the latest CVS
|
# update quietly to the latest CVS
|
||||||
|
echo "testcurl: run cvs up"
|
||||||
cvs -Q up -dP 2>&1
|
cvs -Q up -dP 2>&1
|
||||||
|
|
||||||
cvsstat=$?
|
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"
|
echo "testcurl: cvs returned: $cvsstat"
|
||||||
|
|
||||||
if [ "$cvsstat" -ne "0" ]; then
|
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