Compare commits
12 Commits
curl-7_9_3
...
curl-7_9_3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb5f6e18e6 | ||
|
|
b798e7a5ae | ||
|
|
5deab7ad27 | ||
|
|
12cdfd282d | ||
|
|
eba8035e12 | ||
|
|
edcbf4350b | ||
|
|
9289ea471f | ||
|
|
7d06185aa6 | ||
|
|
01ecb1d7e7 | ||
|
|
e177f14595 | ||
|
|
5c6eddcadd | ||
|
|
b3b4786990 |
26
CHANGES
26
CHANGES
@@ -6,6 +6,32 @@
|
|||||||
|
|
||||||
History of Changes
|
History of Changes
|
||||||
|
|
||||||
|
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 pointed out a timed out transfer 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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
@@ -23,12 +23,57 @@ About this Document
|
|||||||
|
|
||||||
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
|
||||||
|
|
||||||
@@ -118,6 +163,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 +199,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 +215,14 @@ 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.
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
@@ -200,6 +267,50 @@ 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.
|
||||||
|
|
||||||
|
[ URL, options, callback ]
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
Security Considerations
|
||||||
|
|
||||||
|
|
||||||
|
Certificates and Other SSL Tricks
|
||||||
|
|
||||||
|
|
||||||
|
Future
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----
|
-----
|
||||||
Footnotes:
|
Footnotes:
|
||||||
|
|
||||||
@@ -207,3 +318,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.
|
||||||
|
|||||||
@@ -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-pre3"
|
||||||
#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) */
|
||||||
|
|||||||
@@ -369,10 +369,12 @@ 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
|
||||||
/*
|
/*
|
||||||
|
|||||||
92
lib/hostip.c
92
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -212,6 +212,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
|
||||||
|
|||||||
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) */
|
||||||
|
|||||||
@@ -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;
|
||||||
|
sub[0]='\0';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(ssleay_value&0xff0) {
|
||||||
|
sub[0]=((ssleay_value>>4)&0xff) + 'a' -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sub[0]='\0';
|
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-pre3"
|
||||||
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
||||||
|
|||||||
Reference in New Issue
Block a user