Compare commits

...

50 Commits

Author SHA1 Message Date
Daniel Stenberg
ac98c73b04 7.6 2001-01-27 16:16:54 +00:00
Daniel Stenberg
a145654394 http upload resume 2001-01-26 15:53:33 +00:00
Daniel Stenberg
e8382ba290 moved the symbols talk to the library part, updated slightly to match 2001-01-26 15:52:51 +00:00
Daniel Stenberg
fcb347d124 Added a httpreq field in the main struct so that there's one field to check
for what HTTP request that is being used. The old bit-style fields are still
in there as well.
2001-01-26 15:52:01 +00:00
Daniel Stenberg
c331ef02f9 The check for that content-range is received must only be made if we requested
GET resume. Other resumes are upload-wise and don't care about this header
in the download stream
2001-01-26 15:50:56 +00:00
Daniel Stenberg
3a3f632bf0 Made it possible to do "upload resume" over HTTP 2001-01-26 15:49:39 +00:00
Daniel Stenberg
68d7b6f871 7.6-pre4 2001-01-25 13:48:28 +00:00
Daniel Stenberg
c43a9d9068 timespent is now updated in every call to the progress meter update function 2001-01-25 12:32:40 +00:00
Daniel Stenberg
64e80091db Rick's and Jeff's stuff 2001-01-25 12:31:44 +00:00
Daniel Stenberg
4f255ffbeb make the configure script die if select() or socket() is missing 2001-01-25 12:28:46 +00:00
Daniel Stenberg
80d75b0eaf Added Ingo Ralf Blum 2001-01-25 12:28:10 +00:00
Daniel Stenberg
808c4020e6 use this function only once note added 2001-01-25 12:27:44 +00:00
Daniel Stenberg
149d6363b3 modified the Curl_ConnectHTTPProxyTunnel proto 2001-01-25 12:24:34 +00:00
Daniel Stenberg
30eab8ca51 moved curl_read() and curl_write() to sendf.c 2001-01-25 12:23:57 +00:00
Daniel Stenberg
e49a82b06c converted to use Curl_read() and Curl_write() 2001-01-25 12:23:12 +00:00
Daniel Stenberg
45fdb48189 uses Curl_read() and Curl_write()
unfolded telwrite() instead of being a separate single function
2001-01-25 12:22:17 +00:00
Daniel Stenberg
3fcc9677c4 use recv()/send() instead of read()/write() with sockets 2001-01-25 12:21:10 +00:00
Daniel Stenberg
1552bd9c8c sendf is now only Curl_sendf
Curl_write() and Curl_read() are here
2001-01-25 12:20:30 +00:00
Daniel Stenberg
939c0c5521 removed two compiler warnings 2001-01-25 12:19:36 +00:00
Daniel Stenberg
f0b9aefd2e Curl_read() and Curl_write() are now used for reading/writing sockets.
Some functions changed prototype due to this change as well.
2001-01-25 12:19:02 +00:00
Daniel Stenberg
11f3c51e8f Get get-ftp-response function is now using Curl_read() for reading from a
socket. Curl_ConnectHTTPProxyTunnel changed prototype.
2001-01-25 12:17:07 +00:00
Daniel Stenberg
1a329b98a3 replaced sendf() calls with Curl_sendf() 2001-01-25 12:13:35 +00:00
Daniel Stenberg
29bcba9a90 Ingo Ralf Blum's cygwin fixes 2001-01-24 14:44:05 +00:00
Daniel Stenberg
1716dbb68a Robert Weaver's win32 getenv fix, my added comments in some files 2001-01-24 14:04:47 +00:00
Daniel Stenberg
16ecfcf62c Added Robert Weaver as contributor 2001-01-24 14:04:14 +00:00
Daniel Stenberg
8bafc3692d fixed the comment for 'path' 2001-01-24 14:03:48 +00:00
Daniel Stenberg
8a75120568 added comments all over 2001-01-24 12:32:34 +00:00
Daniel Stenberg
3d96ee7423 extended the gname field one byte to avoid a possible overflow
added lots of explaining comments
2001-01-24 12:10:10 +00:00
Daniel Stenberg
b3dbdfa306 Robert Weaver's fix 2001-01-24 09:01:32 +00:00
Daniel Stenberg
25bad589ba generated by autoheader 2001-01-23 13:00:43 +00:00
Daniel Stenberg
0b6cd75004 ipv6 adjustments 2001-01-23 10:29:16 +00:00
Daniel Stenberg
7872cc131a Enabled support for IPv6-style IP-addresses if ENABLE_IPV6 is set. If it isn't,
curl will return an error when such an address is used.
2001-01-23 10:21:30 +00:00
Daniel Stenberg
210aa4371c big reorg to make it not exit when it fails, but instead just not do any
globbing, it makes IPv6 support easier and smoother to add.
2001-01-23 10:14:43 +00:00
Daniel Stenberg
6f438bc8fb Added 'ipv6 enabled' for ipv6 compiled versions 2001-01-23 08:16:59 +00:00
Daniel Stenberg
65840f1fd1 Added simple IPv6 recognition support 2001-01-22 23:54:54 +00:00
Daniel Stenberg
5fc492e5c6 Bjrn's progress meter fix, new test cases and ftpserver.pl patch 2001-01-22 16:25:55 +00:00
Daniel Stenberg
abcd1e7d5a Bjrn Stenberg's patch for making the progress meter betterlooking 2001-01-22 16:21:05 +00:00
Daniel Stenberg
6429c378a2 the custom reply engine was not inited properly 2001-01-22 16:16:18 +00:00
Daniel Stenberg
d830f10417 test case 121 2001-01-22 16:05:12 +00:00
Daniel Stenberg
3d6fcbf97b Added test case 120, ftp with '-Q -' 2001-01-22 16:00:28 +00:00
Daniel Stenberg
609be218c2 Removed the deprecated -c and -t from the --help output. 2001-01-22 10:09:04 +00:00
Daniel Stenberg
41084e57ca Added 5.5 the CURLOPT_FILE problem on win32, DeYoung provided it! 2001-01-22 08:42:00 +00:00
Daniel Stenberg
9afab85105 Added -g/--globoff description 2001-01-19 12:24:46 +00:00
Daniel Stenberg
7822233964 Made the complaint on free-twice errors a lot better 2001-01-19 12:20:30 +00:00
Daniel Stenberg
022315089b removed URL length restrictions, added a test case 2001-01-19 12:20:02 +00:00
Daniel Stenberg
faa5c14aee No more URL length restrictions 2001-01-19 12:15:23 +00:00
Daniel Stenberg
3dd886955b removed MAX_URL_LENGTH, there is no longer any length restrictions on URLs
anywhere within libcurl
2001-01-19 12:14:55 +00:00
Daniel Stenberg
c2dbf21459 corrected url memory handling with --globoff 2001-01-19 12:14:09 +00:00
Daniel Stenberg
133eb220b9 Added files for test case 28 2001-01-19 12:13:37 +00:00
Daniel Stenberg
c5796d9e39 --globoff test case 2001-01-19 12:12:54 +00:00
43 changed files with 882 additions and 761 deletions

75
CHANGES
View File

@@ -6,6 +6,81 @@
History of Changes
Version 7.6
Daniel (26 January 2001)
- Lots of mails back and forth with Bob Schader finally made me add a small
piece of code in the HTTP engine so that HTTP upload resume works. You can
now do an operation like 'curl -T file -C <offset> <URL>' and curl will PUT
the ending part of the file starting at given offet to the specified URL.
Version 7.6-pre4
Daniel (25 January 2001)
- I took hold of Rick Jones' question why we don't use recv() and send() for
reading/writing to the sockets and I've now modified the sread() and
swrite() macros to use them instead. If nothing else, they could be tested
in the next beta-round coming right up.
- Jeff Morrow found a problem with libcurl's usage of SSL_read() and supplied
his research results in how to fix this. It turns out we have to invoke the
function several times in some cases. The same goes for the SSL_write().
I made some rather drastic changes all over libcurl to make all writes and
reads get done on one single place so that this repeated-attempts thing
would only have to be implemented at one point.
- Rick Jones spotted that the 'total time' counter really didn't measure the
total time very accurate on subsecond levels.
- Johan Nilsson pointed out the need to more clearly specify that the timeout
value you set for a download is for the *entire* download. There's currently
no option available that sets a timeout for the connection phase only.
Daniel (24 January 2001)
- Ingo Ralf Blum submitted a series of patches required to get curl to compile
properly with cygwin.
- Robert Weaver posted a fix for the win32 section of the curl_getenv() code
that corrected a potential memory leak.
- Added comments in a few files in a sudden attempt to make the sources more
easy to read and understand!
Daniel (23 January 2001)
- Added simple IPv6 detection in the configure script and made the version
string add 'ipv6' to the enable section in that case. ENABLE_IPV6 will be
set if curl is compiled with IPv6 support enabled.
- Added a parser for IPv6-style specified IP-addresses in a URL. Thus, when
IPv6 gets enabled soon, we can use URLs like '[0::1]:80'...
- Made the URL globbing in the client possible to fail silently if there's an
error in the globbing. It makes it almost intuitive, so when you don't
follow the syntax rules, globbing is simply switched off and the raw string
is used instead.
I still think we'll get problems with IPv6-style IP-addresses when we *want*
globbing on parts of the URL as the initial part of the URL will for sure
seriously confuse the globber.
Daniel (22 January 2001)
- Bj<42>rn Stenberg supplied a progress meter patch that makes it look better even
during slow starts. Previously it made some silly assumptions...
- Added two FTP tests for -Q and -Q - stuff since it was being discussed on
the mailing list. Had to correct the ftpserver.pl too as it bugged slightly.
Daniel (19 January 2001)
- Made the Location: parsers deal with any-length URLs. Thus I removed the last
code that restricts the length of URLs that curl supports.
- Added a --globoff test case (#28) and it quickly identified a memory problem
in src/main.c that I took care of.
Version 7.6-pre3
Daniel (17 January 2001)
- Made the two former files lib/download.c and lib/highlevel.c become the new
lib/transfer.c which makes more sense. I also did the rename from Transfer()

View File

@@ -36,3 +36,6 @@
/* Define if you have the Kerberos4 libraries (including -ldes) */
#undef KRB4
/* Define if you want to enable IPv6 support */
#undef ENABLE_IPV6

View File

@@ -1,312 +0,0 @@
/* config.h.in. Generated automatically from configure.in by autoheader. */
/* Define if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
#ifndef _ALL_SOURCE
#undef _ALL_SOURCE
#endif
/* Define to empty if the keyword does not work. */
#undef const
/* Define as the return type of signal handlers (int or void). */
#undef RETSIGTYPE
/* Define to `unsigned' if <sys/types.h> doesn't define. */
#undef size_t
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define cpu-machine-OS */
#undef OS
/* Define if you have the gethostbyaddr_r() function with 5 arguments */
#undef HAVE_GETHOSTBYADDR_R_5
/* Define if you have the gethostbyaddr_r() function with 7 arguments */
#undef HAVE_GETHOSTBYADDR_R_7
/* Define if you have the gethostbyaddr_r() function with 8 arguments */
#undef HAVE_GETHOSTBYADDR_R_8
/* Define if you have the gethostbyname_r() function with 3 arguments */
#undef HAVE_GETHOSTBYNAME_R_3
/* Define if you have the gethostbyname_r() function with 5 arguments */
#undef HAVE_GETHOSTBYNAME_R_5
/* 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
/* The number of bytes in a long long. */
#undef SIZEOF_LONG_LONG
/* Define if you have the RAND_screen function. */
#undef HAVE_RAND_SCREEN
/* Define if you have the RAND_status function. */
#undef HAVE_RAND_STATUS
/* Define if you have the closesocket function. */
#undef HAVE_CLOSESOCKET
/* Define if you have the gethostbyaddr function. */
#undef HAVE_GETHOSTBYADDR
/* Define if you have the gethostbyaddr_r function. */
#undef HAVE_GETHOSTBYADDR_R
/* Define if you have the gethostbyname_r function. */
#undef HAVE_GETHOSTBYNAME_R
/* Define if you have the gethostname function. */
#undef HAVE_GETHOSTNAME
/* Define if you have the getpass_r function. */
#undef HAVE_GETPASS_R
/* Define if you have the getservbyname function. */
#undef HAVE_GETSERVBYNAME
/* Define if you have the gettimeofday function. */
#undef HAVE_GETTIMEOFDAY
/* Define if you have the inet_addr function. */
#undef HAVE_INET_ADDR
/* Define if you have the inet_ntoa function. */
#undef HAVE_INET_NTOA
/* 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
/* Define if you have the perror function. */
#undef HAVE_PERROR
/* Define if you have the select function. */
#undef HAVE_SELECT
/* Define if you have the setvbuf function. */
#undef HAVE_SETVBUF
/* Define if you have the sigaction function. */
#undef HAVE_SIGACTION
/* Define if you have the signal function. */
#undef HAVE_SIGNAL
/* Define if you have the socket function. */
#undef HAVE_SOCKET
/* Define if you have the strcasecmp function. */
#undef HAVE_STRCASECMP
/* Define if you have the strcmpi function. */
#undef HAVE_STRCMPI
/* Define if you have the strdup function. */
#undef HAVE_STRDUP
/* Define if you have the strftime function. */
#undef HAVE_STRFTIME
/* 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
/* Define if you have the tcgetattr function. */
#undef HAVE_TCGETATTR
/* Define if you have the tcsetattr function. */
#undef HAVE_TCSETATTR
/* Define if you have the uname function. */
#undef HAVE_UNAME
/* Define if you have the <alloca.h> header file. */
#undef HAVE_ALLOCA_H
/* Define if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* 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
/* Define if you have the <err.h> header file. */
#undef HAVE_ERR_H
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
/* 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
/* Define if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
/* 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
/* Define if you have the <openssl/crypto.h> header file. */
#undef HAVE_OPENSSL_CRYPTO_H
/* Define if you have the <openssl/err.h> header file. */
#undef HAVE_OPENSSL_ERR_H
/* Define if you have the <openssl/pem.h> header file. */
#undef HAVE_OPENSSL_PEM_H
/* Define if you have the <openssl/rsa.h> header file. */
#undef HAVE_OPENSSL_RSA_H
/* Define if you have the <openssl/ssl.h> header file. */
#undef HAVE_OPENSSL_SSL_H
/* Define if you have the <openssl/x509.h> header file. */
#undef HAVE_OPENSSL_X509_H
/* Define if you have the <pem.h> header file. */
#undef HAVE_PEM_H
/* Define if you have the <rsa.h> header file. */
#undef HAVE_RSA_H
/* Define if you have the <sgtty.h> header file. */
#undef HAVE_SGTTY_H
/* Define if you have the <ssl.h> header file. */
#undef HAVE_SSL_H
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define if you have the <sys/sockio.h> header file. */
#undef HAVE_SYS_SOCKIO_H
/* Define if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define if you have the <termio.h> header file. */
#undef HAVE_TERMIO_H
/* Define if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the <winsock.h> header file. */
#undef HAVE_WINSOCK_H
/* Define if you have the <x509.h> header file. */
#undef HAVE_X509_H
/* Define if you have the crypto library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define if you have the dl library (-ldl). */
#undef HAVE_LIBDL
/* 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
/* Define if you have the socket library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define if you have the ssl library (-lssl). */
#undef HAVE_LIBSSL
/* Define if you have the ucb library (-lucb). */
#undef HAVE_LIBUCB
/* Name of package */
#undef PACKAGE
/* 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

@@ -237,6 +237,44 @@ exit (rc != 0 ? 1 : 0); }],[
])
dnl **********************************************************************
dnl Checks for IPv6
dnl **********************************************************************
AC_MSG_CHECKING([whether to enable ipv6])
AC_ARG_ENABLE(ipv6,
[ --enable-ipv6 Enable ipv6 (with ipv4) support
--disable-ipv6 Disable ipv6 support],
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
ipv6=no
;;
*) AC_MSG_RESULT(yes)
AC_DEFINE(ENABLE_IPV6)
ipv6=yes
;;
esac ],
AC_TRY_RUN([ /* is AF_INET6 available? */
#include <sys/types.h>
#include <sys/socket.h>
main()
{
if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
exit(1);
else
exit(0);
}
],
AC_MSG_RESULT(yes)
AC_DEFINE(ENABLE_IPV6)
ipv6=yes,
AC_MSG_RESULT(no)
ipv6=no,
AC_MSG_RESULT(no)
ipv6=no
))
dnl **********************************************************************
dnl Checks for libraries.
@@ -590,6 +628,9 @@ AC_CHECK_FUNCS( socket \
dnl removed 'getpass' check on October 26, 2000
if test "$ac_cv_func_select" != "yes"; then
AC_MSG_ERROR(Can't work without an existing select() function)
fi
if test "$ac_cv_func_socket" != "yes"; then
AC_MSG_ERROR(Can't work without an existing socket() function)
fi

View File

@@ -1,4 +1,4 @@
Updated: January 15, 2001 (http://curl.haxx.se/docs/faq.shtml)
Updated: January 22, 2001 (http://curl.haxx.se/docs/faq.shtml)
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
@@ -52,6 +52,7 @@ FAQ
5.2 How can I receive all data into a large memory chunk?
5.3 How do I fetch multiple files with libcurl?
5.4 Does libcurl do Winsock initing on win32 systems?
5.5 Does CURLOPT_FILE work on win32 ?
6. License Issues
6.1 I have a GPL program, can I use the libcurl library?
@@ -472,6 +473,15 @@ FAQ
use several different libraries and parts, and there's no reason for every
single library to do this.
5.5 Does CURLOPT_FILE work on win32 ?
Yes, but you cannot open a FILE * and pass the pointer to a DLL and have
that DLL use the FILE *. You must use CURLOPT_WRITEFUNCTION as well to set a
function that writes the file, even if that simply writes the data to the
specified FILE*.
(provided by Joel DeYoung)
6. License Issues
NOTE: This section is now updated to concern curl 7.5.2 or later!

View File

@@ -1,3 +1,4 @@
Updated for curl 7.6 on January 26, 2001
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
@@ -12,13 +13,6 @@ INTERNALS
Thus, the largest amount of code and complexity is in the library part.
SYMBOLS
=======
All symbols used internally must use a 'Curl_' prefix if they're used in more
than a single file. Single-file symbols must be made static. Public
(exported) symbols must use a 'curl_' prefix. (There are exceptions, but they
are destined to be changed to follow this pattern in the future.)
CVS
===
All changes to the sources are committed to the CVS repository as soon as
@@ -35,10 +29,11 @@ Windows vs Unix
There are a few differences in how to program curl the unix way compared to
the Windows way. The four perhaps most notable details are:
1. Different function names for close(), read(), write()
1. Different function names for socket operations.
In curl, this is solved with defines and macros, so that the source looks
the same at all places except for the header file that defines them.
the same at all places except for the header file that defines them. The
macros in use are sclose(), sread() and swrite().
2. Windows requires a couple of init calls for the socket stuff
@@ -187,6 +182,15 @@ Library
exists in lib/getpass.c. libcurl offers a custom callback that can be used
instead of this, but it doesn't change much to us.
Library Symbols
===============
All symbols used internally in libcurl must use a 'Curl_' prefix if they're
used in more than a single file. Single-file symbols must be made
static. Public (exported) symbols must use a 'curl_' prefix. (There are
exceptions, but they are destined to be changed to follow this pattern in the
future.)
Return Codes and Informationals
===============================

View File

@@ -2,7 +2,7 @@
.\" nroff -man curl.1
.\" Written by Daniel Stenberg
.\"
.TH curl 1 "9 January 2001" "Curl 7.6" "Curl Manual"
.TH curl 1 "19 January 2001" "Curl 7.6" "Curl Manual"
.SH NAME
curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or
HTTPS syntax.
@@ -205,6 +205,12 @@ To read the file's content from stdin insted of a file, use - where the file
name should've been. This goes for both @ and < constructs.
This option can be used multiple times.
.IP "-g/--globoff"
This option switches off the "URL globbing parser". When you set this option,
you can specify URLs that contain the letters {}[] without having them being
interpreted by curl itself. Note that these letters are not normal legal URL
contents but they should be encoded according to the URI standard. (Option
added in curl 7.6)
.IP "-h/--help"
Usage help.
.IP "-H/--header <header>"
@@ -780,6 +786,8 @@ If you do find bugs, mail them to curl-bug@haxx.se.
- Alexander Kourakos <awk@users.sourceforge.net>
- James Griffiths <griffiths_james@yahoo.com>
- Loic Dachary <loic@senga.org>
- Robert Weaver <robert.weaver@sabre.com>
- Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
.SH WWW
http://curl.haxx.se

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file]
.\" Written by daniel@haxx.se
.\"
.TH curl_easy_perform 3 "26 May 2000" "Curl 7.0" "libcurl Manual"
.TH curl_easy_perform 3 "25 Jan 2001" "Curl 7.0" "libcurl Manual"
.SH NAME
curl_easy_perform - Do the actual transfer in a "easy" session
.SH SYNOPSIS
@@ -16,6 +16,10 @@ are made, and will perform the transfer as described in the options.
It must be called with the same
.I handle
as input as the curl_easy_init call returned.
You are only allowed to call this function once using the same handle. If you
want to do repeated calls, you must call curl_easy_cleanup and curl_easy_init
again first.
.SH RETURN VALUE
0 means everything was ok, non-zero means an error occurred as
.I <curl/curl.h>

View File

@@ -166,10 +166,6 @@ typedef enum {
#define CURL_ERROR_SIZE 256
/* maximum URL length we deal with in headers */
#define URL_MAX_LENGTH 4096
#define URL_MAX_LENGTH_TXT "4095"
/* name is uppercase CURLOPT_<name>,
type is one of the defined CURLOPTTYPE_<type>
number is unique identifier */
@@ -456,7 +452,7 @@ char *curl_getenv(char *variable);
char *curl_version(void);
/* This is the version number */
#define LIBCURL_VERSION "7.6-pre3"
#define LIBCURL_VERSION "7.6"
#define LIBCURL_VERSION_NUM 0x070600
/* linked-list structure for the CURLOPT_QUOTE option (and other) */

View File

@@ -141,21 +141,21 @@ CURLcode Curl_dict(struct connectdata *conn)
nth = atoi(nthdef);
}
sendf(data->firstsocket, data,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
"MATCH "
"%s " /* database */
"%s " /* strategy */
"%s\n" /* word */
"QUIT\n",
Curl_sendf(data->firstsocket, conn,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
"MATCH "
"%s " /* database */
"%s " /* strategy */
"%s\n" /* word */
"QUIT\n",
database,
strategy,
word
);
database,
strategy,
word
);
result = Curl_Transfer(conn, data->firstsocket, -1, FALSE, bytecount,
-1, NULL); /* no upload */
-1, NULL); /* no upload */
if(result)
return result;
@@ -191,20 +191,20 @@ CURLcode Curl_dict(struct connectdata *conn)
nth = atoi(nthdef);
}
sendf(data->firstsocket, data,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
"DEFINE "
"%s " /* database */
"%s\n" /* word */
"QUIT\n",
database,
word
);
Curl_sendf(data->firstsocket, conn,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
"DEFINE "
"%s " /* database */
"%s\n" /* word */
"QUIT\n",
database,
word
);
result = Curl_Transfer(conn, data->firstsocket, -1, FALSE, bytecount,
-1, NULL); /* no upload */
-1, NULL); /* no upload */
if(result)
return result;
@@ -220,14 +220,14 @@ CURLcode Curl_dict(struct connectdata *conn)
if (ppath[i] == ':')
ppath[i] = ' ';
}
sendf(data->firstsocket, data,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
"%s\n"
"QUIT\n",
ppath);
Curl_sendf(data->firstsocket, conn,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
"%s\n"
"QUIT\n",
ppath);
result = Curl_Transfer(conn, data->firstsocket, -1, FALSE, bytecount,
-1, NULL);
-1, NULL);
if(result)
return result;

View File

@@ -221,7 +221,7 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
int *ftpcode)
{
int nread;
int keepon=TRUE;
size_t keepon=TRUE;
char *ptr;
int timeout = 3600; /* in seconds */
struct timeval interval;
@@ -272,22 +272,17 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
break;
case 0: /* timeout */
error = SELECT_TIMEOUT;
infof(data, "Transfer aborted due to timeout\n");
failf(data, "Transfer aborted due to timeout");
break;
default:
#ifdef USE_SSLEAY
if (data->ssl.use) {
keepon = SSL_read(data->ssl.handle, ptr, 1);
}
else {
#endif
keepon = sread(sockfd, ptr, 1);
#ifdef USE_SSLEAY
}
#endif /* USE_SSLEAY */
if ((*ptr == '\n') || (*ptr == '\r'))
/*
* This code previously didn't use the kerberos sec_read() code
* to read, but when we use Curl_read() it may do so. Do confirm
* that this is still ok and then remove this comment!
*/
if(CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &keepon))
keepon = FALSE;
else if ((*ptr == '\n') || (*ptr == '\r'))
keepon = FALSE;
}
if(keepon) {
@@ -372,7 +367,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
if (data->bits.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
result = Curl_ConnectHTTPProxyTunnel(data, data->firstsocket,
result = Curl_ConnectHTTPProxyTunnel(conn, data->firstsocket,
data->hostname, data->remote_port);
if(CURLE_OK != result)
return result;
@@ -979,7 +974,7 @@ CURLcode _ftp(struct connectdata *conn)
if (data->bits.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
result = Curl_ConnectHTTPProxyTunnel(data, data->secondarysocket,
result = Curl_ConnectHTTPProxyTunnel(conn, data->secondarysocket,
newhost, newport);
if(CURLE_OK != result)
return result;

View File

@@ -41,12 +41,13 @@ char *GetEnv(char *variable)
char env[MAX_PATH]; /* MAX_PATH is from windef.h */
char *temp = getenv(variable);
env[0] = '\0';
ExpandEnvironmentStrings(temp, env, sizeof(env));
if (temp != NULL)
ExpandEnvironmentStrings(temp, env, sizeof(env));
#else
/* no length control */
char *env = getenv(variable);
#endif
return env?strdup(env):NULL;
return (env && env[0])?strdup(env):NULL;
}
char *curl_getenv(char *v)

View File

@@ -94,7 +94,6 @@
#include "base64.h"
#include "cookie.h"
#include "strequal.h"
#include "url.h"
#include "ssluse.h"
#define _MPRINTF_REPLACE /* use our functions only */
@@ -141,7 +140,7 @@ size_t add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in)
fwrite(in->buffer, in->size_used, 1, conn->data->err);
}
amount = ssend(sockfd, conn, in->buffer, in->size_used);
Curl_write(conn, sockfd, in->buffer, in->size_used, &amount);
if(in->buffer)
free(in->buffer);
@@ -213,28 +212,21 @@ CURLcode add_buffer(send_buffer *in, void *inptr, size_t size)
*/
static
int GetLine(int sockfd, char *buf, struct UrlData *data)
int GetLine(int sockfd, char *buf, struct connectdata *conn)
{
int nread;
size_t nread;
int read_rc=1;
char *ptr;
struct UrlData *data=conn->data;
ptr=buf;
/* get us a full line, terminated with a newline */
for(nread=0;
(nread<BUFSIZE) && read_rc;
nread++, ptr++) {
#ifdef USE_SSLEAY
if (data->ssl.use) {
read_rc = SSL_read(data->ssl.handle, ptr, 1);
}
else {
#endif
read_rc = sread(sockfd, ptr, 1);
#ifdef USE_SSLEAY
}
#endif /* USE_SSLEAY */
if (*ptr == '\n')
if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) ||
(*ptr == '\n'))
break;
}
*ptr=0; /* zero terminate */
@@ -272,27 +264,29 @@ bool static checkheaders(struct UrlData *data, char *thisheader)
* this proxy. After that, the socket can be used just as a normal socket.
*/
CURLcode Curl_ConnectHTTPProxyTunnel(struct UrlData *data, int tunnelsocket,
CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
int tunnelsocket,
char *hostname, int remote_port)
{
int httperror=0;
int subversion=0;
struct UrlData *data=conn->data;
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:"")
);
/* OK, now send the connect request to the proxy */
Curl_sendf(tunnelsocket, conn,
"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)) {
while(GetLine(tunnelsocket, data->buffer, conn)) {
if('\r' == data->buffer[0])
break; /* end of headers */
if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
@@ -330,7 +324,7 @@ CURLcode Curl_http_connect(struct connectdata *conn)
if (conn->protocol & PROT_HTTPS) {
if (data->bits.httpproxy) {
/* HTTPS through a proxy can only be done with a tunnel */
result = Curl_ConnectHTTPProxyTunnel(data, data->firstsocket,
result = Curl_ConnectHTTPProxyTunnel(conn, data->firstsocket,
data->hostname, data->remote_port);
if(CURLE_OK != result)
return result;
@@ -477,6 +471,64 @@ CURLcode Curl_http(struct connectdata *conn)
if(!checkheaders(data, "Accept:"))
http->p_accept = "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n";
if((data->bits.http_post ||
data->bits.http_formpost ||
data->bits.http_put) &&
data->resume_from) {
/**********************************************************************
* Resuming upload in HTTP means that we PUT or POST and that we have
* got a resume_from value set. The resume value has already created
* a Range: header that will be passed along. We need to "fast forward"
* the file the given number of bytes and decrease the assume upload
* file size before we continue this venture in the dark lands of HTTP.
*********************************************************************/
if(data->resume_from < 0 ) {
/*
* This is meant to get the size of the present remote-file by itself.
* We don't support this now. Bail out!
*/
data->resume_from = 0;
}
if(data->resume_from) {
/* do we still game? */
int passed=0;
/* Now, let's read off the proper amount of bytes from the
input. If we knew it was a proper file we could've just
fseek()ed but we only have a stream here */
do {
int readthisamountnow = (data->resume_from - passed);
int actuallyread;
if(readthisamountnow > BUFSIZE)
readthisamountnow = BUFSIZE;
actuallyread =
data->fread(data->buffer, 1, readthisamountnow, data->in);
passed += actuallyread;
if(actuallyread != readthisamountnow) {
failf(data, "Could only read %d bytes from the input\n",
passed);
return CURLE_READ_ERROR;
}
} while(passed != data->resume_from); /* loop until done */
/* now, decrease the size of the read */
if(data->infilesize>0) {
data->infilesize -= data->resume_from;
if(data->infilesize <= 0) {
failf(data, "File already completely uploaded\n");
return CURLE_PARTIAL_FILE;
}
}
/* we've passed, proceed as normal */
}
}
do {
send_buffer *req_buffer;
struct curl_slist *headers=data->headers;

View File

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

View File

@@ -32,7 +32,7 @@
#include <unistd.h>
#endif
#if ! defined(WIN32) && ! defined(__BEOS__)
#if ! defined(WIN32) && ! defined(__BEOS__) && !defined(__CYGWIN32__)
#ifdef NEED_REENTRANT
#define _REENTRANT

View File

@@ -283,7 +283,9 @@ krb4_auth(void *app_data, struct connectdata *conn)
u_int32_t cs;
struct krb4_data *d = app_data;
struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR;
#if 0
struct sockaddr_in *remoteaddr = (struct sockaddr_in *)REMOTE_ADDR;
#endif
char *host = conn->hp->h_name;
size_t nread;
int l = sizeof(local_addr);
@@ -313,7 +315,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
else {
if (natAddr.s_addr != localaddr->sin_addr.s_addr) {
printf("Using NAT IP address (%s) for kerberos 4\n",
inet_ntoa(natAddr));
(char *)inet_ntoa(natAddr));
localaddr->sin_addr = natAddr;
/*
@@ -399,7 +401,6 @@ void krb_kauth(struct connectdata *conn)
KTEXT_ST tkt, tktcopy;
char *name;
char *p;
int overbose;
char passwd[100];
int tmp;
size_t nread;
@@ -417,12 +418,10 @@ void krb_kauth(struct connectdata *conn)
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");
@@ -444,7 +443,6 @@ void krb_kauth(struct connectdata *conn)
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;

View File

@@ -212,14 +212,14 @@ int Curl_pgrsUpdate(struct UrlData *data)
now = Curl_tvnow(); /* what time is it */
/* The exact time spent so far */
data->progress.timespent = Curl_tvdiff (now, data->progress.start);
if(data->progress.lastshow == Curl_tvlong(now))
return 0; /* never update this more than once a second if the end isn't
reached */
data->progress.lastshow = now.tv_sec;
/* The exact time spent so far */
data->progress.timespent = Curl_tvdiff (now, data->progress.start);
/* The average download speed this far */
data->progress.dlspeed = data->progress.downloaded/(data->progress.timespent!=0.0?data->progress.timespent:1.0);
@@ -257,17 +257,13 @@ int Curl_pgrsUpdate(struct UrlData *data)
}
/* Figure out the estimated time of arrival for the upload */
if(data->progress.flags & PGRS_UL_SIZE_KNOWN) {
if(!data->progress.ulspeed)
data->progress.ulspeed=1;
if((data->progress.flags & PGRS_UL_SIZE_KNOWN) && data->progress.ulspeed){
ulestimate = data->progress.size_ul / data->progress.ulspeed;
ulpercen = (data->progress.uploaded / data->progress.size_ul)*100;
}
/* ... and the download */
if(data->progress.flags & PGRS_DL_SIZE_KNOWN) {
if(!data->progress.dlspeed)
data->progress.dlspeed=1;
if((data->progress.flags & PGRS_DL_SIZE_KNOWN) && data->progress.dlspeed) {
dlestimate = data->progress.size_dl / data->progress.dlspeed;
dlpercen = (data->progress.downloaded / data->progress.size_dl)*100;
}

View File

@@ -77,59 +77,87 @@ void Curl_failf(struct UrlData *data, char *fmt, ...)
va_end(ap);
}
/* sendf() sends the formated data to the server */
size_t Curl_sendf(int fd, struct UrlData *data, char *fmt, ...)
/* Curl_sendf() sends formated data to the server */
size_t Curl_sendf(int sockfd, struct connectdata *conn,
char *fmt, ...)
{
struct UrlData *data = conn->data;
size_t bytes_written;
char *s;
va_list ap;
va_start(ap, fmt);
s = vaprintf(fmt, ap);
s = vaprintf(fmt, ap); /* returns an allocated string */
va_end(ap);
if(!s)
return 0; /* failure */
if(data->bits.verbose)
fprintf(data->err, "> %s", s);
#ifndef USE_SSLEAY
bytes_written = swrite(fd, s, strlen(s));
#else /* USE_SSLEAY */
if (data->ssl.use) {
bytes_written = SSL_write(data->ssl.handle, s, strlen(s));
} else {
bytes_written = swrite(fd, s, strlen(s));
}
#endif /* USE_SSLEAY */
/* Write the buffer to the socket */
Curl_write(conn, sockfd, s, strlen(s), &bytes_written);
free(s); /* free the output string */
return(bytes_written);
return bytes_written;
}
/* ssend() sends plain (binary) data to the server */
size_t Curl_ssend(int fd, struct connectdata *conn, void *mem, size_t len)
/*
* Curl_write() is an internal write function that sends plain (binary) data
* to the server. Works with plain sockets, SSL or kerberos.
*
*/
CURLcode Curl_write(struct connectdata *conn, int sockfd,
void *mem, size_t len,
size_t *written)
{
size_t bytes_written;
struct UrlData *data=conn->data; /* conn knows data, not vice versa */
#ifdef USE_SSLEAY
if (data->ssl.use) {
bytes_written = SSL_write(data->ssl.handle, mem, len);
int loop=100; /* just a precaution to never loop endlessly */
while(loop--) {
bytes_written = SSL_write(data->ssl.handle, mem, len);
if((-1 != bytes_written) ||
(SSL_ERROR_WANT_WRITE != SSL_get_error(data->ssl.handle,
bytes_written) ))
break;
}
}
else {
#endif
#ifdef KRB4
if(conn->sec_complete) {
bytes_written = sec_write(conn, fd, mem, len);
bytes_written = sec_write(conn, sockfd, mem, len);
}
else
#endif /* KRB4 */
bytes_written = swrite(fd, mem, len);
bytes_written = swrite(sockfd, mem, len);
#ifdef USE_SSLEAY
}
#endif
return bytes_written;
*written = bytes_written;
return CURLE_OK;
}
/*
* External write-function, writes to the data-socket.
* Takes care of plain sockets, SSL or kerberos transparently.
*/
CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount,
size_t *n)
{
struct connectdata *conn = (struct connectdata *)c_conn;
if(!n || !conn || (conn->handle != STRUCT_CONNECT))
return CURLE_FAILED_INIT;
return Curl_write(conn, conn->sockfd, buf, amount, n);
}
/* client_write() sends data to the write callback(s)
The bit pattern defines to what "streams" to write to. Body and/or header.
@@ -163,3 +191,56 @@ CURLcode Curl_client_write(struct UrlData *data,
return CURLE_OK;
}
/*
* Internal read-from-socket function. This is meant to deal with plain
* sockets, SSL sockets and kerberos sockets.
*/
CURLcode Curl_read(struct connectdata *conn, int sockfd,
char *buf, size_t buffersize,
size_t *n)
{
struct UrlData *data = conn->data;
size_t nread;
#ifdef USE_SSLEAY
if (data->ssl.use) {
int loop=100; /* just a precaution to never loop endlessly */
while(loop--) {
nread = SSL_read(data->ssl.handle, buf, buffersize);
if((-1 != nread) ||
(SSL_ERROR_WANT_READ != SSL_get_error(data->ssl.handle, nread) ))
break;
}
}
else {
#endif
#ifdef KRB4
if(conn->sec_complete)
nread = sec_read(conn, sockfd, buf, buffersize);
else
#endif
nread = sread (sockfd, buf, buffersize);
#ifdef USE_SSLEAY
}
#endif /* USE_SSLEAY */
*n = nread;
return CURLE_OK;
}
/*
* The public read function reads from the 'sockfd' file descriptor only.
* Use the Curl_read() internally when you want to specify fd.
*/
CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize,
size_t *n)
{
struct connectdata *conn = (struct connectdata *)c_conn;
if(!n || !conn || (conn->handle != STRUCT_CONNECT))
return CURLE_FAILED_INIT;
return Curl_read(conn, conn->sockfd, buf, buffersize, n);
}

View File

@@ -23,13 +23,10 @@
* $Id$
*****************************************************************************/
size_t Curl_sendf(int fd, struct UrlData *, char *fmt, ...);
size_t Curl_ssend(int fd, struct connectdata *, void *fmt, size_t len);
size_t Curl_sendf(int fd, struct connectdata *, char *fmt, ...);
void Curl_infof(struct UrlData *, char *fmt, ...);
void Curl_failf(struct UrlData *, char *fmt, ...);
#define sendf Curl_sendf
#define ssend Curl_ssend
#define infof Curl_infof
#define failf Curl_failf
@@ -47,4 +44,13 @@ typedef struct send_buffer send_buffer;
CURLcode Curl_client_write(struct UrlData *data, int type, char *ptr,
size_t len);
/* internal read-function, does plain socket, SSL and krb4 */
CURLcode Curl_read(struct connectdata *conn, int sockfd,
char *buf, size_t buffersize,
size_t *n);
/* internal write-function, does plain socket, SSL and krb4 */
CURLcode Curl_write(struct connectdata *conn, int sockfd,
void *mem, size_t len,
size_t *written);
#endif

View File

@@ -100,7 +100,6 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
1. close a socket
2. read from a socket
3. write to a socket
(Hopefully, only win32-crap do this weird name changing)
4. set the SIGALRM signal timeout
5. set dir/file naming defines
@@ -115,8 +114,8 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
#else
/* gcc-for-win is still good :) */
#define sclose(x) close(x)
#define sread(x,y,z) read(x,y,z)
#define swrite(x,y,z) write(x,y,z)
#define sread(x,y,z) recv(x,y,z,0)
#define swrite(x,y,z) send(x,y,z,0)
#define myalarm(x) alarm(x)
#endif

View File

@@ -73,8 +73,6 @@
#include <curl/curl.h>
#include "transfer.h"
#include "sendf.h"
#include "formdata.h"
#include "progress.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -97,11 +95,6 @@
#define SB_EOF() (subpointer >= subend)
#define SB_LEN() (subend - subpointer)
static
void telwrite(struct UrlData *data,
unsigned char *buffer, /* Data to write */
int count); /* Number of bytes to write */
static
void telrcv(struct UrlData *data,
unsigned char *inbuf, /* Data received from socket */
@@ -826,36 +819,6 @@ void telrcv(struct UrlData *data,
}
}
static
void telwrite(struct UrlData *data,
unsigned char *buffer, /* Data to write */
int count) /* Number of bytes to write */
{
unsigned char outbuf[2];
int out_count = 0;
int bytes_written;
while(count--)
{
outbuf[0] = *buffer++;
out_count = 1;
if(outbuf[0] == IAC)
outbuf[out_count++] = IAC;
#ifndef USE_SSLEAY
bytes_written = swrite(data->firstsocket, outbuf, out_count);
#else
if (data->ssl.use) {
bytes_written = SSL_write(data->ssl.handle, (char *)outbuf,
out_count);
}
else {
bytes_written = swrite(data->firstsocket, outbuf, out_count);
}
#endif /* USE_SSLEAY */
}
}
CURLcode Curl_telnet_done(struct connectdata *conn)
{
return CURLE_OK;
@@ -870,7 +833,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
bool keepon = TRUE;
char *buf = data->buffer;
int nread;
size_t nread;
init_telnet(data);
@@ -880,49 +843,49 @@ CURLcode Curl_telnet(struct connectdata *conn)
keepfd = readfd;
while (keepon)
{
readfd = keepfd; /* set this every lap in the loop */
while (keepon) {
readfd = keepfd; /* set this every lap in the loop */
switch (select (sockfd + 1, &readfd, NULL, NULL, NULL))
{
case -1: /* error, stop reading */
keepon = FALSE;
continue;
case 0: /* timeout */
break;
default: /* read! */
if(FD_ISSET(1, &readfd))
{
nread = read(1, buf, 255);
telwrite(data, (unsigned char *)buf, nread);
}
switch (select (sockfd + 1, &readfd, NULL, NULL, NULL)) {
case -1: /* error, stop reading */
keepon = FALSE;
continue;
case 0: /* timeout */
break;
default: /* read! */
if(FD_ISSET(1, &readfd)) { /* read from stdin */
unsigned char outbuf[2];
int out_count = 0;
size_t bytes_written;
char *buffer = buf;
nread = read(1, buf, 255);
if(FD_ISSET(sockfd, &readfd))
{
#ifndef USE_SSLEAY
nread = sread (sockfd, buf, BUFSIZE - 1);
#else
if (data->ssl.use) {
nread = SSL_read (data->ssl.handle, buf, BUFSIZE - 1);
}
else {
nread = sread (sockfd, buf, BUFSIZE - 1);
}
#endif /* USE_SSLEAY */
}
/* if we receive 0 or less here, the server closed the connection and
we bail out from this! */
if (nread <= 0) {
keepon = FALSE;
break;
}
telrcv(data, (unsigned char *)buf, nread);
while(nread--) {
outbuf[0] = *buffer++;
out_count = 1;
if(outbuf[0] == IAC)
outbuf[out_count++] = IAC;
Curl_write(conn, data->firstsocket, outbuf,
out_count, &bytes_written);
}
}
}
return CURLE_OK;
if(FD_ISSET(sockfd, &readfd))
Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
/* if we receive 0 or less here, the server closed the connection and
we bail out from this! */
if (nread <= 0) {
keepon = FALSE;
break;
}
telrcv(data, (unsigned char *)buf, nread);
}
}
return CURLE_OK;
}

View File

@@ -133,8 +133,6 @@ _Transfer(struct connectdata *c_conn)
CURLcode urg;
time_t timeofdoc=0;
long bodywrites=0;
char newurl[URL_MAX_LENGTH]; /* buffer for Location: URL */
int writetype;
/* the highest fd we use + 1 */
@@ -224,7 +222,7 @@ _Transfer(struct connectdata *c_conn)
default:
if((keepon & KEEP_READ) && FD_ISSET(conn->sockfd, &readfd)) {
/* read! */
urg = curl_read(conn, buf, BUFSIZE -1, &nread);
urg = Curl_read(conn, conn->sockfd, buf, BUFSIZE -1, &nread);
/* NULL terminate, allowing string ops to be used */
if (0 < (signed int) nread)
@@ -389,12 +387,21 @@ _Transfer(struct connectdata *c_conn)
}
else if ((code >= 300 && code < 400) &&
(data->bits.http_follow_location) &&
strnequal("Location", p, 8) &&
sscanf (p+8, ": %" URL_MAX_LENGTH_TXT "s",
newurl)) {
/* this is the URL that the server advices us to get
instead */
data->newurl = strdup (newurl);
strnequal("Location: ", p, 10)) {
/* this is the URL that the server advices us to get instead */
char *ptr;
char *start=p;
char backup;
start += 10; /* pass "Location: " */
ptr = start; /* start scanning here */
/* scan through the string to find the end */
while(*ptr && !isspace((int)*ptr))
ptr++;
backup = *ptr; /* store the ending letter */
*ptr = '\0'; /* zero terminate */
data->newurl = strdup(start); /* clone string */
*ptr = backup; /* restore ending letter */
}
writetype = CLIENTWRITE_HEADER;
@@ -437,10 +444,14 @@ _Transfer(struct connectdata *c_conn)
write a chunk of the body */
if(conn->protocol&PROT_HTTP) {
/* HTTP-only checks */
if (data->resume_from && !content_range ) {
if (data->resume_from &&
!content_range &&
(data->httpreq==HTTPREQ_GET)) {
/* we wanted to resume a download, although the server
doesn't seem to support this */
failf (data, "HTTP server doesn't seem to support byte ranges. Cannot resume.");
doesn't seem to support this and we did this with a GET
(if it wasn't a GET we did a POST or PUT resume) */
failf (data, "HTTP server doesn't seem to support "
"byte ranges. Cannot resume.");
return CURLE_HTTP_RANGE_ERROR;
}
else if (data->newurl) {
@@ -534,7 +545,8 @@ _Transfer(struct connectdata *c_conn)
}
/* write to socket */
urg = curl_write(conn, buf, nread, &bytes_written);
urg = Curl_write(conn, conn->writesockfd, buf, nread,
&bytes_written);
if(nread != bytes_written) {
failf(data, "Failed uploading data");
@@ -613,8 +625,9 @@ CURLcode curl_transfer(CURL *curl)
This is assumed to happen for HTTP(S) only!
*/
char prot[16];
char path[URL_MAX_LENGTH];
char prot[16]; /* URL protocol string storage */
char letter; /* used for a silly sscanf */
if (data->maxredirs && (data->followlocation >= data->maxredirs)) {
failf(data,"Maximum (%d) redirects followed", data->maxredirs);
curl_disconnect(c_connect);
@@ -638,12 +651,11 @@ CURLcode curl_transfer(CURL *curl)
}
data->referer = strdup(data->url);
data->free_referer = TRUE; /* yes, free this later */
data->free_referer = TRUE; /* yes, free this later */
data->bits.http_set_referer = TRUE; /* might have been false */
}
if(2 != sscanf(data->newurl, "%15[^:]://%" URL_MAX_LENGTH_TXT
"s", prot, path)) {
if(2 != sscanf(data->newurl, "%15[^:]://%c", prot, &letter)) {
/***
*DANG* this is an RFC 2068 violation. The URL is supposed
to be absolute and this doesn't seem to be that!

306
lib/url.c
View File

@@ -301,6 +301,8 @@ CURLcode curl_open(CURL **curl, char *url)
data->current_speed = -1; /* init to negative == impossible */
data->httpreq = HTTPREQ_GET; /* Default HTTP request */
*curl = data;
return CURLE_OK;
}
@@ -340,6 +342,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
break;
case CURLOPT_POST:
data->bits.http_post = va_arg(param, long)?TRUE:FALSE;
data->httpreq = HTTPREQ_POST;
break;
case CURLOPT_FILETIME:
data->bits.get_filetime = va_arg(param, long)?TRUE:FALSE;
@@ -361,19 +364,17 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
break;
case CURLOPT_PUT:
data->bits.http_put = va_arg(param, long)?TRUE:FALSE;
data->httpreq = HTTPREQ_PUT;
break;
case CURLOPT_MUTE:
data->bits.mute = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_TIMECONDITION:
data->timecondition = va_arg(param, long);
break;
case CURLOPT_TIMEVALUE:
data->timevalue = va_arg(param, long);
break;
case CURLOPT_SSLVERSION:
data->ssl.version = va_arg(param, long);
break;
@@ -405,10 +406,12 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
break;
case CURLOPT_CUSTOMREQUEST:
data->customrequest = va_arg(param, char *);
data->httpreq = HTTPREQ_CUSTOM;
break;
case CURLOPT_HTTPPOST:
data->httppost = va_arg(param, struct HttpPost *);
data->bits.http_formpost = data->httppost?1:0;
data->httpreq = HTTPREQ_POST_FORM;
break;
case CURLOPT_INFILE:
data->in = va_arg(param, FILE *);
@@ -533,7 +536,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
return CURLE_OK;
}
#ifndef WIN32
#if !defined(WIN32)||defined(__CYGWIN32__)
#ifndef RETSIGTYPE
#define RETSIGTYPE void
#endif
@@ -546,67 +549,6 @@ RETSIGTYPE alarmfunc(int signal)
}
#endif
CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount,
size_t *n)
{
struct connectdata *conn = (struct connectdata *)c_conn;
struct UrlData *data;
size_t bytes_written;
if(!n || !conn || (conn->handle != STRUCT_CONNECT))
return CURLE_FAILED_INIT;
data = conn->data;
#ifdef USE_SSLEAY
if (data->ssl.use) {
bytes_written = SSL_write(data->ssl.handle, buf, amount);
}
else {
#endif
#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 */
*n = bytes_written;
return CURLE_OK;
}
CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize,
size_t *n)
{
struct connectdata *conn = (struct connectdata *)c_conn;
struct UrlData *data;
size_t nread;
if(!n || !conn || (conn->handle != STRUCT_CONNECT))
return CURLE_FAILED_INIT;
data = conn->data;
#ifdef USE_SSLEAY
if (data->ssl.use) {
nread = SSL_read (data->ssl.handle, buf, buffersize);
}
else {
#endif
#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 */
*n = nread;
return CURLE_OK;
}
CURLcode curl_disconnect(CURLconnect *c_connect)
{
struct connectdata *conn = c_connect;
@@ -635,17 +577,25 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
char resumerange[40]="";
struct UrlData *data = curl;
struct connectdata *conn;
char endbracket;
#ifdef HAVE_SIGACTION
struct sigaction sigact;
#endif
int urllen;
/*************************************************************
* Check input data
*************************************************************/
if(!data || (data->handle != STRUCT_OPEN))
return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */
if(!data->url)
return CURLE_URL_MALFORMAT;
/*************************************************************
* Allocate and initiate a connection struct
*************************************************************/
conn = (struct connectdata *)malloc(sizeof(struct connectdata));
if(!conn) {
*in_connect = NULL; /* clear the pointer */
@@ -664,6 +614,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
buf = data->buffer; /* this is our buffer */
/*************************************************************
* Set signal handler
*************************************************************/
#ifdef HAVE_SIGACTION
sigaction(SIGALRM, NULL, &sigact);
sigact.sa_handler = alarmfunc;
@@ -680,9 +633,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
#endif
/* We need to allocate memory to store the path in. We get the size of the
full URL to be sure, and we need to make it at least 256 bytes since
other parts of the code will rely on this fact */
/***********************************************************
* We need to allocate memory to store the path in. We get the size of the
* full URL to be sure, and we need to make it at least 256 bytes since
* other parts of the code will rely on this fact
***********************************************************/
#define LEAST_PATH_ALLOC 256
urllen=strlen(data->url);
if(urllen < LEAST_PATH_ALLOC)
@@ -692,25 +647,30 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
if(NULL == conn->path)
return CURLE_OUT_OF_MEMORY; /* really bad error */
/* Parse <url> */
/* We need to parse the url, even when using the proxy, because
* we will need the hostname and port in case we are trying
* to SSL connect through the proxy -- and we don't know if we
* will need to use SSL until we parse the url ...
*/
/*************************************************************
* Parse the URL.
*
* We need to parse the url even when using the proxy, because we will need
* the hostname and port in case we are trying to SSL connect through the
* proxy -- and we don't know if we will need to use SSL until we parse the
* url ...
************************************************************/
if((2 == sscanf(data->url, "%64[^:]://%[^\n]",
conn->proto,
conn->path)) && strequal(conn->proto, "file")) {
/* we deal with file://<host>/<path> differently since it
supports no hostname other than "localhost" and "127.0.0.1",
which is unique among the protocols specified in RFC 1738 */
/*
* we deal with file://<host>/<path> differently since it supports no
* hostname other than "localhost" and "127.0.0.1", which is unique among
* the URL protocols specified in RFC 1738
*/
if (strnequal(conn->path, "localhost/", 10) ||
strnequal(conn->path, "127.0.0.1/", 10))
/* ... since coincidentally both host strings are of equal length
otherwise, <host>/ is quietly ommitted */
/* If there's another host name than the one we support, <host>/ is
* quietly ommitted */
strcpy(conn->path, &conn->path[10]);
strcpy(conn->proto, "file");
strcpy(conn->proto, "file"); /* store protocol string lowercase */
}
else {
/* Set default host and default path */
@@ -721,12 +681,24 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
"%64[^\n:]://%256[^\n/]%[^\n]",
conn->proto, conn->gname, conn->path)) {
/* badly formatted, let's try the browser-style _without_ 'http://' */
/*
* The URL was badly formatted, let's try the browser-style _without_
* protocol specified like 'http://'.
*/
if((1 > sscanf(data->url, "%256[^\n/]%[^\n]",
conn->gname, conn->path)) ) {
/*
* We couldn't even get this format.
*/
failf(data, "<url> malformed");
return CURLE_URL_MALFORMAT;
}
/*
* Since there was no protocol part specified, we guess what protocol it
* is based on the first letters of the server name.
*/
if(strnequal(conn->gname, "FTP", 3)) {
strcpy(conn->proto, "ftp");
}
@@ -750,6 +722,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
}
}
/*************************************************************
* Take care of user and password authentication stuff
*************************************************************/
if(data->bits.user_passwd && !data->bits.use_netrc) {
data->user[0] =0;
@@ -773,6 +748,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
}
}
/*************************************************************
* Take care of proxy authentication stuff
*************************************************************/
if(data->bits.proxy_user_passwd) {
data->proxyuser[0] =0;
data->proxypasswd[0]=0;
@@ -798,30 +776,36 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
}
/*************************************************************
* Set a few convenience pointers
*************************************************************/
conn->name = conn->gname;
conn->ppath = conn->path;
data->hostname = conn->name;
/*************************************************************
* Detect what (if any) proxy to use
*************************************************************/
if(!data->bits.httpproxy) {
/* If proxy was not specified, we check for default proxy environment
variables, to enable i.e Lynx compliance:
http_proxy=http://some.server.dom:port/
https_proxy=http://some.server.dom:port/
ftp_proxy=http://some.server.dom:port/
gopher_proxy=http://some.server.dom:port/
no_proxy=domain1.dom,host.domain2.dom
(a comma-separated list of hosts which should
not be proxied, or an asterisk to override
all proxy variables)
all_proxy=http://some.server.dom:port/
(seems to exist for the CERN www lib. Probably
the first to check for.)
For compatibility, the all-uppercase versions of these variables are
checked if the lowercase versions don't exist.
*/
* variables, to enable i.e Lynx compliance:
*
* http_proxy=http://some.server.dom:port/
* https_proxy=http://some.server.dom:port/
* ftp_proxy=http://some.server.dom:port/
* gopher_proxy=http://some.server.dom:port/
* no_proxy=domain1.dom,host.domain2.dom
* (a comma-separated list of hosts which should
* not be proxied, or an asterisk to override
* all proxy variables)
* all_proxy=http://some.server.dom:port/
* (seems to exist for the CERN www lib. Probably
* the first to check for.)
*
* For compatibility, the all-uppercase versions of these variables are
* checked if the lowercase versions don't exist.
*/
char *no_proxy=NULL;
char *proxy=NULL;
char proxy_env[128];
@@ -890,6 +874,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
free(no_proxy);
} /* if not using proxy */
/*************************************************************
* No protocol but proxy usage needs attention
*************************************************************/
if((conn->protocol&PROT_MISSING) && data->bits.httpproxy ) {
/* We're guessing prefixes here and since we're told to use a proxy, we
need to add the protocol prefix to the URL string before we continue!
@@ -909,13 +896,15 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
conn->protocol &= ~PROT_MISSING; /* switch that one off again */
}
/* RESUME on a HTTP page is a tricky business. First, let's just check that
'range' isn't used, then set the range parameter and leave the resume as
it is to inform about this situation for later use. We will then
"attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
server, we will get the document resumed. If we talk to a HTTP/1.0
server, we just fail since we can't rewind the file writing from within
this function. */
/************************************************************
* RESUME on a HTTP page is a tricky business. First, let's just check that
* 'range' isn't used, then set the range parameter and leave the resume as
* it is to inform about this situation for later use. We will then
* "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
* server, we will get the document resumed. If we talk to a HTTP/1.0
* server, we just fail since we can't rewind the file writing from within
* this function.
***********************************************************/
if(data->resume_from) {
if(!data->bits.set_range) {
/* if it already was in use, we just skip this */
@@ -926,19 +915,19 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
}
}
/*************************************************************
* Set timeout if that is being used
*************************************************************/
if(data->timeout) {
/* We set the timeout on the connection/resolving phase first, separately
from the download/upload part to allow a maximum time on everything */
* from the download/upload part to allow a maximum time on everything */
myalarm(data->timeout); /* this sends a signal when the timeout fires
off, and that will abort system calls */
}
/*
* Hmm, if we are using a proxy, then we can skip the GOPHER and the
* FTP steps, although we cannot skip the HTTPS step (since the proxy
* works differently, depending on whether its SSL or not).
*/
/*************************************************************
* Setup internals depending on protocol
*************************************************************/
if (strequal(conn->proto, "HTTP")) {
if(!data->port)
@@ -1006,7 +995,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
conn->ppath++; /* don't include the initial slash */
/* FTP URLs support an extension like ";type=<typecode>" that
we'll try to get now! */
* we'll try to get now! */
type=strstr(conn->ppath, ";type=");
if(!type) {
type=strstr(conn->gname, ";type=");
@@ -1068,12 +1057,16 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
return CURLE_OK;
}
else {
/* We fell through all checks and thus we don't support the specified
protocol */
failf(data, "Unsupported protocol: %s", conn->proto);
return CURLE_UNSUPPORTED_PROTOCOL;
}
/*************************************************************
* .netrc scanning coming up
*************************************************************/
if(data->bits.use_netrc) {
if(Curl_parsenetrc(data->hostname, data->user, data->passwd)) {
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
@@ -1092,9 +1085,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
else if(!(data->bits.user_passwd) &&
(conn->protocol & (PROT_FTP|PROT_HTTP)) ) {
/* This is a FTP or HTTP URL, and we haven't got the user+password in
the extra parameter, we will now try to extract the possible
user+password pair in a string like:
ftp://user:password@ftp.my.site:8021/README */
* the extra parameter, we will now try to extract the possible
* user+password pair in a string like:
* ftp://user:password@ftp.my.site:8021/README */
char *ptr=NULL; /* assign to remove possible warnings */
if((ptr=strchr(conn->name, '@'))) {
/* there's a user+password given here, to the left of the @ */
@@ -1146,15 +1139,47 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
}
}
/*************************************************************
* Figure out the remote port number
*
* No matter if we use a proxy or not, we have to figure out the remote
* port number of various reasons.
*
* To be able to detect port number flawlessly, we must not confuse them
* IPv6-specified addresses in the [0::1] style.
*************************************************************/
if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:]%c", &endbracket)) &&
(']' == endbracket)) {
/* this is a IPv6-style specified IP-address */
#ifndef ENABLE_IPV6
failf(data, "You haven't enabled IPv6 support");
return CURLE_URL_MALFORMAT;
#else
tmp = strchr(conn->name, ']');
tmp++; /* pass the ending bracket */
if(':' != *tmp)
tmp = NULL; /* no port number available */
#endif
}
else {
/* traditional IPv4-style port-extracting */
tmp = strchr(conn->name, ':');
}
if (tmp) {
*tmp++ = '\0'; /* cut off the name there */
data->remote_port = atoi(tmp);
}
/*************************************************************
* Resolve the name of the server or proxy
*************************************************************/
if(!data->bits.httpproxy) {
/* If not connecting via a proxy, extract the port from the URL, if it is
* there, thus overriding any defaults that might have been set above. */
tmp = strchr(conn->name, ':');
if (tmp) {
*tmp++ = '\0';
data->port = atoi(tmp);
}
data->remote_port = data->port; /* it is the same port */
data->port = data->remote_port; /* it is the same port */
/* Connect to target host right on */
conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf);
@@ -1179,14 +1204,6 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
return CURLE_OUT_OF_MEMORY;
}
/* we use proxy all right, but we wanna know the remote port for SSL
reasons */
tmp = strchr(conn->name, ':');
if (tmp) {
*tmp++ = '\0'; /* cut off the name there */
data->remote_port = atoi(tmp);
}
/* Daniel Dec 10, 1998:
We do the proxy host string parsing here. We want the host name and the
port name. Accept a protocol:// prefix, even though it should just be
@@ -1231,20 +1248,20 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
conn->serv_addr.sin_family = conn->hp->h_addrtype;
conn->serv_addr.sin_port = htons(data->port);
#ifndef WIN32
#if !defined(WIN32)||defined(__CYGWIN32__)
/* We don't generally like checking for OS-versions, we should make this
HAVE_XXXX based, although at the moment I don't have a decent test for
this! */
/* sck 8/31/2000 add support for specifing device to bind socket to */
/* 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
/*************************************************************
* Select device to bind socket to
*************************************************************/
if (data->device && (strlen(data->device)<255)) {
struct sockaddr_in sa;
struct hostent *h=NULL;
@@ -1351,6 +1368,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
#endif /* end of HAVE_INET_NTOA */
#endif /* end of not WIN32 */
/*************************************************************
* Connect to server/proxy
*************************************************************/
if (connect(data->firstsocket,
(struct sockaddr *) &(conn->serv_addr),
sizeof(conn->serv_addr)
@@ -1400,6 +1420,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
return CURLE_COULDNT_CONNECT;
}
/*************************************************************
* Proxy authentication
*************************************************************/
if(data->bits.proxy_user_passwd) {
char *authorization;
snprintf(data->buffer, BUFSIZE, "%s:%s",
@@ -1411,6 +1434,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
free(authorization);
}
}
/*************************************************************
* Send user-agent to HTTP proxies even if the target protocol
* isn't HTTP.
*************************************************************/
if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) {
if(data->useragent) {
data->ptr_uagent =
@@ -1422,9 +1450,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
/* is there a connect() procedure? */
/* set start time here for timeout purposes in the
connect procedure, it is later set again for the
progress meter purpose */
* connect procedure, it is later set again for the
* progress meter purpose */
conn->now = Curl_tvnow();
/* Call the protocol-specific connect function */
result = conn->curl_connect(conn);
if(result != CURLE_OK)
return result; /* pass back errors */
@@ -1435,7 +1465,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
conn->now = Curl_tvnow(); /* time this *after* the connect is done */
conn->bytecount = 0;
/* Figure out the ip-number and the first host name it shows: */
/* Figure out the ip-number and display the first host name it shows: */
{
struct in_addr in;
(void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr));

View File

@@ -82,8 +82,8 @@
/* Download buffer size, keep it fairly big for speed reasons */
#define BUFSIZE (1024*50)
/* Upload buffer size, keep it smallish to get faster progress meter
updates. This should probably become dynamic and adjust to the upload
/* Defaul upload buffer size, keep it smallish to get faster progress meter
updates. This is just default, it is dynamic and adjusts to the upload
speed. */
#define UPLOAD_BUFSIZE (1024*2)
@@ -91,10 +91,14 @@
of need. */
#define HEADERSIZE 256
/* Just a convenience macro to get the larger value out of two given */
#ifndef MAX
#define MAX(x,y) ((x)>(y)?(x):(y))
#endif
/* Type of handle. All publicly returned 'handles' in the curl interface
have a handle first in the struct that describes what kind of handle it
is. Used to detect bad handle usage. */
typedef enum {
STRUCT_NONE,
STRUCT_OPEN,
@@ -102,6 +106,8 @@ typedef enum {
STRUCT_LAST
} Handle;
/* Connecting to a remote server using the curl interface is moving through
a state machine, this type is used to store the current state */
typedef enum {
CONN_NONE, /* illegal state */
CONN_INIT, /* curl_connect() has been called */
@@ -112,6 +118,7 @@ typedef enum {
} ConnState;
#ifdef KRB4
/* Types needed for krb4-ftp connections */
struct krb4buffer {
void *data;
size_t size;
@@ -155,13 +162,13 @@ struct connectdata {
char *hostent_buf; /* pointer to allocated memory for name info */
struct hostent *hp;
struct sockaddr_in serv_addr;
char proto[64];
char gname[256];
char *name;
char *path; /* formerly staticly this size: URL_MAX_LENGTH */
char proto[64]; /* store the protocol string in this buffer */
char gname[257]; /* store the hostname in this buffer */
char *name; /* host name pointer to fool around with */
char *path; /* allocated buffer to store the URL's path part in */
char *ppath;
long bytecount;
struct timeval now;
struct timeval now; /* current time */
long upload_bufsize; /* adjust as you see fit, never bigger than BUFSIZE
never smaller than UPLOAD_BUFSIZE */
@@ -248,9 +255,9 @@ struct Progress {
struct HTTP {
struct FormData *sendit;
int postsize;
char *p_pragma;
char *p_accept;
long readbytecount;
char *p_pragma; /* Pragma: string */
char *p_accept; /* Accept: string */
long readbytecount;
long writebytecount;
/* For FORM posting */
@@ -264,14 +271,32 @@ struct HTTP {
***************************************************************************/
struct FTP {
long *bytecountp;
char *user;
char *passwd;
char *user; /* user name string */
char *passwd; /* password string */
char *urlpath; /* the originally given path part of the URL */
char *dir; /* decoded directory */
char *file; /* decoded file */
};
typedef enum {
HTTPREQ_NONE, /* first in list */
HTTPREQ_GET,
HTTPREQ_POST,
HTTPREQ_POST_FORM, /* we make a difference internally */
HTTPREQ_PUT,
HTTPREQ_CUSTOM,
HTTPREQ_LAST /* last in list */
} Curl_HttpReq;
/* This struct is for boolean settings that define how to behave during
this session. */
struct Configbits {
/* these four request types mirror the httpreq field */
bool http_formpost;
bool http_post;
bool http_put;
bool http_get;
bool get_filetime;
bool tunnel_thru_httpproxy;
bool ftp_append;
@@ -281,10 +306,7 @@ struct Configbits {
bool hide_progress;
bool http_fail_on_error;
bool http_follow_location;
bool http_formpost;
bool http_include_header;
bool http_post;
bool http_put;
bool http_set_referer;
bool http_auto_referer; /* set "correct" referer when following location: */
bool httpproxy;
@@ -299,7 +321,6 @@ struct Configbits {
bool verbose;
bool this_is_a_follow; /* this is a followed Location: request */
bool krb4; /* kerberos4 connection requested */
bool proxystringalloc; /* the http proxy string is malloc()'ed */
bool rangestringalloc; /* the range string is malloc()'ed */
bool urlstringalloc; /* the URL string is malloc()'ed */
@@ -313,6 +334,7 @@ typedef enum {
CURLI_LAST
} CurlInterface;
/* struct for data related to SSL and SSL connections */
struct ssldata {
bool use; /* use ssl encrypted communications TRUE/FALSE */
long version; /* what version the client wants to use */
@@ -468,8 +490,10 @@ struct UrlData {
struct curl_slist *quote; /* before the transfer */
struct curl_slist *postquote; /* after the transfer */
TimeCond timecondition;
time_t timevalue;
TimeCond timecondition; /* kind of comparison */
time_t timevalue; /* what time to compare with */
Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
char *customrequest; /* http/ftp request to use */
@@ -482,7 +506,7 @@ struct UrlData {
completion */
#endif
struct Progress progress;
struct Progress progress; /* for all the progress meter data */
#define MAX_CURL_USER_LENGTH 128
#define MAX_CURL_PASSWORD_LENGTH 128
@@ -492,6 +516,7 @@ struct UrlData {
* host (which location-following otherwise could lead to)
*/
/* buffers to store authentication data in */
char user[MAX_CURL_USER_LENGTH];
char passwd[MAX_CURL_PASSWORD_LENGTH];
char proxyuser[MAX_CURL_USER_LENGTH];
@@ -506,7 +531,7 @@ struct UrlData {
char *ptr_cookie; /* free later if not NULL! */
char *ptr_host; /* free later if not NULL */
char *krb4_level;
char *krb4_level; /* what security level */
#ifdef KRB4
FILE *cmdchannel;
#endif

View File

@@ -61,8 +61,18 @@ char *curl_version(void)
ptr=strchr(ptr, '\0');
#endif
#if defined(KRB4) || defined(ENABLE_IPV6)
strcat(ptr, " (");
ptr+=2;
#ifdef KRB4
sprintf(ptr, " (krb4 enabled)");
sprintf(ptr, "krb4 ");
ptr += strlen(ptr);
#endif
#ifdef ENABLE_IPV6
sprintf(ptr, "ipv6 ");
ptr += strlen(ptr);
#endif
sprintf(ptr, "enabled)");
ptr += strlen(ptr);
#endif

View File

@@ -26,13 +26,17 @@ while(<STDIN>) {
if($function =~ /free\(0x([0-9a-f]*)/) {
$addr = $1;
if($sizeataddr{$addr} <= 0) {
if($sizeataddr{$addr} == 0) {
print "FREE ERROR: No memory allocated: $line\n";
}
elsif(-1 == $sizeataddr{$addr}) {
print "FREE ERROR: Memory freed twice: $line\n";
print "FREE ERROR: Previously freed at: ".$getmem{$addr}."\n";
}
else {
$totalmem -= $sizeataddr{$addr};
$sizeataddr{$addr}=0;
$getmem{$addr}=""; # forget after a good free()
$sizeataddr{$addr}=-1; # set -1 to mark as freed
$getmem{$addr}="$source:$linenum";
}
}
elsif($function =~ /malloc\((\d*)\) = 0x([0-9a-f]*)/) {

View File

@@ -48,7 +48,7 @@
/* This is now designed to have its own local setup.h */
#include "setup.h"
#ifdef WIN32
#if defined(WIN32)&&!defined(__CYGWIN32__)
#include <winsock.h>
#endif
@@ -244,7 +244,6 @@ static void help(void)
" -A/--user-agent <string> User-Agent to send to server (H)\n"
" -b/--cookie <name=string/file> Cookie string or file to read cookies from (H)\n"
" -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 <data> HTTP POST data (H)\n"
" --data-ascii <data> HTTP POST ASCII data (H)\n"
@@ -278,7 +277,6 @@ static void help(void)
" -r/--range <range> Retrieve a byte range from a HTTP/1.1 or FTP server\n"
" -s/--silent Silent mode. Don't output anything\n"
" -S/--show-error Show error. With -s, make curl show errors when they occur\n"
" -t/--upload Transfer/upload stdin to remote site\n"
" -T/--upload-file <file> Transfer/upload <file> to remote site\n"
" --url <URL> Another way to specify URL to work with\n"
" -u/--user <user[:password]> Specify user and password to use\n"
@@ -1579,7 +1577,9 @@ operate(struct Configurable *config, int argc, char *argv[])
/* multiple files extracted to stdout, insert separators! */
separator = 1;
}
for (i = 0; (url = urls?next_url(urls):(i?NULL:url)); ++i) {
for(i = 0;
(url = urls?next_url(urls):(i?NULL:strdup(url)));
i++) {
char *outfile;
outfile = outfiles?strdup(outfiles):NULL;
@@ -1713,7 +1713,7 @@ operate(struct Configurable *config, int argc, char *argv[])
if(!config->errors)
config->errors = stderr;
#ifdef WIN32
#if defined(WIN32) && !defined(__CYGWIN32__)
if(!outfile && !(config->conf & CONF_GETTEXT)) {
/* We get the output to stdout and we have not got the ASCII/text flag,
then set stdout to be binary */

View File

@@ -32,9 +32,23 @@
#include "../lib/memdebug.h"
#endif
int glob_word(URLGlob *, char*, int);
typedef enum {
GLOB_OK,
GLOB_ERROR
} GlobCode;
int glob_set(URLGlob *glob, char *pattern, int pos)
/*
* glob_word()
*
* Input a full globbed string, set the forth argument to the amount of
* strings we get out of this. Return GlobCode.
*/
GlobCode glob_word(URLGlob *, /* object anchor */
char *, /* globbed string */
int, /* position */
int *); /* returned number of strings */
GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
{
/* processes a set expression with the point behind the opening '{'
','-separated elements are collected until the next closing '}'
@@ -52,13 +66,15 @@ int glob_set(URLGlob *glob, char *pattern, int pos)
while (1) {
switch (*pattern) {
case '\0': /* URL ended while set was still open */
printf("error: unmatched brace at pos %d\n", pos);
exit (CURLE_URL_MALFORMAT);
case '\0': /* URL ended while set was still open */
/*printf("error: unmatched brace at pos %d\n", pos);*/
return GLOB_ERROR;
case '{':
case '[': /* no nested expressions at this time */
printf("error: nested braces not supported %d\n", pos);
exit (CURLE_URL_MALFORMAT);
case '[': /* no nested expressions at this time */
/*printf("error: nested braces not supported %d\n", pos);*/
return GLOB_ERROR;
case ',':
case '}': /* set element completed */
*buf = '\0';
@@ -66,40 +82,51 @@ int glob_set(URLGlob *glob, char *pattern, int pos)
realloc(pat->content.Set.elements,
(pat->content.Set.size + 1) * sizeof(char*));
if (!pat->content.Set.elements) {
printf("out of memory in set pattern\n");
exit(CURLE_OUT_OF_MEMORY);
/*printf("out of memory in set pattern\n");*/
return GLOB_ERROR;
}
pat->content.Set.elements[pat->content.Set.size] =
strdup(glob->glob_buffer);
++pat->content.Set.size;
if (*pattern == '}') /* entire set pattern completed */
if (*pattern == '}') {
/* entire set pattern completed */
int wordamount;
/* always check for a literal (may be "") between patterns */
return pat->content.Set.size * glob_word(glob, ++pattern, ++pos);
if(GLOB_ERROR == glob_word(glob, ++pattern, ++pos, &wordamount))
wordamount=1;
*amount = pat->content.Set.size * wordamount;
return GLOB_OK;
}
buf = glob->glob_buffer;
++pattern;
++pos;
break;
case ']': /* illegal closing bracket */
printf("error: illegal pattern at pos %d\n", pos);
exit (CURLE_URL_MALFORMAT);
/*printf("error: illegal pattern at pos %d\n", pos);*/
return GLOB_ERROR;
case '\\': /* escaped character, skip '\' */
if (*(buf+1) == '\0') { /* but no escaping of '\0'! */
printf("error: illegal pattern at pos %d\n", pos);
exit (CURLE_URL_MALFORMAT);
/*printf("error: illegal pattern at pos %d\n", pos); */
return GLOB_ERROR;
}
++pattern;
++pos; /* intentional fallthrough */
default:
*buf++ = *pattern++; /* copy character to set element */
++pos;
}
}
exit (CURLE_FAILED_INIT);
return GLOB_ERROR;
}
int glob_range(URLGlob *glob, char *pattern, int pos)
GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
{
/* processes a range expression with the point behind the opening '['
- char range: e.g. "a-z]", "B-Q]"
@@ -109,6 +136,7 @@ int glob_range(URLGlob *glob, char *pattern, int pos)
*/
URLPattern *pat;
char *c;
int wordamount=1;
pat = (URLPattern*)&glob->pattern[glob->size / 2];
/* patterns 0,1,2,... correspond to size=1,3,5,... */
@@ -116,44 +144,71 @@ int glob_range(URLGlob *glob, char *pattern, int pos)
if (isalpha((int)*pattern)) { /* character range detected */
pat->type = UPTCharRange;
if (sscanf(pattern, "%c-%c]", &pat->content.CharRange.min_c, &pat->content.CharRange.max_c) != 2 ||
if (sscanf(pattern, "%c-%c]", &pat->content.CharRange.min_c,
&pat->content.CharRange.max_c) != 2 ||
pat->content.CharRange.min_c >= pat->content.CharRange.max_c ||
pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') {
/* the pattern is not well-formed */
printf("error: illegal pattern or range specification after pos %d\n", pos);
exit (CURLE_URL_MALFORMAT);
#if 0
printf("error: illegal pattern or range specification after pos %d\n",
pos);
#endif
return GLOB_ERROR;
}
pat->content.CharRange.ptr_c = pat->content.CharRange.min_c;
/* always check for a literal (may be "") between patterns */
return (pat->content.CharRange.max_c - pat->content.CharRange.min_c + 1) *
glob_word(glob, pattern + 4, pos + 4);
if(GLOB_ERROR == glob_word(glob, pattern + 4, pos + 4, &wordamount))
wordamount=1;
*amount = (pat->content.CharRange.max_c -
pat->content.CharRange.min_c + 1) *
wordamount;
return GLOB_OK;
}
if (isdigit((int)*pattern)) { /* numeric range detected */
if (isdigit((int)*pattern)) { /* numeric range detected */
pat->type = UPTNumRange;
pat->content.NumRange.padlength = 0;
if (sscanf(pattern, "%d-%d]", &pat->content.NumRange.min_n, &pat->content.NumRange.max_n) != 2 ||
if (sscanf(pattern, "%d-%d]",
&pat->content.NumRange.min_n,
&pat->content.NumRange.max_n) != 2 ||
pat->content.NumRange.min_n >= pat->content.NumRange.max_n) {
/* the pattern is not well-formed */
printf("error: illegal pattern or range specification after pos %d\n", pos);
exit (CURLE_URL_MALFORMAT);
#if 0
printf("error: illegal pattern or range specification after pos %d\n",
pos);
#endif
return GLOB_ERROR;
}
if (*pattern == '0') { /* leading zero specified */
c = pattern;
while (isdigit((int)*c++))
++pat->content.NumRange.padlength; /* padding length is set for all instances
of this pattern */
++pat->content.NumRange.padlength; /* padding length is set for all
instances of this pattern */
}
pat->content.NumRange.ptr_n = pat->content.NumRange.min_n;
c = (char*)(strchr(pattern, ']') + 1); /* continue after next ']' */
/* always check for a literal (may be "") between patterns */
return (pat->content.NumRange.max_n - pat->content.NumRange.min_n + 1) *
glob_word(glob, c, pos + (c - pattern));
if(GLOB_ERROR == glob_word(glob, c, pos + (c - pattern), &wordamount))
wordamount = 1;
*amount = (pat->content.NumRange.max_n -
pat->content.NumRange.min_n + 1) *
wordamount;
return GLOB_OK;
}
printf("error: illegal character in range specification at pos %d\n", pos);
exit (CURLE_URL_MALFORMAT);
/*printf("error: illegal character in range specification at pos %d\n",
pos);*/
return GLOB_ERROR;
}
int glob_word(URLGlob *glob, char *pattern, int pos)
GlobCode glob_word(URLGlob *glob, char *pattern, int pos, int *amount)
{
/* processes a literal string component of a URL
special characters '{' and '[' branch to set/range processing functions
@@ -161,17 +216,17 @@ int glob_word(URLGlob *glob, char *pattern, int pos)
char* buf = glob->glob_buffer;
int litindex;
*amount = 1; /* default is one single string */
while (*pattern != '\0' && *pattern != '{' && *pattern != '[') {
if (*pattern == '}' || *pattern == ']') {
printf("illegal character at position %d\n", pos);
exit (CURLE_URL_MALFORMAT);
return GLOB_ERROR;
}
if (*pattern == '\\') { /* escape character, skip '\' */
++pattern;
++pos;
if (*pattern == '\0') { /* but no escaping of '\0'! */
printf("illegal character at position %d\n", pos);
exit (CURLE_URL_MALFORMAT);
return GLOB_ERROR;
}
}
*buf++ = *pattern++; /* copy character to literal */
@@ -182,16 +237,21 @@ int glob_word(URLGlob *glob, char *pattern, int pos)
/* literals 0,1,2,... correspond to size=0,2,4,... */
glob->literal[litindex] = strdup(glob->glob_buffer);
++glob->size;
if (*pattern == '\0')
return 1; /* singular URL processed */
if (*pattern == '{') {
return glob_set(glob, ++pattern, ++pos); /* process set pattern */
switch (*pattern) {
case '\0':
return GLOB_OK; /* singular URL processed */
case '{':
/* process set pattern */
return glob_set(glob, ++pattern, ++pos, amount);
case '[':
/* process range pattern */
return glob_range(glob, ++pattern, ++pos, amount);
}
if (*pattern == '[') {
return glob_range(glob, ++pattern, ++pos);/* process range pattern */
}
printf("internal error\n");
exit (CURLE_FAILED_INIT);
return GLOB_ERROR; /* something got wrong */
}
int glob_url(URLGlob** glob, char* url, int *urlnum)
@@ -201,7 +261,9 @@ int glob_url(URLGlob** glob, char* url, int *urlnum)
* as the specified URL!
*/
URLGlob *glob_expand;
int amount;
char *glob_buffer=(char *)malloc(strlen(url)+1);
if(NULL == glob_buffer)
return CURLE_OUT_OF_MEMORY;
@@ -214,7 +276,16 @@ int glob_url(URLGlob** glob, char* url, int *urlnum)
glob_expand->urllen = strlen(url);
glob_expand->glob_buffer = glob_buffer;
glob_expand->beenhere=0;
*urlnum = glob_word(glob_expand, url, 1);
if(GLOB_OK == glob_word(glob_expand, url, 1, &amount))
*urlnum = amount;
else {
/* it failed, we cleanup */
free(glob_buffer);
free(glob_expand);
glob_expand = NULL;
*urlnum = 1;
}
*glob = glob_expand;
return CURLE_OK;
}

View File

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

View File

@@ -53,4 +53,7 @@ command8.txt name14.txt prot5.txt \
command9.txt name15.txt prot6.txt \
error111.txt name16.txt prot7.txt \
command26.txt prot26.txt command27.txt prot27.txt \
name26.txt reply26.txt name27.txt stdout27.txt
name26.txt reply26.txt name27.txt stdout27.txt \
command28.txt name28.txt prot28.txt reply28.txt \
command120.txt name120.txt prot120.txt reply120.txt \
command121.txt name121.txt prot121.txt reply121.txt

View File

@@ -0,0 +1,3 @@
ftp://%HOSTIP:%FTPPORT/106 -Q "-DELE file"

View File

@@ -0,0 +1 @@
ftp://%HOSTIP:%FTPPORT/106 -Q "-DELE after_transfer" -Q "DELE before_transfer"

1
tests/data/command28.txt Normal file
View File

@@ -0,0 +1 @@
--globoff http://%HOSTIP:%HOSTPORT/wantit/{}[]/28

1
tests/data/name120.txt Normal file
View File

@@ -0,0 +1 @@
ftp download with post-quote delete operation

1
tests/data/name121.txt Normal file
View File

@@ -0,0 +1 @@
ftp download with post- and pre-transfer delete operations

1
tests/data/name28.txt Normal file
View File

@@ -0,0 +1 @@
--globoff with {][} in URL

6
tests/data/prot120.txt Normal file
View File

@@ -0,0 +1,6 @@
USER anonymous
PASS curl_by_daniel@haxx.se
PASV
TYPE I
RETR 106
DELE file

7
tests/data/prot121.txt Normal file
View File

@@ -0,0 +1,7 @@
USER anonymous
PASS curl_by_daniel@haxx.se
DELE before_transfer
PASV
TYPE I
RETR 106
DELE after_transfer

5
tests/data/prot28.txt Normal file
View File

@@ -0,0 +1,5 @@
GET /wantit/{}[]/28 HTTP/1.0
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*

6
tests/data/reply120.txt Normal file
View File

@@ -0,0 +1,6 @@
data
to
see
that FTP
works
so does it?

6
tests/data/reply121.txt Normal file
View File

@@ -0,0 +1,6 @@
data
to
see
that FTP
works
so does it?

5
tests/data/reply28.txt Normal file
View File

@@ -0,0 +1,5 @@
HTTP/1.1 200 OK
Server: fake
{}[] in the URL is not legal

View File

@@ -76,6 +76,7 @@ my %commandok = (
'SIZE' => 'loggedin|twosock',
'PWD' => 'loggedin|twosock',
'QUIT' => 'loggedin|twosock',
'DELE' => 'loggedin|twosock'
);
# initially, we're in 'fresh' state
@@ -97,6 +98,7 @@ my %displaytext = ('USER' => '331 We are happy you popped in!',
'QUIT' => '221 bye bye baby', # just reply something
'PWD' => '257 "/nowhere/anywhere" is current directory',
'REST' => '350 Yeah yeah we set it there for you',
'DELE' => '200 OK OK OK whatever you say'
);
# callback functions for certain commands
@@ -300,6 +302,7 @@ $SIG{CHLD} = \&REAPER;
my %customreply;
sub customize {
undef %customreply;
open(CUSTOM, "<log/ftpserver.cmd") ||
return 1;
@@ -307,7 +310,6 @@ sub customize {
print STDERR "FTPD: Getting commands from log/ftpserver.cmd\n";
}
undef %customreply;
while(<CUSTOM>) {
if($_ =~ /REPLY ([A-Z]+) (.*)/) {
$customreply{$1}=$2;