Compare commits
18 Commits
curl-7_6_1
...
curl-7_6_1
Author | SHA1 | Date | |
---|---|---|---|
![]() |
61e2a8108b | ||
![]() |
abb14de7e0 | ||
![]() |
ccd57e58f6 | ||
![]() |
58d70db92e | ||
![]() |
09f6fc22ed | ||
![]() |
833ce37cb9 | ||
![]() |
07e7018564 | ||
![]() |
db70cd28b3 | ||
![]() |
f6e2bfd464 | ||
![]() |
1ae5dab8fb | ||
![]() |
c6355e6a43 | ||
![]() |
7d26eb61fe | ||
![]() |
8613ce377f | ||
![]() |
d6b94488a1 | ||
![]() |
5d7b32d09f | ||
![]() |
ed16d30ea8 | ||
![]() |
6f7c70fbbc | ||
![]() |
9ab5d30e3b |
44
CHANGES
44
CHANGES
@@ -7,10 +7,50 @@
|
|||||||
History of Changes
|
History of Changes
|
||||||
|
|
||||||
|
|
||||||
|
Daniel (7 February 2001)
|
||||||
|
- SM found a flaw in the response reading function for FTP that could make
|
||||||
|
libcurl not get out of the loop properly when it should, if libcurl got -1
|
||||||
|
returned when reading the socket.
|
||||||
|
|
||||||
|
- I found a similar mistake in http.c when using a proxy and reading the
|
||||||
|
results from the proxy connection.
|
||||||
|
|
||||||
|
Daniel (6 February 2001)
|
||||||
|
- A friendly person named "SM" (nntp at iname.com) pointed out that the VC
|
||||||
|
makefile in src/ needed the libpath set for the debug build to work.
|
||||||
|
|
||||||
|
- Daniel Gehriger stepped in to assist with the VC++ stuff Robert Weaver
|
||||||
|
brought up yesterday.
|
||||||
|
|
||||||
|
Daniel (5 February 2001)
|
||||||
|
- Jun-ichiro itojun Hagino brought a big patch that brings IPv6-awareness to
|
||||||
|
a bunch of different areas within libcurl.
|
||||||
|
|
||||||
|
- Robert Weaver told me about the problems the MS VC++ 6.0 compiler has with
|
||||||
|
the 'static' keyword on a number of libcurl functions. I might need to add a
|
||||||
|
patch that redefines static when libcurl is compiled with that compiler.
|
||||||
|
How do I know when VC++ compiles, anyone?
|
||||||
|
|
||||||
|
Daniel (4 February 2001)
|
||||||
|
- curl_getinfo() was extended with two new options:
|
||||||
|
CURLINFO_CONTENT_LENGTH_DOWNLOAD and CURLINFO_CONTENT_LENGTH_UPLOAD. They
|
||||||
|
return the full assumed content length of the transfer in the given
|
||||||
|
direction. The CURLINFO_CONTENT_LENGTH_DOWNLOAD will be the Content-Length:
|
||||||
|
size of a HTTP download. Added descriptions to the man page as well. This
|
||||||
|
was done after discussions with Bob Schader.
|
||||||
|
|
||||||
|
Daniel (3 February 2001)
|
||||||
|
- Ingo Ralf Blum provided another fix that makes curl build under the more
|
||||||
|
recent cygwin installations. It seems they've changed the preset defines to
|
||||||
|
not include WIN32 anymore.
|
||||||
|
|
||||||
|
Version 7.6.1-pre2
|
||||||
|
|
||||||
Daniel (31 January 2001)
|
Daniel (31 January 2001)
|
||||||
- Curl_read() and curl_read() now return a ssize_t for the size, as it had to
|
- Curl_read() and curl_read() now return a ssize_t for the size, as it had to
|
||||||
be able to return -1. The telnet support crashed due to this and there was
|
be able to return -1. The telnet support crashed due to this and there was a
|
||||||
a possibility to weird behaviour all over.
|
possibility to weird behaviour all over. Linus Nielsen Feltzing helped me
|
||||||
|
find this.
|
||||||
|
|
||||||
- Added a configure.in check for a working getaddrinfo() if IPv6 is requested.
|
- Added a configure.in check for a working getaddrinfo() if IPv6 is requested.
|
||||||
I also made the configure script feature --enable-debug which sets a couple
|
I also made the configure script feature --enable-debug which sets a couple
|
||||||
|
@@ -39,3 +39,7 @@
|
|||||||
|
|
||||||
/* Define if you want to enable IPv6 support */
|
/* Define if you want to enable IPv6 support */
|
||||||
#undef ENABLE_IPV6
|
#undef ENABLE_IPV6
|
||||||
|
|
||||||
|
/* Define this to 'int' if ssize_t is not an available typedefed type */
|
||||||
|
#undef ssize_t
|
||||||
|
|
||||||
|
@@ -23,6 +23,9 @@
|
|||||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||||
/* #undef size_t */
|
/* #undef size_t */
|
||||||
|
|
||||||
|
/* Define this to 'int' if ssize_t is not an available typedefed type */
|
||||||
|
#define ssize_t int
|
||||||
|
|
||||||
/* Define if you have the ANSI C header files. */
|
/* Define if you have the ANSI C header files. */
|
||||||
#define STDC_HEADERS 1
|
#define STDC_HEADERS 1
|
||||||
|
|
||||||
|
18
configure.in
18
configure.in
@@ -53,15 +53,9 @@ dnl
|
|||||||
AC_DEFUN(CURL_CHECK_WORKING_GETADDRINFO,[
|
AC_DEFUN(CURL_CHECK_WORKING_GETADDRINFO,[
|
||||||
AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
|
AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
|
||||||
AC_TRY_RUN( [
|
AC_TRY_RUN( [
|
||||||
#ifdef HAVE_NETDB_H
|
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif
|
#include <sys/types.h>
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
struct addrinfo hints, *ai;
|
struct addrinfo hints, *ai;
|
||||||
@@ -434,6 +428,10 @@ AC_MSG_CHECKING([if Kerberos4 support is requested])
|
|||||||
|
|
||||||
if test "$want_krb4" = yes
|
if test "$want_krb4" = yes
|
||||||
then
|
then
|
||||||
|
if test "$ipv6" = "yes"; then
|
||||||
|
echo krb4 is not compatible with IPv6
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
|
||||||
dnl Check for & handle argument to --with-krb4
|
dnl Check for & handle argument to --with-krb4
|
||||||
@@ -661,6 +659,9 @@ AC_CHECK_SIZEOF(long double, 8)
|
|||||||
# check for 'long long'
|
# check for 'long long'
|
||||||
AC_CHECK_SIZEOF(long long, 4)
|
AC_CHECK_SIZEOF(long long, 4)
|
||||||
|
|
||||||
|
# check for ssize_t
|
||||||
|
AC_CHECK_TYPE(ssize_t, int)
|
||||||
|
|
||||||
dnl Get system canonical name
|
dnl Get system canonical name
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_DEFINE_UNQUOTED(OS, "${host}")
|
AC_DEFINE_UNQUOTED(OS, "${host}")
|
||||||
@@ -691,7 +692,8 @@ AC_CHECK_FUNCS( socket \
|
|||||||
setvbuf \
|
setvbuf \
|
||||||
sigaction \
|
sigaction \
|
||||||
signal \
|
signal \
|
||||||
getpass_r
|
getpass_r \
|
||||||
|
strlcat
|
||||||
)
|
)
|
||||||
|
|
||||||
dnl removed 'getpass' check on October 26, 2000
|
dnl removed 'getpass' check on October 26, 2000
|
||||||
|
15
docs/FAQ
15
docs/FAQ
@@ -1,4 +1,4 @@
|
|||||||
Updated: January 29, 2001 (http://curl.haxx.se/docs/faq.shtml)
|
Updated: February 2, 2001 (http://curl.haxx.se/docs/faq.shtml)
|
||||||
_ _ ____ _
|
_ _ ____ _
|
||||||
___| | | | _ \| |
|
___| | | | _ \| |
|
||||||
/ __| | | | |_) | |
|
/ __| | | | |_) | |
|
||||||
@@ -53,7 +53,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 ?
|
5.5 Does CURLOPT_FILE and CURLOPT_INFILE work on win32 ?
|
||||||
5.6 What about Keep-Alive or persistant connections?
|
5.6 What about Keep-Alive or persistant connections?
|
||||||
|
|
||||||
6. License Issues
|
6. License Issues
|
||||||
@@ -491,14 +491,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 ?
|
5.5 Does CURLOPT_FILE and CURLOPT_INFILE work on win32 ?
|
||||||
|
|
||||||
Yes, but you cannot open a FILE * and pass the pointer to a DLL and have
|
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
|
that DLL use the FILE *. If you set CURLOPT_FILE you must also use
|
||||||
function that writes the file, even if that simply writes the data to the
|
CURLOPT_WRITEFUNCTION as well to set a function that writes the file, even
|
||||||
specified FILE*.
|
if that simply writes the data to the specified FILE*. Similarly, if you use
|
||||||
|
CURLOPT_INFILE you must also specify CURLOPT_READFUNCTION.
|
||||||
|
|
||||||
(provided by Joel DeYoung)
|
(Provided by Joel DeYoung and Bob Schader)
|
||||||
|
|
||||||
5.6 What about Keep-Alive or persistant connections?
|
5.6 What about Keep-Alive or persistant connections?
|
||||||
|
|
||||||
|
15
docs/INSTALL
15
docs/INSTALL
@@ -84,9 +84,10 @@ UNIX
|
|||||||
|
|
||||||
KNOWN PROBLEMS
|
KNOWN PROBLEMS
|
||||||
|
|
||||||
If you happen to have autoconf installed, but a version older than
|
If you happen to have autoconf installed, but a version older than 2.12
|
||||||
2.12 you will get into trouble. Then you can still build curl by
|
you will get into trouble. Then you can still build curl by issuing these
|
||||||
issuing these commands: (from Ralph Beckmann)
|
commands (note that this requires curl to be built staticly): (from Ralph
|
||||||
|
Beckmann)
|
||||||
|
|
||||||
./configure [...]
|
./configure [...]
|
||||||
cd lib; make; cd ..
|
cd lib; make; cd ..
|
||||||
@@ -139,6 +140,14 @@ UNIX
|
|||||||
|
|
||||||
./configure --with-krb4=/usr/athena
|
./configure --with-krb4=/usr/athena
|
||||||
|
|
||||||
|
If your system support shared libraries, but you want to built a static
|
||||||
|
version only, you can disable building the shared version by using:
|
||||||
|
|
||||||
|
./configure --disable-shared
|
||||||
|
|
||||||
|
If you're a curl developer and use gcc, you might want to enable more
|
||||||
|
debug options with the --enable-debug option.
|
||||||
|
|
||||||
Win32
|
Win32
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
19
docs/MANUAL
19
docs/MANUAL
@@ -726,6 +726,25 @@ KERBEROS4 FTP TRANSFER
|
|||||||
There's no use for a password on the -u switch, but a blank one will make
|
There's no use for a password on the -u switch, but a blank one will make
|
||||||
curl ask for one and you already entered the real password to kauth.
|
curl ask for one and you already entered the real password to kauth.
|
||||||
|
|
||||||
|
TELNET
|
||||||
|
|
||||||
|
The curl telnet support is basic and very easy to use. Curl passes all data
|
||||||
|
passed to it on stdin to the remote server. Connect to a remote telnet
|
||||||
|
server using a command line similar to:
|
||||||
|
|
||||||
|
curl telnet://remote.server.com
|
||||||
|
|
||||||
|
And enter the data to pass to the server on stdin. The result will be sent
|
||||||
|
to stdout or to the file you specify with -o.
|
||||||
|
|
||||||
|
You might want the -N/--no-buffer option to switch off the buffered output
|
||||||
|
for slow connections or similar.
|
||||||
|
|
||||||
|
NOTE: the telnet protocol does not specify any way to login with a specified
|
||||||
|
user and password so curl can't do that automatically. To do that, you need
|
||||||
|
to track when the login prompt is received and send the username and
|
||||||
|
password accordingly.
|
||||||
|
|
||||||
MAILING LIST
|
MAILING LIST
|
||||||
|
|
||||||
We have an open mailing list to discuss curl, its development and things
|
We have an open mailing list to discuss curl, its development and things
|
||||||
|
@@ -788,6 +788,7 @@ If you do find bugs, mail them to curl-bug@haxx.se.
|
|||||||
- Loic Dachary <loic@senga.org>
|
- Loic Dachary <loic@senga.org>
|
||||||
- Robert Weaver <robert.weaver@sabre.com>
|
- Robert Weaver <robert.weaver@sabre.com>
|
||||||
- Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
|
- Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
|
||||||
|
- Jun-ichiro itojun Hagino <itojun@iijlab.net>
|
||||||
|
|
||||||
.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_init 3 "22 November 2000" "Curl 7.5" "libcurl Manual"
|
.TH curl_easy_init 3 "4 February 2001" "Curl 7.6.1" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_easy_getinfo - Extract information from a curl session (added in 7.4)
|
curl_easy_getinfo - Extract information from a curl session (added in 7.4)
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -81,6 +81,14 @@ than one request if FOLLOWLOCATION is true.
|
|||||||
Pass a pointer to a long to receive the result of the certification
|
Pass a pointer to a long to receive the result of the certification
|
||||||
verification that was requested (using the CURLOPT_SSL_VERIFYPEER option to
|
verification that was requested (using the CURLOPT_SSL_VERIFYPEER option to
|
||||||
curl_easy_setopt). (Added in 7.4.2)
|
curl_easy_setopt). (Added in 7.4.2)
|
||||||
|
.TP
|
||||||
|
.B CURLINFO_CONTENT_LENGTH_DOWNLOAD
|
||||||
|
Pass a pointer to a double to receive the content-length of the download.
|
||||||
|
(Added in 7.6.1)
|
||||||
|
.TP
|
||||||
|
.B CURLINFO_CONTENT_LENGTH_UPLOAD
|
||||||
|
Pass a pointer to a double to receive the specified size of the upload.
|
||||||
|
(Added in 7.6.1)
|
||||||
.PP
|
.PP
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
.\" nroff -man [file]
|
.\" nroff -man [file]
|
||||||
.\" Written by daniel@haxx.se
|
.\" Written by daniel@haxx.se
|
||||||
.\"
|
.\"
|
||||||
.TH curl_easy_setopt 3 "28 November 2000" "Curl 7.5" "libcurl Manual"
|
.TH curl_easy_setopt 3 "2 February 2001" "Curl 7.5" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_easy_setopt - Set curl easy-session options
|
curl_easy_setopt - Set curl easy-session options
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -35,6 +35,12 @@ Data pointer to pass instead of FILE * to the file write function. Note that
|
|||||||
if you specify the
|
if you specify the
|
||||||
.I CURLOPT_WRITEFUNCTION
|
.I CURLOPT_WRITEFUNCTION
|
||||||
, this is the pointer you'll get as input.
|
, this is the pointer you'll get as input.
|
||||||
|
|
||||||
|
NOTE: If you're using libcurl as a win32 .DLL, you MUST use a
|
||||||
|
.I CURLOPT_WRITEFUNCTION
|
||||||
|
if you set the
|
||||||
|
.I CURLOPT_FILE
|
||||||
|
option.
|
||||||
.TP
|
.TP
|
||||||
.B CURLOPT_WRITEFUNCTION
|
.B CURLOPT_WRITEFUNCTION
|
||||||
Function pointer that should use match the following prototype:
|
Function pointer that should use match the following prototype:
|
||||||
@@ -53,6 +59,12 @@ Data pointer to pass instead of FILE * to the file read function. Note that if
|
|||||||
you specify the
|
you specify the
|
||||||
.I CURLOPT_READFUNCTION
|
.I CURLOPT_READFUNCTION
|
||||||
, this is the pointer you'll get as input.
|
, this is the pointer you'll get as input.
|
||||||
|
|
||||||
|
NOTE: If you're using libcurl as a win32 .DLL, you MUST use a
|
||||||
|
.I CURLOPT_READFUNCTION
|
||||||
|
if you set the
|
||||||
|
.I CURLOPT_INFILE
|
||||||
|
option.
|
||||||
.TP
|
.TP
|
||||||
.B CURLOPT_READFUNCTION
|
.B CURLOPT_READFUNCTION
|
||||||
Function pointer that should use match the following prototype:
|
Function pointer that should use match the following prototype:
|
||||||
|
@@ -452,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.1-pre2"
|
#define LIBCURL_VERSION "7.6.1-pre3"
|
||||||
#define LIBCURL_VERSION_NUM 0x070601
|
#define LIBCURL_VERSION_NUM 0x070601
|
||||||
|
|
||||||
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
||||||
@@ -676,7 +676,10 @@ typedef enum {
|
|||||||
CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13,
|
CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13,
|
||||||
CURLINFO_FILETIME = CURLINFO_LONG + 14,
|
CURLINFO_FILETIME = CURLINFO_LONG + 14,
|
||||||
|
|
||||||
CURLINFO_LASTONE = 15
|
CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15,
|
||||||
|
CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16,
|
||||||
|
|
||||||
|
CURLINFO_LASTONE = 17
|
||||||
} CURLINFO;
|
} CURLINFO;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
269
lib/ftp.c
269
lib/ftp.c
@@ -282,6 +282,8 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
|
|||||||
*/
|
*/
|
||||||
if(CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &keepon))
|
if(CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &keepon))
|
||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
|
else if(keepon < 0)
|
||||||
|
error = SELECT_ERROR;
|
||||||
else if ((*ptr == '\n') || (*ptr == '\r'))
|
else if ((*ptr == '\n') || (*ptr == '\r'))
|
||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
}
|
}
|
||||||
@@ -564,6 +566,9 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
#if defined (HAVE_INET_NTOA_R)
|
#if defined (HAVE_INET_NTOA_R)
|
||||||
char ntoa_buf[64];
|
char ntoa_buf[64];
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct addrinfo *ai;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct curl_slist *qitem; /* QUOTE item */
|
struct curl_slist *qitem; /* QUOTE item */
|
||||||
/* the ftp struct is already inited in ftp_connect() */
|
/* the ftp struct is already inited in ftp_connect() */
|
||||||
@@ -702,6 +707,178 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
|
|
||||||
/* We have chosen to use the PORT command */
|
/* We have chosen to use the PORT command */
|
||||||
if(data->bits.ftp_use_port) {
|
if(data->bits.ftp_use_port) {
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct addrinfo hints, *res, *ai;
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
int sslen;
|
||||||
|
char hbuf[NI_MAXHOST];
|
||||||
|
char *localaddr;
|
||||||
|
struct sockaddr *sa=(struct sockaddr *)&ss;
|
||||||
|
#ifdef NI_WITHSCOPEID
|
||||||
|
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
|
||||||
|
#else
|
||||||
|
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
|
||||||
|
#endif
|
||||||
|
unsigned char *ap;
|
||||||
|
unsigned char *pp;
|
||||||
|
int alen, plen;
|
||||||
|
char portmsgbuf[4096], tmp[4096];
|
||||||
|
char *p;
|
||||||
|
char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
|
||||||
|
char **modep;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we should use Curl_if2ip? given pickiness of recent ftpd,
|
||||||
|
* I believe we should use the same address as the control connection.
|
||||||
|
*/
|
||||||
|
sslen = sizeof(ss);
|
||||||
|
if (getsockname(data->firstsocket, (struct sockaddr *)&ss, &sslen) < 0)
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
|
||||||
|
if (getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL, 0,
|
||||||
|
niflags))
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = sa->sa_family;
|
||||||
|
/*hints.ai_family = ss.ss_family;
|
||||||
|
this way can be used if sockaddr_storage is properly defined, as glibc
|
||||||
|
2.1.X doesn't do*/
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
if (getaddrinfo(hbuf, "0", &hints, &res))
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
|
||||||
|
portsock = -1;
|
||||||
|
for (ai = res; ai; ai = ai->ai_next) {
|
||||||
|
portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||||
|
if (portsock < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||||
|
close(portsock);
|
||||||
|
portsock = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(portsock, 1) < 0) {
|
||||||
|
close(portsock);
|
||||||
|
portsock = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (portsock < 0) {
|
||||||
|
failf(data, strerror(errno));
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
sslen = sizeof(ss);
|
||||||
|
if (getsockname(portsock, sa, &sslen) < 0) {
|
||||||
|
failf(data, strerror(errno));
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (modep = mode; modep && *modep; modep++) {
|
||||||
|
int lprtaf, eprtaf;
|
||||||
|
|
||||||
|
switch (sa->sa_family) {
|
||||||
|
case AF_INET:
|
||||||
|
ap = (char *)&((struct sockaddr_in *)&ss)->sin_addr;
|
||||||
|
alen = sizeof(((struct sockaddr_in *)&ss)->sin_addr);
|
||||||
|
pp = (char *)&((struct sockaddr_in *)&ss)->sin_port;
|
||||||
|
plen = sizeof(((struct sockaddr_in *)&ss)->sin_port);
|
||||||
|
lprtaf = 4;
|
||||||
|
eprtaf = 1;
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
ap = (char *)&((struct sockaddr_in6 *)&ss)->sin6_addr;
|
||||||
|
alen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_addr);
|
||||||
|
pp = (char *)&((struct sockaddr_in6 *)&ss)->sin6_port;
|
||||||
|
plen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_port);
|
||||||
|
lprtaf = 6;
|
||||||
|
eprtaf = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ap = pp = NULL;
|
||||||
|
lprtaf = eprtaf = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(*modep, "EPRT") == 0) {
|
||||||
|
if (eprtaf < 0)
|
||||||
|
continue;
|
||||||
|
if (getnameinfo((struct sockaddr *)&ss, sslen,
|
||||||
|
portmsgbuf, sizeof(portmsgbuf), tmp, sizeof(tmp), niflags))
|
||||||
|
continue;
|
||||||
|
/* do not transmit IPv6 scope identifier to the wire */
|
||||||
|
if (sa->sa_family == AF_INET6) {
|
||||||
|
char *q = strchr(portmsgbuf, '%');
|
||||||
|
if (q)
|
||||||
|
*q = '\0';
|
||||||
|
}
|
||||||
|
ftpsendf(data->firstsocket, conn, "%s |%d|%s|%s|", *modep, eprtaf,
|
||||||
|
portmsgbuf, tmp);
|
||||||
|
} else if (strcmp(*modep, "LPRT") == 0 || strcmp(*modep, "PORT") == 0) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(*modep, "PORT") == 0 && sa->sa_family != AF_INET)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
portmsgbuf[0] = '\0';
|
||||||
|
if (strcmp(*modep, "LPRT") == 0) {
|
||||||
|
snprintf(tmp, sizeof(tmp), "%d,%d", lprtaf, alen);
|
||||||
|
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < alen; i++) {
|
||||||
|
if (portmsgbuf[0])
|
||||||
|
snprintf(tmp, sizeof(tmp), ",%u", ap[i]);
|
||||||
|
else
|
||||||
|
snprintf(tmp, sizeof(tmp), "%u", ap[i]);
|
||||||
|
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strcmp(*modep, "LPRT") == 0) {
|
||||||
|
snprintf(tmp, sizeof(tmp), ",%d", plen);
|
||||||
|
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf))
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
for (i = 0; i < plen; i++) {
|
||||||
|
snprintf(tmp, sizeof(tmp), ",%u", pp[i]);
|
||||||
|
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ftpsendf(data->firstsocket, conn, "%s %s", *modep, portmsgbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode);
|
||||||
|
if (nread < 0)
|
||||||
|
return CURLE_OPERATION_TIMEOUTED;
|
||||||
|
|
||||||
|
if (ftpcode != 200) {
|
||||||
|
failf(data, "Server does not grok %s", *modep);
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
again:;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*modep) {
|
||||||
|
close(portsock);
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
struct hostent *h=NULL;
|
struct hostent *h=NULL;
|
||||||
char *hostdataptr=NULL;
|
char *hostdataptr=NULL;
|
||||||
@@ -809,26 +986,43 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
failf(data, "Server does not grok PORT, try without it!");
|
failf(data, "Server does not grok PORT, try without it!");
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
#endif /* ENABLE_IPV6 */
|
||||||
}
|
}
|
||||||
else { /* we use the PASV command */
|
else { /* we use the PASV command */
|
||||||
|
#if 0
|
||||||
|
char *mode[] = { "EPSV", "LPSV", "PASV", NULL };
|
||||||
|
int results[] = { 229, 228, 227, 0 };
|
||||||
|
#else
|
||||||
|
char *mode[] = { "PASV", NULL };
|
||||||
|
int results[] = { 227, 0 };
|
||||||
|
#endif
|
||||||
|
int modeoff;
|
||||||
|
|
||||||
ftpsendf(data->firstsocket, conn, "PASV");
|
for (modeoff = 0; mode[modeoff]; modeoff++) {
|
||||||
|
ftpsendf(data->firstsocket, conn, mode[modeoff]);
|
||||||
|
nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode);
|
||||||
|
if(nread < 0)
|
||||||
|
return CURLE_OPERATION_TIMEOUTED;
|
||||||
|
|
||||||
nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode);
|
if (ftpcode == results[modeoff])
|
||||||
if(nread < 0)
|
break;
|
||||||
return CURLE_OPERATION_TIMEOUTED;
|
}
|
||||||
|
|
||||||
if(ftpcode != 227) {
|
if (!mode[modeoff]) {
|
||||||
failf(data, "Odd return code after PASV");
|
failf(data, "Odd return code after PASV");
|
||||||
return CURLE_FTP_WEIRD_PASV_REPLY;
|
return CURLE_FTP_WEIRD_PASV_REPLY;
|
||||||
}
|
}
|
||||||
else {
|
else if (strcmp(mode[modeoff], "PASV") == 0) {
|
||||||
int ip[4];
|
int ip[4];
|
||||||
int port[2];
|
int port[2];
|
||||||
unsigned short newport; /* remote port, not necessary the local one */
|
unsigned short newport; /* remote port, not necessary the local one */
|
||||||
unsigned short connectport; /* the local port connect() should use! */
|
unsigned short connectport; /* the local port connect() should use! */
|
||||||
char newhost[32];
|
char newhost[32];
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct addrinfo *res;
|
||||||
|
#else
|
||||||
struct hostent *he;
|
struct hostent *he;
|
||||||
|
#endif
|
||||||
char *str=buf,*ip_addr;
|
char *str=buf,*ip_addr;
|
||||||
char *hostdataptr=NULL;
|
char *hostdataptr=NULL;
|
||||||
|
|
||||||
@@ -863,20 +1057,78 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
* proxy again here. We already have the name info for it since the
|
* proxy again here. We already have the name info for it since the
|
||||||
* previous lookup.
|
* previous lookup.
|
||||||
*/
|
*/
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
res = conn->res;
|
||||||
|
#else
|
||||||
he = conn->hp;
|
he = conn->hp;
|
||||||
|
#endif
|
||||||
connectport =
|
connectport =
|
||||||
(unsigned short)data->port; /* we connect to the proxy's port */
|
(unsigned short)data->port; /* we connect to the proxy's port */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* normal, direct, ftp connection */
|
/* normal, direct, ftp connection */
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
res = Curl_getaddrinfo(data, newhost, newport);
|
||||||
|
if(!res)
|
||||||
|
#else
|
||||||
he = Curl_gethost(data, newhost, &hostdataptr);
|
he = Curl_gethost(data, newhost, &hostdataptr);
|
||||||
if(!he) {
|
if(!he)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
failf(data, "Can't resolve new host %s", newhost);
|
failf(data, "Can't resolve new host %s", newhost);
|
||||||
return CURLE_FTP_CANT_GET_HOST;
|
return CURLE_FTP_CANT_GET_HOST;
|
||||||
}
|
}
|
||||||
connectport = newport; /* we connect to the remote port */
|
connectport = newport; /* we connect to the remote port */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
data->secondarysocket = -1;
|
||||||
|
for (ai = res; ai; ai = ai->ai_next) {
|
||||||
|
/* XXX for now, we can do IPv4 only */
|
||||||
|
if (ai->ai_family != AF_INET)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
data->secondarysocket = socket(ai->ai_family, ai->ai_socktype,
|
||||||
|
ai->ai_protocol);
|
||||||
|
if (data->secondarysocket < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(data->bits.verbose) {
|
||||||
|
char hbuf[NI_MAXHOST];
|
||||||
|
char nbuf[NI_MAXHOST];
|
||||||
|
char sbuf[NI_MAXSERV];
|
||||||
|
#ifdef NI_WITHSCOPEID
|
||||||
|
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
|
||||||
|
#else
|
||||||
|
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
|
||||||
|
#endif
|
||||||
|
if (getnameinfo(res->ai_addr, res->ai_addrlen, nbuf, sizeof(nbuf),
|
||||||
|
sbuf, sizeof(sbuf), niflags)) {
|
||||||
|
snprintf(nbuf, sizeof(nbuf), "?");
|
||||||
|
snprintf(sbuf, sizeof(sbuf), "?");
|
||||||
|
}
|
||||||
|
if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
|
||||||
|
NULL, 0, 0)) {
|
||||||
|
infof(data, "Connecting to %s port %s\n", nbuf, sbuf);
|
||||||
|
} else {
|
||||||
|
infof(data, "Connecting to %s (%s) port %s\n", hbuf, nbuf, sbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connect(data->secondarysocket, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||||
|
close(data->secondarysocket);
|
||||||
|
data->secondarysocket = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->secondarysocket < 0) {
|
||||||
|
failf(data, strerror(errno));
|
||||||
|
return CURLE_FTP_CANT_RECONNECT;
|
||||||
|
}
|
||||||
|
#else
|
||||||
data->secondarysocket = socket(AF_INET, SOCK_STREAM, 0);
|
data->secondarysocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
|
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
|
||||||
@@ -971,6 +1223,7 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
return CURLE_FTP_CANT_RECONNECT;
|
return CURLE_FTP_CANT_RECONNECT;
|
||||||
}
|
}
|
||||||
|
#endif /*ENABLE_IPV6*/
|
||||||
|
|
||||||
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 */
|
||||||
@@ -979,6 +1232,8 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
if(CURLE_OK != result)
|
if(CURLE_OK != result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return CURLE_FTP_CANT_RECONNECT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* we have the (new) data connection ready */
|
/* we have the (new) data connection ready */
|
||||||
|
@@ -103,6 +103,12 @@ CURLcode curl_getinfo(CURL *curl, CURLINFO info, ...)
|
|||||||
case CURLINFO_SSL_VERIFYRESULT:
|
case CURLINFO_SSL_VERIFYRESULT:
|
||||||
*param_longp = data->ssl.certverifyresult;
|
*param_longp = data->ssl.certverifyresult;
|
||||||
break;
|
break;
|
||||||
|
case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
|
||||||
|
*param_doublep = data->progress.size_dl;
|
||||||
|
break;
|
||||||
|
case CURLINFO_CONTENT_LENGTH_UPLOAD:
|
||||||
|
*param_doublep = data->progress.size_ul;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
23
lib/hostip.c
23
lib/hostip.c
@@ -83,6 +83,29 @@ static char *MakeIP(unsigned long num,char *addr, int addr_len)
|
|||||||
return (addr);
|
return (addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct addrinfo *Curl_getaddrinfo(struct UrlData *data,
|
||||||
|
char *hostname,
|
||||||
|
int port)
|
||||||
|
{
|
||||||
|
struct addrinfo hints, *res;
|
||||||
|
int error;
|
||||||
|
char sbuf[NI_MAXSERV];
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = PF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_CANONNAME;
|
||||||
|
snprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||||
|
error = getaddrinfo(hostname, sbuf, &hints, &res);
|
||||||
|
if (error) {
|
||||||
|
infof(data, "getaddrinfo(3) failed for %s\n", hostname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The original code to this function was once stolen from the Dancer source
|
/* The original code to this function was once stolen from the Dancer source
|
||||||
code, written by Bjorn Reese, it has since been patched and modified
|
code, written by Bjorn Reese, it has since been patched and modified
|
||||||
considerably. */
|
considerably. */
|
||||||
|
@@ -23,6 +23,11 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
struct addrinfo;
|
||||||
|
struct addrinfo *Curl_getaddrinfo(struct UrlData *data,
|
||||||
|
char *hostname,
|
||||||
|
int port);
|
||||||
|
|
||||||
struct hostent *Curl_gethost(struct UrlData *data,
|
struct hostent *Curl_gethost(struct UrlData *data,
|
||||||
char *hostname,
|
char *hostname,
|
||||||
char **bufp);
|
char **bufp);
|
||||||
|
@@ -226,17 +226,18 @@ int GetLine(int sockfd, char *buf, struct connectdata *conn)
|
|||||||
(nread<BUFSIZE) && read_rc;
|
(nread<BUFSIZE) && read_rc;
|
||||||
nread++, ptr++) {
|
nread++, ptr++) {
|
||||||
if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) ||
|
if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) ||
|
||||||
|
(nread <= 0) ||
|
||||||
(*ptr == '\n'))
|
(*ptr == '\n'))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*ptr=0; /* zero terminate */
|
*ptr=0; /* zero terminate */
|
||||||
|
|
||||||
if(data->bits.verbose) {
|
if(data->bits.verbose) {
|
||||||
fputs("< ", data->err);
|
fputs("< ", data->err);
|
||||||
fwrite(buf, 1, nread, data->err);
|
fwrite(buf, 1, nread, data->err);
|
||||||
fputs("\n", data->err);
|
fputs("\n", data->err);
|
||||||
}
|
}
|
||||||
return nread;
|
return nread>0?nread:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
|
||||||
#if ! defined(WIN32) && ! defined(__BEOS__)
|
#if ! defined(WIN32) && ! defined(__BEOS__) && !defined(__CYGWIN32__)
|
||||||
extern char *Curl_if2ip(char *interface, char *buf, int buf_size);
|
extern char *Curl_if2ip(char *interface, char *buf, int buf_size);
|
||||||
#else
|
#else
|
||||||
#define Curl_if2ip(a,b,c) NULL
|
#define Curl_if2ip(a,b,c) NULL
|
||||||
|
@@ -27,7 +27,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "getenv.h"
|
#include <curl/curl.h>
|
||||||
|
|
||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
|
|
||||||
/* Debug this single source file with:
|
/* Debug this single source file with:
|
||||||
|
@@ -66,3 +66,44 @@ int Curl_strnequal(const char *first, const char *second, size_t max)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_STRLCAT
|
||||||
|
/*
|
||||||
|
* The strlcat() function appends the NUL-terminated string src to the end
|
||||||
|
* of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-termi-
|
||||||
|
* nating the result.
|
||||||
|
*
|
||||||
|
* The strlcpy() and strlcat() functions return the total length of the
|
||||||
|
* string they tried to create. For strlcpy() that means the length of src.
|
||||||
|
* For strlcat() that means the initial length of dst plus the length of
|
||||||
|
* src. While this may seem somewhat confusing it was done to make trunca-
|
||||||
|
* tion detection simple.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
size_t strlcat(char *dst, const char *src, size_t siz)
|
||||||
|
{
|
||||||
|
char *d = dst;
|
||||||
|
const char *s = src;
|
||||||
|
size_t n = siz;
|
||||||
|
size_t dlen;
|
||||||
|
|
||||||
|
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||||
|
while (n-- != 0 && *d != '\0')
|
||||||
|
d++;
|
||||||
|
dlen = d - dst;
|
||||||
|
n = siz - dlen;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
return(dlen + strlen(s));
|
||||||
|
while (*s != '\0') {
|
||||||
|
if (n != 1) {
|
||||||
|
*d++ = *s;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
*d = '\0';
|
||||||
|
|
||||||
|
return(dlen + (s - src)); /* count does not include NUL */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@@ -82,7 +82,6 @@
|
|||||||
#include <curl/types.h>
|
#include <curl/types.h>
|
||||||
#include "netrc.h"
|
#include "netrc.h"
|
||||||
|
|
||||||
#include "getenv.h"
|
|
||||||
#include "hostip.h"
|
#include "hostip.h"
|
||||||
#include "transfer.h"
|
#include "transfer.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
|
72
lib/url.c
72
lib/url.c
@@ -80,7 +80,6 @@
|
|||||||
#include "netrc.h"
|
#include "netrc.h"
|
||||||
|
|
||||||
#include "formdata.h"
|
#include "formdata.h"
|
||||||
#include "getenv.h"
|
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "ssluse.h"
|
#include "ssluse.h"
|
||||||
#include "hostip.h"
|
#include "hostip.h"
|
||||||
@@ -562,8 +561,13 @@ CURLcode curl_disconnect(CURLconnect *c_connect)
|
|||||||
|
|
||||||
struct UrlData *data = conn->data;
|
struct UrlData *data = conn->data;
|
||||||
|
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
if(conn->res) /* host name info */
|
||||||
|
freeaddrinfo(conn->res);
|
||||||
|
#else
|
||||||
if(conn->hostent_buf) /* host name info */
|
if(conn->hostent_buf) /* host name info */
|
||||||
free(conn->hostent_buf);
|
free(conn->hostent_buf);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(conn->path) /* the URL path part */
|
if(conn->path) /* the URL path part */
|
||||||
free(conn->path);
|
free(conn->path);
|
||||||
@@ -589,6 +593,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
struct sigaction sigact;
|
struct sigaction sigact;
|
||||||
#endif
|
#endif
|
||||||
int urllen;
|
int urllen;
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct addrinfo *ai;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Check input data
|
* Check input data
|
||||||
@@ -1189,13 +1196,23 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
data->port = data->remote_port; /* it is the same port */
|
data->port = data->remote_port; /* it is the same port */
|
||||||
|
|
||||||
/* Connect to target host right on */
|
/* Connect to target host right on */
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
conn->res = Curl_getaddrinfo(data, conn->name, data->port);
|
||||||
|
if(!conn->res)
|
||||||
|
#else
|
||||||
conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf);
|
conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf);
|
||||||
if(!conn->hp) {
|
if(!conn->hp)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
failf(data, "Couldn't resolve host '%s'", conn->name);
|
failf(data, "Couldn't resolve host '%s'", conn->name);
|
||||||
return CURLE_COULDNT_RESOLVE_HOST;
|
return CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
failf(data, "proxy yet to be supported");
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
#else
|
||||||
char *prox_portno;
|
char *prox_portno;
|
||||||
char *endofprot;
|
char *endofprot;
|
||||||
|
|
||||||
@@ -1244,9 +1261,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(proxydup); /* free the duplicate pointer and not the modified */
|
free(proxydup); /* free the duplicate pointer and not the modified */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
Curl_pgrsTime(data, TIMER_NAMELOOKUP);
|
Curl_pgrsTime(data, TIMER_NAMELOOKUP);
|
||||||
|
|
||||||
|
#ifndef ENABLE_IPV6
|
||||||
data->firstsocket = socket(AF_INET, SOCK_STREAM, 0);
|
data->firstsocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
|
memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
|
||||||
@@ -1254,6 +1273,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
conn->hp->h_addr, conn->hp->h_length);
|
conn->hp->h_addr, conn->hp->h_length);
|
||||||
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);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(WIN32)||defined(__CYGWIN32__)
|
#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
|
||||||
@@ -1266,6 +1286,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
#define INADDR_NONE (unsigned long) ~0
|
#define INADDR_NONE (unsigned long) ~0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ENABLE_IPV6
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Select device to bind socket to
|
* Select device to bind socket to
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
@@ -1374,10 +1395,31 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
} /* end of device selection support */
|
} /* end of device selection support */
|
||||||
#endif /* end of HAVE_INET_NTOA */
|
#endif /* end of HAVE_INET_NTOA */
|
||||||
#endif /* end of not WIN32 */
|
#endif /* end of not WIN32 */
|
||||||
|
#endif /*ENABLE_IPV6*/
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Connect to server/proxy
|
* Connect to server/proxy
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
data->firstsocket = -1;
|
||||||
|
for (ai = conn->res; ai; ai = ai->ai_next) {
|
||||||
|
data->firstsocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||||
|
if (data->firstsocket < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (connect(data->firstsocket, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||||
|
close(data->firstsocket);
|
||||||
|
data->firstsocket = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (data->firstsocket < 0) {
|
||||||
|
failf(data, strerror(errno));
|
||||||
|
return CURLE_COULDNT_CONNECT;
|
||||||
|
}
|
||||||
|
#else
|
||||||
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)
|
||||||
@@ -1426,6 +1468,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
}
|
}
|
||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Proxy authentication
|
* Proxy authentication
|
||||||
@@ -1473,11 +1516,31 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
conn->bytecount = 0;
|
conn->bytecount = 0;
|
||||||
|
|
||||||
/* Figure out the ip-number and display the first host name it shows: */
|
/* Figure out the ip-number and display the first host name it shows: */
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
{
|
||||||
|
char hbuf[NI_MAXHOST];
|
||||||
|
#ifdef NI_WITHSCOPEID
|
||||||
|
const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
|
||||||
|
#else
|
||||||
|
const int niflags = NI_NUMERICHOST;
|
||||||
|
#endif
|
||||||
|
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0,
|
||||||
|
niflags)) {
|
||||||
|
snprintf(hbuf, sizeof(hbuf), "?");
|
||||||
|
}
|
||||||
|
if (ai->ai_canonname) {
|
||||||
|
infof(data, "Connected to %s (%s)\n", ai->ai_canonname, hbuf);
|
||||||
|
} else {
|
||||||
|
infof(data, "Connected to %s\n", hbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
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));
|
||||||
infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in));
|
infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __EMX__
|
#ifdef __EMX__
|
||||||
/* 20000330 mgs
|
/* 20000330 mgs
|
||||||
@@ -1509,8 +1572,13 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
if(conn) {
|
if(conn) {
|
||||||
if(conn->path)
|
if(conn->path)
|
||||||
free(conn->path);
|
free(conn->path);
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
if(conn->res)
|
||||||
|
freeaddrinfo(conn->res);
|
||||||
|
#else
|
||||||
if(conn->hostent_buf)
|
if(conn->hostent_buf)
|
||||||
free(conn->hostent_buf);
|
free(conn->hostent_buf);
|
||||||
|
#endif
|
||||||
free(conn);
|
free(conn);
|
||||||
*in_connect=NULL;
|
*in_connect=NULL;
|
||||||
}
|
}
|
||||||
|
@@ -159,9 +159,13 @@ struct connectdata {
|
|||||||
#define PROT_LDAP (1<<7)
|
#define PROT_LDAP (1<<7)
|
||||||
#define PROT_FILE (1<<8)
|
#define PROT_FILE (1<<8)
|
||||||
|
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct addrinfo *res;
|
||||||
|
#else
|
||||||
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;
|
||||||
|
#endif
|
||||||
char proto[64]; /* store the protocol string in this buffer */
|
char proto[64]; /* store the protocol string in this buffer */
|
||||||
char gname[257]; /* store the hostname in this buffer */
|
char gname[257]; /* store the hostname in this buffer */
|
||||||
char *name; /* host name pointer to fool around with */
|
char *name; /* host name pointer to fool around with */
|
||||||
|
@@ -17,7 +17,7 @@ LINKR = link.exe /incremental:no /libpath:"../lib"
|
|||||||
|
|
||||||
## Debug
|
## Debug
|
||||||
CCD = cl.exe /MDd /Gm /ZI /Od /D "_DEBUG" /GZ
|
CCD = cl.exe /MDd /Gm /ZI /Od /D "_DEBUG" /GZ
|
||||||
LINKD = link.exe /incremental:yes /debug
|
LINKD = link.exe /incremental:yes /debug /libpath:"../lib"
|
||||||
|
|
||||||
CFLAGS = /I "../include" /nologo /W3 /GX /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
CFLAGS = /I "../include" /nologo /W3 /GX /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||||
LFLAGS = /nologo /out:$(PROGRAM_NAME) /subsystem:console /machine:I386
|
LFLAGS = /nologo /out:$(PROGRAM_NAME) /subsystem:console /machine:I386
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
#define CURL_NAME "curl"
|
#define CURL_NAME "curl"
|
||||||
#define CURL_VERSION "7.6.1-pre2"
|
#define CURL_VERSION "7.6.1-pre3"
|
||||||
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
||||||
|
Reference in New Issue
Block a user