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
|
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)
|
Daniel (17 January 2001)
|
||||||
- Made the two former files lib/download.c and lib/highlevel.c become the new
|
- 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()
|
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) */
|
/* Define if you have the Kerberos4 libraries (including -ldes) */
|
||||||
#undef KRB4
|
#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 **********************************************************************
|
||||||
dnl Checks for libraries.
|
dnl Checks for libraries.
|
||||||
@@ -590,6 +628,9 @@ AC_CHECK_FUNCS( socket \
|
|||||||
dnl removed 'getpass' check on October 26, 2000
|
dnl removed 'getpass' check on October 26, 2000
|
||||||
|
|
||||||
if test "$ac_cv_func_select" != "yes"; then
|
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)
|
AC_MSG_ERROR(Can't work without an existing socket() function)
|
||||||
fi
|
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.2 How can I receive all data into a large memory chunk?
|
||||||
5.3 How do I fetch multiple files with libcurl?
|
5.3 How do I fetch multiple files with libcurl?
|
||||||
5.4 Does libcurl do Winsock initing on win32 systems?
|
5.4 Does libcurl do Winsock initing on win32 systems?
|
||||||
|
5.5 Does CURLOPT_FILE work on win32 ?
|
||||||
|
|
||||||
6. License Issues
|
6. License Issues
|
||||||
6.1 I have a GPL program, can I use the libcurl library?
|
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
|
use several different libraries and parts, and there's no reason for every
|
||||||
single library to do this.
|
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
|
6. License Issues
|
||||||
|
|
||||||
NOTE: This section is now updated to concern curl 7.5.2 or later!
|
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.
|
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
|
CVS
|
||||||
===
|
===
|
||||||
All changes to the sources are committed to the CVS repository as soon as
|
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
|
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:
|
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
|
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
|
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
|
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.
|
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
|
Return Codes and Informationals
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
|
|||||||
10
docs/curl.1
10
docs/curl.1
@@ -2,7 +2,7 @@
|
|||||||
.\" nroff -man curl.1
|
.\" nroff -man curl.1
|
||||||
.\" Written by Daniel Stenberg
|
.\" Written by Daniel Stenberg
|
||||||
.\"
|
.\"
|
||||||
.TH curl 1 "9 January 2001" "Curl 7.6" "Curl Manual"
|
.TH curl 1 "19 January 2001" "Curl 7.6" "Curl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or
|
curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or
|
||||||
HTTPS syntax.
|
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.
|
name should've been. This goes for both @ and < constructs.
|
||||||
|
|
||||||
This option can be used multiple times.
|
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"
|
.IP "-h/--help"
|
||||||
Usage help.
|
Usage help.
|
||||||
.IP "-H/--header <header>"
|
.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>
|
- Alexander Kourakos <awk@users.sourceforge.net>
|
||||||
- James Griffiths <griffiths_james@yahoo.com>
|
- James Griffiths <griffiths_james@yahoo.com>
|
||||||
- Loic Dachary <loic@senga.org>
|
- Loic Dachary <loic@senga.org>
|
||||||
|
- Robert Weaver <robert.weaver@sabre.com>
|
||||||
|
- Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
|
||||||
|
|
||||||
.SH WWW
|
.SH WWW
|
||||||
http://curl.haxx.se
|
http://curl.haxx.se
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
.\" nroff -man [file]
|
.\" nroff -man [file]
|
||||||
.\" Written by daniel@haxx.se
|
.\" 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
|
.SH NAME
|
||||||
curl_easy_perform - Do the actual transfer in a "easy" session
|
curl_easy_perform - Do the actual transfer in a "easy" session
|
||||||
.SH SYNOPSIS
|
.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
|
It must be called with the same
|
||||||
.I handle
|
.I handle
|
||||||
as input as the curl_easy_init call returned.
|
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
|
.SH RETURN VALUE
|
||||||
0 means everything was ok, non-zero means an error occurred as
|
0 means everything was ok, non-zero means an error occurred as
|
||||||
.I <curl/curl.h>
|
.I <curl/curl.h>
|
||||||
|
|||||||
@@ -166,10 +166,6 @@ typedef enum {
|
|||||||
|
|
||||||
#define CURL_ERROR_SIZE 256
|
#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>,
|
/* name is uppercase CURLOPT_<name>,
|
||||||
type is one of the defined CURLOPTTYPE_<type>
|
type is one of the defined CURLOPTTYPE_<type>
|
||||||
number is unique identifier */
|
number is unique identifier */
|
||||||
@@ -456,7 +452,7 @@ char *curl_getenv(char *variable);
|
|||||||
char *curl_version(void);
|
char *curl_version(void);
|
||||||
|
|
||||||
/* This is the version number */
|
/* This is the version number */
|
||||||
#define LIBCURL_VERSION "7.6-pre3"
|
#define LIBCURL_VERSION "7.6"
|
||||||
#define LIBCURL_VERSION_NUM 0x070600
|
#define LIBCURL_VERSION_NUM 0x070600
|
||||||
|
|
||||||
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
/* 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);
|
nth = atoi(nthdef);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendf(data->firstsocket, data,
|
Curl_sendf(data->firstsocket, conn,
|
||||||
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
|
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
|
||||||
"MATCH "
|
"MATCH "
|
||||||
"%s " /* database */
|
"%s " /* database */
|
||||||
"%s " /* strategy */
|
"%s " /* strategy */
|
||||||
"%s\n" /* word */
|
"%s\n" /* word */
|
||||||
"QUIT\n",
|
"QUIT\n",
|
||||||
|
|
||||||
database,
|
database,
|
||||||
strategy,
|
strategy,
|
||||||
word
|
word
|
||||||
);
|
);
|
||||||
|
|
||||||
result = Curl_Transfer(conn, data->firstsocket, -1, FALSE, bytecount,
|
result = Curl_Transfer(conn, data->firstsocket, -1, FALSE, bytecount,
|
||||||
-1, NULL); /* no upload */
|
-1, NULL); /* no upload */
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
@@ -191,20 +191,20 @@ CURLcode Curl_dict(struct connectdata *conn)
|
|||||||
nth = atoi(nthdef);
|
nth = atoi(nthdef);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendf(data->firstsocket, data,
|
Curl_sendf(data->firstsocket, conn,
|
||||||
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
|
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
|
||||||
"DEFINE "
|
"DEFINE "
|
||||||
"%s " /* database */
|
"%s " /* database */
|
||||||
"%s\n" /* word */
|
"%s\n" /* word */
|
||||||
"QUIT\n",
|
"QUIT\n",
|
||||||
|
|
||||||
database,
|
database,
|
||||||
word
|
word
|
||||||
);
|
);
|
||||||
|
|
||||||
result = Curl_Transfer(conn, data->firstsocket, -1, FALSE, bytecount,
|
result = Curl_Transfer(conn, data->firstsocket, -1, FALSE, bytecount,
|
||||||
-1, NULL); /* no upload */
|
-1, NULL); /* no upload */
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -220,14 +220,14 @@ CURLcode Curl_dict(struct connectdata *conn)
|
|||||||
if (ppath[i] == ':')
|
if (ppath[i] == ':')
|
||||||
ppath[i] = ' ';
|
ppath[i] = ' ';
|
||||||
}
|
}
|
||||||
sendf(data->firstsocket, data,
|
Curl_sendf(data->firstsocket, conn,
|
||||||
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
|
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
|
||||||
"%s\n"
|
"%s\n"
|
||||||
"QUIT\n",
|
"QUIT\n",
|
||||||
ppath);
|
ppath);
|
||||||
|
|
||||||
result = Curl_Transfer(conn, data->firstsocket, -1, FALSE, bytecount,
|
result = Curl_Transfer(conn, data->firstsocket, -1, FALSE, bytecount,
|
||||||
-1, NULL);
|
-1, NULL);
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
return 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 *ftpcode)
|
||||||
{
|
{
|
||||||
int nread;
|
int nread;
|
||||||
int keepon=TRUE;
|
size_t keepon=TRUE;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int timeout = 3600; /* in seconds */
|
int timeout = 3600; /* in seconds */
|
||||||
struct timeval interval;
|
struct timeval interval;
|
||||||
@@ -272,22 +272,17 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
|
|||||||
break;
|
break;
|
||||||
case 0: /* timeout */
|
case 0: /* timeout */
|
||||||
error = SELECT_TIMEOUT;
|
error = SELECT_TIMEOUT;
|
||||||
infof(data, "Transfer aborted due to timeout\n");
|
|
||||||
failf(data, "Transfer aborted due to timeout");
|
failf(data, "Transfer aborted due to timeout");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef USE_SSLEAY
|
/*
|
||||||
if (data->ssl.use) {
|
* This code previously didn't use the kerberos sec_read() code
|
||||||
keepon = SSL_read(data->ssl.handle, ptr, 1);
|
* to read, but when we use Curl_read() it may do so. Do confirm
|
||||||
}
|
* that this is still ok and then remove this comment!
|
||||||
else {
|
*/
|
||||||
#endif
|
if(CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &keepon))
|
||||||
keepon = sread(sockfd, ptr, 1);
|
keepon = FALSE;
|
||||||
#ifdef USE_SSLEAY
|
else if ((*ptr == '\n') || (*ptr == '\r'))
|
||||||
}
|
|
||||||
#endif /* USE_SSLEAY */
|
|
||||||
|
|
||||||
if ((*ptr == '\n') || (*ptr == '\r'))
|
|
||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
}
|
}
|
||||||
if(keepon) {
|
if(keepon) {
|
||||||
@@ -372,7 +367,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
|
|||||||
|
|
||||||
if (data->bits.tunnel_thru_httpproxy) {
|
if (data->bits.tunnel_thru_httpproxy) {
|
||||||
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
/* 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);
|
data->hostname, data->remote_port);
|
||||||
if(CURLE_OK != result)
|
if(CURLE_OK != result)
|
||||||
return result;
|
return result;
|
||||||
@@ -979,7 +974,7 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
|
|
||||||
if (data->bits.tunnel_thru_httpproxy) {
|
if (data->bits.tunnel_thru_httpproxy) {
|
||||||
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
||||||
result = Curl_ConnectHTTPProxyTunnel(data, data->secondarysocket,
|
result = Curl_ConnectHTTPProxyTunnel(conn, data->secondarysocket,
|
||||||
newhost, newport);
|
newhost, newport);
|
||||||
if(CURLE_OK != result)
|
if(CURLE_OK != result)
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -41,12 +41,13 @@ char *GetEnv(char *variable)
|
|||||||
char env[MAX_PATH]; /* MAX_PATH is from windef.h */
|
char env[MAX_PATH]; /* MAX_PATH is from windef.h */
|
||||||
char *temp = getenv(variable);
|
char *temp = getenv(variable);
|
||||||
env[0] = '\0';
|
env[0] = '\0';
|
||||||
ExpandEnvironmentStrings(temp, env, sizeof(env));
|
if (temp != NULL)
|
||||||
|
ExpandEnvironmentStrings(temp, env, sizeof(env));
|
||||||
#else
|
#else
|
||||||
/* no length control */
|
/* no length control */
|
||||||
char *env = getenv(variable);
|
char *env = getenv(variable);
|
||||||
#endif
|
#endif
|
||||||
return env?strdup(env):NULL;
|
return (env && env[0])?strdup(env):NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *curl_getenv(char *v)
|
char *curl_getenv(char *v)
|
||||||
|
|||||||
108
lib/http.c
108
lib/http.c
@@ -94,7 +94,6 @@
|
|||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "cookie.h"
|
#include "cookie.h"
|
||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
#include "url.h"
|
|
||||||
#include "ssluse.h"
|
#include "ssluse.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#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);
|
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)
|
if(in->buffer)
|
||||||
free(in->buffer);
|
free(in->buffer);
|
||||||
@@ -213,28 +212,21 @@ CURLcode add_buffer(send_buffer *in, void *inptr, size_t size)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static
|
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;
|
int read_rc=1;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
struct UrlData *data=conn->data;
|
||||||
|
|
||||||
ptr=buf;
|
ptr=buf;
|
||||||
|
|
||||||
/* get us a full line, terminated with a newline */
|
/* get us a full line, terminated with a newline */
|
||||||
for(nread=0;
|
for(nread=0;
|
||||||
(nread<BUFSIZE) && read_rc;
|
(nread<BUFSIZE) && read_rc;
|
||||||
nread++, ptr++) {
|
nread++, ptr++) {
|
||||||
#ifdef USE_SSLEAY
|
if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) ||
|
||||||
if (data->ssl.use) {
|
(*ptr == '\n'))
|
||||||
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')
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*ptr=0; /* zero terminate */
|
*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.
|
* 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)
|
char *hostname, int remote_port)
|
||||||
{
|
{
|
||||||
int httperror=0;
|
int httperror=0;
|
||||||
int subversion=0;
|
int subversion=0;
|
||||||
|
struct UrlData *data=conn->data;
|
||||||
|
|
||||||
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
|
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
|
||||||
|
|
||||||
/* OK, now send the connect statment */
|
/* OK, now send the connect request to the proxy */
|
||||||
sendf(tunnelsocket, data,
|
Curl_sendf(tunnelsocket, conn,
|
||||||
"CONNECT %s:%d HTTP/1.0\015\012"
|
"CONNECT %s:%d HTTP/1.0\015\012"
|
||||||
"%s"
|
"%s"
|
||||||
"%s"
|
"%s"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
hostname, remote_port,
|
hostname, remote_port,
|
||||||
(data->bits.proxy_user_passwd)?data->ptr_proxyuserpwd:"",
|
(data->bits.proxy_user_passwd)?data->ptr_proxyuserpwd:"",
|
||||||
(data->useragent?data->ptr_uagent:"")
|
(data->useragent?data->ptr_uagent:"")
|
||||||
);
|
);
|
||||||
|
|
||||||
/* wait for the proxy to send us a HTTP/1.0 200 OK header */
|
/* 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])
|
if('\r' == data->buffer[0])
|
||||||
break; /* end of headers */
|
break; /* end of headers */
|
||||||
if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
|
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 (conn->protocol & PROT_HTTPS) {
|
||||||
if (data->bits.httpproxy) {
|
if (data->bits.httpproxy) {
|
||||||
/* HTTPS through a proxy can only be done with a tunnel */
|
/* 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);
|
data->hostname, data->remote_port);
|
||||||
if(CURLE_OK != result)
|
if(CURLE_OK != result)
|
||||||
return result;
|
return result;
|
||||||
@@ -477,6 +471,64 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
if(!checkheaders(data, "Accept:"))
|
if(!checkheaders(data, "Accept:"))
|
||||||
http->p_accept = "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n";
|
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 {
|
do {
|
||||||
send_buffer *req_buffer;
|
send_buffer *req_buffer;
|
||||||
struct curl_slist *headers=data->headers;
|
struct curl_slist *headers=data->headers;
|
||||||
|
|||||||
@@ -25,7 +25,8 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/* ftp can use this as well */
|
/* 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);
|
char *hostname, int remote_port);
|
||||||
|
|
||||||
/* protocol-specific functions set up to be called by the main engine */
|
/* protocol-specific functions set up to be called by the main engine */
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ! defined(WIN32) && ! defined(__BEOS__)
|
#if ! defined(WIN32) && ! defined(__BEOS__) && !defined(__CYGWIN32__)
|
||||||
|
|
||||||
#ifdef NEED_REENTRANT
|
#ifdef NEED_REENTRANT
|
||||||
#define _REENTRANT
|
#define _REENTRANT
|
||||||
|
|||||||
@@ -283,7 +283,9 @@ krb4_auth(void *app_data, struct connectdata *conn)
|
|||||||
u_int32_t cs;
|
u_int32_t cs;
|
||||||
struct krb4_data *d = app_data;
|
struct krb4_data *d = app_data;
|
||||||
struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR;
|
struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR;
|
||||||
|
#if 0
|
||||||
struct sockaddr_in *remoteaddr = (struct sockaddr_in *)REMOTE_ADDR;
|
struct sockaddr_in *remoteaddr = (struct sockaddr_in *)REMOTE_ADDR;
|
||||||
|
#endif
|
||||||
char *host = conn->hp->h_name;
|
char *host = conn->hp->h_name;
|
||||||
size_t nread;
|
size_t nread;
|
||||||
int l = sizeof(local_addr);
|
int l = sizeof(local_addr);
|
||||||
@@ -313,7 +315,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
|
|||||||
else {
|
else {
|
||||||
if (natAddr.s_addr != localaddr->sin_addr.s_addr) {
|
if (natAddr.s_addr != localaddr->sin_addr.s_addr) {
|
||||||
printf("Using NAT IP address (%s) for kerberos 4\n",
|
printf("Using NAT IP address (%s) for kerberos 4\n",
|
||||||
inet_ntoa(natAddr));
|
(char *)inet_ntoa(natAddr));
|
||||||
localaddr->sin_addr = natAddr;
|
localaddr->sin_addr = natAddr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -399,7 +401,6 @@ void krb_kauth(struct connectdata *conn)
|
|||||||
KTEXT_ST tkt, tktcopy;
|
KTEXT_ST tkt, tktcopy;
|
||||||
char *name;
|
char *name;
|
||||||
char *p;
|
char *p;
|
||||||
int overbose;
|
|
||||||
char passwd[100];
|
char passwd[100];
|
||||||
int tmp;
|
int tmp;
|
||||||
size_t nread;
|
size_t nread;
|
||||||
@@ -417,12 +418,10 @@ void krb_kauth(struct connectdata *conn)
|
|||||||
return /*CURLE_OPERATION_TIMEOUTED*/;
|
return /*CURLE_OPERATION_TIMEOUTED*/;
|
||||||
|
|
||||||
if(/*ret != CONTINUE*/conn->data->buffer[0] != '3'){
|
if(/*ret != CONTINUE*/conn->data->buffer[0] != '3'){
|
||||||
/*verbose = overbose;***/
|
|
||||||
set_command_prot(conn, save);
|
set_command_prot(conn, save);
|
||||||
/*code = -1;***/
|
/*code = -1;***/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*verbose = overbose;***/
|
|
||||||
p = strstr(/*reply_string***/conn->data->buffer, "T=");
|
p = strstr(/*reply_string***/conn->data->buffer, "T=");
|
||||||
if(!p){
|
if(!p){
|
||||||
printf("Bad reply from server.\n");
|
printf("Bad reply from server.\n");
|
||||||
@@ -444,7 +443,6 @@ void krb_kauth(struct connectdata *conn)
|
|||||||
p = strstr(/*reply_string***/conn->data->buffer, "P=");
|
p = strstr(/*reply_string***/conn->data->buffer, "P=");
|
||||||
if(!p){
|
if(!p){
|
||||||
printf("Bad reply from server.\n");
|
printf("Bad reply from server.\n");
|
||||||
/*verbose = overbose;***/
|
|
||||||
set_command_prot(conn, save);
|
set_command_prot(conn, save);
|
||||||
/*code = -1;***/
|
/*code = -1;***/
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -212,14 +212,14 @@ int Curl_pgrsUpdate(struct UrlData *data)
|
|||||||
|
|
||||||
now = Curl_tvnow(); /* what time is it */
|
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))
|
if(data->progress.lastshow == Curl_tvlong(now))
|
||||||
return 0; /* never update this more than once a second if the end isn't
|
return 0; /* never update this more than once a second if the end isn't
|
||||||
reached */
|
reached */
|
||||||
data->progress.lastshow = now.tv_sec;
|
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 */
|
/* The average download speed this far */
|
||||||
data->progress.dlspeed = data->progress.downloaded/(data->progress.timespent!=0.0?data->progress.timespent:1.0);
|
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 */
|
/* Figure out the estimated time of arrival for the upload */
|
||||||
if(data->progress.flags & PGRS_UL_SIZE_KNOWN) {
|
if((data->progress.flags & PGRS_UL_SIZE_KNOWN) && data->progress.ulspeed){
|
||||||
if(!data->progress.ulspeed)
|
|
||||||
data->progress.ulspeed=1;
|
|
||||||
ulestimate = data->progress.size_ul / data->progress.ulspeed;
|
ulestimate = data->progress.size_ul / data->progress.ulspeed;
|
||||||
ulpercen = (data->progress.uploaded / data->progress.size_ul)*100;
|
ulpercen = (data->progress.uploaded / data->progress.size_ul)*100;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ... and the download */
|
/* ... and the download */
|
||||||
if(data->progress.flags & PGRS_DL_SIZE_KNOWN) {
|
if((data->progress.flags & PGRS_DL_SIZE_KNOWN) && data->progress.dlspeed) {
|
||||||
if(!data->progress.dlspeed)
|
|
||||||
data->progress.dlspeed=1;
|
|
||||||
dlestimate = data->progress.size_dl / data->progress.dlspeed;
|
dlestimate = data->progress.size_dl / data->progress.dlspeed;
|
||||||
dlpercen = (data->progress.downloaded / data->progress.size_dl)*100;
|
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);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sendf() sends the formated data to the server */
|
/* Curl_sendf() sends formated data to the server */
|
||||||
size_t Curl_sendf(int fd, struct UrlData *data, char *fmt, ...)
|
size_t Curl_sendf(int sockfd, struct connectdata *conn,
|
||||||
|
char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
struct UrlData *data = conn->data;
|
||||||
size_t bytes_written;
|
size_t bytes_written;
|
||||||
char *s;
|
char *s;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
s = vaprintf(fmt, ap);
|
s = vaprintf(fmt, ap); /* returns an allocated string */
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
if(!s)
|
if(!s)
|
||||||
return 0; /* failure */
|
return 0; /* failure */
|
||||||
if(data->bits.verbose)
|
if(data->bits.verbose)
|
||||||
fprintf(data->err, "> %s", s);
|
fprintf(data->err, "> %s", s);
|
||||||
|
|
||||||
#ifndef USE_SSLEAY
|
/* Write the buffer to the socket */
|
||||||
bytes_written = swrite(fd, s, strlen(s));
|
Curl_write(conn, sockfd, s, strlen(s), &bytes_written);
|
||||||
#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 */
|
|
||||||
free(s); /* free the output string */
|
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;
|
size_t bytes_written;
|
||||||
struct UrlData *data=conn->data; /* conn knows data, not vice versa */
|
struct UrlData *data=conn->data; /* conn knows data, not vice versa */
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
if (data->ssl.use) {
|
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 {
|
else {
|
||||||
#endif
|
#endif
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
if(conn->sec_complete) {
|
if(conn->sec_complete) {
|
||||||
bytes_written = sec_write(conn, fd, mem, len);
|
bytes_written = sec_write(conn, sockfd, mem, len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* KRB4 */
|
#endif /* KRB4 */
|
||||||
bytes_written = swrite(fd, mem, len);
|
bytes_written = swrite(sockfd, mem, len);
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
/* client_write() sends data to the write callback(s)
|
||||||
|
|
||||||
The bit pattern defines to what "streams" to write to. Body and/or header.
|
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;
|
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$
|
* $Id$
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
size_t Curl_sendf(int fd, struct UrlData *, char *fmt, ...);
|
size_t Curl_sendf(int fd, struct connectdata *, char *fmt, ...);
|
||||||
size_t Curl_ssend(int fd, struct connectdata *, void *fmt, size_t len);
|
|
||||||
void Curl_infof(struct UrlData *, char *fmt, ...);
|
void Curl_infof(struct UrlData *, char *fmt, ...);
|
||||||
void Curl_failf(struct UrlData *, char *fmt, ...);
|
void Curl_failf(struct UrlData *, char *fmt, ...);
|
||||||
|
|
||||||
#define sendf Curl_sendf
|
|
||||||
#define ssend Curl_ssend
|
|
||||||
#define infof Curl_infof
|
#define infof Curl_infof
|
||||||
#define failf Curl_failf
|
#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,
|
CURLcode Curl_client_write(struct UrlData *data, int type, char *ptr,
|
||||||
size_t len);
|
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
|
#endif
|
||||||
|
|||||||
@@ -100,7 +100,6 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
|
|||||||
1. close a socket
|
1. close a socket
|
||||||
2. read from a socket
|
2. read from a socket
|
||||||
3. write to a socket
|
3. write to a socket
|
||||||
(Hopefully, only win32-crap do this weird name changing)
|
|
||||||
|
|
||||||
4. set the SIGALRM signal timeout
|
4. set the SIGALRM signal timeout
|
||||||
5. set dir/file naming defines
|
5. set dir/file naming defines
|
||||||
@@ -115,8 +114,8 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
|
|||||||
#else
|
#else
|
||||||
/* gcc-for-win is still good :) */
|
/* gcc-for-win is still good :) */
|
||||||
#define sclose(x) close(x)
|
#define sclose(x) close(x)
|
||||||
#define sread(x,y,z) read(x,y,z)
|
#define sread(x,y,z) recv(x,y,z,0)
|
||||||
#define swrite(x,y,z) write(x,y,z)
|
#define swrite(x,y,z) send(x,y,z,0)
|
||||||
#define myalarm(x) alarm(x)
|
#define myalarm(x) alarm(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
119
lib/telnet.c
119
lib/telnet.c
@@ -73,8 +73,6 @@
|
|||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include "transfer.h"
|
#include "transfer.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
#include "formdata.h"
|
|
||||||
#include "progress.h"
|
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -97,11 +95,6 @@
|
|||||||
#define SB_EOF() (subpointer >= subend)
|
#define SB_EOF() (subpointer >= subend)
|
||||||
#define SB_LEN() (subend - subpointer)
|
#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
|
static
|
||||||
void telrcv(struct UrlData *data,
|
void telrcv(struct UrlData *data,
|
||||||
unsigned char *inbuf, /* Data received from socket */
|
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)
|
CURLcode Curl_telnet_done(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@@ -870,7 +833,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
|||||||
|
|
||||||
bool keepon = TRUE;
|
bool keepon = TRUE;
|
||||||
char *buf = data->buffer;
|
char *buf = data->buffer;
|
||||||
int nread;
|
size_t nread;
|
||||||
|
|
||||||
init_telnet(data);
|
init_telnet(data);
|
||||||
|
|
||||||
@@ -880,49 +843,49 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
|||||||
|
|
||||||
keepfd = readfd;
|
keepfd = readfd;
|
||||||
|
|
||||||
while (keepon)
|
while (keepon) {
|
||||||
{
|
readfd = keepfd; /* set this every lap in the loop */
|
||||||
readfd = keepfd; /* set this every lap in the loop */
|
|
||||||
|
|
||||||
switch (select (sockfd + 1, &readfd, NULL, NULL, NULL))
|
switch (select (sockfd + 1, &readfd, NULL, NULL, NULL)) {
|
||||||
{
|
case -1: /* error, stop reading */
|
||||||
case -1: /* error, stop reading */
|
keepon = FALSE;
|
||||||
keepon = FALSE;
|
continue;
|
||||||
continue;
|
case 0: /* timeout */
|
||||||
case 0: /* timeout */
|
break;
|
||||||
break;
|
default: /* read! */
|
||||||
default: /* read! */
|
if(FD_ISSET(1, &readfd)) { /* read from stdin */
|
||||||
if(FD_ISSET(1, &readfd))
|
unsigned char outbuf[2];
|
||||||
{
|
int out_count = 0;
|
||||||
nread = read(1, buf, 255);
|
size_t bytes_written;
|
||||||
telwrite(data, (unsigned char *)buf, nread);
|
char *buffer = buf;
|
||||||
}
|
|
||||||
|
nread = read(1, buf, 255);
|
||||||
|
|
||||||
if(FD_ISSET(sockfd, &readfd))
|
while(nread--) {
|
||||||
{
|
outbuf[0] = *buffer++;
|
||||||
#ifndef USE_SSLEAY
|
out_count = 1;
|
||||||
nread = sread (sockfd, buf, BUFSIZE - 1);
|
if(outbuf[0] == IAC)
|
||||||
#else
|
outbuf[out_count++] = IAC;
|
||||||
if (data->ssl.use) {
|
|
||||||
nread = SSL_read (data->ssl.handle, buf, BUFSIZE - 1);
|
Curl_write(conn, data->firstsocket, outbuf,
|
||||||
}
|
out_count, &bytes_written);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
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;
|
CURLcode urg;
|
||||||
time_t timeofdoc=0;
|
time_t timeofdoc=0;
|
||||||
long bodywrites=0;
|
long bodywrites=0;
|
||||||
|
|
||||||
char newurl[URL_MAX_LENGTH]; /* buffer for Location: URL */
|
|
||||||
int writetype;
|
int writetype;
|
||||||
|
|
||||||
/* the highest fd we use + 1 */
|
/* the highest fd we use + 1 */
|
||||||
@@ -224,7 +222,7 @@ _Transfer(struct connectdata *c_conn)
|
|||||||
default:
|
default:
|
||||||
if((keepon & KEEP_READ) && FD_ISSET(conn->sockfd, &readfd)) {
|
if((keepon & KEEP_READ) && FD_ISSET(conn->sockfd, &readfd)) {
|
||||||
/* read! */
|
/* 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 */
|
/* NULL terminate, allowing string ops to be used */
|
||||||
if (0 < (signed int) nread)
|
if (0 < (signed int) nread)
|
||||||
@@ -389,12 +387,21 @@ _Transfer(struct connectdata *c_conn)
|
|||||||
}
|
}
|
||||||
else if ((code >= 300 && code < 400) &&
|
else if ((code >= 300 && code < 400) &&
|
||||||
(data->bits.http_follow_location) &&
|
(data->bits.http_follow_location) &&
|
||||||
strnequal("Location", p, 8) &&
|
strnequal("Location: ", p, 10)) {
|
||||||
sscanf (p+8, ": %" URL_MAX_LENGTH_TXT "s",
|
/* this is the URL that the server advices us to get instead */
|
||||||
newurl)) {
|
char *ptr;
|
||||||
/* this is the URL that the server advices us to get
|
char *start=p;
|
||||||
instead */
|
char backup;
|
||||||
data->newurl = strdup (newurl);
|
|
||||||
|
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;
|
writetype = CLIENTWRITE_HEADER;
|
||||||
@@ -437,10 +444,14 @@ _Transfer(struct connectdata *c_conn)
|
|||||||
write a chunk of the body */
|
write a chunk of the body */
|
||||||
if(conn->protocol&PROT_HTTP) {
|
if(conn->protocol&PROT_HTTP) {
|
||||||
/* HTTP-only checks */
|
/* 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
|
/* we wanted to resume a download, although the server
|
||||||
doesn't seem to support this */
|
doesn't seem to support this and we did this with a GET
|
||||||
failf (data, "HTTP server doesn't seem to support byte ranges. Cannot resume.");
|
(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;
|
return CURLE_HTTP_RANGE_ERROR;
|
||||||
}
|
}
|
||||||
else if (data->newurl) {
|
else if (data->newurl) {
|
||||||
@@ -534,7 +545,8 @@ _Transfer(struct connectdata *c_conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* write to socket */
|
/* 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) {
|
if(nread != bytes_written) {
|
||||||
failf(data, "Failed uploading data");
|
failf(data, "Failed uploading data");
|
||||||
@@ -613,8 +625,9 @@ CURLcode curl_transfer(CURL *curl)
|
|||||||
|
|
||||||
This is assumed to happen for HTTP(S) only!
|
This is assumed to happen for HTTP(S) only!
|
||||||
*/
|
*/
|
||||||
char prot[16];
|
char prot[16]; /* URL protocol string storage */
|
||||||
char path[URL_MAX_LENGTH];
|
char letter; /* used for a silly sscanf */
|
||||||
|
|
||||||
if (data->maxredirs && (data->followlocation >= data->maxredirs)) {
|
if (data->maxredirs && (data->followlocation >= data->maxredirs)) {
|
||||||
failf(data,"Maximum (%d) redirects followed", data->maxredirs);
|
failf(data,"Maximum (%d) redirects followed", data->maxredirs);
|
||||||
curl_disconnect(c_connect);
|
curl_disconnect(c_connect);
|
||||||
@@ -638,12 +651,11 @@ CURLcode curl_transfer(CURL *curl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
data->referer = strdup(data->url);
|
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 */
|
data->bits.http_set_referer = TRUE; /* might have been false */
|
||||||
}
|
}
|
||||||
|
|
||||||
if(2 != sscanf(data->newurl, "%15[^:]://%" URL_MAX_LENGTH_TXT
|
if(2 != sscanf(data->newurl, "%15[^:]://%c", prot, &letter)) {
|
||||||
"s", prot, path)) {
|
|
||||||
/***
|
/***
|
||||||
*DANG* this is an RFC 2068 violation. The URL is supposed
|
*DANG* this is an RFC 2068 violation. The URL is supposed
|
||||||
to be absolute and this doesn't seem to be that!
|
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->current_speed = -1; /* init to negative == impossible */
|
||||||
|
|
||||||
|
data->httpreq = HTTPREQ_GET; /* Default HTTP request */
|
||||||
|
|
||||||
*curl = data;
|
*curl = data;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
@@ -340,6 +342,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
|
|||||||
break;
|
break;
|
||||||
case CURLOPT_POST:
|
case CURLOPT_POST:
|
||||||
data->bits.http_post = va_arg(param, long)?TRUE:FALSE;
|
data->bits.http_post = va_arg(param, long)?TRUE:FALSE;
|
||||||
|
data->httpreq = HTTPREQ_POST;
|
||||||
break;
|
break;
|
||||||
case CURLOPT_FILETIME:
|
case CURLOPT_FILETIME:
|
||||||
data->bits.get_filetime = va_arg(param, long)?TRUE:FALSE;
|
data->bits.get_filetime = va_arg(param, long)?TRUE:FALSE;
|
||||||
@@ -361,19 +364,17 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
|
|||||||
break;
|
break;
|
||||||
case CURLOPT_PUT:
|
case CURLOPT_PUT:
|
||||||
data->bits.http_put = va_arg(param, long)?TRUE:FALSE;
|
data->bits.http_put = va_arg(param, long)?TRUE:FALSE;
|
||||||
|
data->httpreq = HTTPREQ_PUT;
|
||||||
break;
|
break;
|
||||||
case CURLOPT_MUTE:
|
case CURLOPT_MUTE:
|
||||||
data->bits.mute = va_arg(param, long)?TRUE:FALSE;
|
data->bits.mute = va_arg(param, long)?TRUE:FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURLOPT_TIMECONDITION:
|
case CURLOPT_TIMECONDITION:
|
||||||
data->timecondition = va_arg(param, long);
|
data->timecondition = va_arg(param, long);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURLOPT_TIMEVALUE:
|
case CURLOPT_TIMEVALUE:
|
||||||
data->timevalue = va_arg(param, long);
|
data->timevalue = va_arg(param, long);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURLOPT_SSLVERSION:
|
case CURLOPT_SSLVERSION:
|
||||||
data->ssl.version = va_arg(param, long);
|
data->ssl.version = va_arg(param, long);
|
||||||
break;
|
break;
|
||||||
@@ -405,10 +406,12 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
|
|||||||
break;
|
break;
|
||||||
case CURLOPT_CUSTOMREQUEST:
|
case CURLOPT_CUSTOMREQUEST:
|
||||||
data->customrequest = va_arg(param, char *);
|
data->customrequest = va_arg(param, char *);
|
||||||
|
data->httpreq = HTTPREQ_CUSTOM;
|
||||||
break;
|
break;
|
||||||
case CURLOPT_HTTPPOST:
|
case CURLOPT_HTTPPOST:
|
||||||
data->httppost = va_arg(param, struct HttpPost *);
|
data->httppost = va_arg(param, struct HttpPost *);
|
||||||
data->bits.http_formpost = data->httppost?1:0;
|
data->bits.http_formpost = data->httppost?1:0;
|
||||||
|
data->httpreq = HTTPREQ_POST_FORM;
|
||||||
break;
|
break;
|
||||||
case CURLOPT_INFILE:
|
case CURLOPT_INFILE:
|
||||||
data->in = va_arg(param, FILE *);
|
data->in = va_arg(param, FILE *);
|
||||||
@@ -533,7 +536,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#if !defined(WIN32)||defined(__CYGWIN32__)
|
||||||
#ifndef RETSIGTYPE
|
#ifndef RETSIGTYPE
|
||||||
#define RETSIGTYPE void
|
#define RETSIGTYPE void
|
||||||
#endif
|
#endif
|
||||||
@@ -546,67 +549,6 @@ RETSIGTYPE alarmfunc(int signal)
|
|||||||
}
|
}
|
||||||
#endif
|
#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)
|
CURLcode curl_disconnect(CURLconnect *c_connect)
|
||||||
{
|
{
|
||||||
struct connectdata *conn = c_connect;
|
struct connectdata *conn = c_connect;
|
||||||
@@ -635,17 +577,25 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
char resumerange[40]="";
|
char resumerange[40]="";
|
||||||
struct UrlData *data = curl;
|
struct UrlData *data = curl;
|
||||||
struct connectdata *conn;
|
struct connectdata *conn;
|
||||||
|
char endbracket;
|
||||||
#ifdef HAVE_SIGACTION
|
#ifdef HAVE_SIGACTION
|
||||||
struct sigaction sigact;
|
struct sigaction sigact;
|
||||||
#endif
|
#endif
|
||||||
int urllen;
|
int urllen;
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* Check input data
|
||||||
|
*************************************************************/
|
||||||
|
|
||||||
if(!data || (data->handle != STRUCT_OPEN))
|
if(!data || (data->handle != STRUCT_OPEN))
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */
|
return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */
|
||||||
|
|
||||||
if(!data->url)
|
if(!data->url)
|
||||||
return CURLE_URL_MALFORMAT;
|
return CURLE_URL_MALFORMAT;
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* Allocate and initiate a connection struct
|
||||||
|
*************************************************************/
|
||||||
conn = (struct connectdata *)malloc(sizeof(struct connectdata));
|
conn = (struct connectdata *)malloc(sizeof(struct connectdata));
|
||||||
if(!conn) {
|
if(!conn) {
|
||||||
*in_connect = NULL; /* clear the pointer */
|
*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 */
|
buf = data->buffer; /* this is our buffer */
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* Set signal handler
|
||||||
|
*************************************************************/
|
||||||
#ifdef HAVE_SIGACTION
|
#ifdef HAVE_SIGACTION
|
||||||
sigaction(SIGALRM, NULL, &sigact);
|
sigaction(SIGALRM, NULL, &sigact);
|
||||||
sigact.sa_handler = alarmfunc;
|
sigact.sa_handler = alarmfunc;
|
||||||
@@ -680,9 +633,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
|
|
||||||
#endif
|
#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
|
* We need to allocate memory to store the path in. We get the size of the
|
||||||
other parts of the code will rely on this fact */
|
* 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
|
#define LEAST_PATH_ALLOC 256
|
||||||
urllen=strlen(data->url);
|
urllen=strlen(data->url);
|
||||||
if(urllen < LEAST_PATH_ALLOC)
|
if(urllen < LEAST_PATH_ALLOC)
|
||||||
@@ -692,25 +647,30 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
if(NULL == conn->path)
|
if(NULL == conn->path)
|
||||||
return CURLE_OUT_OF_MEMORY; /* really bad error */
|
return CURLE_OUT_OF_MEMORY; /* really bad error */
|
||||||
|
|
||||||
/* Parse <url> */
|
/*************************************************************
|
||||||
/* We need to parse the url, even when using the proxy, because
|
* Parse the URL.
|
||||||
* 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
|
* We need to parse the url even when using the proxy, because we will need
|
||||||
* will need to use SSL until we parse the url ...
|
* 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]",
|
if((2 == sscanf(data->url, "%64[^:]://%[^\n]",
|
||||||
conn->proto,
|
conn->proto,
|
||||||
conn->path)) && strequal(conn->proto, "file")) {
|
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",
|
* we deal with file://<host>/<path> differently since it supports no
|
||||||
which is unique among the protocols specified in RFC 1738 */
|
* 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) ||
|
if (strnequal(conn->path, "localhost/", 10) ||
|
||||||
strnequal(conn->path, "127.0.0.1/", 10))
|
strnequal(conn->path, "127.0.0.1/", 10))
|
||||||
/* ... since coincidentally both host strings are of equal length
|
/* If there's another host name than the one we support, <host>/ is
|
||||||
otherwise, <host>/ is quietly ommitted */
|
* quietly ommitted */
|
||||||
strcpy(conn->path, &conn->path[10]);
|
strcpy(conn->path, &conn->path[10]);
|
||||||
|
|
||||||
strcpy(conn->proto, "file");
|
strcpy(conn->proto, "file"); /* store protocol string lowercase */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Set default host and default path */
|
/* Set default host and default path */
|
||||||
@@ -721,12 +681,24 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
"%64[^\n:]://%256[^\n/]%[^\n]",
|
"%64[^\n:]://%256[^\n/]%[^\n]",
|
||||||
conn->proto, conn->gname, conn->path)) {
|
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]",
|
if((1 > sscanf(data->url, "%256[^\n/]%[^\n]",
|
||||||
conn->gname, conn->path)) ) {
|
conn->gname, conn->path)) ) {
|
||||||
|
/*
|
||||||
|
* We couldn't even get this format.
|
||||||
|
*/
|
||||||
failf(data, "<url> malformed");
|
failf(data, "<url> malformed");
|
||||||
return CURLE_URL_MALFORMAT;
|
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)) {
|
if(strnequal(conn->gname, "FTP", 3)) {
|
||||||
strcpy(conn->proto, "ftp");
|
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) {
|
if(data->bits.user_passwd && !data->bits.use_netrc) {
|
||||||
data->user[0] =0;
|
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) {
|
if(data->bits.proxy_user_passwd) {
|
||||||
data->proxyuser[0] =0;
|
data->proxyuser[0] =0;
|
||||||
data->proxypasswd[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->name = conn->gname;
|
||||||
conn->ppath = conn->path;
|
conn->ppath = conn->path;
|
||||||
data->hostname = conn->name;
|
data->hostname = conn->name;
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* Detect what (if any) proxy to use
|
||||||
|
*************************************************************/
|
||||||
if(!data->bits.httpproxy) {
|
if(!data->bits.httpproxy) {
|
||||||
/* If proxy was not specified, we check for default proxy environment
|
/* If proxy was not specified, we check for default proxy environment
|
||||||
variables, to enable i.e Lynx compliance:
|
* variables, to enable i.e Lynx compliance:
|
||||||
|
*
|
||||||
http_proxy=http://some.server.dom:port/
|
* http_proxy=http://some.server.dom:port/
|
||||||
https_proxy=http://some.server.dom:port/
|
* https_proxy=http://some.server.dom:port/
|
||||||
ftp_proxy=http://some.server.dom:port/
|
* ftp_proxy=http://some.server.dom:port/
|
||||||
gopher_proxy=http://some.server.dom:port/
|
* gopher_proxy=http://some.server.dom:port/
|
||||||
no_proxy=domain1.dom,host.domain2.dom
|
* no_proxy=domain1.dom,host.domain2.dom
|
||||||
(a comma-separated list of hosts which should
|
* (a comma-separated list of hosts which should
|
||||||
not be proxied, or an asterisk to override
|
* not be proxied, or an asterisk to override
|
||||||
all proxy variables)
|
* all proxy variables)
|
||||||
all_proxy=http://some.server.dom:port/
|
* all_proxy=http://some.server.dom:port/
|
||||||
(seems to exist for the CERN www lib. Probably
|
* (seems to exist for the CERN www lib. Probably
|
||||||
the first to check for.)
|
* the first to check for.)
|
||||||
|
*
|
||||||
For compatibility, the all-uppercase versions of these variables are
|
* For compatibility, the all-uppercase versions of these variables are
|
||||||
checked if the lowercase versions don't exist.
|
* checked if the lowercase versions don't exist.
|
||||||
*/
|
*/
|
||||||
char *no_proxy=NULL;
|
char *no_proxy=NULL;
|
||||||
char *proxy=NULL;
|
char *proxy=NULL;
|
||||||
char proxy_env[128];
|
char proxy_env[128];
|
||||||
@@ -890,6 +874,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
free(no_proxy);
|
free(no_proxy);
|
||||||
} /* if not using proxy */
|
} /* if not using proxy */
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* No protocol but proxy usage needs attention
|
||||||
|
*************************************************************/
|
||||||
if((conn->protocol&PROT_MISSING) && data->bits.httpproxy ) {
|
if((conn->protocol&PROT_MISSING) && data->bits.httpproxy ) {
|
||||||
/* We're guessing prefixes here and since we're told to use a proxy, we
|
/* 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!
|
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 */
|
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
|
* RESUME on a HTTP page is a tricky business. First, let's just check that
|
||||||
it is to inform about this situation for later use. We will then
|
* 'range' isn't used, then set the range parameter and leave the resume as
|
||||||
"attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
|
* it is to inform about this situation for later use. We will then
|
||||||
server, we will get the document resumed. If we talk to a HTTP/1.0
|
* "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
|
||||||
server, we just fail since we can't rewind the file writing from within
|
* server, we will get the document resumed. If we talk to a HTTP/1.0
|
||||||
this function. */
|
* server, we just fail since we can't rewind the file writing from within
|
||||||
|
* this function.
|
||||||
|
***********************************************************/
|
||||||
if(data->resume_from) {
|
if(data->resume_from) {
|
||||||
if(!data->bits.set_range) {
|
if(!data->bits.set_range) {
|
||||||
/* if it already was in use, we just skip this */
|
/* 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) {
|
if(data->timeout) {
|
||||||
/* We set the timeout on the connection/resolving phase first, separately
|
/* 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
|
myalarm(data->timeout); /* this sends a signal when the timeout fires
|
||||||
off, and that will abort system calls */
|
off, and that will abort system calls */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*************************************************************
|
||||||
* Hmm, if we are using a proxy, then we can skip the GOPHER and the
|
* Setup internals depending on protocol
|
||||||
* FTP steps, although we cannot skip the HTTPS step (since the proxy
|
*************************************************************/
|
||||||
* works differently, depending on whether its SSL or not).
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (strequal(conn->proto, "HTTP")) {
|
if (strequal(conn->proto, "HTTP")) {
|
||||||
if(!data->port)
|
if(!data->port)
|
||||||
@@ -1006,7 +995,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
conn->ppath++; /* don't include the initial slash */
|
conn->ppath++; /* don't include the initial slash */
|
||||||
|
|
||||||
/* FTP URLs support an extension like ";type=<typecode>" that
|
/* 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=");
|
type=strstr(conn->ppath, ";type=");
|
||||||
if(!type) {
|
if(!type) {
|
||||||
type=strstr(conn->gname, ";type=");
|
type=strstr(conn->gname, ";type=");
|
||||||
@@ -1068,12 +1057,16 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
/* We fell through all checks and thus we don't support the specified
|
||||||
|
protocol */
|
||||||
failf(data, "Unsupported protocol: %s", conn->proto);
|
failf(data, "Unsupported protocol: %s", conn->proto);
|
||||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* .netrc scanning coming up
|
||||||
|
*************************************************************/
|
||||||
if(data->bits.use_netrc) {
|
if(data->bits.use_netrc) {
|
||||||
if(Curl_parsenetrc(data->hostname, data->user, data->passwd)) {
|
if(Curl_parsenetrc(data->hostname, data->user, data->passwd)) {
|
||||||
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
|
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
|
||||||
@@ -1092,9 +1085,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
else if(!(data->bits.user_passwd) &&
|
else if(!(data->bits.user_passwd) &&
|
||||||
(conn->protocol & (PROT_FTP|PROT_HTTP)) ) {
|
(conn->protocol & (PROT_FTP|PROT_HTTP)) ) {
|
||||||
/* This is a FTP or HTTP URL, and we haven't got the user+password in
|
/* 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
|
* the extra parameter, we will now try to extract the possible
|
||||||
user+password pair in a string like:
|
* user+password pair in a string like:
|
||||||
ftp://user:password@ftp.my.site:8021/README */
|
* ftp://user:password@ftp.my.site:8021/README */
|
||||||
char *ptr=NULL; /* assign to remove possible warnings */
|
char *ptr=NULL; /* assign to remove possible warnings */
|
||||||
if((ptr=strchr(conn->name, '@'))) {
|
if((ptr=strchr(conn->name, '@'))) {
|
||||||
/* there's a user+password given here, to the left of the @ */
|
/* 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(!data->bits.httpproxy) {
|
||||||
/* If not connecting via a proxy, extract the port from the URL, if it is
|
/* If not connecting via a proxy, extract the port from the URL, if it is
|
||||||
* there, thus overriding any defaults that might have been set above. */
|
* there, thus overriding any defaults that might have been set above. */
|
||||||
tmp = strchr(conn->name, ':');
|
data->port = data->remote_port; /* it is the same port */
|
||||||
if (tmp) {
|
|
||||||
*tmp++ = '\0';
|
|
||||||
data->port = atoi(tmp);
|
|
||||||
}
|
|
||||||
data->remote_port = data->port; /* it is the same port */
|
|
||||||
|
|
||||||
/* Connect to target host right on */
|
/* Connect to target host right on */
|
||||||
conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf);
|
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;
|
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:
|
/* Daniel Dec 10, 1998:
|
||||||
We do the proxy host string parsing here. We want the host name and the
|
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
|
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_family = conn->hp->h_addrtype;
|
||||||
conn->serv_addr.sin_port = htons(data->port);
|
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
|
/* 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
|
HAVE_XXXX based, although at the moment I don't have a decent test for
|
||||||
this! */
|
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
|
#ifdef HAVE_INET_NTOA
|
||||||
|
|
||||||
#ifndef INADDR_NONE
|
#ifndef INADDR_NONE
|
||||||
#define INADDR_NONE (unsigned long) ~0
|
#define INADDR_NONE (unsigned long) ~0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* Select device to bind socket to
|
||||||
|
*************************************************************/
|
||||||
if (data->device && (strlen(data->device)<255)) {
|
if (data->device && (strlen(data->device)<255)) {
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
struct hostent *h=NULL;
|
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 HAVE_INET_NTOA */
|
||||||
#endif /* end of not WIN32 */
|
#endif /* end of not WIN32 */
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* Connect to server/proxy
|
||||||
|
*************************************************************/
|
||||||
if (connect(data->firstsocket,
|
if (connect(data->firstsocket,
|
||||||
(struct sockaddr *) &(conn->serv_addr),
|
(struct sockaddr *) &(conn->serv_addr),
|
||||||
sizeof(conn->serv_addr)
|
sizeof(conn->serv_addr)
|
||||||
@@ -1400,6 +1420,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* Proxy authentication
|
||||||
|
*************************************************************/
|
||||||
if(data->bits.proxy_user_passwd) {
|
if(data->bits.proxy_user_passwd) {
|
||||||
char *authorization;
|
char *authorization;
|
||||||
snprintf(data->buffer, BUFSIZE, "%s:%s",
|
snprintf(data->buffer, BUFSIZE, "%s:%s",
|
||||||
@@ -1411,6 +1434,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
free(authorization);
|
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((conn->protocol&PROT_HTTP) || data->bits.httpproxy) {
|
||||||
if(data->useragent) {
|
if(data->useragent) {
|
||||||
data->ptr_uagent =
|
data->ptr_uagent =
|
||||||
@@ -1422,9 +1450,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
/* is there a connect() procedure? */
|
/* is there a connect() procedure? */
|
||||||
|
|
||||||
/* set start time here for timeout purposes in the
|
/* set start time here for timeout purposes in the
|
||||||
connect procedure, it is later set again for the
|
* connect procedure, it is later set again for the
|
||||||
progress meter purpose */
|
* progress meter purpose */
|
||||||
conn->now = Curl_tvnow();
|
conn->now = Curl_tvnow();
|
||||||
|
|
||||||
|
/* Call the protocol-specific connect function */
|
||||||
result = conn->curl_connect(conn);
|
result = conn->curl_connect(conn);
|
||||||
if(result != CURLE_OK)
|
if(result != CURLE_OK)
|
||||||
return result; /* pass back errors */
|
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->now = Curl_tvnow(); /* time this *after* the connect is done */
|
||||||
conn->bytecount = 0;
|
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;
|
struct in_addr in;
|
||||||
(void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr));
|
(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 */
|
/* Download buffer size, keep it fairly big for speed reasons */
|
||||||
#define BUFSIZE (1024*50)
|
#define BUFSIZE (1024*50)
|
||||||
|
|
||||||
/* Upload buffer size, keep it smallish to get faster progress meter
|
/* Defaul upload buffer size, keep it smallish to get faster progress meter
|
||||||
updates. This should probably become dynamic and adjust to the upload
|
updates. This is just default, it is dynamic and adjusts to the upload
|
||||||
speed. */
|
speed. */
|
||||||
#define UPLOAD_BUFSIZE (1024*2)
|
#define UPLOAD_BUFSIZE (1024*2)
|
||||||
|
|
||||||
@@ -91,10 +91,14 @@
|
|||||||
of need. */
|
of need. */
|
||||||
#define HEADERSIZE 256
|
#define HEADERSIZE 256
|
||||||
|
|
||||||
|
/* Just a convenience macro to get the larger value out of two given */
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
#define MAX(x,y) ((x)>(y)?(x):(y))
|
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||||
#endif
|
#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 {
|
typedef enum {
|
||||||
STRUCT_NONE,
|
STRUCT_NONE,
|
||||||
STRUCT_OPEN,
|
STRUCT_OPEN,
|
||||||
@@ -102,6 +106,8 @@ typedef enum {
|
|||||||
STRUCT_LAST
|
STRUCT_LAST
|
||||||
} Handle;
|
} 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 {
|
typedef enum {
|
||||||
CONN_NONE, /* illegal state */
|
CONN_NONE, /* illegal state */
|
||||||
CONN_INIT, /* curl_connect() has been called */
|
CONN_INIT, /* curl_connect() has been called */
|
||||||
@@ -112,6 +118,7 @@ typedef enum {
|
|||||||
} ConnState;
|
} ConnState;
|
||||||
|
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
|
/* Types needed for krb4-ftp connections */
|
||||||
struct krb4buffer {
|
struct krb4buffer {
|
||||||
void *data;
|
void *data;
|
||||||
size_t size;
|
size_t size;
|
||||||
@@ -155,13 +162,13 @@ struct connectdata {
|
|||||||
char *hostent_buf; /* pointer to allocated memory for name info */
|
char *hostent_buf; /* pointer to allocated memory for name info */
|
||||||
struct hostent *hp;
|
struct hostent *hp;
|
||||||
struct sockaddr_in serv_addr;
|
struct sockaddr_in serv_addr;
|
||||||
char proto[64];
|
char proto[64]; /* store the protocol string in this buffer */
|
||||||
char gname[256];
|
char gname[257]; /* store the hostname in this buffer */
|
||||||
char *name;
|
char *name; /* host name pointer to fool around with */
|
||||||
char *path; /* formerly staticly this size: URL_MAX_LENGTH */
|
char *path; /* allocated buffer to store the URL's path part in */
|
||||||
char *ppath;
|
char *ppath;
|
||||||
long bytecount;
|
long bytecount;
|
||||||
struct timeval now;
|
struct timeval now; /* current time */
|
||||||
|
|
||||||
long upload_bufsize; /* adjust as you see fit, never bigger than BUFSIZE
|
long upload_bufsize; /* adjust as you see fit, never bigger than BUFSIZE
|
||||||
never smaller than UPLOAD_BUFSIZE */
|
never smaller than UPLOAD_BUFSIZE */
|
||||||
@@ -248,9 +255,9 @@ struct Progress {
|
|||||||
struct HTTP {
|
struct HTTP {
|
||||||
struct FormData *sendit;
|
struct FormData *sendit;
|
||||||
int postsize;
|
int postsize;
|
||||||
char *p_pragma;
|
char *p_pragma; /* Pragma: string */
|
||||||
char *p_accept;
|
char *p_accept; /* Accept: string */
|
||||||
long readbytecount;
|
long readbytecount;
|
||||||
long writebytecount;
|
long writebytecount;
|
||||||
|
|
||||||
/* For FORM posting */
|
/* For FORM posting */
|
||||||
@@ -264,14 +271,32 @@ struct HTTP {
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
struct FTP {
|
struct FTP {
|
||||||
long *bytecountp;
|
long *bytecountp;
|
||||||
char *user;
|
char *user; /* user name string */
|
||||||
char *passwd;
|
char *passwd; /* password string */
|
||||||
char *urlpath; /* the originally given path part of the URL */
|
char *urlpath; /* the originally given path part of the URL */
|
||||||
char *dir; /* decoded directory */
|
char *dir; /* decoded directory */
|
||||||
char *file; /* decoded file */
|
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 {
|
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 get_filetime;
|
||||||
bool tunnel_thru_httpproxy;
|
bool tunnel_thru_httpproxy;
|
||||||
bool ftp_append;
|
bool ftp_append;
|
||||||
@@ -281,10 +306,7 @@ struct Configbits {
|
|||||||
bool hide_progress;
|
bool hide_progress;
|
||||||
bool http_fail_on_error;
|
bool http_fail_on_error;
|
||||||
bool http_follow_location;
|
bool http_follow_location;
|
||||||
bool http_formpost;
|
|
||||||
bool http_include_header;
|
bool http_include_header;
|
||||||
bool http_post;
|
|
||||||
bool http_put;
|
|
||||||
bool http_set_referer;
|
bool http_set_referer;
|
||||||
bool http_auto_referer; /* set "correct" referer when following location: */
|
bool http_auto_referer; /* set "correct" referer when following location: */
|
||||||
bool httpproxy;
|
bool httpproxy;
|
||||||
@@ -299,7 +321,6 @@ struct Configbits {
|
|||||||
bool verbose;
|
bool verbose;
|
||||||
bool this_is_a_follow; /* this is a followed Location: request */
|
bool this_is_a_follow; /* this is a followed Location: request */
|
||||||
bool krb4; /* kerberos4 connection requested */
|
bool krb4; /* kerberos4 connection requested */
|
||||||
|
|
||||||
bool proxystringalloc; /* the http proxy string is malloc()'ed */
|
bool proxystringalloc; /* the http proxy string is malloc()'ed */
|
||||||
bool rangestringalloc; /* the range string is malloc()'ed */
|
bool rangestringalloc; /* the range string is malloc()'ed */
|
||||||
bool urlstringalloc; /* the URL string is malloc()'ed */
|
bool urlstringalloc; /* the URL string is malloc()'ed */
|
||||||
@@ -313,6 +334,7 @@ typedef enum {
|
|||||||
CURLI_LAST
|
CURLI_LAST
|
||||||
} CurlInterface;
|
} CurlInterface;
|
||||||
|
|
||||||
|
/* struct for data related to SSL and SSL connections */
|
||||||
struct ssldata {
|
struct ssldata {
|
||||||
bool use; /* use ssl encrypted communications TRUE/FALSE */
|
bool use; /* use ssl encrypted communications TRUE/FALSE */
|
||||||
long version; /* what version the client wants to use */
|
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 *quote; /* before the transfer */
|
||||||
struct curl_slist *postquote; /* after the transfer */
|
struct curl_slist *postquote; /* after the transfer */
|
||||||
|
|
||||||
TimeCond timecondition;
|
TimeCond timecondition; /* kind of comparison */
|
||||||
time_t timevalue;
|
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 */
|
char *customrequest; /* http/ftp request to use */
|
||||||
|
|
||||||
@@ -482,7 +506,7 @@ struct UrlData {
|
|||||||
completion */
|
completion */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Progress progress;
|
struct Progress progress; /* for all the progress meter data */
|
||||||
|
|
||||||
#define MAX_CURL_USER_LENGTH 128
|
#define MAX_CURL_USER_LENGTH 128
|
||||||
#define MAX_CURL_PASSWORD_LENGTH 128
|
#define MAX_CURL_PASSWORD_LENGTH 128
|
||||||
@@ -492,6 +516,7 @@ struct UrlData {
|
|||||||
* host (which location-following otherwise could lead to)
|
* host (which location-following otherwise could lead to)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* buffers to store authentication data in */
|
||||||
char user[MAX_CURL_USER_LENGTH];
|
char user[MAX_CURL_USER_LENGTH];
|
||||||
char passwd[MAX_CURL_PASSWORD_LENGTH];
|
char passwd[MAX_CURL_PASSWORD_LENGTH];
|
||||||
char proxyuser[MAX_CURL_USER_LENGTH];
|
char proxyuser[MAX_CURL_USER_LENGTH];
|
||||||
@@ -506,7 +531,7 @@ struct UrlData {
|
|||||||
char *ptr_cookie; /* free later if not NULL! */
|
char *ptr_cookie; /* free later if not NULL! */
|
||||||
char *ptr_host; /* free later if not NULL */
|
char *ptr_host; /* free later if not NULL */
|
||||||
|
|
||||||
char *krb4_level;
|
char *krb4_level; /* what security level */
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
FILE *cmdchannel;
|
FILE *cmdchannel;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -61,8 +61,18 @@ char *curl_version(void)
|
|||||||
ptr=strchr(ptr, '\0');
|
ptr=strchr(ptr, '\0');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(KRB4) || defined(ENABLE_IPV6)
|
||||||
|
strcat(ptr, " (");
|
||||||
|
ptr+=2;
|
||||||
#ifdef KRB4
|
#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);
|
ptr += strlen(ptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -26,13 +26,17 @@ while(<STDIN>) {
|
|||||||
|
|
||||||
if($function =~ /free\(0x([0-9a-f]*)/) {
|
if($function =~ /free\(0x([0-9a-f]*)/) {
|
||||||
$addr = $1;
|
$addr = $1;
|
||||||
if($sizeataddr{$addr} <= 0) {
|
if($sizeataddr{$addr} == 0) {
|
||||||
print "FREE ERROR: No memory allocated: $line\n";
|
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 {
|
else {
|
||||||
$totalmem -= $sizeataddr{$addr};
|
$totalmem -= $sizeataddr{$addr};
|
||||||
$sizeataddr{$addr}=0;
|
$sizeataddr{$addr}=-1; # set -1 to mark as freed
|
||||||
$getmem{$addr}=""; # forget after a good free()
|
$getmem{$addr}="$source:$linenum";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif($function =~ /malloc\((\d*)\) = 0x([0-9a-f]*)/) {
|
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 */
|
/* This is now designed to have its own local setup.h */
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined(WIN32)&&!defined(__CYGWIN32__)
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -244,7 +244,6 @@ static void help(void)
|
|||||||
" -A/--user-agent <string> User-Agent to send to server (H)\n"
|
" -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/--cookie <name=string/file> Cookie string or file to read cookies from (H)\n"
|
||||||
" -B/--use-ascii Use ASCII/text transfer\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"
|
" -C/--continue-at <offset> Specify absolute resume offset\n"
|
||||||
" -d/--data <data> HTTP POST data (H)\n"
|
" -d/--data <data> HTTP POST data (H)\n"
|
||||||
" --data-ascii <data> HTTP POST ASCII data (H)\n"
|
" --data-ascii <data> HTTP POST ASCII data (H)\n"
|
||||||
@@ -278,7 +277,6 @@ static void help(void)
|
|||||||
" -r/--range <range> Retrieve a byte range from a HTTP/1.1 or FTP server\n"
|
" -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/--silent Silent mode. Don't output anything\n"
|
||||||
" -S/--show-error Show error. With -s, make curl show errors when they occur\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"
|
" -T/--upload-file <file> Transfer/upload <file> to remote site\n"
|
||||||
" --url <URL> Another way to specify URL to work with\n"
|
" --url <URL> Another way to specify URL to work with\n"
|
||||||
" -u/--user <user[:password]> Specify user and password to use\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! */
|
/* multiple files extracted to stdout, insert separators! */
|
||||||
separator = 1;
|
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;
|
char *outfile;
|
||||||
outfile = outfiles?strdup(outfiles):NULL;
|
outfile = outfiles?strdup(outfiles):NULL;
|
||||||
|
|
||||||
@@ -1713,7 +1713,7 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
if(!config->errors)
|
if(!config->errors)
|
||||||
config->errors = stderr;
|
config->errors = stderr;
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined(WIN32) && !defined(__CYGWIN32__)
|
||||||
if(!outfile && !(config->conf & CONF_GETTEXT)) {
|
if(!outfile && !(config->conf & CONF_GETTEXT)) {
|
||||||
/* We get the output to stdout and we have not got the ASCII/text flag,
|
/* We get the output to stdout and we have not got the ASCII/text flag,
|
||||||
then set stdout to be binary */
|
then set stdout to be binary */
|
||||||
|
|||||||
167
src/urlglob.c
167
src/urlglob.c
@@ -32,9 +32,23 @@
|
|||||||
#include "../lib/memdebug.h"
|
#include "../lib/memdebug.h"
|
||||||
#endif
|
#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 '{'
|
/* processes a set expression with the point behind the opening '{'
|
||||||
','-separated elements are collected until the next closing '}'
|
','-separated elements are collected until the next closing '}'
|
||||||
@@ -52,13 +66,15 @@ int glob_set(URLGlob *glob, char *pattern, int pos)
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
switch (*pattern) {
|
switch (*pattern) {
|
||||||
case '\0': /* URL ended while set was still open */
|
case '\0': /* URL ended while set was still open */
|
||||||
printf("error: unmatched brace at pos %d\n", pos);
|
/*printf("error: unmatched brace at pos %d\n", pos);*/
|
||||||
exit (CURLE_URL_MALFORMAT);
|
return GLOB_ERROR;
|
||||||
|
|
||||||
case '{':
|
case '{':
|
||||||
case '[': /* no nested expressions at this time */
|
case '[': /* no nested expressions at this time */
|
||||||
printf("error: nested braces not supported %d\n", pos);
|
/*printf("error: nested braces not supported %d\n", pos);*/
|
||||||
exit (CURLE_URL_MALFORMAT);
|
return GLOB_ERROR;
|
||||||
|
|
||||||
case ',':
|
case ',':
|
||||||
case '}': /* set element completed */
|
case '}': /* set element completed */
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
@@ -66,40 +82,51 @@ int glob_set(URLGlob *glob, char *pattern, int pos)
|
|||||||
realloc(pat->content.Set.elements,
|
realloc(pat->content.Set.elements,
|
||||||
(pat->content.Set.size + 1) * sizeof(char*));
|
(pat->content.Set.size + 1) * sizeof(char*));
|
||||||
if (!pat->content.Set.elements) {
|
if (!pat->content.Set.elements) {
|
||||||
printf("out of memory in set pattern\n");
|
/*printf("out of memory in set pattern\n");*/
|
||||||
exit(CURLE_OUT_OF_MEMORY);
|
return GLOB_ERROR;
|
||||||
}
|
}
|
||||||
pat->content.Set.elements[pat->content.Set.size] =
|
pat->content.Set.elements[pat->content.Set.size] =
|
||||||
strdup(glob->glob_buffer);
|
strdup(glob->glob_buffer);
|
||||||
++pat->content.Set.size;
|
++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 */
|
/* 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;
|
buf = glob->glob_buffer;
|
||||||
++pattern;
|
++pattern;
|
||||||
++pos;
|
++pos;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ']': /* illegal closing bracket */
|
case ']': /* illegal closing bracket */
|
||||||
printf("error: illegal pattern at pos %d\n", pos);
|
/*printf("error: illegal pattern at pos %d\n", pos);*/
|
||||||
exit (CURLE_URL_MALFORMAT);
|
return GLOB_ERROR;
|
||||||
|
|
||||||
case '\\': /* escaped character, skip '\' */
|
case '\\': /* escaped character, skip '\' */
|
||||||
if (*(buf+1) == '\0') { /* but no escaping of '\0'! */
|
if (*(buf+1) == '\0') { /* but no escaping of '\0'! */
|
||||||
printf("error: illegal pattern at pos %d\n", pos);
|
/*printf("error: illegal pattern at pos %d\n", pos); */
|
||||||
exit (CURLE_URL_MALFORMAT);
|
return GLOB_ERROR;
|
||||||
}
|
}
|
||||||
++pattern;
|
++pattern;
|
||||||
++pos; /* intentional fallthrough */
|
++pos; /* intentional fallthrough */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
*buf++ = *pattern++; /* copy character to set element */
|
*buf++ = *pattern++; /* copy character to set element */
|
||||||
++pos;
|
++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 '['
|
/* processes a range expression with the point behind the opening '['
|
||||||
- char range: e.g. "a-z]", "B-Q]"
|
- char range: e.g. "a-z]", "B-Q]"
|
||||||
@@ -109,6 +136,7 @@ int glob_range(URLGlob *glob, char *pattern, int pos)
|
|||||||
*/
|
*/
|
||||||
URLPattern *pat;
|
URLPattern *pat;
|
||||||
char *c;
|
char *c;
|
||||||
|
int wordamount=1;
|
||||||
|
|
||||||
pat = (URLPattern*)&glob->pattern[glob->size / 2];
|
pat = (URLPattern*)&glob->pattern[glob->size / 2];
|
||||||
/* patterns 0,1,2,... correspond to size=1,3,5,... */
|
/* 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 */
|
if (isalpha((int)*pattern)) { /* character range detected */
|
||||||
pat->type = UPTCharRange;
|
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.min_c >= pat->content.CharRange.max_c ||
|
||||||
pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') {
|
pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') {
|
||||||
/* the pattern is not well-formed */
|
/* the pattern is not well-formed */
|
||||||
printf("error: illegal pattern or range specification after pos %d\n", pos);
|
#if 0
|
||||||
exit (CURLE_URL_MALFORMAT);
|
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;
|
pat->content.CharRange.ptr_c = pat->content.CharRange.min_c;
|
||||||
/* always check for a literal (may be "") between patterns */
|
/* 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->type = UPTNumRange;
|
||||||
pat->content.NumRange.padlength = 0;
|
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) {
|
pat->content.NumRange.min_n >= pat->content.NumRange.max_n) {
|
||||||
/* the pattern is not well-formed */
|
/* the pattern is not well-formed */
|
||||||
printf("error: illegal pattern or range specification after pos %d\n", pos);
|
#if 0
|
||||||
exit (CURLE_URL_MALFORMAT);
|
printf("error: illegal pattern or range specification after pos %d\n",
|
||||||
|
pos);
|
||||||
|
#endif
|
||||||
|
return GLOB_ERROR;
|
||||||
}
|
}
|
||||||
if (*pattern == '0') { /* leading zero specified */
|
if (*pattern == '0') { /* leading zero specified */
|
||||||
c = pattern;
|
c = pattern;
|
||||||
while (isdigit((int)*c++))
|
while (isdigit((int)*c++))
|
||||||
++pat->content.NumRange.padlength; /* padding length is set for all instances
|
++pat->content.NumRange.padlength; /* padding length is set for all
|
||||||
of this pattern */
|
instances of this pattern */
|
||||||
}
|
}
|
||||||
pat->content.NumRange.ptr_n = pat->content.NumRange.min_n;
|
pat->content.NumRange.ptr_n = pat->content.NumRange.min_n;
|
||||||
c = (char*)(strchr(pattern, ']') + 1); /* continue after next ']' */
|
c = (char*)(strchr(pattern, ']') + 1); /* continue after next ']' */
|
||||||
|
|
||||||
/* always check for a literal (may be "") between patterns */
|
/* 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);
|
/*printf("error: illegal character in range specification at pos %d\n",
|
||||||
exit (CURLE_URL_MALFORMAT);
|
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
|
/* processes a literal string component of a URL
|
||||||
special characters '{' and '[' branch to set/range processing functions
|
special characters '{' and '[' branch to set/range processing functions
|
||||||
@@ -161,17 +216,17 @@ int glob_word(URLGlob *glob, char *pattern, int pos)
|
|||||||
char* buf = glob->glob_buffer;
|
char* buf = glob->glob_buffer;
|
||||||
int litindex;
|
int litindex;
|
||||||
|
|
||||||
|
*amount = 1; /* default is one single string */
|
||||||
|
|
||||||
while (*pattern != '\0' && *pattern != '{' && *pattern != '[') {
|
while (*pattern != '\0' && *pattern != '{' && *pattern != '[') {
|
||||||
if (*pattern == '}' || *pattern == ']') {
|
if (*pattern == '}' || *pattern == ']') {
|
||||||
printf("illegal character at position %d\n", pos);
|
return GLOB_ERROR;
|
||||||
exit (CURLE_URL_MALFORMAT);
|
|
||||||
}
|
}
|
||||||
if (*pattern == '\\') { /* escape character, skip '\' */
|
if (*pattern == '\\') { /* escape character, skip '\' */
|
||||||
++pattern;
|
++pattern;
|
||||||
++pos;
|
++pos;
|
||||||
if (*pattern == '\0') { /* but no escaping of '\0'! */
|
if (*pattern == '\0') { /* but no escaping of '\0'! */
|
||||||
printf("illegal character at position %d\n", pos);
|
return GLOB_ERROR;
|
||||||
exit (CURLE_URL_MALFORMAT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*buf++ = *pattern++; /* copy character to literal */
|
*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,... */
|
/* literals 0,1,2,... correspond to size=0,2,4,... */
|
||||||
glob->literal[litindex] = strdup(glob->glob_buffer);
|
glob->literal[litindex] = strdup(glob->glob_buffer);
|
||||||
++glob->size;
|
++glob->size;
|
||||||
if (*pattern == '\0')
|
|
||||||
return 1; /* singular URL processed */
|
switch (*pattern) {
|
||||||
if (*pattern == '{') {
|
case '\0':
|
||||||
return glob_set(glob, ++pattern, ++pos); /* process set pattern */
|
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 */
|
return GLOB_ERROR; /* something got wrong */
|
||||||
}
|
|
||||||
printf("internal error\n");
|
|
||||||
exit (CURLE_FAILED_INIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int glob_url(URLGlob** glob, char* url, int *urlnum)
|
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!
|
* as the specified URL!
|
||||||
*/
|
*/
|
||||||
URLGlob *glob_expand;
|
URLGlob *glob_expand;
|
||||||
|
int amount;
|
||||||
char *glob_buffer=(char *)malloc(strlen(url)+1);
|
char *glob_buffer=(char *)malloc(strlen(url)+1);
|
||||||
|
|
||||||
if(NULL == glob_buffer)
|
if(NULL == glob_buffer)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
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->urllen = strlen(url);
|
||||||
glob_expand->glob_buffer = glob_buffer;
|
glob_expand->glob_buffer = glob_buffer;
|
||||||
glob_expand->beenhere=0;
|
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;
|
*glob = glob_expand;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#define CURL_NAME "curl"
|
#define CURL_NAME "curl"
|
||||||
#define CURL_VERSION "7.6-pre3"
|
#define CURL_VERSION "7.6"
|
||||||
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
||||||
|
|||||||
@@ -53,4 +53,7 @@ command8.txt name14.txt prot5.txt \
|
|||||||
command9.txt name15.txt prot6.txt \
|
command9.txt name15.txt prot6.txt \
|
||||||
error111.txt name16.txt prot7.txt \
|
error111.txt name16.txt prot7.txt \
|
||||||
command26.txt prot26.txt command27.txt prot27.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',
|
'SIZE' => 'loggedin|twosock',
|
||||||
'PWD' => 'loggedin|twosock',
|
'PWD' => 'loggedin|twosock',
|
||||||
'QUIT' => 'loggedin|twosock',
|
'QUIT' => 'loggedin|twosock',
|
||||||
|
'DELE' => 'loggedin|twosock'
|
||||||
);
|
);
|
||||||
|
|
||||||
# initially, we're in 'fresh' state
|
# 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
|
'QUIT' => '221 bye bye baby', # just reply something
|
||||||
'PWD' => '257 "/nowhere/anywhere" is current directory',
|
'PWD' => '257 "/nowhere/anywhere" is current directory',
|
||||||
'REST' => '350 Yeah yeah we set it there for you',
|
'REST' => '350 Yeah yeah we set it there for you',
|
||||||
|
'DELE' => '200 OK OK OK whatever you say'
|
||||||
);
|
);
|
||||||
|
|
||||||
# callback functions for certain commands
|
# callback functions for certain commands
|
||||||
@@ -300,6 +302,7 @@ $SIG{CHLD} = \&REAPER;
|
|||||||
|
|
||||||
my %customreply;
|
my %customreply;
|
||||||
sub customize {
|
sub customize {
|
||||||
|
undef %customreply;
|
||||||
open(CUSTOM, "<log/ftpserver.cmd") ||
|
open(CUSTOM, "<log/ftpserver.cmd") ||
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@@ -307,7 +310,6 @@ sub customize {
|
|||||||
print STDERR "FTPD: Getting commands from log/ftpserver.cmd\n";
|
print STDERR "FTPD: Getting commands from log/ftpserver.cmd\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
undef %customreply;
|
|
||||||
while(<CUSTOM>) {
|
while(<CUSTOM>) {
|
||||||
if($_ =~ /REPLY ([A-Z]+) (.*)/) {
|
if($_ =~ /REPLY ([A-Z]+) (.*)/) {
|
||||||
$customreply{$1}=$2;
|
$customreply{$1}=$2;
|
||||||
|
|||||||
Reference in New Issue
Block a user