Compare commits

..

75 Commits

Author SHA1 Message Date
Daniel Stenberg
13962adcb5 7.3 commit 2000-09-28 10:26:44 +00:00
Daniel Stenberg
221f1c2ca2 replaced the old base64 stuff with the new ones 2000-09-28 08:01:52 +00:00
Daniel Stenberg
0e0b72714c more configure options explained 2000-09-26 22:32:46 +00:00
Daniel Stenberg
3396d97399 a --krb4 usage example added 2000-09-26 22:31:52 +00:00
Daniel Stenberg
c4fc231934 added krb4-info 2000-09-26 22:30:23 +00:00
Daniel Stenberg
bac96e9f49 Added strlcpy() since it turns out some krb4-implementations don't include
their own, even if mine did!
2000-09-26 22:28:46 +00:00
Daniel Stenberg
00505c9247 moved the RAND_status() and RAND_screen() checks to the openssl section
added strlcpy() check in the krb4 section
2000-09-26 22:27:24 +00:00
Daniel Stenberg
60ee571bd6 CRYPTO_free() of course, it makes it run with previous openssl versions too 2000-09-26 07:03:59 +00:00
Daniel Stenberg
bdfe654aee The last week's changes 2000-09-25 22:23:17 +00:00
Daniel Stenberg
32e013eb87 -c and -t is no longer prefered 2000-09-25 22:20:02 +00:00
Daniel Stenberg
d03db1cd11 corrected curl_write() for kerberos 2000-09-25 22:16:36 +00:00
Daniel Stenberg
1dac7f4d05 Martin Hedenfalk added sec_fflush_fd() 2000-09-25 22:15:56 +00:00
Daniel Stenberg
ad01481b28 krb4 transfers get a sec_fflush_fd() to get uploads to work 2000-09-25 22:15:28 +00:00
Daniel Stenberg
28ad7dc4a1 a single cookie does not require a trailing semicolon anymore 2000-09-25 22:14:42 +00:00
Daniel Stenberg
e40f0be7e3 No longer uses Free() as that was removed from OpenSSL with 0.9.6 2000-09-25 22:04:51 +00:00
Daniel Stenberg
f353258ff6 corrected bad data re-use and buffer problems 2000-09-25 21:49:37 +00:00
Daniel Stenberg
1754d6166c Added CURLOPT_KRB4LEVEL 2000-09-21 08:54:36 +00:00
Daniel Stenberg
481871768b updated 2000-09-21 08:53:59 +00:00
Daniel Stenberg
43d75c5f3b added docs/examples
now only includes specified files in src/ as I tend to store debug-source files
in there as well!
2000-09-21 08:53:20 +00:00
Daniel Stenberg
35e901a21e Added krb4 support for libcurl 7.3 2000-09-21 08:52:08 +00:00
Daniel Stenberg
c62cc76fdb now reports "krb4 enabled" is that's so 2000-09-21 08:51:15 +00:00
Daniel Stenberg
7bac857fdd krb4 fields structs and fields added 2000-09-21 08:50:48 +00:00
Daniel Stenberg
ce406a732f krb4 support
new GetHost() usage
new base64 encoder usage
2000-09-21 08:50:05 +00:00
Daniel Stenberg
a82eb0fc6d adjusted to support krb4 2000-09-21 08:49:16 +00:00
Daniel Stenberg
6f6dfa97a8 Uses the new interface to ssend() and the base64 encoder 2000-09-21 08:48:48 +00:00
Daniel Stenberg
aa8a2fbde3 GetHost() changed function arguments 2000-09-21 08:47:48 +00:00
Daniel Stenberg
3471e2c59d krb4 support added, new GetHost() usage 2000-09-21 08:47:20 +00:00
Daniel Stenberg
37249c3a41 new interface to the base64 encoder 2000-09-21 08:46:44 +00:00
Daniel Stenberg
def69c3087 new for kerberos support 2000-09-21 08:46:14 +00:00
Daniel Stenberg
35aa363587 new libcurl example code stuff 2000-09-20 22:32:08 +00:00
Daniel Stenberg
7eafb0f325 Stephen Kick's --interface was added 2000-09-18 21:54:46 +00:00
Daniel Stenberg
c9c7fcf411 Stephen Kick's interface fixes 2000-09-18 21:54:08 +00:00
Daniel Stenberg
4dba5750d4 Stephen Kick added CURLOPT_INTERFACE 2000-09-18 21:53:21 +00:00
Daniel Stenberg
398e3f423f GetHost() now should return NULL when it fails, even for Tru64 unix 2000-09-18 21:16:27 +00:00
Daniel Stenberg
281d4cedc7 Added --disable-shared info and updated the 'make install' section. 2000-09-18 14:14:33 +00:00
Daniel Stenberg
c23f35ce2a ftp through http proxy tunnel is now implemented 2000-09-18 06:25:50 +00:00
Daniel Stenberg
0f4444e90b Added PowerPC and sparc linux 2000-09-15 14:16:50 +00:00
Daniel Stenberg
a98648bd8c Updated to be accurate with the new proxytunnel option 2000-09-15 14:16:13 +00:00
Daniel Stenberg
4ee420f23e proxy tunnel update 2000-09-15 14:15:47 +00:00
Daniel Stenberg
31dc1f4247 spell corrections, changed some wording 2000-09-15 14:15:16 +00:00
Daniel Stenberg
ec109b3540 Added curl.linuxworx.com.au as an "official" mirror 2000-09-15 13:22:27 +00:00
Daniel Stenberg
5019fe75a7 proxytunnel added 2000-09-15 13:20:34 +00:00
Daniel Stenberg
00eaf20298 bugfixed the proxytunnel 2000-09-15 12:55:38 +00:00
Daniel Stenberg
96009453e8 -p/--proxytunnel was added 2000-09-15 06:11:46 +00:00
Daniel Stenberg
0da7057591 more "anything through http proxy tunnel" fixes 2000-09-15 06:10:52 +00:00
Daniel Stenberg
23f22bd53e Added HTTPPROXYTUNNEL 2000-09-14 14:14:03 +00:00
Daniel Stenberg
86ff2c46b7 introduced 'tunnel through http proxy' for ftp 2000-09-14 14:05:01 +00:00
Daniel Stenberg
be8b2a1e30 updated the show-off list 2000-09-14 11:25:54 +00:00
Daniel Stenberg
0a2f677374 file:// fix that prevents name lookup and sets no-upload and no-download 2000-09-14 10:41:07 +00:00
Daniel Stenberg
74be53a577 C++ adjusted 2000-09-07 11:34:08 +00:00
Daniel Stenberg
5e7cd528b0 made -I (size info only) work for ftp again 2000-08-31 12:04:55 +00:00
Daniel Stenberg
60eab89f10 in unescape(), '+' is now only converted to space after the first '?' 2000-08-31 12:03:04 +00:00
Daniel Stenberg
1cedcce3e9 patched 7.2 configure to work! 2000-08-31 06:10:02 +00:00
Daniel Stenberg
61c4342736 7.2 cleanup commit 2000-08-30 11:54:57 +00:00
Daniel Stenberg
216b198494 7.2 2000-08-30 11:53:39 +00:00
Daniel Stenberg
6e3a6e79e5 7.2 commit 2000-08-30 11:50:16 +00:00
Daniel Stenberg
2cf44fb374 renamed to acinclude.m4 to get included by aclocal automatically 2000-08-30 06:09:06 +00:00
Daniel Stenberg
dab9658b3e Added Albert to the list contributors. The question is why I hadn't done
that a long time ago...!
2000-08-24 19:19:38 +00:00
Daniel Stenberg
3f9b9dfdee added acinclude.m4 2000-08-24 19:17:30 +00:00
Daniel Stenberg
76229d3da1 largefile.m4 was turned into acinclude.m4 2000-08-24 19:16:26 +00:00
Daniel Stenberg
6562caf6a2 --data-binary and family ;-) 2000-08-24 17:56:20 +00:00
Daniel Stenberg
d49eba2aed Jan Schmidt supplied an update 2000-08-24 17:55:48 +00:00
Daniel Stenberg
bb7929ec50 Inreased buffer size for the Linux gethostbyname_r() test 2000-08-24 17:12:46 +00:00
Daniel Stenberg
a1c0a5d0f2 Added CURLOPT_POSTFIELDSIZE 2000-08-24 16:27:04 +00:00
Daniel Stenberg
1be0bf56a6 new binary post details 2000-08-24 14:28:48 +00:00
Daniel Stenberg
53c2798886 moved include setup.h 2000-08-24 14:28:11 +00:00
Daniel Stenberg
7271ebf23e include config.h first 2000-08-24 14:27:51 +00:00
Daniel Stenberg
b6e18f2f66 #include "setup.h" moved first of all includes 2000-08-24 14:26:33 +00:00
Daniel Stenberg
400ca043c7 inet_ntoa_r() usage made more portable 2000-08-24 14:26:06 +00:00
Daniel Stenberg
d4ffc5ef32 removed the AC_TRY_RUN complaints 2000-08-24 13:05:24 +00:00
Daniel Stenberg
1b1f143cd6 hostname and large file support added 2000-08-24 12:33:16 +00:00
Daniel Stenberg
31b8eea041 Bjorn Reese helped me update the license section 2000-08-23 07:27:00 +00:00
Daniel Stenberg
903f4c16cc Fixed name problems, updated FAQ, -d post problem found 2000-08-23 07:25:50 +00:00
Daniel Stenberg
1998aee2a2 Albert's fixes 2000-08-23 07:25:21 +00:00
Daniel Stenberg
d4731b7050 Albert Chin-A-Young's fixes 2000-08-23 07:23:42 +00:00
66 changed files with 3778 additions and 960 deletions

203
CHANGES
View File

@@ -6,6 +6,207 @@
History of Changes
Version 7.3
Daniel (28 September 2000)
- Removed the base64_krb.[ch] files. They've now replaced the former
base64.[ch] files.
Daniel (26 September 2000)
- Updated some docs.
- I changed the OpenSSL fix to work with older versions as well. The posted
patch was only working with 0.9.6 and no older ones.
Version 7.3-pre8
Daniel (25 September 2000)
- Erdmut Pfeifer informed us that curl didn't build with OpenSSL 0.9.6 and
showed us what needed to get patched in order to make it build properly
again.
- Dirk Kruschewski found a bug in the cookie parser. I made an alternative
approach to the solution Dirk himself suggested. The bug made a cookie
header that didn't end with a trailing semicolon to not get parsed.
- I've marked -c and -t deprecated now. If you use any of them, curl will tell
you to use "-C -" or "-T -" instead. I don't think occupying two letters for
nearly identical functions is good use. Also, -T - kind of follows the curl
tradition of using - for stdin where a file name is expected.
Daniel (23 September 2000)
- Martin Hedenfalk provided the patch that finally made the krb4 ftp upload
work!
Daniel (21 September 2000)
- The kerberos code is not quite thread-safe yet. There are a few more globals
that need to be take care of. Let's get the upload working first!
Daniel (20 September 2000)
- Richard Prescott solved another name lookup buffer size problem. I took this
opportunity to rewrite the GetHost() function. With these large buffer
sizes, I think keeping them as local arrays quickly turn ugly. I now use
malloc() to get the buffer memory. Thanks to this, I now can realloc() to a
large buffer in case of demand (errno == ERANGE) in case a solution like
that would become necessary. I still want to avoid that kind of nastiness.
- Tried to compile and run curl on Linux for alpha and FreeBSD for alpha. Went
as smooth as it could.
- Added a docs/examples directory with two tiny example sources that show how
to use libcurl. I hope users will supply me with more useful examples
further on.
- Applied a patch by J<>rn Hartroth to no longer use the word 'inteface' in the
config struct in the src/main.c file since certain compilers have that word
"reservered". I figure that is some kind of C++ decease.
- Updated the curl.1 man page with --interface and --krb4.
- Modified the base64Encode() function to work like the kerberos one, so that
I could remove the use of that. There is no need for *two* base64 encoding
functions! ;-)
Version 7.3pre5
Daniel (19 September 2000)
- The kerberos4-layer source code that is much "influenced" by the original
krb4 source code, through yafc into curl, was using quite a lot of global
variables. libcurl can't work properly with globals like that why I had to
clean up almost every function in the new security.c to make them use
connection specific variables instead of the globals. I just hope I didn't
destroy anything now... :-) configure updated, version string now reflects
krb4 built-in. It almost works now. Only uploads are still being naughty.
Version 7.3pre3
Daniel (18 September 2000)
- Martin Hedenfalk supplied a major patch that introduces krb4-ftp support to
curl. Martin is the primary author of the ftp client named yafc and he did
not hesitate to help us implement this when I asked him. Many and sincere
thanks to a splendid effort. It didn't even take many hours!
- Stephen Kick supplied a big patch that introduces the --interface flag to
the curl tool and CURLOPT_INTERFACE for libcurl. It allows you to specify an
outgoing interface to use for your request. This may not work on all
platforms. This needs testing.
- Richard Prescott noticed that curl on Tru64 unix could core dumped if the
name didn't resolve properly. This was due to the GetHost() function not
returning an error even though it failed on some platforms!
Daniel (15 September 2000)
- Updated all sorts of documents in regards to the new proxytunnel support.
Version 7.3pre2
Daniel (15 September 2000)
- Kai-Uwe Rommel pointed out a problem in the httpproxytunnel stuff for ftp.
Adjusted it. Added better info message when setting up the tunnel and the
pasv message when doing the second connect.
Version 7.3pre1
Daniel (15 September 2000)
- libcurl now allows "httpproxytunnel" to an arbitrary host and port name. The
second connection on ftp needed that.
- TheArtOfHTTPScripting was corrected all over. I both type and spell really
bad at times!
Daniel (14 September 2000)
- -p/--proxytunnel was added to 'curl'. It uses the new
CURLOPT_HTTPPROXYTUNNEL libcurl option that allows "any" protocol to tunnel
through the specified http proxy. At the moment, this should work with ftp.
Daniel (13 September 2000)
- Jochen Schaeuble found that file:// didn't work as expected. Corrected this
and mailed the patch to the mailing list.
Daniel (7 September 2000)
- I changed the #define T() in curl.h since it turned out it wasn't really
a good symbol to use (when you compiled PHP with curl as a module, that
define collided with some IMAP define or something). This was posted to the
PHP bug tracker.
- I added extern "C" stuff in two header files to better allow libcurl usage
in C++ sorces. Discussions on the libcurl list with Danny Horswell lead to
this.
Version 7.2.1
Daniel (31 August 2000)
- Albert Chin-A-Young fixed the configure script *again* and now it seems to
detect Linux name resolving properly! (heard that before?)
- Troels Walsted Hansen pointed out that downloading a file containing the
letter '+' from an ftp server didn't work. It did work from HTTP though and
the reason was my lame URL decoder.
- I happened to notice that -I didn't at all work on ftp anymore. I corrected
that.
Version 7.2
Daniel (30 August 2000)
- Understanding AIX is a hard task. I believe I'll never figure out why they
solve things so differently from the other unixes. Now, I'm left with the
AIX 4.3 run-time warnings about duplicate symbols that according to this
article (http://www.geocrawler.com/archives/3/405/1999/9/0/2593428/) is a
libtool flaw. I tried the mentioned patch, although that stops the linking
completely.
So, if I select to ignore the ld warnings there are compiler warnings that
fill the screen pretty bad when curl compiles. It turns out that if I want
to '#include <arpa/inet.h>', I can get tid of the warnings by include the
following three include files before that one:
#include <net/if_dl.h>
#include <sys/mbuf.h>
#include <netinet/if_ether.h>
Now, is it really sane to add those include files before arpa/inet.h in all
the source files that include it?
Thanks to Albert Chin-A-Young at thewrittenword.com who gave me the AIX
login to try everything on.
Daniel (24 August 2000)
- Jan Schmidt supplied us a new VC6 makefile for Windows as the previous one
was not up to date but lacked several object files.
- More work on the naming.
- Albert Chin-A-Young provided a configure-check for large file support, as
some systems seem to need that for them to work. Had to change the position
for the config.h include file in every .c file in the libcurl dir...
- As suggested on the mailing list (by Troy Engel), I did use a --data-binary
option instead of the messy way I've left described below. It seems to
work. The libcurl fix remained the same as yesterday.
Daniel (23 August 2000)
- Back on the -d stripping newlines thing. The 'plain post' thing was added
when I had no thought of that one could actually post binary data with
it. Now, I have to add this functionality in a graceful manner and I think
I've managed to come up with a way: '-d @file;binary' will thus post the
file binary, exactly as its contents are. It is implemented with a new
*setopt() option (CURLOPT_POSTFIELDSIZE) to set the postfield size, since
libcurl can't strlen() the data in these cases.
- Albert Chin-A-Young made some very serious efforts and all the name
resolving problems seem to have been sorted out now on all the platforms
that previously showed them. I'll make another release now anyday because of
this.
- The FAQ was much enhanced when it comes to the licensing issues thanks to
Bjorn Reese.
Daniel (21 August 2000)
- Rick Welykochy pointed out a problem when you use -d to post and you want to
keep the newlines, as curl strips them off as a bonus before posting...
This needs to be addressed.
Version 7.1.1
Daniel (21 August 2000)
@@ -2078,7 +2279,7 @@ Version 4 (1998-03-20)
***************************************************************************
Version 3.12
Version 3.12 (14 March 1998)
Daniel Stenberg
- End-of-header tracking still lacked support for \r\n or just \n at the
end of the last header line.

15
FILES
View File

@@ -21,10 +21,13 @@ docs/Makefile.in
docs/Makefile.am
docs/TheArtOfHttpScripting
docs/*.3
docs/examples/README
docs/examples/*.c
maketgz
Makefile.in
Makefile.am
acconfig.h
acinclude.m4
aclocal.m4
config.guess
config.h.in
@@ -39,9 +42,15 @@ reconf
stamp-h.in
ltconfig
ltmain.sh
src/*.[ch]
src/*in
src/*am
src/config-win32.h
src/hugehelp.c
src/main.c
src/setup.h
src/urlglob.c
src/urlglob.h
src/version.h
src/*.in
src/*.am
src/mkhelp.pl
src/Makefile.vc6
src/*m32

15
README
View File

@@ -23,21 +23,22 @@ README
The official download mirror sites are:
Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/
Germany -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/
Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/
Germany -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/
Australia -- http://curl.linuxworx.com.au/
To download the very latest source off the CVS server do this:
cvs -d :pserver:anonymous@cvs.curl.sourceforge.net:/cvsroot/curl login
(just press enter when asked for password)
(just press enter when asked for password)
cvs -d :pserver:anonymous@cvs.curl.sourceforge.net:/cvsroot/curl co .
(now, you'll get all the latest sources downloaded into your current
directory. Note that this does not create a directory named curl or
anything)
(now, you'll get all the latest sources downloaded into your current
directory. Note that this does NOT create a directory named curl or
anything)
cvs -d :pserver:anonymous@cvs.curl.sourceforge.net:/cvsroot/curl logout
(you're off the hook!)
(you're off the hook!)

View File

@@ -27,3 +27,12 @@
/* Define if you have the gethostbyname_r() function with 6 arguments */
#undef HAVE_GETHOSTBYNAME_R_6
/* Define if you have the inet_ntoa_r function declared. */
#undef HAVE_INET_NTOA_R_DECL
/* Define if you need the _REENTRANT define for some functions */
#undef NEED_REENTRANT
/* Define if you have the Kerberos4 libraries (including -ldes) */
#undef KRB4

75
acinclude.m4 Normal file
View File

@@ -0,0 +1,75 @@
#serial 12
dnl By default, many hosts won't let programs access large files;
dnl one must use special compiler options to get large-file access to work.
dnl For more details about this brain damage please see:
dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html
dnl Written by Paul Eggert <eggert@twinsun.com>.
dnl Internal subroutine of AC_SYS_LARGEFILE.
dnl AC_SYS_LARGEFILE_TEST_INCLUDES
AC_DEFUN(AC_SYS_LARGEFILE_TEST_INCLUDES,
[[#include <sys/types.h>
int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
]])
dnl Internal subroutine of AC_SYS_LARGEFILE.
dnl AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE, CACHE-VAR, COMMENT, INCLUDES, FUNCTION-BODY)
AC_DEFUN(AC_SYS_LARGEFILE_MACRO_VALUE,
[AC_CACHE_CHECK([for $1 value needed for large files], $3,
[$3=no
AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES
$5
,
[$6],
,
[AC_TRY_COMPILE([#define $1 $2]
AC_SYS_LARGEFILE_TEST_INCLUDES
$5
,
[$6],
[$3=$2])])])
if test "[$]$3" != no; then
AC_DEFINE_UNQUOTED([$1], [$]$3, [$4])
fi])
AC_DEFUN(AC_SYS_LARGEFILE,
[AC_ARG_ENABLE(largefile,
[ --disable-largefile omit support for large files])
if test "$enable_largefile" != no; then
AC_CACHE_CHECK([for special C compiler options needed for large files],
ac_cv_sys_largefile_CC,
[ac_cv_sys_largefile_CC=no
if test "$GCC" != yes; then
# IRIX 6.2 and later do not support large files by default,
# so use the C compiler's -n32 option if that helps.
AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES, , ,
[ac_save_CC="$CC"
CC="$CC -n32"
AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES, ,
ac_cv_sys_largefile_CC=' -n32')
CC="$ac_save_CC"])
fi])
if test "$ac_cv_sys_largefile_CC" != no; then
CC="$CC$ac_cv_sys_largefile_CC"
fi
AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, 64,
ac_cv_sys_file_offset_bits,
[Number of bits in a file offset, on hosts where this is settable.])
AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, 1,
ac_cv_sys_largefile_source,
[Define to make ftello visible on some hosts (e.g. HP-UX 10.20).],
[#include <stdio.h>], [return !ftello;])
AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1,
ac_cv_sys_large_files,
[Define for large files, on AIX-style hosts.])
dnl lftp does not need ftello, and _XOPEN_SOURCE=500 makes resolv.h fail.
dnl AC_SYS_LARGEFILE_MACRO_VALUE(_XOPEN_SOURCE, 500,
dnl ac_cv_sys_xopen_source,
dnl [Define to make ftello visible on some hosts (e.g. glibc 2.1.3).],
dnl [#include <stdio.h>], [return !ftello;])
fi
])

76
aclocal.m4 vendored
View File

@@ -10,6 +10,82 @@ dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
dnl PARTICULAR PURPOSE.
#serial 12
dnl By default, many hosts won't let programs access large files;
dnl one must use special compiler options to get large-file access to work.
dnl For more details about this brain damage please see:
dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html
dnl Written by Paul Eggert <eggert@twinsun.com>.
dnl Internal subroutine of AC_SYS_LARGEFILE.
dnl AC_SYS_LARGEFILE_TEST_INCLUDES
AC_DEFUN(AC_SYS_LARGEFILE_TEST_INCLUDES,
[[#include <sys/types.h>
int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
]])
dnl Internal subroutine of AC_SYS_LARGEFILE.
dnl AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE, CACHE-VAR, COMMENT, INCLUDES, FUNCTION-BODY)
AC_DEFUN(AC_SYS_LARGEFILE_MACRO_VALUE,
[AC_CACHE_CHECK([for $1 value needed for large files], $3,
[$3=no
AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES
$5
,
[$6],
,
[AC_TRY_COMPILE([#define $1 $2]
AC_SYS_LARGEFILE_TEST_INCLUDES
$5
,
[$6],
[$3=$2])])])
if test "[$]$3" != no; then
AC_DEFINE_UNQUOTED([$1], [$]$3, [$4])
fi])
AC_DEFUN(AC_SYS_LARGEFILE,
[AC_ARG_ENABLE(largefile,
[ --disable-largefile omit support for large files])
if test "$enable_largefile" != no; then
AC_CACHE_CHECK([for special C compiler options needed for large files],
ac_cv_sys_largefile_CC,
[ac_cv_sys_largefile_CC=no
if test "$GCC" != yes; then
# IRIX 6.2 and later do not support large files by default,
# so use the C compiler's -n32 option if that helps.
AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES, , ,
[ac_save_CC="$CC"
CC="$CC -n32"
AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES, ,
ac_cv_sys_largefile_CC=' -n32')
CC="$ac_save_CC"])
fi])
if test "$ac_cv_sys_largefile_CC" != no; then
CC="$CC$ac_cv_sys_largefile_CC"
fi
AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, 64,
ac_cv_sys_file_offset_bits,
[Number of bits in a file offset, on hosts where this is settable.])
AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, 1,
ac_cv_sys_largefile_source,
[Define to make ftello visible on some hosts (e.g. HP-UX 10.20).],
[#include <stdio.h>], [return !ftello;])
AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1,
ac_cv_sys_large_files,
[Define for large files, on AIX-style hosts.])
dnl lftp does not need ftello, and _XOPEN_SOURCE=500 makes resolv.h fail.
dnl AC_SYS_LARGEFILE_MACRO_VALUE(_XOPEN_SOURCE, 500,
dnl ac_cv_sys_xopen_source,
dnl [Define to make ftello visible on some hosts (e.g. glibc 2.1.3).],
dnl [#include <stdio.h>], [return !ftello;])
fi
])
# Like AC_CONFIG_HEADER, but automatically create stamp file.
AC_DEFUN(AM_CONFIG_HEADER,

View File

@@ -43,6 +43,15 @@
/* Define if you have the gethostbyname_r() function with 6 arguments */
#undef HAVE_GETHOSTBYNAME_R_6
/* Define if you have the inet_ntoa_r function declared. */
#undef HAVE_INET_NTOA_R_DECL
/* Define if you need the _REENTRANT define for some functions */
#undef NEED_REENTRANT
/* Define if you have the Kerberos4 libraries (including -ldes) */
#undef KRB4
/* The number of bytes in a long double. */
#undef SIZEOF_LONG_DOUBLE
@@ -88,6 +97,9 @@
/* Define if you have the inet_ntoa_r function. */
#undef HAVE_INET_NTOA_R
/* Define if you have the krb_get_our_ip_for_realm function. */
#undef HAVE_KRB_GET_OUR_IP_FOR_REALM
/* Define if you have the localtime_r function. */
#undef HAVE_LOCALTIME_R
@@ -118,6 +130,9 @@
/* Define if you have the stricmp function. */
#undef HAVE_STRICMP
/* Define if you have the strlcpy function. */
#undef HAVE_STRLCPY
/* Define if you have the strstr function. */
#undef HAVE_STRSTR
@@ -139,6 +154,9 @@
/* Define if you have the <crypto.h> header file. */
#undef HAVE_CRYPTO_H
/* Define if you have the <des.h> header file. */
#undef HAVE_DES_H
/* Define if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
@@ -154,6 +172,9 @@
/* Define if you have the <io.h> header file. */
#undef HAVE_IO_H
/* Define if you have the <krb.h> header file. */
#undef HAVE_KRB_H
/* Define if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
@@ -163,6 +184,9 @@
/* Define if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define if you have the <netinet/if_ether.h> header file. */
#undef HAVE_NETINET_IF_ETHER_H
/* Define if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
@@ -247,6 +271,9 @@
/* Define if you have the nsl library (-lnsl). */
#undef HAVE_LIBNSL
/* Define if you have the resolv library (-lresolv). */
#undef HAVE_LIBRESOLV
/* Define if you have the resolve library (-lresolve). */
#undef HAVE_LIBRESOLVE
@@ -265,6 +292,15 @@
/* Version number of package */
#undef VERSION
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define to make ftello visible on some hosts (e.g. HP-UX 10.20). */
#undef _LARGEFILE_SOURCE
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Set to explicitly specify we don't want to use thread-safe functions */
#undef DISABLED_THREADSAFE

View File

@@ -2,7 +2,7 @@ dnl $Id$
dnl Process this file with autoconf to produce a configure script.
AC_INIT(lib/urldata.h)
AM_CONFIG_HEADER(config.h src/config.h)
AM_INIT_AUTOMAKE(curl,"7.1.1")
AM_INIT_AUTOMAKE(curl,"7.3")
AM_PROG_LIBTOOL
dnl
@@ -13,12 +13,17 @@ AC_CANONICAL_TARGET
dnl Checks for programs.
AC_PROG_CC
dnl Check for AIX weirdos
AC_AIX
dnl check for how to do large files
AC_SYS_LARGEFILE
dnl The install stuff has already been taken care of by the automake stuff
dnl AC_PROG_INSTALL
AC_PROG_MAKE_SET
dnl Check for AIX weirdos
AC_AIX
dnl **********************************************************************
dnl Checks for libraries.
@@ -67,6 +72,88 @@ AC_CHECK_FUNC(gethostname, , AC_CHECK_LIB(ucb, gethostname))
dnl dl lib?
AC_CHECK_FUNC(dlopen, , AC_CHECK_LIB(dl, dlopen))
dnl **********************************************************************
dnl Check for the presence of Kerberos4 libraries and headers
dnl **********************************************************************
AC_ARG_WITH(krb4-includes,
[ --with-krb4-includes[=DIR] Specify location of kerberos4 headers],[
CPPFLAGS="$CPPFLAGS -I$withval"
KRB4INC="$withval"
want_krb4=yes
])
AC_ARG_WITH(krb4-libs,
[ --with-krb4-libs[=DIR] Specify location of kerberos4 libs],[
LDFLAGS="$LDFLAGS -L$withval"
KRB4LIB="$withval"
want_krb4=yes
])
OPT_KRB4=off
AC_ARG_WITH(krb4,dnl
[ --with-krb4[=DIR] where to look for Kerberos4],[
OPT_KRB4="$withval"
if test X"$OPT_KRB4" != Xyes
then
LDFLAGS="$LDFLAGS -L$OPT_KRB4/lib"
KRB4LIB="$OPT_KRB4/lib"
CPPFLAGS="$CPPFLAGS -I$OPT_KRB4/include"
KRB4INC="$OPT_KRB4/include"
fi
want_krb4="yes"
])
AC_MSG_CHECKING([if Kerberos4 support is requested])
if test "$want_krb4" = yes
then
AC_MSG_RESULT(yes)
dnl Check for & handle argument to --with-krb4
AC_MSG_CHECKING(where to look for Kerberos4)
if test X"$OPT_KRB4" = Xyes
then
AC_MSG_RESULT([defaults])
else
AC_MSG_RESULT([libs in $KRB4LIB, headers in $KRB4INC])
fi
dnl Check for DES library
AC_CHECK_LIB(des, des_pcbc_encrypt,
[
AC_CHECK_HEADERS(des.h)
dnl resolv lib?
AC_CHECK_FUNC(res_search, , AC_CHECK_LIB(resolv, res_search))
dnl Check for the Kerberos4 library
AC_CHECK_LIB(krb, krb_net_read,
[
dnl Check for header files
AC_CHECK_HEADERS(krb.h)
dnl we found the required libraries, add to LIBS
LIBS="-lkrb -ldes $LIBS"
dnl Check for function krb_get_our_ip_for_realm
dnl this is needed for NAT networks
AC_CHECK_FUNCS(krb_get_our_ip_for_realm)
dnl add define KRB4
AC_DEFINE(KRB4)
dnl the krb4 stuff needs a strlcpy()
AC_CHECK_FUNCS(strlcpy)
])
])
else
AC_MSG_RESULT(no)
fi
dnl **********************************************************************
dnl Check for the presence of SSL libraries and headers
dnl **********************************************************************
@@ -113,6 +200,12 @@ else
fi
fi
dnl these can only exist if openssl exists
AC_CHECK_FUNCS( RAND_status \
RAND_screen )
fi
dnl **********************************************************************
@@ -161,164 +254,202 @@ then
AC_DEFINE(DISABLED_THREADSAFE, 1, \
Set to explicitly specify we don't want to use thread-safe functions)
else
dnl check for a few thread-safe functions
AC_CHECK_FUNCS( gethostbyname_r \
gethostbyaddr_r \
localtime_r \
inet_ntoa_r
)
if test "$ac_cv_func_gethostbyname_r" = "yes"; then
dnl **********************************************************************
dnl Time to make a check for gethostbyname_r
dnl If it exists, it may use one of three different interfaces
dnl **********************************************************************
AC_MSG_CHECKING(for gethostbyname_r)
if test -z "$ac_cv_gethostbyname_args"; then
AC_TRY_COMPILE(
[
dnl check for number of arguments to gethostbyname_r. it might take
dnl either 3, 5, or 6 arguments.
AC_CHECK_FUNCS(gethostbyname_r,[
AC_MSG_CHECKING(if gethostbyname_r takes 3 arguments)
AC_TRY_RUN([
#include <string.h>
#include <sys/types.h>
#include <netdb.h>],
[
#include <netdb.h>
int
main () {
struct hostent h;
struct hostent_data hdata;
char *name;
int rc;
rc = gethostbyname_r(name, &h, &hdata);],
ac_cv_gethostbyname_args=3)
fi
if test -z "$ac_cv_gethostbyname_args"; then
AC_TRY_COMPILE(
[
char *name = "localhost";
int rc;
memset(&h, 0, sizeof(struct hostent));
memset(&hdata, 0, sizeof(struct hostent_data));
rc = gethostbyname_r(name, &h, &hdata);
exit (rc != 0 ? 1 : 0); }],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GETHOSTBYNAME_R_3)
ac_cv_gethostbyname_args=3],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING(if gethostbyname_r with -D_REENTRANT takes 3 arguments)
AC_TRY_RUN([
#define _REENTRANT
#include <string.h>
#include <sys/types.h>
#include <netdb.h>],
[
#include <netdb.h>
int
main () {
struct hostent h;
struct hostent_data hdata;
char *name = "localhost";
int rc;
memset(&h, 0, sizeof(struct hostent));
memset(&hdata, 0, sizeof(struct hostent_data));
rc = gethostbyname_r(name, &h, &hdata);
exit (rc != 0 ? 1 : 0); }],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GETHOSTBYNAME_R_3)
AC_DEFINE(NEED_REENTRANT)
ac_cv_gethostbyname_args=3],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING(if gethostbyname_r takes 5 arguments)
AC_TRY_RUN([
#include <sys/types.h>
#include <netdb.h>
int
main () {
struct hostent *hp;
struct hostent h;
char *name;
char buffer[10];
int h_errno;
hp = gethostbyname_r(name, &h, buffer, 10, &h_errno);],
ac_cv_gethostbyname_args=5)
fi
if test -z "$ac_cv_gethostbyname_args"; then
AC_TRY_COMPILE(
[
char *name = "localhost";
char buffer[8192];
int h_errno;
hp = gethostbyname_r(name, &h, buffer, 8192, &h_errno);
exit (hp == NULL ? 1 : 0); }],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GETHOSTBYNAME_R_5)
ac_cv_gethostbyname_args=5],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING(if gethostbyname_r takes 6 arguments)
AC_TRY_RUN([
#include <sys/types.h>
#include <netdb.h>],
[
#include <netdb.h>
int
main () {
struct hostent h;
struct hostent *hp;
char *name;
char buf[10];
char *name = "localhost";
char buf[8192];
int rc;
int h_errno;
rc = gethostbyname_r(name, &h, buf, 8192, &hp, &h_errno);
exit (rc != 0 ? 1 : 0); }],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GETHOSTBYNAME_R_6)
ac_cv_gethostbyname_args=6],[
AC_MSG_RESULT(no)
have_missing_r_funcs="$have_missing_r_funcs gethostbyname_r"],
[ac_cv_gethostbyname_args=0])],
[ac_cv_gethostbyname_args=0])],
[ac_cv_gethostbyname_args=0])],
[ac_cv_gethostbyname_args=0])])
rc = gethostbyname_r(name, &h, buf, 10, &hp, &h_errno);
],
ac_cv_gethostbyname_args=6)
fi
if test -z "$ac_cv_gethostbyname_args"; then
AC_MSG_RESULT(no)
have_missing_r_funcs="$have_missing_r_funcs gethostbyname_r"
else
if test "$ac_cv_gethostbyname_args" = 3; then
AC_DEFINE(HAVE_GETHOSTBYNAME_R_3)
elif test "$ac_cv_gethostbyname_args" = 5; then
AC_DEFINE(HAVE_GETHOSTBYNAME_R_5)
elif test "$ac_cv_gethostbyname_args" = 6; then
AC_DEFINE(HAVE_GETHOSTBYNAME_R_6)
fi
AC_MSG_RESULT([yes, and it takes $ac_cv_gethostbyname_args arguments])
fi
dnl **********************************************************************
dnl Time to make a check for gethostbyaddr_r
dnl If it exists, it may use one of three different interfaces
dnl **********************************************************************
AC_MSG_CHECKING(for gethostbyaddr_r)
if test -z "$ac_cv_gethostbyaddr_args"; then
AC_TRY_COMPILE(
[
dnl check for number of arguments to gethostbyaddr_r. it might take
dnl either 5, 7, or 8 arguments.
AC_CHECK_FUNCS(gethostbyaddr_r,[
AC_MSG_CHECKING(if gethostbyaddr_r takes 5 arguments)
AC_TRY_COMPILE([
#include <sys/types.h>
#include <netdb.h>],
[
char * address;
int length;
int type;
struct hostent h;
struct hostent_data hdata;
int rc;
rc = gethostbyaddr_r(address, length, type, &h, &hdata);
],
ac_cv_gethostbyaddr_args=5)
fi
if test -z "$ac_cv_gethostbyaddr_args"; then
AC_TRY_COMPILE(
[
#include <netdb.h>],[
char * address;
int length;
int type;
struct hostent h;
struct hostent_data hdata;
int rc;
rc = gethostbyaddr_r(address, length, type, &h, &hdata);],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GETHOSTBYADDR_R_5)
ac_cv_gethostbyaddr_args=5],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING(if gethostbyaddr_r with -D_REENTRANT takes 5 arguments)
AC_TRY_COMPILE([
#define _REENTRANT
#include <sys/types.h>
#include <netdb.h>],
[
char * address;
int length;
int type;
struct hostent h;
char buffer[10];
int buflen;
int h_errnop;
struct hostent * hp;
hp = gethostbyaddr_r(address, length, type, &h,
buffer, buflen, &h_errnop);
],
ac_cv_gethostbyaddr_args=7)
fi
if test -z "$ac_cv_gethostbyaddr_args"; then
AC_TRY_COMPILE(
[
#include <netdb.h>],[
char * address;
int length;
int type;
struct hostent h;
struct hostent_data hdata;
int rc;
rc = gethostbyaddr_r(address, length, type, &h, &hdata);],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GETHOSTBYADDR_R_5)
AC_DEFINE(NEED_REENTRANT)
ac_cv_gethostbyaddr_args=5],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING(if gethostbyaddr_r takes 7 arguments)
AC_TRY_COMPILE([
#include <sys/types.h>
#include <netdb.h>],
[
char * address;
int length;
int type;
struct hostent h;
char buffer[10];
int buflen;
int h_errnop;
struct hostent * hp;
int rc;
#include <netdb.h>],[
char * address;
int length;
int type;
struct hostent h;
char buffer[8192];
int h_errnop;
struct hostent * hp;
rc = gethostbyaddr_r(address, length, type, &h,
buffer, buflen, &hp, &h_errnop);
],
ac_cv_gethostbyaddr_args=8)
fi
if test -z "$ac_cv_gethostbyaddr_args"; then
AC_MSG_RESULT(no)
have_missing_r_funcs="$have_missing_r_funcs gethostbyaddr_r"
else
if test "$ac_cv_gethostbyaddr_args" = 5; then
AC_DEFINE(HAVE_GETHOSTBYADDR_R_5)
elif test "$ac_cv_gethostbyaddr_args" = 7; then
AC_DEFINE(HAVE_GETHOSTBYADDR_R_7)
elif test "$ac_cv_gethostbyaddr_args" = 8; then
AC_DEFINE(HAVE_GETHOSTBYADDR_R_8)
fi
AC_MSG_RESULT([yes, and it takes $ac_cv_gethostbyaddr_args arguments])
fi
hp = gethostbyaddr_r(address, length, type, &h,
buffer, 8192, &h_errnop);],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GETHOSTBYADDR_R_7)
ac_cv_gethostbyaddr_args=7],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING(if gethostbyaddr_r takes 8 arguments)
AC_TRY_COMPILE([
#include <sys/types.h>
#include <netdb.h>],[
char * address;
int length;
int type;
struct hostent h;
char buffer[8192];
int h_errnop;
struct hostent * hp;
int rc;
fi
rc = gethostbyaddr_r(address, length, type, &h,
buffer, 8192, &hp, &h_errnop);],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GETHOSTBYADDR_R_8)
ac_cv_gethostbyaddr_args=8],[
AC_MSG_RESULT(no)
have_missing_r_funcs="$have_missing_r_funcs gethostbyaddr_r"])])])])])
dnl determine if function definition for inet_ntoa_r exists.
AC_CHECK_FUNCS(inet_ntoa_r,[
AC_MSG_CHECKING(whether inet_ntoa_r is declared)
AC_EGREP_CPP(inet_ntoa_r,[
#include <arpa/inet.h>],[
AC_DEFINE(HAVE_INET_NTOA_R_DECL)
AC_MSG_RESULT(yes)],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING(whether inet_ntoa_r with -D_REENTRANT is declared)
AC_EGREP_CPP(inet_ntoa_r,[
#define _REENTRANT
#include <arpa/inet.h>],[
AC_DEFINE(HAVE_INET_NTOA_R_DECL)
AC_DEFINE(NEED_REENTRANT)
AC_MSG_RESULT(yes)],
AC_MSG_RESULT(no))])])
dnl check for a few thread-safe functions
AC_CHECK_FUNCS(localtime_r,[
AC_MSG_CHECKING(whether localtime_r is declared)
AC_EGREP_CPP(localtime_r,[
#include <time.h>],[
AC_MSG_RESULT(yes)],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING(whether localtime_r with -D_REENTRANT is declared)
AC_EGREP_CPP(localtime_r,[
#define _REENTRANT
#include <time.h>],[
AC_DEFINE(NEED_REENTRANT)
AC_MSG_RESULT(yes)],
AC_MSG_RESULT(no))])])
fi
dnl **********************************************************************
dnl Back to "normal" configuring
dnl **********************************************************************
@@ -332,6 +463,7 @@ AC_CHECK_HEADERS( \
arpa/inet.h \
net/if.h \
netinet/in.h \
netinet/if_ether.h \
netdb.h \
sys/select.h \
sys/socket.h \
@@ -395,9 +527,7 @@ AC_CHECK_FUNCS( socket \
perror \
getpass \
closesocket \
setvbuf \
RAND_status \
RAND_screen
setvbuf
)
if test "$ac_cv_func_select" != "yes"; then
@@ -430,6 +560,3 @@ dnl perl/checklinks.pl \
dnl perl/getlinks.pl \
dnl perl/formfind.pl \
dnl perl/recursiveftpget.pl )

View File

@@ -1,4 +1,4 @@
Updated: August 17, 2000 (http://curl.haxx.se/docs/faq.shtml)
Updated: August 22, 2000 (http://curl.haxx.se/docs/faq.shtml)
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
@@ -50,9 +50,10 @@ FAQ
6. License Issues
6.1 I have a GPL program, can I use the libcurl library?
6.2 I have a closed-source program, can I use the libcurl library?
6.3 I have a program that uses LGPL libraries, can I use libcurl?
6.4 Can I modify curl/libcurl for my program and keep the changes secret?
6.5 Can you please change the curl/libcurl license to XXXX?
6.3 I have a BSD licensed program, can I use the libcurl library?
6.4 I have a program that uses LGPL libraries, can I use libcurl?
6.5 Can I modify curl/libcurl for my program and keep the changes secret?
6.6 Can you please change the curl/libcurl license to XXXX?
==============================================================================
@@ -95,6 +96,10 @@ FAQ
Curl is not a PHP tool, even though it works perfectly well when used from
or with PHP.
Curl is not a single-OS program. Curl exists, compiles, builds and runs
under a long range of operating systems, including all modern Unixes,
Windows, Amiga, BeOS, OS/2, OS X, QNX etc.
1.4 When will you make curl do XXXX ?
I love suggestions of what to change in order to make curl and libcurl
@@ -136,6 +141,7 @@ FAQ
Solaris (native cc compiler)
HPUX (native cc compiler)
SGI IRIX (native cc compiler)
SCO UNIX (native cc compiler)
When configuring curl, I specify --with-ssl. OpenSSL is installed in
/usr/local/ssl Configure reports SSL in /usr/local/ssl, but fails to find
@@ -384,20 +390,40 @@ FAQ
Curl and libcurl are released under the MPL, the Mozilla Public License. To
get a really good answer to this or other licensing questions, you should
study the MPL license and the license you are about to use and check for
clashes yourself. This is a brief summary for a few cases for which we get
questions:
clashes yourself. This is a brief summary for the cases we get the most
questions. (Parts of this section was enhanced by Bjorn Reese.)
6.1. I have a GPL program, can I use the libcurl library?
No, you can't distribute your program as a binary and you cannot
distribute the (lib)curl code with your code. GPL'd software requires all
parts of the final executable to be licensed under GPL or a license that
"does impose further restrictions". (One could argue about which license
that acutally imposes the restrictions, but that'll be left for you to
ponder about.) MPL is not compatible with GPL.
No, unfortunately you cannot distribute the (lib)curl code with your code.
According to both the Free Software Foundation and the Mozilla
Organization, MPL and GPL are not compatible, because GPL requires of
other licenses that they do "not impose any further restrictions on the
recipients' exercise of the rights granted herein" [GPL paragraph 6] (One
could argue about which license that actually imposes restrictions, but
that'll be left for you to ponder about.)
However, nothing prevents you from distributing your program separately
from curl and libcurl and request that the user gets it separately.
However, you have two alternative options:
1) Nothing prevents you from distributing your program separately from
curl and libcurl, and request that the user receives it separately.
The incompability issues between MPL and GPL only applies to the
distribution.
2) Add the following exception to your distribution (you must have the
consent of all the copyright holders of the source code in your
project in order to do this)
As a special exception, you have permission to link this program
with the curl library and distribute executables, as long as you
follow the requirements of the GNU GPL in regard to all of the
software in the executable aside from curl.
This exception must be added to your GPL covered source code files
immediately after the notification mentioned in the appendix of GPL.
The wording was originally suggested by the Free Software Foundation
in relationship with the Qt library. We have changed the wording to
apply to curl.
6.2. I have a closed-source program, can I use the libcurl library?
@@ -405,21 +431,27 @@ FAQ
library. If you end up doing changes to the library, only those changes
must be made available, not the ones to your program.
6.3. I have a program that uses LGPL libraries, can I use libcurl?
6.3. I have a BSD licensed program, can I use the libcurl library?
Yes, libcurl does not put any restrictions on the program that uses the
library. If you end up doing changes to the library, only those changes
must be made available, not the ones to your program.
6.4. I have a program that uses LGPL libraries, can I use libcurl?
Yes you can. LGPL libraries don't spread to other libraries the same way
GPL ones do.
However, when you read paragraph (3) of the LGPL license, you'll see that
anyone - at will - may at any time convert that LGPL program into GPL. And
GPL programs can't be distributed together, neither with (lib)curl source
code and not as a binary.
GPL programs can't be distributed together with MPL programs, neither with
(lib)curl source code and not as a binary.
6.4. Can I modify curl/libcurl for my program and keep the changes secret?
6.5. Can I modify curl/libcurl for my program and keep the changes secret?
No, you're not allowed to do that.
6.5. Can you please change the curl/libcurl license to XXXX?
6.6. Can you please change the curl/libcurl license to XXXX?
No. We carefully picked this license years ago and a large amount of
people have contributed with source code knowing that this is the license

View File

@@ -30,7 +30,7 @@ HTTP
- follow redirects
- custom HTTP request
- cookie get/send
- understands the netscape cookie file
- understands the netscape cookie file format
- custom headers (that can replace/remove internally generated headers)
- custom user-agent string
- custom referer string
@@ -38,6 +38,7 @@ HTTP
- proxy authentication
- time conditions
- via http-proxy
- specify interface device/port
HTTPS (*1)
- (all the HTTP features)
@@ -47,6 +48,7 @@ HTTPS (*1)
FTP
- download
- authentication
- kerberos security
- PORT or PASV
- single file size information (compare to HTTP HEAD)
- 'type=' URL support
@@ -60,6 +62,7 @@ FTP
- custom ftp commands (before and/or after the transfer)
- simple "range" support
- via http-proxy
- all operations can be tunneled through a http-proxy
TELNET
- connection negotiation

View File

@@ -21,25 +21,31 @@ PORTS
- Ultrix
- SINIX-Z v5
Alpha DEC OSF 4
Alpha Digital UNIX V3.2D-1 (rev 41)
HP-PA HP-UX 10.X 11.X
MIPS IRIX 6.2, 6.5
Power AIX 4.2, 4.3.1, 4.3.2
PowerPC Darwin 1.0
PowerPC Mac OS X
Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7
Sparc SunOS 4.1.*
i386 BeOS
i386 FreeBSD
i386 Linux 1.3, 2.0, 2.2
i386 NetBSD
i386 OS/2
i386 OpenBSD
i386 Solaris 2.7
i386 Windows 95, 98, NT
m68k AmigaOS 3
m68k OpenBSD
- Alpha DEC OSF 4
- Alpha Digital UNIX v3.2
- Alpha FreeBSD 4.1
- Alpha Linux 2.2.16
- Alpha Tru64 v5.0 5.1
- HP-PA HP-UX 9.X 10.X 11.X
- MIPS IRIX 6.2, 6.5
- Power AIX 4.2, 4.3.1, 4.3.2
- PowerPC Darwin 1.0
- PowerPC Linux
- PowerPC Mac OS X
- Sparc Linux
- Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8
- Sparc SunOS 4.1.*
- i386 BeOS
- i386 FreeBSD
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4
- i386 NetBSD
- i386 OS/2
- i386 OpenBSD
- i386 Solaris 2.7
- i386 Windows 95, 98, NT, 2000
- ia64 Linux 2.3.99
- m68k AmigaOS 3
- m68k OpenBSD
UNIX
====
@@ -95,9 +101,9 @@ UNIX
Use the executable `curl` in src/ directory.
'make install' copies the curl file to /usr/local/bin/ (or $prefix/bin
if you used the --prefix option to configure) and copies the curl.1
man page to a suitable place too.
'make install' copies the curl file to /usr/local/bin/ (or $prefix/bin if
you used the --prefix option to configure) and copies the man pages, the
lib and the include files to a suitable place too.
KNOWN PROBLEMS
@@ -119,6 +125,27 @@ UNIX
or
env Cc=cc ./configure
To force a static library compile, disable the shared library creation
by running configure like:
./configure --disable-shared
To tell the configure script to skip searching for thread-safe functions,
add an option like:
./configure --disable-thread
To build curl with kerberos4 support enabled, curl requires the krb4 libs
and headers installed. You can then use a set of options to tell
configure where those are:
--with-krb4-includes[=DIR] Specify location of kerberos4 headers
--with-krb4-libs[=DIR] Specify location of kerberos4 libs
--with-krb4[=DIR] where to look for Kerberos4
In most cases, /usr/athena is the install prefix and then it works with
./configure --with-krb4=/usr/athena
Win32
=====
@@ -245,7 +272,7 @@ MingW32/Cygwin
You'll find MingW32 and Cygwin information at:
http://www.xraylith.wisc.edu/~khan/software/gnu-win32/index.html
http://www.mingw.org
OpenLDAP
========

View File

@@ -139,9 +139,11 @@ UPLOADING
curl -T localfile -a ftp://ftp.upload.com/remotefile
NOTE: Curl does not support ftp upload through a proxy! The reason for this
is simply that proxies are seldomly configured to allow this and that no
author has supplied code that makes it possible!
Curl also supports ftp upload through a proxy, but only if the proxy is
configured to allow that kind of tunneling. If it does, you can run curl in
a fashion similar to:
curl --proxytunnel -x proxy:port -T localfile ftp.upload.com
HTTP
@@ -480,13 +482,14 @@ FTP and firewalls
connect to the client on the given (as parameters to the PORT command) IP
number and port.
The -P flag to curl allows for different options. Your machine may have
The -P flag to curl supports a few different options. Your machine may have
several IP-addresses and/or network interfaces and curl allows you to select
which of them to use. Default address can also be used:
curl -P - ftp.download.com
Download with PORT but use the IP address of our 'le0' interface:
Download with PORT but use the IP address of our 'le0' interface (this does
not work on windows):
curl -P le0 ftp.download.com
@@ -494,6 +497,16 @@ FTP and firewalls
curl -P 192.168.0.10 ftp.download.com
NETWORK INTERFACE
Get a web page from a server using a specified port for the interface:
curl --interface eth0:1 http://www.netscape.com/
or
curl --interface 192.168.1.10 http://www.netscape.com/
HTTPS
Secure HTTP requires SSL libraries to be installed and used when curl is
@@ -689,13 +702,26 @@ CUSTOM OUTPUT
curl -w 'We downloaded %{size_download} bytes\n' www.download.com
KERBEROS4 FTP TRANSFER
Curl supports kerberos4 for FTP transfers. You need the kerberos package
installed and used at curl build time for it to be used.
First, get the krb-ticket the normal way, like with the kauth tool. Then use
curl in way similar to:
curl --krb4 private ftp://krb4site.com -u username:fakepwd
There's no use for a password on the -u switch, but a blank one will make
curl ask for one and you already entered the real password to kauth.
MAILING LIST
We have an open mailing list to discuss curl, its development and things
relevant to this.
To subscribe, mail curl-request@contactor.se with "subscribe <your email
address>" in the body.
To subscribe, mail curl-request@contactor.se with "subscribe <fill in your
email address>" in the body.
To post to the list, mail curl@contactor.se.

View File

@@ -68,7 +68,7 @@ Standards
Compilers
---------
MingW32 - http://www.xraylith.wisc.edu/~khan/software/gnu-win32/index.html
MingW32 - http://www.mingw.org
gcc - http://www.gnu.org/software/gcc/gcc.html

View File

@@ -22,9 +22,11 @@ For the future
* Move non-URL related functions that are used by both the lib and the curl
application to a separate "portability lib".
* Add support for other languages than C (not important)
* Add support for other languages than C. C++ and perl comes to mind. Python?
* Improve the -K config file parser.
* Improve the -K config file parser (the parameter following the flag should
be possible to get specified *exactly* as it is done on a shell command
line).
* rtsp:// support -- "Real Time Streaming Protocol" (RFC 2326)
@@ -35,28 +37,13 @@ For the future
started in October 1999 but halted again since it proved more work than we
thought. It is still a good idea to implement though.
* HTTP Pipelining/persistant connections
- We should introduce HTTP "pipelining". Curl could be able to request for
several HTTP documents in one connect. It would be the beginning for
supporing more advanced functions in the future, like web site
mirroring. This will require that the urlget() function supports several
documents from a single HTTP server, which it doesn't today.
- When curl supports fetching several documents from the same server using
pipelining, I'd like to offer that function to the command line. Anyone has
a good idea how? The current way of specifying one URL with the output sent
to the stdout or a file gets in the way. Imagine a syntax that supports
"additional documents from the same server" in a way similar to:
curl <main URL> --more-doc <path> --more-doc <path>
where --more-doc specifies another document on the same server. Where are
the output files gonna be put and how should they be named? Should each
"--more-doc" parameter require a local file name to store the result in?
Like "--more-file" as in:
curl <URL> --more-doc <path> --more-file <file>
* Authentication: NTLM. It would be cool to support 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.
* RFC2617 compliance, "Digest Access Authentication"
A valid test page seem to exist at:
@@ -70,12 +57,6 @@ For the future
sends the password in cleartext over the network, this "Digest" method uses
a challange-response protocol which increases security quite a lot.
* Different FTP Upload Through Web Proxy
I don't know any web proxies that allow CONNECT through on port 21, but
that would be the best way to do ftp upload. All we would need to do would
be to 'CONNECT <host>:<port> HTTP/1.0\r\n\r\n' and then do business as
usual. I least I think so. It would be fun if someone tried this...
* Multiple Proxies?
Is there anyone that actually uses serial-proxies? I mean, send CONNECT to
the first proxy to connect to the second proxy to which you send CONNECT to
@@ -86,8 +67,7 @@ For the future
Ftp-kind proxy, Socks5, whatever kind of proxies are there?
* IPv6 Awareness and support
Where ever it would fit. I am not that into v6 yet to fully grasp what we
would need to do, but letting the autoconf search for v6-versions of a few
Where ever it would fit. configure search for v6-versions of a few
functions and then use them instead is of course the first thing to do...
RFC 2428 "FTP Extensions for IPv6 and NATs" will be interesting. PORT
should be replaced with EPRT for IPv6, and EPSV instead of PASV.
@@ -99,6 +79,3 @@ For the future
* Make curl capable of verifying the server's certificate when connecting
with HTTPS://.
* Kerberos-FTP

View File

@@ -1,6 +1,6 @@
Author: Daniel Stenberg <daniel@haxx.se>
Date: August 7, 2000
Version: 0.2
Date: September 15, 2000
Version: 0.3
The Art Of Scripting HTTP Requests Using Curl
=============================================
@@ -31,7 +31,7 @@ Version: 0.2
1. The HTTP Protocol
HTTP is the protocol used to fetch data from web servers. It is a very simple
protocol that is built upon TCP/IP. The protocol also allow information to
protocol that is built upon TCP/IP. The protocol also allows information to
get sent to the server from the client using a few different methods, as will
be shown here.
@@ -130,12 +130,12 @@ Version: 0.2
curl -d "birthyear=1905&press=OK" www.hotmail.com/when/junk.cgi
This kind of POST will use the Content-Type
application/x-www-form-urlencoded and is the most widly used POST kind.
application/x-www-form-urlencoded and is the most widely used POST kind.
4.3 FILE UPLOAD POST
Back in late 1995 they defined a new to post data over HTTP. It was
documented in the RFC 1867, why this method sometimes are refered to as
Back in late 1995 they defined a new way to post data over HTTP. It was
documented in the RFC 1867, why this method sometimes is refered to as
a rfc1867-posting.
This method is mainly designed to better support file uploads. A form that
@@ -165,7 +165,7 @@ Version: 0.2
<form method="POST" action="foobar.cgi">
<input type=text name="birthyear">
<input type=text name="person" value="daniel">
<input type=hidden name="person" value="daniel">
<input type=submit name="press" value="OK">
</form>
@@ -209,17 +209,18 @@ Version: 0.2
Do note that when a program is run, its parameters are possible to see when
listing the running processes of the system. Thus, other users may be able to
watch your passwords if you pass them as plain command line options.
watch your passwords if you pass them as plain command line options. There
are ways to circumvent this.
7. REFERER
A HTTP request has the ability to feature a 'referer' field, which can be
used to tell which URL that causes the client to get this particular
resource. Some programs/scripts check the referer field of requests to verify
that this wasn't arriving from an external site or unknown page. While this
is a stupid way to check something so easily forged, many scripts still do
it. Using curl, you can put anything you want in the referer-field and thus
more easily being able to fool the server into serving your request.
A HTTP request may include a 'referer' field, which can be used to tell from
which URL the client got to this particular resource. Some programs/scripts
check the referer field of requests to verify that this wasn't arriving from
an external site or an unknown page. While this is a stupid way to check
something so easily forged, many scripts still do it. Using curl, you can put
anything you want in the referer-field and thus more easily be able to fool
the server into serving your request.
Use curl to set the referer field with:
@@ -278,10 +279,10 @@ Version: 0.2
specified in a received cookie, the client sends back the cookies and their
contents to the server, unless of course they are expired.
Many applications and server use this method to connect a series of request
Many applications and servers use this method to connect a series of requests
into a single logical session. To be able to use curl in such occations, we
must be able to record and send back cookies in the way that the web
application expects them. The same way browsers deal with them.
must be able to record and send back cookies the way the web application
expects them. The same way browsers deal with them.
The simplest way to send a few cookies to the server when getting a page with
curl is to add them on the command line like:
@@ -307,15 +308,15 @@ Version: 0.2
There are a few ways to do secure HTTP transfers. The by far most common
protocol for doing this is what is generally known as HTTPS, HTTP over
SSL. SSL encrypts all the data that is send and received over the network and
SSL. SSL encrypts all the data that is sent and received over the network and
thus makes it harder for attackers to spy on sensitive information.
SSL (or TLS as the latest version of the standard is called) offers a
truckload of advanced features to allow all those encryptions and key
infrastructure mechanisms ecnrypted HTTP requires.
infrastructure mechanisms encrypted HTTP requires.
Curl supports enscrypted fetches thanks to the freely available OpenSSL
libraries. To get a pafe from a https server, simply run curl like:
Curl supports encrypted fetches thanks to the freely available OpenSSL
libraries. To get a page from a HTTPS server, simply run curl like:
curl https://that.secure.server.com

View File

@@ -2,7 +2,7 @@
.\" nroff -man curl.1
.\" Written by Daniel Stenberg
.\"
.TH curl 1 "1 August 2000" "Curl 7.0" "Curl Manual"
.TH curl 1 "26 September 2000" "Curl 7.3" "Curl Manual"
.SH NAME
curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or
HTTPS syntax.
@@ -72,6 +72,7 @@ Use ASCII transfer when getting an FTP file or LDAP info. For FTP, this can
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.
.IP "-c/--continue"
.B Deprecated. Use '-C -' instead.
Continue/Resume a previous file transfer. This instructs curl to
continue appending data on the file where it was previously left,
possibly because of a broken connection to the server. There must be
@@ -88,16 +89,26 @@ If used with uploads, the ftp server command SIZE will not be used by
curl. Upload resume is for FTP only.
HTTP resume is only possible with HTTP/1.1 or later servers.
.IP "-d/--data <data>"
(HTTP)
Sends the specified data in a POST request to the HTTP server. Note
that the data is sent exactly as specified with no extra processing.
The data is expected to be "url-encoded". This will cause curl to
pass the data to the server using the content-type
(HTTP) Sends the specified data in a POST request to the HTTP server. Note
that the data is sent exactly as specified with no extra processing (with all
newlines cut off). The data is expected to be "url-encoded". This will cause
curl to pass the data to the server using the content-type
application/x-www-form-urlencoded. Compare to -F.
If you start the data with the letter @, the rest should be a file name to
read the data from, or - if you want curl to read the data from stdin.
The contents of the file must already be url-encoded.
To post data purely binary, you should instead use the --data-binary option.
-d/--data is the same as --data-ascii.
.IP "--data-ascii <data>"
(HTTP) This is an alias for the -d/--data option.
.IP "--data-binary <data>"
(HTTP) This posts data in a similar manner as --data-ascii does, although when
using this option the entire context of the posted data is kept as-is. If you
want to post a binary file without the strip-newlines feature of the
--data-ascii option, this is for you.
.IP "-D/--dump-header <file>"
(HTTP/FTP)
Write the HTTP headers to this file. Write the FTP file info to this
@@ -162,11 +173,20 @@ prevent that header from appearing.
(HTTP)
Include the HTTP-header in the output. The HTTP-header includes things
like server-name, date of the document, HTTP-version and more...
.IP "--interface <name>"
Perform an operation using a specified interface. You can enter interface
name, IP address or host name. An example could look like:
.B "curl --interface eth0:1 http://www.netscape.com/"
.IP "-I/--head"
(HTTP/FTP)
Fetch the HTTP-header only! HTTP-servers feature the command HEAD
which this uses to get nothing but the header of a document. When used
on a FTP file, curl displays the file size only.
.IP "--krb4 <level>"
(FTP) Enable kerberos4 authentication and use. The level must be entered and
should be one of 'clear', 'safe', 'confidential' or 'private'. Should you use
a level that is not one of these, 'private' will instead be used.
.IP "-K/--config <config file>"
Specify which config file to read curl arguments from. The config
file is a text file in which command line arguments can be written
@@ -231,6 +251,12 @@ or use several variables like:
.IP "-O/--remote-name"
Write output to a local file named like the remote file we get. (Only
the file part of the remote file is used, the path is cut off.)
.IP "-p/--proxytunnel"
When an HTTP proxy is used, this option will cause non-HTTP protocols to
attempt to tunnel through the proxy instead of merely using it to do HTTP-like
operations. The tunnel approach is made with the HTTP proxy CONNECT request
and requires that the proxy allows direct connect to the remote port number
curl wants to tunnel through to.
.IP "-P/--ftpport <address>"
(FTP)
Reverses the initiator/listener roles when connecting with ftp. This
@@ -307,6 +333,7 @@ Curl mute.
.IP "-S/--show-error"
When used with -s it makes curl show error message if it fails.
.IP "-t/--upload"
.B Deprecated. Use '-T -' instead.
Transfer the stdin data to the specified file. Curl will read
everything from stdin until EOF and store with the supplied name. If
this is used on a http(s) server, the PUT command will be used.
@@ -605,6 +632,10 @@ If you do find any (or have other suggestions), mail Daniel Stenberg
- Kristian K<>hntopp <kris@koehntopp.de>
- Fred Noz <FNoz@siac.com>
- Caolan McNamara <caolan@csn.ul.ie>
- Albert Chin-A-Young <china@thewrittenword.com>
- Stephen Kick <skick@epicrealm.com>
- Martin Hedenfalk <mhe@stacken.kth.se>
- Richard Prescott
.SH WWW
http://curl.haxx.se

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file]
.\" Written by daniel@haxx.se
.\"
.TH curl_easy_init 3 "22 May 2000" "Curl 7.0" "libcurl Manual"
.TH curl_easy_init 3 "26 September 2000" "Curl 7.0" "libcurl Manual"
.SH NAME
curl_easy_init - Start a libcurl "easy" session
.SH SYNOPSIS
@@ -16,6 +16,9 @@ that you shall use as input to the other easy-functions. The init calls
intializes curl and this call MUST have a corresponding call to
.I curl_easy_cleanup
when the operation is complete.
On win32 systems, you need to init the winsock stuff manually, libcurl will
not do that for you. WSAStartup() and WSACleanup() should be used accordingly.
.SH RETURN VALUE
If this function returns NULL, something went wrong and you cannot use the
other curl functions.

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file]
.\" Written by daniel@haxx.se
.\"
.TH curl_easy_setopt 3 "16 June 2000" "Curl 7.0" "libcurl Manual"
.TH curl_easy_setopt 3 "26 September 2000" "Curl 7.3" "libcurl Manual"
.SH NAME
curl_easy_setopt - Set curl easy-session options
.SH SYNOPSIS
@@ -19,6 +19,8 @@ options are set with the
followed by a parameter. That parameter can be a long, a function pointer or
an object pointer, all depending on what the option in question expects. Read
this manual carefully as bad input values may cause libcurl to behave badly!
You can only set one option in each function call. A typical application uses
many calls in the setup phase.
The
.I "handle"
@@ -85,6 +87,12 @@ the end of the host name. The proxy string may be prefixed with
Set this long with this option to set the proxy port to use unless it is
specified in the proxy string CURLOPT_PROXY.
.TP
.B CURLOPT_HTTPPROXYTUNNEL
Set the parameter to non-zero to get the library to tunnel all non-HTTP
operations through the given HTTP proxy. Do note that there is a big
difference to use a proxy and to tunnel through it. If you don't know what
this means, you probably don't want this tunnel option. (Added in libcurl 7.3)
.TP
.B CURLOPT_VERBOSE
Set the parameter to non-zero to get the library to display a lot of verbose
information about its operations.
@@ -117,7 +125,7 @@ CURLOPT_INFILE and CURLOPT_INFILESIZE are also interesting for uploads.
A non-zero parameter tells the library to do a regular HTTP post. This is a
normal application/x-www-form-urlencoded kind, which is the most commonly used
one by HTML forms. See the CURLOPT_POSTFIELDS option for how to specify the
data to post.
data to post and CURLOPT_POSTFIELDSIZE in how to set the data size.
.TP
.B CURLOPT_FTPLISTONLY
A non-zero parameter tells the library to just list the names of an ftp
@@ -188,6 +196,13 @@ few minutes risk aborting perfectly normal operations.
Pass a char * as parameter, which should be the full data to post in a HTTP
post operation. See also the CURLOPT_POST.
.TP
.B CURLOPT_POSTFIELDSIZE
If you want to post data to the server without letting libcurl do a strlen()
to measure the data size, this option must be used. Also, when this option is
used, you can post fully binary data which otherwise is likely to fail. If
this size is set to zero, the library will use strlen() to get the data
size. (Added in libcurl 7.2)
.TP
.B CURLOPT_REFERER
Pass a pointer to a zero terminated string as parameter. It will be used to
set the referer: header in the http request sent to the remote server. This
@@ -302,6 +317,18 @@ your server supports the command first.
Pass a FILE * as parameter. This is the stream to use instead of stderr
internally when reporting errors.
.TP
.B CURLOPT_INTERFACE
Pass a char * as parameter. This set the interface name to use as outgoing
network interface. The name can be an interface name, an IP address or a host
name. (Added in libcurl 7.3)
.TP
.B CURLOPT_KRB4LEVEL
Pass a char * as parameter. Set the krb4 security level, this also enables
krb4 awareness. This is a string, 'clear', 'safe', 'confidential' or
'private'. If the string is set but doesn't match one of these, 'private'
will be used. Set the string to NULL to disable kerberos4. The kerberos
support only works for FTP. (Added in libcurl 7.3)
.TP
.B CURLOPT_WRITEINFO
Pass a pointer to a zero terminated string as parameter. It will be used to
report information after a successful request. This string may contain

8
docs/examples/README Normal file
View File

@@ -0,0 +1,8 @@
EXAMPLES
This directory is for tiny libcurl programming examples. They are meant to
show some simple steps on how you can build your own application to take full
advantage of libcurl.
If you end up with other small but still useful example sources, please mail
them for submission in future packages and on the web site.

View File

@@ -0,0 +1,63 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
written = fwrite(ptr,size,nmemb,outfile);
return written;
}
int main(int argc, char **argv)
{
CURL *curl_handle;
char *headerfilename = "head.out";
FILE *headerfile;
char *bodyfilename = "body.out";
FILE *bodyfile;
/* init the curl session */
curl_handle = curl_easy_init();
/* set URL to get */
curl_easy_setopt(curl_handle, CURLOPT_URL, "http://curl.haxx.se");
/* no progress meter please */
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
/* shut up completely */
curl_easy_setopt(curl_handle, CURLOPT_MUTE, 1);
/* send all data to this function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
/* open the files */
headerfile = fopen(headerfilename,"w");
if (headerfile == NULL) {
curl_easy_cleanup(curl_handle);
return -1;
}
bodyfile = fopen(bodyfilename,"w");
if (bodyfile == NULL) {
curl_easy_cleanup(curl_handle);
return -1;
}
/* we want the headers to this file handle */
curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER ,headerfile);
/* get it! */
curl_easy_perform(curl_handle);
/* close the header file */
fclose(headerfile);
/* cleanup curl stuff */
curl_easy_cleanup(curl_handle);
return 0;
}

26
docs/examples/simple.c Normal file
View File

@@ -0,0 +1,26 @@
#include <stdio.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
int main(int argc, char **argv)
{
CURL *curl;
CURLcode res;
FILE *headerfile;
headerfile = fopen("dumpit", "w");
curl = curl_easy_init();
if(curl) {
/* what call to write: */
curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se");
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, headerfile);
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}

View File

@@ -67,6 +67,10 @@
#include <curl/types.h>
#ifdef __cplusplus
extern "C" {
#endif
struct HttpPost {
struct HttpPost *next; /* next entry in the list */
char *name; /* pointer to allocated name */
@@ -141,6 +145,8 @@ typedef enum {
CURLE_HTTP_POST_ERROR,
CURLE_HTTP_PORT_FAILED, /* HTTP Interface operation failed */
CURLE_SSL_CONNECT_ERROR, /* something was wrong when connecting with SSL */
CURLE_FTP_BAD_DOWNLOAD_RESUME, /* couldn't resume download */
@@ -172,7 +178,10 @@ typedef enum {
/* name is uppercase CURLOPT_<name>,
type is one of the defined CURLOPTTYPE_<type>
number is unique identifier */
#define T(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number
#ifdef CINIT
#undef CINIT
#endif
#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number
/* long may be 32 or 64 bits, but we should never depend on anything else
but 32 */
@@ -181,74 +190,74 @@ typedef enum {
#define CURLOPTTYPE_FUNCTIONPOINT 20000
typedef enum {
T(NOTHING, LONG, 0), /********* the first one is unused ************/
CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/
/* This is the FILE * the regular output should be written to. */
T(FILE, OBJECTPOINT, 1),
CINIT(FILE, OBJECTPOINT, 1),
/* The full URL to get/put */
T(URL, OBJECTPOINT, 2),
CINIT(URL, OBJECTPOINT, 2),
/* Port number to connect to, if other than default. Specify the CONF_PORT
flag in the CURLOPT_FLAGS to activate this */
T(PORT, LONG, 3),
CINIT(PORT, LONG, 3),
/* Name of proxy to use. Specify the CONF_PROXY flag in the CURLOPT_FLAGS to
activate this */
T(PROXY, OBJECTPOINT, 4),
CINIT(PROXY, OBJECTPOINT, 4),
/* Name and password to use when fetching. Specify the CONF_USERPWD flag in
the CURLOPT_FLAGS to activate this */
T(USERPWD, OBJECTPOINT, 5),
CINIT(USERPWD, OBJECTPOINT, 5),
/* Name and password to use with Proxy. Specify the CONF_PROXYUSERPWD
flag in the CURLOPT_FLAGS to activate this */
T(PROXYUSERPWD, OBJECTPOINT, 6),
CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
/* Range to get, specified as an ASCII string. Specify the CONF_RANGE flag
in the CURLOPT_FLAGS to activate this */
T(RANGE, OBJECTPOINT, 7),
CINIT(RANGE, OBJECTPOINT, 7),
#if 0
/* Configuration flags */
T(FLAGS, LONG, 8),
CINIT(FLAGS, LONG, 8),
#endif
/* Specified file stream to upload from (use as input): */
T(INFILE, OBJECTPOINT, 9),
CINIT(INFILE, OBJECTPOINT, 9),
/* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
* bytes big. If this is not used, error messages go to stderr instead: */
T(ERRORBUFFER, OBJECTPOINT, 10),
CINIT(ERRORBUFFER, OBJECTPOINT, 10),
/* Function that will be called to store the output (instead of fwrite). The
* parameters will use fwrite() syntax, make sure to follow them. */
T(WRITEFUNCTION, FUNCTIONPOINT, 11),
CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
/* Function that will be called to read the input (instead of fread). The
* parameters will use fread() syntax, make sure to follow them. */
T(READFUNCTION, FUNCTIONPOINT, 12),
CINIT(READFUNCTION, FUNCTIONPOINT, 12),
/* Time-out the read operation after this amount of seconds */
T(TIMEOUT, LONG, 13),
CINIT(TIMEOUT, LONG, 13),
/* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
* how large the file being sent really is. That allows better error
* checking and better verifies that the upload was succcessful. -1 means
* unknown size. */
T(INFILESIZE, LONG, 14),
CINIT(INFILESIZE, LONG, 14),
/* POST input fields. */
T(POSTFIELDS, OBJECTPOINT, 15),
CINIT(POSTFIELDS, OBJECTPOINT, 15),
/* Set the referer page (needed by some CGIs) */
T(REFERER, OBJECTPOINT, 16),
CINIT(REFERER, OBJECTPOINT, 16),
/* Set the FTP PORT string (interface name, named or numerical IP address)
Use i.e '-' to use default address. */
T(FTPPORT, OBJECTPOINT, 17),
CINIT(FTPPORT, OBJECTPOINT, 17),
/* Set the User-Agent string (examined by some CGIs) */
T(USERAGENT, OBJECTPOINT, 18),
CINIT(USERAGENT, OBJECTPOINT, 18),
/* If the download receives less than "low speed limit" bytes/second
* during "low speed time" seconds, the operations is aborted.
@@ -257,119 +266,133 @@ typedef enum {
*/
/* Set the "low speed limit" */
T(LOW_SPEED_LIMIT, LONG , 19),
CINIT(LOW_SPEED_LIMIT, LONG , 19),
/* Set the "low speed time" */
T(LOW_SPEED_TIME, LONG, 20),
CINIT(LOW_SPEED_TIME, LONG, 20),
/* Set the continuation offset */
T(RESUME_FROM, LONG, 21),
CINIT(RESUME_FROM, LONG, 21),
/* Set cookie in request: */
T(COOKIE, OBJECTPOINT, 22),
CINIT(COOKIE, OBJECTPOINT, 22),
/* This points to a linked list of headers, struct HttpHeader kind */
T(HTTPHEADER, OBJECTPOINT, 23),
CINIT(HTTPHEADER, OBJECTPOINT, 23),
/* This points to a linked list of post entries, struct HttpPost */
T(HTTPPOST, OBJECTPOINT, 24),
CINIT(HTTPPOST, OBJECTPOINT, 24),
/* name of the file keeping your private SSL-certificate */
T(SSLCERT, OBJECTPOINT, 25),
CINIT(SSLCERT, OBJECTPOINT, 25),
/* password for the SSL-certificate */
T(SSLCERTPASSWD, OBJECTPOINT, 26),
CINIT(SSLCERTPASSWD, OBJECTPOINT, 26),
/* send TYPE parameter? */
T(CRLF, LONG, 27),
CINIT(CRLF, LONG, 27),
/* send linked-list of QUOTE commands */
T(QUOTE, OBJECTPOINT, 28),
CINIT(QUOTE, OBJECTPOINT, 28),
/* send FILE * to store headers to */
T(WRITEHEADER, OBJECTPOINT, 29),
CINIT(WRITEHEADER, OBJECTPOINT, 29),
#ifdef MULTIDOC
/* send linked list of MoreDoc structs */
T(MOREDOCS, OBJECTPOINT, 30),
CINIT(MOREDOCS, OBJECTPOINT, 30),
#endif
/* point to a file to read the initial cookies from, also enables
"cookie awareness" */
T(COOKIEFILE, OBJECTPOINT, 31),
CINIT(COOKIEFILE, OBJECTPOINT, 31),
/* What version to specifly try to use.
3 = SSLv3, 2 = SSLv2, all else makes it try v3 first then v2 */
T(SSLVERSION, LONG, 32),
CINIT(SSLVERSION, LONG, 32),
/* What kind of HTTP time condition to use, see defines */
T(TIMECONDITION, LONG, 33),
CINIT(TIMECONDITION, LONG, 33),
/* Time to use with the above condition. Specified in number of seconds
since 1 Jan 1970 */
T(TIMEVALUE, LONG, 34),
CINIT(TIMEVALUE, LONG, 34),
/* HTTP request, for odd commands like DELETE, TRACE and others */
/* OBSOLETE DEFINE, left for tradition only */
T(HTTPREQUEST, OBJECTPOINT, 35),
CINIT(HTTPREQUEST, OBJECTPOINT, 35),
/* Custom request, for customizing the get command like
HTTP: DELETE, TRACE and others
FTP: to use a different list command
*/
T(CUSTOMREQUEST, OBJECTPOINT, 36),
CINIT(CUSTOMREQUEST, OBJECTPOINT, 36),
/* HTTP request, for odd commands like DELETE, TRACE and others */
T(STDERR, OBJECTPOINT, 37),
CINIT(STDERR, OBJECTPOINT, 37),
#if 0
/* Progress mode set alternative progress mode displays. Alternative
ones should now be made by the client, not the lib! */
T(PROGRESSMODE, LONG, 38),
CINIT(PROGRESSMODE, LONG, 38),
#endif
/* send linked-list of post-transfer QUOTE commands */
T(POSTQUOTE, OBJECTPOINT, 39),
CINIT(POSTQUOTE, OBJECTPOINT, 39),
/* Pass a pointer to string of the output using full variable-replacement
as described elsewhere. */
T(WRITEINFO, OBJECTPOINT, 40),
CINIT(WRITEINFO, OBJECTPOINT, 40),
/* Previous FLAG bits */
T(VERBOSE, LONG, 41), /* talk a lot */
T(HEADER, LONG, 42), /* throw the header out too */
T(NOPROGRESS, LONG, 43), /* shut off the progress meter */
T(NOBODY, LONG, 44), /* use HEAD to get http document */
T(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */
T(UPLOAD, LONG, 46), /* this is an upload */
T(POST, LONG, 47), /* HTTP POST method */
T(FTPLISTONLY, LONG, 48), /* Use NLST when listing ftp dir */
CINIT(VERBOSE, LONG, 41), /* talk a lot */
CINIT(HEADER, LONG, 42), /* throw the header out too */
CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */
CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */
CINIT(UPLOAD, LONG, 46), /* this is an upload */
CINIT(POST, LONG, 47), /* HTTP POST method */
CINIT(FTPLISTONLY, LONG, 48), /* Use NLST when listing ftp dir */
T(FTPAPPEND, LONG, 50), /* Append instead of overwrite on upload! */
T(NETRC, LONG, 51), /* read user+password from .netrc */
T(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */
CINIT(FTPAPPEND, LONG, 50), /* Append instead of overwrite on upload! */
CINIT(NETRC, LONG, 51), /* read user+password from .netrc */
CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */
/* This FTPASCII name is now obsolete, to be removed, use the TRANSFERTEXT
instead. It goes for more protocols than just ftp... */
T(FTPASCII, LONG, 53), /* use TYPE A for transfer */
CINIT(FTPASCII, LONG, 53), /* use TYPE A for transfer */
T(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
T(PUT, LONG, 54), /* PUT the input file */
T(MUTE, LONG, 55), /* force NOPROGRESS */
CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
CINIT(PUT, LONG, 54), /* PUT the input file */
CINIT(MUTE, LONG, 55), /* force NOPROGRESS */
/* Function that will be called instead of the internal progress display
* function. This function should be defined as the curl_progress_callback
* prototype defines. */
T(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
/* Data passed to the progress callback */
T(PROGRESSDATA, OBJECTPOINT, 57),
CINIT(PROGRESSDATA, OBJECTPOINT, 57),
/* We want the referer field set automatically when following locations */
T(AUTOREFERER, LONG, 58),
CINIT(AUTOREFERER, LONG, 58),
/* Port of the proxy, can be set in the proxy string as well with:
"[host]:[port]" */
T(PROXYPORT, LONG, 59),
CINIT(PROXYPORT, LONG, 59),
/* size of the POST input data, if strlen() is not good to use */
CINIT(POSTFIELDSIZE, LONG, 60),
/* tunnel non-http operations through a HTTP proxy */
CINIT(HTTPPROXYTUNNEL, LONG, 61),
/* Set the interface string to use as outgoing network interface */
CINIT(INTERFACE, OBJECTPOINT, 62),
/* Set the krb4 security level, this also enables krb4 awareness. This is a
* string, 'clear', 'safe', 'confidential' or 'private'. If the string is
* set but doesn't match one of these, 'private' will be used. */
CINIT(KRB4LEVEL, OBJECTPOINT, 63),
CURLOPT_LASTENTRY /* the last unusued */
} CURLoption;
@@ -419,8 +442,8 @@ char *curl_getenv(char *variable);
char *curl_version(void);
/* This is the version number */
#define LIBCURL_VERSION "7.1.1"
#define LIBCURL_VERSION_NUM 0x070101
#define LIBCURL_VERSION "7.3"
#define LIBCURL_VERSION_NUM 0x070300
/* linked-list structure for the CURLOPT_QUOTE option */
struct curl_slist {
@@ -619,4 +642,8 @@ CURLcode curl_disconnect(CURLconnect *connect);
*/
time_t curl_getdate(const char *p, const time_t *now);
#ifdef __cplusplus
}
#endif
#endif /* __CURL_CURL_H */

View File

@@ -39,8 +39,17 @@
*
* ------------------------------------------------------------
****************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
CURL *curl_easy_init(void);
CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
CURLcode curl_easy_perform(CURL *curl);
void curl_easy_cleanup(CURL *curl);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -2,7 +2,7 @@
# $Id$
#
AUTOMAKE_OPTIONS = foreign no-dependencies
AUTOMAKE_OPTIONS = foreign
lib_LTLIBRARIES = libcurl.la
@@ -23,7 +23,8 @@ download.c getdate.h ldap.c ssluse.c version.c \
download.h getenv.c ldap.h ssluse.h \
escape.c getenv.h mprintf.c telnet.c \
escape.h getpass.c netrc.c telnet.h \
writeout.c writeout.h highlevel.c strequal.c strequal.h easy.c
writeout.c writeout.h highlevel.c strequal.c strequal.h easy.c \
security.h security.c krb4.c
# Say $(srcdir), so GNU make does not report an ambiguity with the .y.c rule.
$(srcdir)/getdate.c: getdate.y

View File

@@ -77,7 +77,7 @@ RANLIB = @RANLIB@
VERSION = @VERSION@
YACC = @YACC@
AUTOMAKE_OPTIONS = foreign no-dependencies
AUTOMAKE_OPTIONS = foreign
lib_LTLIBRARIES = libcurl.la
@@ -86,7 +86,7 @@ lib_LTLIBRARIES = libcurl.la
INCLUDES = -I$(top_srcdir)/include
libcurl_la_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c base64.c file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.h sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h dict.h getdate.c if2ip.h speedcheck.h urldata.h download.c getdate.h ldap.c ssluse.c version.c download.h getenv.c ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c telnet.h writeout.c writeout.h highlevel.c strequal.c strequal.h easy.c
libcurl_la_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c base64.c file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.h sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h dict.h getdate.c if2ip.h speedcheck.h urldata.h download.c getdate.h ldap.c ssluse.c version.c download.h getenv.c ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c telnet.h writeout.c writeout.h highlevel.c strequal.c strequal.h easy.c security.h security.c krb4.c
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h ../src/config.h
@@ -104,7 +104,7 @@ libcurl_la_OBJECTS = file.lo timeval.lo base64.lo hostip.lo progress.lo \
formdata.lo cookie.lo http.lo sendf.lo ftp.lo url.lo dict.lo if2ip.lo \
speedcheck.lo getdate.lo download.lo ldap.lo ssluse.lo version.lo \
getenv.lo escape.lo mprintf.lo telnet.lo getpass.lo netrc.lo \
writeout.lo highlevel.lo strequal.lo easy.lo
writeout.lo highlevel.lo strequal.lo easy.lo security.lo krb4.lo
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)

View File

@@ -53,11 +53,11 @@ RELEASE_OBJS= \
timevalr.obj \
urlr.obj \
filer.obj \
writeoutr.obj \
writeoutr.obj \
versionr.obj \
easyr.obj \
highlevelr.obj \
strequalr.obj
easyr.obj \
highlevelr.obj \
strequalr.obj
DEBUG_OBJS= \
base64d.obj \
@@ -67,7 +67,7 @@ DEBUG_OBJS= \
formdatad.obj \
ftpd.obj \
httpd.obj \
ldapd.obj \
ldapd.obj \
dictd.obj \
telnetd.obj \
getdated.obj \
@@ -84,11 +84,11 @@ DEBUG_OBJS= \
timevald.obj \
urld.obj \
filed.obj \
writeoutd.obj \
versiond.obj \
easyd.obj \
highleveld.obj \
strequald.obj
writeoutd.obj \
versiond.obj \
easyd.obj \
highleveld.obj \
strequald.obj
RELEASE_SSL_OBJS= \
base64rs.obj \
@@ -98,7 +98,7 @@ RELEASE_SSL_OBJS= \
formdatars.obj \
ftprs.obj \
httprs.obj \
ldaprs.obj \
ldaprs.obj \
dictrs.obj \
telnetrs.obj \
getdaters.obj \
@@ -115,11 +115,11 @@ RELEASE_SSL_OBJS= \
timevalrs.obj \
urlrs.obj \
filers.obj \
writeouts.obj \
writeouts.obj \
versionrs.obj \
easyrs.obj \
highlevelrs.obj \
strequalrs.obj
easyrs.obj \
highlevelrs.obj \
strequalrs.obj
LINK_OBJS= \
base64.obj \
@@ -129,7 +129,7 @@ LINK_OBJS= \
formdata.obj \
ftp.obj \
http.obj \
ldap.obj \
ldap.obj \
dict.obj \
telnet.obj \
getdate.obj \
@@ -146,11 +146,11 @@ LINK_OBJS= \
timeval.obj \
url.obj \
file.obj \
writeout.obj \
writeout.obj \
version.obj \
easy.obj \
highlevel.obj \
strequal.obj
easy.obj \
highlevel.obj \
strequal.obj
all : release
@@ -217,6 +217,12 @@ writeoutr.obj: writeout.c
$(CCR) $(CFLAGS) writeout.c
versionr.obj: version.c
$(CCR) $(CFLAGS) version.c
easyr.obj: easy.c
$(CCR) $(CFLAGS) easy.c
highlevelr.obj: highlevel.c
$(CCR) $(CFLAGS) highlevel.c
strequalr.obj: strequal.c
$(CCR) $(CFLAGS) strequal.c
## Debug
base64d.obj: base64.c
@@ -271,6 +277,12 @@ writeoutd.obj: writeout.c
$(CCR) $(CFLAGS) writeout.c
versiond.obj: version.c
$(CCD) $(CFLAGS) version.c
easyd.obj: easy.c
$(CCR) $(CFLAGS) easy.c
highleveld.obj: highlevel.c
$(CCR) $(CFLAGS) highlevel.c
strequald.obj: strequal.c
$(CCR) $(CFLAGS) strequal.c
## Release SSL
@@ -326,6 +338,12 @@ writeoutrs.obj: writeout.c
$(CCR) $(CFLAGS) writeout.c
versionrs.obj: version.c
$(CCRS) $(CFLAGS) version.c
easyrs.obj: easy.c
$(CCR) $(CFLAGS) easy.c
highlevelrs.obj: highlevel.c
$(CCR) $(CFLAGS) highlevel.c
strequalrs.obj: strequal.c
$(CCR) $(CFLAGS) strequal.c
clean:
-@erase *.obj

View File

@@ -1,94 +1,147 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Curl.
*
* The Initial Developer of the Original Code is Daniel Stenberg.
*
* Portions created by the Initial Developer are Copyright (C) 1998.
* All Rights Reserved.
*
* ------------------------------------------------------------
* Main author:
* - Daniel Stenberg <daniel@haxx.se>
*
* http://curl.haxx.se
*
* $Source$
* $Revision$
* $Date$
* $Author$
* $State$
* $Locker$
*
* ------------------------------------------------------------
****************************************************************************/
/*
* Copyright (c) 1995 - 1999 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdio.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include "base64.h"
/* ---- Base64 Encoding --- */
static char table64[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void base64Encode(char *intext, char *output)
static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static int pos(char c)
{
unsigned char ibuf[3];
unsigned char obuf[4];
int i;
int inputparts;
while(*intext) {
for (i = inputparts = 0; i < 3; i++) {
if(*intext) {
inputparts++;
ibuf[i] = *intext;
intext++;
}
else
ibuf[i] = 0;
}
obuf [0] = (ibuf [0] & 0xFC) >> 2;
obuf [1] = ((ibuf [0] & 0x03) << 4) | ((ibuf [1] & 0xF0) >> 4);
obuf [2] = ((ibuf [1] & 0x0F) << 2) | ((ibuf [2] & 0xC0) >> 6);
obuf [3] = ibuf [2] & 0x3F;
switch(inputparts) {
case 1: /* only one byte read */
sprintf(output, "%c%c==",
table64[obuf[0]],
table64[obuf[1]]);
break;
case 2: /* two bytes read */
sprintf(output, "%c%c%c=",
table64[obuf[0]],
table64[obuf[1]],
table64[obuf[2]]);
break;
default:
sprintf(output, "%c%c%c%c",
table64[obuf[0]],
table64[obuf[1]],
table64[obuf[2]],
table64[obuf[3]] );
break;
}
output += 4;
}
*output=0;
char *p;
for(p = base64; *p; p++)
if(*p == c)
return p - base64;
return -1;
}
#if 1
int base64_encode(const void *data, int size, char **str)
{
char *s, *p;
int i;
int c;
const unsigned char *q;
p = s = (char*)malloc(size*4/3+4);
if (p == NULL)
return -1;
q = (const unsigned char*)data;
i=0;
for(i = 0; i < size;){
c=q[i++];
c*=256;
if(i < size)
c+=q[i];
i++;
c*=256;
if(i < size)
c+=q[i];
i++;
p[0]=base64[(c&0x00fc0000) >> 18];
p[1]=base64[(c&0x0003f000) >> 12];
p[2]=base64[(c&0x00000fc0) >> 6];
p[3]=base64[(c&0x0000003f) >> 0];
if(i > size)
p[3]='=';
if(i > size+1)
p[2]='=';
p+=4;
}
*p=0;
*str = s;
return strlen(s);
}
#endif
int base64_decode(const char *str, void *data)
{
const char *p;
unsigned char *q;
int c;
int x;
int done = 0;
q=(unsigned char*)data;
for(p=str; *p && !done; p+=4){
x = pos(p[0]);
if(x >= 0)
c = x;
else{
done = 3;
break;
}
c*=64;
x = pos(p[1]);
if(x >= 0)
c += x;
else
return -1;
c*=64;
if(p[2] == '=')
done++;
else{
x = pos(p[2]);
if(x >= 0)
c += x;
else
return -1;
}
c*=64;
if(p[3] == '=')
done++;
else{
if(done)
return -1;
x = pos(p[3]);
if(x >= 0)
c += x;
else
return -1;
}
if(done < 3)
*q++=(c&0x00ff0000)>>16;
if(done < 2)
*q++=(c&0x0000ff00)>>8;
if(done < 1)
*q++=(c&0x000000ff)>>0;
}
return q - (unsigned char*)data;
}
/* ---- End of Base64 Encoding ---- */

View File

@@ -1,44 +1,39 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef __BASE64_H
#define __BASE64_H
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Curl.
*
* The Initial Developer of the Original Code is Daniel Stenberg.
*
* Portions created by the Initial Developer are Copyright (C) 1998.
* All Rights Reserved.
*
* ------------------------------------------------------------
* Main author:
* - Daniel Stenberg <daniel@haxx.se>
*
* http://curl.haxx.se
*
* $Source$
* $Revision$
* $Date$
* $Author$
* $State$
* $Locker$
*
* ------------------------------------------------------------
****************************************************************************/
void base64Encode(char *intext, char *output);
int base64_encode(const void *data, int size, char **str);
#endif

View File

@@ -55,12 +55,13 @@ Example set of cookies:
13-Jun-1988 03:04:55 GMT; domain=.fidelity.com; path=/; secure
****/
#include "setup.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "cookie.h"
#include "setup.h"
#include "getdate.h"
#include "strequal.h"
@@ -98,8 +99,9 @@ struct Cookie *cookie_add(struct CookieInfo *c,
semiptr=strchr(lineptr, ';'); /* first, find a semicolon */
ptr = lineptr;
while(semiptr) {
*semiptr='\0'; /* zero terminate for a while */
do {
if(semiptr)
*semiptr='\0'; /* zero terminate for a while */
/* we have a <what>=<this> pair or a 'secure' word here */
if(strchr(ptr, '=')) {
name[0]=what[0]=0; /* init the buffers */
@@ -155,12 +157,15 @@ struct Cookie *cookie_add(struct CookieInfo *c,
; /* unsupported keyword without assign! */
}
}
if(!semiptr)
continue; /* we already know there are no more cookies */
*semiptr=';'; /* put the semicolon back */
ptr=semiptr+1;
while(ptr && *ptr && isspace((int)*ptr))
ptr++;
semiptr=strchr(ptr, ';'); /* now, find the next semicolon */
}
} while(semiptr);
}
else {
/* This line is NOT a HTTP header style line, we do offer support for

View File

@@ -38,6 +38,8 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
@@ -49,8 +51,6 @@
#include <errno.h>
#include "setup.h"
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
#include <time.h>

View File

@@ -38,12 +38,12 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "setup.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

View File

@@ -38,6 +38,8 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
@@ -49,7 +51,6 @@
#include <errno.h>
#include "setup.h"
#include "strequal.h"
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
@@ -108,6 +109,9 @@ CURL *curl_easy_init(void)
return NULL;
data->interf = CURLI_EASY; /* mark it as an easy one */
/* SAC */
data->device = NULL;
return data;
}

View File

@@ -41,6 +41,9 @@
/* Escape and unescape URL encoding in strings. The functions return a new
* allocated string or NULL if an error occurred. */
#include "setup.h"
#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -88,17 +91,24 @@ char *curl_unescape(char *string, int length)
unsigned char in;
int index=0;
int hex;
char querypart=FALSE; /* everything to the right of a '?' letter is
the "query part" where '+' should become ' '.
RFC 2316, section 3.10 */
while(--alloc) {
in = *string;
if('+' == in)
in = ' ';
if(querypart && ('+' == in))
in = ' ';
else if(!querypart && ('?' == in)) {
/* we have "walked in" to the query part */
querypart=TRUE;
}
else if('%' == in) {
/* encoded part */
if(sscanf(string+1, "%02X", &hex)) {
in = hex;
string+=2;
}
/* encoded part */
if(sscanf(string+1, "%02X", &hex)) {
in = hex;
string+=2;
}
}
ns[index++] = in;

View File

@@ -38,6 +38,8 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
@@ -49,8 +51,6 @@
#include <errno.h>
#include "setup.h"
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
#include <time.h>
@@ -60,13 +60,17 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#include <sys/time.h>
#include <sys/resource.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif

View File

@@ -49,6 +49,8 @@
*/
#include "setup.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -56,7 +58,6 @@
#include <time.h>
#include "setup.h"
#include <curl/curl.h>
#include "formdata.h"

232
lib/ftp.c
View File

@@ -38,14 +38,14 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include "setup.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -60,22 +60,22 @@
#include <sys/socket.h>
#endif
#include <sys/types.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <sys/utsname.h>
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#endif
#if defined(WIN32) && defined(__GNUC__) || defined(__MINGW32__)
#include <errno.h>
#endif
#ifdef HAVE_INET_NTOA_R
#include "inet_ntoa_r.h"
#endif
#include <curl/curl.h>
#include "urldata.h"
#include "sendf.h"
@@ -86,6 +86,10 @@
#include "download.h"
#include "escape.h"
#ifdef KRB4
#include "security.h"
#endif
/* returns last node in linked list */
static struct curl_slist *slist_get_last(struct curl_slist *list)
{
@@ -285,6 +289,19 @@ int GetLastResponse(int sockfd, char *buf,
}
*ptr=0; /* zero terminate */
#if KRB4
{ /* handle the security-oriented responses 6xx ***/
/* FIXME: some errorchecking perhaps... ***/
if(strncmp(buf, "631", 3) == 0)
sec_read_msg(conn, buf, prot_safe);
else if(strncmp(buf, "632", 3) == 0)
sec_read_msg(conn, buf, prot_private);
else if(strncmp(buf, "633", 3) == 0)
sec_read_msg(conn, buf, prot_confidential);
nread = strlen(buf);
}
#endif
if(data->bits.verbose && buf[0]) {
fputs("< ", data->err);
fwrite(buf, 1, nread, data->err);
@@ -372,6 +389,7 @@ CURLcode ftp_connect(struct connectdata *conn)
struct UrlData *data=conn->data;
char *buf = data->buffer; /* this is our buffer */
struct FTP *ftp;
CURLcode result;
myalarm(0); /* switch off the alarm stuff */
@@ -387,6 +405,14 @@ CURLcode ftp_connect(struct connectdata *conn)
ftp->user = data->user;
ftp->passwd = data->passwd;
if (data->bits.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
result = GetHTTPProxyTunnel(data, data->firstsocket,
data->hostname, data->remote_port);
if(CURLE_OK != result)
return result;
}
/* The first thing we do is wait for the "220*" line: */
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
@@ -396,8 +422,28 @@ CURLcode ftp_connect(struct connectdata *conn)
return CURLE_FTP_WEIRD_SERVER_REPLY;
}
#ifdef KRB4
/* if not anonymous login, try a secure login */
if(data->bits.krb4) {
/* request data protection level (default is 'clear') */
sec_request_prot(conn, "private");
/* We set private first as default, in case the line below fails to
set a valid level */
sec_request_prot(conn, data->krb4_level);
data->cmdchannel = fdopen(data->firstsocket, "w");
if(sec_login(conn) != 0)
infof(data, "Logging in with password in cleartext!\n");
else
infof(data, "Authentication successful\n");
}
#endif
/* send USER */
sendf(data->firstsocket, data, "USER %s\r\n", ftp->user);
ftpsendf(data->firstsocket, conn, "USER %s", ftp->user);
/* wait for feedback */
nread = GetLastResponse(data->firstsocket, buf, conn);
@@ -413,7 +459,7 @@ CURLcode ftp_connect(struct connectdata *conn)
else if(!strncmp(buf, "331", 3)) {
/* 331 Password required for ...
(the server requires to send the user's password too) */
sendf(data->firstsocket, data, "PASS %s\r\n", ftp->passwd);
ftpsendf(data->firstsocket, conn, "PASS %s", ftp->passwd);
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
return CURLE_OPERATION_TIMEOUTED;
@@ -435,10 +481,23 @@ CURLcode ftp_connect(struct connectdata *conn)
return CURLE_FTP_WEIRD_PASS_REPLY;
}
}
else if(! strncmp(buf, "230", 3)) {
else if(/*! strncmp(buf, "230", 3)***/ buf[0] == '2') {
/* 230 User ... logged in.
(the user logged in without password) */
infof(data, "We have successfully logged in\n");
#ifdef KRB4
/* we are logged in (with Kerberos)
* now set the requested protection level
*/
if(conn->sec_complete)
sec_set_protection_level(conn);
/* we may need to issue a KAUTH here to have access to the files
* do it if user supplied a password
*/
if(conn->data->passwd && *conn->data->passwd)
krb_kauth(conn);
#endif
}
else {
failf(data, "Odd return code after USER");
@@ -471,25 +530,30 @@ CURLcode ftp_done(struct connectdata *conn)
failf(data, "Received only partial file");
return CURLE_PARTIAL_FILE;
}
else if(0 == *ftp->bytecountp) {
else if(!data->bits.no_body && (0 == *ftp->bytecountp)) {
failf(data, "No data was received!");
return CURLE_FTP_COULDNT_RETR_FILE;
}
}
#ifdef KRB4
sec_fflush_fd(conn, data->secondarysocket);
#endif
/* shut down the socket to inform the server we're done */
sclose(data->secondarysocket);
data->secondarysocket = -1;
/* now let's see what the server says about the transfer we
just performed: */
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
return CURLE_OPERATION_TIMEOUTED;
/* 226 Transfer complete, 250 Requested file action okay, completed. */
if(!strncmp(buf, "226", 3) && !strncmp(buf, "250", 3)) {
failf(data, "%s", buf+4);
return CURLE_FTP_WRITE_ERROR;
if(!data->bits.no_body) {
/* now let's see what the server says about the transfer we
just performed: */
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
return CURLE_OPERATION_TIMEOUTED;
/* 226 Transfer complete, 250 Requested file action okay, completed. */
if(!strncmp(buf, "226", 3) && !strncmp(buf, "250", 3)) {
failf(data, "%s", buf+4);
return CURLE_FTP_WRITE_ERROR;
}
}
/* Send any post-transfer QUOTE strings? */
@@ -499,7 +563,7 @@ CURLcode ftp_done(struct connectdata *conn)
while (qitem) {
/* Send string */
if (qitem->data) {
sendf(data->firstsocket, data, "%s\r\n", qitem->data);
ftpsendf(data->firstsocket, conn, "%s", qitem->data);
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
@@ -556,7 +620,7 @@ CURLcode _ftp(struct connectdata *conn)
while (qitem) {
/* Send string */
if (qitem->data) {
sendf(data->firstsocket, data, "%s\r\n", qitem->data);
ftpsendf(data->firstsocket, conn, "%s", qitem->data);
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
@@ -572,6 +636,19 @@ CURLcode _ftp(struct connectdata *conn)
}
}
/* change directory first! */
if(ftp->dir && ftp->dir[0]) {
ftpsendf(data->firstsocket, conn, "CWD %s", ftp->dir);
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
return CURLE_OPERATION_TIMEOUTED;
if(strncmp(buf, "250", 3)) {
failf(data, "Couldn't change to directory %s", ftp->dir);
return CURLE_FTP_ACCESS_DENIED;
}
}
/* If we have selected NOBODY, it means that we only want file information.
Which in FTP can't be much more than the file size! */
if(data->bits.no_body) {
@@ -579,7 +656,7 @@ CURLcode _ftp(struct connectdata *conn)
may not support it! It is however the only way we have to get a file's
size! */
int filesize;
sendf(data->firstsocket, data, "SIZE %s\r\n", ftp->file);
ftpsendf(data->firstsocket, conn, "SIZE %s", ftp->file);
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
@@ -613,23 +690,24 @@ CURLcode _ftp(struct connectdata *conn)
if(data->bits.ftp_use_port) {
struct sockaddr_in sa;
struct hostent *h=NULL;
char *hostdataptr=NULL;
size_t size;
unsigned short porttouse;
char myhost[256] = "";
if(data->ftpport) {
if(if2ip(data->ftpport, myhost, sizeof(myhost))) {
h = GetHost(data, myhost, hostent_buf, sizeof(hostent_buf));
h = GetHost(data, myhost, &hostdataptr);
}
else {
if(strlen(data->ftpport)>1)
h = GetHost(data, data->ftpport, hostent_buf, sizeof(hostent_buf));
h = GetHost(data, data->ftpport, &hostdataptr);
if(h)
strcpy(myhost,data->ftpport);
strcpy(myhost, data->ftpport); /* buffer overflow risk */
}
}
if(! *myhost) {
h=GetHost(data, getmyhost(myhost,sizeof(myhost)), hostent_buf, sizeof(hostent_buf));
h=GetHost(data, getmyhost(myhost, sizeof(myhost)), &hostdataptr);
}
infof(data, "We connect from %s\n", myhost);
@@ -658,16 +736,19 @@ CURLcode _ftp(struct connectdata *conn)
if ( listen(portsock, 1) < 0 ) {
failf(data, "listen(2) failed on socket");
free(hostdataptr);
return CURLE_FTP_PORT_FAILED;
}
}
else {
failf(data, "bind(2) failed on socket");
free(hostdataptr);
return CURLE_FTP_PORT_FAILED;
}
}
else {
failf(data, "socket(2) failed (%s)");
free(hostdataptr);
return CURLE_FTP_PORT_FAILED;
}
}
@@ -680,13 +761,16 @@ CURLcode _ftp(struct connectdata *conn)
unsigned short ip[5];
(void) memcpy(&in.s_addr, *h->h_addr_list, sizeof (in.s_addr));
#if defined (HAVE_INET_NTOA_R)
sscanf( inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)), "%hu.%hu.%hu.%hu",
/* ignore the return code from inet_ntoa_r() as it is int or
char * depending on system */
inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf));
sscanf( ntoa_buf, "%hu.%hu.%hu.%hu",
&ip[0], &ip[1], &ip[2], &ip[3]);
#else
sscanf( inet_ntoa(in), "%hu.%hu.%hu.%hu",
&ip[0], &ip[1], &ip[2], &ip[3]);
#endif
sendf(data->firstsocket, data, "PORT %d,%d,%d,%d,%d,%d\r\n",
ftpsendf(data->firstsocket, conn, "PORT %d,%d,%d,%d,%d,%d",
ip[0], ip[1], ip[2], ip[3],
porttouse >> 8,
porttouse & 255);
@@ -703,7 +787,7 @@ CURLcode _ftp(struct connectdata *conn)
}
else { /* we use the PASV command */
sendf(data->firstsocket, data, "PASV\r\n");
ftpsendf(data->firstsocket, conn, "PASV");
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
@@ -716,10 +800,12 @@ CURLcode _ftp(struct connectdata *conn)
else {
int ip[4];
int port[2];
unsigned short newport;
unsigned short newport; /* remote port, not necessary the local one */
unsigned short connectport; /* the local port connect() should use! */
char newhost[32];
struct hostent *he;
char *str=buf,*ip_addr;
char *hostdataptr=NULL;
/*
* New 227-parser June 3rd 1999.
@@ -743,21 +829,35 @@ CURLcode _ftp(struct connectdata *conn)
failf(data, "Couldn't interpret this 227-reply: %s", buf);
return CURLE_FTP_WEIRD_227_FORMAT;
}
sprintf(newhost, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
he = GetHost(data, newhost, hostent_buf, sizeof(hostent_buf));
if(!he) {
failf(data, "Can't resolve new host %s", newhost);
return CURLE_FTP_CANT_GET_HOST;
}
sprintf(newhost, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
newport = (port[0]<<8) + port[1];
if(data->bits.httpproxy) {
/*
* This is a tunnel through a http proxy and we need to connect to the
* proxy again here. We already have the name info for it since the
* previous lookup.
*/
he = conn->hp;
connectport = data->port; /* we connect to the proxy's port */
}
else {
/* normal, direct, ftp connection */
he = GetHost(data, newhost, &hostdataptr);
if(!he) {
failf(data, "Can't resolve new host %s", newhost);
return CURLE_FTP_CANT_GET_HOST;
}
connectport = newport; /* we connect to the remote port */
}
data->secondarysocket = socket(AF_INET, SOCK_STREAM, 0);
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
memcpy((char *)&(serv_addr.sin_addr), he->h_addr, he->h_length);
serv_addr.sin_family = he->h_addrtype;
serv_addr.sin_port = htons(newport);
serv_addr.sin_port = htons(connectport);
if(data->bits.verbose) {
struct in_addr in;
@@ -815,13 +915,16 @@ CURLcode _ftp(struct connectdata *conn)
infof(data, "Connecting to %s (%s) port %u\n",
answer?answer->h_name:newhost,
#if defined(HAVE_INET_NTOA_R)
ip_addr = inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)),
inet_ntoa_r(in, ip_addr=ntoa_buf, sizeof(ntoa_buf)),
#else
ip_addr = inet_ntoa(in),
#endif
newport);
connectport);
}
if(hostdataptr)
free(hostdataptr);
if (connect(data->secondarysocket, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0) {
switch(errno) {
@@ -842,30 +945,23 @@ CURLcode _ftp(struct connectdata *conn)
}
return CURLE_FTP_CANT_RECONNECT;
}
}
if (data->bits.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
result = GetHTTPProxyTunnel(data, data->secondarysocket,
newhost, newport);
if(CURLE_OK != result)
return result;
}
}
}
/* we have the (new) data connection ready */
infof(data, "Connected!\n");
/* change directory first */
if(ftp->dir && ftp->dir[0]) {
sendf(data->firstsocket, data, "CWD %s\r\n", ftp->dir);
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
return CURLE_OPERATION_TIMEOUTED;
if(strncmp(buf, "250", 3)) {
failf(data, "Couldn't change to directory %s", ftp->dir);
return CURLE_FTP_ACCESS_DENIED;
}
}
infof(data, "Connected the data stream!\n");
if(data->bits.upload) {
/* Set type to binary (unless specified ASCII) */
sendf(data->firstsocket, data, "TYPE %s\r\n",
ftpsendf(data->firstsocket, conn, "TYPE %s",
(data->bits.ftp_ascii)?"A":"I");
nread = GetLastResponse(data->firstsocket, buf, conn);
@@ -897,7 +993,7 @@ CURLcode _ftp(struct connectdata *conn)
/* we could've got a specified offset from the command line,
but now we know we didn't */
sendf(data->firstsocket, data, "SIZE %s\r\n", ftp->file);
ftpsendf(data->firstsocket, conn, "SIZE %s", ftp->file);
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
@@ -920,7 +1016,7 @@ CURLcode _ftp(struct connectdata *conn)
infof(data, "Instructs server to resume from offset %d\n",
data->resume_from);
sendf(data->firstsocket, data, "REST %d\r\n", data->resume_from);
ftpsendf(data->firstsocket, conn, "REST %d", data->resume_from);
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
@@ -972,9 +1068,9 @@ CURLcode _ftp(struct connectdata *conn)
/* Send everything on data->in to the socket */
if(data->bits.ftp_append)
/* we append onto the file instead of rewriting it */
sendf(data->firstsocket, data, "APPE %s\r\n", ftp->file);
ftpsendf(data->firstsocket, conn, "APPE %s", ftp->file);
else
sendf(data->firstsocket, data, "STOR %s\r\n", ftp->file);
ftpsendf(data->firstsocket, conn, "STOR %s", ftp->file);
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
@@ -1060,7 +1156,7 @@ CURLcode _ftp(struct connectdata *conn)
dirlist = TRUE;
/* Set type to ASCII */
sendf(data->firstsocket, data, "TYPE A\r\n");
ftpsendf(data->firstsocket, conn, "TYPE A");
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
@@ -1075,13 +1171,13 @@ CURLcode _ftp(struct connectdata *conn)
better used since the LIST command output is not specified or
standard in any way */
sendf(data->firstsocket, data, "%s\r\n",
ftpsendf(data->firstsocket, conn, "%s",
data->customrequest?data->customrequest:
(data->bits.ftp_list_only?"NLST":"LIST"));
}
else {
/* Set type to binary (unless specified ASCII) */
sendf(data->firstsocket, data, "TYPE %s\r\n",
ftpsendf(data->firstsocket, conn, "TYPE %s",
(data->bits.ftp_list_only)?"A":"I");
nread = GetLastResponse(data->firstsocket, buf, conn);
@@ -1103,7 +1199,7 @@ CURLcode _ftp(struct connectdata *conn)
* of the file we're gonna get. If we can get the size, this is by far
* the best way to know if we're trying to resume beyond the EOF. */
sendf(data->firstsocket, data, "SIZE %s\r\n", ftp->file);
ftpsendf(data->firstsocket, conn, "SIZE %s", ftp->file);
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
@@ -1147,7 +1243,7 @@ CURLcode _ftp(struct connectdata *conn)
infof(data, "Instructs server to resume from offset %d\n",
data->resume_from);
sendf(data->firstsocket, data, "REST %d\r\n", data->resume_from);
ftpsendf(data->firstsocket, conn, "REST %d", data->resume_from);
nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0)
@@ -1159,7 +1255,7 @@ CURLcode _ftp(struct connectdata *conn)
}
}
sendf(data->firstsocket, data, "RETR %s\r\n", ftp->file);
ftpsendf(data->firstsocket, conn, "RETR %s", ftp->file);
}
nread = GetLastResponse(data->firstsocket, buf, conn);

View File

@@ -32,15 +32,18 @@
** This code is in the public domain and has no copyright.
*/
#define _REENTRANT /* Necessary to use in Solaris, since the silly guys at Sun
made the localtime_r() prototype dependent on it (or
_POSIX_C_SOURCE or _POSIX_PTHREAD_SEMANTICS). */
#ifdef HAVE_CONFIG_H
# include "config.h"
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# endif
# ifdef NEED_REENTRANT
# define _REENTRANT /* Necessary to use in Solaris, since the silly guys at
Sun made the localtime_r() prototype dependent on it
(or _POSIX_C_SOURCE or _POSIX_PTHREAD_SEMANTICS) */
# endif
# ifdef HAVE_TIME_H
# include <time.h>
# endif
@@ -219,7 +222,7 @@ static int yyRelSeconds;
static int yyRelYear;
#line 202 "getdate.y"
#line 205 "getdate.y"
typedef union {
int Number;
enum _MERIDIAN Meridian;
@@ -302,11 +305,11 @@ static const short yyrhs[] = { -1,
#if YYDEBUG != 0
static const short yyrline[] = { 0,
218, 219, 222, 225, 228, 231, 234, 237, 240, 246,
252, 261, 267, 279, 282, 285, 291, 295, 299, 305,
309, 327, 333, 339, 343, 348, 352, 359, 367, 370,
373, 376, 379, 382, 385, 388, 391, 394, 397, 400,
403, 406, 409, 412, 415, 418, 421, 426, 459, 463
221, 222, 225, 228, 231, 234, 237, 240, 243, 249,
255, 264, 270, 282, 285, 288, 294, 298, 302, 308,
312, 330, 336, 342, 346, 351, 355, 362, 370, 373,
376, 379, 382, 385, 388, 391, 394, 397, 400, 403,
406, 409, 412, 415, 418, 421, 424, 429, 462, 466
};
#endif
@@ -387,7 +390,7 @@ static const short yycheck[] = { 0,
56
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
#line 3 "/usr/local/share/bison.simple"
#line 3 "/opt/TWWfsw/bison/share/bison.simple"
/* This file comes from bison-1.28. */
/* Skeleton output parser for bison,
@@ -601,7 +604,7 @@ __yy_memcpy (char *to, char *from, unsigned int count)
#endif
#endif
#line 217 "/usr/local/share/bison.simple"
#line 217 "/opt/TWWfsw/bison/share/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@@ -930,37 +933,37 @@ yyreduce:
switch (yyn) {
case 3:
#line 222 "getdate.y"
#line 225 "getdate.y"
{
yyHaveTime++;
;
break;}
case 4:
#line 225 "getdate.y"
#line 228 "getdate.y"
{
yyHaveZone++;
;
break;}
case 5:
#line 228 "getdate.y"
#line 231 "getdate.y"
{
yyHaveDate++;
;
break;}
case 6:
#line 231 "getdate.y"
#line 234 "getdate.y"
{
yyHaveDay++;
;
break;}
case 7:
#line 234 "getdate.y"
#line 237 "getdate.y"
{
yyHaveRel++;
;
break;}
case 9:
#line 240 "getdate.y"
#line 243 "getdate.y"
{
yyHour = yyvsp[-1].Number;
yyMinutes = 0;
@@ -969,7 +972,7 @@ case 9:
;
break;}
case 10:
#line 246 "getdate.y"
#line 249 "getdate.y"
{
yyHour = yyvsp[-3].Number;
yyMinutes = yyvsp[-1].Number;
@@ -978,7 +981,7 @@ case 10:
;
break;}
case 11:
#line 252 "getdate.y"
#line 255 "getdate.y"
{
yyHour = yyvsp[-3].Number;
yyMinutes = yyvsp[-1].Number;
@@ -990,7 +993,7 @@ case 11:
;
break;}
case 12:
#line 261 "getdate.y"
#line 264 "getdate.y"
{
yyHour = yyvsp[-5].Number;
yyMinutes = yyvsp[-3].Number;
@@ -999,7 +1002,7 @@ case 12:
;
break;}
case 13:
#line 267 "getdate.y"
#line 270 "getdate.y"
{
yyHour = yyvsp[-5].Number;
yyMinutes = yyvsp[-3].Number;
@@ -1012,53 +1015,53 @@ case 13:
;
break;}
case 14:
#line 279 "getdate.y"
#line 282 "getdate.y"
{
yyTimezone = yyvsp[0].Number;
;
break;}
case 15:
#line 282 "getdate.y"
#line 285 "getdate.y"
{
yyTimezone = yyvsp[0].Number - 60;
;
break;}
case 16:
#line 286 "getdate.y"
#line 289 "getdate.y"
{
yyTimezone = yyvsp[-1].Number - 60;
;
break;}
case 17:
#line 291 "getdate.y"
#line 294 "getdate.y"
{
yyDayOrdinal = 1;
yyDayNumber = yyvsp[0].Number;
;
break;}
case 18:
#line 295 "getdate.y"
#line 298 "getdate.y"
{
yyDayOrdinal = 1;
yyDayNumber = yyvsp[-1].Number;
;
break;}
case 19:
#line 299 "getdate.y"
#line 302 "getdate.y"
{
yyDayOrdinal = yyvsp[-1].Number;
yyDayNumber = yyvsp[0].Number;
;
break;}
case 20:
#line 305 "getdate.y"
#line 308 "getdate.y"
{
yyMonth = yyvsp[-2].Number;
yyDay = yyvsp[0].Number;
;
break;}
case 21:
#line 309 "getdate.y"
#line 312 "getdate.y"
{
/* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY.
The goal in recognizing YYYY/MM/DD is solely to support legacy
@@ -1079,7 +1082,7 @@ case 21:
;
break;}
case 22:
#line 327 "getdate.y"
#line 330 "getdate.y"
{
/* ISO 8601 format. yyyy-mm-dd. */
yyYear = yyvsp[-2].Number;
@@ -1088,7 +1091,7 @@ case 22:
;
break;}
case 23:
#line 333 "getdate.y"
#line 336 "getdate.y"
{
/* e.g. 17-JUN-1992. */
yyDay = yyvsp[-2].Number;
@@ -1097,14 +1100,14 @@ case 23:
;
break;}
case 24:
#line 339 "getdate.y"
#line 342 "getdate.y"
{
yyMonth = yyvsp[-1].Number;
yyDay = yyvsp[0].Number;
;
break;}
case 25:
#line 343 "getdate.y"
#line 346 "getdate.y"
{
yyMonth = yyvsp[-3].Number;
yyDay = yyvsp[-2].Number;
@@ -1112,14 +1115,14 @@ case 25:
;
break;}
case 26:
#line 348 "getdate.y"
#line 351 "getdate.y"
{
yyMonth = yyvsp[0].Number;
yyDay = yyvsp[-1].Number;
;
break;}
case 27:
#line 352 "getdate.y"
#line 355 "getdate.y"
{
yyMonth = yyvsp[-1].Number;
yyDay = yyvsp[-2].Number;
@@ -1127,7 +1130,7 @@ case 27:
;
break;}
case 28:
#line 359 "getdate.y"
#line 362 "getdate.y"
{
yyRelSeconds = -yyRelSeconds;
yyRelMinutes = -yyRelMinutes;
@@ -1138,115 +1141,115 @@ case 28:
;
break;}
case 30:
#line 370 "getdate.y"
{
yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 31:
#line 373 "getdate.y"
{
yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 32:
case 31:
#line 376 "getdate.y"
{
yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 32:
#line 379 "getdate.y"
{
yyRelYear += yyvsp[0].Number;
;
break;}
case 33:
#line 379 "getdate.y"
{
yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 34:
#line 382 "getdate.y"
{
yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 35:
case 34:
#line 385 "getdate.y"
{
yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 35:
#line 388 "getdate.y"
{
yyRelMonth += yyvsp[0].Number;
;
break;}
case 36:
#line 388 "getdate.y"
{
yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 37:
#line 391 "getdate.y"
{
yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 38:
case 37:
#line 394 "getdate.y"
{
yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 38:
#line 397 "getdate.y"
{
yyRelDay += yyvsp[0].Number;
;
break;}
case 39:
#line 397 "getdate.y"
{
yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 40:
#line 400 "getdate.y"
{
yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 41:
case 40:
#line 403 "getdate.y"
{
yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 41:
#line 406 "getdate.y"
{
yyRelHour += yyvsp[0].Number;
;
break;}
case 42:
#line 406 "getdate.y"
{
yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 43:
#line 409 "getdate.y"
{
yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 44:
case 43:
#line 412 "getdate.y"
{
yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 44:
#line 415 "getdate.y"
{
yyRelMinutes += yyvsp[0].Number;
;
break;}
case 45:
#line 415 "getdate.y"
{
yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 46:
#line 418 "getdate.y"
{
yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 47:
case 46:
#line 421 "getdate.y"
{
yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
;
break;}
case 47:
#line 424 "getdate.y"
{
yyRelSeconds += yyvsp[0].Number;
;
break;}
case 48:
#line 427 "getdate.y"
#line 430 "getdate.y"
{
if (yyHaveTime && yyHaveDate && !yyHaveRel)
yyYear = yyvsp[0].Number;
@@ -1279,20 +1282,20 @@ case 48:
;
break;}
case 49:
#line 460 "getdate.y"
#line 463 "getdate.y"
{
yyval.Meridian = MER24;
;
break;}
case 50:
#line 464 "getdate.y"
#line 467 "getdate.y"
{
yyval.Meridian = yyvsp[0].Meridian;
;
break;}
}
/* the action file gets copied in in place of this dollarsign */
#line 543 "/usr/local/share/bison.simple"
#line 543 "/opt/TWWfsw/bison/share/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
@@ -1512,7 +1515,7 @@ yyerrhandle:
}
return 1;
}
#line 469 "getdate.y"
#line 472 "getdate.y"
/* Include this file down here because bison inserts code above which

View File

@@ -8,15 +8,18 @@
** This code is in the public domain and has no copyright.
*/
#define _REENTRANT /* Necessary to use in Solaris, since the silly guys at Sun
made the localtime_r() prototype dependent on it (or
_POSIX_C_SOURCE or _POSIX_PTHREAD_SEMANTICS). */
#ifdef HAVE_CONFIG_H
# include "config.h"
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# endif
# ifdef NEED_REENTRANT
# define _REENTRANT /* Necessary to use in Solaris, since the silly guys at
Sun made the localtime_r() prototype dependent on it
(or _POSIX_C_SOURCE or _POSIX_PTHREAD_SEMANTICS) */
# endif
# ifdef HAVE_TIME_H
# include <time.h>
# endif

View File

@@ -38,6 +38,8 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
@@ -49,7 +51,6 @@
#include <errno.h>
#include "setup.h"
#include "strequal.h"
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
@@ -171,7 +172,9 @@ _Transfer(struct connectdata *c_conn)
if(conn->size > 0)
pgrsSetDownloadSize(data, conn->size);
}
{
/* we want header and/or body, if neither then don't do this! */
if(conn->getheader ||
!data->bits.no_body) {
fd_set readfd;
fd_set writefd;
fd_set rkeepfd;

View File

@@ -38,10 +38,13 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
#include <string.h>
#include <malloc.h>
#include <errno.h>
#include "setup.h"
#define _REENTRANT
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
@@ -52,8 +55,12 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
@@ -62,9 +69,7 @@
#include "urldata.h"
#include "sendf.h"
#define _REENTRANT
#ifdef HAVE_INET_NTOA_R
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
#include "inet_ntoa_r.h"
#endif
@@ -98,11 +103,21 @@ char *MakeIP(unsigned long num,char *addr, int addr_len)
#endif
struct hostent *GetHost(struct UrlData *data,
char *hostname,
char *buf,
int buf_size )
char **bufp)
{
struct hostent *h = NULL;
unsigned long in;
int ret;
#define CURL_NAMELOOKUP_SIZE 9000
/* Allocate enough memory to hold the full name information structs and
* everything. OSF1 is known to require at least 8872 bytes. The buffer
* required for storing all possible aliases and IP numbers is according to
* Stevens' Unix Network Programming 2nd editor, p. 304: 8192 bytes! */
char *buf = (char *)malloc(CURL_NAMELOOKUP_SIZE);
if(!buf)
return NULL; /* major failure */
if ( (in=inet_addr(hostname)) != INADDR_NONE ) {
struct in_addr *addrentry;
@@ -117,18 +132,20 @@ struct hostent *GetHost(struct UrlData *data,
h->h_length = sizeof(*addrentry);
h->h_name = *(h->h_addr_list) + h->h_length;
/* bad one h->h_name = (char*)(h->h_addr_list + h->h_length); */
MakeIP(ntohl(in),h->h_name,buf_size - (long)(h->h_name) + (long)buf);
MakeIP(ntohl(in),h->h_name, CURL_NAMELOOKUP_SIZE - (long)(h->h_name) + (long)buf);
}
#if defined(HAVE_GETHOSTBYNAME_R)
else {
int h_errnop;
memset(buf,0,buf_size); /* workaround for gethostbyname_r bug in qnx nto */
/* Workaround for gethostbyname_r bug in qnx nto. It is also _required_
for some of these functions. */
memset(buf, 0, CURL_NAMELOOKUP_SIZE);
#ifdef HAVE_GETHOSTBYNAME_R_5
/* Solaris, IRIX and more */
if ((h = gethostbyname_r(hostname,
(struct hostent *)buf,
buf + sizeof(struct hostent),
buf_size - sizeof(struct hostent),
CURL_NAMELOOKUP_SIZE - sizeof(struct hostent),
&h_errnop)) == NULL )
#endif
#ifdef HAVE_GETHOSTBYNAME_R_6
@@ -136,30 +153,41 @@ struct hostent *GetHost(struct UrlData *data,
if( gethostbyname_r(hostname,
(struct hostent *)buf,
buf + sizeof(struct hostent),
buf_size - sizeof(struct hostent),
CURL_NAMELOOKUP_SIZE - sizeof(struct hostent),
&h, /* DIFFERENCE */
&h_errnop))
#endif
#ifdef HAVE_GETHOSTBYNAME_R_3
/* AIX, Digital Unix, HPUX 10, more? */
/* August 4th, 2000. I don't have any such system around so I write this
blindly in hope it might work or that someone else will help me fix
this. */
if(CURL_NAMELOOKUP_SIZE >=
(sizeof(struct hostent)+sizeof(struct hostent_data)))
h = gethostbyname_r(hostname,
(struct hostent *)buf,
(struct hostent_data *)(buf + sizeof(struct hostent)));
/* August 22nd, 2000: Albert Chin-A-Young brought an updated version
* that should work! September 20: Richard Prescott worked on the buffer
* size dilemma. */
ret = gethostbyname_r(hostname,
(struct hostent *)buf,
(struct hostent_data *)(buf + sizeof(struct hostent)));
else
ret = -1; /* failure, too smallish buffer size */
/* result expected in h */
h = (struct hostent*)buf;
h_errnop= errno; /* we don't deal with this, but set it anyway */
if(NULL == h)
if(ret)
#endif
{
infof(data, "gethostbyname_r(2) failed for %s\n", hostname);
h = NULL; /* set return code to NULL */
free(buf);
}
#else
else {
if ((h = gethostbyname(hostname)) == NULL ) {
infof(data, "gethostbyname(2) failed for %s\n", hostname);
free(buf);
}
#endif
}

View File

@@ -40,7 +40,6 @@
* ------------------------------------------------------------
****************************************************************************/
extern struct hostent *GetHost(struct UrlData *data, char *hostname, char *buf, int buf_size );
extern char *MakeIP(unsigned long num,char *addr, int addr_len);
struct hostent *GetHost(struct UrlData *data, char *hostname, char **bufp );
#endif

View File

@@ -38,9 +38,7 @@
* ------------------------------------------------------------
****************************************************************************/
#define _REENTRANT /* Necessary to use in Solaris, since the silly guys at Sun
made the localtime_r() prototype dependent on it (or
_POSIX_C_SOURCE or _POSIX_PTHREAD_SEMANTICS). */
#include "setup.h"
/* -- WIN32 approved -- */
#include <stdio.h>
@@ -53,7 +51,12 @@
#include <errno.h>
#include "setup.h"
#ifdef NEED_REENTRANT
#define _REENTRANT /* Necessary to use in Solaris, since the silly guys at Sun
made the localtime_r() prototype dependent on it (or
_POSIX_C_SOURCE or _POSIX_PTHREAD_SEMANTICS). */
#endif
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
@@ -63,7 +66,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#include <sys/time.h>
#ifdef HAVE_TIME_H
@@ -129,9 +134,58 @@ bool static checkheaders(struct UrlData *data, char *thisheader)
return FALSE;
}
/*
* GetHTTPProxyTunnel() requires that we're connected to a HTTP proxy. This
* function will issue the necessary commands to get a seamless tunnel through
* this proxy. After that, the socket can be used just as a normal socket.
*/
CURLcode GetHTTPProxyTunnel(struct UrlData *data, int tunnelsocket,
char *hostname, int remote_port)
{
int httperror=0;
int subversion=0;
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
/* OK, now send the connect statment */
sendf(tunnelsocket, data,
"CONNECT %s:%d HTTP/1.0\015\012"
"%s"
"%s"
"\r\n",
hostname, remote_port,
(data->bits.proxy_user_passwd)?data->ptr_proxyuserpwd:"",
(data->useragent?data->ptr_uagent:"")
);
/* wait for the proxy to send us a HTTP/1.0 200 OK header */
while(GetLine(tunnelsocket, data->buffer, data)) {
if('\r' == data->buffer[0])
break; /* end of headers */
if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
&subversion,
&httperror)) {
;
}
}
if(200 != httperror) {
if(407 == httperror)
/* Added Nov 6 1998 */
failf(data, "Proxy requires authorization!");
else
failf(data, "Received error code %d from proxy", httperror);
return CURLE_READ_ERROR;
}
infof (data, "Proxy replied to CONNECT request\n");
return CURLE_OK;
}
CURLcode http_connect(struct connectdata *conn)
{
struct UrlData *data;
CURLcode result;
data=conn->data;
@@ -141,59 +195,28 @@ CURLcode http_connect(struct connectdata *conn)
* us to the host we want to talk to. Only after the connect
* has occured, can we start talking SSL
*/
if (conn->protocol & PROT_HTTPS) {
if (data->bits.httpproxy) {
if (conn->protocol & PROT_HTTPS) {
if (data->bits.httpproxy) {
/* HTTPS through a proxy can only be done with a tunnel */
result = GetHTTPProxyTunnel(data, data->firstsocket,
data->hostname, data->remote_port);
if(CURLE_OK != result)
return result;
}
/* OK, now send the connect statment */
sendf(data->firstsocket, data,
"CONNECT %s:%d HTTP/1.0\015\012"
"%s"
"%s"
"\r\n",
data->hostname, data->remote_port,
(data->bits.proxy_user_passwd)?data->ptr_proxyuserpwd:"",
(data->useragent?data->ptr_uagent:"")
);
/* wait for the proxy to send us a HTTP/1.0 200 OK header */
/* Daniel rewrote this part Nov 5 1998 to make it more obvious */
{
int httperror=0;
int subversion=0;
while(GetLine(data->firstsocket, data->buffer, data)) {
if('\r' == data->buffer[0])
break; /* end of headers */
if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
&subversion,
&httperror)) {
;
}
}
if(200 != httperror) {
if(407 == httperror)
/* Added Nov 6 1998 */
failf(data, "Proxy requires authorization!");
else
failf(data, "Received error code %d from proxy", httperror);
return CURLE_READ_ERROR;
}
}
infof (data, "Proxy has replied to CONNECT request\n");
}
/* now, perform the SSL initialization for this socket */
if(UrgSSLConnect (data)) {
return CURLE_SSL_CONNECT_ERROR;
}
/* now, perform the SSL initialization for this socket */
if(UrgSSLConnect (data)) {
return CURLE_SSL_CONNECT_ERROR;
}
}
if(data->bits.user_passwd && !data->bits.this_is_a_follow) {
/* Authorization: is requested, this is not a followed location, get the
original host name */
data->auth_host = strdup(data->hostname);
}
if(data->bits.user_passwd && !data->bits.this_is_a_follow) {
/* Authorization: is requested, this is not a followed location, get the
original host name */
data->auth_host = strdup(data->hostname);
}
return CURLE_OK;
return CURLE_OK;
}
/* called from curl_close() when this struct is about to get wasted, free
@@ -264,7 +287,7 @@ CURLcode http(struct connectdata *conn)
}
if((data->bits.user_passwd) && !checkheaders(data, "Authorization:")) {
char authorization[512];
char *authorization;
/* To prevent the user+password to get sent to other than the original
host due to a location-follow, we do some weirdo checks here */
@@ -272,9 +295,12 @@ CURLcode http(struct connectdata *conn)
!data->auth_host ||
strequal(data->auth_host, data->hostname)) {
sprintf(data->buffer, "%s:%s", data->user, data->passwd);
base64Encode(data->buffer, authorization);
data->ptr_userpwd = maprintf( "Authorization: Basic %s\015\012",
authorization);
if(base64_encode(data->buffer, strlen(data->buffer),
&authorization) >= 0) {
data->ptr_userpwd = maprintf( "Authorization: Basic %s\015\012",
authorization);
free(authorization);
}
}
}
if((data->bits.set_range) && !checkheaders(data, "Range:")) {
@@ -374,7 +400,7 @@ CURLcode http(struct connectdata *conn)
#ifdef HAVE_LOCALTIME_R
/* thread-safe version */
struct tm keeptime;
thistime = localtime_r(&data->timevalue, &keeptime);
thistime = (struct tm *)localtime_r(&data->timevalue, &keeptime);
#else
thistime = localtime(&data->timevalue);
#endif
@@ -488,13 +514,19 @@ CURLcode http(struct connectdata *conn)
actually set your own */
sendf(data->firstsocket, data,
"Content-Length: %d\r\n",
strlen(data->postfields));
(data->postfieldsize?data->postfieldsize:
strlen(data->postfields)) );
if(!checkheaders(data, "Content-Type:"))
sendf(data->firstsocket, data,
"Content-Type: application/x-www-form-urlencoded\r\n");
/* and here comes the actual data */
if(data->postfieldsize) {
ssend(data->firstsocket, conn, "\r\n", 2);
ssend(data->firstsocket, conn, data->postfields, data->postfieldsize);
ssend(data->firstsocket, conn, "\r\n", 2);
}
sendf(data->firstsocket, data,
"\r\n"
"%s\r\n",

View File

@@ -41,8 +41,11 @@
* ------------------------------------------------------------
****************************************************************************/
/* protocol-specific functions set up to be called by the main engine */
/* ftp can use this as well */
CURLcode GetHTTPProxyTunnel(struct UrlData *data, int tunnelsocket,
char *hostname, int remote_port);
/* protocol-specific functions set up to be called by the main engine */
CURLcode http(struct connectdata *conn);
CURLcode http_done(struct connectdata *conn);
CURLcode http_connect(struct connectdata *conn);

View File

@@ -38,11 +38,12 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "setup.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -50,12 +51,19 @@
#if ! defined(WIN32) && ! defined(__BEOS__)
#ifdef NEED_REENTRANT
#define _REENTRANT
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <netinet/in.h>
#ifdef HAVE_SYS_TIME_H
/* This must be before net/if.h for AIX 3.2 to enjoy life */
@@ -75,7 +83,7 @@
#include <sys/sockio.h>
#endif
#ifdef HAVE_INET_NTOA_R
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
#include "inet_ntoa_r.h"
#endif

492
lib/krb4.c Normal file
View File

@@ -0,0 +1,492 @@
/* modified by Martin Hedenfalk <mhe@stacken.kth.se> for use in Curl
* last modified 2000-09-18
*/
/*
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "setup.h"
#ifdef KRB4
#include "security.h"
#include "base64_krb.h"
#include <stdlib.h>
#include <netdb.h>
#include <syslog.h>
#include <string.h>
#include <krb.h>
#ifdef FTP_SERVER
#define LOCAL_ADDR ctrl_addr
#define REMOTE_ADDR his_addr
#else
/*#define LOCAL_ADDR myctladdr***/
/*#define REMOTE_ADDR hisctladdr***/
#endif
/*extern struct sockaddr *LOCAL_ADDR, *REMOTE_ADDR;***/
#define LOCAL_ADDR (&local_addr)
#define REMOTE_ADDR (&conn->serv_addr)
#define myctladdr LOCAL_ADDR
#define hisctladdr REMOTE_ADDR
static struct sockaddr_in local_addr;
struct krb4_data {
des_cblock key;
des_key_schedule schedule;
char name[ANAME_SZ];
char instance[INST_SZ];
char realm[REALM_SZ];
};
#ifndef HAVE_STRLCPY
size_t
strlcpy (char *dst, const char *src, size_t dst_sz)
{
size_t n;
char *p;
for (p = dst, n = 0;
n + 1 < dst_sz && *src != '\0';
++p, ++src, ++n)
*p = *src;
*p = '\0';
if (*src == '\0')
return n;
else
return n + strlen (src);
}
#endif
static int
krb4_check_prot(void *app_data, int level)
{
if(level == prot_confidential)
return -1;
return 0;
}
static int
krb4_decode(void *app_data, void *buf, int len, int level,
struct connectdata *conn)
{
MSG_DAT m;
int e;
struct krb4_data *d = app_data;
if(level == prot_safe)
e = krb_rd_safe(buf, len, &d->key,
(struct sockaddr_in *)REMOTE_ADDR,
(struct sockaddr_in *)LOCAL_ADDR, &m);
else
e = krb_rd_priv(buf, len, d->schedule, &d->key,
(struct sockaddr_in *)REMOTE_ADDR,
(struct sockaddr_in *)LOCAL_ADDR, &m);
if(e){
syslog(LOG_ERR, "krb4_decode: %s", krb_get_err_text(e));
return -1;
}
memmove(buf, m.app_data, m.app_length);
return m.app_length;
}
static int
krb4_overhead(void *app_data, int level, int len)
{
return 31;
}
static int
krb4_encode(void *app_data, void *from, int length, int level, void **to,
struct connectdata *conn)
{
struct krb4_data *d = app_data;
*to = malloc(length + 31);
if(level == prot_safe)
return krb_mk_safe(from, *to, length, &d->key,
(struct sockaddr_in *)LOCAL_ADDR,
(struct sockaddr_in *)REMOTE_ADDR);
else if(level == prot_private)
return krb_mk_priv(from, *to, length, d->schedule, &d->key,
(struct sockaddr_in *)LOCAL_ADDR,
(struct sockaddr_in *)REMOTE_ADDR);
else
return -1;
}
#ifdef FTP_SERVER
static int
krb4_adat(void *app_data, void *buf, size_t len)
{
KTEXT_ST tkt;
AUTH_DAT auth_dat;
char *p;
int kerror;
u_int32_t cs;
char msg[35]; /* size of encrypted block */
int tmp_len;
struct krb4_data *d = app_data;
char inst[INST_SZ];
struct sockaddr_in *his_addr_sin = (struct sockaddr_in *)his_addr;
memcpy(tkt.dat, buf, len);
tkt.length = len;
k_getsockinst(0, inst, sizeof(inst));
kerror = krb_rd_req(&tkt, "ftp", inst,
his_addr_sin->sin_addr.s_addr, &auth_dat, "");
if(kerror == RD_AP_UNDEC){
k_getsockinst(0, inst, sizeof(inst));
kerror = krb_rd_req(&tkt, "rcmd", inst,
his_addr_sin->sin_addr.s_addr, &auth_dat, "");
}
if(kerror){
reply(535, "Error reading request: %s.", krb_get_err_text(kerror));
return -1;
}
memcpy(d->key, auth_dat.session, sizeof(d->key));
des_set_key(&d->key, d->schedule);
strlcpy(d->name, auth_dat.pname, sizeof(d->name));
strlcpy(d->instance, auth_dat.pinst, sizeof(d->instance));
strlcpy(d->realm, auth_dat.prealm, sizeof(d->instance));
cs = auth_dat.checksum + 1;
{
unsigned char tmp[4];
KRB_PUT_INT(cs, tmp, 4, sizeof(tmp));
tmp_len = krb_mk_safe(tmp, msg, 4, &d->key,
(struct sockaddr_in *)LOCAL_ADDR,
(struct sockaddr_in *)REMOTE_ADDR);
}
if(tmp_len < 0){
reply(535, "Error creating reply: %s.", strerror(errno));
return -1;
}
len = tmp_len;
if(base64_encode(msg, len, &p) < 0) {
reply(535, "Out of memory base64-encoding.");
return -1;
}
reply(235, "ADAT=%s", p);
sec_complete = 1;
free(p);
return 0;
}
static int
krb4_userok(void *app_data, char *user)
{
struct krb4_data *d = app_data;
return krb_kuserok(d->name, d->instance, d->realm, user);
}
struct sec_server_mech krb4_server_mech = {
"KERBEROS_V4",
sizeof(struct krb4_data),
NULL, /* init */
NULL, /* end */
krb4_check_prot,
krb4_overhead,
krb4_encode,
krb4_decode,
/* */
NULL,
krb4_adat,
NULL, /* pbsz */
NULL, /* ccc */
krb4_userok
};
#else /* FTP_SERVER */
static int
mk_auth(struct krb4_data *d, KTEXT adat,
char *service, char *host, int checksum)
{
int ret;
CREDENTIALS cred;
char sname[SNAME_SZ], inst[INST_SZ], realm[REALM_SZ];
strlcpy(sname, service, sizeof(sname));
strlcpy(inst, krb_get_phost(host), sizeof(inst));
strlcpy(realm, krb_realmofhost(host), sizeof(realm));
ret = krb_mk_req(adat, sname, inst, realm, checksum);
if(ret)
return ret;
strlcpy(sname, service, sizeof(sname));
strlcpy(inst, krb_get_phost(host), sizeof(inst));
strlcpy(realm, krb_realmofhost(host), sizeof(realm));
ret = krb_get_cred(sname, inst, realm, &cred);
memmove(&d->key, &cred.session, sizeof(des_cblock));
des_key_sched(&d->key, d->schedule);
memset(&cred, 0, sizeof(cred));
return ret;
}
static int
krb4_auth(void *app_data, struct connectdata *conn)
{
int ret;
char *p;
int len;
KTEXT_ST adat;
MSG_DAT msg_data;
int checksum;
u_int32_t cs;
struct krb4_data *d = app_data;
struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR;
struct sockaddr_in *remoteaddr = (struct sockaddr_in *)REMOTE_ADDR;
char *host = conn->hp->h_name;
size_t nread;
int l = sizeof(local_addr);
if(getsockname(conn->data->firstsocket, LOCAL_ADDR, &l) < 0)
perror("getsockname()");
checksum = getpid();
ret = mk_auth(d, &adat, "ftp", host, checksum);
if(ret == KDC_PR_UNKNOWN)
ret = mk_auth(d, &adat, "rcmd", host, checksum);
if(ret){
printf("%s\n", krb_get_err_text(ret));
return AUTH_CONTINUE;
}
#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM
if (krb_get_config_bool("nat_in_use")) {
struct in_addr natAddr;
if (krb_get_our_ip_for_realm(krb_realmofhost(host),
&natAddr) != KSUCCESS
&& krb_get_our_ip_for_realm(NULL, &natAddr) != KSUCCESS)
printf("Can't get address for realm %s\n",
krb_realmofhost(host));
else {
if (natAddr.s_addr != localaddr->sin_addr.s_addr) {
printf("Using NAT IP address (%s) for kerberos 4\n",
inet_ntoa(natAddr));
localaddr->sin_addr = natAddr;
/*
* This not the best place to do this, but it
* is here we know that (probably) NAT is in
* use!
*/
/*passivemode = 1;***/
/*printf("Setting: Passive mode on.\n");***/
}
}
}
#endif
/*printf("Local address is %s\n", inet_ntoa(localaddr->sin_addr));***/
/*printf("Remote address is %s\n", inet_ntoa(remoteaddr->sin_addr));***/
if(base64_encode(adat.dat, adat.length, &p) < 0) {
printf("Out of memory base64-encoding.\n");
return AUTH_CONTINUE;
}
/*ret = command("ADAT %s", p)*/
ftpsendf(conn->data->firstsocket, conn, "ADAT %s", p);
/* wait for feedback */
nread = GetLastResponse(conn->data->firstsocket,
conn->data->buffer, conn);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/-1;
free(p);
if(/*ret != COMPLETE*/conn->data->buffer[0] != '2'){
printf("Server didn't accept auth data.\n");
return AUTH_ERROR;
}
p = strstr(/*reply_string*/conn->data->buffer, "ADAT=");
if(!p){
printf("Remote host didn't send adat reply.\n");
return AUTH_ERROR;
}
p += 5;
len = base64_decode(p, adat.dat);
if(len < 0){
printf("Failed to decode base64 from server.\n");
return AUTH_ERROR;
}
adat.length = len;
ret = krb_rd_safe(adat.dat, adat.length, &d->key,
(struct sockaddr_in *)hisctladdr,
(struct sockaddr_in *)myctladdr, &msg_data);
if(ret){
printf("Error reading reply from server: %s.\n",
krb_get_err_text(ret));
return AUTH_ERROR;
}
krb_get_int(msg_data.app_data, &cs, 4, 0);
if(cs - checksum != 1){
printf("Bad checksum returned from server.\n");
return AUTH_ERROR;
}
return AUTH_OK;
}
struct sec_client_mech krb4_client_mech = {
"KERBEROS_V4",
sizeof(struct krb4_data),
NULL, /* init */
krb4_auth,
NULL, /* end */
krb4_check_prot,
krb4_overhead,
krb4_encode,
krb4_decode
};
#endif /* FTP_SERVER */
void krb_kauth(struct connectdata *conn)
{
int ret;
char buf[1024];
des_cblock key;
des_key_schedule schedule;
KTEXT_ST tkt, tktcopy;
char *name;
char *p;
int overbose;
char passwd[100];
int tmp;
size_t nread;
int save;
save = set_command_prot(conn, prot_private);
/*ret = command("SITE KAUTH %s", name);***/
ftpsendf(conn->data->firstsocket, conn,
"SITE KAUTH %s", conn->data->user);
/* wait for feedback */
nread = GetLastResponse(conn->data->firstsocket, conn->data->buffer, conn);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/;
if(/*ret != CONTINUE*/conn->data->buffer[0] != '3'){
/*verbose = overbose;***/
set_command_prot(conn, save);
/*code = -1;***/
return;
}
/*verbose = overbose;***/
p = strstr(/*reply_string***/conn->data->buffer, "T=");
if(!p){
printf("Bad reply from server.\n");
set_command_prot(conn, save);
/*code = -1;***/
return;
}
p += 2;
tmp = base64_decode(p, &tkt.dat);
if(tmp < 0){
printf("Failed to decode base64 in reply.\n");
set_command_prot(conn, save);
/*code = -1;***/
return;
}
tkt.length = tmp;
tktcopy.length = tkt.length;
p = strstr(/*reply_string***/conn->data->buffer, "P=");
if(!p){
printf("Bad reply from server.\n");
/*verbose = overbose;***/
set_command_prot(conn, save);
/*code = -1;***/
return;
}
name = p + 2;
for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
*p = 0;
#if 0
snprintf(buf, sizeof(buf), "Password for %s:", name);
if (des_read_pw_string (passwd, sizeof(passwd)-1, buf, 0))
*passwd = '\0';
des_string_to_key (passwd, &key);
#else
des_string_to_key (conn->data->passwd, &key);
#endif
des_key_sched(&key, schedule);
des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat,
tkt.length,
schedule, &key, DES_DECRYPT);
if (strcmp ((char*)tktcopy.dat + 8,
KRB_TICKET_GRANTING_TICKET) != 0) {
afs_string_to_key (passwd,
krb_realmofhost(/*hostname***/conn->hp->h_name),
&key);
des_key_sched (&key, schedule);
des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat,
tkt.length,
schedule, &key, DES_DECRYPT);
}
memset(key, 0, sizeof(key));
memset(schedule, 0, sizeof(schedule));
memset(passwd, 0, sizeof(passwd));
if(base64_encode(tktcopy.dat, tktcopy.length, &p) < 0) {
failf(conn->data, "Out of memory base64-encoding.\n");
set_command_prot(conn, save);
/*code = -1;***/
return;
}
memset (tktcopy.dat, 0, tktcopy.length);
/*ret = command("SITE KAUTH %s %s", name, p);***/
ftpsendf(conn->data->firstsocket, conn,
"SITE KAUTH %s %s", name, p);
/* wait for feedback */
nread = GetLastResponse(conn->data->firstsocket, conn->data->buffer, conn);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/;
free(p);
set_command_prot(conn, save);
}
#endif /* KRB4 */

View File

@@ -38,6 +38,8 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
@@ -48,8 +50,6 @@
#include <sys/stat.h>
#include <errno.h>
#include "setup.h"
#if defined(WIN32) && !defined(__GNUC__)
#else
# ifdef HAVE_UNISTD_H

View File

@@ -50,11 +50,12 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "setup.h"
#include "getenv.h"
#include "strequal.h"

View File

@@ -38,9 +38,10 @@
* ------------------------------------------------------------
****************************************************************************/
#include <string.h>
#include "setup.h"
#include <string.h>
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#if defined(__MINGW32__)
#include <winsock.h>
@@ -182,7 +183,7 @@ int pgrsUpdate(struct UrlData *data)
struct timeval now;
int result;
char max5[6][6];
char max5[6][10];
double dlpercen=0;
double ulpercen=0;
double total_percen=0;
@@ -190,12 +191,7 @@ int pgrsUpdate(struct UrlData *data)
double total_transfer;
double total_expected_transfer;
#define CURR_TIME 5
static double speeder[ CURR_TIME ];
static int speeder_c=0;
int nowindex = speeder_c% CURR_TIME;
int nowindex = data->progress.speeder_c% CURR_TIME;
int checkindex;
int count;
@@ -240,15 +236,19 @@ int pgrsUpdate(struct UrlData *data)
/* Let's do the "current speed" thing, which should use the fastest
of the dl/ul speeds */
speeder[ nowindex ] = data->progress.downloaded>data->progress.uploaded?
data->progress.speeder[ nowindex ] =
data->progress.downloaded>data->progress.uploaded?
data->progress.downloaded:data->progress.uploaded;
speeder_c++; /* increase */
count = ((speeder_c>=CURR_TIME)?CURR_TIME:speeder_c) - 1;
checkindex = (speeder_c>=CURR_TIME)?speeder_c%CURR_TIME:0;
data->progress.speeder_c++; /* increase */
count = ((data->progress.speeder_c>=CURR_TIME)?
CURR_TIME:data->progress.speeder_c) - 1;
checkindex = (data->progress.speeder_c>=CURR_TIME)?
data->progress.speeder_c%CURR_TIME:0;
/* find out the average speed the last CURR_TIME seconds */
data->progress.current_speed =
(speeder[nowindex]-speeder[checkindex])/(count?count:1);
(data->progress.speeder[nowindex]-
data->progress.speeder[checkindex])/(count?count:1);
if(data->progress.flags & PGRS_HIDE)
return 0;
@@ -283,6 +283,7 @@ int pgrsUpdate(struct UrlData *data)
total estimate! */
total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
/* If we have a total estimate, we can display that and the expected
time left */
if(total_estimate) {
@@ -328,5 +329,5 @@ int pgrsUpdate(struct UrlData *data)
max5data(data->progress.current_speed, max5[5]) /* current speed */
);
return 0;
return 0;
}

655
lib/security.c Normal file
View File

@@ -0,0 +1,655 @@
/* modified by Martin Hedenfalk <mhe@stacken.kth.se> for use in Curl
* last modified 2000-09-18
* Even more obscurified to merge better into libcurl by Daniel Stenberg.
*/
/*
* Copyright (c) 1998, 1999 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "setup.h"
#include <curl/mprintf.h>
#ifdef KRB4
#include "security.h"
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include "base64_krb.h"
#define min(a, b) ((a) < (b) ? (a) : (b))
static struct {
enum protection_level level;
const char *name;
} level_names[] = {
{ prot_clear, "clear" },
{ prot_safe, "safe" },
{ prot_confidential, "confidential" },
{ prot_private, "private" }
};
static const char *
level_to_name(enum protection_level level)
{
int i;
for(i = 0; i < sizeof(level_names) / sizeof(level_names[0]); i++)
if(level_names[i].level == level)
return level_names[i].name;
return "unknown";
}
#ifndef FTP_SERVER /* not used in server */
static enum protection_level
name_to_level(const char *name)
{
int i;
for(i = 0; i < sizeof(level_names) / sizeof(level_names[0]); i++)
if(!strncasecmp(level_names[i].name, name, strlen(name)))
return level_names[i].level;
return (enum protection_level)-1;
}
#endif
#ifdef FTP_SERVER
static struct sec_server_mech *mechs[] = {
#ifdef KRB5
&gss_server_mech,
#endif
#ifdef KRB4
&krb4_server_mech,
#endif
NULL
};
static struct sec_server_mech *mech;
#else
static struct sec_client_mech *mechs[] = {
#ifdef KRB5
&gss_client_mech,
#endif
#ifdef KRB4
&krb4_client_mech,
#endif
NULL
};
static struct sec_client_mech *mech;
#endif
int
sec_getc(struct connectdata *conn, FILE *F)
{
if(conn->sec_complete && conn->data_prot) {
char c;
if(sec_read(conn, fileno(F), &c, 1) <= 0)
return EOF;
return c;
} else
return getc(F);
}
static int
block_read(int fd, void *buf, size_t len)
{
unsigned char *p = buf;
int b;
while(len) {
b = read(fd, p, len);
if (b == 0)
return 0;
else if (b < 0)
return -1;
len -= b;
p += b;
}
return p - (unsigned char*)buf;
}
static int
block_write(int fd, void *buf, size_t len)
{
unsigned char *p = buf;
int b;
while(len) {
b = write(fd, p, len);
if(b < 0)
return -1;
len -= b;
p += b;
}
return p - (unsigned char*)buf;
}
static int
sec_get_data(struct connectdata *conn,
int fd, struct krb4buffer *buf, int level)
{
int len;
int b;
b = block_read(fd, &len, sizeof(len));
if (b == 0)
return 0;
else if (b < 0)
return -1;
len = ntohl(len);
buf->data = realloc(buf->data, len);
b = block_read(fd, buf->data, len);
if (b == 0)
return 0;
else if (b < 0)
return -1;
buf->size = (*mech->decode)(conn->app_data, buf->data, len,
conn->data_prot, conn);
buf->index = 0;
return 0;
}
static size_t
buffer_read(struct krb4buffer *buf, void *data, size_t len)
{
len = min(len, buf->size - buf->index);
memcpy(data, (char*)buf->data + buf->index, len);
buf->index += len;
return len;
}
static size_t
buffer_write(struct krb4buffer *buf, void *data, size_t len)
{
if(buf->index + len > buf->size) {
void *tmp;
if(buf->data == NULL)
tmp = malloc(1024);
else
tmp = realloc(buf->data, buf->index + len);
if(tmp == NULL)
return -1;
buf->data = tmp;
buf->size = buf->index + len;
}
memcpy((char*)buf->data + buf->index, data, len);
buf->index += len;
return len;
}
int
sec_read(struct connectdata *conn, int fd, void *buffer, int length)
{
size_t len;
int rx = 0;
if(conn->sec_complete == 0 || conn->data_prot == 0)
return read(fd, buffer, length);
if(conn->in_buffer.eof_flag){
conn->in_buffer.eof_flag = 0;
return 0;
}
len = buffer_read(&conn->in_buffer, buffer, length);
length -= len;
rx += len;
buffer = (char*)buffer + len;
while(length) {
if(sec_get_data(conn, fd, &conn->in_buffer, conn->data_prot) < 0)
return -1;
if(conn->in_buffer.size == 0) {
if(rx)
conn->in_buffer.eof_flag = 1;
return rx;
}
len = buffer_read(&conn->in_buffer, buffer, length);
length -= len;
rx += len;
buffer = (char*)buffer + len;
}
return rx;
}
static int
sec_send(struct connectdata *conn, int fd, char *from, int length)
{
int bytes;
void *buf;
bytes = (*mech->encode)(conn->app_data, from, length, conn->data_prot, &buf, conn);
bytes = htonl(bytes);
block_write(fd, &bytes, sizeof(bytes));
block_write(fd, buf, ntohl(bytes));
free(buf);
return length;
}
int
sec_fflush(struct connectdata *conn, FILE *F)
{
if(conn->data_prot != prot_clear) {
if(conn->out_buffer.index > 0){
sec_write(conn, fileno(F),
conn->out_buffer.data, conn->out_buffer.index);
conn->out_buffer.index = 0;
}
sec_send(conn, fileno(F), NULL, 0);
}
fflush(F);
return 0;
}
int
sec_fflush_fd(struct connectdata *conn, int fd)
{
if(conn->data_prot != prot_clear) {
if(conn->out_buffer.index > 0){
sec_write(conn, fd,
conn->out_buffer.data, conn->out_buffer.index);
conn->out_buffer.index = 0;
}
sec_send(conn, fd, NULL, 0);
}
return 0;
}
int
sec_write(struct connectdata *conn, int fd, char *buffer, int length)
{
int len = conn->buffer_size;
int tx = 0;
if(conn->data_prot == prot_clear)
return write(fd, buffer, length);
len -= (*mech->overhead)(conn->app_data, conn->data_prot, len);
while(length){
if(length < len)
len = length;
sec_send(conn, fd, buffer, len);
length -= len;
buffer += len;
tx += len;
}
return tx;
}
int
sec_vfprintf2(struct connectdata *conn, FILE *f, const char *fmt, va_list ap)
{
char *buf;
int ret;
if(conn->data_prot == prot_clear)
return vfprintf(f, fmt, ap);
else {
buf = maprintf(fmt, ap);
ret = buffer_write(&conn->out_buffer, buf, strlen(buf));
free(buf);
return ret;
}
}
int
sec_fprintf2(struct connectdata *conn, FILE *f, const char *fmt, ...)
{
int ret;
va_list ap;
va_start(ap, fmt);
ret = sec_vfprintf2(conn, f, fmt, ap);
va_end(ap);
return ret;
}
int
sec_putc(struct connectdata *conn, int c, FILE *F)
{
char ch = c;
if(conn->data_prot == prot_clear)
return putc(c, F);
buffer_write(&conn->out_buffer, &ch, 1);
if(c == '\n' || conn->out_buffer.index >= 1024 /* XXX */) {
sec_write(conn, fileno(F), conn->out_buffer.data, conn->out_buffer.index);
conn->out_buffer.index = 0;
}
return c;
}
int
sec_read_msg(struct connectdata *conn, char *s, int level)
{
int len;
char *buf;
int code;
buf = malloc(strlen(s));
len = base64_decode(s + 4, buf); /* XXX */
len = (*mech->decode)(conn->app_data, buf, len, level, conn);
if(len < 0)
return -1;
buf[len] = '\0';
if(buf[3] == '-')
code = 0;
else
sscanf(buf, "%d", &code);
if(buf[len-1] == '\n')
buf[len-1] = '\0';
strcpy(s, buf);
free(buf);
return code;
}
/* modified to return how many bytes written, or -1 on error ***/
int
sec_vfprintf(struct connectdata *conn, FILE *f, const char *fmt, va_list ap)
{
int ret = 0;
char *buf;
void *enc;
int len;
if(!conn->sec_complete)
return vfprintf(f, fmt, ap);
buf = maprintf(fmt, ap);
len = (*mech->encode)(conn->app_data, buf, strlen(buf),
conn->command_prot, &enc,
conn);
free(buf);
if(len < 0) {
failf(conn->data, "Failed to encode command.\n");
return -1;
}
if(base64_encode(enc, len, &buf) < 0){
failf(conn->data, "Out of memory base64-encoding.\n");
return -1;
}
#ifdef FTP_SERVER
if(command_prot == prot_safe)
fprintf(f, "631 %s\r\n", buf);
else if(command_prot == prot_private)
fprintf(f, "632 %s\r\n", buf);
else if(command_prot == prot_confidential)
fprintf(f, "633 %s\r\n", buf);
#else
if(conn->command_prot == prot_safe)
ret = fprintf(f, "MIC %s", buf);
else if(conn->command_prot == prot_private)
ret = fprintf(f, "ENC %s", buf);
else if(conn->command_prot == prot_confidential)
ret = fprintf(f, "CONF %s", buf);
#endif
free(buf);
return ret;
}
int
sec_fprintf(struct connectdata *conn, FILE *f, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = sec_vfprintf(conn, f, fmt, ap);
va_end(ap);
return ret;
}
/* end common stuff */
#ifdef FTP_SERVER
/* snip */
#else /* FTP_SERVER */
#if 0
void
sec_status(void)
{
if(conn->sec_complete){
printf("Using %s for authentication.\n", mech->name);
printf("Using %s command channel.\n", level_to_name(command_prot));
printf("Using %s data channel.\n", level_to_name(data_prot));
if(buffer_size > 0)
printf("Protection buffer size: %lu.\n",
(unsigned long)buffer_size);
}else{
printf("Not using any security mechanism.\n");
}
}
#endif
static int
sec_prot_internal(struct connectdata *conn, int level)
{
int ret;
char *p;
unsigned int s = 1048576;
size_t nread;
if(!conn->sec_complete){
infof(conn->data, "No security data exchange has taken place.\n");
return -1;
}
if(level){
ftpsendf(conn->data->firstsocket, conn,
"PBSZ %u", s);
/* wait for feedback */
nread = GetLastResponse(conn->data->firstsocket,
conn->data->buffer, conn);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/-1;
if(/*ret != COMPLETE*/conn->data->buffer[0] != '2'){
failf(conn->data, "Failed to set protection buffer size.\n");
return -1;
}
conn->buffer_size = s;
p = strstr(/*reply_string*/conn->data->buffer, "PBSZ=");
if(p)
sscanf(p, "PBSZ=%u", &s);
if(s < conn->buffer_size)
conn->buffer_size = s;
}
ftpsendf(conn->data->firstsocket, conn,
"PROT %c", level["CSEP"]);
/* wait for feedback */
nread = GetLastResponse(conn->data->firstsocket,
conn->data->buffer, conn);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/-1;
if(/*ret != COMPLETE*/conn->data->buffer[0] != '2'){
failf(conn->data, "Failed to set protection level.\n");
return -1;
}
conn->data_prot = (enum protection_level)level;
return 0;
}
enum protection_level
set_command_prot(struct connectdata *conn, enum protection_level level)
{
enum protection_level old = conn->command_prot;
conn->command_prot = level;
return old;
}
#if 0
void
sec_prot(int argc, char **argv)
{
int level = -1;
if(argc < 2 || argc > 3)
goto usage;
if(!sec_complete) {
printf("No security data exchange has taken place.\n");
code = -1;
return;
}
level = name_to_level(argv[argc - 1]);
if(level == -1)
goto usage;
if((*mech->check_prot)(conn->app_data, level)) {
printf("%s does not implement %s protection.\n",
mech->name, level_to_name(level));
code = -1;
return;
}
if(argc == 2 || strncasecmp(argv[1], "data", strlen(argv[1])) == 0) {
if(sec_prot_internal(level) < 0){
code = -1;
return;
}
} else if(strncasecmp(argv[1], "command", strlen(argv[1])) == 0)
set_command_prot(level);
else
goto usage;
code = 0;
return;
usage:
printf("usage: %s [command|data] [clear|safe|confidential|private]\n",
argv[0]);
code = -1;
}
#endif
void
sec_set_protection_level(struct connectdata *conn)
{
if(conn->sec_complete && conn->data_prot != conn->request_data_prot)
sec_prot_internal(conn, conn->request_data_prot);
}
int
sec_request_prot(struct connectdata *conn, char *level)
{
int l = name_to_level(level);
if(l == -1)
return -1;
conn->request_data_prot = (enum protection_level)l;
return 0;
}
int
sec_login(struct connectdata *conn)
{
int ret;
struct sec_client_mech **m;
size_t nread;
struct UrlData *data=conn->data;
for(m = mechs; *m && (*m)->name; m++) {
void *tmp;
tmp = realloc(conn->app_data, (*m)->size);
if (tmp == NULL) {
failf (data, "realloc %u failed", (*m)->size);
return -1;
}
conn->app_data = tmp;
if((*m)->init && (*(*m)->init)(conn->app_data) != 0) {
infof(data, "Skipping %s...\n", (*m)->name);
continue;
}
infof(data, "Trying %s...\n", (*m)->name);
/*ret = command("AUTH %s", (*m)->name);***/
ftpsendf(conn->data->firstsocket, conn,
"AUTH %s", (*m)->name);
/* wait for feedback */
nread = GetLastResponse(conn->data->firstsocket,
conn->data->buffer, conn);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/-1;
if(/*ret != CONTINUE*/conn->data->buffer[0] != '3'){
if(/*code == 504*/strncmp(conn->data->buffer,"504",3) == 0) {
infof(data,
"%s is not supported by the server.\n", (*m)->name);
}
else if(/*code == 534*/strncmp(conn->data->buffer,"534",3) == 0) {
infof(data, "%s rejected as security mechanism.\n", (*m)->name);
}
else if(/*ret == ERROR*/conn->data->buffer[0] == '5') {
infof(data, "The server doesn't support the FTP "
"security extensions.\n");
return -1;
}
continue;
}
ret = (*(*m)->auth)(conn->app_data, /*host***/conn);
if(ret == AUTH_CONTINUE)
continue;
else if(ret != AUTH_OK){
/* mechanism is supposed to output error string */
return -1;
}
mech = *m;
conn->sec_complete = 1;
conn->command_prot = prot_safe;
break;
}
return *m == NULL;
}
void
sec_end(struct connectdata *conn)
{
if (mech != NULL) {
if(mech->end)
(*mech->end)(conn->app_data);
memset(conn->app_data, 0, mech->size);
free(conn->app_data);
conn->app_data = NULL;
}
conn->sec_complete = 0;
conn->data_prot = (enum protection_level)0;
}
#endif /* FTP_SERVER */
#endif /* KRB4 */

134
lib/security.h Normal file
View File

@@ -0,0 +1,134 @@
/* modified by Martin Hedenfalk <mhe@stacken.kth.se> for use in Curl
* last modified 2000-09-18
*/
/*
* Copyright (c) 1998, 1999 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* $Id$ */
#ifndef __security_h__
#define __security_h__
#include <stdarg.h>
#include "urldata.h" /* for struct connectdata * */
struct sec_client_mech {
char *name;
size_t size;
int (*init)(void *);
int (*auth)(void *, struct connectdata *);
void (*end)(void *);
int (*check_prot)(void *, int);
int (*overhead)(void *, int, int);
int (*encode)(void *, void*, int, int, void**, struct connectdata *);
int (*decode)(void *, void*, int, int, struct connectdata *);
};
struct sec_server_mech {
char *name;
size_t size;
int (*init)(void *);
void (*end)(void *);
int (*check_prot)(void *, int);
int (*overhead)(void *, int, int);
int (*encode)(void *, void*, int, int, void**);
int (*decode)(void *, void*, int, int);
int (*auth)(void *);
int (*adat)(void *, void*, size_t);
size_t (*pbsz)(void *, size_t);
int (*ccc)(void*);
int (*userok)(void*, char*);
};
#define AUTH_OK 0
#define AUTH_CONTINUE 1
#define AUTH_ERROR 2
#ifdef FTP_SERVER
extern struct sec_server_mech krb4_server_mech, gss_server_mech;
#else
extern struct sec_client_mech krb4_client_mech, gss_client_mech;
#endif
extern int sec_complete;
#ifdef FTP_SERVER
extern char *ftp_command;
void new_ftp_command(char*);
void delete_ftp_command(void);
#endif
/* ---- */
int sec_fflush (struct connectdata *conn, FILE *);
int sec_fflush_fd(struct connectdata *conn, int fd);
int sec_fprintf (struct connectdata *, FILE *, const char *, ...);
int sec_getc (struct connectdata *conn, FILE *);
int sec_putc (struct connectdata *conn, int, FILE *);
int sec_read (struct connectdata *conn, int, void *, int);
int sec_read_msg (struct connectdata *conn, char *, int);
int sec_vfprintf(struct connectdata *, FILE *, const char *, va_list);
int sec_fprintf2(struct connectdata *conn, FILE *f, const char *fmt, ...);
int sec_vfprintf2(struct connectdata *conn, FILE *, const char *, va_list);
int sec_write (struct connectdata *conn, int, char *, int);
#ifdef FTP_SERVER
void adat (char *);
void auth (char *);
void ccc (void);
void mec (char *, enum protection_level);
void pbsz (int);
void prot (char *);
void delete_ftp_command (void);
void new_ftp_command (char *);
int sec_userok (char *);
int secure_command (void);
enum protection_level get_command_prot(void);
#else
void sec_end (struct connectdata *);
int sec_login (struct connectdata *);
void sec_prot (int, char **);
int sec_request_prot (struct connectdata *conn, char *);
void sec_set_protection_level(struct connectdata *conn);
void sec_status (void);
enum protection_level set_command_prot(struct connectdata *,
enum protection_level);
#endif
#endif /* __security_h__ */

View File

@@ -38,12 +38,12 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include "setup.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -56,6 +56,11 @@
#include <curl/mprintf.h>
#ifdef KRB4
#include "security.h"
#include <string.h>
#endif
/* infof() is for info message along the way */
void infof(struct UrlData *data, char *fmt, ...)
@@ -84,7 +89,6 @@ void failf(struct UrlData *data, char *fmt, ...)
}
/* sendf() sends the formated data to the server */
int sendf(int fd, struct UrlData *data, char *fmt, ...)
{
size_t bytes_written;
@@ -97,9 +101,10 @@ int sendf(int fd, struct UrlData *data, char *fmt, ...)
return 0; /* failure */
if(data->bits.verbose)
fprintf(data->err, "> %s", s);
#ifndef USE_SSLEAY
bytes_written = swrite(fd, s, strlen(s));
#else
bytes_written = swrite(fd, s, strlen(s));
#else /* USE_SSLEAY */
if (data->use_ssl) {
bytes_written = SSL_write(data->ssl, s, strlen(s));
} else {
@@ -110,6 +115,68 @@ int sendf(int fd, struct UrlData *data, char *fmt, ...)
return(bytes_written);
}
/*
* ftpsendf() sends the formated string as a ftp command to a ftp server
*/
int ftpsendf(int fd, struct connectdata *conn, char *fmt, ...)
{
size_t bytes_written;
char *s;
va_list ap;
va_start(ap, fmt);
s = mvaprintf(fmt, ap);
va_end(ap);
if(!s)
return 0; /* failure */
if(conn->data->bits.verbose)
fprintf(conn->data->err, "> %s\n", s);
#ifdef KRB4
if(conn->sec_complete && conn->data->cmdchannel) {
bytes_written = sec_fprintf(conn, conn->data->cmdchannel, s);
bytes_written += fprintf(conn->data->cmdchannel, "\r\n");
fflush(conn->data->cmdchannel);
}
else
#endif /* KRB4 */
{
bytes_written = swrite(fd, s, strlen(s));
bytes_written += swrite(fd, "\r\n", 2);
}
free(s); /* free the output string */
return(bytes_written);
}
/* ssend() sends plain (binary) data to the server */
size_t ssend(int fd, struct connectdata *conn, void *mem, size_t len)
{
size_t bytes_written;
struct UrlData *data=conn->data; /* conn knows data, not vice versa */
if(data->bits.verbose)
fprintf(data->err, "> [binary output]\n");
#ifdef USE_SSLEAY
if (data->use_ssl) {
bytes_written = SSL_write(data->ssl, mem, len);
}
else {
#endif
#ifdef KRB4
if(conn->sec_complete) {
bytes_written = sec_write(conn, fd, mem, len);
}
else
#endif /* KRB4 */
bytes_written = swrite(fd, mem, len);
#ifdef USE_SSLEAY
}
#endif
return bytes_written;
}

View File

@@ -40,7 +40,9 @@
* ------------------------------------------------------------
****************************************************************************/
int sendf(int fd, struct UrlData *, char *fmt, ...);
size_t ftpsendf(int fd, struct connectdata *, char *fmt, ...);
size_t sendf(int fd, struct UrlData *, char *fmt, ...);
size_t ssend(int fd, struct connectdata *, void *fmt, size_t len);
void infof(struct UrlData *, char *fmt, ...);
void failf(struct UrlData *, char *fmt, ...);

View File

@@ -40,7 +40,7 @@
* ------------------------------------------------------------
****************************************************************************/
#include <stdio.h>
#if !defined(WIN32) && defined(_WIN32)
/* This _might_ be a good Borland fix. Please report whether this works or
@@ -57,6 +57,7 @@
#endif
#endif
#include <stdio.h>
#ifndef OS
#ifdef WIN32
#define OS "win32"

View File

@@ -38,6 +38,8 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
#include <stdio.h>
#if defined(__MINGW32__)
#include <winsock.h>

View File

@@ -43,7 +43,7 @@
* Linas Vepstas <linas@linas.org> and Sampo Kellomaki <sampo@iki.fi>
*/
#include "setup.h"
#include <string.h>
#include <stdlib.h>
@@ -265,28 +265,25 @@ UrgSSLConnect (struct UrlData *data)
failf(data, "SSL: couldn't get X509-subject!");
return 4;
}
infof (data, "\t subject: %s\n", str);
Free (str);
infof(data, "\t subject: %s\n", str);
CRYPTO_free(str);
str = X509_NAME_oneline (X509_get_issuer_name (data->server_cert), NULL, 0);
if(!str) {
failf(data, "SSL: couldn't get X509-issuer name!");
return 5;
}
infof (data, "\t issuer: %s\n", str);
Free (str);
infof(data, "\t issuer: %s\n", str);
CRYPTO_free(str);
/* We could do all sorts of certificate verification stuff here before
deallocating the certificate. */
#if SSL_VERIFY_CERT
infof(data, "Verify result: %d\n", SSL_get_verify_result(data->ssl));
#endif
X509_free (data->server_cert);
X509_free(data->server_cert);
#else /* USE_SSLEAY */
/* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
(void) data;

View File

@@ -38,10 +38,10 @@
* ------------------------------------------------------------
****************************************************************************/
#include <string.h>
#include "setup.h"
#include <string.h>
int strequal(const char *first, const char *second)
{
#if defined(HAVE_STRCASECMP)

View File

@@ -46,6 +46,8 @@
*
****************************************************************************/
#include "setup.h"
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
@@ -57,8 +59,6 @@
#include <errno.h>
#include "setup.h"
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
#include <time.h>

View File

@@ -40,6 +40,8 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <time.h>
#include <winsock.h>
@@ -47,7 +49,6 @@
#include <sys/time.h>
#endif
#include "setup.h"
#ifndef HAVE_GETTIMEOFDAY
#if !defined(_WINSOCKAPI_) && !defined(__MINGW32__)

245
lib/url.c
View File

@@ -39,6 +39,9 @@
****************************************************************************/
/* -- WIN32 approved -- */
#include "setup.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
@@ -49,8 +52,6 @@
#include <errno.h>
#include "setup.h"
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
#include <time.h>
@@ -123,6 +124,10 @@
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#ifdef KRB4
#include "security.h"
#endif
/* -- -- */
@@ -421,6 +426,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
case CURLOPT_POSTFIELDS:
data->postfields = va_arg(param, char *);
break;
case CURLOPT_POSTFIELDSIZE:
data->postfieldsize = va_arg(param, long);
break;
case CURLOPT_REFERER:
data->referer = va_arg(param, char *);
data->bits.http_set_referer = (data->referer && *data->referer)?1:0;
@@ -432,6 +440,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
data->proxy = va_arg(param, char *);
data->bits.httpproxy = data->proxy?1:0;
break;
case CURLOPT_HTTPPROXYTUNNEL:
data->bits.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_PROXYPORT:
data->proxyport = va_arg(param, long);
break;
@@ -490,6 +501,13 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
case CURLOPT_QUOTE:
data->quote = va_arg(param, struct curl_slist *);
break;
case CURLOPT_INTERFACE:
data->device = va_arg(param, char *);
break;
case CURLOPT_KRB4LEVEL:
data->krb4_level = va_arg(param, char *);
data->bits.krb4=data->krb4_level?TRUE:FALSE;
break;
default:
/* unknown tag and its companion, just ignore: */
return CURLE_READ_ERROR; /* correct this */
@@ -566,7 +584,12 @@ CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount,
}
else {
#endif
bytes_written = swrite(conn->writesockfd, buf, amount);
#ifdef KRB4
if(conn->sec_complete)
bytes_written = sec_write(conn, conn->writesockfd, buf, amount);
else
#endif
bytes_written = swrite(conn->writesockfd, buf, amount);
#ifdef USE_SSLEAY
}
#endif /* USE_SSLEAY */
@@ -592,7 +615,12 @@ CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize,
}
else {
#endif
nread = sread (conn->sockfd, buf, buffersize);
#ifdef KRB4
if(conn->sec_complete)
nread = sec_read(conn, conn->sockfd, buf, buffersize);
else
#endif
nread = sread (conn->sockfd, buf, buffersize);
#ifdef USE_SSLEAY
}
#endif /* USE_SSLEAY */
@@ -606,6 +634,9 @@ CURLcode curl_disconnect(CURLconnect *c_connect)
struct UrlData *data = conn->data;
if(conn->hostent_buf) /* host name info */
free(conn->hostent_buf);
free(conn); /* free the connection oriented data */
/* clean up the sockets and SSL stuff from the previous "round" */
@@ -614,6 +645,7 @@ CURLcode curl_disconnect(CURLconnect *c_connect)
return CURLE_OK;
}
/*
* NAME curl_connect()
*
@@ -641,12 +673,6 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
struct UrlData *data = curl;
struct connectdata *conn;
/* I believe the longest possible name in a DNS is set to 255 letters, FQDN.
Although the buffer required for storing all possible aliases and IP
numbers is according to Stevens' Unix Network Programming 2nd editor,
p. 304: 8192 bytes. Let's go with that! */
char hostent_buf[8192];
if(!data || (data->handle != STRUCT_OPEN))
return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */
@@ -943,7 +969,10 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
data->remote_port = PORT_FTP;
conn->protocol |= PROT_FTP;
if(data->bits.httpproxy) {
if(data->bits.httpproxy &&
!data->bits.tunnel_thru_httpproxy) {
/* Unless we have asked to tunnel ftp operations through the proxy, we
switch and use HTTP operations only */
conn->curl_do = http;
conn->curl_done = http_done;
conn->curl_close = http_close;
@@ -1013,6 +1042,11 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
conn->curl_do = file;
/* no done() function */
result = Transfer(conn, -1, -1, FALSE, NULL, /* no download */
-1, NULL); /* no upload */
return CURLE_OK;
}
else {
@@ -1087,7 +1121,8 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
}
/* Connect to target host right on */
if(!(conn->hp = GetHost(data, conn->name, hostent_buf, sizeof(hostent_buf)))) {
conn->hp = GetHost(data, conn->name, &conn->hostent_buf);
if(!conn->hp) {
failf(data, "Couldn't resolv host '%s'", conn->name);
return CURLE_COULDNT_RESOLVE_HOST;
}
@@ -1142,7 +1177,8 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
}
/* connect to proxy */
if(!(conn->hp = GetHost(data, proxyptr, hostent_buf, sizeof(hostent_buf)))) {
conn->hp = GetHost(data, proxyptr, &conn->hostent_buf);
if(!conn->hp) {
failf(data, "Couldn't resolv proxy '%s'", proxyptr);
return CURLE_COULDNT_RESOLVE_PROXY;
}
@@ -1159,6 +1195,138 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
conn->serv_addr.sin_family = conn->hp->h_addrtype;
conn->serv_addr.sin_port = htons(data->port);
/* sck 8/31/2000 add support for specifing device to bind socket to */
/* #ifdef LINUX */
/* I am using this, but it may not work everywhere, only tested on RedHat 6.2 */
#ifdef HAVE_INET_NTOA
#ifndef INADDR_NONE
#define INADDR_NONE (unsigned long) ~0
#endif
if (data->device && (strlen(data->device)<255)) {
struct ifreq ifr;
struct sockaddr_in sa;
struct hostent *h=NULL;
char *hostdataptr;
size_t size;
unsigned short porttouse;
char myhost[256] = "";
unsigned long in;
if(if2ip(data->device, myhost, sizeof(myhost))) {
h = GetHost(data, myhost, &hostdataptr);
}
else {
if(strlen(data->device)>1) {
h = GetHost(data, data->device, &hostdataptr);
}
if(h) {
/* we know data->device is shorter than the myhost array */
strcpy(myhost, data->device);
}
}
if(! *myhost) {
/* need to fix this
h=GetHost(data,
getmyhost(*myhost,sizeof(myhost)),
hostent_buf,
sizeof(hostent_buf));
*/
printf("in here\n");
}
infof(data, "We connect from %s\n", myhost);
if ( (in=inet_addr(myhost)) != INADDR_NONE ) {
if ( h ) {
memset((char *)&sa, 0, sizeof(sa));
memcpy((char *)&sa.sin_addr,
h->h_addr,
h->h_length);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = in;
sa.sin_port = 0; /* get any port */
if( bind(data->firstsocket, (struct sockaddr *)&sa, sizeof(sa)) >= 0) {
/* we succeeded to bind */
struct sockaddr_in add;
size = sizeof(add);
if(getsockname(data->firstsocket, (struct sockaddr *) &add,
(int *)&size)<0) {
failf(data, "getsockname() failed");
return CURLE_HTTP_PORT_FAILED;
}
}
else {
switch(errno) {
case EBADF:
failf(data, "Invalid descriptor: %d", errno);
break;
case EINVAL:
failf(data, "Invalid request: %d", errno);
break;
case EACCES:
failf(data, "Address is protected, user not superuser: %d", errno);
break;
case ENOTSOCK:
failf(data,
"Argument is a descriptor for a file, not a socket: %d",
errno);
break;
case EFAULT:
failf(data, "Inaccessable memory error: %d", errno);
break;
case ENAMETOOLONG:
failf(data, "Address too long: %d", errno);
break;
case ENOMEM:
failf(data, "Insufficient kernel memory was available: %d", errno);
break;
#if 0
case EROFS:
failf(data,
"Socket inode would reside on a read-only file system: %d",
errno);
break;
case ENOENT:
failf(data, "File does not exist: %d", errno);
break;
case ENOTDIR:
failf(data, "Component of path prefix is not a directory: %d",
errno);
break;
case ELOOP:
failf(data,"Too many symbolic links encountered: %d",errno);
break;
#endif
default:
failf(data,"errno %d\n");
} /* end of switch */
return CURLE_HTTP_PORT_FAILED;
} /* end of else */
} /* end of if h */
else {
failf(data,"could't find my own IP address (%s)", myhost);
return CURLE_HTTP_PORT_FAILED;
}
} /* end of inet_addr */
else {
failf(data, "could't find my own IP address (%s)", myhost);
return CURLE_HTTP_PORT_FAILED;
}
free(hostdataptr); /* allocated by GetHost() */
} /* end of device selection support */
#endif /* end of HAVE_INET_NTOA */
if (connect(data->firstsocket,
(struct sockaddr *) &(conn->serv_addr),
sizeof(conn->serv_addr)
@@ -1169,11 +1337,50 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
case ECONNREFUSED:
failf(data, "Connection refused");
break;
case EFAULT:
failf(data, "Invalid socket address: %d",errno);
break;
case EISCONN:
failf(data, "Socket already connected: %d",errno);
break;
case ETIMEDOUT:
failf(data, "Timeout while accepting connection, server busy: %d",errno);
break;
case ENETUNREACH:
failf(data, "Network is unreachable: %d",errno);
break;
case EADDRINUSE:
failf(data, "Local address already in use: %d",errno);
break;
case EINPROGRESS:
failf(data, "Socket is nonblocking and connection can not be completed immediately: %d",errno);
break;
case EALREADY:
failf(data, "Socket is nonblocking and a previous connection attempt not completed: %d",errno);
break;
case EAGAIN:
failf(data, "No more free local ports: %d",errno);
break;
case EACCES:
case EPERM:
failf(data, "Attempt to connect to broadcast address without socket broadcast flag or local firewall rule violated: %d",errno);
break;
#endif
#ifdef EINTR
case EINTR:
failf(data, "Connection timeouted");
break;
#endif
#if 0
case EAFNOSUPPORT:
failf(data, "Incorrect address family: %d",errno);
break;
case ENOTSOCK:
failf(data, "File descriptor is not a socket: %d",errno);
break;
case EBADF:
failf(data, "File descriptor is not a valid index in descriptor table: %d",errno);
break;
#endif
default:
failf(data, "Can't connect to server: %d", errno);
@@ -1183,12 +1390,14 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
}
if(data->bits.proxy_user_passwd) {
char authorization[512];
char *authorization;
sprintf(data->buffer, "%s:%s", data->proxyuser, data->proxypasswd);
base64Encode(data->buffer, authorization);
data->ptr_proxyuserpwd = maprintf("Proxy-authorization: Basic %s\015\012",
authorization);
if(base64_encode(data->buffer, strlen(data->buffer),
&authorization) >= 0) {
data->ptr_proxyuserpwd =
maprintf("Proxy-authorization: Basic %s\015\012", authorization);
free(authorization);
}
}
if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) {
if(data->useragent) {

View File

@@ -123,6 +123,20 @@ typedef enum {
CONN_LAST /* illegal state */
} ConnState;
#ifdef KRB4
struct krb4buffer {
void *data;
size_t size;
size_t index;
int eof_flag;
};
enum protection_level {
prot_clear,
prot_safe,
prot_confidential,
prot_private
};
#endif
/*
* The connectdata struct contains all fields and variables that should be
@@ -150,6 +164,7 @@ struct connectdata {
#define PROT_LDAP (1<<7)
#define PROT_FILE (1<<8)
char *hostent_buf; /* pointer to allocated memory for name info */
struct hostent *hp;
struct sockaddr_in serv_addr;
char proto[64];
@@ -188,6 +203,20 @@ struct connectdata {
the same we read from. -1 disables */
long *writebytecountp; /* return number of bytes written or NULL */
#ifdef KRB4
enum protection_level command_prot;
enum protection_level data_prot;
enum protection_level request_data_prot;
size_t buffer_size;
struct krb4buffer in_buffer, out_buffer;
int sec_complete;
void *app_data;
#endif
};
struct Progress {
@@ -213,6 +242,11 @@ struct Progress {
struct timeval t_connect;
struct timeval t_pretransfer;
int httpcode;
#define CURR_TIME 5
double speeder[ CURR_TIME ];
int speeder_c;
};
/****************************************************************************
@@ -245,6 +279,7 @@ struct FTP {
};
struct Configbits {
bool tunnel_thru_httpproxy;
bool ftp_append;
bool ftp_ascii;
bool ftp_list_only;
@@ -270,6 +305,7 @@ struct Configbits {
bool user_passwd;
bool verbose;
bool this_is_a_follow; /* this is a followed Location: request */
bool krb4; /* kerberos4 connection requested */
};
/* What type of interface that intiated this struct */
@@ -345,6 +381,9 @@ struct UrlData {
char *range; /* range, if used. See README for detailed specification on
this syntax. */
char *postfields; /* if POST, set the fields' values here */
long postfieldsize; /* if POST, this might have a size to use instead of
strlen(), and then the data *may* be binary (contain
zero bytes) */
bool free_referer; /* set TRUE if 'referer' points to a string we
allocated */
@@ -352,6 +391,7 @@ struct UrlData {
char *useragent; /* User-Agent string */
char *ftpport; /* port to send with the PORT command */
char *device; /* Interface to use */
/* function that stores the output:*/
curl_write_callback fwrite;
@@ -441,6 +481,11 @@ struct UrlData {
char *ptr_ref; /* free later if not NULL! */
char *ptr_cookie; /* free later if not NULL! */
char *ptr_host; /* free later if not NULL */
char *krb4_level;
#ifdef KRB4
FILE *cmdchannel;
#endif
};
#define LIBCURL_NAME "libcurl"

View File

@@ -38,10 +38,11 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
#include <string.h>
#include <stdio.h>
#include "setup.h"
#include <curl/curl.h>
#include "urldata.h"
@@ -78,8 +79,14 @@ char *curl_version(void)
ptr=strchr(ptr, '\0');
#endif
#ifdef KRB4
sprintf(ptr, " (krb4 enabled)");
ptr += strlen(ptr);
#endif
#ifdef USE_ZLIB
sprintf(ptr, " (zlib %s)", zlibVersion());
ptr += strlen(ptr);
#endif
return version;

View File

@@ -38,6 +38,8 @@
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
#include <stdio.h>
#include <string.h>

9
reconf
View File

@@ -9,8 +9,7 @@ die(){
echo "$@" ; exit
}
aclocal || die "ahhhhh"
autoheader || die "ahhhhh"
automake || die "ahhhhh"
autoconf || die "ahhhhh"
aclocal -I . || die "ahhhhh"
autoheader || die "ahhhhh"
automake || die "ahhhhh"
autoconf || die "ahhhhh"

View File

@@ -87,15 +87,15 @@ puts (
" sent to stdout to be in text mode for win32 systems.\n"
"\n"
" -c/--continue\n"
" Continue/Resume a previous file transfer. This\n"
" instructs curl to continue appending data on the file\n"
" where it was previously left, possibly because of a\n"
" broken connection to the server. There must be a named\n"
" physical file to append to for this to work. Note:\n"
" Upload resume is depening on a command named SIZE not\n"
" always present in all ftp servers! Upload resume is for\n"
" FTP only. HTTP resume is only possible with HTTP/1.1\n"
" or later servers.\n"
" Deprecated. Use '-C -' instead. Continue/Resume a pre<EFBFBD>\n"
" vious file transfer. This instructs curl to continue\n"
" appending data on the file where it was previously\n"
" left, possibly because of a broken connection to the\n"
" server. There must be a named physical file to append\n"
" to for this to work. Note: Upload resume is depening\n"
" on a command named SIZE not always present in all ftp\n"
" servers! Upload resume is for FTP only. HTTP resume is\n"
" only possible with HTTP/1.1 or later servers.\n"
"\n"
" -C/--continue-at <offset>\n"
" Continue/Resume a previous file transfer at the given\n"
@@ -110,16 +110,32 @@ puts (
" -d/--data <data>\n"
" (HTTP) Sends the specified data in a POST request to\n"
" the HTTP server. Note that the data is sent exactly as\n"
" specified with no extra processing. The data is\n"
" expected to be \"url-encoded\". This will cause curl to\n"
" pass the data to the server using the content-type\n"
" application/x-www-form-urlencoded. Compare to -F.\n"
" specified with no extra processing (with all newlines\n"
" cut off). The data is expected to be \"url-encoded\".\n"
" This will cause curl to pass the data to the server\n"
" using the content-type application/x-www-form-urlen<EFBFBD>\n"
" coded. Compare to -F.\n"
"\n"
" If you start the data with the letter @, the rest\n"
" should be a file name to read the data from, or - if\n"
" you want curl to read the data from stdin. The con<EFBFBD>\n"
" If you start the data with the letter @, the rest\n"
" should be a file name to read the data from, or - if\n"
" you want curl to read the data from stdin. The con<6F>\n"
" tents of the file must already be url-encoded.\n"
"\n"
" To post data purely binary, you should instead use the\n"
" --data-binary option.\n"
"\n"
" -d/--data is the same as --data-ascii.\n"
"\n"
" --data-ascii <data>\n"
" (HTTP) This is an alias for the -d/--data option.\n"
"\n"
" --data-binary <data>\n"
" (HTTP) This posts data in a similar manner as --data-\n"
" ascii does, although when using this option the entire\n"
" context of the posted data is kept as-is. If you want\n"
" to post a binary file without the strip-newlines fea<65>\n"
" ture of the --data-ascii option, this is for you.\n"
"\n"
" -D/--dump-header <file>\n"
" (HTTP/FTP) Write the HTTP headers to this file. Write\n"
" the FTP file info to this file if -I/--head is used.\n"
@@ -198,6 +214,12 @@ puts (
" (HTTP) Include the HTTP-header in the output. The HTTP-\n"
" header includes things like server-name, date of the\n"
" document, HTTP-version and more...\n"
" --interface <name>\n"
" Perform an operation using a specified interface. You\n"
" can enter interface name, IP address or host name. An\n"
" example could look like:\n"
"\n"
" curl --interface eth0:1 http://www.netscape.com/\n"
"\n"
" -I/--head\n"
" (HTTP/FTP) Fetch the HTTP-header only! HTTP-servers\n"
@@ -205,6 +227,15 @@ puts (
" but the header of a document. When used on a FTP file,\n"
" curl displays the file size only.\n"
"\n"
" --krb4 <level>\n"
" (FTP) Enable kerberos4 authentication and use. The\n"
);
puts(
" level must be entered and should be one of 'clear',\n"
" 'safe', 'confidential' or 'private'. Should you use a\n"
" level that is not one of these, 'private' will instead\n"
" be used.\n"
"\n"
" -K/--config <config file>\n"
" Specify which config file to read curl arguments from.\n"
" The config file is a text file in which command line\n"
@@ -215,6 +246,7 @@ puts (
"\n"
" Specify the filename as '-' to make curl read the file\n"
" from stdin.\n"
"\n"
" -l/--list-only\n"
" (FTP) When listing an FTP directory, this switch forces\n"
" a name-only view. Especially useful if you want to\n"
@@ -226,8 +258,6 @@ puts (
" (HTTP/HTTPS) If the server reports that the requested\n"
" page has a different location (indicated with the\n"
" header line Location:) this flag will let curl attempt\n"
);
puts(
" to reattempt the get on the new place. If used together\n"
" with -i or -I, headers from all requested pages will be\n"
" shown. If this flag is used when making a HTTP POST,\n"
@@ -286,6 +316,15 @@ puts (
" we get. (Only the file part of the remote file is used,\n"
" the path is cut off.)\n"
"\n"
" -p/--proxytunnel\n"
" When an HTTP proxy is used, this option will cause non-\n"
" HTTP protocols to attempt to tunnel through the proxy\n"
" instead of merely using it to do HTTP-like operations.\n"
" The tunnel approach is made with the HTTP proxy CONNECT\n"
" request and requires that the proxy allows direct con<6F>\n"
" nect to the remote port number curl wants to tunnel\n"
" through to.\n"
"\n"
" -P/--ftpport <address>\n"
" (FTP) Reverses the initiator/listener roles when con<6F>\n"
" necting with ftp. This switch makes Curl use the PORT\n"
@@ -320,6 +359,7 @@ puts (
" to be run before and after the transfer. If the server\n"
" returns failure for one of the commands, the entire\n"
" operation will be aborted.\n"
"\n"
" -r/--range <range>\n"
" (HTTP/FTP) Retrieve a byte range (i.e a partial docu<63>\n"
" ment) from a HTTP/1.1 or FTP server. Ranges can be\n"
@@ -331,8 +371,8 @@ puts (
"\n"
" -500 specifies the last 500 bytes\n"
"\n"
" 9500 specifies the bytes from offset 9500 and for<6F>\n"
" ward\n"
" 9500 specifies the bytes from offset 9500 and\n"
" forward\n"
"\n"
" 0-0,-1 specifies the first and last byte only(*)(H)\n"
"\n"
@@ -362,141 +402,141 @@ puts (
" it fails.\n"
"\n"
" -t/--upload\n"
" Transfer the stdin data to the specified file. Curl\n"
" will read everything from stdin until EOF and store\n"
" with the supplied name. If this is used on a http(s)\n"
" server, the PUT command will be used.\n"
" Deprecated. Use '-T -' instead. Transfer the stdin\n"
" data to the specified file. Curl will read everything\n"
" from stdin until EOF and store with the supplied name.\n"
" If this is used on a http(s) server, the PUT command\n"
" will be used.\n"
"\n"
" -T/--upload-file <file>\n"
" Like -t, but this transfers the specified local file.\n"
" If there is no file part in the specified URL, Curl\n"
" Like -t, but this transfers the specified local file.\n"
" If there is no file part in the specified URL, Curl\n"
" will append the local file name. NOTE that you must use\n"
" a trailing / on the last directory to really prove to\n"
" a trailing / on the last directory to really prove to\n"
" Curl that there is no file name or curl will think that\n"
" your last directory name is the remote file name to\n"
" use. That will most likely cause the upload operation\n"
" to fail. If this is used on a http(s) server, the PUT\n"
" your last directory name is the remote file name to\n"
" use. That will most likely cause the upload operation\n"
" to fail. If this is used on a http(s) server, the PUT\n"
" command will be used.\n"
"\n"
" -u/--user <user:password>\n"
" Specify user and password to use when fetching. See\n"
" README.curl for detailed examples of how to use this.\n"
" If no password is specified, curl will ask for it\n"
" Specify user and password to use when fetching. See\n"
" README.curl for detailed examples of how to use this.\n"
" If no password is specified, curl will ask for it\n"
" interactively.\n"
"\n"
" -U/--proxy-user <user:password>\n"
" Specify user and password to use for Proxy authentica<EFBFBD>\n"
" Specify user and password to use for Proxy authentica<63>\n"
" tion. If no password is specified, curl will ask for it\n"
" interactively.\n"
"\n"
" -v/--verbose\n"
" Makes the fetching more verbose/talkative. Mostly\n"
" usable for debugging. Lines starting with '>' means\n"
" Makes the fetching more verbose/talkative. Mostly\n"
" usable for debugging. Lines starting with '>' means\n"
" data sent by curl, '<' means data received by curl that\n"
" is hidden in normal cases and lines starting with '*'\n"
" is hidden in normal cases and lines starting with '*'\n"
" means additional info provided by curl.\n"
"\n"
" -V/--version\n"
" Displays the full version of curl, libcurl and other\n"
" Displays the full version of curl, libcurl and other\n"
" 3rd party libraries linked with the executable.\n"
"\n"
" -w/--write-out <format>\n"
" Defines what to display after a completed and success<73>\n"
" ful operation. The format is a string that may contain\n"
" plain text mixed with any number of variables. The\n"
" Defines what to display after a completed and success<EFBFBD>\n"
" ful operation. The format is a string that may contain\n"
" plain text mixed with any number of variables. The\n"
" string can be specified as \"string\", to get read from a\n"
" particular file you specify it \"@filename\" and to tell\n"
" particular file you specify it \"@filename\" and to tell\n"
" curl to read the format from stdin you write \"@-\".\n"
"\n"
" The variables present in the output format will be sub<75>\n"
" stituted by the value or text that curl thinks fit, as\n"
" stituted by the value or text that curl thinks fit, as\n"
" described below. All variables are specified like\n"
" %{variable_name} and to output a normal % you just\n"
" write them like %%. You can output a newline by using\n"
" %{variable_name} and to output a normal % you just\n"
" write them like %%. You can output a newline by using\n"
" \\n, a carrige return with \\r and a tab space with \\t.\n"
"\n"
" NOTE: The %-letter is a special letter in the\n"
" win32-environment, where all occurrences of % must be\n"
" NOTE: The %-letter is a special letter in the\n"
" win32-environment, where all occurrences of % must be\n"
" doubled when using this option.\n"
"\n"
" Available variables are at this point:\n"
"\n"
" url_effective The URL that was fetched last. This is\n"
" url_effective The URL that was fetched last. This is\n"
" mostly meaningful if you've told curl to\n"
" follow location: headers.\n"
"\n"
" http_code The numerical code that was found in the\n"
);
puts(
" last retrieved HTTP(S) page.\n"
"\n"
" time_total The total time, in seconds, that the\n"
" full operation lasted. The time will be\n"
" time_total The total time, in seconds, that the\n"
" full operation lasted. The time will be\n"
" displayed with millisecond resolution.\n"
"\n"
" time_namelookup\n"
" The time, in seconds, it took from the\n"
" start until the name resolving was com<6F>\n"
" The time, in seconds, it took from the\n"
" start until the name resolving was com<EFBFBD>\n"
" pleted.\n"
"\n"
" time_connect The time, in seconds, it took from the\n"
" start until the connect to the remote\n"
" time_connect The time, in seconds, it took from the\n"
" start until the connect to the remote\n"
" host (or proxy) was completed.\n"
"\n"
" time_pretransfer\n"
" The time, in seconds, it took from the\n"
" start until the file transfer is just\n"
" about to begin. This includes all pre-\n"
" transfer commands and negotiations that\n"
" are specific to the particular proto<EFBFBD>\n"
" The time, in seconds, it took from the\n"
" start until the file transfer is just\n"
" about to begin. This includes all pre-\n"
" transfer commands and negotiations that\n"
" are specific to the particular proto<74>\n"
" col(s) involved.\n"
"\n"
" size_download The total amount of bytes that were\n"
" size_download The total amount of bytes that were\n"
" downloaded.\n"
"\n"
" size_upload The total amount of bytes that were\n"
" size_upload The total amount of bytes that were\n"
" uploaded.\n"
"\n"
" speed_download The average download speed that curl\n"
" speed_download The average download speed that curl\n"
" measured for the complete download.\n"
"\n"
" speed_upload The average upload speed that curl mea<EFBFBD>\n"
" speed_upload The average upload speed that curl mea<65>\n"
" sured for the complete download.\n"
"\n"
" -x/--proxy <proxyhost[:port]>\n"
" Use specified proxy. If the port number is not speci<63>\n"
" Use specified proxy. If the port number is not speci<EFBFBD>\n"
" fied, it is assumed at port 1080.\n"
"\n"
" -X/--request <command>\n"
" (HTTP) Specifies a custom request to use when communi<EFBFBD>\n"
);
puts(
" cating with the HTTP server. The specified request\n"
" (HTTP) Specifies a custom request to use when communi<6E>\n"
" cating with the HTTP server. The specified request\n"
" will be used instead of the standard GET. Read the HTTP\n"
" 1.1 specification for details and explanations.\n"
"\n"
" (FTP) Specifies a custom FTP command to use instead of\n"
" (FTP) Specifies a custom FTP command to use instead of\n"
" LIST when doing file lists with ftp.\n"
"\n"
" -y/--speed-time <time>\n"
" If a download is slower than speed-limit bytes per sec<65>\n"
" ond during a speed-time period, the download gets\n"
" ond during a speed-time period, the download gets\n"
" aborted. If speed-time is used, the default speed-limit\n"
" will be 1 unless set with -y.\n"
"\n"
" -Y/--speed-limit <speed>\n"
" If a download is slower than this given speed, in bytes\n"
" per second, for speed-time seconds it gets aborted.\n"
" per second, for speed-time seconds it gets aborted.\n"
" speed-time is set with -Y and is 30 if not set.\n"
"\n"
" -z/--time-cond <date expression>\n"
" (HTTP) Request to get a file that has been modified\n"
" later than the given time and date, or one that has\n"
" (HTTP) Request to get a file that has been modified\n"
" later than the given time and date, or one that has\n"
" been modified before that time. The date expression can\n"
" be all sorts of date strings or if it doesn't match any\n"
" internal ones, it tries to get the time from a given\n"
" file name instead! See the GNU date(1) or curl_get<EFBFBD>\n"
" internal ones, it tries to get the time from a given\n"
" file name instead! See the GNU date(1) or curl_get<65>\n"
" date(3) man pages for date expression details.\n"
"\n"
" Start the date expression with a dash (-) to make it\n"
" request for a document that is older than the given\n"
" Start the date expression with a dash (-) to make it\n"
" request for a document that is older than the given\n"
" date/time, default is a document that is newer than the\n"
" specified date/time.\n"
"\n"
@@ -509,15 +549,15 @@ puts (
" ing with a remote SSL server.\n"
"\n"
" -#/--progress-bar\n"
" Make curl display progress information as a progress\n"
" Make curl display progress information as a progress\n"
" bar instead of the default statistics.\n"
"\n"
" --crlf\n"
" (FTP) Convert LF to CRLF in upload. Useful for MVS\n"
" (FTP) Convert LF to CRLF in upload. Useful for MVS\n"
" (OS/390).\n"
"\n"
" --stderr <file>\n"
" Redirect all writes to stderr to the specified file\n"
" Redirect all writes to stderr to the specified file\n"
" instead. If the file name is a plain '-', it is instead\n"
" written to stdout. This option has no point when you're\n"
" using a shell with decent redirecting capabilities.\n"
@@ -529,6 +569,7 @@ puts (
"ENVIRONMENT\n"
" HTTP_PROXY [protocol://]<host>[:port]\n"
" Sets proxy server to use for HTTP.\n"
"\n"
" HTTPS_PROXY [protocol://]<host>[:port]\n"
" Sets proxy server to use for HTTPS.\n"
"\n"
@@ -539,7 +580,7 @@ puts (
" Sets proxy server to use for GOPHER.\n"
"\n"
" ALL_PROXY [protocol://]<host>[:port]\n"
" Sets proxy server to use if no protocol-specific proxy\n"
" Sets proxy server to use if no protocol-specific proxy\n"
" is set.\n"
"\n"
" NO_PROXY <comma-separated list of hosts>\n"
@@ -547,12 +588,12 @@ puts (
" If set to a asterisk '*' only, it matches all hosts.\n"
"\n"
" COLUMNS <integer>\n"
" The width of the terminal. This variable only affects\n"
" The width of the terminal. This variable only affects\n"
" curl when the --progress-bar option is used.\n"
"\n"
"EXIT CODES\n"
" There exists a bunch of different error codes and their cor<6F>\n"
" responding error messages that may appear during bad condi<64>\n"
" responding error messages that may appear during bad condi<EFBFBD>\n"
" tions. At the time of this writing, the exit codes are:\n"
"\n"
" 1 Unsupported protocol. This build of curl has no support\n"
@@ -562,40 +603,40 @@ puts (
"\n"
" 3 URL malformat. The syntax was not correct.\n"
"\n"
" 4 URL user malformatted. The user-part of the URL syntax\n"
" 4 URL user malformatted. The user-part of the URL syntax\n"
" was not correct.\n"
"\n"
" 5 Couldn't resolve proxy. The given proxy host could not\n"
" 5 Couldn't resolve proxy. The given proxy host could not\n"
" be resolved.\n"
"\n"
" 6 Couldn't resolve host. The given remote host was not\n"
" 6 Couldn't resolve host. The given remote host was not\n"
" resolved.\n"
"\n"
" 7 Failed to connect to host.\n"
"\n"
" 8 FTP weird server reply. The server sent data curl\n"
" 8 FTP weird server reply. The server sent data curl\n"
" couldn't parse.\n"
"\n"
" 9 FTP access denied. The server denied login.\n"
"\n"
" 10 FTP user/password incorrect. Either one or both were\n"
" 10 FTP user/password incorrect. Either one or both were\n"
" not accepted by the server.\n"
" 11 FTP weird PASS reply. Curl couldn't parse the reply\n"
"\n"
" 11 FTP weird PASS reply. Curl couldn't parse the reply\n"
" sent to the PASS request.\n"
"\n"
" 12 FTP weird USER reply. Curl couldn't parse the reply\n"
" 12 FTP weird USER reply. Curl couldn't parse the reply\n"
" sent to the USER request.\n"
"\n"
" 13 FTP weird PASV reply, Curl couldn't parse the reply\n"
" 13 FTP weird PASV reply, Curl couldn't parse the reply\n"
" sent to the PASV request.\n"
"\n"
" 14 FTP weird 227 formay. Curl couldn't parse the 227-line\n"
" 14 FTP weird 227 formay. Curl couldn't parse the 227-line\n"
" the server sent.\n"
"\n"
" 15 FTP can't get host. Couldn't resolve the host IP we got\n"
" in the 227-line.\n"
"\n"
" 16 FTP can't reconnect. Couldn't connect to the host we\n"
" 16 FTP can't reconnect. Couldn't connect to the host we\n"
" got in the 227-line.\n"
"\n"
" 17 FTP couldn't set binary. Couldn't change transfer\n"
@@ -605,51 +646,51 @@ puts (
"\n"
" 19 FTP couldn't RETR file. The RETR command failed.\n"
"\n"
" 20 FTP write error. The transfer was reported bad by the\n"
" 20 FTP write error. The transfer was reported bad by the\n"
" server.\n"
"\n"
" 21 FTP quote error. A quote command returned error from\n"
" 21 FTP quote error. A quote command returned error from\n"
" the server.\n"
"\n"
" 22 HTTP not found. The requested page was not found. This\n"
" 22 HTTP not found. The requested page was not found. This\n"
" return code only appears if --fail is used.\n"
"\n"
" 23 Write error. Curl couldn't write data to a local\n"
" 23 Write error. Curl couldn't write data to a local\n"
" filesystem or similar.\n"
"\n"
" 24 Malformat user. User name badly specified.\n"
"\n"
" 25 FTP couldn't STOR file. The server denied the STOR\n"
" 25 FTP couldn't STOR file. The server denied the STOR\n"
" operation.\n"
"\n"
" 26 Read error. Various reading problems.\n"
"\n"
" 27 Out of memory. A memory allocation request failed.\n"
"\n"
" 28 Operation timeout. The specified time-out period was\n"
" 28 Operation timeout. The specified time-out period was\n"
" reached according to the conditions.\n"
"\n"
" 29 FTP couldn't set ASCII. The server returned an unknown\n"
" 29 FTP couldn't set ASCII. The server returned an unknown\n"
" reply.\n"
"\n"
" 30 FTP PORT failed. The PORT command failed.\n"
"\n"
" 31 FTP couldn't use REST. The REST command failed.\n"
"\n"
" 32 FTP couldn't use SIZE. The SIZE command failed. The\n"
" command is an extension to the original FTP spec RFC\n"
" 32 FTP couldn't use SIZE. The SIZE command failed. The\n"
" command is an extension to the original FTP spec RFC\n"
" 959.\n"
"\n"
" 33 HTTP range error. The range \"command\" didn't work.\n"
"\n"
" 34 HTTP post error. Internal post-request generation\n"
" 34 HTTP post error. Internal post-request generation\n"
" error.\n"
"\n"
" 35 SSL connect error. The SSL handshaking failed.\n"
"\n"
" 36 FTP bad download resume. Couldn't continue an earlier\n"
" 36 FTP bad download resume. Couldn't continue an earlier\n"
" aborted download.\n"
"\n"
" 37 FILE couldn't read file. Failed to open the file. Per<65>\n"
" 37 FILE couldn't read file. Failed to open the file. Per<65>\n"
" missions?\n"
"\n"
" 38 LDAP cannot bind. LDAP bind operation failed.\n"
@@ -658,14 +699,14 @@ puts (
"\n"
" 40 Library not found. The LDAP library was not found.\n"
"\n"
" 41 Function not found. A required LDAP function was not\n"
" 41 Function not found. A required LDAP function was not\n"
" found.\n"
"\n"
" XX There will appear more error codes here in future\n"
" releases. The existing ones are meant to never change.\n"
" XX There will appear more error codes here in future\n"
" releases. The existing ones are meant to never change.\n"
"\n"
"BUGS\n"
" If you do find any (or have other suggestions), mail Daniel\n"
" If you do find any (or have other suggestions), mail Daniel\n"
" Stenberg <Daniel.Stenberg@haxx.se>.\n"
"\n"
"AUTHORS / CONTRIBUTORS\n"
@@ -707,6 +748,8 @@ puts (
" - Paul Marquis <pmarquis@iname.com>\n"
" - Ellis Pritchard <ellis@citria.com>\n"
" - Damien Adant <dams@usa.net>\n"
);
puts(
" - Chris <cbayliss@csc.come>\n"
" - Marco G. Salvagno <mgs@whiz.cjb.net>\n"
" - Paul Marquis <pmarquis@iname.com>\n"
@@ -717,6 +760,10 @@ puts (
" - Kristian K<>hntopp <kris@koehntopp.de>\n"
" - Fred Noz <FNoz@siac.com>\n"
" - Caolan McNamara <caolan@csn.ul.ie>\n"
" - Albert Chin-A-Young <china@thewrittenword.com>\n"
" - Stephen Kick <skick@epicrealm.com>\n"
" - Martin Hedenfalk <mhe@stacken.kth.se>\n"
" - Richard Prescott\n"
"\n"
"WWW\n"
" http://curl.haxx.se\n"
@@ -779,8 +826,6 @@ puts (
" To ftp files using name+passwd, include them in the URL like:\n"
"\n"
" curl ftp://name:passwd@machine.domain:port/full/path/to/file\n"
);
puts(
"\n"
" or specify them with the -u flag like\n"
"\n"
@@ -870,9 +915,11 @@ puts (
"\n"
" curl -T localfile -a ftp://ftp.upload.com/remotefile\n"
"\n"
" NOTE: Curl does not support ftp upload through a proxy! The reason for this\n"
" is simply that proxies are seldomly configured to allow this and that no\n"
" author has supplied code that makes it possible!\n"
" Curl also supports ftp upload through a proxy, but only if the proxy is\n"
" configured to allow that kind of tunneling. If it does, you can run curl in\n"
" a fashion similar to:\n"
"\n"
" curl --proxytunnel -x proxy:port -T localfile ftp.upload.com\n"
"\n"
" HTTP\n"
"\n"
@@ -1016,6 +1063,8 @@ puts (
" A HTTP request has the option to include information about the browser\n"
" that generated the request. Curl allows it to be specified on the command\n"
" line. It is especially useful to fool or trick stupid servers or CGI\n"
);
puts(
" scripts that only accept certain browsers.\n"
"\n"
" Example:\n"
@@ -1061,8 +1110,6 @@ puts (
" Curl also has the ability to use previously received cookies in following\n"
" sessions. If you get cookies from a server and store them in a file in a\n"
" manner similar to:\n"
);
puts(
"\n"
" curl --dump-header headers www.example.com\n"
"\n"
@@ -1213,13 +1260,14 @@ puts (
" connect to the client on the given (as parameters to the PORT command) IP\n"
" number and port.\n"
"\n"
" The -P flag to curl allows for different options. Your machine may have\n"
" The -P flag to curl supports a few different options. Your machine may have\n"
" several IP-addresses and/or network interfaces and curl allows you to select\n"
" which of them to use. Default address can also be used:\n"
"\n"
" curl -P - ftp.download.com\n"
"\n"
" Download with PORT but use the IP address of our 'le0' interface:\n"
" Download with PORT but use the IP address of our 'le0' interface (this does\n"
" not work on windows):\n"
"\n"
" curl -P le0 ftp.download.com\n"
"\n"
@@ -1227,6 +1275,16 @@ puts (
"\n"
" curl -P 192.168.0.10 ftp.download.com\n"
"\n"
"NETWORK INTERFACE\n"
"\n"
" Get a web page from a server using a specified port for the interface:\n"
"\n"
" curl --interface eth0:1 http://www.netscape.com/\n"
"\n"
" or\n"
"\n"
" curl --interface 192.168.1.10 http://www.netscape.com/\n"
"\n"
"HTTPS\n"
"\n"
" Secure HTTP requires SSL libraries to be installed and used when curl is\n"
@@ -1266,6 +1324,8 @@ puts (
" curl -2 https://secure.site.com/\n"
"\n"
" Otherwise, curl will first attempt to use v3 and then v2.\n"
);
puts(
"\n"
" To use OpenSSL to convert your favourite browser's certificate into a PEM\n"
" formatted one that curl can use, do something like this (assuming netscape,\n"
@@ -1332,8 +1392,6 @@ puts (
" curl -z yesterday http://remote.server.com/remote.html\n"
"\n"
" Curl will then accept a wide range of date formats. You always make the date\n"
);
puts(
" check the other way around by prepending it with a dash '-'.\n"
"\n"
"DICT\n"
@@ -1424,13 +1482,26 @@ puts (
"\n"
" curl -w 'We downloaded %{size_download} bytes\\n' www.download.com\n"
"\n"
"KERBEROS4 FTP TRANSFER\n"
"\n"
" Curl supports kerberos4 for FTP transfers. You need the kerberos package\n"
" installed and used at curl build time for it to be used.\n"
"\n"
" First, get the krb-ticket the normal way, like with the kauth tool. Then use\n"
" curl in way similar to:\n"
"\n"
" curl --krb4 private ftp://krb4site.com -u username:fakepwd\n"
"\n"
" There's no use for a password on the -u switch, but a blank one will make\n"
" curl ask for one and you already entered the real password to kauth.\n"
"\n"
"MAILING LIST\n"
"\n"
" We have an open mailing list to discuss curl, its development and things\n"
" relevant to this.\n"
"\n"
" To subscribe, mail curl-request@contactor.se with \"subscribe <your email\n"
" address>\" in the body.\n"
" To subscribe, mail curl-request@contactor.se with \"subscribe <fill in your\n"
" email address>\" in the body.\n"
"\n"
" To post to the list, mail curl@contactor.se.\n"
"\n"

View File

@@ -230,7 +230,9 @@ static void help(void)
" -B/--use-ascii Use ASCII/text transfer\n"
" -c/--continue Resume a previous transfer where we left it\n"
" -C/--continue-at <offset> Specify absolute resume offset\n"
" -d/--data POST data (H)\n"
" -d/--data <data> HTTP POST data (H)\n"
" --data-ascii <data> HTTP POST ASCII data (H)\n"
" --data-binary <data> HTTP POST binary data (H)\n"
" -D/--dump-header <file> Write the headers to this file\n"
" -e/--referer Referer page (H)\n"
" -E/--cert <cert:passwd> Specifies your certificate file and password (HTTPS)\n"
@@ -241,6 +243,8 @@ static void help(void)
" -H/--header <line> Custom header to pass to server. (H)\n"
" -i/--include Include the HTTP-header in the output (H)\n"
" -I/--head Fetch document info only (HTTP HEAD/FTP SIZE)\n"
" --interface <interface> Specify the interface to be used\n"
" --krb4 <level> Enable krb4 with specified security level (F)\n"
" -K/--config Specify which config file to read\n"
" -l/--list-only List only names of an FTP directory (F)\n"
" -L/--location Follow Location: hints (H)\n"
@@ -250,9 +254,7 @@ static void help(void)
" -N/--no-buffer Disables the buffering of the output stream\n"
" -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"
#if 0
" -p/--port <port> Use port other than default for current protocol.\n"
#endif
" -p/--proxytunnel Perform non-HTTP services through a HTTP proxy\n"
" -P/--ftpport <address> Use PORT with address instead of PASV when ftping (F)\n"
" -q When used as the first parameter disables .curlrc\n"
" -Q/--quote <cmd> Send QUOTE command to FTP before file transfer (F)\n"
@@ -292,12 +294,14 @@ struct Configurable {
bool use_resume;
int resume_from;
char *postfields;
long postfieldsize;
char *referer;
long timeout;
char *outfile;
char *headerfile;
char remotefile;
char *ftpport;
char *iface;
unsigned short porttouse;
char *range;
int low_speed_limit;
@@ -308,6 +312,7 @@ struct Configurable {
char *proxyuserpwd;
char *proxy;
bool configread;
bool proxytunnel;
long conf;
char *url;
char *cert;
@@ -315,6 +320,7 @@ struct Configurable {
bool crlf;
char *cookiefile;
char *customrequest;
char *krb4level;
bool progressmode;
bool nobuffer;
@@ -385,6 +391,36 @@ static char *file2string(FILE *file)
return NULL; /* no string */
}
static char *file2memory(FILE *file, long *size)
{
char buffer[1024];
char *ptr;
char *string=NULL;
char *newstring=NULL;
long len=0;
long stringlen=0;
if(file) {
while(len = fread(buffer, 1, sizeof(buffer), file)) {
if(string) {
newstring = realloc(string, len+stringlen);
if(newstring)
string = newstring;
else
break; /* no more strings attached! :-) */
}
else
string = malloc(len);
memcpy(&string[stringlen], buffer, len);
stringlen+=len;
}
*size = stringlen;
return string;
}
else
return NULL; /* no string */
}
static int getparameter(char *flag, /* f or -long-flag */
char *nextarg, /* NULL if unset */
bool *usedarg, /* set to TRUE if the arg has been
@@ -392,11 +428,14 @@ static int getparameter(char *flag, /* f or -long-flag */
struct Configurable *config)
{
char letter;
char subletter=0; /* subletters can only occur on long options */
char *parse=NULL;
int res;
int j;
time_t now;
int hit=-1;
bool longopt=FALSE;
/* single-letter,
long-name,
@@ -405,6 +444,8 @@ static int getparameter(char *flag, /* f or -long-flag */
struct LongShort aliases[]= {
{"9", "crlf", FALSE},
{"8", "stderr", TRUE},
{"7", "interface", TRUE},
{"6", "krb4", TRUE},
{"2", "sslv2", FALSE},
{"3", "sslv3", FALSE},
@@ -416,6 +457,8 @@ static int getparameter(char *flag, /* f or -long-flag */
{"c", "continue", FALSE},
{"C", "continue-at", TRUE},
{"d", "data", TRUE},
{"da", "data-ascii", TRUE},
{"db", "data-binary", TRUE},
{"D", "dump-header", TRUE},
{"e", "referer", TRUE},
{"E", "cert", TRUE},
@@ -435,9 +478,7 @@ static int getparameter(char *flag, /* f or -long-flag */
{"N", "no-buffer", FALSE},
{"o", "output", TRUE},
{"O", "remote-name", FALSE},
#if 0
{"p", "port", TRUE},
#endif
{"p", "proxytunnel", FALSE},
{"P", "ftpport", TRUE},
{"q", "disable", FALSE},
{"Q", "quote", TRUE},
@@ -465,6 +506,7 @@ static int getparameter(char *flag, /* f or -long-flag */
int fnam=strlen(&flag[1]);
for(j=0; j< sizeof(aliases)/sizeof(aliases[0]); j++) {
if(strnequal(aliases[j].lname, &flag[1], fnam)) {
longopt = TRUE;
if(strequal(aliases[j].lname, &flag[1])) {
parse = aliases[j].letter;
hit = j;
@@ -492,7 +534,12 @@ static int getparameter(char *flag, /* f or -long-flag */
do {
/* we can loop here if we have multiple single-letters */
letter = parse?*parse:'\0';
if(!longopt)
letter = parse?*parse:'\0';
else {
letter = parse[0];
subletter = parse[1];
}
*usedarg = FALSE; /* default is that we don't use the arg */
#if 0
@@ -500,7 +547,7 @@ static int getparameter(char *flag, /* f or -long-flag */
#endif
if(hit < 0) {
for(j=0; j< sizeof(aliases)/sizeof(aliases[0]); j++) {
if(letter == *aliases[j].letter) {
if(letter == aliases[j].letter[0]) {
hit = j;
break;
}
@@ -568,6 +615,14 @@ static int getparameter(char *flag, /* f or -long-flag */
else
config->errors = stdout;
break;
case '7': /* there is no short letter for this */
/* interface */
GetStr(&config->iface, nextarg);
break;
case '6': /* there is no short letter for this */
/* krb4 level string */
GetStr(&config->krb4level, nextarg);
break;
case '#': /* added 19990617 larsa */
config->progressmode ^= CURL_PROGRESS_BAR;
break;
@@ -606,10 +661,12 @@ static int getparameter(char *flag, /* f or -long-flag */
case 'c':
/* This makes us continue an ftp transfer */
config->use_resume^=TRUE;
fprintf(stderr, "-c is a deprecated switch, use '-C -' instead!\n");
break;
case 'C':
/* This makes us continue an ftp transfer at given position */
config->resume_from= atoi(nextarg);
if(!strequal(nextarg, "-"))
config->resume_from= atoi(nextarg);
config->use_resume=TRUE;
break;
case 'd':
@@ -618,12 +675,19 @@ static int getparameter(char *flag, /* f or -long-flag */
/* the data begins with a '@' letter, it means that a file name
or - (stdin) follows */
FILE *file;
char *ptr;
nextarg++; /* pass the @ */
if(strequal("-", nextarg))
file = stdin;
else
file = fopen(nextarg, "r");
config->postfields = file2string(file);
if(subletter == 'b') /* forced binary */
config->postfields = file2memory(file, &config->postfieldsize);
else
config->postfields = file2string(file);
if(file && (file != stdin))
fclose(stdin);
}
@@ -738,15 +802,11 @@ static int getparameter(char *flag, /* f or -long-flag */
*/
GetStr(&config->ftpport, nextarg);
break;
#if 0
case 'p':
/* specified port */
fputs("You've used the -p option, it will be removed in a future version\n",
stderr);
config->porttouse = atoi(nextarg);
config->conf |= CONF_PORT; /* changed port */
/* proxy tunnel for non-http protocols */
config->proxytunnel ^= TRUE;
break;
#endif
case 'q': /* if used first, already taken care of, we do it like
this so we don't cause an error! */
break;
@@ -777,11 +837,14 @@ static int getparameter(char *flag, /* f or -long-flag */
case 't':
/* we are uploading */
config->conf ^= CONF_UPLOAD;
fprintf(stderr, "-t is a deprecated switch, use '-T -' instead!\n");
break;
case 'T':
/* we are uploading */
config->conf |= CONF_UPLOAD;
GetStr(&config->infile, nextarg);
if(!strequal("-", nextarg))
/* make - equal stdin */
GetStr(&config->infile, nextarg);
break;
case 'u':
/* user:password */
@@ -1422,6 +1485,10 @@ int main(int argc, char *argv[])
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, config.timeout);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, config.postfields);
/* new in libcurl 7.2: */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, config.postfieldsize);
curl_easy_setopt(curl, CURLOPT_REFERER, config.referer);
curl_easy_setopt(curl, CURLOPT_AUTOREFERER, config.conf&CONF_AUTO_REFERER);
curl_easy_setopt(curl, CURLOPT_USERAGENT, config.useragent);
@@ -1447,6 +1514,11 @@ int main(int argc, char *argv[])
curl_easy_setopt(curl, CURLOPT_STDERR, config.errors);
curl_easy_setopt(curl, CURLOPT_WRITEINFO, config.writeout);
/* three new ones in libcurl 7.3: */
curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, config.proxytunnel);
curl_easy_setopt(curl, CURLOPT_INTERFACE, config.iface);
curl_easy_setopt(curl, CURLOPT_KRB4LEVEL, config.krb4level);
if((config.progressmode == CURL_PROGRESS_BAR) &&
!(config.conf&(CONF_NOPROGRESS|CONF_MUTE))) {
/* we want the alternative style, then we have to implement it

View File

@@ -1,3 +1,3 @@
#define CURL_NAME "curl"
#define CURL_VERSION "7.1"
#define CURL_VERSION "7.3"
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "