Compare commits
39 Commits
curl-7_9_3
...
curl-7_9_3
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7e16ec8724 | ||
![]() |
8c459156f8 | ||
![]() |
2db894807b | ||
![]() |
95ceeb6e0b | ||
![]() |
c9c00d2a23 | ||
![]() |
1afe49864d | ||
![]() |
6924bee3a0 | ||
![]() |
39d4552dab | ||
![]() |
a23c63738f | ||
![]() |
e911945c55 | ||
![]() |
6d58d13710 | ||
![]() |
0b177cb165 | ||
![]() |
3e31b619de | ||
![]() |
f925979b2f | ||
![]() |
49f7fa82b9 | ||
![]() |
e4cd4cf3f3 | ||
![]() |
e74b20926d | ||
![]() |
a312127c91 | ||
![]() |
1dc5bf4f73 | ||
![]() |
01cfe670c5 | ||
![]() |
fd307bfe29 | ||
![]() |
a00de093a7 | ||
![]() |
7bfe853af3 | ||
![]() |
cbaecca8e9 | ||
![]() |
8edfb370a8 | ||
![]() |
4c08c8f7db | ||
![]() |
c174680a03 | ||
![]() |
cb5f6e18e6 | ||
![]() |
b798e7a5ae | ||
![]() |
5deab7ad27 | ||
![]() |
12cdfd282d | ||
![]() |
eba8035e12 | ||
![]() |
edcbf4350b | ||
![]() |
9289ea471f | ||
![]() |
7d06185aa6 | ||
![]() |
01ecb1d7e7 | ||
![]() |
e177f14595 | ||
![]() |
5c6eddcadd | ||
![]() |
b3b4786990 |
57
CHANGES
57
CHANGES
@@ -6,6 +6,63 @@
|
|||||||
|
|
||||||
History of Changes
|
History of Changes
|
||||||
|
|
||||||
|
Version 7.9.3
|
||||||
|
|
||||||
|
Daniel (23 January 2002)
|
||||||
|
- Andr<64>s Garc<72>a found a persistancy problem when doing HTTP HEAD, that made
|
||||||
|
curl "hang" until the connection was closed by the server. This problem has
|
||||||
|
been introduced in 7.9.3 due to internal rewrites, this was not present in
|
||||||
|
7.9.2.
|
||||||
|
|
||||||
|
Version 7.9.3-pre4
|
||||||
|
|
||||||
|
Daniel (19 January 2002)
|
||||||
|
- Antonio filed bug report #505514 and provided a fix! When doing multipart
|
||||||
|
formposts, libcurl would include an error text in the actual post if a
|
||||||
|
specified file wasn't found. This is not libcurl's job. Instead we add an
|
||||||
|
empty part.
|
||||||
|
|
||||||
|
Daniel (18 January 2002)
|
||||||
|
- Played around with stricter compiler warnings for gcc (when ./configure
|
||||||
|
--enable-debug is used) and changed some minor things to stop the warnings.
|
||||||
|
|
||||||
|
- Commented out the 'long long' and 'long double' checks in configure.in, as
|
||||||
|
we don't currently use them anyway and the code in lib/mprintf.c that use
|
||||||
|
them causes warnings.
|
||||||
|
|
||||||
|
- Saul Good and jonatan pointed out Mac OS X build problems with pre3 and how
|
||||||
|
to correct them. Two compiler warnings were removed as well.
|
||||||
|
|
||||||
|
- Andr<64>s Garc<72>a fixed two minor mingw32 building problems.
|
||||||
|
|
||||||
|
Version 7.9.3-pre3
|
||||||
|
|
||||||
|
Daniel (17 January 2002)
|
||||||
|
- docs/libcurl-the-guide is a new tutorial for our libcurl programming
|
||||||
|
friends.
|
||||||
|
|
||||||
|
- Richard Archer brought back the ability to compile and build with OpenSSL
|
||||||
|
versions before 0.9.5.
|
||||||
|
[http://sourceforge.net/tracker/?func=detail&atid=100976&aid=504163&group_id=976]
|
||||||
|
|
||||||
|
- The DNS cache code didn't take the port number into account, which made it
|
||||||
|
work rather bad on IPv6-enabled hosts (especially when doing passive
|
||||||
|
FTP). Sterling fixed it.
|
||||||
|
|
||||||
|
Daniel (16 January 2002)
|
||||||
|
- Georg Horn could make a transfer time-out without error text. I found it and
|
||||||
|
corrected it.
|
||||||
|
|
||||||
|
- SSL writes didn't work, they return an uninitialized value that caused
|
||||||
|
havoc all over. Georg Horn experienced this.
|
||||||
|
|
||||||
|
- Kevin Roth patched the curl_version() function to use the proper OpenSSL
|
||||||
|
function for version information. This way, curl will report the version of
|
||||||
|
the SSL library actually running right now, not the one that had its headers
|
||||||
|
installed when libcurl was built. Mainly intersting when running with shared
|
||||||
|
OpenSSL libraries.
|
||||||
|
|
||||||
|
Version 7.9.3-pre2
|
||||||
|
|
||||||
Daniel (16 January 2002)
|
Daniel (16 January 2002)
|
||||||
- Mofied the main transfer loop and related stuff to deal with non-blocking
|
- Mofied the main transfer loop and related stuff to deal with non-blocking
|
||||||
|
@@ -69,7 +69,7 @@ AC_ARG_ENABLE(debug,
|
|||||||
*) AC_MSG_RESULT(yes)
|
*) AC_MSG_RESULT(yes)
|
||||||
|
|
||||||
CPPFLAGS="$CPPFLAGS -DMALLOCDEBUG"
|
CPPFLAGS="$CPPFLAGS -DMALLOCDEBUG"
|
||||||
CFLAGS="-W -Wall -Wwrite-strings -pedantic -g"
|
CFLAGS="-W -Wall -Wwrite-strings -pedantic -Wundef -Wpointer-arith -Wcast-align -Wnested-externs -g"
|
||||||
;;
|
;;
|
||||||
esac ],
|
esac ],
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
@@ -524,9 +524,9 @@ AC_HEADER_TIME
|
|||||||
# mprintf() checks:
|
# mprintf() checks:
|
||||||
|
|
||||||
# check for 'long double'
|
# check for 'long double'
|
||||||
AC_CHECK_SIZEOF(long double, 8)
|
# 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
|
# check for ssize_t
|
||||||
AC_CHECK_TYPE(ssize_t, int)
|
AC_CHECK_TYPE(ssize_t, int)
|
||||||
|
7
docs/FAQ
7
docs/FAQ
@@ -1,4 +1,4 @@
|
|||||||
Updated: December 21, 2001 (http://curl.haxx.se/docs/faq.shtml)
|
Updated: January 22, 2002 (http://curl.haxx.se/docs/faq.shtml)
|
||||||
_ _ ____ _
|
_ _ ____ _
|
||||||
___| | | | _ \| |
|
___| | | | _ \| |
|
||||||
/ __| | | | |_) | |
|
/ __| | | | |_) | |
|
||||||
@@ -163,9 +163,8 @@ FAQ
|
|||||||
|
|
||||||
1.6 What do you get for making cURL?
|
1.6 What do you get for making cURL?
|
||||||
|
|
||||||
Project cURL is entirely free and open, without any commercial interests or
|
Project cURL is entirely free and open. No person gets paid in any way for
|
||||||
money involved. No person gets paid in any way for developing curl. We all
|
developing curl. We all do this voluntarily on our spare time.
|
||||||
do this voluntarily on our spare time.
|
|
||||||
|
|
||||||
We get some help from companies. Contactor Data hosts the curl web site and
|
We get some help from companies. Contactor Data hosts the curl web site and
|
||||||
the main mailing list, Haxx owns the curl web site's domain and
|
the main mailing list, Haxx owns the curl web site's domain and
|
||||||
|
88
docs/TODO
88
docs/TODO
@@ -19,10 +19,7 @@ TODO
|
|||||||
|
|
||||||
* The new 'multi' interface is being designed. Work out the details, start
|
* The new 'multi' interface is being designed. Work out the details, start
|
||||||
implementing and write test applications!
|
implementing and write test applications!
|
||||||
[http://curl.haxx.se/dev/multi.h]
|
[http://curl.haxx.se/lxr/source/lib/multi.h]
|
||||||
|
|
||||||
* Add a name resolve cache to libcurl to make repeated fetches to the same
|
|
||||||
host name (when persitancy isn't available) faster.
|
|
||||||
|
|
||||||
* Introduce another callback interface for upload/download that makes one
|
* Introduce another callback interface for upload/download that makes one
|
||||||
less copy of data and thus a faster operation.
|
less copy of data and thus a faster operation.
|
||||||
@@ -33,13 +30,36 @@ TODO
|
|||||||
telnet, ldap, dict or file.
|
telnet, ldap, dict or file.
|
||||||
|
|
||||||
* Add asynchronous name resolving. http://curl.haxx.se/dev/async-resolver.txt
|
* Add asynchronous name resolving. http://curl.haxx.se/dev/async-resolver.txt
|
||||||
|
This should be made to work on most of the supported platforms, or
|
||||||
|
otherwise it isn't really interesting.
|
||||||
|
|
||||||
* Strip any trailing CR from the error message when Curl_failf() is used.
|
* Data sharing. Tell which easy handles within a multi handle that should
|
||||||
|
share cookies, connection cache, dns cache, ssl session cache.
|
||||||
|
|
||||||
|
* Mutexes. By adding mutex callback support, the 'data sharing' mentioned
|
||||||
|
above can be made between several easy handles running in different threads
|
||||||
|
too. The actual mutex implementations will be left for the application to
|
||||||
|
implement, libcurl will merely call 'getmutex' and 'leavemutex' callbacks.
|
||||||
|
|
||||||
|
* No-faster-then-this transfers. Many people have limited bandwidth and they
|
||||||
|
want the ability to make sure their transfers never use more bandwith than
|
||||||
|
they think is good.
|
||||||
|
|
||||||
|
* Set the SO_KEEPALIVE socket option to make libcurl notice and disconnect
|
||||||
|
very long time idle connections.
|
||||||
|
|
||||||
|
* Make sure we don't ever loop because of non-blocking sockets return
|
||||||
|
EWOULDBLOCK or similar. This concerns the HTTP request sending, the FTP
|
||||||
|
command sending etc.
|
||||||
|
|
||||||
|
* Go through the code and verify that libcurl deals with big files >2GB and
|
||||||
|
>4GB all over. Bug reports indicate that it doesn't currently work
|
||||||
|
properly.
|
||||||
|
|
||||||
DOCUMENTATION
|
DOCUMENTATION
|
||||||
|
|
||||||
* Document all CURLcode error codes, why they happen and what most likely
|
* Document all CURLcode error codes, why they happen and what most likely
|
||||||
will make them not happen again.
|
will make them not happen again. In a libcurl point of view.
|
||||||
|
|
||||||
FTP
|
FTP
|
||||||
|
|
||||||
@@ -54,11 +74,7 @@ TODO
|
|||||||
already working http dito works. It of course requires that 'MDTM' works,
|
already working http dito works. It of course requires that 'MDTM' works,
|
||||||
and it isn't a standard FTP command.
|
and it isn't a standard FTP command.
|
||||||
|
|
||||||
* Suggested on the mailing list: CURLOPT_FTP_MKDIR...!
|
* Add FTPS support with SSL for the data connection too.
|
||||||
|
|
||||||
* Always use the FTP SIZE command before downloading, as that makes it more
|
|
||||||
likely that we know the size when downloading. Some sites support SIZE but
|
|
||||||
don't show the size in the RETR response!
|
|
||||||
|
|
||||||
HTTP
|
HTTP
|
||||||
|
|
||||||
@@ -83,34 +99,53 @@ TODO
|
|||||||
http://www.innovation.ch/java/ntlm.html that contains detailed reverse-
|
http://www.innovation.ch/java/ntlm.html that contains detailed reverse-
|
||||||
engineered info.
|
engineered info.
|
||||||
|
|
||||||
* RFC2617 compliance, "Digest Access Authentication"
|
* RFC2617 compliance, "Digest Access Authentication" A valid test page seem
|
||||||
A valid test page seem to exist at:
|
to exist at: http://hopf.math.nwu.edu/testpage/digest/ And some friendly
|
||||||
http://hopf.math.nwu.edu/testpage/digest/
|
person's server source code is available at
|
||||||
And some friendly person's server source code is available at
|
http://hopf.math.nwu.edu/digestauth/index.html Then there's the Apache
|
||||||
http://hopf.math.nwu.edu/digestauth/index.html
|
mod_digest source code too of course. It seems as if Netscape doesn't
|
||||||
Then there's the Apache mod_digest source code too of course. It seems as
|
support this, and not many servers do. Although this is a lot better
|
||||||
if Netscape doesn't support this, and not many servers do. Although this is
|
authentication method than the more common "Basic". Basic sends the
|
||||||
a lot better authentication method than the more common "Basic". Basic
|
password in cleartext over the network, this "Digest" method uses a
|
||||||
sends the password in cleartext over the network, this "Digest" method uses
|
challange-response protocol which increases security quite a lot.
|
||||||
a challange-response protocol which increases security quite a lot.
|
|
||||||
|
* Pipelining. Sending multiple requests before the previous one(s) are done.
|
||||||
|
This could possibly be implemented using the multi interface to queue
|
||||||
|
requests and the response data.
|
||||||
|
|
||||||
TELNET
|
TELNET
|
||||||
|
|
||||||
* Make TELNET work on windows98!
|
* Make TELNET work on windows98!
|
||||||
|
|
||||||
|
* Reading input (to send to the remote server) on stdin is a crappy solution
|
||||||
|
for library purposes. We need to invent a good way for the application to
|
||||||
|
be able to provide the data to send.
|
||||||
|
|
||||||
|
* Move the telnet support's network select() loop go away and merge the code
|
||||||
|
into the main transfer loop. Until this is done, the multi interface won't
|
||||||
|
work for telnet.
|
||||||
|
|
||||||
SSL
|
SSL
|
||||||
|
|
||||||
* Add an interface to libcurl that enables "session IDs" to get
|
* Add an interface to libcurl that enables "session IDs" to get
|
||||||
exported/imported. Cris Bailiff said: "OpenSSL has functions which can
|
exported/imported. Cris Bailiff said: "OpenSSL has functions which can
|
||||||
serialise the current SSL state to a buffer of your choice, and
|
serialise the current SSL state to a buffer of your choice, and
|
||||||
recover/reset the state from such a buffer at a later date - this is used
|
recover/reset the state from such a buffer at a later date - this is used
|
||||||
by mod_ssl for apache to implement and SSL session ID cache"
|
by mod_ssl for apache to implement and SSL session ID cache". This whole
|
||||||
|
idea might become moot if we enable the 'data sharing' as mentioned in the
|
||||||
|
LIBCURL label above.
|
||||||
|
|
||||||
* Make curl's SSL layer option capable of using other free SSL libraries.
|
* Make curl's SSL layer option capable of using other free SSL libraries.
|
||||||
Such as the Mozilla Security Services
|
Such as the Mozilla Security Services
|
||||||
(http://www.mozilla.org/projects/security/pki/nss/) and GNUTLS
|
(http://www.mozilla.org/projects/security/pki/nss/) and GNUTLS
|
||||||
(http://gnutls.hellug.gr/)
|
(http://gnutls.hellug.gr/)
|
||||||
|
|
||||||
|
LDAP
|
||||||
|
|
||||||
|
* Look over the implementation. The looping will have to "go away" from the
|
||||||
|
lib/ldap.c source file and get moved to the main network code so that the
|
||||||
|
multi interface and friends will work for LDAP as well.
|
||||||
|
|
||||||
CLIENT
|
CLIENT
|
||||||
|
|
||||||
* "curl ftp://site.com/*.txt"
|
* "curl ftp://site.com/*.txt"
|
||||||
@@ -119,11 +154,10 @@ TODO
|
|||||||
the same syntax to specify several files to get uploaded (using the same
|
the same syntax to specify several files to get uploaded (using the same
|
||||||
persistant connection), using -T.
|
persistant connection), using -T.
|
||||||
|
|
||||||
* Say you have a list of FTP addresses to download in a file named
|
* When the multi interface has been implemented and proved to work, the
|
||||||
ftp-list.txt: "cat ftp-list.txt | xargs curl -O -O -O [...]". curl _needs_
|
client could be told to use maximum N simultaneous transfers and then just
|
||||||
an "-Oalways" flag -- all addresses on the command line use the base
|
make sure that happens. It should of course not make more than one
|
||||||
filename to store locally. Else a script must precount the # of URLs,
|
connection to the same remote host.
|
||||||
construct the proper number of "-O"s...
|
|
||||||
|
|
||||||
TEST SUITE
|
TEST SUITE
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
.\" nroff -man curl-config.1
|
.\" nroff -man curl-config.1
|
||||||
.\" Written by Daniel Stenberg
|
.\" Written by Daniel Stenberg
|
||||||
.\"
|
.\"
|
||||||
.TH curl-config 1 "16 August 2001" "Curl 7.8.1" "curl-config manual"
|
.TH curl-config 1 "21 January 2002" "Curl 7.9.3" "curl-config manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl-config \- Get information about a libcurl installation
|
curl-config \- Get information about a libcurl installation
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -11,6 +11,8 @@ curl-config \- Get information about a libcurl installation
|
|||||||
.B curl-config
|
.B curl-config
|
||||||
displays information about a previous curl and libcurl installation.
|
displays information about a previous curl and libcurl installation.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
|
.IP "--cc"
|
||||||
|
Displays the compiler used to build libcurl.
|
||||||
.IP "--cflags"
|
.IP "--cflags"
|
||||||
Set of compiler options (CFLAGS) to use when compiling files that use
|
Set of compiler options (CFLAGS) to use when compiling files that use
|
||||||
libcurl. Currently that is only thw include path to the curl include files.
|
libcurl. Currently that is only thw include path to the curl include files.
|
||||||
@@ -38,18 +40,23 @@ major, minor, patch. So that libcurl 7.7.4 would appear as 070704 and libcurl
|
|||||||
.SH "EXAMPLES"
|
.SH "EXAMPLES"
|
||||||
What linker options do I need when I link with libcurl?
|
What linker options do I need when I link with libcurl?
|
||||||
|
|
||||||
curl-config --libs
|
$ curl-config --libs
|
||||||
|
|
||||||
What compiler options do I need when I compile using libcurl functions?
|
What compiler options do I need when I compile using libcurl functions?
|
||||||
|
|
||||||
curl-config --cflags
|
$ curl-config --cflags
|
||||||
|
|
||||||
How do I know if libcurl was built with SSL support?
|
How do I know if libcurl was built with SSL support?
|
||||||
|
|
||||||
curl-config --feature | grep SSL
|
$ curl-config --feature | grep SSL
|
||||||
|
|
||||||
What's the installed libcurl version?
|
What's the installed libcurl version?
|
||||||
|
|
||||||
curl-config --version
|
$ curl-config --version
|
||||||
|
|
||||||
|
How do I build a single file with a one-line command?
|
||||||
|
|
||||||
|
$ `curl-config --cc --cflags --libs` -o example example.c
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR curl (1)
|
.BR curl (1)
|
||||||
|
@@ -28,6 +28,9 @@
|
|||||||
4.2. if the format of the key file is DER, set pKeyType to "DER"
|
4.2. if the format of the key file is DER, set pKeyType to "DER"
|
||||||
|
|
||||||
!! verify of the server certificate is not implemented here !!
|
!! verify of the server certificate is not implemented here !!
|
||||||
|
|
||||||
|
**** This example only works with libcurl 7.9.3 and later! ****
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
@@ -10,7 +10,7 @@ PROGRAMMING WITH LIBCURL
|
|||||||
About this Document
|
About this Document
|
||||||
|
|
||||||
This document will attempt to describe the general principle and some basic
|
This document will attempt to describe the general principle and some basic
|
||||||
approach to consider when programming with libcurl. The text will focus
|
approaches to consider when programming with libcurl. The text will focus
|
||||||
mainly on the C/C++ interface but might apply fairly well on other interfaces
|
mainly on the C/C++ interface but might apply fairly well on other interfaces
|
||||||
as well as they usually follow the C one pretty closely.
|
as well as they usually follow the C one pretty closely.
|
||||||
|
|
||||||
@@ -20,15 +20,62 @@ About this Document
|
|||||||
source code that you write that is using libcurl for transfers. The program
|
source code that you write that is using libcurl for transfers. The program
|
||||||
is outside libcurl and libcurl is outside of the program.
|
is outside libcurl and libcurl is outside of the program.
|
||||||
|
|
||||||
|
To get the more details on all options and functions described herein, please
|
||||||
|
refer to their respective man pages.
|
||||||
|
|
||||||
Building
|
Building
|
||||||
|
|
||||||
|
There are many different ways to build C programs. This chapter will assume a
|
||||||
|
unix-style build process. If you use a different build system, you can still
|
||||||
|
read this to get general information that may apply to your environment as
|
||||||
|
well.
|
||||||
|
|
||||||
Compiling the Program
|
Compiling the Program
|
||||||
|
|
||||||
|
Your compiler needs to know where the libcurl headers are
|
||||||
|
located. Therefore you must set your compiler's include path to point to
|
||||||
|
the directory where you installed them. The 'curl-config'[3] tool can be
|
||||||
|
used to get this information:
|
||||||
|
|
||||||
|
$ curl-config --cflags
|
||||||
|
|
||||||
Linking the Program with libcurl
|
Linking the Program with libcurl
|
||||||
|
|
||||||
|
When having compiled the program, you need to link your object files to
|
||||||
|
create a single executable. For that to succeed, you need to link with
|
||||||
|
libcurl and possibly also with other libraries that libcurl itself depends
|
||||||
|
on. Like OpenSSL librararies, but even some standard OS libraries may be
|
||||||
|
needed on the command line. To figure out which flags to use, once again
|
||||||
|
the 'curl-config' tool comes to the rescue:
|
||||||
|
|
||||||
|
$ curl-config --libs
|
||||||
|
|
||||||
SSL or Not
|
SSL or Not
|
||||||
|
|
||||||
|
libcurl can be built and customized in many ways. One of the things that
|
||||||
|
varies from different libraries and builds is the support for SSL-based
|
||||||
|
transfers, like HTTPS and FTPS. If OpenSSL was detected properly at
|
||||||
|
build-time, libcurl will be built with SSL support. To figure out if an
|
||||||
|
installed libcurl has been built with SSL support enabled, use
|
||||||
|
'curl-config' like this:
|
||||||
|
|
||||||
|
$ curl-config --feature
|
||||||
|
|
||||||
|
And if SSL is supported, the keyword 'SSL' will be written to stdout,
|
||||||
|
possibly together with a few other features that can be on and off on
|
||||||
|
different libcurls.
|
||||||
|
|
||||||
|
|
||||||
|
Portable Code in a Portable World
|
||||||
|
|
||||||
|
The people behind libcurl have put a considerable effort to make libcurl work
|
||||||
|
on a large amount of different operating systems and environments.
|
||||||
|
|
||||||
|
You program libcurl the same way on all platforms that libcurl runs on. There
|
||||||
|
are only very few minor considerations that differs. If you just make sure to
|
||||||
|
write your code portable enough, you may very well create yourself a very
|
||||||
|
portable program. libcurl shouldn't stop you from that.
|
||||||
|
|
||||||
|
|
||||||
Global Preparation
|
Global Preparation
|
||||||
|
|
||||||
@@ -69,7 +116,7 @@ Global Preparation
|
|||||||
Repeated calls to curl_global_init() and curl_global_cleanup() should be
|
Repeated calls to curl_global_init() and curl_global_cleanup() should be
|
||||||
avoided. They should be called once each.
|
avoided. They should be called once each.
|
||||||
|
|
||||||
Handle the easy libcurl
|
Handle the Easy libcurl
|
||||||
|
|
||||||
libcurl version 7 is oriented around the so called easy interface. All
|
libcurl version 7 is oriented around the so called easy interface. All
|
||||||
operations in the easy interface are prefixed with 'curl_easy'.
|
operations in the easy interface are prefixed with 'curl_easy'.
|
||||||
@@ -118,6 +165,19 @@ Handle the easy libcurl
|
|||||||
and the function that gets invoked by libcurl. libcurl itself won't touch the
|
and the function that gets invoked by libcurl. libcurl itself won't touch the
|
||||||
data you pass with CURLOPT_FILE.
|
data you pass with CURLOPT_FILE.
|
||||||
|
|
||||||
|
libcurl offers its own default internal callback that'll take care of the
|
||||||
|
data if you don't set the callback with CURLOPT_WRITEFUNCTION. It will then
|
||||||
|
simply output the received data to stdout. You can have the default callback
|
||||||
|
write the data to a different file handle by passing a 'FILE *' to a file
|
||||||
|
opened for writing with the CURLOPT_FILE option.
|
||||||
|
|
||||||
|
Now, we need to take a step back and have a deep breath. Here's one of those
|
||||||
|
rare platform-dependent nitpicks. Did you spot it? On some platforms[2],
|
||||||
|
libcurl won't be able to operate on files opened by the program. Thus, if you
|
||||||
|
use the default callback and pass in a an open file with CURLOPT_FILE, it
|
||||||
|
will crash. You should therefore avoid this to make your program run fine
|
||||||
|
virtually everywhere.
|
||||||
|
|
||||||
There are of course many more options you can set, and we'll get back to a
|
There are of course many more options you can set, and we'll get back to a
|
||||||
few of them later. Let's instead continue to the actual transfer:
|
few of them later. Let's instead continue to the actual transfer:
|
||||||
|
|
||||||
@@ -141,6 +201,7 @@ Handle the easy libcurl
|
|||||||
you intend to make another transfer. libcurl will then attempt to re-use the
|
you intend to make another transfer. libcurl will then attempt to re-use the
|
||||||
previous
|
previous
|
||||||
|
|
||||||
|
|
||||||
When It Doesn't Work
|
When It Doesn't Work
|
||||||
|
|
||||||
There will always be times when the transfer fails for some reason. You might
|
There will always be times when the transfer fails for some reason. You might
|
||||||
@@ -156,6 +217,19 @@ When It Doesn't Work
|
|||||||
wht the server behaves the way it does. Include headers in the normal body
|
wht the server behaves the way it does. Include headers in the normal body
|
||||||
output with CURLOPT_HEADER set TRUE.
|
output with CURLOPT_HEADER set TRUE.
|
||||||
|
|
||||||
|
Of course there are bugs left. We need to get to know about them to be able
|
||||||
|
to fix them, so we're quite dependent on your bug reports! When you do report
|
||||||
|
suspected bugs in libcurl, please include as much details you possibly can: a
|
||||||
|
protocol dump that CURLOPT_VERBOSE produces, library version, as much as
|
||||||
|
possible of your code that uses libcurl, operating system name and version,
|
||||||
|
compiler name and version etc.
|
||||||
|
|
||||||
|
Getting some in-depth knowledge about the protocols involved is never wrong,
|
||||||
|
and if you're trying to funny things, you might very well understand libcurl
|
||||||
|
and how to use it better if you study the appropriate RFC documents at least
|
||||||
|
briefly.
|
||||||
|
|
||||||
|
|
||||||
Upload Data to a Remote Site
|
Upload Data to a Remote Site
|
||||||
|
|
||||||
libcurl tries to keep a protocol independent approach to most transfers, thus
|
libcurl tries to keep a protocol independent approach to most transfers, thus
|
||||||
@@ -171,12 +245,13 @@ Upload Data to a Remote Site
|
|||||||
the custom pointer libcurl will pass to our read callback. The read callback
|
the custom pointer libcurl will pass to our read callback. The read callback
|
||||||
should have a prototype similar to:
|
should have a prototype similar to:
|
||||||
|
|
||||||
size_t function(char *buffer, size_t size, size_t nitems, void *userp);
|
size_t function(char *bufptr, size_t size, size_t nitems, void *userp);
|
||||||
|
|
||||||
Where buffer is the pointer to a buffer we fill in with data to upload and
|
Where bufptr is the pointer to a buffer we fill in with data to upload and
|
||||||
size*nitems is the size of the buffer. The 'userp' pointer is the custom
|
size*nitems is the size of the buffer and therefore also the maximum amount
|
||||||
pointer we set to point to a struct of ours to pass private data between the
|
of data we can return to libcurl in this call. The 'userp' pointer is the
|
||||||
application and the callback.
|
custom pointer we set to point to a struct of ours to pass private data
|
||||||
|
between the application and the callback.
|
||||||
|
|
||||||
curl_easy_setopt(easyhandle, CURLOPT_READFUNCTION, read_function);
|
curl_easy_setopt(easyhandle, CURLOPT_READFUNCTION, read_function);
|
||||||
|
|
||||||
@@ -192,7 +267,7 @@ Upload Data to a Remote Site
|
|||||||
|
|
||||||
curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE, file_size);
|
curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE, file_size);
|
||||||
|
|
||||||
So, then you call curl_easy_perform() this time, it'll perform all necessary
|
When you call curl_easy_perform() this time, it'll perform all the necessary
|
||||||
operations and when it has invoked the upload it'll call your supplied
|
operations and when it has invoked the upload it'll call your supplied
|
||||||
callback to get the data to upload. The program should return as much data as
|
callback to get the data to upload. The program should return as much data as
|
||||||
possible in every invoke, as that is likely to make the upload perform as
|
possible in every invoke, as that is likely to make the upload perform as
|
||||||
@@ -200,6 +275,243 @@ Upload Data to a Remote Site
|
|||||||
the buffer. Returning 0 will signal the end of the upload.
|
the buffer. Returning 0 will signal the end of the upload.
|
||||||
|
|
||||||
|
|
||||||
|
Passwords
|
||||||
|
|
||||||
|
Many protocols use or even require that user name and password are provided
|
||||||
|
to be able to download or upload the data of your choice. libcurl offers
|
||||||
|
several ways to specify them.
|
||||||
|
|
||||||
|
Most protocols support that you specify the name and password in the URL
|
||||||
|
itself. libcurl will detect this and use them accordingly. This is written
|
||||||
|
like this:
|
||||||
|
|
||||||
|
protocol://user:password@example.com/path/
|
||||||
|
|
||||||
|
If you need any odd letters in your user name or password, you should enter
|
||||||
|
them URL encoded, as %XX where XX is a two-digit hexadecimal number.
|
||||||
|
|
||||||
|
libcurl also provides options to set various passwords. The user name and
|
||||||
|
password as shown embedded in the URL can instead get set with the
|
||||||
|
CURLOPT_USERPWD option. The argument passed to libcurl should be a char * to
|
||||||
|
a string in the format "user:password:". In a manner like this:
|
||||||
|
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_USERPWD, "myname:thesecret");
|
||||||
|
|
||||||
|
Another case where name and password might be needed at times, is for those
|
||||||
|
users who need to athenticate themselves to a proxy they use. libcurl offers
|
||||||
|
another option for this, the CURLOPT_PROXYUSERPWD. It is used quite similar
|
||||||
|
to the CURLOPT_USERPWD option like this:
|
||||||
|
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, "myname:thesecret");
|
||||||
|
|
||||||
|
There's a long time unix "standard" way of storing ftp user names and
|
||||||
|
passwords, namely in the $HOME/.netrc file. The file should be made private
|
||||||
|
so that only the user may read it (see also the "Security Considerations"
|
||||||
|
chapter), as it might contain the password in plain text. libcurl has the
|
||||||
|
ability to use this file to figure out what set of user name and password to
|
||||||
|
use for a particular host. As an extension to the normal functionality,
|
||||||
|
libcurl also supports this file for non-FTP protocols such as HTTP. To make
|
||||||
|
curl use this file, use the CURLOPT_NETRC option:
|
||||||
|
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_NETRC, TRUE);
|
||||||
|
|
||||||
|
And a very basic example of how such a .netrc file may look like:
|
||||||
|
|
||||||
|
machine myhost.mydomain.com
|
||||||
|
login userlogin
|
||||||
|
password secretword
|
||||||
|
|
||||||
|
All these examples have been cases where the password has been optional, or
|
||||||
|
at least you could leave it out and have libcurl attempt to do its job
|
||||||
|
without it. There are times when the password isn't optional, like when
|
||||||
|
you're using an SSL private key for secure transfers.
|
||||||
|
|
||||||
|
You can in this situation either pass a password to libcurl to use to unlock
|
||||||
|
the private key, or you can let libcurl prompt the user for it. If you prefer
|
||||||
|
to ask the user, then you can provide your own callback function that will be
|
||||||
|
called when libcurl wants the password. That way, you can control how the
|
||||||
|
question will appear to the user.
|
||||||
|
|
||||||
|
To pass the known private key password to libcurl:
|
||||||
|
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_SSLKEYPASSWD, "keypassword");
|
||||||
|
|
||||||
|
To make a password callback:
|
||||||
|
|
||||||
|
int enter_passwd(void *ourp, const char *prompt, char *buffer, int len);
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_PASSWDFUNCTION, enter_passwd);
|
||||||
|
|
||||||
|
|
||||||
|
HTTP POSTing
|
||||||
|
|
||||||
|
We get many questions regarding how to issue HTTP POSTs with libcurl the
|
||||||
|
proper way. This chapter will thus include examples using both different
|
||||||
|
versions of HTTP POST that libcurl supports.
|
||||||
|
|
||||||
|
The first version is the simple POST, the most common version, that most HTML
|
||||||
|
pages using the <form> tag uses. We provide a pointer to the data and tell
|
||||||
|
libcurl to post it all to the remote site:
|
||||||
|
|
||||||
|
char *data="name=daniel&project=curl";
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, data);
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_URL, "http://posthere.com/");
|
||||||
|
|
||||||
|
curl_easy_perform(easyhandle); /* post away! */
|
||||||
|
|
||||||
|
Simple enough, huh? Ok, so what if you want to post binary data that also
|
||||||
|
requires you to set the Content-Type: header of the post? Well, binary posts
|
||||||
|
prevents libcurl from being able to do strlen() on the data to figure out the
|
||||||
|
size, so therefore we must tell libcurl the size of the post data. Setting
|
||||||
|
headers in libcurl requests are done in a generic way, by building a list of
|
||||||
|
our own headers and then passing that list to libcurl.
|
||||||
|
|
||||||
|
struct curl_slist *headers=NULL;
|
||||||
|
headers = curl_slist_append(headers, "Content-Type: text/xml");
|
||||||
|
|
||||||
|
/* post binary data */
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELD, binaryptr);
|
||||||
|
|
||||||
|
/* set the size of the postfields data */
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDSIZE, 23);
|
||||||
|
|
||||||
|
/* pass our list of custom made headers */
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);
|
||||||
|
|
||||||
|
curl_easy_perform(easyhandle); /* post away! */
|
||||||
|
|
||||||
|
curl_slist_free_all(headers); /* free the header list */
|
||||||
|
|
||||||
|
While the simple examples above cover the majority of all cases where HTTP
|
||||||
|
POST operations are required, they don't do multipart formposts. Multipart
|
||||||
|
formposts were introduced as a better way to post (possibly large) binary
|
||||||
|
data and was first documented in the RFC1867. They're called multipart
|
||||||
|
because they're built by a chain of parts, each being a single unit. Each
|
||||||
|
part has its own name and contents. You can in fact create and post a
|
||||||
|
multipart formpost with the regular libcurl POST support described above, but
|
||||||
|
that would require that you build a formpost yourself and provide to
|
||||||
|
libcurl. To make that easier, libcurl provides curl_formadd(). Using this
|
||||||
|
function, you add parts to the form. When you're done adding parts, you post
|
||||||
|
the whole form.
|
||||||
|
|
||||||
|
The following example sets two simple text parts with plain textual contents,
|
||||||
|
and then a file with binary contents and upload the whole thing.
|
||||||
|
|
||||||
|
struct HttpPost *post=NULL;
|
||||||
|
struct HttpPost *last=NULL;
|
||||||
|
curl_formadd(&post, &last,
|
||||||
|
CURLFORM_COPYNAME, "name",
|
||||||
|
CURLFORM_COPYCONTENTS, "daniel", CURLFORM_END);
|
||||||
|
curl_formadd(&post, &last,
|
||||||
|
CURLFORM_COPYNAME, "project",
|
||||||
|
CURLFORM_COPYCONTENTS, "curl", CURLFORM_END);
|
||||||
|
curl_formadd(&post, &last,
|
||||||
|
CURLFORM_COPYNAME, "logotype-image",
|
||||||
|
CURLFORM_FILECONTENT, "curl.png", CURLFORM_END);
|
||||||
|
|
||||||
|
/* Set the form info */
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_HTTPPOST, post);
|
||||||
|
|
||||||
|
curl_easy_perform(easyhandle); /* post away! */
|
||||||
|
|
||||||
|
/* free the post data again */
|
||||||
|
curl_formfree(post);
|
||||||
|
|
||||||
|
The multipart formposts are a chain of parts using MIME-style separators and
|
||||||
|
headers. That means that each of these separate parts get a few headers set
|
||||||
|
that describes its individual content-type, size etc. Now, to enable your
|
||||||
|
application to handicraft this formpost even more, libcurl allows you to
|
||||||
|
supply your own custom headers to an individual form part. You can of course
|
||||||
|
supply headers to as many parts you like, but this little example will show
|
||||||
|
how you have set headers to one specific part when you add that to post
|
||||||
|
handle:
|
||||||
|
|
||||||
|
struct curl_slist *headers=NULL;
|
||||||
|
headers = curl_slist_append(headers, "Content-Type: text/xml");
|
||||||
|
|
||||||
|
curl_formadd(&post, &last,
|
||||||
|
CURLFORM_COPYNAME, "logotype-image",
|
||||||
|
CURLFORM_FILECONTENT, "curl.xml",
|
||||||
|
CURLFORM_CONTENTHEADER, headers,
|
||||||
|
CURLFORM_END);
|
||||||
|
|
||||||
|
curl_easy_perform(easyhandle); /* post away! */
|
||||||
|
|
||||||
|
curl_formfree(post); /* free post */
|
||||||
|
curl_slist_free_all(post); /* free custom header list */
|
||||||
|
|
||||||
|
|
||||||
|
Showing Progress
|
||||||
|
|
||||||
|
|
||||||
|
libcurl with C++
|
||||||
|
|
||||||
|
There's basicly only one thing to keep in mind when using C++ instead of C
|
||||||
|
when interfacing libcurl:
|
||||||
|
|
||||||
|
"The Callbacks Must Be Plain C"
|
||||||
|
|
||||||
|
So if you want a write callback set in libcurl, you should put it within
|
||||||
|
'extern'. Similar to this:
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
size_t write_data(void *ptr, size_t size, size_t nmemb,
|
||||||
|
void *ourpointer)
|
||||||
|
{
|
||||||
|
/* do what you want with the data */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
This will of course effectively turn the callback code into C. There won't be
|
||||||
|
any "this" pointer available etc.
|
||||||
|
|
||||||
|
|
||||||
|
Proxies
|
||||||
|
|
||||||
|
What "proxy" means according to Merriam-Webster: "a person authorized to act
|
||||||
|
for another" but also "the agency, function, or office of a deputy who acts
|
||||||
|
as a substitute for another".
|
||||||
|
|
||||||
|
Proxies are exceedingly common these days. Companies often only offer
|
||||||
|
internet access to employees through their HTTP proxies. Network clients or
|
||||||
|
user-agents ask the proxy for docuements, the proxy does the actual request
|
||||||
|
and then it returns them.
|
||||||
|
|
||||||
|
libcurl has full support for HTTP proxies, so when a given URL is wanted,
|
||||||
|
libcurl will ask the proxy for it instead of trying to connect to the actual
|
||||||
|
host identified in the URL.
|
||||||
|
|
||||||
|
The fact that the proxy is a HTTP proxy puts certain restrictions on what can
|
||||||
|
actually happen. A requested URL that might not be a HTTP URL will be still
|
||||||
|
be passed to the HTTP proxy to deliver back to libcurl. This happens
|
||||||
|
transparantly, and an application may not need to know. I say "may", because
|
||||||
|
at times it is very important to understand that all operations over a HTTP
|
||||||
|
proxy is using the HTTP protocol. For example, you can't invoke your own
|
||||||
|
custom FTP commands or even proper FTP directory listings.
|
||||||
|
|
||||||
|
To tell libcurl to use a proxy at a given port number:
|
||||||
|
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_PROXY, "proxy-host.com:8080");
|
||||||
|
|
||||||
|
Some proxies require user authentication before allowing a request, and you
|
||||||
|
pass that information similar to this:
|
||||||
|
|
||||||
|
curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, "user:password");
|
||||||
|
|
||||||
|
[ environment variables, SSL, tunneling, automatic proxy config (.pac) ]
|
||||||
|
|
||||||
|
|
||||||
|
Security Considerations
|
||||||
|
|
||||||
|
[ ps output, netrc plain text, plain text protocols / base64 ]
|
||||||
|
|
||||||
|
|
||||||
|
Certificates and Other SSL Tricks
|
||||||
|
|
||||||
|
|
||||||
|
Future
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----
|
-----
|
||||||
Footnotes:
|
Footnotes:
|
||||||
|
|
||||||
@@ -207,3 +519,11 @@ Footnotes:
|
|||||||
but libcurl does not support the chunked transfers on uploading that is
|
but libcurl does not support the chunked transfers on uploading that is
|
||||||
necessary for this feature to work. We'd gratefully appreciate patches
|
necessary for this feature to work. We'd gratefully appreciate patches
|
||||||
that bring this functionality...
|
that bring this functionality...
|
||||||
|
|
||||||
|
[2] = This happens on Windows machines when libcurl is built and used as a
|
||||||
|
DLL. However, you can still do this on Windows if you link with a static
|
||||||
|
library.
|
||||||
|
|
||||||
|
[3] = The curl-config tool is generated at build-time (on unix-like systems)
|
||||||
|
and should be installed with the 'make install' or similar instruction
|
||||||
|
that installs the library, header files, man pages etc.
|
||||||
|
@@ -30,11 +30,11 @@
|
|||||||
# include <time.h>
|
# include <time.h>
|
||||||
#else
|
#else
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
# if TIME_WITH_SYS_TIME
|
# ifdef TIME_WITH_SYS_TIME
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
# include <time.h>
|
# include <time.h>
|
||||||
# else
|
# else
|
||||||
# if HAVE_SYS_TIME_H
|
# ifdef HAVE_SYS_TIME_H
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
# else
|
# else
|
||||||
# include <time.h>
|
# include <time.h>
|
||||||
@@ -613,7 +613,7 @@ CURLcode curl_global_init(long flags);
|
|||||||
void curl_global_cleanup(void);
|
void curl_global_cleanup(void);
|
||||||
|
|
||||||
/* This is the version number */
|
/* This is the version number */
|
||||||
#define LIBCURL_VERSION "7.9.3-pre2"
|
#define LIBCURL_VERSION "7.9.3"
|
||||||
#define LIBCURL_VERSION_NUM 0x070903
|
#define LIBCURL_VERSION_NUM 0x070903
|
||||||
|
|
||||||
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
||||||
|
@@ -35,14 +35,14 @@ libcurl_a_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c base64.c \
|
|||||||
ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c \
|
ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c \
|
||||||
telnet.h getinfo.c strequal.c strequal.h easy.c security.h \
|
telnet.h getinfo.c strequal.c strequal.h easy.c security.h \
|
||||||
security.c krb4.h krb4.c memdebug.h memdebug.c inet_ntoa_r.h http_chunks.h http_chunks.c \
|
security.c krb4.h krb4.c memdebug.h memdebug.c inet_ntoa_r.h http_chunks.h http_chunks.c \
|
||||||
strtok.c connect.c
|
strtok.c connect.c hash.c llist.c
|
||||||
|
|
||||||
libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
|
libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
|
||||||
formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \
|
formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \
|
||||||
speedcheck.o getdate.o transfer.o ldap.o ssluse.o version.o \
|
speedcheck.o getdate.o transfer.o ldap.o ssluse.o version.o \
|
||||||
getenv.o escape.o mprintf.o telnet.o getpass.o netrc.o getinfo.o \
|
getenv.o escape.o mprintf.o telnet.o getpass.o netrc.o getinfo.o \
|
||||||
strequal.o easy.o security.o krb4.o memdebug.o http_chunks.o \
|
strequal.o easy.o security.o krb4.o memdebug.o http_chunks.o \
|
||||||
strtok.o connect.o
|
strtok.o connect.o hash.o llist.o
|
||||||
|
|
||||||
LIBRARIES = $(libcurl_a_LIBRARIES)
|
LIBRARIES = $(libcurl_a_LIBRARIES)
|
||||||
SOURCES = $(libcurl_a_SOURCES)
|
SOURCES = $(libcurl_a_SOURCES)
|
||||||
|
@@ -369,9 +369,11 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
/* subtract the passed time */
|
/* subtract the passed time */
|
||||||
timeout_ms -= (long)has_passed;
|
timeout_ms -= (long)has_passed;
|
||||||
|
|
||||||
if(timeout_ms < 0)
|
if(timeout_ms < 0) {
|
||||||
/* a precaution, no need to continue if time already is up */
|
/* a precaution, no need to continue if time already is up */
|
||||||
|
failf(data, "Connection time-out");
|
||||||
return CURLE_OPERATION_TIMEOUTED;
|
return CURLE_OPERATION_TIMEOUTED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
|
@@ -1155,10 +1155,13 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
|
|||||||
}
|
}
|
||||||
if(fileread != stdin)
|
if(fileread != stdin)
|
||||||
fclose(fileread);
|
fclose(fileread);
|
||||||
} else {
|
|
||||||
size += AddFormData(&form, "[File wasn't found by client]", 0);
|
|
||||||
}
|
}
|
||||||
} else {
|
else {
|
||||||
|
/* File wasn't found, add a nothing field! */
|
||||||
|
size += AddFormData(&form, "", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
/* include the contents we got */
|
/* include the contents we got */
|
||||||
size += AddFormData(&form, post->contents, post->contentslength);
|
size += AddFormData(&form, post->contents, post->contentslength);
|
||||||
}
|
}
|
||||||
|
@@ -358,7 +358,7 @@ int Curl_GetFTPResponse(char *buf,
|
|||||||
if(!error)
|
if(!error)
|
||||||
code = atoi(buf);
|
code = atoi(buf);
|
||||||
|
|
||||||
#if KRB4
|
#ifdef KRB4
|
||||||
/* handle the security-oriented responses 6xx ***/
|
/* handle the security-oriented responses 6xx ***/
|
||||||
/* FIXME: some errorchecking perhaps... ***/
|
/* FIXME: some errorchecking perhaps... ***/
|
||||||
switch(code) {
|
switch(code) {
|
||||||
@@ -911,7 +911,7 @@ ftp_pasv_verbose(struct connectdata *conn,
|
|||||||
# ifdef HAVE_GETHOSTBYADDR_R_7
|
# ifdef HAVE_GETHOSTBYADDR_R_7
|
||||||
/* Solaris and IRIX */
|
/* Solaris and IRIX */
|
||||||
answer = gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,
|
answer = gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,
|
||||||
(struct hostent *)hostent_buf,
|
(struct hostent *)bigbuf,
|
||||||
hostent_buf + sizeof(*answer),
|
hostent_buf + sizeof(*answer),
|
||||||
sizeof(hostent_buf) - sizeof(*answer),
|
sizeof(hostent_buf) - sizeof(*answer),
|
||||||
&h_errnop);
|
&h_errnop);
|
||||||
|
119
lib/getdate.c
119
lib/getdate.c
@@ -45,6 +45,11 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef YYDEBUG
|
||||||
|
/* to satisfy gcc -Wundef, we set this to 0 */
|
||||||
|
#define YYDEBUG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Since the code of getdate.y is not included in the Emacs executable
|
/* Since the code of getdate.y is not included in the Emacs executable
|
||||||
itself, there is no need to #define static in this file. Even if
|
itself, there is no need to #define static in this file. Even if
|
||||||
the code were included in the Emacs executable, it probably
|
the code were included in the Emacs executable, it probably
|
||||||
@@ -223,7 +228,7 @@ static int yyRelSeconds;
|
|||||||
static int yyRelYear;
|
static int yyRelYear;
|
||||||
|
|
||||||
|
|
||||||
#line 206 "getdate.y"
|
#line 211 "getdate.y"
|
||||||
typedef union {
|
typedef union {
|
||||||
int Number;
|
int Number;
|
||||||
enum _MERIDIAN Meridian;
|
enum _MERIDIAN Meridian;
|
||||||
@@ -306,11 +311,11 @@ static const short yyrhs[] = { -1,
|
|||||||
|
|
||||||
#if YYDEBUG != 0
|
#if YYDEBUG != 0
|
||||||
static const short yyrline[] = { 0,
|
static const short yyrline[] = { 0,
|
||||||
222, 223, 226, 229, 232, 235, 238, 241, 244, 250,
|
227, 228, 231, 234, 237, 240, 243, 246, 249, 255,
|
||||||
256, 265, 271, 283, 286, 289, 295, 299, 303, 309,
|
261, 270, 276, 288, 291, 294, 300, 304, 308, 314,
|
||||||
313, 331, 337, 343, 347, 352, 356, 363, 371, 374,
|
318, 336, 342, 348, 352, 357, 361, 368, 376, 379,
|
||||||
377, 380, 383, 386, 389, 392, 395, 398, 401, 404,
|
382, 385, 388, 391, 394, 397, 400, 403, 406, 409,
|
||||||
407, 410, 413, 416, 419, 422, 425, 430, 463, 467
|
412, 415, 418, 421, 424, 427, 430, 435, 468, 472
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -934,37 +939,37 @@ yyreduce:
|
|||||||
switch (yyn) {
|
switch (yyn) {
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
#line 226 "getdate.y"
|
#line 231 "getdate.y"
|
||||||
{
|
{
|
||||||
yyHaveTime++;
|
yyHaveTime++;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 4:
|
case 4:
|
||||||
#line 229 "getdate.y"
|
#line 234 "getdate.y"
|
||||||
{
|
{
|
||||||
yyHaveZone++;
|
yyHaveZone++;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 5:
|
case 5:
|
||||||
#line 232 "getdate.y"
|
#line 237 "getdate.y"
|
||||||
{
|
{
|
||||||
yyHaveDate++;
|
yyHaveDate++;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 6:
|
case 6:
|
||||||
#line 235 "getdate.y"
|
#line 240 "getdate.y"
|
||||||
{
|
{
|
||||||
yyHaveDay++;
|
yyHaveDay++;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 7:
|
case 7:
|
||||||
#line 238 "getdate.y"
|
#line 243 "getdate.y"
|
||||||
{
|
{
|
||||||
yyHaveRel++;
|
yyHaveRel++;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 9:
|
case 9:
|
||||||
#line 244 "getdate.y"
|
#line 249 "getdate.y"
|
||||||
{
|
{
|
||||||
yyHour = yyvsp[-1].Number;
|
yyHour = yyvsp[-1].Number;
|
||||||
yyMinutes = 0;
|
yyMinutes = 0;
|
||||||
@@ -973,7 +978,7 @@ case 9:
|
|||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 10:
|
case 10:
|
||||||
#line 250 "getdate.y"
|
#line 255 "getdate.y"
|
||||||
{
|
{
|
||||||
yyHour = yyvsp[-3].Number;
|
yyHour = yyvsp[-3].Number;
|
||||||
yyMinutes = yyvsp[-1].Number;
|
yyMinutes = yyvsp[-1].Number;
|
||||||
@@ -982,7 +987,7 @@ case 10:
|
|||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 11:
|
case 11:
|
||||||
#line 256 "getdate.y"
|
#line 261 "getdate.y"
|
||||||
{
|
{
|
||||||
yyHour = yyvsp[-3].Number;
|
yyHour = yyvsp[-3].Number;
|
||||||
yyMinutes = yyvsp[-1].Number;
|
yyMinutes = yyvsp[-1].Number;
|
||||||
@@ -994,7 +999,7 @@ case 11:
|
|||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 12:
|
case 12:
|
||||||
#line 265 "getdate.y"
|
#line 270 "getdate.y"
|
||||||
{
|
{
|
||||||
yyHour = yyvsp[-5].Number;
|
yyHour = yyvsp[-5].Number;
|
||||||
yyMinutes = yyvsp[-3].Number;
|
yyMinutes = yyvsp[-3].Number;
|
||||||
@@ -1003,7 +1008,7 @@ case 12:
|
|||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 13:
|
case 13:
|
||||||
#line 271 "getdate.y"
|
#line 276 "getdate.y"
|
||||||
{
|
{
|
||||||
yyHour = yyvsp[-5].Number;
|
yyHour = yyvsp[-5].Number;
|
||||||
yyMinutes = yyvsp[-3].Number;
|
yyMinutes = yyvsp[-3].Number;
|
||||||
@@ -1016,53 +1021,53 @@ case 13:
|
|||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 14:
|
case 14:
|
||||||
#line 283 "getdate.y"
|
#line 288 "getdate.y"
|
||||||
{
|
{
|
||||||
yyTimezone = yyvsp[0].Number;
|
yyTimezone = yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 15:
|
case 15:
|
||||||
#line 286 "getdate.y"
|
#line 291 "getdate.y"
|
||||||
{
|
{
|
||||||
yyTimezone = yyvsp[0].Number - 60;
|
yyTimezone = yyvsp[0].Number - 60;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 16:
|
case 16:
|
||||||
#line 290 "getdate.y"
|
#line 295 "getdate.y"
|
||||||
{
|
{
|
||||||
yyTimezone = yyvsp[-1].Number - 60;
|
yyTimezone = yyvsp[-1].Number - 60;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 17:
|
case 17:
|
||||||
#line 295 "getdate.y"
|
#line 300 "getdate.y"
|
||||||
{
|
{
|
||||||
yyDayOrdinal = 1;
|
yyDayOrdinal = 1;
|
||||||
yyDayNumber = yyvsp[0].Number;
|
yyDayNumber = yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 18:
|
case 18:
|
||||||
#line 299 "getdate.y"
|
#line 304 "getdate.y"
|
||||||
{
|
{
|
||||||
yyDayOrdinal = 1;
|
yyDayOrdinal = 1;
|
||||||
yyDayNumber = yyvsp[-1].Number;
|
yyDayNumber = yyvsp[-1].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 19:
|
case 19:
|
||||||
#line 303 "getdate.y"
|
#line 308 "getdate.y"
|
||||||
{
|
{
|
||||||
yyDayOrdinal = yyvsp[-1].Number;
|
yyDayOrdinal = yyvsp[-1].Number;
|
||||||
yyDayNumber = yyvsp[0].Number;
|
yyDayNumber = yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 20:
|
case 20:
|
||||||
#line 309 "getdate.y"
|
#line 314 "getdate.y"
|
||||||
{
|
{
|
||||||
yyMonth = yyvsp[-2].Number;
|
yyMonth = yyvsp[-2].Number;
|
||||||
yyDay = yyvsp[0].Number;
|
yyDay = yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 21:
|
case 21:
|
||||||
#line 313 "getdate.y"
|
#line 318 "getdate.y"
|
||||||
{
|
{
|
||||||
/* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY.
|
/* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY.
|
||||||
The goal in recognizing YYYY/MM/DD is solely to support legacy
|
The goal in recognizing YYYY/MM/DD is solely to support legacy
|
||||||
@@ -1083,7 +1088,7 @@ case 21:
|
|||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 22:
|
case 22:
|
||||||
#line 331 "getdate.y"
|
#line 336 "getdate.y"
|
||||||
{
|
{
|
||||||
/* ISO 8601 format. yyyy-mm-dd. */
|
/* ISO 8601 format. yyyy-mm-dd. */
|
||||||
yyYear = yyvsp[-2].Number;
|
yyYear = yyvsp[-2].Number;
|
||||||
@@ -1092,7 +1097,7 @@ case 22:
|
|||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 23:
|
case 23:
|
||||||
#line 337 "getdate.y"
|
#line 342 "getdate.y"
|
||||||
{
|
{
|
||||||
/* e.g. 17-JUN-1992. */
|
/* e.g. 17-JUN-1992. */
|
||||||
yyDay = yyvsp[-2].Number;
|
yyDay = yyvsp[-2].Number;
|
||||||
@@ -1101,14 +1106,14 @@ case 23:
|
|||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 24:
|
case 24:
|
||||||
#line 343 "getdate.y"
|
#line 348 "getdate.y"
|
||||||
{
|
{
|
||||||
yyMonth = yyvsp[-1].Number;
|
yyMonth = yyvsp[-1].Number;
|
||||||
yyDay = yyvsp[0].Number;
|
yyDay = yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 25:
|
case 25:
|
||||||
#line 347 "getdate.y"
|
#line 352 "getdate.y"
|
||||||
{
|
{
|
||||||
yyMonth = yyvsp[-3].Number;
|
yyMonth = yyvsp[-3].Number;
|
||||||
yyDay = yyvsp[-2].Number;
|
yyDay = yyvsp[-2].Number;
|
||||||
@@ -1116,14 +1121,14 @@ case 25:
|
|||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 26:
|
case 26:
|
||||||
#line 352 "getdate.y"
|
#line 357 "getdate.y"
|
||||||
{
|
{
|
||||||
yyMonth = yyvsp[0].Number;
|
yyMonth = yyvsp[0].Number;
|
||||||
yyDay = yyvsp[-1].Number;
|
yyDay = yyvsp[-1].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 27:
|
case 27:
|
||||||
#line 356 "getdate.y"
|
#line 361 "getdate.y"
|
||||||
{
|
{
|
||||||
yyMonth = yyvsp[-1].Number;
|
yyMonth = yyvsp[-1].Number;
|
||||||
yyDay = yyvsp[-2].Number;
|
yyDay = yyvsp[-2].Number;
|
||||||
@@ -1131,7 +1136,7 @@ case 27:
|
|||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 28:
|
case 28:
|
||||||
#line 363 "getdate.y"
|
#line 368 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelSeconds = -yyRelSeconds;
|
yyRelSeconds = -yyRelSeconds;
|
||||||
yyRelMinutes = -yyRelMinutes;
|
yyRelMinutes = -yyRelMinutes;
|
||||||
@@ -1142,115 +1147,115 @@ case 28:
|
|||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 30:
|
case 30:
|
||||||
#line 374 "getdate.y"
|
#line 379 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
|
yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 31:
|
case 31:
|
||||||
#line 377 "getdate.y"
|
#line 382 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
|
yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 32:
|
case 32:
|
||||||
#line 380 "getdate.y"
|
#line 385 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelYear += yyvsp[0].Number;
|
yyRelYear += yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 33:
|
case 33:
|
||||||
#line 383 "getdate.y"
|
#line 388 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
|
yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 34:
|
case 34:
|
||||||
#line 386 "getdate.y"
|
#line 391 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
|
yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 35:
|
case 35:
|
||||||
#line 389 "getdate.y"
|
#line 394 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelMonth += yyvsp[0].Number;
|
yyRelMonth += yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 36:
|
case 36:
|
||||||
#line 392 "getdate.y"
|
#line 397 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
|
yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 37:
|
case 37:
|
||||||
#line 395 "getdate.y"
|
#line 400 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
|
yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 38:
|
case 38:
|
||||||
#line 398 "getdate.y"
|
#line 403 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelDay += yyvsp[0].Number;
|
yyRelDay += yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 39:
|
case 39:
|
||||||
#line 401 "getdate.y"
|
#line 406 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
|
yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 40:
|
case 40:
|
||||||
#line 404 "getdate.y"
|
#line 409 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
|
yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 41:
|
case 41:
|
||||||
#line 407 "getdate.y"
|
#line 412 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelHour += yyvsp[0].Number;
|
yyRelHour += yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 42:
|
case 42:
|
||||||
#line 410 "getdate.y"
|
#line 415 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
|
yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 43:
|
case 43:
|
||||||
#line 413 "getdate.y"
|
#line 418 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
|
yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 44:
|
case 44:
|
||||||
#line 416 "getdate.y"
|
#line 421 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelMinutes += yyvsp[0].Number;
|
yyRelMinutes += yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 45:
|
case 45:
|
||||||
#line 419 "getdate.y"
|
#line 424 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
|
yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 46:
|
case 46:
|
||||||
#line 422 "getdate.y"
|
#line 427 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
|
yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 47:
|
case 47:
|
||||||
#line 425 "getdate.y"
|
#line 430 "getdate.y"
|
||||||
{
|
{
|
||||||
yyRelSeconds += yyvsp[0].Number;
|
yyRelSeconds += yyvsp[0].Number;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 48:
|
case 48:
|
||||||
#line 431 "getdate.y"
|
#line 436 "getdate.y"
|
||||||
{
|
{
|
||||||
if (yyHaveTime && yyHaveDate && !yyHaveRel)
|
if (yyHaveTime && yyHaveDate && !yyHaveRel)
|
||||||
yyYear = yyvsp[0].Number;
|
yyYear = yyvsp[0].Number;
|
||||||
@@ -1283,13 +1288,13 @@ case 48:
|
|||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 49:
|
case 49:
|
||||||
#line 464 "getdate.y"
|
#line 469 "getdate.y"
|
||||||
{
|
{
|
||||||
yyval.Meridian = MER24;
|
yyval.Meridian = MER24;
|
||||||
;
|
;
|
||||||
break;}
|
break;}
|
||||||
case 50:
|
case 50:
|
||||||
#line 468 "getdate.y"
|
#line 473 "getdate.y"
|
||||||
{
|
{
|
||||||
yyval.Meridian = yyvsp[0].Meridian;
|
yyval.Meridian = yyvsp[0].Meridian;
|
||||||
;
|
;
|
||||||
@@ -1516,7 +1521,7 @@ yyerrhandle:
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#line 473 "getdate.y"
|
#line 478 "getdate.y"
|
||||||
|
|
||||||
|
|
||||||
/* Include this file down here because bison inserts code above which
|
/* Include this file down here because bison inserts code above which
|
||||||
@@ -2126,11 +2131,3 @@ main (ac, av)
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
#endif /* defined (TEST) */
|
#endif /* defined (TEST) */
|
||||||
|
|
||||||
/*
|
|
||||||
* local variables:
|
|
||||||
* eval: (load-file "../curl-mode.el")
|
|
||||||
* end:
|
|
||||||
* vim600: fdm=marker
|
|
||||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
|
||||||
*/
|
|
||||||
|
@@ -21,6 +21,11 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef YYDEBUG
|
||||||
|
/* to satisfy gcc -Wundef, we set this to 0 */
|
||||||
|
#define YYDEBUG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Since the code of getdate.y is not included in the Emacs executable
|
/* Since the code of getdate.y is not included in the Emacs executable
|
||||||
itself, there is no need to #define static in this file. Even if
|
itself, there is no need to #define static in this file. Even if
|
||||||
the code were included in the Emacs executable, it probably
|
the code were included in the Emacs executable, it probably
|
||||||
|
@@ -101,7 +101,10 @@ curl_hash_alloc(int slots, curl_hash_dtor dtor)
|
|||||||
{
|
{
|
||||||
curl_hash *h;
|
curl_hash *h;
|
||||||
|
|
||||||
h = malloc(sizeof(curl_hash));
|
h = (curl_hash *)malloc(sizeof(curl_hash));
|
||||||
|
if(NULL == h)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
curl_hash_init(h, slots, dtor);
|
curl_hash_init(h, slots, dtor);
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
|
100
lib/hostip.c
100
lib/hostip.c
@@ -60,6 +60,9 @@
|
|||||||
#include "hostip.h"
|
#include "hostip.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||||
#include "inet_ntoa_r.h"
|
#include "inet_ntoa_r.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -98,13 +101,71 @@ struct curl_dns_cache_entry {
|
|||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* count the number of characters that an integer takes up */
|
||||||
|
static int _num_chars(int i)
|
||||||
|
{
|
||||||
|
int chars = 0;
|
||||||
|
|
||||||
|
/* While the number divided by 10 is greater than one,
|
||||||
|
* re-divide the number by 10, and increment the number of
|
||||||
|
* characters by 1.
|
||||||
|
*
|
||||||
|
* this relies on the fact that for every multiple of 10,
|
||||||
|
* a new digit is added onto every number
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
chars++;
|
||||||
|
|
||||||
|
i = (int) i / 10;
|
||||||
|
} while (i > 1);
|
||||||
|
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a hostcache id */
|
||||||
|
static char *
|
||||||
|
_create_hostcache_id(char *server, int port, ssize_t *entry_len)
|
||||||
|
{
|
||||||
|
char *id = NULL;
|
||||||
|
|
||||||
|
/* Get the length of the new entry id */
|
||||||
|
*entry_len = *entry_len + /* Hostname length */
|
||||||
|
1 + /* The ':' seperator */
|
||||||
|
_num_chars(port); /* The number of characters the port will take up */
|
||||||
|
|
||||||
|
/* Allocate the new entry id */
|
||||||
|
id = malloc(*entry_len + 1);
|
||||||
|
if (!id) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the new entry */
|
||||||
|
/* If sprintf() doesn't return the entry length, that signals failure */
|
||||||
|
if (sprintf(id, "%s:%d", server, port) != *entry_len) {
|
||||||
|
/* Free the allocated id, set length to zero and return NULL */
|
||||||
|
*entry_len = 0;
|
||||||
|
free(id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Macro to save redundant free'ing of entry_id */
|
||||||
|
#define _hostcache_return(__v) \
|
||||||
|
{ \
|
||||||
|
free(entry_id); \
|
||||||
|
return (__v); \
|
||||||
|
}
|
||||||
|
|
||||||
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||||
char *hostname,
|
char *hostname,
|
||||||
int port,
|
int port,
|
||||||
char **bufp)
|
char **bufp)
|
||||||
{
|
{
|
||||||
|
char *entry_id = NULL;
|
||||||
struct curl_dns_cache_entry *p = NULL;
|
struct curl_dns_cache_entry *p = NULL;
|
||||||
size_t hostname_len;
|
ssize_t entry_len;
|
||||||
time_t now;
|
time_t now;
|
||||||
|
|
||||||
/* If the host cache timeout is 0, we don't do DNS cach'ing
|
/* If the host cache timeout is 0, we don't do DNS cach'ing
|
||||||
@@ -113,40 +174,47 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
|||||||
return Curl_getaddrinfo(data, hostname, port, bufp);
|
return Curl_getaddrinfo(data, hostname, port, bufp);
|
||||||
}
|
}
|
||||||
|
|
||||||
hostname_len = strlen(hostname)+1;
|
/* Create an entry id, based upon the hostname and port */
|
||||||
|
entry_len = strlen(hostname);
|
||||||
|
entry_id = _create_hostcache_id(hostname, port, &entry_len);
|
||||||
|
/* If we can't create the entry id, don't cache, just fall-through
|
||||||
|
to the plain Curl_getaddrinfo() */
|
||||||
|
if (!entry_id) {
|
||||||
|
return Curl_getaddrinfo(data, hostname, port, bufp);
|
||||||
|
}
|
||||||
|
|
||||||
time(&now);
|
time(&now);
|
||||||
/* See if its already in our dns cache */
|
/* See if its already in our dns cache */
|
||||||
if (curl_hash_find(data->hostcache, hostname, hostname_len, (void **) &p)) {
|
if (entry_id && curl_hash_find(data->hostcache, entry_id, entry_len+1, (void **) &p)) {
|
||||||
/* Do we need to check for a cache timeout? */
|
/* Do we need to check for a cache timeout? */
|
||||||
if (data->set.dns_cache_timeout != -1) {
|
if (data->set.dns_cache_timeout != -1) {
|
||||||
/* Return if the entry has not timed out */
|
/* Return if the entry has not timed out */
|
||||||
if ((now - p->timestamp) < data->set.dns_cache_timeout) {
|
if ((now - p->timestamp) < data->set.dns_cache_timeout) {
|
||||||
return p->addr;
|
_hostcache_return(p->addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return p->addr;
|
_hostcache_return(p->addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new cache entry */
|
/* Create a new cache entry */
|
||||||
p = (struct curl_dns_cache_entry *)
|
p = (struct curl_dns_cache_entry *) malloc(sizeof(struct curl_dns_cache_entry));
|
||||||
malloc(sizeof(struct curl_dns_cache_entry));
|
if (!p) {
|
||||||
if (!p)
|
_hostcache_return(NULL);
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
p->addr = Curl_getaddrinfo(data, hostname, port, bufp);
|
p->addr = Curl_getaddrinfo(data, hostname, port, bufp);
|
||||||
if (!p->addr) {
|
if (!p->addr) {
|
||||||
free(p);
|
free(p);
|
||||||
return NULL;
|
_hostcache_return(NULL);
|
||||||
}
|
}
|
||||||
p->timestamp = now;
|
p->timestamp = now;
|
||||||
|
|
||||||
/* Save it in our host cache */
|
/* Save it in our host cache */
|
||||||
curl_hash_update(data->hostcache, hostname, hostname_len, (const void *) p);
|
curl_hash_update(data->hostcache, entry_id, entry_len+1, (const void *) p);
|
||||||
|
|
||||||
return p->addr;
|
_hostcache_return(p->addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -358,10 +426,10 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
|||||||
* everything. OSF1 is known to require at least 8872 bytes. The buffer
|
* everything. OSF1 is known to require at least 8872 bytes. The buffer
|
||||||
* required for storing all possible aliases and IP numbers is according to
|
* required for storing all possible aliases and IP numbers is according to
|
||||||
* Stevens' Unix Network Programming 2nd editor, p. 304: 8192 bytes! */
|
* Stevens' Unix Network Programming 2nd editor, p. 304: 8192 bytes! */
|
||||||
char *buf = (char *)malloc(CURL_NAMELOOKUP_SIZE);
|
int *buf = (int *)malloc(CURL_NAMELOOKUP_SIZE);
|
||||||
if(!buf)
|
if(!buf)
|
||||||
return NULL; /* major failure */
|
return NULL; /* major failure */
|
||||||
*bufp = buf;
|
*bufp = (char *)buf;
|
||||||
|
|
||||||
port=0; /* unused in IPv4 code */
|
port=0; /* unused in IPv4 code */
|
||||||
ret = 0; /* to prevent the compiler warning */
|
ret = 0; /* to prevent the compiler warning */
|
||||||
@@ -391,7 +459,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
|||||||
/* Solaris, IRIX and more */
|
/* Solaris, IRIX and more */
|
||||||
if ((h = gethostbyname_r(hostname,
|
if ((h = gethostbyname_r(hostname,
|
||||||
(struct hostent *)buf,
|
(struct hostent *)buf,
|
||||||
buf + sizeof(struct hostent),
|
(char *)buf + sizeof(struct hostent),
|
||||||
CURL_NAMELOOKUP_SIZE - sizeof(struct hostent),
|
CURL_NAMELOOKUP_SIZE - sizeof(struct hostent),
|
||||||
&h_errnop)) == NULL )
|
&h_errnop)) == NULL )
|
||||||
#endif
|
#endif
|
||||||
|
@@ -46,7 +46,10 @@ curl_llist_alloc(curl_llist_dtor dtor)
|
|||||||
{
|
{
|
||||||
curl_llist *list;
|
curl_llist *list;
|
||||||
|
|
||||||
list = malloc(sizeof(curl_llist));
|
list = (curl_llist *)malloc(sizeof(curl_llist));
|
||||||
|
if(NULL == list)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
curl_llist_init(list, dtor);
|
curl_llist_init(list, dtor);
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
|
@@ -24,73 +24,11 @@
|
|||||||
* - Max 128 parameters
|
* - Max 128 parameters
|
||||||
* - No 'long double' support.
|
* - No 'long double' support.
|
||||||
*
|
*
|
||||||
*************************************************************************
|
* If you ever want truly portable and good *printf() clones, the project that
|
||||||
*
|
* took on from here is named 'Trio' and you find more details on the trio web
|
||||||
*
|
* page at http://daniel.haxx.se/trio/
|
||||||
* 1998/01/10 (v2.8)
|
*/
|
||||||
* Daniel
|
|
||||||
* - Updated version number.
|
|
||||||
* - Corrected a static non-zero prefixed width problem.
|
|
||||||
*
|
|
||||||
* 1998/11/17 - Daniel
|
|
||||||
* Added daprintf() and dvaprintf() for allocated printf() and vprintf().
|
|
||||||
* They return an allocated buffer with the result inside. The result must
|
|
||||||
* be free()ed!
|
|
||||||
*
|
|
||||||
* 1998/08/23 - breese
|
|
||||||
*
|
|
||||||
* Converted all non-printable (and non-whitespace) characters into
|
|
||||||
* their decimal ASCII value preceeded by a '\' character
|
|
||||||
* (this only applies to snprintf family so far)
|
|
||||||
*
|
|
||||||
* Added %S (which is the same as %#s)
|
|
||||||
*
|
|
||||||
* 1998/05/05 (v2.7)
|
|
||||||
*
|
|
||||||
* Fixed precision and width qualifiers (%.*s)
|
|
||||||
*
|
|
||||||
* Added support for snprintf()
|
|
||||||
*
|
|
||||||
* Quoting (%#s) is disabled for the (nil) pointer
|
|
||||||
*
|
|
||||||
* 1997/06/09 (v2.6)
|
|
||||||
*
|
|
||||||
* %#s means that the string will be quoted with "
|
|
||||||
* (I was getting tired of writing \"%s\" all the time)
|
|
||||||
*
|
|
||||||
* [ERR] for strings changed to (nil)
|
|
||||||
*
|
|
||||||
* v2.5
|
|
||||||
* - Added C++ support
|
|
||||||
* - Prepended all internal functions with dprintf_
|
|
||||||
* - Defined the booleans
|
|
||||||
*
|
|
||||||
* v2.4
|
|
||||||
* - Added dvsprintf(), dvfprintf() and dvprintf().
|
|
||||||
* - Made the formatting function available with the name _formatf() to enable
|
|
||||||
* other *printf()-inspired functions. (I considered adding a dmsprintf()
|
|
||||||
* that works like sprintf() but allocates the destination string and
|
|
||||||
* possibly enlarges it itself, but things like that should be done with the
|
|
||||||
* new _formatf() instead.)
|
|
||||||
*
|
|
||||||
* v2.3
|
|
||||||
* - Small modifications to make it compile nicely at both Daniel's and
|
|
||||||
* Bjorn's place.
|
|
||||||
*
|
|
||||||
* v2.2
|
|
||||||
* - Made it work with text to the right of the last %!
|
|
||||||
* - Introduced dprintf(), dsprintf() and dfprintf().
|
|
||||||
* - Float/double support enabled. This system is currently using the ordinary
|
|
||||||
* sprintf() function. NOTE that positional parameters, widths and precisions
|
|
||||||
* will still work like it should since the d-system takes care of that and
|
|
||||||
* passes that information re-formatted to the old sprintf().
|
|
||||||
*
|
|
||||||
* v2.1
|
|
||||||
* - Fixed space padding (i.e %d was extra padded previously)
|
|
||||||
* - long long output is supported
|
|
||||||
* - alternate output is done correct like in %#08x
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -100,6 +38,15 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef SIZEOF_LONG_LONG
|
||||||
|
/* prevents warnings on picky compilers */
|
||||||
|
#define SIZEOF_LONG_LONG 0
|
||||||
|
#endif
|
||||||
|
#ifndef SIZEOF_LONG_DOUBLE
|
||||||
|
#define SIZEOF_LONG_DOUBLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#ifdef MALLOCDEBUG
|
#ifdef MALLOCDEBUG
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
@@ -1191,7 +1138,7 @@ int main()
|
|||||||
{
|
{
|
||||||
char buffer[129];
|
char buffer[129];
|
||||||
char *ptr;
|
char *ptr;
|
||||||
#ifdef SIZEOF_LONG_LONG
|
#if SIZEOF_LONG_LONG>0
|
||||||
long long hullo;
|
long long hullo;
|
||||||
dprintf("%3$12s %1$s %2$qd %4$d\n", "daniel", hullo, "stenberg", 65);
|
dprintf("%3$12s %1$s %2$qd %4$d\n", "daniel", hullo, "stenberg", 65);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -157,7 +157,7 @@ int Curl_parsenetrc(char *host,
|
|||||||
}
|
}
|
||||||
else if(state_password) {
|
else if(state_password) {
|
||||||
strncpy(password, tok, PASSWORDSIZE-1);
|
strncpy(password, tok, PASSWORDSIZE-1);
|
||||||
#if _NETRC_DEBUG
|
#ifdef _NETRC_DEBUG
|
||||||
printf("PASSWORD: %s\n", password);
|
printf("PASSWORD: %s\n", password);
|
||||||
#endif
|
#endif
|
||||||
state_password=0;
|
state_password=0;
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* In order to be useful for every potential user, curl and libcurl are
|
* In order to be useful for every potential user, curl and libcurl are
|
||||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||||
@@ -26,6 +26,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -212,6 +214,7 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
|||||||
failf(conn->data, "SSL_write() return error %d\n", err);
|
failf(conn->data, "SSL_write() return error %d\n", err);
|
||||||
return CURLE_WRITE_ERROR;
|
return CURLE_WRITE_ERROR;
|
||||||
}
|
}
|
||||||
|
bytes_written = rc;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#endif
|
#endif
|
||||||
@@ -226,7 +229,7 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
|
|||||||
}
|
}
|
||||||
if(-1 == bytes_written) {
|
if(-1 == bytes_written) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if(EWOULDBLOCK == GetLastError())
|
if(WSAEWOULDBLOCK == GetLastError())
|
||||||
#else
|
#else
|
||||||
if(EWOULDBLOCK == errno)
|
if(EWOULDBLOCK == errno)
|
||||||
#endif
|
#endif
|
||||||
@@ -338,7 +341,7 @@ int Curl_read(struct connectdata *conn,
|
|||||||
|
|
||||||
if(-1 == nread) {
|
if(-1 == nread) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if(EWOULDBLOCK == GetLastError())
|
if(WSAEWOULDBLOCK == GetLastError())
|
||||||
#else
|
#else
|
||||||
if(EWOULDBLOCK == errno)
|
if(EWOULDBLOCK == errno)
|
||||||
#endif
|
#endif
|
||||||
|
23
lib/ssluse.c
23
lib/ssluse.c
@@ -43,6 +43,12 @@
|
|||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x0090581fL
|
||||||
|
#define HAVE_SSL_GET1_SESSION 1
|
||||||
|
#else
|
||||||
|
#undef HAVE_SSL_GET1_SESSION
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x00904100L
|
#if OPENSSL_VERSION_NUMBER >= 0x00904100L
|
||||||
#define HAVE_USERDATA_IN_PWD_CALLBACK 1
|
#define HAVE_USERDATA_IN_PWD_CALLBACK 1
|
||||||
#else
|
#else
|
||||||
@@ -558,11 +564,26 @@ static int Store_SSL_Session(struct connectdata *conn)
|
|||||||
int oldest_age=data->state.session[0].age; /* zero if unused */
|
int oldest_age=data->state.session[0].age; /* zero if unused */
|
||||||
|
|
||||||
/* ask OpenSSL, say please */
|
/* ask OpenSSL, say please */
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL_GET1_SESSION
|
||||||
ssl_sessionid = SSL_get1_session(conn->ssl.handle);
|
ssl_sessionid = SSL_get1_session(conn->ssl.handle);
|
||||||
|
|
||||||
/* SSL_get1_session() will increment the reference
|
/* SSL_get1_session() will increment the reference
|
||||||
count and the session will stay in memory until explicitly freed with
|
count and the session will stay in memory until explicitly freed with
|
||||||
SSL_SESSION_free(3), regardless of its state. */
|
SSL_SESSION_free(3), regardless of its state.
|
||||||
|
This function was introduced in openssl 0.9.5a. */
|
||||||
|
#else
|
||||||
|
ssl_sessionid = SSL_get_session(conn->ssl.handle);
|
||||||
|
|
||||||
|
/* if SSL_get1_session() is unavailable, use SSL_get_session().
|
||||||
|
This is an inferior option because the session can be flushed
|
||||||
|
at any time by openssl. It is included only so curl compiles
|
||||||
|
under versions of openssl < 0.9.5a.
|
||||||
|
|
||||||
|
WARNING: How curl behaves if it's session is flushed is
|
||||||
|
untested.
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Now we should add the session ID and the host name to the cache, (remove
|
/* Now we should add the session ID and the host name to the cache, (remove
|
||||||
the oldest if necessary) */
|
the oldest if necessary) */
|
||||||
|
@@ -356,10 +356,11 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
* If we requested a "no body", this is a good time to get
|
* If we requested a "no body", this is a good time to get
|
||||||
* out and return home.
|
* out and return home.
|
||||||
*/
|
*/
|
||||||
if(data->set.no_body)
|
bool stop_reading = FALSE;
|
||||||
return CURLE_OK;
|
|
||||||
|
|
||||||
if(!conn->bits.close) {
|
if(data->set.no_body)
|
||||||
|
stop_reading = TRUE;
|
||||||
|
else if(!conn->bits.close) {
|
||||||
/* If this is not the last request before a close, we must
|
/* If this is not the last request before a close, we must
|
||||||
set the maximum download size to the size of the
|
set the maximum download size to the size of the
|
||||||
expected document or else, we won't know when to stop
|
expected document or else, we won't know when to stop
|
||||||
@@ -370,10 +371,18 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
/* If max download size is *zero* (nothing) we already
|
/* If max download size is *zero* (nothing) we already
|
||||||
have nothing and can safely return ok now! */
|
have nothing and can safely return ok now! */
|
||||||
if(0 == conn->maxdownload)
|
if(0 == conn->maxdownload)
|
||||||
return CURLE_OK;
|
stop_reading = TRUE;
|
||||||
|
|
||||||
/* What to do if the size is *not* known? */
|
/* What to do if the size is *not* known? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(stop_reading) {
|
||||||
|
/* we make sure that this socket isn't read more now */
|
||||||
|
k->keepon &= ~KEEP_READ;
|
||||||
|
FD_ZERO(&k->rkeepfd);
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
break; /* exit header line loop */
|
break; /* exit header line loop */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* In order to be useful for every potential user, curl and libcurl are
|
* In order to be useful for every potential user, curl and libcurl are
|
||||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||||
@@ -38,20 +38,28 @@ char *curl_version(void)
|
|||||||
|
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
|
|
||||||
#if (SSLEAY_VERSION_NUMBER >= 0x906000)
|
#if (SSLEAY_VERSION_NUMBER >= 0x905000)
|
||||||
{
|
{
|
||||||
char sub[2];
|
char sub[2];
|
||||||
|
unsigned long ssleay_value;
|
||||||
sub[1]='\0';
|
sub[1]='\0';
|
||||||
if(SSLEAY_VERSION_NUMBER&0xff0) {
|
ssleay_value=SSLeay();
|
||||||
sub[0]=((SSLEAY_VERSION_NUMBER>>4)&0xff) + 'a' -1;
|
if(ssleay_value < 0x906000) {
|
||||||
}
|
ssleay_value=SSLEAY_VERSION_NUMBER;
|
||||||
else
|
|
||||||
sub[0]='\0';
|
sub[0]='\0';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(ssleay_value&0xff0) {
|
||||||
|
sub[0]=((ssleay_value>>4)&0xff) + 'a' -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sub[0]='\0';
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(ptr, " (OpenSSL %lx.%lx.%lx%s)",
|
sprintf(ptr, " (OpenSSL %lx.%lx.%lx%s)",
|
||||||
(SSLEAY_VERSION_NUMBER>>28)&0xf,
|
(ssleay_value>>28)&0xf,
|
||||||
(SSLEAY_VERSION_NUMBER>>20)&0xff,
|
(ssleay_value>>20)&0xff,
|
||||||
(SSLEAY_VERSION_NUMBER>>12)&0xff,
|
(ssleay_value>>12)&0xff,
|
||||||
sub);
|
sub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
#define CURL_NAME "curl"
|
#define CURL_NAME "curl"
|
||||||
#define CURL_VERSION "7.9.3-pre2"
|
#define CURL_VERSION "7.9.3"
|
||||||
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
||||||
|
Reference in New Issue
Block a user