Compare commits
50 Commits
curl_7_6-p
...
curl-7_6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac98c73b04 | ||
|
|
a145654394 | ||
|
|
e8382ba290 | ||
|
|
fcb347d124 | ||
|
|
c331ef02f9 | ||
|
|
3a3f632bf0 | ||
|
|
68d7b6f871 | ||
|
|
c43a9d9068 | ||
|
|
64e80091db | ||
|
|
4f255ffbeb | ||
|
|
80d75b0eaf | ||
|
|
808c4020e6 | ||
|
|
149d6363b3 | ||
|
|
30eab8ca51 | ||
|
|
e49a82b06c | ||
|
|
45fdb48189 | ||
|
|
3fcc9677c4 | ||
|
|
1552bd9c8c | ||
|
|
939c0c5521 | ||
|
|
f0b9aefd2e | ||
|
|
11f3c51e8f | ||
|
|
1a329b98a3 | ||
|
|
29bcba9a90 | ||
|
|
1716dbb68a | ||
|
|
16ecfcf62c | ||
|
|
8bafc3692d | ||
|
|
8a75120568 | ||
|
|
3d96ee7423 | ||
|
|
b3dbdfa306 | ||
|
|
25bad589ba | ||
|
|
0b6cd75004 | ||
|
|
7872cc131a | ||
|
|
210aa4371c | ||
|
|
6f438bc8fb | ||
|
|
65840f1fd1 | ||
|
|
5fc492e5c6 | ||
|
|
abcd1e7d5a | ||
|
|
6429c378a2 | ||
|
|
d830f10417 | ||
|
|
3d6fcbf97b | ||
|
|
609be218c2 | ||
|
|
41084e57ca | ||
|
|
9afab85105 | ||
|
|
7822233964 | ||
|
|
022315089b | ||
|
|
faa5c14aee | ||
|
|
3dd886955b | ||
|
|
c2dbf21459 | ||
|
|
133eb220b9 | ||
|
|
c5796d9e39 |
75
CHANGES
75
CHANGES
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
312
config.h.in
312
config.h.in
@@ -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
|
||||
|
||||
41
configure.in
41
configure.in
@@ -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
|
||||
|
||||
|
||||
12
docs/FAQ
12
docs/FAQ
@@ -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!
|
||||
|
||||
@@ -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
|
||||
===============================
|
||||
|
||||
|
||||
10
docs/curl.1
10
docs/curl.1
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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) */
|
||||
|
||||
60
lib/dict.c
60
lib/dict.c
@@ -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;
|
||||
|
||||
27
lib/ftp.c
27
lib/ftp.c
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
108
lib/http.c
108
lib/http.c
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
119
lib/sendf.c
119
lib/sendf.c
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
14
lib/sendf.h
14
lib/sendf.h
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
119
lib/telnet.c
119
lib/telnet.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
306
lib/url.c
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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]*)/) {
|
||||
|
||||
10
src/main.c
10
src/main.c
@@ -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 */
|
||||
|
||||
167
src/urlglob.c
167
src/urlglob.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 ") "
|
||||
|
||||
@@ -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
|
||||
|
||||
3
tests/data/command120.txt
Normal file
3
tests/data/command120.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
ftp://%HOSTIP:%FTPPORT/106 -Q "-DELE file"
|
||||
|
||||
|
||||
1
tests/data/command121.txt
Normal file
1
tests/data/command121.txt
Normal file
@@ -0,0 +1 @@
|
||||
ftp://%HOSTIP:%FTPPORT/106 -Q "-DELE after_transfer" -Q "DELE before_transfer"
|
||||
1
tests/data/command28.txt
Normal file
1
tests/data/command28.txt
Normal file
@@ -0,0 +1 @@
|
||||
--globoff http://%HOSTIP:%HOSTPORT/wantit/{}[]/28
|
||||
1
tests/data/name120.txt
Normal file
1
tests/data/name120.txt
Normal file
@@ -0,0 +1 @@
|
||||
ftp download with post-quote delete operation
|
||||
1
tests/data/name121.txt
Normal file
1
tests/data/name121.txt
Normal file
@@ -0,0 +1 @@
|
||||
ftp download with post- and pre-transfer delete operations
|
||||
1
tests/data/name28.txt
Normal file
1
tests/data/name28.txt
Normal file
@@ -0,0 +1 @@
|
||||
--globoff with {][} in URL
|
||||
6
tests/data/prot120.txt
Normal file
6
tests/data/prot120.txt
Normal 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
7
tests/data/prot121.txt
Normal 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
5
tests/data/prot28.txt
Normal 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
6
tests/data/reply120.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
data
|
||||
to
|
||||
see
|
||||
that FTP
|
||||
works
|
||||
so does it?
|
||||
6
tests/data/reply121.txt
Normal file
6
tests/data/reply121.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
data
|
||||
to
|
||||
see
|
||||
that FTP
|
||||
works
|
||||
so does it?
|
||||
5
tests/data/reply28.txt
Normal file
5
tests/data/reply28.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
HTTP/1.1 200 OK
|
||||
Server: fake
|
||||
|
||||
{}[] in the URL is not legal
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user