Compare commits
30 Commits
curl-7_6_1
...
curl-7_6_1
Author | SHA1 | Date | |
---|---|---|---|
![]() |
948c3b3aa9 | ||
![]() |
a140e5311d | ||
![]() |
7686ac3f2c | ||
![]() |
54778134e4 | ||
![]() |
c59baa06f0 | ||
![]() |
c107303ade | ||
![]() |
21b05afc99 | ||
![]() |
eebcf7d4f5 | ||
![]() |
8d169dfadd | ||
![]() |
b12e334d83 | ||
![]() |
7e36c4437e | ||
![]() |
3c7a80a275 | ||
![]() |
61e2a8108b | ||
![]() |
abb14de7e0 | ||
![]() |
ccd57e58f6 | ||
![]() |
58d70db92e | ||
![]() |
09f6fc22ed | ||
![]() |
833ce37cb9 | ||
![]() |
07e7018564 | ||
![]() |
db70cd28b3 | ||
![]() |
f6e2bfd464 | ||
![]() |
1ae5dab8fb | ||
![]() |
c6355e6a43 | ||
![]() |
7d26eb61fe | ||
![]() |
8613ce377f | ||
![]() |
d6b94488a1 | ||
![]() |
5d7b32d09f | ||
![]() |
ed16d30ea8 | ||
![]() |
6f7c70fbbc | ||
![]() |
9ab5d30e3b |
69
CHANGES
69
CHANGES
@@ -6,11 +6,76 @@
|
||||
|
||||
History of Changes
|
||||
|
||||
Version 7.6.1
|
||||
|
||||
Daniel (9 February 2001)
|
||||
- Frank Reid and Cain Hopwood provided information and research around a HTTPS
|
||||
PUT/upload problem we seem to have. No solution found yet.
|
||||
|
||||
Daniel (8 February 2001)
|
||||
- An interesting discussion is how to specify an empty password without having
|
||||
curl ask for it interactively? The current implmentation takes an empty
|
||||
password as a request for a password prompt. However, I still want to
|
||||
support a blank user field. Thus, today if you enter "-u :" (without user
|
||||
and password) curl will prompt for the password. Tricky. How would you
|
||||
specify you want the prompt otherwise?
|
||||
|
||||
- Made the netrc parse result possible to use for other protocols than FTP and
|
||||
HTTP (such as the upcoming TELNET fixes).
|
||||
|
||||
- The previously mentioned "MSVC++ problems" turned out to be a non-issue.
|
||||
|
||||
- Added a HTTP file upload code example in the docs/examples/ section on
|
||||
request.
|
||||
|
||||
- Adjusted the FTP response fix slightly.
|
||||
|
||||
Version 7.6.1-pre3
|
||||
|
||||
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)
|
||||
- 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
|
||||
a possibility to weird behaviour all over.
|
||||
be able to return -1. The telnet support crashed due to this and there was a
|
||||
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.
|
||||
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 */
|
||||
#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. */
|
||||
/* #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 STDC_HEADERS 1
|
||||
|
||||
|
18
configure.in
18
configure.in
@@ -53,15 +53,9 @@ dnl
|
||||
AC_DEFUN(CURL_CHECK_WORKING_GETADDRINFO,[
|
||||
AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
|
||||
AC_TRY_RUN( [
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
void main(void) {
|
||||
struct addrinfo hints, *ai;
|
||||
@@ -434,6 +428,10 @@ AC_MSG_CHECKING([if Kerberos4 support is requested])
|
||||
|
||||
if test "$want_krb4" = yes
|
||||
then
|
||||
if test "$ipv6" = "yes"; then
|
||||
echo krb4 is not compatible with IPv6
|
||||
exit 1
|
||||
fi
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
dnl Check for & handle argument to --with-krb4
|
||||
@@ -661,6 +659,9 @@ AC_CHECK_SIZEOF(long double, 8)
|
||||
# check for 'long long'
|
||||
AC_CHECK_SIZEOF(long long, 4)
|
||||
|
||||
# check for ssize_t
|
||||
AC_CHECK_TYPE(ssize_t, int)
|
||||
|
||||
dnl Get system canonical name
|
||||
AC_CANONICAL_HOST
|
||||
AC_DEFINE_UNQUOTED(OS, "${host}")
|
||||
@@ -691,7 +692,8 @@ AC_CHECK_FUNCS( socket \
|
||||
setvbuf \
|
||||
sigaction \
|
||||
signal \
|
||||
getpass_r
|
||||
getpass_r \
|
||||
strlcat
|
||||
)
|
||||
|
||||
dnl removed 'getpass' check on October 26, 2000
|
||||
|
67
docs/FAQ
67
docs/FAQ
@@ -1,4 +1,4 @@
|
||||
Updated: January 29, 2001 (http://curl.haxx.se/docs/faq.shtml)
|
||||
Updated: February 12, 2001 (http://curl.haxx.se/docs/faq.shtml)
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
@@ -31,6 +31,7 @@ FAQ
|
||||
3.7 Can I use curl to delete/rename a file through FTP?
|
||||
3.8 How do I tell curl to follow HTTP redirects?
|
||||
3.9 How do I use curl in PHP?
|
||||
3.10 What about SOAP, WEBDAV, XML-RPC or similar protocols over HTTP?
|
||||
|
||||
4. Running Problems
|
||||
4.1 Problems connecting to SSL servers.
|
||||
@@ -53,7 +54,7 @@ FAQ
|
||||
5.2 How can I receive all data into a large memory chunk?
|
||||
5.3 How do I fetch multiple files with libcurl?
|
||||
5.4 Does libcurl do Winsock initing on win32 systems?
|
||||
5.5 Does CURLOPT_FILE work on win32 ?
|
||||
5.5 Does CURLOPT_FILE and CURLOPT_INFILE work on win32 ?
|
||||
5.6 What about Keep-Alive or persistant connections?
|
||||
|
||||
6. License Issues
|
||||
@@ -106,8 +107,8 @@ FAQ
|
||||
or with PHP.
|
||||
|
||||
Curl is not a single-OS program. Curl exists, compiles, builds and runs
|
||||
under a wide range of operating systems, including all modern Unixes,
|
||||
Windows, Amiga, BeOS, OS/2, OS X, QNX etc.
|
||||
under a wide range of operating systems, including all modern Unixes (and a
|
||||
bunch of older ones too), Windows, Amiga, BeOS, OS/2, OS X, QNX etc.
|
||||
|
||||
1.4 When will you make curl do XXXX ?
|
||||
|
||||
@@ -230,7 +231,7 @@ FAQ
|
||||
|
||||
You can't simply use -F or -d at your choice. The web server that will
|
||||
receive your post assumes one of the formats. If the form you're trying to
|
||||
"fake" sets the type to 'multipart/form-data', than and only then you must
|
||||
"fake" sets the type to 'multipart/form-data', then and only then you must
|
||||
use the -F type. In all the most common cases, you should use -d which then
|
||||
causes a posting with the type 'application/x-www-form-urlencoded'.
|
||||
|
||||
@@ -294,6 +295,16 @@ FAQ
|
||||
invoke the curl tool using a command line. This is the way to use curl if
|
||||
you're using PHP3 or PHP4 built without curl module support.
|
||||
|
||||
3.10 What about SOAP, WEBDAV, XML-RPC or similar protocols over HTTP?
|
||||
|
||||
Curl adheres to the HTTP spec, which basically means you can play with *any*
|
||||
protocol that is built ontop of HTTP. Protocols such as SOAP, WEBDAV and
|
||||
XML-RPC are all such ones. You can use -X to set custom requests and -H to
|
||||
set custom headers (or replace internally generated ones).
|
||||
|
||||
Using libcurl or PHP's curl modules is just as fine and you'd just use the
|
||||
proper library options to do the same.
|
||||
|
||||
4. Running Problems
|
||||
|
||||
4.1. Problems connecting to SSL servers.
|
||||
@@ -426,7 +437,8 @@ FAQ
|
||||
4.9. Curl can't authenticate to the server that requires NTLM?
|
||||
|
||||
NTLM is a Microsoft proprietary protocol. Unfortunately, curl does not
|
||||
currently support that.
|
||||
currently support that. Proprietary formats are evil. You should not use
|
||||
such ones.
|
||||
|
||||
5. libcurl Issues
|
||||
|
||||
@@ -491,14 +503,15 @@ FAQ
|
||||
use several different libraries and parts, and there's no reason for every
|
||||
single library to do this.
|
||||
|
||||
5.5 Does CURLOPT_FILE work on win32 ?
|
||||
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
|
||||
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*.
|
||||
that DLL use the FILE *. If you set CURLOPT_FILE you must also use
|
||||
CURLOPT_WRITEFUNCTION as well to set a function that writes the file, even
|
||||
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?
|
||||
|
||||
@@ -511,7 +524,7 @@ FAQ
|
||||
|
||||
6. License Issues
|
||||
|
||||
NOTE: This section is now updated to concern curl 7.5.2 or later!
|
||||
NOTE: This section concerns curl 7.5.2 or later!
|
||||
|
||||
Curl and libcurl are released under a MIT/X derivate license *or* the MPL,
|
||||
the Mozilla Public License. To get a really good answer to your license
|
||||
@@ -529,27 +542,25 @@ FAQ
|
||||
|
||||
6.2. I have a closed-source program, can I use the libcurl library?
|
||||
|
||||
Yes.
|
||||
Yes!
|
||||
|
||||
libcurl does not put any restrictions on the program that uses the
|
||||
library.
|
||||
libcurl does not put any restrictions on the program that uses the library.
|
||||
|
||||
6.3. I have a BSD licensed program, can I use the libcurl library?
|
||||
|
||||
Yes.
|
||||
Yes!
|
||||
|
||||
libcurl does not put any restrictions on the program that uses the
|
||||
library.
|
||||
libcurl does not put any restrictions on the program that uses the library.
|
||||
|
||||
6.4. I have a program that uses LGPL libraries, can I use libcurl?
|
||||
|
||||
Yes.
|
||||
Yes!
|
||||
|
||||
The LGPL license don't clash with other licenses.
|
||||
The LGPL license doesn't clash with other licenses.
|
||||
|
||||
6.5. Can I modify curl/libcurl for my program and keep the changes secret?
|
||||
|
||||
Yes.
|
||||
Yes!
|
||||
|
||||
The MIT/X derivate license practically allows you to do almost anything with
|
||||
the sources, on the condition that the copyright texts in the sources are
|
||||
@@ -557,9 +568,11 @@ FAQ
|
||||
|
||||
6.6. Can you please change the curl/libcurl license to XXXX?
|
||||
|
||||
No. We carefully picked this license years ago and a large amount of people
|
||||
have contributed with source code knowing that this is the license we
|
||||
use. This license puts the restrictions we want on curl/libcurl and it does
|
||||
not spread to other programs or libraries that use it. The recent dual
|
||||
license modification should make it possible for everyone to use libcurl or
|
||||
curl in their projects, no matter what license they already have in use.
|
||||
No.
|
||||
|
||||
We carefully picked this license years ago and a large amount of people have
|
||||
contributed with source code knowing that this is the license we use. This
|
||||
license puts the restrictions we want on curl/libcurl and it does not spread
|
||||
to other programs or libraries that use it. The recent dual license
|
||||
modification should make it possible for everyone to use libcurl or curl in
|
||||
their projects, no matter what license they already have in use.
|
||||
|
15
docs/INSTALL
15
docs/INSTALL
@@ -84,9 +84,10 @@ UNIX
|
||||
|
||||
KNOWN PROBLEMS
|
||||
|
||||
If you happen to have autoconf installed, but a version older than
|
||||
2.12 you will get into trouble. Then you can still build curl by
|
||||
issuing these commands: (from Ralph Beckmann)
|
||||
If you happen to have autoconf installed, but a version older than 2.12
|
||||
you will get into trouble. Then you can still build curl by issuing these
|
||||
commands (note that this requires curl to be built staticly): (from Ralph
|
||||
Beckmann)
|
||||
|
||||
./configure [...]
|
||||
cd lib; make; cd ..
|
||||
@@ -139,6 +140,14 @@ UNIX
|
||||
|
||||
./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
|
||||
=====
|
||||
|
||||
|
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
|
||||
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
|
||||
|
||||
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>
|
||||
- Robert Weaver <robert.weaver@sabre.com>
|
||||
- Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
|
||||
- Jun-ichiro itojun Hagino <itojun@iijlab.net>
|
||||
|
||||
.SH WWW
|
||||
http://curl.haxx.se
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" 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
|
||||
curl_easy_getinfo - Extract information from a curl session (added in 7.4)
|
||||
.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
|
||||
verification that was requested (using the CURLOPT_SSL_VERIFYPEER option to
|
||||
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
|
||||
|
||||
.SH RETURN VALUE
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" 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
|
||||
curl_easy_setopt - Set curl easy-session options
|
||||
.SH SYNOPSIS
|
||||
@@ -35,6 +35,12 @@ Data pointer to pass instead of FILE * to the file write function. Note that
|
||||
if you specify the
|
||||
.I CURLOPT_WRITEFUNCTION
|
||||
, 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
|
||||
.B CURLOPT_WRITEFUNCTION
|
||||
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
|
||||
.I CURLOPT_READFUNCTION
|
||||
, 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
|
||||
.B CURLOPT_READFUNCTION
|
||||
Function pointer that should use match the following prototype:
|
||||
|
@@ -2,13 +2,13 @@
|
||||
.\" nroff -man [file]
|
||||
.\" Written by daniel@haxx.se
|
||||
.\"
|
||||
.TH curl_formparse 3 "6 June 2000" "Curl 7.0" "libcurl Manual"
|
||||
.TH curl_formparse 3 "8 February 2001" "Curl 7.0" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_formparse - add a section to a multipart/formdata HTTP POST
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
.sp
|
||||
.BI "CURLcode *curl_formparse(char *" string, "struct HttpPost **" firstitem,
|
||||
.BI "CURLcode curl_formparse(char *" string, "struct HttpPost **" firstitem,
|
||||
.BI "struct HttpPost ** "lastitem ");"
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
|
@@ -5,7 +5,7 @@
|
||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
|
||||
EXTRA_DIST =
|
||||
README curlgtk.c sepheaders.c simple.c
|
||||
README curlgtk.c sepheaders.c simple.c postit.c
|
||||
|
||||
all:
|
||||
@echo "done"
|
||||
|
68
docs/examples/postit.c
Normal file
68
docs/examples/postit.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Example code that uploads a file name 'foo' to a remote script that accepts
|
||||
* "HTML form based" (as described in RFC1738) uploads using HTTP POST.
|
||||
*
|
||||
* The imaginary form we'll fill in looks like:
|
||||
*
|
||||
* <form method="post" enctype="multipart/form-data" action="examplepost.cgi">
|
||||
* Enter file: <input type="file" name="sendfile" size="40">
|
||||
* Enter file name: <input type="text" name="filename" size="30">
|
||||
* <input type="submit" value="send" name="submit">
|
||||
* </form>
|
||||
*
|
||||
* This exact source code has not been verified to work.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
struct HttpPost *formpost=NULL;
|
||||
struct HttpPost *lastptr=NULL;
|
||||
|
||||
/* Fill in the file upload field */
|
||||
curl_formparse("sendfile=@foo",
|
||||
&formpost,
|
||||
&lastptr);
|
||||
|
||||
/* Fill in the filename field */
|
||||
curl_formparse("filename=foo",
|
||||
&formpost,
|
||||
&lastptr);
|
||||
|
||||
|
||||
/* Fill in the submit field too, even if this is rarely needed */
|
||||
curl_formparse("submit=send",
|
||||
&formpost,
|
||||
&lastptr);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* what URL that receives this POST */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://curl.haxx.se/examplepost.cgi");
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
/* then cleanup the formpost chain */
|
||||
curl_formfree(formpost);
|
||||
}
|
||||
return 0;
|
||||
}
|
@@ -452,7 +452,7 @@ char *curl_getenv(char *variable);
|
||||
char *curl_version(void);
|
||||
|
||||
/* This is the version number */
|
||||
#define LIBCURL_VERSION "7.6.1-pre2"
|
||||
#define LIBCURL_VERSION "7.6.1"
|
||||
#define LIBCURL_VERSION_NUM 0x070601
|
||||
|
||||
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
||||
@@ -676,7 +676,10 @@ typedef enum {
|
||||
CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13,
|
||||
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;
|
||||
|
||||
/*
|
||||
|
@@ -55,7 +55,7 @@ dict.c ftp.h if2ip.c speedcheck.c url.h \
|
||||
dict.h getdate.c if2ip.h speedcheck.h urldata.h \
|
||||
getdate.h ldap.c ssluse.c version.c \
|
||||
getenv.c ldap.h ssluse.h \
|
||||
escape.c getenv.h mprintf.c telnet.c \
|
||||
escape.c mprintf.c telnet.c \
|
||||
escape.h getpass.c netrc.c telnet.h \
|
||||
getinfo.c transfer.c strequal.c strequal.h easy.c \
|
||||
security.h security.c krb4.c krb4.h memdebug.c memdebug.h inet_ntoa_r.h
|
||||
|
274
lib/ftp.c
274
lib/ftp.c
@@ -282,6 +282,10 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
|
||||
*/
|
||||
if(CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &keepon))
|
||||
keepon = FALSE;
|
||||
else if(keepon <= 0) {
|
||||
error = SELECT_ERROR;
|
||||
failf(data, "Connection aborted");
|
||||
}
|
||||
else if ((*ptr == '\n') || (*ptr == '\r'))
|
||||
keepon = FALSE;
|
||||
}
|
||||
@@ -541,9 +545,6 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
|
||||
}
|
||||
}
|
||||
|
||||
free(ftp);
|
||||
data->proto.ftp=NULL; /* it is gone */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -564,6 +565,9 @@ CURLcode _ftp(struct connectdata *conn)
|
||||
#if defined (HAVE_INET_NTOA_R)
|
||||
char ntoa_buf[64];
|
||||
#endif
|
||||
#ifdef ENABLE_IPV6
|
||||
struct addrinfo *ai;
|
||||
#endif
|
||||
|
||||
struct curl_slist *qitem; /* QUOTE item */
|
||||
/* the ftp struct is already inited in ftp_connect() */
|
||||
@@ -702,6 +706,178 @@ CURLcode _ftp(struct connectdata *conn)
|
||||
|
||||
/* We have chosen to use the PORT command */
|
||||
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 hostent *h=NULL;
|
||||
char *hostdataptr=NULL;
|
||||
@@ -809,26 +985,43 @@ CURLcode _ftp(struct connectdata *conn)
|
||||
failf(data, "Server does not grok PORT, try without it!");
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
#endif /* ENABLE_IPV6 */
|
||||
}
|
||||
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(nread < 0)
|
||||
return CURLE_OPERATION_TIMEOUTED;
|
||||
if (ftpcode == results[modeoff])
|
||||
break;
|
||||
}
|
||||
|
||||
if(ftpcode != 227) {
|
||||
if (!mode[modeoff]) {
|
||||
failf(data, "Odd return code after PASV");
|
||||
return CURLE_FTP_WEIRD_PASV_REPLY;
|
||||
}
|
||||
else {
|
||||
else if (strcmp(mode[modeoff], "PASV") == 0) {
|
||||
int ip[4];
|
||||
int port[2];
|
||||
unsigned short newport; /* remote port, not necessary the local one */
|
||||
unsigned short connectport; /* the local port connect() should use! */
|
||||
char newhost[32];
|
||||
#ifdef ENABLE_IPV6
|
||||
struct addrinfo *res;
|
||||
#else
|
||||
struct hostent *he;
|
||||
#endif
|
||||
char *str=buf,*ip_addr;
|
||||
char *hostdataptr=NULL;
|
||||
|
||||
@@ -863,20 +1056,78 @@ CURLcode _ftp(struct connectdata *conn)
|
||||
* proxy again here. We already have the name info for it since the
|
||||
* previous lookup.
|
||||
*/
|
||||
#ifdef ENABLE_IPV6
|
||||
res = conn->res;
|
||||
#else
|
||||
he = conn->hp;
|
||||
#endif
|
||||
connectport =
|
||||
(unsigned short)data->port; /* we connect to the proxy's port */
|
||||
}
|
||||
else {
|
||||
/* normal, direct, ftp connection */
|
||||
#ifdef ENABLE_IPV6
|
||||
res = Curl_getaddrinfo(data, newhost, newport);
|
||||
if(!res)
|
||||
#else
|
||||
he = Curl_gethost(data, newhost, &hostdataptr);
|
||||
if(!he) {
|
||||
if(!he)
|
||||
#endif
|
||||
{
|
||||
failf(data, "Can't resolve new host %s", newhost);
|
||||
return CURLE_FTP_CANT_GET_HOST;
|
||||
}
|
||||
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);
|
||||
|
||||
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
|
||||
@@ -971,6 +1222,7 @@ CURLcode _ftp(struct connectdata *conn)
|
||||
}
|
||||
return CURLE_FTP_CANT_RECONNECT;
|
||||
}
|
||||
#endif /*ENABLE_IPV6*/
|
||||
|
||||
if (data->bits.tunnel_thru_httpproxy) {
|
||||
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
||||
@@ -979,6 +1231,8 @@ CURLcode _ftp(struct connectdata *conn)
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
return CURLE_FTP_CANT_RECONNECT;
|
||||
}
|
||||
}
|
||||
/* we have the (new) data connection ready */
|
||||
|
28
lib/getenv.h
28
lib/getenv.h
@@ -1,28 +0,0 @@
|
||||
#ifndef __GETENV_H
|
||||
#define __GETENV_H
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* In order to be useful for every potential user, curl and libcurl are
|
||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the MPL or the MIT/X-derivate
|
||||
* licenses. You may pick one of these licenses.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#endif
|
@@ -103,6 +103,12 @@ CURLcode curl_getinfo(CURL *curl, CURLINFO info, ...)
|
||||
case CURLINFO_SSL_VERIFYRESULT:
|
||||
*param_longp = data->ssl.certverifyresult;
|
||||
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:
|
||||
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);
|
||||
}
|
||||
|
||||
#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
|
||||
code, written by Bjorn Reese, it has since been patched and modified
|
||||
considerably. */
|
||||
|
@@ -23,6 +23,11 @@
|
||||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
struct addrinfo;
|
||||
struct addrinfo *Curl_getaddrinfo(struct UrlData *data,
|
||||
char *hostname,
|
||||
int port);
|
||||
|
||||
struct hostent *Curl_gethost(struct UrlData *data,
|
||||
char *hostname,
|
||||
char **bufp);
|
||||
|
@@ -226,17 +226,18 @@ int GetLine(int sockfd, char *buf, struct connectdata *conn)
|
||||
(nread<BUFSIZE) && read_rc;
|
||||
nread++, ptr++) {
|
||||
if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) ||
|
||||
(nread <= 0) ||
|
||||
(*ptr == '\n'))
|
||||
break;
|
||||
}
|
||||
*ptr=0; /* zero terminate */
|
||||
|
||||
|
||||
if(data->bits.verbose) {
|
||||
fputs("< ", data->err);
|
||||
fwrite(buf, 1, nread, data->err);
|
||||
fputs("\n", data->err);
|
||||
}
|
||||
return nread;
|
||||
return nread>0?nread:0;
|
||||
}
|
||||
|
||||
|
||||
@@ -374,9 +375,6 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
||||
*bytecount = http->readbytecount + http->writebytecount;
|
||||
}
|
||||
|
||||
free(http);
|
||||
data->proto.http=NULL; /* it is gone */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
@@ -24,7 +24,7 @@
|
||||
*****************************************************************************/
|
||||
#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);
|
||||
#else
|
||||
#define Curl_if2ip(a,b,c) NULL
|
||||
|
@@ -27,7 +27,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "getenv.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "strequal.h"
|
||||
|
||||
/* Debug this single source file with:
|
||||
|
@@ -66,3 +66,44 @@ int Curl_strnequal(const char *first, const char *second, size_t max)
|
||||
#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 "netrc.h"
|
||||
|
||||
#include "getenv.h"
|
||||
#include "hostip.h"
|
||||
#include "transfer.h"
|
||||
#include "sendf.h"
|
||||
|
92
lib/url.c
92
lib/url.c
@@ -80,7 +80,6 @@
|
||||
#include "netrc.h"
|
||||
|
||||
#include "formdata.h"
|
||||
#include "getenv.h"
|
||||
#include "base64.h"
|
||||
#include "ssluse.h"
|
||||
#include "hostip.h"
|
||||
@@ -562,8 +561,17 @@ CURLcode curl_disconnect(CURLconnect *c_connect)
|
||||
|
||||
struct UrlData *data = conn->data;
|
||||
|
||||
if(data->proto.generic)
|
||||
free(data->proto.generic);
|
||||
data->proto.generic=NULL; /* it is gone */
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
if(conn->res) /* host name info */
|
||||
freeaddrinfo(conn->res);
|
||||
#else
|
||||
if(conn->hostent_buf) /* host name info */
|
||||
free(conn->hostent_buf);
|
||||
#endif
|
||||
|
||||
if(conn->path) /* the URL path part */
|
||||
free(conn->path);
|
||||
@@ -589,6 +597,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
||||
struct sigaction sigact;
|
||||
#endif
|
||||
int urllen;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct addrinfo *ai;
|
||||
#endif
|
||||
|
||||
/*************************************************************
|
||||
* Check input data
|
||||
@@ -741,7 +752,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
||||
/* the name is given, get user+password */
|
||||
sscanf(data->userpwd, "%127[^:]:%127[^\n]",
|
||||
data->user, data->passwd);
|
||||
}
|
||||
}
|
||||
else
|
||||
/* no name given, get the password only */
|
||||
sscanf(data->userpwd+1, "%127[^\n]", data->passwd);
|
||||
@@ -1079,15 +1090,15 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
||||
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
|
||||
data->hostname);
|
||||
}
|
||||
else
|
||||
data->bits.user_passwd = 1; /* enable user+password */
|
||||
|
||||
/* weather we failed or not, we don't know which fields that were filled
|
||||
in anyway */
|
||||
if(!data->user[0])
|
||||
strcpy(data->user, CURL_DEFAULT_USER);
|
||||
if(!data->passwd[0])
|
||||
strcpy(data->passwd, CURL_DEFAULT_PASSWORD);
|
||||
if(conn->protocol&PROT_HTTP) {
|
||||
data->bits.user_passwd = 1; /* enable user+password */
|
||||
}
|
||||
}
|
||||
else if(!(data->bits.user_passwd) &&
|
||||
(conn->protocol & (PROT_FTP|PROT_HTTP)) ) {
|
||||
@@ -1189,13 +1200,23 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
||||
data->port = data->remote_port; /* it is the same port */
|
||||
|
||||
/* 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);
|
||||
if(!conn->hp) {
|
||||
if(!conn->hp)
|
||||
#endif
|
||||
{
|
||||
failf(data, "Couldn't resolve host '%s'", conn->name);
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef ENABLE_IPV6
|
||||
failf(data, "proxy yet to be supported");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#else
|
||||
char *prox_portno;
|
||||
char *endofprot;
|
||||
|
||||
@@ -1244,9 +1265,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
||||
}
|
||||
|
||||
free(proxydup); /* free the duplicate pointer and not the modified */
|
||||
#endif
|
||||
}
|
||||
Curl_pgrsTime(data, TIMER_NAMELOOKUP);
|
||||
|
||||
#ifndef ENABLE_IPV6
|
||||
data->firstsocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
|
||||
@@ -1254,6 +1277,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
||||
conn->hp->h_addr, conn->hp->h_length);
|
||||
conn->serv_addr.sin_family = conn->hp->h_addrtype;
|
||||
conn->serv_addr.sin_port = htons(data->port);
|
||||
#endif
|
||||
|
||||
#if !defined(WIN32)||defined(__CYGWIN32__)
|
||||
/* We don't generally like checking for OS-versions, we should make this
|
||||
@@ -1266,6 +1290,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
||||
#define INADDR_NONE (unsigned long) ~0
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_IPV6
|
||||
/*************************************************************
|
||||
* Select device to bind socket to
|
||||
*************************************************************/
|
||||
@@ -1374,10 +1399,31 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
||||
} /* end of device selection support */
|
||||
#endif /* end of HAVE_INET_NTOA */
|
||||
#endif /* end of not WIN32 */
|
||||
#endif /*ENABLE_IPV6*/
|
||||
|
||||
/*************************************************************
|
||||
* 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,
|
||||
(struct sockaddr *) &(conn->serv_addr),
|
||||
sizeof(conn->serv_addr)
|
||||
@@ -1426,6 +1472,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
||||
}
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************
|
||||
* Proxy authentication
|
||||
@@ -1473,11 +1520,31 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
||||
conn->bytecount = 0;
|
||||
|
||||
/* 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;
|
||||
(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));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __EMX__
|
||||
/* 20000330 mgs
|
||||
@@ -1509,8 +1576,13 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
|
||||
if(conn) {
|
||||
if(conn->path)
|
||||
free(conn->path);
|
||||
#ifdef ENABLE_IPV6
|
||||
if(conn->res)
|
||||
freeaddrinfo(conn->res);
|
||||
#else
|
||||
if(conn->hostent_buf)
|
||||
free(conn->hostent_buf);
|
||||
#endif
|
||||
free(conn);
|
||||
*in_connect=NULL;
|
||||
}
|
||||
@@ -1576,7 +1648,13 @@ CURLcode curl_do(CURLconnect *in_conn)
|
||||
if(!conn || (conn->handle!= STRUCT_CONNECT)) {
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
if(conn->state != CONN_INIT) {
|
||||
switch(conn->state) {
|
||||
case CONN_INIT:
|
||||
case CONN_DONE:
|
||||
/* these two states are OK */
|
||||
break;
|
||||
default:
|
||||
/* anything else is bad */
|
||||
return CURLE_BAD_CALLING_ORDER;
|
||||
}
|
||||
|
||||
|
@@ -159,9 +159,13 @@ struct connectdata {
|
||||
#define PROT_LDAP (1<<7)
|
||||
#define PROT_FILE (1<<8)
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
struct addrinfo *res;
|
||||
#else
|
||||
char *hostent_buf; /* pointer to allocated memory for name info */
|
||||
struct hostent *hp;
|
||||
struct sockaddr_in serv_addr;
|
||||
#endif
|
||||
char proto[64]; /* store the protocol string in this buffer */
|
||||
char gname[257]; /* store the hostname in this buffer */
|
||||
char *name; /* host name pointer to fool around with */
|
||||
|
@@ -17,7 +17,7 @@ LINKR = link.exe /incremental:no /libpath:"../lib"
|
||||
|
||||
## Debug
|
||||
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
|
||||
LFLAGS = /nologo /out:$(PROGRAM_NAME) /subsystem:console /machine:I386
|
||||
|
@@ -1,3 +1,3 @@
|
||||
#define CURL_NAME "curl"
|
||||
#define CURL_VERSION "7.6.1-pre2"
|
||||
#define CURL_VERSION "7.6.1"
|
||||
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
||||
|
Reference in New Issue
Block a user