mirror of
https://github.com/darlinghq/darling-curl.git
synced 2024-11-23 03:09:43 +00:00
curl-83.40.2
This commit is contained in:
commit
7e51b6d6cf
34
README.APPLE
Normal file
34
README.APPLE
Normal file
@ -0,0 +1,34 @@
|
||||
The 'curl' subdirectory is based on curl 7.43.0
|
||||
|
||||
== Updating ==
|
||||
|
||||
Confirm/update versions in xcconfigs/libcurl-version.xcconfig
|
||||
- This will probably require building the regular open source version and running otool on the resulting library.
|
||||
|
||||
Update CURL_SUPPORT_* in xcconfigs/common.xcconfig
|
||||
- Run configure, check config.status
|
||||
|
||||
If options change (see below), update CURL_CONFIGURE_OPTIONS in xcconfigs/common.xcconfig
|
||||
|
||||
Make sure all files are being compiled.
|
||||
curl: CURL_CFILES and CURLX_CFILES in curl/src/Makefile.inc
|
||||
libcurl: LIB_CFILES and LIB_VTLS_CFILES in curl/lib/Makefile.inc
|
||||
The Xcode targets list the files in the same order.
|
||||
Might be able to process the Makefile.inc files into Xcode file lists at some point.
|
||||
|
||||
Make sure all man pages and headers are being installed.
|
||||
|
||||
Update xcscripts/install_libtest.sh (see comment at top)
|
||||
|
||||
== Configuration ==
|
||||
|
||||
./configure --with-gssapi --enable-hidden-symbols --disable-static --enable-threaded-resolver --with-darwinssl --without-libssh2
|
||||
|
||||
Changes to include/curl/curlbuild.h post-configure:
|
||||
(1) Add #ifdef __LP64__ for CURL_SIZEOF_LONG.
|
||||
(2) Change CURL_TYPEOF_CURL_OFF_T and associated defines to int64_t (configure gets it wrong for 32-bit).
|
||||
(requires CURL_PULL_STDINT_H, CURL_PULL_INTTYPES_H)
|
||||
|
||||
Changes to lib/curl_config.h post-configure:
|
||||
(1) Add #ifdef __LP64__ for SIZEOF_LONG, SIZEOF_SIZE_T, SIZEOF_TIME_T, SIZEOF_VOIDP
|
||||
(2) #undef HAVE_GSSAPI, OS - conditionally defined in common.xcconfig
|
30
curl.plist
Normal file
30
curl.plist
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>OpenSourceProject</key>
|
||||
<string>curl</string>
|
||||
<key>OpenSourceVersion</key>
|
||||
<string>7.43.0</string>
|
||||
<key>OpenSourceWebsiteURL</key>
|
||||
<string>http://curl.haxx.se/</string>
|
||||
<key>OpenSourceURL</key>
|
||||
<string>http://curl.haxx.se/download/curl-7.43.0.tar.bz2</string>
|
||||
<key>OpenSourceSHA1</key>
|
||||
<string>d821ea39610b7f1122f1f574a4d8e20e81b3c561</string>
|
||||
<key>OpenSourceImportDate</key>
|
||||
<string>2015-07-13</string>
|
||||
<key>OpenSourceModifications</key>
|
||||
<array>
|
||||
<string>curl-config.in: remove -I, -L, and static library info</string>
|
||||
<string>docs/curl.1: remove references to netrc(4) and wget(1)</string>
|
||||
<string>include/curl/multi.h: Add availability to curl_multi_wait (13158909)</string>
|
||||
<string>lib/ldap.c: 5648196</string>
|
||||
<string>lib/multi.c, lib/transfer.c: 903b6e05565bf826b4194447864288642214b094</string>
|
||||
</array>
|
||||
<key>OpenSourceLicense</key>
|
||||
<string>MIT</string>
|
||||
<key>OpenSourceLicenseFile</key>
|
||||
<string>curl.txt</string>
|
||||
</dict>
|
||||
</plist>
|
3266
curl.xcodeproj/project.pbxproj
Normal file
3266
curl.xcodeproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load Diff
5217
curl/CHANGES
Normal file
5217
curl/CHANGES
Normal file
File diff suppressed because it is too large
Load Diff
2
curl/CMake/CMakeConfigurableFile.in
Normal file
2
curl/CMake/CMakeConfigurableFile.in
Normal file
@ -0,0 +1,2 @@
|
||||
@CMAKE_CONFIGURABLE_FILE_CONTENT@
|
||||
|
535
curl/CMake/CurlTests.c
Normal file
535
curl/CMake/CurlTests.c
Normal file
@ -0,0 +1,535 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
/* Time with sys/time test */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if ((struct tm *) 0)
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCNTL_O_NONBLOCK
|
||||
|
||||
/* headers for FCNTL_O_NONBLOCK test */
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
/* */
|
||||
#if defined(sun) || defined(__sun__) || \
|
||||
defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
# if defined(__SVR4) || defined(__srv4__)
|
||||
# define PLATFORM_SOLARIS
|
||||
# else
|
||||
# define PLATFORM_SUNOS4
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
|
||||
# define PLATFORM_AIX_V3
|
||||
#endif
|
||||
/* */
|
||||
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__)
|
||||
#error "O_NONBLOCK does not work on this platform"
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
/* O_NONBLOCK source test */
|
||||
int flags = 0;
|
||||
if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* tests for gethostbyaddr_r or gethostbyname_r */
|
||||
#if defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
|
||||
# define _REENTRANT
|
||||
/* no idea whether _REENTRANT is always set, just invent a new flag */
|
||||
# define TEST_GETHOSTBYFOO_REENTRANT
|
||||
#endif
|
||||
#if defined(HAVE_GETHOSTBYADDR_R_5) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_7) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_3) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_5) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6) || \
|
||||
defined(TEST_GETHOSTBYFOO_REENTRANT)
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
int main(void)
|
||||
{
|
||||
char *address = "example.com";
|
||||
int length = 0;
|
||||
int type = 0;
|
||||
struct hostent h;
|
||||
int rc = 0;
|
||||
#if defined(HAVE_GETHOSTBYADDR_R_5) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \
|
||||
\
|
||||
defined(HAVE_GETHOSTBYNAME_R_3) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
|
||||
struct hostent_data hdata;
|
||||
#elif defined(HAVE_GETHOSTBYADDR_R_7) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \
|
||||
\
|
||||
defined(HAVE_GETHOSTBYNAME_R_5) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
|
||||
char buffer[8192];
|
||||
int h_errnop;
|
||||
struct hostent *hp;
|
||||
#endif
|
||||
|
||||
#ifndef gethostbyaddr_r
|
||||
(void)gethostbyaddr_r;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GETHOSTBYADDR_R_5) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT)
|
||||
rc = gethostbyaddr_r(address, length, type, &h, &hdata);
|
||||
#elif defined(HAVE_GETHOSTBYADDR_R_7) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT)
|
||||
hp = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &h_errnop);
|
||||
(void)hp;
|
||||
#elif defined(HAVE_GETHOSTBYADDR_R_8) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT)
|
||||
rc = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &hp, &h_errnop);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GETHOSTBYNAME_R_3) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
|
||||
rc = gethostbyname_r(address, &h, &hdata);
|
||||
#elif defined(HAVE_GETHOSTBYNAME_R_5) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT)
|
||||
rc = gethostbyname_r(address, &h, buffer, 8192, 0, &h_errnop);
|
||||
(void)hp; /* not used for test */
|
||||
#elif defined(HAVE_GETHOSTBYNAME_R_6) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
|
||||
rc = gethostbyname_r(address, &h, buffer, 8192, &hp, &h_errnop);
|
||||
#endif
|
||||
|
||||
(void)length;
|
||||
(void)type;
|
||||
(void)rc;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SOCKLEN_T
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if ((socklen_t *) 0)
|
||||
return 0;
|
||||
if (sizeof (socklen_t))
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_IN_ADDR_T
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if ((in_addr_t *) 0)
|
||||
return 0;
|
||||
if (sizeof (in_addr_t))
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BOOL_T
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (sizeof (bool *) )
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
int main() { return 0; }
|
||||
#endif
|
||||
#ifdef RETSIGTYPE_TEST
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#ifdef signal
|
||||
# undef signal
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
extern "C" void (*signal (int, void (*)(int)))(int);
|
||||
#else
|
||||
void (*signal ()) ();
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_INET_NTOA_R_DECL
|
||||
#include <arpa/inet.h>
|
||||
|
||||
typedef void (*func_type)();
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef inet_ntoa_r
|
||||
func_type func;
|
||||
func = (func_type)inet_ntoa_r;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_INET_NTOA_R_DECL_REENTRANT
|
||||
#define _REENTRANT
|
||||
#include <arpa/inet.h>
|
||||
|
||||
typedef void (*func_type)();
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef inet_ntoa_r
|
||||
func_type func;
|
||||
func = (func_type)&inet_ntoa_r;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int main(void) {
|
||||
struct addrinfo hints, *ai;
|
||||
int error;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
#ifndef getaddrinfo
|
||||
(void)getaddrinfo;
|
||||
#endif
|
||||
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
|
||||
if (error) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_FILE_OFFSET_BITS
|
||||
#ifdef _FILE_OFFSET_BITS
|
||||
#undef _FILE_OFFSET_BITS
|
||||
#endif
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int main () { ; return 0; }
|
||||
#endif
|
||||
#ifdef HAVE_IOCTLSOCKET
|
||||
/* includes start */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
/* ioctlsocket source code */
|
||||
int socket;
|
||||
unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef HAVE_IOCTLSOCKET_CAMEL
|
||||
/* includes start */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
/* IoctlSocket source code */
|
||||
if(0 != IoctlSocket(0, 0, 0))
|
||||
return 1;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO
|
||||
/* includes start */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
/* IoctlSocket source code */
|
||||
long flags = 0;
|
||||
if(0 != ioctlsocket(0, FIONBIO, &flags))
|
||||
return 1;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_IOCTLSOCKET_FIONBIO
|
||||
/* includes start */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
int flags = 0;
|
||||
if(0 != ioctlsocket(0, FIONBIO, &flags))
|
||||
return 1;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_IOCTL_FIONBIO
|
||||
/* headers for FIONBIO test */
|
||||
/* includes start */
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_STROPTS_H
|
||||
# include <stropts.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
int flags = 0;
|
||||
if(0 != ioctl(0, FIONBIO, &flags))
|
||||
return 1;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_IOCTL_SIOCGIFADDR
|
||||
/* headers for FIONBIO test */
|
||||
/* includes start */
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_STROPTS_H
|
||||
# include <stropts.h>
|
||||
#endif
|
||||
#include <net/if.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
struct ifreq ifr;
|
||||
if(0 != ioctl(0, SIOCGIFADDR, &ifr))
|
||||
return 1;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_SETSOCKOPT_SO_NONBLOCK
|
||||
/* includes start */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
/* includes start */
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
/* includes end */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if(0 != setsockopt(0, SOL_SOCKET, SO_NONBLOCK, 0, 0))
|
||||
return 1;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_GLIBC_STRERROR_R
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
int
|
||||
main () {
|
||||
char buffer[1024]; /* big enough to play with */
|
||||
char *string =
|
||||
strerror_r(EACCES, buffer, sizeof(buffer));
|
||||
/* this should've returned a string */
|
||||
if(!string || !string[0])
|
||||
return 99;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_POSIX_STRERROR_R
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
int
|
||||
main () {
|
||||
char buffer[1024]; /* big enough to play with */
|
||||
int error =
|
||||
strerror_r(EACCES, buffer, sizeof(buffer));
|
||||
/* This should've returned zero, and written an error string in the
|
||||
buffer.*/
|
||||
if(!buffer[0] || error)
|
||||
return 99;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
289
curl/CMake/FindGSS.cmake
Normal file
289
curl/CMake/FindGSS.cmake
Normal file
@ -0,0 +1,289 @@
|
||||
# - Try to find the GSS Kerberos library
|
||||
# Once done this will define
|
||||
#
|
||||
# GSS_ROOT_DIR - Set this variable to the root installation of GSS
|
||||
#
|
||||
# Read-Only variables:
|
||||
# GSS_FOUND - system has the Heimdal library
|
||||
# GSS_FLAVOUR - "MIT" or "Heimdal" if anything found.
|
||||
# GSS_INCLUDE_DIR - the Heimdal include directory
|
||||
# GSS_LIBRARIES - The libraries needed to use GSS
|
||||
# GSS_LINK_DIRECTORIES - Directories to add to linker search path
|
||||
# GSS_LINKER_FLAGS - Additional linker flags
|
||||
# GSS_COMPILER_FLAGS - Additional compiler flags
|
||||
# GSS_VERSION - This is set to version advertised by pkg-config or read from manifest.
|
||||
# In case the library is found but no version info availabe it'll be set to "unknown"
|
||||
|
||||
set(_MIT_MODNAME mit-krb5-gssapi)
|
||||
set(_HEIMDAL_MODNAME heimdal-gssapi)
|
||||
|
||||
include(CheckIncludeFile)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckTypeSize)
|
||||
|
||||
set(_GSS_ROOT_HINTS
|
||||
"${GSS_ROOT_DIR}"
|
||||
"$ENV{GSS_ROOT_DIR}"
|
||||
)
|
||||
|
||||
# try to find library using system pkg-config if user didn't specify root dir
|
||||
if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
|
||||
if(UNIX)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
|
||||
list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
|
||||
elseif(WIN32)
|
||||
list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach.
|
||||
find_file(_GSS_CONFIGURE_SCRIPT
|
||||
NAMES
|
||||
"krb5-config"
|
||||
HINTS
|
||||
${_GSS_ROOT_HINTS}
|
||||
PATH_SUFFIXES
|
||||
bin
|
||||
NO_CMAKE_PATH
|
||||
NO_CMAKE_ENVIRONMENT_PATH
|
||||
)
|
||||
|
||||
# if not found in user-supplied directories, maybe system knows better
|
||||
find_file(_GSS_CONFIGURE_SCRIPT
|
||||
NAMES
|
||||
"krb5-config"
|
||||
PATH_SUFFIXES
|
||||
bin
|
||||
)
|
||||
|
||||
if(_GSS_CONFIGURE_SCRIPT)
|
||||
execute_process(
|
||||
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
|
||||
OUTPUT_VARIABLE _GSS_CFLAGS
|
||||
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
|
||||
)
|
||||
message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
|
||||
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
|
||||
# should also work in an odd case when multiple directories are given
|
||||
string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
|
||||
string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
|
||||
string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1"_GSS_CFLAGS "${_GSS_CFLAGS}")
|
||||
|
||||
foreach(_flag ${_GSS_CFLAGS})
|
||||
if(_flag MATCHES "^-I.*")
|
||||
string(REGEX REPLACE "^-I" "" _val "${_flag}")
|
||||
list(APPEND _GSS_INCLUDE_DIR "${_val}")
|
||||
else()
|
||||
list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
|
||||
OUTPUT_VARIABLE _GSS_LIB_FLAGS
|
||||
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
|
||||
)
|
||||
message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
|
||||
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
|
||||
# this script gives us libraries and link directories. Blah. We have to deal with it.
|
||||
string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
|
||||
string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
|
||||
string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1"_GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
|
||||
|
||||
foreach(_flag ${_GSS_LIB_FLAGS})
|
||||
if(_flag MATCHES "^-l.*")
|
||||
string(REGEX REPLACE "^-l" "" _val "${_flag}")
|
||||
list(APPEND _GSS_LIBRARIES "${_val}")
|
||||
elseif(_flag MATCHES "^-L.*")
|
||||
string(REGEX REPLACE "^-L" "" _val "${_flag}")
|
||||
list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
|
||||
else()
|
||||
list(APPEND _GSS_LINKER_FLAGS "${_flag}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
||||
execute_process(
|
||||
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
|
||||
OUTPUT_VARIABLE _GSS_VERSION
|
||||
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
|
||||
)
|
||||
|
||||
# older versions may not have the "--version" parameter. In this case we just don't care.
|
||||
if(_GSS_CONFIGURE_FAILED)
|
||||
set(_GSS_VERSION 0)
|
||||
endif()
|
||||
|
||||
|
||||
execute_process(
|
||||
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
|
||||
OUTPUT_VARIABLE _GSS_VENDOR
|
||||
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
|
||||
)
|
||||
|
||||
# older versions may not have the "--vendor" parameter. In this case we just don't care.
|
||||
if(_GSS_CONFIGURE_FAILED)
|
||||
set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
|
||||
else()
|
||||
if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
|
||||
set(GSS_FLAVOUR "Heimdal")
|
||||
else()
|
||||
set(GSS_FLAVOUR "MIT")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
|
||||
|
||||
find_path(_GSS_INCLUDE_DIR
|
||||
NAMES
|
||||
"gssapi/gssapi.h"
|
||||
HINTS
|
||||
${_GSS_ROOT_HINTS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
inc
|
||||
)
|
||||
|
||||
if(_GSS_INCLUDE_DIR) #jay, we've found something
|
||||
set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
|
||||
check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
|
||||
|
||||
if(_GSS_HAVE_MIT_HEADERS)
|
||||
set(GSS_FLAVOUR "MIT")
|
||||
else()
|
||||
# prevent compiling the header - just check if we can include it
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__")
|
||||
check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
|
||||
|
||||
check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
|
||||
if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
|
||||
set(GSS_FLAVOUR "Heimdal")
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "")
|
||||
endif()
|
||||
else()
|
||||
# I'm not convienced if this is the right way but this is what autotools do at the moment
|
||||
find_path(_GSS_INCLUDE_DIR
|
||||
NAMES
|
||||
"gssapi.h"
|
||||
HINTS
|
||||
${_GSS_ROOT_HINTS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
inc
|
||||
)
|
||||
|
||||
if(_GSS_INCLUDE_DIR)
|
||||
set(GSS_FLAVOUR "Heimdal")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# if we have headers, check if we can link libraries
|
||||
if(GSS_FLAVOUR)
|
||||
set(_GSS_LIBDIR_SUFFIXES "")
|
||||
set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS})
|
||||
get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH)
|
||||
list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT})
|
||||
|
||||
if(WIN32)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64")
|
||||
if(GSS_FLAVOUR STREQUAL "MIT")
|
||||
set(_GSS_LIBNAME "gssapi64")
|
||||
else()
|
||||
set(_GSS_LIBNAME "libgssapi")
|
||||
endif()
|
||||
else()
|
||||
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
|
||||
if(GSS_FLAVOUR STREQUAL "MIT")
|
||||
set(_GSS_LIBNAME "gssapi32")
|
||||
else()
|
||||
set(_GSS_LIBNAME "libgssapi")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS
|
||||
if(GSS_FLAVOUR STREQUAL "MIT")
|
||||
set(_GSS_LIBNAME "gssapi_krb5")
|
||||
else()
|
||||
set(_GSS_LIBNAME "gssapi")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_library(_GSS_LIBRARIES
|
||||
NAMES
|
||||
${_GSS_LIBNAME}
|
||||
HINTS
|
||||
${_GSS_LIBDIR_HINTS}
|
||||
PATH_SUFFIXES
|
||||
${_GSS_LIBDIR_SUFFIXES}
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
endif()
|
||||
else()
|
||||
if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
|
||||
set(GSS_FLAVOUR "MIT")
|
||||
set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
|
||||
else()
|
||||
set(GSS_FLAVOUR "Heimdal")
|
||||
set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR})
|
||||
set(GSS_LIBRARIES ${_GSS_LIBRARIES})
|
||||
set(GSS_LINK_DIRECTORIES ${_GSS_LINK_DIRECTORIES})
|
||||
set(GSS_LINKER_FLAGS ${_GSS_LINKER_FLAGS})
|
||||
set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS})
|
||||
set(GSS_VERSION ${_GSS_VERSION})
|
||||
|
||||
if(GSS_FLAVOUR)
|
||||
|
||||
if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
|
||||
else()
|
||||
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
|
||||
endif()
|
||||
|
||||
if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
|
||||
file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
|
||||
REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
|
||||
|
||||
string(REGEX MATCH "[0-9]\\.[^\"]+"
|
||||
GSS_VERSION "${heimdal_version_str}")
|
||||
endif()
|
||||
|
||||
if(NOT GSS_VERSION)
|
||||
set(GSS_VERSION "Heimdal Unknown")
|
||||
endif()
|
||||
elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
|
||||
get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
|
||||
if(WIN32 AND _MIT_VERSION)
|
||||
set(GSS_VERSION "${_MIT_VERSION}")
|
||||
else()
|
||||
set(GSS_VERSION "MIT Unknown")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR)
|
||||
|
||||
find_package_handle_standard_args(GSS
|
||||
REQUIRED_VARS
|
||||
${_GSS_REQUIRED_VARS}
|
||||
VERSION_VAR
|
||||
GSS_VERSION
|
||||
FAIL_MESSAGE
|
||||
"Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR"
|
||||
)
|
||||
|
||||
mark_as_advanced(GSS_INCLUDE_DIR GSS_LIBRARIES)
|
95
curl/CMake/Macros.cmake
Normal file
95
curl/CMake/Macros.cmake
Normal file
@ -0,0 +1,95 @@
|
||||
#File defines convenience macros for available feature testing
|
||||
|
||||
# This macro checks if the symbol exists in the library and if it
|
||||
# does, it prepends library to the list. It is intended to be called
|
||||
# multiple times with a sequence of possibly dependent libraries in
|
||||
# order of least-to-most-dependent. Some libraries depend on others
|
||||
# to link correctly.
|
||||
macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
|
||||
check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
|
||||
${VARIABLE})
|
||||
if(${VARIABLE})
|
||||
set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
|
||||
endif(${VARIABLE})
|
||||
endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
|
||||
|
||||
# Check if header file exists and add it to the list.
|
||||
# This macro is intended to be called multiple times with a sequence of
|
||||
# possibly dependent header files. Some headers depend on others to be
|
||||
# compiled correctly.
|
||||
macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
|
||||
check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE})
|
||||
if(${VARIABLE})
|
||||
set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
|
||||
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
|
||||
endif(${VARIABLE})
|
||||
endmacro(CHECK_INCLUDE_FILE_CONCAT)
|
||||
|
||||
# For other curl specific tests, use this macro.
|
||||
macro(CURL_INTERNAL_TEST CURL_TEST)
|
||||
if(NOT DEFINED "${CURL_TEST}")
|
||||
set(MACRO_CHECK_FUNCTION_DEFINITIONS
|
||||
"-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
|
||||
if(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CURL_TEST_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
endif(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST}")
|
||||
try_compile(${CURL_TEST}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
|
||||
"${CURL_TEST_ADD_LIBRARIES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
if(${CURL_TEST})
|
||||
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Performing Curl Test ${CURL_TEST} passed with the following output:\n"
|
||||
"${OUTPUT}\n")
|
||||
else(${CURL_TEST})
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
|
||||
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
|
||||
"${OUTPUT}\n")
|
||||
endif(${CURL_TEST})
|
||||
endif()
|
||||
endmacro(CURL_INTERNAL_TEST)
|
||||
|
||||
macro(CURL_INTERNAL_TEST_RUN CURL_TEST)
|
||||
if(NOT DEFINED "${CURL_TEST}_COMPILE")
|
||||
set(MACRO_CHECK_FUNCTION_DEFINITIONS
|
||||
"-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}")
|
||||
if(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CURL_TEST_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
endif(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST}")
|
||||
try_run(${CURL_TEST} ${CURL_TEST}_COMPILE
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
|
||||
"${CURL_TEST_ADD_LIBRARIES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
if(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
|
||||
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
|
||||
else(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
|
||||
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
|
||||
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
|
||||
"${OUTPUT}")
|
||||
if(${CURL_TEST}_COMPILE)
|
||||
file(APPEND
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
|
||||
"There was a problem running this test\n")
|
||||
endif(${CURL_TEST}_COMPILE)
|
||||
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
|
||||
"\n\n")
|
||||
endif(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
|
||||
endif()
|
||||
endmacro(CURL_INTERNAL_TEST_RUN)
|
229
curl/CMake/OtherTests.cmake
Normal file
229
curl/CMake/OtherTests.cmake
Normal file
@ -0,0 +1,229 @@
|
||||
include(CheckCSourceCompiles)
|
||||
# The begin of the sources (macros and includes)
|
||||
set(_source_epilogue "#undef inline")
|
||||
|
||||
macro(add_header_include check header)
|
||||
if(${check})
|
||||
set(_source_epilogue "${_source_epilogue}\n#include <${header}>")
|
||||
endif(${check})
|
||||
endmacro(add_header_include)
|
||||
|
||||
set(signature_call_conv)
|
||||
if(HAVE_WINDOWS_H)
|
||||
add_header_include(HAVE_WINDOWS_H "windows.h")
|
||||
add_header_include(HAVE_WINSOCK2_H "winsock2.h")
|
||||
add_header_include(HAVE_WINSOCK_H "winsock.h")
|
||||
set(_source_epilogue
|
||||
"${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif")
|
||||
set(signature_call_conv "PASCAL")
|
||||
if(HAVE_LIBWS2_32)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
|
||||
endif()
|
||||
else(HAVE_WINDOWS_H)
|
||||
add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
|
||||
add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
|
||||
endif(HAVE_WINDOWS_H)
|
||||
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void) {
|
||||
recv(0, 0, 0, 0);
|
||||
return 0;
|
||||
}" curl_cv_recv)
|
||||
if(curl_cv_recv)
|
||||
if(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
|
||||
foreach(recv_retv "int" "ssize_t" )
|
||||
foreach(recv_arg1 "int" "ssize_t" "SOCKET")
|
||||
foreach(recv_arg2 "void *" "char *")
|
||||
foreach(recv_arg3 "size_t" "int" "socklen_t" "unsigned int")
|
||||
foreach(recv_arg4 "int" "unsigned int")
|
||||
if(NOT curl_cv_func_recv_done)
|
||||
unset(curl_cv_func_recv_test CACHE)
|
||||
check_c_source_compiles("
|
||||
${_source_epilogue}
|
||||
extern ${recv_retv} ${signature_call_conv}
|
||||
recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4});
|
||||
int main(void) {
|
||||
${recv_arg1} s=0;
|
||||
${recv_arg2} buf=0;
|
||||
${recv_arg3} len=0;
|
||||
${recv_arg4} flags=0;
|
||||
${recv_retv} res = recv(s, buf, len, flags);
|
||||
(void) res;
|
||||
return 0;
|
||||
}"
|
||||
curl_cv_func_recv_test)
|
||||
message(STATUS
|
||||
"Tested: ${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})")
|
||||
if(curl_cv_func_recv_test)
|
||||
set(curl_cv_func_recv_args
|
||||
"${recv_arg1},${recv_arg2},${recv_arg3},${recv_arg4},${recv_retv}")
|
||||
set(RECV_TYPE_ARG1 "${recv_arg1}")
|
||||
set(RECV_TYPE_ARG2 "${recv_arg2}")
|
||||
set(RECV_TYPE_ARG3 "${recv_arg3}")
|
||||
set(RECV_TYPE_ARG4 "${recv_arg4}")
|
||||
set(RECV_TYPE_RETV "${recv_retv}")
|
||||
set(HAVE_RECV 1)
|
||||
set(curl_cv_func_recv_done 1)
|
||||
endif(curl_cv_func_recv_test)
|
||||
endif(NOT curl_cv_func_recv_done)
|
||||
endforeach(recv_arg4)
|
||||
endforeach(recv_arg3)
|
||||
endforeach(recv_arg2)
|
||||
endforeach(recv_arg1)
|
||||
endforeach(recv_retv)
|
||||
else()
|
||||
string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}")
|
||||
string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG3 "${curl_cv_func_recv_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" RECV_TYPE_ARG4 "${curl_cv_func_recv_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}")
|
||||
endif()
|
||||
|
||||
if("${curl_cv_func_recv_args}" STREQUAL "unknown")
|
||||
message(FATAL_ERROR "Cannot find proper types to use for recv args")
|
||||
endif("${curl_cv_func_recv_args}" STREQUAL "unknown")
|
||||
else(curl_cv_recv)
|
||||
message(FATAL_ERROR "Unable to link function recv")
|
||||
endif(curl_cv_recv)
|
||||
set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
|
||||
set(HAVE_RECV 1)
|
||||
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void) {
|
||||
send(0, 0, 0, 0);
|
||||
return 0;
|
||||
}" curl_cv_send)
|
||||
if(curl_cv_send)
|
||||
if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
|
||||
foreach(send_retv "int" "ssize_t" )
|
||||
foreach(send_arg1 "int" "ssize_t" "SOCKET")
|
||||
foreach(send_arg2 "const void *" "void *" "char *" "const char *")
|
||||
foreach(send_arg3 "size_t" "int" "socklen_t" "unsigned int")
|
||||
foreach(send_arg4 "int" "unsigned int")
|
||||
if(NOT curl_cv_func_send_done)
|
||||
unset(curl_cv_func_send_test CACHE)
|
||||
check_c_source_compiles("
|
||||
${_source_epilogue}
|
||||
extern ${send_retv} ${signature_call_conv}
|
||||
send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4});
|
||||
int main(void) {
|
||||
${send_arg1} s=0;
|
||||
${send_arg2} buf=0;
|
||||
${send_arg3} len=0;
|
||||
${send_arg4} flags=0;
|
||||
${send_retv} res = send(s, buf, len, flags);
|
||||
(void) res;
|
||||
return 0;
|
||||
}"
|
||||
curl_cv_func_send_test)
|
||||
message(STATUS
|
||||
"Tested: ${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})")
|
||||
if(curl_cv_func_send_test)
|
||||
string(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}")
|
||||
string(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}")
|
||||
set(curl_cv_func_send_args
|
||||
"${send_arg1},${send_arg2},${send_arg3},${send_arg4},${send_retv},${send_qual_arg2}")
|
||||
set(SEND_TYPE_ARG1 "${send_arg1}")
|
||||
set(SEND_TYPE_ARG2 "${send_arg2}")
|
||||
set(SEND_TYPE_ARG3 "${send_arg3}")
|
||||
set(SEND_TYPE_ARG4 "${send_arg4}")
|
||||
set(SEND_TYPE_RETV "${send_retv}")
|
||||
set(HAVE_SEND 1)
|
||||
set(curl_cv_func_send_done 1)
|
||||
endif(curl_cv_func_send_test)
|
||||
endif(NOT curl_cv_func_send_done)
|
||||
endforeach(send_arg4)
|
||||
endforeach(send_arg3)
|
||||
endforeach(send_arg2)
|
||||
endforeach(send_arg1)
|
||||
endforeach(send_retv)
|
||||
else()
|
||||
string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}")
|
||||
string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG3 "${curl_cv_func_send_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG4 "${curl_cv_func_send_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" SEND_TYPE_RETV "${curl_cv_func_send_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" SEND_QUAL_ARG2 "${curl_cv_func_send_args}")
|
||||
endif()
|
||||
|
||||
if("${curl_cv_func_send_args}" STREQUAL "unknown")
|
||||
message(FATAL_ERROR "Cannot find proper types to use for send args")
|
||||
endif("${curl_cv_func_send_args}" STREQUAL "unknown")
|
||||
set(SEND_QUAL_ARG2 "const")
|
||||
else(curl_cv_send)
|
||||
message(FATAL_ERROR "Unable to link function send")
|
||||
endif(curl_cv_send)
|
||||
set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
|
||||
set(HAVE_SEND 1)
|
||||
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void) {
|
||||
int flag = MSG_NOSIGNAL;
|
||||
(void)flag;
|
||||
return 0;
|
||||
}" HAVE_MSG_NOSIGNAL)
|
||||
|
||||
if(NOT HAVE_WINDOWS_H)
|
||||
add_header_include(HAVE_SYS_TIME_H "sys/time.h")
|
||||
add_header_include(TIME_WITH_SYS_TIME "time.h")
|
||||
add_header_include(HAVE_TIME_H "time.h")
|
||||
endif()
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void) {
|
||||
struct timeval ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_usec = 0;
|
||||
(void)ts;
|
||||
return 0;
|
||||
}" HAVE_STRUCT_TIMEVAL)
|
||||
|
||||
|
||||
include(CheckCSourceRuns)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
if(HAVE_SYS_POLL_H)
|
||||
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
|
||||
endif(HAVE_SYS_POLL_H)
|
||||
check_c_source_runs("
|
||||
#ifdef HAVE_SYS_POLL_H
|
||||
# include <sys/poll.h>
|
||||
#endif
|
||||
int main(void) {
|
||||
return poll((void *)0, 0, 10 /*ms*/);
|
||||
}" HAVE_POLL_FINE)
|
||||
|
||||
set(HAVE_SIG_ATOMIC_T 1)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
if(HAVE_SIGNAL_H)
|
||||
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SIGNAL_H")
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
|
||||
endif(HAVE_SIGNAL_H)
|
||||
check_type_size("sig_atomic_t" SIZEOF_SIG_ATOMIC_T)
|
||||
if(HAVE_SIZEOF_SIG_ATOMIC_T)
|
||||
check_c_source_compiles("
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
# include <signal.h>
|
||||
#endif
|
||||
int main(void) {
|
||||
static volatile sig_atomic_t dummy = 0;
|
||||
(void)dummy;
|
||||
return 0;
|
||||
}" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
|
||||
if(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
|
||||
set(HAVE_SIG_ATOMIC_T_VOLATILE 1)
|
||||
endif(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
|
||||
endif(HAVE_SIZEOF_SIG_ATOMIC_T)
|
||||
|
||||
if(HAVE_WINDOWS_H)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
|
||||
else()
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
if(HAVE_SYS_SOCKET_H)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
|
||||
endif(HAVE_SYS_SOCKET_H)
|
||||
endif()
|
||||
|
||||
check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
|
||||
if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
|
||||
set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
|
||||
endif(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
|
||||
|
125
curl/CMake/Platforms/WindowsCache.cmake
Normal file
125
curl/CMake/Platforms/WindowsCache.cmake
Normal file
@ -0,0 +1,125 @@
|
||||
if(NOT UNIX)
|
||||
if(WIN32)
|
||||
set(HAVE_LIBDL 0)
|
||||
set(HAVE_LIBUCB 0)
|
||||
set(HAVE_LIBSOCKET 0)
|
||||
set(NOT_NEED_LIBNSL 0)
|
||||
set(HAVE_LIBNSL 0)
|
||||
set(HAVE_GETHOSTNAME 1)
|
||||
set(HAVE_LIBZ 0)
|
||||
set(HAVE_LIBCRYPTO 0)
|
||||
|
||||
set(HAVE_DLOPEN 0)
|
||||
|
||||
set(HAVE_ALLOCA_H 0)
|
||||
set(HAVE_ARPA_INET_H 0)
|
||||
set(HAVE_DLFCN_H 0)
|
||||
set(HAVE_FCNTL_H 1)
|
||||
set(HAVE_INTTYPES_H 0)
|
||||
set(HAVE_IO_H 1)
|
||||
set(HAVE_MALLOC_H 1)
|
||||
set(HAVE_MEMORY_H 1)
|
||||
set(HAVE_NETDB_H 0)
|
||||
set(HAVE_NETINET_IF_ETHER_H 0)
|
||||
set(HAVE_NETINET_IN_H 0)
|
||||
set(HAVE_NET_IF_H 0)
|
||||
set(HAVE_PROCESS_H 1)
|
||||
set(HAVE_PWD_H 0)
|
||||
set(HAVE_SETJMP_H 1)
|
||||
set(HAVE_SGTTY_H 0)
|
||||
set(HAVE_SIGNAL_H 1)
|
||||
set(HAVE_SOCKIO_H 0)
|
||||
set(HAVE_STDINT_H 0)
|
||||
set(HAVE_STDLIB_H 1)
|
||||
set(HAVE_STRINGS_H 0)
|
||||
set(HAVE_STRING_H 1)
|
||||
set(HAVE_SYS_PARAM_H 0)
|
||||
set(HAVE_SYS_POLL_H 0)
|
||||
set(HAVE_SYS_SELECT_H 0)
|
||||
set(HAVE_SYS_SOCKET_H 0)
|
||||
set(HAVE_SYS_SOCKIO_H 0)
|
||||
set(HAVE_SYS_STAT_H 1)
|
||||
set(HAVE_SYS_TIME_H 0)
|
||||
set(HAVE_SYS_TYPES_H 1)
|
||||
set(HAVE_SYS_UTIME_H 1)
|
||||
set(HAVE_TERMIOS_H 0)
|
||||
set(HAVE_TERMIO_H 0)
|
||||
set(HAVE_TIME_H 1)
|
||||
set(HAVE_UNISTD_H 0)
|
||||
set(HAVE_UTIME_H 0)
|
||||
set(HAVE_X509_H 0)
|
||||
set(HAVE_ZLIB_H 0)
|
||||
|
||||
set(HAVE_SIZEOF_LONG_DOUBLE 1)
|
||||
set(SIZEOF_LONG_DOUBLE 8)
|
||||
|
||||
set(HAVE_SOCKET 1)
|
||||
set(HAVE_POLL 0)
|
||||
set(HAVE_SELECT 1)
|
||||
set(HAVE_STRDUP 1)
|
||||
set(HAVE_STRSTR 1)
|
||||
set(HAVE_STRTOK_R 0)
|
||||
set(HAVE_STRFTIME 1)
|
||||
set(HAVE_UNAME 0)
|
||||
set(HAVE_STRCASECMP 0)
|
||||
set(HAVE_STRICMP 1)
|
||||
set(HAVE_STRCMPI 1)
|
||||
set(HAVE_GETHOSTBYADDR 1)
|
||||
set(HAVE_GETTIMEOFDAY 0)
|
||||
set(HAVE_INET_ADDR 1)
|
||||
set(HAVE_INET_NTOA 1)
|
||||
set(HAVE_INET_NTOA_R 0)
|
||||
set(HAVE_TCGETATTR 0)
|
||||
set(HAVE_TCSETATTR 0)
|
||||
set(HAVE_PERROR 1)
|
||||
set(HAVE_CLOSESOCKET 1)
|
||||
set(HAVE_SETVBUF 0)
|
||||
set(HAVE_SIGSETJMP 0)
|
||||
set(HAVE_GETPASS_R 0)
|
||||
set(HAVE_STRLCAT 0)
|
||||
set(HAVE_GETPWUID 0)
|
||||
set(HAVE_GETEUID 0)
|
||||
set(HAVE_UTIME 1)
|
||||
set(HAVE_RAND_EGD 0)
|
||||
set(HAVE_RAND_SCREEN 0)
|
||||
set(HAVE_RAND_STATUS 0)
|
||||
set(HAVE_GMTIME_R 0)
|
||||
set(HAVE_LOCALTIME_R 0)
|
||||
set(HAVE_GETHOSTBYADDR_R 0)
|
||||
set(HAVE_GETHOSTBYNAME_R 0)
|
||||
set(HAVE_SIGNAL_FUNC 1)
|
||||
set(HAVE_SIGNAL_MACRO 0)
|
||||
|
||||
set(HAVE_GETHOSTBYADDR_R_5 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_5_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_7 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_7_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_8 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_8_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_3 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_5 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_5_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_6 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_6_REENTRANT 0)
|
||||
|
||||
set(TIME_WITH_SYS_TIME 0)
|
||||
set(HAVE_O_NONBLOCK 0)
|
||||
set(HAVE_IN_ADDR_T 0)
|
||||
set(HAVE_INET_NTOA_R_DECL 0)
|
||||
set(HAVE_INET_NTOA_R_DECL_REENTRANT 0)
|
||||
if(ENABLE_IPV6)
|
||||
set(HAVE_GETADDRINFO 1)
|
||||
else()
|
||||
set(HAVE_GETADDRINFO 0)
|
||||
endif()
|
||||
set(STDC_HEADERS 1)
|
||||
set(RETSIGTYPE_TEST 1)
|
||||
|
||||
set(HAVE_SIGACTION 0)
|
||||
set(HAVE_MACRO_SIGSETJMP 0)
|
||||
else(WIN32)
|
||||
message("This file should be included on Windows platform only")
|
||||
endif(WIN32)
|
||||
endif(NOT UNIX)
|
||||
|
31
curl/CMake/Utilities.cmake
Normal file
31
curl/CMake/Utilities.cmake
Normal file
@ -0,0 +1,31 @@
|
||||
# File containing various utilities
|
||||
|
||||
# Converts a CMake list to a string containing elements separated by spaces
|
||||
function(TO_LIST_SPACES _LIST_NAME OUTPUT_VAR)
|
||||
set(NEW_LIST_SPACE)
|
||||
foreach(ITEM ${${_LIST_NAME}})
|
||||
set(NEW_LIST_SPACE "${NEW_LIST_SPACE} ${ITEM}")
|
||||
endforeach()
|
||||
string(STRIP ${NEW_LIST_SPACE} NEW_LIST_SPACE)
|
||||
set(${OUTPUT_VAR} "${NEW_LIST_SPACE}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Appends a lis of item to a string which is a space-separated list, if they don't already exist.
|
||||
function(LIST_SPACES_APPEND_ONCE LIST_NAME)
|
||||
string(REPLACE " " ";" _LIST ${${LIST_NAME}})
|
||||
list(APPEND _LIST ${ARGN})
|
||||
list(REMOVE_DUPLICATES _LIST)
|
||||
to_list_spaces(_LIST NEW_LIST_SPACE)
|
||||
set(${LIST_NAME} "${NEW_LIST_SPACE}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Convinience function that does the same as LIST(FIND ...) but with a TRUE/FALSE return value.
|
||||
# Ex: IN_STR_LIST(MY_LIST "Searched item" WAS_FOUND)
|
||||
function(IN_STR_LIST LIST_NAME ITEM_SEARCHED RETVAL)
|
||||
list(FIND ${LIST_NAME} ${ITEM_SEARCHED} FIND_POS)
|
||||
if(${FIND_POS} EQUAL -1)
|
||||
set(${RETVAL} FALSE PARENT_SCOPE)
|
||||
else()
|
||||
set(${RETVAL} TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
1175
curl/CMakeLists.txt
Normal file
1175
curl/CMakeLists.txt
Normal file
File diff suppressed because it is too large
Load Diff
21
curl/COPYING
Normal file
21
curl/COPYING
Normal file
@ -0,0 +1,21 @@
|
||||
COPYRIGHT AND PERMISSION NOTICE
|
||||
|
||||
Copyright (c) 1996 - 2015, Daniel Stenberg, <daniel@haxx.se>.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any purpose
|
||||
with or without fee is hereby granted, provided that the above copyright
|
||||
notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of a copyright holder shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization of the copyright holder.
|
146
curl/MacOSX-Framework
Executable file
146
curl/MacOSX-Framework
Executable file
@ -0,0 +1,146 @@
|
||||
#!/bin/bash
|
||||
# This script performs all of the steps needed to build a
|
||||
# universal binary libcurl.framework for Mac OS X 10.4 or greater.
|
||||
#
|
||||
# Hendrik Visage:
|
||||
# Generalizations added since Snowleopard (10.6) do not include
|
||||
# the 10.4u SDK.
|
||||
#
|
||||
# Also note:
|
||||
# 10.5 is the *ONLY* SDK that support PPC64 :( -- 10.6 do not have ppc64 support
|
||||
#If you need to have PPC64 support then change below to 1
|
||||
PPC64_NEEDED=0
|
||||
# Apple does not support building for PPC anymore in Xcode 4 and later.
|
||||
# If you're using Xcode 3 or earlier and need PPC support, then change
|
||||
# the setting below to 1
|
||||
PPC_NEEDED=0
|
||||
|
||||
# For me the default is to develop for the platform I am on, and if you
|
||||
#desire compatibility with older versions then change USE_OLD to 1 :)
|
||||
USE_OLD=0
|
||||
|
||||
VERSION=`/usr/bin/sed -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' include/curl/curlver.h`
|
||||
FRAMEWORK_VERSION=Versions/Release-$VERSION
|
||||
|
||||
#I also wanted to "copy over" the system, and thus the reason I added the
|
||||
# version to Versions/Release-7.20.1 etc.
|
||||
# now a simple rsync -vaP libcurl.framework /Library/Frameworks will install it
|
||||
# and setup the right paths to this version, leaving the system version
|
||||
# "intact", so you can "fix" it later with the links to Versions/A/...
|
||||
|
||||
DEVELOPER_PATH=`xcode-select --print-path`
|
||||
# Around Xcode 4.3, SDKs were moved from the Developer folder into the
|
||||
# MacOSX.platform folder
|
||||
if test -d "$DEVELOPER_PATH/Platforms/MacOSX.platform/Developer/SDKs"; then
|
||||
SDK_PATH="$DEVELOPER_PATH/Platforms/MacOSX.platform/Developer/SDKs"
|
||||
else
|
||||
SDK_PATH="$DEVELOPER_PATH/SDKs";
|
||||
fi
|
||||
OLD_SDK=`ls $SDK_PATH|head -1`
|
||||
NEW_SDK=`ls -r $SDK_PATH|head -1`
|
||||
|
||||
if test "0"$USE_OLD -gt 0
|
||||
then
|
||||
SDK32=$OLD_SDK
|
||||
else
|
||||
SDK32=$NEW_SDK
|
||||
fi
|
||||
|
||||
MACVER=`echo $SDK32|sed -e s/[a-zA-Z]//g -e s/.\$//`
|
||||
|
||||
SDK32_DIR=$SDK_PATH/$SDK32
|
||||
MINVER32='-mmacosx-version-min='$MACVER
|
||||
if test $PPC_NEEDED -gt 0; then
|
||||
ARCHES32='-arch i386 -arch ppc'
|
||||
else
|
||||
ARCHES32='-arch i386'
|
||||
fi
|
||||
|
||||
if test $PPC64_NEEDED -gt 0
|
||||
then
|
||||
SDK64=10.5
|
||||
ARCHES64='-arch x86_64 -arch ppc64'
|
||||
SDK64=`ls $SDK_PATH|grep 10.5|head -1`
|
||||
else
|
||||
ARCHES64='-arch x86_64'
|
||||
#We "know" that 10.4 and earlier do not support 64bit
|
||||
OLD_SDK64=`ls $SDK_PATH|egrep -v "10.[0-4]"|head -1`
|
||||
NEW_SDK64=`ls -r $SDK_PATH|egrep -v "10.[0-4]"|head -1`
|
||||
if test $USE_OLD -gt 0
|
||||
then
|
||||
SDK64=$OLD_SDK64
|
||||
else
|
||||
SDK64=$NEW_SDK64
|
||||
fi
|
||||
fi
|
||||
|
||||
SDK64_DIR=$SDK_PATH/$SDK64
|
||||
MACVER64=`echo $SDK64|sed -e s/[a-zA-Z]//g -e s/.\$//`
|
||||
|
||||
MINVER64='-mmacosx-version-min='$MACVER64
|
||||
|
||||
if test ! -z $SDK32; then
|
||||
echo "----Configuring libcurl for 32 bit universal framework..."
|
||||
make clean
|
||||
./configure --disable-dependency-tracking --disable-static --with-gssapi --with-darwinssl \
|
||||
CFLAGS="-Os -isysroot $SDK32_DIR $ARCHES32" \
|
||||
LDFLAGS="-Wl,-syslibroot,$SDK32_DIR $ARCHES32 -Wl,-headerpad_max_install_names" \
|
||||
CC=$CC
|
||||
|
||||
echo "----Building 32 bit libcurl..."
|
||||
make -j `sysctl -n hw.logicalcpu_max`
|
||||
|
||||
echo "----Creating 32 bit framework..."
|
||||
rm -r libcurl.framework
|
||||
mkdir -p libcurl.framework/${FRAMEWORK_VERSION}/Resources
|
||||
cp lib/.libs/libcurl.dylib libcurl.framework/${FRAMEWORK_VERSION}/libcurl
|
||||
install_name_tool -id @rpath/libcurl.framework/${FRAMEWORK_VERSION}/libcurl libcurl.framework/${FRAMEWORK_VERSION}/libcurl
|
||||
/usr/bin/sed -e "s/7\.12\.3/$VERSION/" lib/libcurl.plist >libcurl.framework/${FRAMEWORK_VERSION}/Resources/Info.plist
|
||||
mkdir -p libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl
|
||||
cp include/curl/*.h libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl
|
||||
pushd libcurl.framework
|
||||
ln -fs ${FRAMEWORK_VERSION}/libcurl libcurl
|
||||
ln -fs ${FRAMEWORK_VERSION}/Resources Resources
|
||||
ln -fs ${FRAMEWORK_VERSION}/Headers Headers
|
||||
cd Versions
|
||||
ln -fs $(basename "${FRAMEWORK_VERSION}") Current
|
||||
|
||||
echo Testing for SDK64
|
||||
if test -d $SDK64_DIR; then
|
||||
echo entering...
|
||||
popd
|
||||
make clean
|
||||
echo "----Configuring libcurl for 64 bit universal framework..."
|
||||
./configure --disable-dependency-tracking --disable-static --with-gssapi --with-darwinssl \
|
||||
CFLAGS="-Os -isysroot $SDK64_DIR $ARCHES64" \
|
||||
LDFLAGS="-Wl,-syslibroot,$SDK64_DIR $ARCHES64 -Wl,-headerpad_max_install_names" \
|
||||
CC=$CC
|
||||
|
||||
echo "----Building 64 bit libcurl..."
|
||||
make -j `sysctl -n hw.logicalcpu_max`
|
||||
|
||||
echo "----Appending 64 bit framework to 32 bit framework..."
|
||||
cp lib/.libs/libcurl.dylib libcurl.framework/${FRAMEWORK_VERSION}/libcurl64
|
||||
install_name_tool -id @rpath/libcurl.framework/${FRAMEWORK_VERSION}/libcurl libcurl.framework/${FRAMEWORK_VERSION}/libcurl64
|
||||
cp libcurl.framework/${FRAMEWORK_VERSION}/libcurl libcurl.framework/${FRAMEWORK_VERSION}/libcurl32
|
||||
pwd
|
||||
lipo libcurl.framework/${FRAMEWORK_VERSION}/libcurl32 libcurl.framework/${FRAMEWORK_VERSION}/libcurl64 -create -output libcurl.framework/${FRAMEWORK_VERSION}/libcurl
|
||||
rm libcurl.framework/${FRAMEWORK_VERSION}/libcurl32 libcurl.framework/${FRAMEWORK_VERSION}/libcurl64
|
||||
cp libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl/curlbuild.h libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl/curlbuild32.h
|
||||
cp include/curl/curlbuild.h libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl/curlbuild64.h
|
||||
cat >libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl/curlbuild.h <<EOF
|
||||
#ifdef __LP64__
|
||||
#include "curl/curlbuild64.h"
|
||||
#else
|
||||
#include "curl/curlbuild32.h"
|
||||
#endif
|
||||
EOF
|
||||
fi
|
||||
|
||||
pwd
|
||||
lipo -info libcurl.framework/${FRAMEWORK_VERSION}/libcurl
|
||||
echo "libcurl.framework is built and can now be included in other projects."
|
||||
echo "Copy libcurl.framework to your bundle's Contents/Frameworks folder, ~/Library/Frameworks or /Library/Frameworks."
|
||||
else
|
||||
echo "Building libcurl.framework requires Mac OS X 10.4 or later with the MacOSX10.4/5/6 SDK installed."
|
||||
fi
|
575
curl/Makefile
Normal file
575
curl/Makefile
Normal file
@ -0,0 +1,575 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
VC=vc6
|
||||
|
||||
all:
|
||||
./configure
|
||||
make
|
||||
|
||||
ssl:
|
||||
./configure --with-ssl
|
||||
make
|
||||
|
||||
borland:
|
||||
cd lib
|
||||
$(MAKE) -f Makefile.b32
|
||||
cd ..\src
|
||||
$(MAKE) -f Makefile.b32
|
||||
|
||||
borland-ssl:
|
||||
cd lib
|
||||
$(MAKE) -f Makefile.b32 WITH_SSL=1
|
||||
cd ..\src
|
||||
$(MAKE) -f Makefile.b32 WITH_SSL=1
|
||||
|
||||
borland-ssl-zlib:
|
||||
cd lib
|
||||
$(MAKE) -f Makefile.b32 WITH_SSL=1 WITH_ZLIB=1
|
||||
cd ..\src
|
||||
$(MAKE) -f Makefile.b32 WITH_SSL=1 WITH_ZLIB=1
|
||||
|
||||
borland-clean:
|
||||
cd lib
|
||||
$(MAKE) -f Makefile.b32 clean
|
||||
cd ..\src
|
||||
$(MAKE) -f Makefile.b32 clean
|
||||
|
||||
watcom: .SYMBOLIC
|
||||
cd lib && $(MAKE) -u -f Makefile.Watcom
|
||||
cd src && $(MAKE) -u -f Makefile.Watcom
|
||||
|
||||
watcom-clean: .SYMBOLIC
|
||||
cd lib && $(MAKE) -u -f Makefile.Watcom clean
|
||||
cd src && $(MAKE) -u -f Makefile.Watcom clean
|
||||
|
||||
watcom-vclean: .SYMBOLIC
|
||||
cd lib && $(MAKE) -u -f Makefile.Watcom vclean
|
||||
cd src && $(MAKE) -u -f Makefile.Watcom vclean
|
||||
|
||||
mingw32:
|
||||
$(MAKE) -C lib -f Makefile.m32
|
||||
$(MAKE) -C src -f Makefile.m32
|
||||
|
||||
mingw32-clean:
|
||||
$(MAKE) -C lib -f Makefile.m32 clean
|
||||
$(MAKE) -C src -f Makefile.m32 clean
|
||||
$(MAKE) -C docs/examples -f Makefile.m32 clean
|
||||
|
||||
mingw32-vclean mingw32-distclean:
|
||||
$(MAKE) -C lib -f Makefile.m32 vclean
|
||||
$(MAKE) -C src -f Makefile.m32 vclean
|
||||
$(MAKE) -C docs/examples -f Makefile.m32 vclean
|
||||
|
||||
mingw32-examples%:
|
||||
$(MAKE) -C docs/examples -f Makefile.m32 CFG=$@
|
||||
|
||||
mingw32%:
|
||||
$(MAKE) -C lib -f Makefile.m32 CFG=$@
|
||||
$(MAKE) -C src -f Makefile.m32 CFG=$@
|
||||
|
||||
vc-clean: $(VC)
|
||||
cd lib
|
||||
nmake -f Makefile.$(VC) clean
|
||||
cd ..\src
|
||||
nmake -f Makefile.$(VC) clean
|
||||
|
||||
vc-all: $(VC)
|
||||
cd lib
|
||||
nmake -f Makefile.$(VC) cfg=release
|
||||
nmake -f Makefile.$(VC) cfg=release-ssl
|
||||
nmake -f Makefile.$(VC) cfg=release-zlib
|
||||
nmake -f Makefile.$(VC) cfg=release-ssl-zlib
|
||||
nmake -f Makefile.$(VC) cfg=release-ssl-dll
|
||||
nmake -f Makefile.$(VC) cfg=release-zlib-dll
|
||||
nmake -f Makefile.$(VC) cfg=release-ssl-dll-zlib-dll
|
||||
nmake -f Makefile.$(VC) cfg=release-dll
|
||||
nmake -f Makefile.$(VC) cfg=release-dll-ssl-dll
|
||||
nmake -f Makefile.$(VC) cfg=release-dll-zlib-dll
|
||||
nmake -f Makefile.$(VC) cfg=release-dll-ssl-dll-zlib-dll
|
||||
nmake -f Makefile.$(VC) cfg=debug
|
||||
nmake -f Makefile.$(VC) cfg=debug-ssl
|
||||
nmake -f Makefile.$(VC) cfg=debug-zlib
|
||||
nmake -f Makefile.$(VC) cfg=debug-ssl-zlib
|
||||
nmake -f Makefile.$(VC) cfg=debug-ssl-dll
|
||||
nmake -f Makefile.$(VC) cfg=debug-zlib-dll
|
||||
nmake -f Makefile.$(VC) cfg=debug-ssl-dll-zlib-dll
|
||||
nmake -f Makefile.$(VC) cfg=debug-dll
|
||||
nmake -f Makefile.$(VC) cfg=debug-dll-ssl-dll
|
||||
nmake -f Makefile.$(VC) cfg=debug-dll-zlib-dll
|
||||
nmake -f Makefile.$(VC) cfg=debug-dll-ssl-dll-zlib-dll
|
||||
|
||||
vc: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC)
|
||||
|
||||
vc-x64: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release
|
||||
|
||||
vc-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release WINDOWS_SSPI=1
|
||||
|
||||
vc-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release USE_IDN=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release USE_IDN=1
|
||||
|
||||
vc-x64-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release USE_IDN=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release USE_IDN=1
|
||||
|
||||
vc-idn-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-idn-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-zlib: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-zlib
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-zlib
|
||||
|
||||
vc-x64-zlib: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib
|
||||
|
||||
vc-zlib-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-zlib WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-zlib WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-zlib-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib WINDOWS_SSPI=1
|
||||
|
||||
vc-zlib-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-zlib USE_IDN=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-zlib USE_IDN=1
|
||||
|
||||
vc-x64-zlib-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib USE_IDN=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib USE_IDN=1
|
||||
|
||||
vc-zlib-idn-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-zlib-idn-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-ssl: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl
|
||||
|
||||
vc-x64-ssl: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl
|
||||
|
||||
vc-ssl-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-ssl-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl WINDOWS_SSPI=1
|
||||
|
||||
vc-ssl-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl USE_IDN=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl USE_IDN=1
|
||||
|
||||
vc-x64-ssl-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl USE_IDN=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl USE_IDN=1
|
||||
|
||||
vc-ssl-idn-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-ssl-idn-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-ssl-zlib: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-zlib
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-zlib
|
||||
|
||||
vc-x64-ssl-zlib: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
|
||||
|
||||
vc-ssl-zlib-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-zlib WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-zlib WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-ssl-zlib-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib WINDOWS_SSPI=1
|
||||
|
||||
vc-ssl-zlib-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-zlib USE_IDN=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-zlib USE_IDN=1
|
||||
|
||||
vc-x64-ssl-zlib-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib USE_IDN=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib USE_IDN=1
|
||||
|
||||
vc-ssl-zlib-idn-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-ssl-zlib-idn-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-ssl-ssh2-zlib: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib
|
||||
|
||||
vc-x64-ssl-ssh2-zlib: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib
|
||||
|
||||
vc-ssl-ssh2-zlib-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-ssl-ssh2-zlib-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib WINDOWS_SSPI=1
|
||||
|
||||
vc-ssl-ssh2-zlib-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib USE_IDN=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib USE_IDN=1
|
||||
|
||||
vc-x64-ssl-ssh2-zlib-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib USE_IDN=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib USE_IDN=1
|
||||
|
||||
vc-ssl-ssh2-zlib-idn-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-ssl-ssh2-zlib-idn-sspi: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-winssl: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-winssl WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-winssl WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-winssl: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl WINDOWS_SSPI=1
|
||||
|
||||
vc-winssl-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-winssl USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-winssl USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-winssl-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-winssl-zlib: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-winssl-zlib WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-winssl-zlib WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-winssl-zlib: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib WINDOWS_SSPI=1
|
||||
|
||||
vc-winssl-zlib-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-winssl-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-winssl-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-x64-winssl-zlib-idn: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib USE_IDN=1 WINDOWS_SSPI=1
|
||||
|
||||
vc-ssl-dll: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-dll
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-dll
|
||||
|
||||
vc-dll-ssl-dll: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-dll-ssl-dll
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-dll-ssl-dll
|
||||
|
||||
vc-dll: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-dll
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-dll
|
||||
|
||||
vc-dll-zlib-dll: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-dll-zlib-dll
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-dll-zlib-dll
|
||||
|
||||
vc-dll-ssl-dll-zlib-dll: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-dll-ssl-dll-zlib-dll
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-dll-ssl-dll-zlib-dll
|
||||
|
||||
vc-ssl-dll-zlib-dll: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-dll-zlib-dll
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-ssl-dll-zlib-dll
|
||||
|
||||
vc-zlib-dll: $(VC)
|
||||
cd lib
|
||||
nmake /f Makefile.$(VC) cfg=release-zlib-dll
|
||||
cd ..\src
|
||||
nmake /f Makefile.$(VC) cfg=release-zlib-dll
|
||||
|
||||
djgpp:
|
||||
$(MAKE) -C lib -f Makefile.dj
|
||||
$(MAKE) -C src -f Makefile.dj
|
||||
|
||||
cygwin:
|
||||
./configure
|
||||
make
|
||||
|
||||
cygwin-ssl:
|
||||
./configure --with-ssl
|
||||
make
|
||||
|
||||
amiga:
|
||||
cd ./lib && make -f makefile.amiga
|
||||
cd ./src && make -f makefile.amiga
|
||||
|
||||
netware:
|
||||
$(MAKE) -C lib -f Makefile.netware
|
||||
$(MAKE) -C src -f Makefile.netware
|
||||
|
||||
netware-clean:
|
||||
$(MAKE) -C lib -f Makefile.netware clean
|
||||
$(MAKE) -C src -f Makefile.netware clean
|
||||
$(MAKE) -C docs/examples -f Makefile.netware clean
|
||||
|
||||
netware-vclean netware-distclean:
|
||||
$(MAKE) -C lib -f Makefile.netware vclean
|
||||
$(MAKE) -C src -f Makefile.netware vclean
|
||||
$(MAKE) -C docs/examples -f Makefile.netware vclean
|
||||
|
||||
netware-install:
|
||||
$(MAKE) -C lib -f Makefile.netware install
|
||||
$(MAKE) -C src -f Makefile.netware install
|
||||
|
||||
netware-examples-%:
|
||||
$(MAKE) -C docs/examples -f Makefile.netware CFG=$@
|
||||
|
||||
netware-%:
|
||||
$(MAKE) -C lib -f Makefile.netware CFG=$@
|
||||
$(MAKE) -C src -f Makefile.netware CFG=$@
|
||||
|
||||
unix: all
|
||||
|
||||
unix-ssl: ssl
|
||||
|
||||
linux: all
|
||||
|
||||
linux-ssl: ssl
|
||||
|
||||
# We don't need to do anything for vc6.
|
||||
vc6:
|
||||
|
||||
# VC7 makefiles are for use with VS.NET and VS.NET 2003
|
||||
vc7: lib/Makefile.vc7 src/Makefile.vc7
|
||||
|
||||
lib/Makefile.vc7: lib/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s/VC6/VC7/g" lib/Makefile.vc6 > lib/Makefile.vc7
|
||||
|
||||
src/Makefile.vc7: src/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s/VC6/VC7/g" src/Makefile.vc6 > src/Makefile.vc7
|
||||
|
||||
# VC8 makefiles are for use with VS2005
|
||||
vc8: lib/Makefile.vc8 src/Makefile.vc8
|
||||
|
||||
lib/Makefile.vc8: lib/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib bufferoverflowu.lib/g" -e "s/VC6/VC8/g" lib/Makefile.vc6 > lib/Makefile.vc8
|
||||
|
||||
src/Makefile.vc8: src/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib bufferoverflowu.lib/g" -e "s/VC6/VC8/g" src/Makefile.vc6 > src/Makefile.vc8
|
||||
|
||||
# VC9 makefiles are for use with VS2008
|
||||
vc9: lib/Makefile.vc9 src/Makefile.vc9
|
||||
|
||||
lib/Makefile.vc9: lib/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc9/g" -e "s/VC6/VC9/g" lib/Makefile.vc6 > lib/Makefile.vc9
|
||||
|
||||
src/Makefile.vc9: src/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc9/g" -e "s/VC6/VC9/g" src/Makefile.vc6 > src/Makefile.vc9
|
||||
|
||||
# VC10 makefiles are for use with VS2010
|
||||
vc10: lib/Makefile.vc10 src/Makefile.vc10
|
||||
|
||||
lib/Makefile.vc10: lib/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc10/g" -e "s/VC6/VC10/g" lib/Makefile.vc6 > lib/Makefile.vc10
|
||||
|
||||
src/Makefile.vc10: src/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc10/g" -e "s/VC6/VC10/g" src/Makefile.vc6 > src/Makefile.vc10
|
||||
|
||||
# VC11 makefiles are for use with VS2012
|
||||
vc11: lib/Makefile.vc11 src/Makefile.vc11
|
||||
|
||||
lib/Makefile.vc11: lib/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc11/g" -e "s/VC6/VC11/g" lib/Makefile.vc6 > lib/Makefile.vc11
|
||||
|
||||
src/Makefile.vc11: src/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc11/g" -e "s/VC6/VC11/g" src/Makefile.vc6 > src/Makefile.vc11
|
||||
|
||||
# VC12 makefiles are for use with VS2013
|
||||
vc12: lib/Makefile.vc12 src/Makefile.vc12
|
||||
|
||||
lib/Makefile.vc12: lib/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc12/g" -e "s/VC6/VC12/g" lib/Makefile.vc6 > lib/Makefile.vc12
|
||||
|
||||
src/Makefile.vc12: src/Makefile.vc6
|
||||
@echo "generate $@"
|
||||
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc12/g" -e "s/VC6/VC12/g" src/Makefile.vc6 > src/Makefile.vc12
|
||||
|
||||
ca-bundle: lib/mk-ca-bundle.pl
|
||||
@echo "generate a fresh ca-bundle.crt"
|
||||
@perl $< -b -l -u lib/ca-bundle.crt
|
||||
|
||||
ca-firefox: lib/firefox-db2pem.sh
|
||||
@echo "generate a fresh ca-bundle.crt"
|
||||
./lib/firefox-db2pem.sh lib/ca-bundle.crt
|
533
curl/Makefile.am
Normal file
533
curl/Makefile.am
Normal file
@ -0,0 +1,533 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in \
|
||||
CMake/CurlTests.c CMake/FindGSS.cmake CMake/OtherTests.cmake \
|
||||
CMake/Platforms/WindowsCache.cmake CMake/Utilities.cmake \
|
||||
include/curl/curlbuild.h.cmake CMake/Macros.cmake
|
||||
|
||||
VC6_LIBTMPL = projects/Windows/VC6/lib/libcurl.tmpl
|
||||
VC6_LIBDSP = projects/Windows/VC6/lib/libcurl.dsp.dist
|
||||
VC6_LIBDSP_DEPS = $(VC6_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC6_SRCTMPL = projects/Windows/VC6/src/curlsrc.tmpl
|
||||
VC6_SRCDSP = projects/Windows/VC6/src/curlsrc.dsp.dist
|
||||
VC6_SRCDSP_DEPS = $(VC6_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC7_LIBTMPL = projects/Windows/VC7/lib/libcurl.tmpl
|
||||
VC7_LIBVCPROJ = projects/Windows/VC7/lib/libcurl.vcproj.dist
|
||||
VC7_LIBVCPROJ_DEPS = $(VC7_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC7_SRCTMPL = projects/Windows/VC7/src/curlsrc.tmpl
|
||||
VC7_SRCVCPROJ = projects/Windows/VC7/src/curlsrc.vcproj.dist
|
||||
VC7_SRCVCPROJ_DEPS = $(VC7_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC71_LIBTMPL = projects/Windows/VC7.1/lib/libcurl.tmpl
|
||||
VC71_LIBVCPROJ = projects/Windows/VC7.1/lib/libcurl.vcproj.dist
|
||||
VC71_LIBVCPROJ_DEPS = $(VC71_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC71_SRCTMPL = projects/Windows/VC7.1/src/curlsrc.tmpl
|
||||
VC71_SRCVCPROJ = projects/Windows/VC7.1/src/curlsrc.vcproj.dist
|
||||
VC71_SRCVCPROJ_DEPS = $(VC71_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC8_LIBTMPL = projects/Windows/VC8/lib/libcurl.tmpl
|
||||
VC8_LIBVCPROJ = projects/Windows/VC8/lib/libcurl.vcproj.dist
|
||||
VC8_LIBVCPROJ_DEPS = $(VC8_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC8_SRCTMPL = projects/Windows/VC8/src/curlsrc.tmpl
|
||||
VC8_SRCVCPROJ = projects/Windows/VC8/src/curlsrc.vcproj.dist
|
||||
VC8_SRCVCPROJ_DEPS = $(VC8_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC9_LIBTMPL = projects/Windows/VC9/lib/libcurl.tmpl
|
||||
VC9_LIBVCPROJ = projects/Windows/VC9/lib/libcurl.vcproj.dist
|
||||
VC9_LIBVCPROJ_DEPS = $(VC9_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC9_SRCTMPL = projects/Windows/VC9/src/curlsrc.tmpl
|
||||
VC9_SRCVCPROJ = projects/Windows/VC9/src/curlsrc.vcproj.dist
|
||||
VC9_SRCVCPROJ_DEPS = $(VC9_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC10_LIBTMPL = projects/Windows/VC10/lib/libcurl.tmpl
|
||||
VC10_LIBVCXPROJ = projects/Windows/VC10/lib/libcurl.vcxproj.dist
|
||||
VC10_LIBVCXPROJ_DEPS = $(VC10_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC10_SRCTMPL = projects/Windows/VC10/src/curlsrc.tmpl
|
||||
VC10_SRCVCXPROJ = projects/Windows/VC10/src/curlsrc.vcxproj.dist
|
||||
VC10_SRCVCXPROJ_DEPS = $(VC10_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC11_LIBTMPL = projects/Windows/VC11/lib/libcurl.tmpl
|
||||
VC11_LIBVCXPROJ = projects/Windows/VC11/lib/libcurl.vcxproj.dist
|
||||
VC11_LIBVCXPROJ_DEPS = $(VC11_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC11_SRCTMPL = projects/Windows/VC11/src/curlsrc.tmpl
|
||||
VC11_SRCVCXPROJ = projects/Windows/VC11/src/curlsrc.vcxproj.dist
|
||||
VC11_SRCVCXPROJ_DEPS = $(VC11_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC12_LIBTMPL = projects/Windows/VC12/lib/libcurl.tmpl
|
||||
VC12_LIBVCXPROJ = projects/Windows/VC12/lib/libcurl.vcxproj.dist
|
||||
VC12_LIBVCXPROJ_DEPS = $(VC12_LIBTMPL) Makefile.am lib/Makefile.inc
|
||||
VC12_SRCTMPL = projects/Windows/VC12/src/curlsrc.tmpl
|
||||
VC12_SRCVCXPROJ = projects/Windows/VC12/src/curlsrc.vcxproj.dist
|
||||
VC12_SRCVCXPROJ_DEPS = $(VC12_SRCTMPL) Makefile.am src/Makefile.inc
|
||||
|
||||
VC_DIST = projects/README \
|
||||
projects/build-openssl.bat \
|
||||
projects/checksrc.bat \
|
||||
projects/Windows/VC6/curl-all.dsw \
|
||||
projects/Windows/VC6/lib/libcurl.dsw \
|
||||
projects/Windows/VC6/src/curlsrc.dsw \
|
||||
projects/Windows/VC7/curl-all.sln \
|
||||
projects/Windows/VC7/lib/libcurl.sln \
|
||||
projects/Windows/VC7/src/curlsrc.sln \
|
||||
projects/Windows/VC7.1/curl-all.sln \
|
||||
projects/Windows/VC7.1/lib/libcurl.sln \
|
||||
projects/Windows/VC7.1/src/curlsrc.sln \
|
||||
projects/Windows/VC8/curl-all.sln \
|
||||
projects/Windows/VC8/lib/libcurl.sln \
|
||||
projects/Windows/VC8/src/curlsrc.sln \
|
||||
projects/Windows/VC9/curl-all.sln \
|
||||
projects/Windows/VC9/lib/libcurl.sln \
|
||||
projects/Windows/VC9/src/curlsrc.sln \
|
||||
projects/Windows/VC10/curl-all.sln \
|
||||
projects/Windows/VC10/lib/libcurl.sln \
|
||||
projects/Windows/VC10/src/curlsrc.sln \
|
||||
projects/Windows/VC11/curl-all.sln \
|
||||
projects/Windows/VC11/lib/libcurl.sln \
|
||||
projects/Windows/VC11/src/curlsrc.sln \
|
||||
projects/Windows/VC12/curl-all.sln \
|
||||
projects/Windows/VC12/lib/libcurl.sln \
|
||||
projects/Windows/VC12/src/curlsrc.sln
|
||||
|
||||
WINBUILD_DIST = winbuild/BUILD.WINDOWS.txt winbuild/gen_resp_file.bat \
|
||||
winbuild/MakefileBuild.vc winbuild/Makefile.vc \
|
||||
winbuild/Makefile.msvc.names
|
||||
|
||||
EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \
|
||||
RELEASE-NOTES buildconf libcurl.pc.in MacOSX-Framework scripts/zsh.pl \
|
||||
$(CMAKE_DIST) $(VC_DIST) $(WINBUILD_DIST) lib/libcurl.vers.in
|
||||
|
||||
CLEANFILES = $(VC6_LIBDSP) $(VC6_SRCDSP) $(VC7_LIBVCPROJ) $(VC7_SRCVCPROJ) \
|
||||
$(VC71_LIBVCPROJ) $(VC71_SRCVCPROJ) $(VC8_LIBVCPROJ) $(VC8_SRCVCPROJ) \
|
||||
$(VC9_LIBVCPROJ) $(VC9_SRCVCPROJ) $(VC10_LIBVCXPROJ) $(VC10_SRCVCXPROJ) \
|
||||
$(VC11_LIBVCXPROJ) $(VC11_SRCVCXPROJ) $(VC12_LIBVCXPROJ) $(VC12_SRCVCXPROJ)
|
||||
|
||||
bin_SCRIPTS = curl-config
|
||||
|
||||
SUBDIRS = lib src include
|
||||
DIST_SUBDIRS = $(SUBDIRS) tests packages docs
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libcurl.pc
|
||||
|
||||
# List of files required to generate VC IDE .dsp, .vcproj and .vcxproj files
|
||||
include lib/Makefile.inc
|
||||
include src/Makefile.inc
|
||||
|
||||
dist-hook:
|
||||
rm -rf $(top_builddir)/tests/log
|
||||
find $(distdir) -name "*.dist" -exec rm {} \;
|
||||
(distit=`find $(srcdir) -name "*.dist" | grep -v ./ares/`; \
|
||||
for file in $$distit; do \
|
||||
strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \
|
||||
cp $$file $(distdir)$$strip; \
|
||||
done)
|
||||
|
||||
html:
|
||||
cd docs; make html
|
||||
|
||||
pdf:
|
||||
cd docs; make pdf
|
||||
|
||||
check: test examples check-docs
|
||||
|
||||
if CROSSCOMPILING
|
||||
test-full: test
|
||||
test-torture: test
|
||||
|
||||
test:
|
||||
@echo "NOTICE: we can't run the tests when cross-compiling!"
|
||||
|
||||
else
|
||||
|
||||
test:
|
||||
@(cd tests; $(MAKE) all quiet-test)
|
||||
|
||||
test-full:
|
||||
@(cd tests; $(MAKE) all full-test)
|
||||
|
||||
test-torture:
|
||||
@(cd tests; $(MAKE) all torture-test)
|
||||
|
||||
test-am:
|
||||
@(cd tests; $(MAKE) all am-test)
|
||||
|
||||
endif
|
||||
|
||||
examples:
|
||||
@(cd docs/examples; $(MAKE) check)
|
||||
|
||||
check-docs:
|
||||
@(cd docs/libcurl; $(MAKE) check)
|
||||
|
||||
# This is a hook to have 'make clean' also clean up the docs and the tests
|
||||
# dir. The extra check for the Makefiles being present is necessary because
|
||||
# 'make distcheck' will make clean first in these directories _before_ it runs
|
||||
# this hook.
|
||||
clean-local:
|
||||
@(if test -f tests/Makefile; then cd tests; $(MAKE) clean; fi)
|
||||
@(if test -f docs/Makefile; then cd docs; $(MAKE) clean; fi)
|
||||
|
||||
#
|
||||
# Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros
|
||||
# must contain the following line:
|
||||
# %_topdir /home/loic/local/rpm
|
||||
# and that /home/loic/local/rpm contains the directory SOURCES, BUILD etc.
|
||||
#
|
||||
# cd /home/loic/local/rpm ; mkdir -p SOURCES BUILD RPMS/i386 SPECS SRPMS
|
||||
#
|
||||
# If additional configure flags are needed to build the package, add the
|
||||
# following in ~/.rpmmacros
|
||||
# %configure CFLAGS="%{optflags}" ./configure %{_target_platform} --prefix=%{_prefix} ${AM_CONFIGFLAGS}
|
||||
# and run make rpm in the following way:
|
||||
# AM_CONFIGFLAGS='--with-uri=/home/users/loic/local/RedHat-6.2' make rpm
|
||||
#
|
||||
|
||||
rpms:
|
||||
$(MAKE) RPMDIST=curl rpm
|
||||
$(MAKE) RPMDIST=curl-ssl rpm
|
||||
|
||||
rpm:
|
||||
RPM_TOPDIR=`rpm --showrc | $(PERL) -n -e 'print if(s/.*_topdir\s+(.*)/$$1/)'` ; \
|
||||
cp $(srcdir)/packages/Linux/RPM/$(RPMDIST).spec $$RPM_TOPDIR/SPECS ; \
|
||||
cp $(PACKAGE)-$(VERSION).tar.gz $$RPM_TOPDIR/SOURCES ; \
|
||||
rpm -ba --clean --rmsource $$RPM_TOPDIR/SPECS/$(RPMDIST).spec ; \
|
||||
mv $$RPM_TOPDIR/RPMS/i386/$(RPMDIST)-*.rpm . ; \
|
||||
mv $$RPM_TOPDIR/SRPMS/$(RPMDIST)-*.src.rpm .
|
||||
|
||||
#
|
||||
# Build a Solaris pkgadd format file
|
||||
# run 'make pkgadd' once you've done './configure' and 'make' to make a Solaris pkgadd format
|
||||
# file (which ends up back in this directory).
|
||||
# The pkgadd file is in 'pkgtrans' format, so to install on Solaris, do
|
||||
# pkgadd -d ./HAXXcurl-*
|
||||
#
|
||||
|
||||
# gak - libtool requires an absoulte directory, hence the pwd below...
|
||||
pkgadd:
|
||||
umask 022 ; \
|
||||
make install DESTDIR=`/bin/pwd`/packages/Solaris/root ; \
|
||||
cat COPYING > $(srcdir)/packages/Solaris/copyright ; \
|
||||
cd $(srcdir)/packages/Solaris && $(MAKE) package
|
||||
|
||||
#
|
||||
# Build a cygwin binary tarball installation file
|
||||
# resulting .tar.bz2 file will end up at packages/Win32/cygwin
|
||||
cygwinbin:
|
||||
$(MAKE) -C packages/Win32/cygwin cygwinbin
|
||||
|
||||
# We extend the standard install with a custom hook:
|
||||
install-data-hook:
|
||||
cd include && $(MAKE) install
|
||||
cd docs && $(MAKE) install
|
||||
|
||||
# We extend the standard uninstall with a custom hook:
|
||||
uninstall-hook:
|
||||
cd include && $(MAKE) uninstall
|
||||
cd docs && $(MAKE) uninstall
|
||||
|
||||
ca-bundle: lib/mk-ca-bundle.pl
|
||||
@echo "generating a fresh ca-bundle.crt"
|
||||
@perl $< -b -l -u lib/ca-bundle.crt
|
||||
|
||||
ca-firefox: lib/firefox-db2pem.sh
|
||||
@echo "generating a fresh ca-bundle.crt"
|
||||
./lib/firefox-db2pem.sh lib/ca-bundle.crt
|
||||
|
||||
checksrc:
|
||||
cd lib && $(MAKE) checksrc
|
||||
cd src && $(MAKE) checksrc
|
||||
|
||||
.PHONY: vc-ide
|
||||
|
||||
vc-ide: $(VC6_LIBDSP_DEPS) $(VC6_SRCDSP_DEPS) $(VC7_LIBVCPROJ_DEPS) \
|
||||
$(VC7_SRCVCPROJ_DEPS) $(VC71_LIBVCPROJ_DEPS) $(VC71_SRCVCPROJ_DEPS) \
|
||||
$(VC8_LIBVCPROJ_DEPS) $(VC8_SRCVCPROJ_DEPS) $(VC9_LIBVCPROJ_DEPS) \
|
||||
$(VC9_SRCVCPROJ_DEPS) $(VC10_LIBVCXPROJ_DEPS) $(VC10_SRCVCXPROJ_DEPS) \
|
||||
$(VC11_LIBVCXPROJ_DEPS) $(VC11_SRCVCXPROJ_DEPS) $(VC12_LIBVCXPROJ_DEPS) \
|
||||
$(VC12_SRCVCXPROJ_DEPS)
|
||||
@(win32_lib_srcs='$(LIB_CFILES)'; \
|
||||
win32_lib_hdrs='$(LIB_HFILES) config-win32.h'; \
|
||||
win32_lib_rc='$(LIB_RCFILES)'; \
|
||||
win32_lib_vtls_srcs='$(LIB_VTLS_CFILES)'; \
|
||||
win32_lib_vtls_hdrs='$(LIB_VTLS_HFILES)'; \
|
||||
win32_src_srcs='$(CURL_CFILES)'; \
|
||||
win32_src_hdrs='$(CURL_HFILES)'; \
|
||||
win32_src_rc='$(CURL_RCFILES)'; \
|
||||
win32_src_x_srcs='$(CURLX_CFILES)'; \
|
||||
win32_src_x_hdrs='$(CURLX_HFILES) ../lib/config-win32.h'; \
|
||||
\
|
||||
sorted_lib_srcs=`for file in $$win32_lib_srcs; do echo $$file; done | sort`; \
|
||||
sorted_lib_hdrs=`for file in $$win32_lib_hdrs; do echo $$file; done | sort`; \
|
||||
sorted_lib_vtls_srcs=`for file in $$win32_lib_vtls_srcs; do echo $$file; done | sort`; \
|
||||
sorted_lib_vtls_hdrs=`for file in $$win32_lib_vtls_hdrs; do echo $$file; done | sort`; \
|
||||
sorted_src_srcs=`for file in $$win32_src_srcs; do echo $$file; done | sort`; \
|
||||
sorted_src_hdrs=`for file in $$win32_src_hdrs; do echo $$file; done | sort`; \
|
||||
sorted_src_x_srcs=`for file in $$win32_src_x_srcs; do echo $$file; done | sort`; \
|
||||
sorted_src_x_hdrs=`for file in $$win32_src_x_hdrs; do echo $$file; done | sort`; \
|
||||
\
|
||||
awk_code='\
|
||||
function gen_element(type, dir, file)\
|
||||
{\
|
||||
sub(/vtls\//, "", file);\
|
||||
\
|
||||
spaces=" ";\
|
||||
if(dir == "lib\\vtls")\
|
||||
tabs=" ";\
|
||||
else\
|
||||
tabs=" ";\
|
||||
\
|
||||
if(type == "dsp") {\
|
||||
printf("# Begin Source File\r\n");\
|
||||
printf("\r\n");\
|
||||
printf("SOURCE=..\\..\\..\\..\\%s\\%s\r\n", dir, file);\
|
||||
printf("# End Source File\r\n");\
|
||||
}\
|
||||
else if(type == "vcproj1") {\
|
||||
printf("%s<File\r\n", tabs);\
|
||||
printf("%s RelativePath=\"..\\..\\..\\..\\%s\\%s\">\r\n",\
|
||||
tabs, dir, file);\
|
||||
printf("%s</File>\r\n", tabs);\
|
||||
}\
|
||||
else if(type == "vcproj2") {\
|
||||
printf("%s<File\r\n", tabs);\
|
||||
printf("%s RelativePath=\"..\\..\\..\\..\\%s\\%s\"\r\n",\
|
||||
tabs, dir, file);\
|
||||
printf("%s>\r\n", tabs);\
|
||||
printf("%s</File>\r\n", tabs);\
|
||||
}\
|
||||
else if(type == "vcxproj") {\
|
||||
i = index(file, ".");\
|
||||
ext = substr(file, i == 0 ? 0 : i + 1);\
|
||||
\
|
||||
if(ext == "c")\
|
||||
printf("%s<ClCompile Include=\"..\\..\\..\\..\\%s\\%s\" />\r\n",\
|
||||
spaces, dir, file);\
|
||||
else if(ext == "h")\
|
||||
printf("%s<ClInclude Include=\"..\\..\\..\\..\\%s\\%s\" />\r\n",\
|
||||
spaces, dir, file);\
|
||||
else if(ext == "rc")\
|
||||
printf("%s<ResourceCompile Include=\"..\\..\\..\\..\\%s\\%s\" />\r\n",\
|
||||
spaces, dir, file);\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
{\
|
||||
\
|
||||
if($$0 == "CURL_LIB_C_FILES") {\
|
||||
split(lib_srcs, arr);\
|
||||
for(val in arr) gen_element(proj_type, "lib", arr[val]);\
|
||||
}\
|
||||
else if($$0 == "CURL_LIB_H_FILES") {\
|
||||
split(lib_hdrs, arr);\
|
||||
for(val in arr) gen_element(proj_type, "lib", arr[val]);\
|
||||
}\
|
||||
else if($$0 == "CURL_LIB_RC_FILES") {\
|
||||
split(lib_rc, arr);\
|
||||
for(val in arr) gen_element(proj_type, "lib", arr[val]);\
|
||||
}\
|
||||
else if($$0 == "CURL_LIB_VTLS_C_FILES") {\
|
||||
split(lib_vtls_srcs, arr);\
|
||||
for(val in arr) gen_element(proj_type, "lib\\vtls", arr[val]);\
|
||||
}\
|
||||
else if($$0 == "CURL_LIB_VTLS_H_FILES") {\
|
||||
split(lib_vtls_hdrs, arr);\
|
||||
for(val in arr) gen_element(proj_type, "lib\\vtls", arr[val]);\
|
||||
}\
|
||||
else if($$0 == "CURL_SRC_C_FILES") {\
|
||||
split(src_srcs, arr);\
|
||||
for(val in arr) gen_element(proj_type, "src", arr[val]);\
|
||||
}\
|
||||
else if($$0 == "CURL_SRC_H_FILES") {\
|
||||
split(src_hdrs, arr);\
|
||||
for(val in arr) gen_element(proj_type, "src", arr[val]);\
|
||||
}\
|
||||
else if($$0 == "CURL_SRC_RC_FILES") {\
|
||||
split(src_rc, arr);\
|
||||
for(val in arr) gen_element(proj_type, "src", arr[val]);\
|
||||
}\
|
||||
else if($$0 == "CURL_SRC_X_C_FILES") {\
|
||||
split(src_x_srcs, arr);\
|
||||
for(val in arr) {\
|
||||
sub(/..\/lib\//, "", arr[val]);\
|
||||
gen_element(proj_type, "lib", arr[val]);\
|
||||
}\
|
||||
}\
|
||||
else if($$0 == "CURL_SRC_X_H_FILES") {\
|
||||
split(src_x_hdrs, arr);\
|
||||
for(val in arr) {\
|
||||
sub(/..\/lib\//, "", arr[val]);\
|
||||
gen_element(proj_type, "lib", arr[val]);\
|
||||
}\
|
||||
}\
|
||||
else\
|
||||
printf("%s\r\n", $$0);\
|
||||
}';\
|
||||
\
|
||||
echo "generating '$(VC6_LIBDSP)'"; \
|
||||
awk -v proj_type=dsp \
|
||||
-v lib_srcs="$$sorted_lib_srcs" \
|
||||
-v lib_hdrs="$$sorted_lib_hdrs" \
|
||||
-v lib_rc="$$win32_lib_rc" \
|
||||
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
|
||||
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC6_LIBTMPL) > $(VC6_LIBDSP) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC6_SRCDSP)'"; \
|
||||
awk -v proj_type=dsp \
|
||||
-v src_srcs="$$sorted_src_srcs" \
|
||||
-v src_hdrs="$$sorted_src_hdrs" \
|
||||
-v src_rc="$$win32_src_rc" \
|
||||
-v src_x_srcs="$$sorted_src_x_srcs" \
|
||||
-v src_x_hdrs="$$sorted_src_x_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC6_SRCTMPL) > $(VC6_SRCDSP) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC7_LIBVCPROJ)'"; \
|
||||
awk -v proj_type=vcproj1 \
|
||||
-v lib_srcs="$$sorted_lib_srcs" \
|
||||
-v lib_hdrs="$$sorted_lib_hdrs" \
|
||||
-v lib_rc="$$win32_lib_rc" \
|
||||
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
|
||||
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC7_LIBTMPL) > $(VC7_LIBVCPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC7_SRCVCPROJ)'"; \
|
||||
awk -v proj_type=vcproj1 \
|
||||
-v src_srcs="$$sorted_src_srcs" \
|
||||
-v src_hdrs="$$sorted_src_hdrs" \
|
||||
-v src_rc="$$win32_src_rc" \
|
||||
-v src_x_srcs="$$sorted_src_x_srcs" \
|
||||
-v src_x_hdrs="$$sorted_src_x_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC7_SRCTMPL) > $(VC7_SRCVCPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC71_LIBVCPROJ)'"; \
|
||||
awk -v proj_type=vcproj1 \
|
||||
-v lib_srcs="$$sorted_lib_srcs" \
|
||||
-v lib_hdrs="$$sorted_lib_hdrs" \
|
||||
-v lib_rc="$$win32_lib_rc" \
|
||||
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
|
||||
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC71_LIBTMPL) > $(VC71_LIBVCPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC71_SRCVCPROJ)'"; \
|
||||
awk -v proj_type=vcproj1 \
|
||||
-v src_srcs="$$sorted_src_srcs" \
|
||||
-v src_hdrs="$$sorted_src_hdrs" \
|
||||
-v src_rc="$$win32_src_rc" \
|
||||
-v src_x_srcs="$$sorted_src_x_srcs" \
|
||||
-v src_x_hdrs="$$sorted_src_x_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC71_SRCTMPL) > $(VC71_SRCVCPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC8_LIBVCPROJ)'"; \
|
||||
awk -v proj_type=vcproj2 \
|
||||
-v lib_srcs="$$sorted_lib_srcs" \
|
||||
-v lib_hdrs="$$sorted_lib_hdrs" \
|
||||
-v lib_rc="$$win32_lib_rc" \
|
||||
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
|
||||
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC8_LIBTMPL) > $(VC8_LIBVCPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC8_SRCVCPROJ)'"; \
|
||||
awk -v proj_type=vcproj2 \
|
||||
-v src_srcs="$$sorted_src_srcs" \
|
||||
-v src_hdrs="$$sorted_src_hdrs" \
|
||||
-v src_rc="$$win32_src_rc" \
|
||||
-v src_x_srcs="$$sorted_src_x_srcs" \
|
||||
-v src_x_hdrs="$$sorted_src_x_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC8_SRCTMPL) > $(VC8_SRCVCPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC9_LIBVCPROJ)'"; \
|
||||
awk -v proj_type=vcproj2 \
|
||||
-v lib_srcs="$$sorted_lib_srcs" \
|
||||
-v lib_hdrs="$$sorted_lib_hdrs" \
|
||||
-v lib_rc="$$win32_lib_rc" \
|
||||
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
|
||||
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC9_LIBTMPL) > $(VC9_LIBVCPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC9_SRCVCPROJ)'"; \
|
||||
awk -v proj_type=vcproj2 \
|
||||
-v src_srcs="$$sorted_src_srcs" \
|
||||
-v src_hdrs="$$sorted_src_hdrs" \
|
||||
-v src_rc="$$win32_src_rc" \
|
||||
-v src_x_srcs="$$sorted_src_x_srcs" \
|
||||
-v src_x_hdrs="$$sorted_src_x_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC9_SRCTMPL) > $(VC9_SRCVCPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC10_LIBVCXPROJ)'"; \
|
||||
awk -v proj_type=vcxproj \
|
||||
-v lib_srcs="$$sorted_lib_srcs" \
|
||||
-v lib_hdrs="$$sorted_lib_hdrs" \
|
||||
-v lib_rc="$$win32_lib_rc" \
|
||||
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
|
||||
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC10_LIBTMPL) > $(VC10_LIBVCXPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC10_SRCVCXPROJ)'"; \
|
||||
awk -v proj_type=vcxproj \
|
||||
-v src_srcs="$$sorted_src_srcs" \
|
||||
-v src_hdrs="$$sorted_src_hdrs" \
|
||||
-v src_rc="$$win32_src_rc" \
|
||||
-v src_x_srcs="$$sorted_src_x_srcs" \
|
||||
-v src_x_hdrs="$$sorted_src_x_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC10_SRCTMPL) > $(VC10_SRCVCXPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC11_LIBVCXPROJ)'"; \
|
||||
awk -v proj_type=vcxproj \
|
||||
-v lib_srcs="$$sorted_lib_srcs" \
|
||||
-v lib_hdrs="$$sorted_lib_hdrs" \
|
||||
-v lib_rc="$$win32_lib_rc" \
|
||||
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
|
||||
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC11_LIBTMPL) > $(VC11_LIBVCXPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC11_SRCVCXPROJ)'"; \
|
||||
awk -v proj_type=vcxproj \
|
||||
-v src_srcs="$$sorted_src_srcs" \
|
||||
-v src_hdrs="$$sorted_src_hdrs" \
|
||||
-v src_rc="$$win32_src_rc" \
|
||||
-v src_x_srcs="$$sorted_src_x_srcs" \
|
||||
-v src_x_hdrs="$$sorted_src_x_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC11_SRCTMPL) > $(VC11_SRCVCXPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC12_LIBVCXPROJ)'"; \
|
||||
awk -v proj_type=vcxproj \
|
||||
-v lib_srcs="$$sorted_lib_srcs" \
|
||||
-v lib_hdrs="$$sorted_lib_hdrs" \
|
||||
-v lib_rc="$$win32_lib_rc" \
|
||||
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
|
||||
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC12_LIBTMPL) > $(VC12_LIBVCXPROJ) || { exit 1; }; \
|
||||
\
|
||||
echo "generating '$(VC12_SRCVCXPROJ)'"; \
|
||||
awk -v proj_type=vcxproj \
|
||||
-v src_srcs="$$sorted_src_srcs" \
|
||||
-v src_hdrs="$$sorted_src_hdrs" \
|
||||
-v src_rc="$$win32_src_rc" \
|
||||
-v src_x_srcs="$$sorted_src_x_srcs" \
|
||||
-v src_x_hdrs="$$sorted_src_x_hdrs" \
|
||||
"$$awk_code" $(srcdir)/$(VC12_SRCTMPL) > $(VC12_SRCVCXPROJ) || { exit 1; };)
|
1664
curl/Makefile.in
Normal file
1664
curl/Makefile.in
Normal file
File diff suppressed because it is too large
Load Diff
49
curl/README
Normal file
49
curl/README
Normal file
@ -0,0 +1,49 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
README
|
||||
|
||||
Curl is a command line tool for transferring data specified with URL
|
||||
syntax. Find out how to use curl by reading the curl.1 man page or the
|
||||
MANUAL document. Find out how to install Curl by reading the INSTALL
|
||||
document.
|
||||
|
||||
libcurl is the library curl is using to do its job. It is readily
|
||||
available to be used by your software. Read the libcurl.3 man page to
|
||||
learn how!
|
||||
|
||||
You find answers to the most frequent questions we get in the FAQ document.
|
||||
|
||||
Study the COPYING file for distribution terms and similar. If you distribute
|
||||
curl binaries or other binaries that involve libcurl, you might enjoy the
|
||||
LICENSE-MIXING document.
|
||||
|
||||
CONTACT
|
||||
|
||||
If you have problems, questions, ideas or suggestions, please contact us
|
||||
by posting to a suitable mailing list. See http://curl.haxx.se/mail/
|
||||
|
||||
All contributors to the project are listed in the THANKS document.
|
||||
|
||||
WEB SITE
|
||||
|
||||
Visit the curl web site for the latest news and downloads:
|
||||
|
||||
http://curl.haxx.se/
|
||||
|
||||
GIT
|
||||
|
||||
To download the very latest source off the GIT server do this:
|
||||
|
||||
git clone https://github.com/bagder/curl.git
|
||||
|
||||
(you'll get a directory named curl created, filled with the source code)
|
||||
|
||||
NOTICE
|
||||
|
||||
Curl contains pieces of source code that is Copyright (c) 1998, 1999
|
||||
Kungliga Tekniska Högskolan. This notice is included here to comply with the
|
||||
distribution terms.
|
145
curl/RELEASE-NOTES
Normal file
145
curl/RELEASE-NOTES
Normal file
@ -0,0 +1,145 @@
|
||||
Curl and libcurl 7.43.0
|
||||
|
||||
Public curl releases: 147
|
||||
Command line options: 176
|
||||
curl_easy_setopt() options: 219
|
||||
Public functions in libcurl: 58
|
||||
Contributors: 1291
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o Added CURLOPT_PROXY_SERVICE_NAME[11]
|
||||
o Added CURLOPT_SERVICE_NAME[12]
|
||||
o New curl option: --proxy-service-name[13]
|
||||
o Mew curl option: --service-name [14]
|
||||
o New curl option: --data-raw [5]
|
||||
o Added CURLOPT_PIPEWAIT [15]
|
||||
o Added support for multiplexing transfers using HTTP/2, enable this
|
||||
with the new CURLPIPE_MULTIPLEX bit for CURLMOPT_PIPELINING [16]
|
||||
o HTTP/2: requires nghttp2 1.0.0 or later
|
||||
o scripts: add zsh.pl for generating zsh completion
|
||||
o curl.h: add CURL_HTTP_VERSION_2
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o CVE-2015-3236: lingering HTTP credentials in connection re-use [30]
|
||||
o CVE-2015-3237: SMB send off unrelated memory contents [31]
|
||||
o nss: fix compilation failure with old versions of NSS [1]
|
||||
o curl_easy_getinfo.3: document 'internals' in CURLINFO_TLS_SESSION
|
||||
o schannel.c: Fix possible SEC_E_BUFFER_TOO_SMALL error
|
||||
o Curl_ossl_init: load builtin modules [2]
|
||||
o configure: follow-up fix for krb5-config [3]
|
||||
o sasl_sspi: Populate domain from the realm in the challenge [4]
|
||||
o netrc: support 'default' token
|
||||
o README: convert to UTF-8
|
||||
o cyassl: Implement public key pinning
|
||||
o nss: implement public key pinning for NSS backend
|
||||
o mingw build: add arch -m32/-m64 to LDFLAGS
|
||||
o schannel: Fix out of bounds array [6]
|
||||
o configure: remove autogenerated files by autoconf
|
||||
o configure: remove --automake from libtoolize call
|
||||
o acinclude.m4: fix shell test for default CA cert bundle/path
|
||||
o schannel: fix regression in schannel_recv [7]
|
||||
o openssl: skip trace outputs for ssl_ver == 0 [8]
|
||||
o gnutls: properly retrieve certificate status
|
||||
o netrc: Read in text mode when cygwin [9]
|
||||
o winbuild: Document the option used to statically link the CRT [10]
|
||||
o FTP: Make EPSV use the control IP address rather than the original host
|
||||
o FTP: fix dangling conn->ip_addr dereference on verbose EPSV
|
||||
o conncache: keep bundles on host+port bases, not only host names
|
||||
o runtests.pl: use 'h2c' now, no -14 anymore
|
||||
o curlver: introducing new version number (checking) macros
|
||||
o openssl: boringssl build brekage, use SSL_CTX_set_msg_callback [17]
|
||||
o CURLOPT_POSTFIELDS.3: correct variable names [18]
|
||||
o curl_easy_unescape.3: update RFC reference [19]
|
||||
o gnutls: don't fail on non-fatal alerts during handshake
|
||||
o testcurl.pl: allow source to be in an arbitrary directory
|
||||
o CURLOPT_HTTPPROXYTUNNEL.3: only works with a HTTP proxy
|
||||
o SSPI-error: Change SEC_E_ILLEGAL_MESSAGE description [20]
|
||||
o parse_proxy: switch off tunneling if non-HTTP proxy [21]
|
||||
o share_init: fix OOM crash
|
||||
o perl: remove subdir, not touched in 9 years
|
||||
o CURLOPT_COOKIELIST.3: Add example
|
||||
o CURLOPT_COOKIE.3: Explain that the cookies won't be modified [22]
|
||||
o CURLOPT_COOKIELIST.3: Explain Set-Cookie without a domain [23]
|
||||
o FAQ: How do I port libcurl to my OS?
|
||||
o openssl: Use TLS_client_method for OpenSSL 1.1.0+
|
||||
o HTTP-NTLM: fail auth on connection close instead of looping [24]
|
||||
o curl_setup: Add macros for FOPEN_READTEXT, FOPEN_WRITETEXT [25]
|
||||
o curl_getdate.3: update RFC reference
|
||||
o curl_multi_info_read.3: added example
|
||||
o curl_multi_perform.3: added example
|
||||
o curl_multi_timeout.3: added example
|
||||
o cookie: Stop exporting any-domain cookies [26]
|
||||
o openssl: remove dummy callback use from SSL_CTX_set_verify()
|
||||
o openssl: remove SSL_get_session()-using code
|
||||
o openssl: removed USERDATA_IN_PWD_CALLBACK kludge
|
||||
o openssl: removed error string #ifdef
|
||||
o openssl: Fix verification of server-sent legacy intermediates [27]
|
||||
o docs: man page indentation and syntax fixes
|
||||
o docs: Spelling fixes
|
||||
o fopen.c: fix a few compiler warnings
|
||||
o CURLOPT_OPENSOCKETFUNCTION: return error at once [28]
|
||||
o schannel: Add support for optional client certificates
|
||||
o build: Properly detect OpenSSL 1.0.2 when using configure
|
||||
o urldata: store POST size in state.infilesize too [29]
|
||||
o security:choose_mech remove dead code
|
||||
o rtsp_do: remove dead code
|
||||
o docs: many HTTP URIs changed to HTTPS
|
||||
o schannel: schannel_recv overhaul [32]
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
o see docs/KNOWN_BUGS (http://curl.haxx.se/docs/knownbugs.html)
|
||||
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Alessandro Ghedini, Alexander Dyagilev, Anders Bakken, Anthony Avina,
|
||||
Ashish Shukla, Bert Huijben, Brian Chrisman, Brian Prodoehl, Chris Araman,
|
||||
Dagobert Michelsen, Dan Fandrich, Daniel Melani, Daniel Stenberg,
|
||||
Dmitry Eremin-Solenikov, Drake Arconis, Egon Eckert, Frank Meier, Fred Stluka,
|
||||
Gisle Vanem, Grant Pannell, Isaac Boukris, Jens Rantil, Joel Depooter,
|
||||
Kamil Dudka, Linus Nielsen Feltzing, Linus Nielsen Feltzing Feltzing,
|
||||
Liviu Chircu, Marc Hoersken, Michael Osipov, Oren Souroujon, Orgad Shaneh,
|
||||
Patrick Monnerat, Patrick Rapin, Paul Howarth, Paul Oliver, Rafayel Mkrtchyan,
|
||||
Ray Satiro, Sean Boudreau, Tatsuhiro Tsujikawa, Tomas Tomecek, Viktor Szakáts,
|
||||
Ville Skyttä, Yehezkel Horowitz,
|
||||
(43 contributors)
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
||||
References to bug reports and discussions on issues:
|
||||
|
||||
[1] = http://curl.haxx.se/mail/lib-2015-04/0095.html
|
||||
[2] = https://github.com/bagder/curl/pull/206
|
||||
[3] = https://github.com/bagder/curl/commit/5b668606527613179d0349f21b4ab0df2971e3d2#commitcomment-10473445
|
||||
[4] = https://github.com/bagder/curl/pull/141
|
||||
[5] = https://github.com/bagder/curl/issues/198
|
||||
[6] = http://curl.haxx.se/mail/lib-2015-04/0199.html
|
||||
[7] = https://github.com/bagder/curl/issues/244
|
||||
[8] = https://github.com/bagder/curl/issues/219
|
||||
[9] = https://github.com/bagder/curl/pull/258
|
||||
[10] = https://github.com/bagder/curl/issues/254
|
||||
[11] = http://curl.haxx.se/libcurl/c/CURLOPT_PROXY_SERVICE_NAME.html
|
||||
[12] = http://curl.haxx.se/libcurl/c/CURLOPT_SERVICE_NAME.html
|
||||
[13] = http://curl.haxx.se/docs/manpage.html#--proxy-service-name
|
||||
[14] = http://curl.haxx.se/docs/manpage.html#--service-name
|
||||
[15] = http://curl.haxx.se/libcurl/c/CURLOPT_PIPEWAIT.html
|
||||
[16] = http://curl.haxx.se/libcurl/c/CURLMOPT_PIPELINING.html
|
||||
[17] = https://github.com/bagder/curl/issues/275
|
||||
[18] = https://github.com/bagder/curl/issues/281
|
||||
[19] = https://github.com/bagder/curl/issues/282
|
||||
[20] = https://github.com/bagder/curl/issues/267
|
||||
[21] = http://curl.haxx.se/mail/lib-2015-05/0056.html
|
||||
[22] = http://curl.haxx.se/mail/lib-2015-05/0115.html
|
||||
[23] = http://curl.haxx.se/mail/lib-2015-05/0137.html
|
||||
[24] = https://github.com/bagder/curl/issues/256
|
||||
[25] = https://github.com/bagder/curl/pull/258#issuecomment-107093055
|
||||
[26] = https://github.com/bagder/curl/issues/292
|
||||
[27] = https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
|
||||
[28] = http://curl.haxx.se/mail/lib-2015-06/0047.html
|
||||
[29] = http://curl.haxx.se/mail/lib-2015-06/0019.html
|
||||
[30] = http://curl.haxx.se/docs/adv_20150617A.html
|
||||
[31] = http://curl.haxx.se/docs/adv_20150617B.html
|
||||
[32] = https://github.com/bagder/curl/issues/244
|
3113
curl/acinclude.m4
Normal file
3113
curl/acinclude.m4
Normal file
File diff suppressed because it is too large
Load Diff
1205
curl/aclocal.m4
vendored
Normal file
1205
curl/aclocal.m4
vendored
Normal file
File diff suppressed because it is too large
Load Diff
449
curl/buildconf
Executable file
449
curl/buildconf
Executable file
@ -0,0 +1,449 @@
|
||||
#!/bin/sh
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# die prints argument string to stdout and exits this shell script.
|
||||
#
|
||||
die(){
|
||||
echo "buildconf: $@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# findtool works as 'which' but we use a different name to make it more
|
||||
# obvious we aren't using 'which'! ;-)
|
||||
# Unlike 'which' does, the current directory is ignored.
|
||||
#
|
||||
findtool(){
|
||||
file="$1"
|
||||
|
||||
if { echo "$file" | grep "/" >/dev/null 2>&1; } then
|
||||
# when file is given with a path check it first
|
||||
if test -f "$file"; then
|
||||
echo "$file"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
old_IFS=$IFS; IFS=':'
|
||||
for path in $PATH
|
||||
do
|
||||
IFS=$old_IFS
|
||||
# echo "checks for $file in $path" >&2
|
||||
if test "$path" -a "$path" != '.' -a -f "$path/$file"; then
|
||||
echo "$path/$file"
|
||||
return
|
||||
fi
|
||||
done
|
||||
IFS=$old_IFS
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# removethis() removes all files and subdirectories with the given name,
|
||||
# inside and below the current subdirectory at invocation time.
|
||||
#
|
||||
removethis(){
|
||||
if test "$#" = "1"; then
|
||||
find . -depth -name $1 -print > buildconf.tmp.$$
|
||||
while read fdname
|
||||
do
|
||||
if test -f "$fdname"; then
|
||||
rm -f "$fdname"
|
||||
elif test -d "$fdname"; then
|
||||
rm -f -r "$fdname"
|
||||
fi
|
||||
done < buildconf.tmp.$$
|
||||
rm -f buildconf.tmp.$$
|
||||
fi
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Ensure that buildconf runs from the subdirectory where configure.ac lives
|
||||
#
|
||||
if test ! -f configure.ac ||
|
||||
test ! -f src/tool_main.c ||
|
||||
test ! -f lib/urldata.h ||
|
||||
test ! -f include/curl/curl.h ||
|
||||
test ! -f m4/curl-functions.m4; then
|
||||
echo "Can not run buildconf from outside of curl's source subdirectory!"
|
||||
echo "Change to the subdirectory where buildconf is found, and try again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# autoconf 2.57 or newer. Unpatched version 2.67 does not generate proper
|
||||
# configure script. Unpatched version 2.68 is simply unusable, we should
|
||||
# disallow 2.68 usage.
|
||||
#
|
||||
need_autoconf="2.57"
|
||||
ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|head -n 1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
||||
if test -z "$ac_version"; then
|
||||
echo "buildconf: autoconf not found."
|
||||
echo " You need autoconf version $need_autoconf or newer installed."
|
||||
exit 1
|
||||
fi
|
||||
old_IFS=$IFS; IFS='.'; set $ac_version; IFS=$old_IFS
|
||||
if test "$1" = "2" -a "$2" -lt "57" || test "$1" -lt "2"; then
|
||||
echo "buildconf: autoconf version $ac_version found."
|
||||
echo " You need autoconf version $need_autoconf or newer installed."
|
||||
echo " If you have a sufficient autoconf installed, but it"
|
||||
echo " is not named 'autoconf', then try setting the"
|
||||
echo " AUTOCONF environment variable."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "$1" = "2" -a "$2" -eq "67"; then
|
||||
echo "buildconf: autoconf version $ac_version (BAD)"
|
||||
echo " Unpatched version generates broken configure script."
|
||||
elif test "$1" = "2" -a "$2" -eq "68"; then
|
||||
echo "buildconf: autoconf version $ac_version (BAD)"
|
||||
echo " Unpatched version generates unusable configure script."
|
||||
else
|
||||
echo "buildconf: autoconf version $ac_version (ok)"
|
||||
fi
|
||||
|
||||
am4te_version=`${AUTOM4TE:-autom4te} --version 2>/dev/null|head -n 1| sed -e 's/autom4te\(.*\)/\1/' -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
||||
if test -z "$am4te_version"; then
|
||||
echo "buildconf: autom4te not found. Weird autoconf installation!"
|
||||
exit 1
|
||||
fi
|
||||
if test "$am4te_version" = "$ac_version"; then
|
||||
echo "buildconf: autom4te version $am4te_version (ok)"
|
||||
else
|
||||
echo "buildconf: autom4te version $am4te_version (ERROR: does not match autoconf version)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# autoheader 2.50 or newer
|
||||
#
|
||||
ah_version=`${AUTOHEADER:-autoheader} --version 2>/dev/null|head -n 1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
||||
if test -z "$ah_version"; then
|
||||
echo "buildconf: autoheader not found."
|
||||
echo " You need autoheader version 2.50 or newer installed."
|
||||
exit 1
|
||||
fi
|
||||
old_IFS=$IFS; IFS='.'; set $ah_version; IFS=$old_IFS
|
||||
if test "$1" = "2" -a "$2" -lt "50" || test "$1" -lt "2"; then
|
||||
echo "buildconf: autoheader version $ah_version found."
|
||||
echo " You need autoheader version 2.50 or newer installed."
|
||||
echo " If you have a sufficient autoheader installed, but it"
|
||||
echo " is not named 'autoheader', then try setting the"
|
||||
echo " AUTOHEADER environment variable."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "buildconf: autoheader version $ah_version (ok)"
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# automake 1.7 or newer
|
||||
#
|
||||
need_automake="1.7"
|
||||
am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|head -n 1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'`
|
||||
if test -z "$am_version"; then
|
||||
echo "buildconf: automake not found."
|
||||
echo " You need automake version $need_automake or newer installed."
|
||||
exit 1
|
||||
fi
|
||||
old_IFS=$IFS; IFS='.'; set $am_version; IFS=$old_IFS
|
||||
if test "$1" = "1" -a "$2" -lt "7" || test "$1" -lt "1"; then
|
||||
echo "buildconf: automake version $am_version found."
|
||||
echo " You need automake version $need_automake or newer installed."
|
||||
echo " If you have a sufficient automake installed, but it"
|
||||
echo " is not named 'automake', then try setting the"
|
||||
echo " AUTOMAKE environment variable."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "buildconf: automake version $am_version (ok)"
|
||||
|
||||
acloc_version=`${ACLOCAL:-aclocal} --version 2>/dev/null|head -n 1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'`
|
||||
if test -z "$acloc_version"; then
|
||||
echo "buildconf: aclocal not found. Weird automake installation!"
|
||||
exit 1
|
||||
fi
|
||||
if test "$acloc_version" = "$am_version"; then
|
||||
echo "buildconf: aclocal version $acloc_version (ok)"
|
||||
else
|
||||
echo "buildconf: aclocal version $acloc_version (ERROR: does not match automake version)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# GNU libtoolize preliminary check
|
||||
#
|
||||
want_lt_major=1
|
||||
want_lt_minor=4
|
||||
want_lt_patch=2
|
||||
want_lt_version=1.4.2
|
||||
|
||||
# This approach that tries 'glibtoolize' first is intended for systems that
|
||||
# have GNU libtool named as 'glibtoolize' and libtoolize not being GNU's.
|
||||
|
||||
libtoolize=`findtool glibtoolize 2>/dev/null`
|
||||
if test ! -x "$libtoolize"; then
|
||||
libtoolize=`findtool ${LIBTOOLIZE:-libtoolize}`
|
||||
fi
|
||||
if test -z "$libtoolize"; then
|
||||
echo "buildconf: libtoolize not found."
|
||||
echo " You need GNU libtoolize $want_lt_version or newer installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
lt_pver=`$libtoolize --version 2>/dev/null|head -n 1`
|
||||
lt_qver=`echo $lt_pver|sed -e "s/([^)]*)//g" -e "s/^[^0-9]*//g"`
|
||||
lt_version=`echo $lt_qver|sed -e "s/[- ].*//" -e "s/\([a-z]*\)$//"`
|
||||
if test -z "$lt_version"; then
|
||||
echo "buildconf: libtoolize not found."
|
||||
echo " You need GNU libtoolize $want_lt_version or newer installed."
|
||||
exit 1
|
||||
fi
|
||||
old_IFS=$IFS; IFS='.'; set $lt_version; IFS=$old_IFS
|
||||
lt_major=$1
|
||||
lt_minor=$2
|
||||
lt_patch=$3
|
||||
|
||||
if test -z "$lt_major"; then
|
||||
lt_status="bad"
|
||||
elif test "$lt_major" -gt "$want_lt_major"; then
|
||||
lt_status="good"
|
||||
elif test "$lt_major" -lt "$want_lt_major"; then
|
||||
lt_status="bad"
|
||||
elif test -z "$lt_minor"; then
|
||||
lt_status="bad"
|
||||
elif test "$lt_minor" -gt "$want_lt_minor"; then
|
||||
lt_status="good"
|
||||
elif test "$lt_minor" -lt "$want_lt_minor"; then
|
||||
lt_status="bad"
|
||||
elif test -z "$lt_patch"; then
|
||||
lt_status="bad"
|
||||
elif test "$lt_patch" -gt "$want_lt_patch"; then
|
||||
lt_status="good"
|
||||
elif test "$lt_patch" -lt "$want_lt_patch"; then
|
||||
lt_status="bad"
|
||||
else
|
||||
lt_status="good"
|
||||
fi
|
||||
if test "$lt_status" != "good"; then
|
||||
echo "buildconf: libtoolize version $lt_version found."
|
||||
echo " You need GNU libtoolize $want_lt_version or newer installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "buildconf: libtoolize version $lt_version (ok)"
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# m4 check
|
||||
#
|
||||
m4=`(${M4:-m4} --version || ${M4:-gm4} --version) 2>/dev/null | head -n 1`;
|
||||
m4_version=`echo $m4 | sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'`
|
||||
|
||||
if { echo $m4 | grep "GNU" >/dev/null 2>&1; } then
|
||||
echo "buildconf: GNU m4 version $m4_version (ok)"
|
||||
else
|
||||
if test -z "$m4"; then
|
||||
echo "buildconf: m4 version not recognized. You need a GNU m4 installed!"
|
||||
else
|
||||
echo "buildconf: m4 version $m4 found. You need a GNU m4 installed!"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# perl check
|
||||
#
|
||||
PERL=`findtool ${PERL:-perl}`
|
||||
if test -z "$PERL"; then
|
||||
echo "buildconf: perl not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Remove files generated on previous buildconf/configure run.
|
||||
#
|
||||
for fname in .deps \
|
||||
.libs \
|
||||
*.la \
|
||||
*.lo \
|
||||
*.a \
|
||||
*.o \
|
||||
Makefile \
|
||||
Makefile.in \
|
||||
aclocal.m4 \
|
||||
aclocal.m4.bak \
|
||||
ares_build.h \
|
||||
ares_config.h \
|
||||
ares_config.h.in \
|
||||
autom4te.cache \
|
||||
compile \
|
||||
config.guess \
|
||||
curl_config.h \
|
||||
curl_config.h.in \
|
||||
config.log \
|
||||
config.lt \
|
||||
config.status \
|
||||
config.sub \
|
||||
configure \
|
||||
configurehelp.pm \
|
||||
curl-config \
|
||||
curlbuild.h \
|
||||
depcomp \
|
||||
libcares.pc \
|
||||
libcurl.pc \
|
||||
libtool \
|
||||
libtool.m4 \
|
||||
libtool.m4.tmp \
|
||||
ltmain.sh \
|
||||
ltoptions.m4 \
|
||||
ltsugar.m4 \
|
||||
ltversion.m4 \
|
||||
lt~obsolete.m4 \
|
||||
missing \
|
||||
install-sh \
|
||||
stamp-h1 \
|
||||
stamp-h2 \
|
||||
stamp-h3 ; do
|
||||
removethis "$fname"
|
||||
done
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# run the correct scripts now
|
||||
#
|
||||
|
||||
echo "buildconf: running libtoolize"
|
||||
${libtoolize} --copy --force || die "libtoolize command failed"
|
||||
|
||||
# When using libtool 1.5.X (X < 26) we copy libtool.m4 to our local m4
|
||||
# subdirectory and this local copy is patched to fix some warnings that
|
||||
# are triggered when running aclocal and using autoconf 2.62 or later.
|
||||
|
||||
if test "$lt_major" = "1" && test "$lt_minor" = "5"; then
|
||||
if test -z "$lt_patch" || test "$lt_patch" -lt "26"; then
|
||||
echo "buildconf: copying libtool.m4 to local m4 subdir"
|
||||
ac_dir=`${ACLOCAL:-aclocal} --print-ac-dir`
|
||||
if test -f $ac_dir/libtool.m4; then
|
||||
cp -f $ac_dir/libtool.m4 m4/libtool.m4
|
||||
else
|
||||
echo "buildconf: $ac_dir/libtool.m4 not found"
|
||||
fi
|
||||
if test -f m4/libtool.m4; then
|
||||
echo "buildconf: renaming some variables in local m4/libtool.m4"
|
||||
$PERL -i.tmp -pe \
|
||||
's/lt_prog_compiler_pic_works/lt_cv_prog_compiler_pic_works/g; \
|
||||
s/lt_prog_compiler_static_works/lt_cv_prog_compiler_static_works/g;' \
|
||||
m4/libtool.m4
|
||||
rm -f m4/libtool.m4.tmp
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -f m4/libtool.m4; then
|
||||
echo "buildconf: converting all mv to mv -f in local m4/libtool.m4"
|
||||
$PERL -i.tmp -pe 's/\bmv +([^-\s])/mv -f $1/g' m4/libtool.m4
|
||||
rm -f m4/libtool.m4.tmp
|
||||
fi
|
||||
|
||||
echo "buildconf: running aclocal"
|
||||
${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS || die "aclocal command failed"
|
||||
|
||||
echo "buildconf: converting all mv to mv -f in local aclocal.m4"
|
||||
$PERL -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
|
||||
|
||||
echo "buildconf: running autoheader"
|
||||
${AUTOHEADER:-autoheader} || die "autoheader command failed"
|
||||
|
||||
echo "buildconf: running autoconf"
|
||||
${AUTOCONF:-autoconf} || die "autoconf command failed"
|
||||
|
||||
if test -d ares; then
|
||||
cd ares
|
||||
echo "buildconf: running in ares"
|
||||
./buildconf
|
||||
cd ..
|
||||
fi
|
||||
|
||||
echo "buildconf: running automake"
|
||||
${AUTOMAKE:-automake} --add-missing --copy || die "automake command failed"
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# GNU libtool complementary check
|
||||
#
|
||||
# Depending on the libtool and automake versions being used, config.guess
|
||||
# might not be installed in the subdirectory until automake has finished.
|
||||
# So we can not attempt to use it until this very last buildconf stage.
|
||||
#
|
||||
if test ! -f ./config.guess; then
|
||||
echo "buildconf: config.guess not found"
|
||||
else
|
||||
buildhost=`./config.guess 2>/dev/null|head -n 1`
|
||||
case $buildhost in
|
||||
*-*-darwin*)
|
||||
need_lt_major=1
|
||||
need_lt_minor=5
|
||||
need_lt_patch=26
|
||||
need_lt_check="yes"
|
||||
;;
|
||||
*-*-hpux*)
|
||||
need_lt_major=1
|
||||
need_lt_minor=5
|
||||
need_lt_patch=24
|
||||
need_lt_check="yes"
|
||||
;;
|
||||
esac
|
||||
if test ! -z "$need_lt_check"; then
|
||||
if test -z "$lt_major"; then
|
||||
lt_status="bad"
|
||||
elif test "$lt_major" -gt "$need_lt_major"; then
|
||||
lt_status="good"
|
||||
elif test "$lt_major" -lt "$need_lt_major"; then
|
||||
lt_status="bad"
|
||||
elif test -z "$lt_minor"; then
|
||||
lt_status="bad"
|
||||
elif test "$lt_minor" -gt "$need_lt_minor"; then
|
||||
lt_status="good"
|
||||
elif test "$lt_minor" -lt "$need_lt_minor"; then
|
||||
lt_status="bad"
|
||||
elif test -z "$lt_patch"; then
|
||||
lt_status="bad"
|
||||
elif test "$lt_patch" -gt "$need_lt_patch"; then
|
||||
lt_status="good"
|
||||
elif test "$lt_patch" -lt "$need_lt_patch"; then
|
||||
lt_status="bad"
|
||||
else
|
||||
lt_status="good"
|
||||
fi
|
||||
if test "$lt_status" != "good"; then
|
||||
need_lt_version="$need_lt_major.$need_lt_minor.$need_lt_patch"
|
||||
echo "buildconf: libtool version $lt_version found."
|
||||
echo " $buildhost requires GNU libtool $need_lt_version or newer installed."
|
||||
rm -f configure
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Finished successfully.
|
||||
#
|
||||
echo "buildconf: OK"
|
||||
exit 0
|
347
curl/compile
Executable file
347
curl/compile
Executable file
@ -0,0 +1,347 @@
|
||||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand '-c -o'.
|
||||
|
||||
scriptversion=2012-10-14.11; # UTC
|
||||
|
||||
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
# We need space, tab and new line, in precisely that order. Quoting is
|
||||
# there to prevent tools from complaining about whitespace usage.
|
||||
IFS=" "" $nl"
|
||||
|
||||
file_conv=
|
||||
|
||||
# func_file_conv build_file lazy
|
||||
# Convert a $build file to $host form and store it in $file
|
||||
# Currently only supports Windows hosts. If the determined conversion
|
||||
# type is listed in (the comma separated) LAZY, no conversion will
|
||||
# take place.
|
||||
func_file_conv ()
|
||||
{
|
||||
file=$1
|
||||
case $file in
|
||||
/ | /[!/]*) # absolute file, and not a UNC file
|
||||
if test -z "$file_conv"; then
|
||||
# lazily determine how to convert abs files
|
||||
case `uname -s` in
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
file_conv=wine
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
case $file_conv/,$2, in
|
||||
*,$file_conv,*)
|
||||
;;
|
||||
mingw/*)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin/*)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine/*)
|
||||
file=`winepath -w "$file" || echo "$file"`
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# func_cl_dashL linkdir
|
||||
# Make cl look for libraries in LINKDIR
|
||||
func_cl_dashL ()
|
||||
{
|
||||
func_file_conv "$1"
|
||||
if test -z "$lib_path"; then
|
||||
lib_path=$file
|
||||
else
|
||||
lib_path="$lib_path;$file"
|
||||
fi
|
||||
linker_opts="$linker_opts -LIBPATH:$file"
|
||||
}
|
||||
|
||||
# func_cl_dashl library
|
||||
# Do a library search-path lookup for cl
|
||||
func_cl_dashl ()
|
||||
{
|
||||
lib=$1
|
||||
found=no
|
||||
save_IFS=$IFS
|
||||
IFS=';'
|
||||
for dir in $lib_path $LIB
|
||||
do
|
||||
IFS=$save_IFS
|
||||
if $shared && test -f "$dir/$lib.dll.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.dll.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/$lib.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/lib$lib.a"; then
|
||||
found=yes
|
||||
lib=$dir/lib$lib.a
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS=$save_IFS
|
||||
|
||||
if test "$found" != yes; then
|
||||
lib=$lib.lib
|
||||
fi
|
||||
}
|
||||
|
||||
# func_cl_wrapper cl arg...
|
||||
# Adjust compile command to suit cl
|
||||
func_cl_wrapper ()
|
||||
{
|
||||
# Assume a capable shell
|
||||
lib_path=
|
||||
shared=:
|
||||
linker_opts=
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.[oO][bB][jJ])
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fo"$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fe"$file"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-I)
|
||||
eat=1
|
||||
func_file_conv "$2" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-I*)
|
||||
func_file_conv "${1#-I}" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-l)
|
||||
eat=1
|
||||
func_cl_dashl "$2"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-l*)
|
||||
func_cl_dashl "${1#-l}"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-L)
|
||||
eat=1
|
||||
func_cl_dashL "$2"
|
||||
;;
|
||||
-L*)
|
||||
func_cl_dashL "${1#-L}"
|
||||
;;
|
||||
-static)
|
||||
shared=false
|
||||
;;
|
||||
-Wl,*)
|
||||
arg=${1#-Wl,}
|
||||
save_ifs="$IFS"; IFS=','
|
||||
for flag in $arg; do
|
||||
IFS="$save_ifs"
|
||||
linker_opts="$linker_opts $flag"
|
||||
done
|
||||
IFS="$save_ifs"
|
||||
;;
|
||||
-Xlinker)
|
||||
eat=1
|
||||
linker_opts="$linker_opts $2"
|
||||
;;
|
||||
-*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
|
||||
func_file_conv "$1"
|
||||
set x "$@" -Tp"$file"
|
||||
shift
|
||||
;;
|
||||
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
|
||||
func_file_conv "$1" mingw
|
||||
set x "$@" "$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
if test -n "$linker_opts"; then
|
||||
linker_opts="-link$linker_opts"
|
||||
fi
|
||||
exec "$@" $linker_opts
|
||||
exit 1
|
||||
}
|
||||
|
||||
eat=
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand '-c -o'.
|
||||
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file 'INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
|
||||
func_cl_wrapper "$@" # Doesn't return...
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
# So we strip '-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no '-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# '.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
1420
curl/config.guess
vendored
Executable file
1420
curl/config.guess
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1799
curl/config.sub
vendored
Executable file
1799
curl/config.sub
vendored
Executable file
File diff suppressed because it is too large
Load Diff
42616
curl/configure
vendored
Executable file
42616
curl/configure
vendored
Executable file
File diff suppressed because it is too large
Load Diff
3706
curl/configure.ac
Normal file
3706
curl/configure.ac
Normal file
File diff suppressed because it is too large
Load Diff
155
curl/curl-config.in
Normal file
155
curl/curl-config.in
Normal file
@ -0,0 +1,155 @@
|
||||
#! /bin/sh
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 2001 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
includedir=@includedir@
|
||||
cppflag_curl_staticlib=@CPPFLAG_CURL_STATICLIB@
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
Usage: curl-config [OPTION]
|
||||
|
||||
Available values for OPTION include:
|
||||
|
||||
--built-shared says 'yes' if libcurl was built shared
|
||||
--ca ca bundle install path
|
||||
--cc compiler
|
||||
--cflags pre-processor and compiler flags
|
||||
--checkfor [version] check for (lib)curl of the specified version
|
||||
--configure the arguments given to configure when building curl
|
||||
--features newline separated list of enabled features
|
||||
--help display this help and exit
|
||||
--libs library linking information
|
||||
--prefix curl install prefix
|
||||
--protocols newline separated list of enabled protocols
|
||||
--static-libs static libcurl library linking information
|
||||
--version output version information
|
||||
--vernum output the version information as a number (hexadecimal)
|
||||
EOF
|
||||
|
||||
exit $1
|
||||
}
|
||||
|
||||
if test $# -eq 0; then
|
||||
usage 1
|
||||
fi
|
||||
|
||||
while test $# -gt 0; do
|
||||
case "$1" in
|
||||
# this deals with options in the style
|
||||
# --option=value and extracts the value part
|
||||
# [not currently used]
|
||||
-*=*) value=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
|
||||
*) value= ;;
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
--built-shared)
|
||||
echo @ENABLE_SHARED@
|
||||
;;
|
||||
|
||||
--ca)
|
||||
echo @CURL_CA_BUNDLE@
|
||||
;;
|
||||
|
||||
--cc)
|
||||
echo "@CC@"
|
||||
;;
|
||||
|
||||
--prefix)
|
||||
echo "$prefix"
|
||||
;;
|
||||
|
||||
--feature|--features)
|
||||
for feature in @SUPPORT_FEATURES@ ""; do
|
||||
test -n "$feature" && echo "$feature"
|
||||
done
|
||||
;;
|
||||
|
||||
--protocols)
|
||||
for protocol in @SUPPORT_PROTOCOLS@; do
|
||||
echo "$protocol"
|
||||
done
|
||||
;;
|
||||
|
||||
--version)
|
||||
echo libcurl @CURLVERSION@
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--checkfor)
|
||||
checkfor=$2
|
||||
cmajor=`echo $checkfor | cut -d. -f1`
|
||||
cminor=`echo $checkfor | cut -d. -f2`
|
||||
# when extracting the patch part we strip off everything after a
|
||||
# dash as that's used for things like version 1.2.3-CVS
|
||||
cpatch=`echo $checkfor | cut -d. -f3 | cut -d- -f1`
|
||||
checknum=`echo "$cmajor*256*256 + $cminor*256 + ${cpatch:-0}" | bc`
|
||||
numuppercase=`echo @VERSIONNUM@ | tr 'a-f' 'A-F'`
|
||||
nownum=`echo "obase=10; ibase=16; $numuppercase" | bc`
|
||||
|
||||
if test "$nownum" -ge "$checknum"; then
|
||||
# silent success
|
||||
exit 0
|
||||
else
|
||||
echo "requested version $checkfor is newer than existing @CURLVERSION@"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
--vernum)
|
||||
echo @VERSIONNUM@
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--help)
|
||||
usage 0
|
||||
;;
|
||||
|
||||
--cflags)
|
||||
echo ""
|
||||
;;
|
||||
|
||||
--libs)
|
||||
echo -lcurl
|
||||
;;
|
||||
|
||||
--static-libs)
|
||||
echo ""
|
||||
;;
|
||||
|
||||
--configure)
|
||||
echo @CONFIGURE_OPTIONS@
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "unknown option: $1"
|
||||
usage 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
exit 0
|
791
curl/depcomp
Executable file
791
curl/depcomp
Executable file
@ -0,0 +1,791 @@
|
||||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2013-05-30.07; # UTC
|
||||
|
||||
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by 'PROGRAMS ARGS'.
|
||||
object Object file output by 'PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputting dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
# Get the directory component of the given path, and save it in the
|
||||
# global variables '$dir'. Note that this directory component will
|
||||
# be either empty or ending with a '/' character. This is deliberate.
|
||||
set_dir_from ()
|
||||
{
|
||||
case $1 in
|
||||
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
|
||||
*) dir=;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Get the suffix-stripped basename of the given path, and save it the
|
||||
# global variable '$base'.
|
||||
set_base_from ()
|
||||
{
|
||||
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
|
||||
}
|
||||
|
||||
# If no dependency file was actually created by the compiler invocation,
|
||||
# we still have to create a dummy depfile, to avoid errors with the
|
||||
# Makefile "include basename.Plo" scheme.
|
||||
make_dummy_depfile ()
|
||||
{
|
||||
echo "#dummy" > "$depfile"
|
||||
}
|
||||
|
||||
# Factor out some common post-processing of the generated depfile.
|
||||
# Requires the auxiliary global variable '$tmpdepfile' to be set.
|
||||
aix_post_process_depfile ()
|
||||
{
|
||||
# If the compiler actually managed to produce a dependency file,
|
||||
# post-process it.
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form 'foo.o: dependency.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# $object: dependency.h
|
||||
# and one to simply output
|
||||
# dependency.h:
|
||||
# which is needed to avoid the deleted-header problem.
|
||||
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
|
||||
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
|
||||
} > "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
}
|
||||
|
||||
# A tabulation character.
|
||||
tab=' '
|
||||
# A newline character.
|
||||
nl='
|
||||
'
|
||||
# Character ranges might be problematic outside the C locale.
|
||||
# These definitions help.
|
||||
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
lower=abcdefghijklmnopqrstuvwxyz
|
||||
digits=0123456789
|
||||
alpha=${upper}${lower}
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Avoid interferences from the environment.
|
||||
gccflag= dashmflag=
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
cygpath_u="cygpath -u -f -"
|
||||
if test "$depmode" = msvcmsys; then
|
||||
# This is just like msvisualcpp but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvisualcpp
|
||||
fi
|
||||
|
||||
if test "$depmode" = msvc7msys; then
|
||||
# This is just like msvc7 but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvc7
|
||||
fi
|
||||
|
||||
if test "$depmode" = xlc; then
|
||||
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
|
||||
gccflag=-qmakedep=gcc,-MF
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
|
||||
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
|
||||
## (see the conditional assignment to $gccflag above).
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say). Also, it might not be
|
||||
## supported by the other compilers which use the 'gcc' depmode.
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# The second -e expression handles DOS-style file names with drive
|
||||
# letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the "deleted header file" problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
## Some versions of gcc put a space before the ':'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well. hp depmode also adds that space, but also prefixes the VPATH
|
||||
## to the object. Take care to not repeat it in the output.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like '#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
|
||||
| tr "$nl" ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
xlc)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts '$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
tmpdepfile3=$dir.libs/$base.u
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$dir$base.u
|
||||
tmpdepfile3=$dir$base.u
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
tcc)
|
||||
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
|
||||
# FIXME: That version still under development at the moment of writing.
|
||||
# Make that this statement remains true also for stable, released
|
||||
# versions.
|
||||
# It will wrap lines (doesn't matter whether long or short) with a
|
||||
# trailing '\', as in:
|
||||
#
|
||||
# foo.o : \
|
||||
# foo.c \
|
||||
# foo.h \
|
||||
#
|
||||
# It will put a trailing '\' even on the last line, and will use leading
|
||||
# spaces rather than leading tabs (at least since its commit 0394caf7
|
||||
# "Emit spaces for -MD").
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
|
||||
# We have to change lines of the first kind to '$object: \'.
|
||||
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
|
||||
# And for each line of the second kind, we have to emit a 'dep.h:'
|
||||
# dummy dependency, to avoid the deleted-header problem.
|
||||
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
## The order of this option in the case statement is important, since the
|
||||
## shell code in configure will try each of these formats in the order
|
||||
## listed in this file. A plain '-MD' option would be understood by many
|
||||
## compilers, so we must ensure this comes after the gcc and icc options.
|
||||
pgcc)
|
||||
# Portland's C compiler understands '-MD'.
|
||||
# Will always output deps to 'file.d' where file is the root name of the
|
||||
# source file under compilation, even if file resides in a subdirectory.
|
||||
# The object file name does not affect the name of the '.d' file.
|
||||
# pgcc 10.2 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using '\' :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
set_dir_from "$object"
|
||||
# Use the source, not the object, to determine the base name, since
|
||||
# that's sadly what pgcc will do too.
|
||||
set_base_from "$source"
|
||||
tmpdepfile=$base.d
|
||||
|
||||
# For projects that build the same source file twice into different object
|
||||
# files, the pgcc approach of using the *source* file root name can cause
|
||||
# problems in parallel builds. Use a locking strategy to avoid stomping on
|
||||
# the same $tmpdepfile.
|
||||
lockdir=$base.d-lock
|
||||
trap "
|
||||
echo '$0: caught signal, cleaning up...' >&2
|
||||
rmdir '$lockdir'
|
||||
exit 1
|
||||
" 1 2 13 15
|
||||
numtries=100
|
||||
i=$numtries
|
||||
while test $i -gt 0; do
|
||||
# mkdir is a portable test-and-set.
|
||||
if mkdir "$lockdir" 2>/dev/null; then
|
||||
# This process acquired the lock.
|
||||
"$@" -MD
|
||||
stat=$?
|
||||
# Release the lock.
|
||||
rmdir "$lockdir"
|
||||
break
|
||||
else
|
||||
# If the lock is being held by a different process, wait
|
||||
# until the winning process is done or we timeout.
|
||||
while test -d "$lockdir" && test $i -gt 0; do
|
||||
sleep 1
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
fi
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
trap - 1 2 13 15
|
||||
if test $i -le 0; then
|
||||
echo "$0: failed to acquire lock after $numtries attempts" >&2
|
||||
echo "$0: check lockdir '$lockdir'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add 'dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in 'foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# Libtool generates 2 separate objects for the 2 libraries. These
|
||||
# two compilations output dependencies in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||
# the former would cause a distcleancheck panic.
|
||||
tmpdepfile1=$dir$base.o.d # libtool 1.5
|
||||
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
|
||||
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
# Same post-processing that is required for AIX mode.
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
msvc7)
|
||||
if test "$libtool" = yes; then
|
||||
showIncludes=-Wc,-showIncludes
|
||||
else
|
||||
showIncludes=-showIncludes
|
||||
fi
|
||||
"$@" $showIncludes > "$tmpdepfile"
|
||||
stat=$?
|
||||
grep -v '^Note: including file: ' "$tmpdepfile"
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# The first sed program below extracts the file names and escapes
|
||||
# backslashes for cygpath. The second sed program outputs the file
|
||||
# name when reading, but also accumulates all include files in the
|
||||
# hold buffer in order to output them again at the end. This only
|
||||
# works with sed implementations that can handle large buffers.
|
||||
sed < "$tmpdepfile" -n '
|
||||
/^Note: including file: *\(.*\)/ {
|
||||
s//\1/
|
||||
s/\\/\\\\/g
|
||||
p
|
||||
}' | $cygpath_u | sort -u | sed -n '
|
||||
s/ /\\ /g
|
||||
s/\(.*\)/'"$tab"'\1 \\/p
|
||||
s/.\(.*\) \\/\1:/
|
||||
H
|
||||
$ {
|
||||
s/.*/'"$tab"'/
|
||||
G
|
||||
p
|
||||
}' >> "$depfile"
|
||||
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvc7msys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for ':'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this sed invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no eat=no
|
||||
for arg
|
||||
do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
if test $eat = yes; then
|
||||
eat=no
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-arch)
|
||||
eat=yes ;;
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
# makedepend may prepend the VPATH from the source file name to the object.
|
||||
# No need to regex-escape $object, excess matching of '.' is harmless.
|
||||
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process the last invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed '1,2d' "$tmpdepfile" \
|
||||
| tr ' ' "$nl" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E \
|
||||
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
| sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
|
||||
echo "$tab" >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvcmsys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
260
curl/docs/BINDINGS
Normal file
260
curl/docs/BINDINGS
Normal file
@ -0,0 +1,260 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
libcurl bindings
|
||||
|
||||
Creative people have written bindings or interfaces for various environments
|
||||
and programming languages. Using one of these allows you to take advantage of
|
||||
curl powers from within your favourite language or system.
|
||||
|
||||
This is a list of all known interfaces as of this writing.
|
||||
|
||||
The bindings listed below are not part of the curl/libcurl distribution
|
||||
archives, but must be downloaded and installed separately.
|
||||
|
||||
Ada95
|
||||
|
||||
Writtten by Andreas Almroth
|
||||
http://www.almroth.com/adacurl/index.html
|
||||
|
||||
Basic
|
||||
|
||||
ScriptBasic bindings to libcurl. Writtten by Peter Verhas
|
||||
http://scriptbasic.com/
|
||||
|
||||
C
|
||||
libcurl is a C library in itself!
|
||||
http://curl.haxx.se/libcurl/
|
||||
|
||||
C++
|
||||
|
||||
Written by Jean-Philippe Barrette-LaPierre
|
||||
http://curlpp.org/
|
||||
|
||||
Ch
|
||||
|
||||
Written by Stephen Nestinger and Jonathan Rogado
|
||||
http://chcurl.sourceforge.net/
|
||||
|
||||
Cocoa
|
||||
|
||||
BBHTTP: written by Bruno de Carvalho
|
||||
https://github.com/brunodecarvalho/BBHTTP
|
||||
|
||||
curlhandle: Written by Dan Wood
|
||||
http://curlhandle.sourceforge.net/
|
||||
|
||||
D
|
||||
|
||||
Written by Kenneth Bogert
|
||||
http://dlang.org/library/std/net/curl.html
|
||||
|
||||
Dylan
|
||||
|
||||
Written by Chris Double
|
||||
http://dylanlibs.sourceforge.net/
|
||||
|
||||
Eiffel
|
||||
|
||||
Written by Eiffel Software
|
||||
https://room.eiffel.com/library/curl
|
||||
|
||||
Euphoria
|
||||
|
||||
Written by Ray Smith
|
||||
http://rays-web.com/eulibcurl.htm
|
||||
|
||||
Falcon
|
||||
|
||||
http://www.falconpl.org/index.ftd?page_id=prjs&prj_id=curl
|
||||
|
||||
Ferite
|
||||
|
||||
Written by Paul Querna
|
||||
http://www.ferite.org/
|
||||
|
||||
Gambas
|
||||
|
||||
http://gambas.sourceforge.net/
|
||||
|
||||
glib/GTK+
|
||||
|
||||
Written by Richard Atterer
|
||||
http://atterer.net/glibcurl/
|
||||
|
||||
Guile:
|
||||
|
||||
Written by Michael L. Gran
|
||||
http://www.lonelycactus.com/guile-curl.html
|
||||
|
||||
Harbour
|
||||
|
||||
Written by Viktor Szakáts
|
||||
https://github.com/vszakats/harbour-core/tree/master/contrib/hbcurl
|
||||
|
||||
Haskell
|
||||
|
||||
Written by Galois, Inc
|
||||
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/curl
|
||||
|
||||
Java
|
||||
|
||||
https://github.com/pjlegato/curl-java
|
||||
|
||||
Julia
|
||||
|
||||
Written by Paul Howe
|
||||
https://github.com/forio/Curl.jl
|
||||
|
||||
Lisp
|
||||
|
||||
Written by Liam Healy
|
||||
http://common-lisp.net/project/cl-curl/
|
||||
|
||||
Lua
|
||||
|
||||
luacurl by Alexander Marinov
|
||||
http://luacurl.luaforge.net/
|
||||
|
||||
Lua-cURL by Jürgen Hötzel
|
||||
http://luaforge.net/projects/lua-curl/
|
||||
|
||||
Mono
|
||||
|
||||
Written by Jeffrey Phillips
|
||||
http://forge.novell.com/modules/xfmod/project/?libcurl-mono
|
||||
|
||||
.NET
|
||||
|
||||
libcurl-net by Jeffrey Phillips
|
||||
https://sourceforge.net/projects/libcurl-net/
|
||||
|
||||
node.js
|
||||
|
||||
node-libcurl by Jonathan Cardoso Machado
|
||||
https://github.com/JCMais/node-libcurl
|
||||
|
||||
Object-Pascal
|
||||
|
||||
Free Pascal, Delphi and Kylix binding written by Christophe Espern.
|
||||
http://www.tekool.com/opcurl
|
||||
|
||||
O'Caml
|
||||
|
||||
Written by Lars Nilsson
|
||||
https://sourceforge.net/projects/ocurl/
|
||||
|
||||
Pascal
|
||||
|
||||
Free Pascal, Delphi and Kylix binding written by Jeffrey Pohlmeyer.
|
||||
http://houston.quik.com/jkp/curlpas/
|
||||
|
||||
Perl
|
||||
|
||||
Maintained by Cris Bailiff and Bálint Szilakszi
|
||||
https://github.com/szbalint/WWW--Curl
|
||||
|
||||
PHP
|
||||
|
||||
Written by Sterling Hughes
|
||||
https://php.net/curl
|
||||
|
||||
PostgreSQL
|
||||
|
||||
Written by Gian Paolo Ciceri
|
||||
http://gborg.postgresql.org/project/pgcurl/projdisplay.php
|
||||
|
||||
Python
|
||||
|
||||
PycURL by Kjetil Jacobsen
|
||||
http://pycurl.sourceforge.net/
|
||||
|
||||
R
|
||||
|
||||
http://cran.r-project.org/package=curl
|
||||
|
||||
Rexx
|
||||
|
||||
Written Mark Hessling
|
||||
http://rexxcurl.sourceforge.net/
|
||||
|
||||
RPG
|
||||
|
||||
Support for ILE/RPG on OS/400 is included in source distribution
|
||||
http://curl.haxx.se/libcurl/
|
||||
See packages/OS400/README.OS400 and packages/OS400/curl.inc.in
|
||||
|
||||
Ruby
|
||||
|
||||
curb - written by Ross Bamford
|
||||
http://curb.rubyforge.org/
|
||||
|
||||
ruby-curl-multi - written by Kristjan Petursson and Keith Rarick
|
||||
http://curl-multi.rubyforge.org/
|
||||
|
||||
Rust
|
||||
|
||||
curl-rust - by Carl Lerche
|
||||
https://github.com/carllerche/curl-rust
|
||||
|
||||
Scheme
|
||||
|
||||
Bigloo binding by Kirill Lisovsky
|
||||
http://www.metapaper.net/lisovsky/web/curl/
|
||||
|
||||
S-Lang
|
||||
|
||||
S-Lang binding by John E Davis
|
||||
http://www.jedsoft.org/slang/modules/curl.html
|
||||
|
||||
Smalltalk
|
||||
|
||||
Smalltalk binding by Danil Osipchuk
|
||||
http://www.squeaksource.com/CurlPlugin/
|
||||
|
||||
SP-Forth
|
||||
|
||||
SP-Forth binding by ygrek
|
||||
http://www.forth.org.ru/~ac/lib/lin/curl/
|
||||
|
||||
SPL
|
||||
|
||||
SPL binding by Clifford Wolf
|
||||
http://www.clifford.at/spl/
|
||||
|
||||
Tcl
|
||||
|
||||
Tclcurl by Andrés García
|
||||
http://mirror.yellow5.com/tclcurl/
|
||||
|
||||
Visual Basic
|
||||
|
||||
libcurl-vb by Jeffrey Phillips
|
||||
https://sourceforge.net/projects/libcurl-vb/
|
||||
|
||||
Visual Foxpro
|
||||
|
||||
by Carlos Alloatti
|
||||
http://www.ctl32.com.ar/libcurl.asp
|
||||
|
||||
Q
|
||||
The libcurl module is part of the default install
|
||||
http://q-lang.sourceforge.net/
|
||||
|
||||
wxWidgets
|
||||
|
||||
Written by Casey O'Donnell
|
||||
http://wxcode.sourceforge.net/components/wxcurl/
|
||||
|
||||
XBLite
|
||||
|
||||
Written by David Szafranski
|
||||
http://perso.wanadoo.fr/xblite/libraries.html
|
||||
|
||||
Xojo
|
||||
|
||||
Written by Andrew Lambert
|
||||
https://github.com/charonn0/RB-libcURL
|
146
curl/docs/BUGS
Normal file
146
curl/docs/BUGS
Normal file
@ -0,0 +1,146 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
BUGS
|
||||
|
||||
1. Bugs
|
||||
1.1 There are still bugs
|
||||
1.2 Where to report
|
||||
1.3 What to report
|
||||
1.4 libcurl problems
|
||||
1.5 Who will fix the problems
|
||||
1.6 How to get a stack trace
|
||||
1.7 Bugs in libcurl bindings
|
||||
|
||||
==============================================================================
|
||||
|
||||
1.1 There are still bugs
|
||||
|
||||
Curl and libcurl have grown substantially since the beginning. At the time
|
||||
of writing (January 2013), there are about 83,000 lines of source code, and
|
||||
by the time you read this it has probably grown even more.
|
||||
|
||||
Of course there are lots of bugs left. And lots of misfeatures.
|
||||
|
||||
To help us make curl the stable and solid product we want it to be, we need
|
||||
bug reports and bug fixes.
|
||||
|
||||
1.2 Where to report
|
||||
|
||||
If you can't fix a bug yourself and submit a fix for it, try to report an as
|
||||
detailed report as possible to a curl mailing list to allow one of us to
|
||||
have a go at a solution. You can optionally also post your bug/problem at
|
||||
curl's bug tracking system over at
|
||||
|
||||
https://github.com/bagder/curl/issues
|
||||
|
||||
Please read the rest of this document below first before doing that!
|
||||
|
||||
If you feel you need to ask around first, find a suitable mailing list and
|
||||
post there. The lists are available on http://curl.haxx.se/mail/
|
||||
|
||||
1.3 What to report
|
||||
|
||||
When reporting a bug, you should include all information that will help us
|
||||
understand what's wrong, what you expected to happen and how to repeat the
|
||||
bad behavior. You therefore need to tell us:
|
||||
|
||||
- your operating system's name and version number
|
||||
|
||||
- what version of curl you're using (curl -V is fine)
|
||||
|
||||
- versions of the used libraries that libcurl is built to use
|
||||
|
||||
- what URL you were working with (if possible), at least which protocol
|
||||
|
||||
and anything and everything else you think matters. Tell us what you
|
||||
expected to happen, tell use what did happen, tell us how you could make it
|
||||
work another way. Dig around, try out, test. Then include all the tiny bits
|
||||
and pieces in your report. You will benefit from this yourself, as it will
|
||||
enable us to help you quicker and more accurately.
|
||||
|
||||
Since curl deals with networks, it often helps us if you include a protocol
|
||||
debug dump with your bug report. The output you get by using the -v or
|
||||
--trace options.
|
||||
|
||||
If curl crashed, causing a core dump (in unix), there is hardly any use to
|
||||
send that huge file to anyone of us. Unless we have an exact same system
|
||||
setup as you, we can't do much with it. Instead we ask you to get a stack
|
||||
trace and send that (much smaller) output to us instead!
|
||||
|
||||
The address and how to subscribe to the mailing lists are detailed in the
|
||||
MANUAL file.
|
||||
|
||||
1.4 libcurl problems
|
||||
|
||||
First, post all libcurl problems on the curl-library mailing list.
|
||||
|
||||
When you've written your own application with libcurl to perform transfers,
|
||||
it is even more important to be specific and detailed when reporting bugs.
|
||||
|
||||
Tell us the libcurl version and your operating system. Tell us the name and
|
||||
version of all relevant sub-components like for example the SSL library
|
||||
you're using and what name resolving your libcurl uses. If you use SFTP or
|
||||
SCP, the libssh2 version is relevant etc.
|
||||
|
||||
Showing us a real source code example repeating your problem is the best way
|
||||
to get our attention and it will greatly increase our chances to understand
|
||||
your problem and to work on a fix (if we agree it truly is a problem).
|
||||
|
||||
Lots of problems that appear to be libcurl problems are actually just abuses
|
||||
of the libcurl API or other malfunctions in your applications. It is advised
|
||||
that you run your problematic program using a memory debug tool like
|
||||
valgrind or similar before you post memory-related or "crashing" problems to
|
||||
us.
|
||||
|
||||
1.5 Who will fix the problems
|
||||
|
||||
If the problems or bugs you describe are considered to be bugs, we want to
|
||||
have the problems fixed.
|
||||
|
||||
There are no developers in the curl project that are paid to work on bugs.
|
||||
All developers that take on reported bugs do this on a voluntary basis. We
|
||||
do it out of an ambition to keep curl and libcurl excellent products and out
|
||||
of pride.
|
||||
|
||||
But please do not assume that you can just lump over something to us and it
|
||||
will then magically be fixed after some given time. Most often we need
|
||||
feedback and help to understand what you've experienced and how to repeat a
|
||||
problem. Then we may only be able to assist YOU to debug the problem and to
|
||||
track down the proper fix.
|
||||
|
||||
We get reports from many people every month and each report can take a
|
||||
considerable amount of time to really go to the bottom with.
|
||||
|
||||
1.6 How to get a stack trace
|
||||
|
||||
First, you must make sure that you compile all sources with -g and that you
|
||||
don't 'strip' the final executable. Try to avoid optimizing the code as
|
||||
well, remove -O, -O2 etc from the compiler options.
|
||||
|
||||
Run the program until it cores.
|
||||
|
||||
Run your debugger on the core file, like '<debugger> curl core'. <debugger>
|
||||
should be replaced with the name of your debugger, in most cases that will
|
||||
be 'gdb', but 'dbx' and others also occur.
|
||||
|
||||
When the debugger has finished loading the core file and presents you a
|
||||
prompt, enter 'where' (without the quotes) and press return.
|
||||
|
||||
The list that is presented is the stack trace. If everything worked, it is
|
||||
supposed to contain the chain of functions that were called when curl
|
||||
crashed. Include the stack trace with your detailed bug report. It'll help a
|
||||
lot.
|
||||
|
||||
1.7 Bugs in libcurl bindings
|
||||
|
||||
There will of course pop up bugs in libcurl bindings. You should then
|
||||
primarily approach the team that works on that particular binding and see
|
||||
what you can do to help them fix the problem.
|
||||
|
||||
If you suspect that the problem exists in the underlying libcurl, then
|
||||
please convert your program over to plain C and follow the steps outlined
|
||||
above.
|
306
curl/docs/CONTRIBUTE
Normal file
306
curl/docs/CONTRIBUTE
Normal file
@ -0,0 +1,306 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
When Contributing Source Code
|
||||
|
||||
This document is intended to offer guidelines that can be useful to keep in
|
||||
mind when you decide to contribute to the project. This concerns new features
|
||||
as well as corrections to existing flaws or bugs.
|
||||
|
||||
1. Learning cURL
|
||||
1.1 Join the Community
|
||||
1.2 License
|
||||
1.3 What To Read
|
||||
|
||||
2. cURL Coding Standards
|
||||
2.1 Naming
|
||||
2.2 Indenting
|
||||
2.3 Commenting
|
||||
2.4 Line Lengths
|
||||
2.5 General Style
|
||||
2.6 Non-clobbering All Over
|
||||
2.7 Platform Dependent Code
|
||||
2.8 Write Separate Patches
|
||||
2.9 Patch Against Recent Sources
|
||||
2.10 Document
|
||||
2.11 Test Cases
|
||||
|
||||
3. Pushing Out Your Changes
|
||||
3.1 Write Access to git Repository
|
||||
3.2 How To Make a Patch with git
|
||||
3.3 How To Make a Patch without git
|
||||
3.4 How to get your changes into the main sources
|
||||
3.5 Write good commit messages
|
||||
3.6 About pull requests
|
||||
|
||||
==============================================================================
|
||||
|
||||
1. Learning cURL
|
||||
|
||||
1.1 Join the Community
|
||||
|
||||
Skip over to http://curl.haxx.se/mail/ and join the appropriate mailing
|
||||
list(s). Read up on details before you post questions. Read this file before
|
||||
you start sending patches! We prefer patches and discussions being held on
|
||||
the mailing list(s), not sent to individuals.
|
||||
|
||||
Before posting to one of the curl mailing lists, please read up on the mailing
|
||||
list etiquette: http://curl.haxx.se/mail/etiquette.html
|
||||
|
||||
We also hang out on IRC in #curl on irc.freenode.net
|
||||
|
||||
If you're at all interested in the code side of things, consider clicking
|
||||
'watch' on the curl repo at github to get notified on pull requests and new
|
||||
issues posted there.
|
||||
|
||||
1.2. License
|
||||
|
||||
When contributing with code, you agree to put your changes and new code under
|
||||
the same license curl and libcurl is already using unless stated and agreed
|
||||
otherwise.
|
||||
|
||||
If you add a larger piece of code, you can opt to make that file or set of
|
||||
files to use a different license as long as they don't enforce any changes to
|
||||
the rest of the package and they make sense. Such "separate parts" can not be
|
||||
GPL licensed (as we don't want copyleft to affect users of libcurl) but they
|
||||
must use "GPL compatible" licenses (as we want to allow users to use libcurl
|
||||
properly in GPL licensed environments).
|
||||
|
||||
When changing existing source code, you do not alter the copyright of the
|
||||
original file(s). The copyright will still be owned by the original
|
||||
creator(s) or those who have been assigned copyright by the original
|
||||
author(s).
|
||||
|
||||
By submitting a patch to the curl project, you are assumed to have the right
|
||||
to the code and to be allowed by your employer or whatever to hand over that
|
||||
patch/code to us. We will credit you for your changes as far as possible, to
|
||||
give credit but also to keep a trace back to who made what changes. Please
|
||||
always provide us with your full real name when contributing!
|
||||
|
||||
1.3 What To Read
|
||||
|
||||
Source code, the man pages, the INTERNALS document, TODO, KNOWN_BUGS and the
|
||||
most recent changes in the git log. Just lurking on the curl-library mailing
|
||||
list is gonna give you a lot of insights on what's going on right now. Asking
|
||||
there is a good idea too.
|
||||
|
||||
2. cURL Coding Standards
|
||||
|
||||
2.1 Naming
|
||||
|
||||
Try using a non-confusing naming scheme for your new functions and variable
|
||||
names. It doesn't necessarily have to mean that you should use the same as in
|
||||
other places of the code, just that the names should be logical,
|
||||
understandable and be named according to what they're used for. File-local
|
||||
functions should be made static. We like lower case names.
|
||||
|
||||
See the INTERNALS document on how we name non-exported library-global
|
||||
symbols.
|
||||
|
||||
2.2 Indenting
|
||||
|
||||
Use the same indenting levels and bracing method as all the other code
|
||||
already does. It makes the source code easier to follow if all of it is
|
||||
written using the same style. We don't ask you to like it, we just ask you to
|
||||
follow the tradition! ;-) This mainly means: 2-level indents, using spaces
|
||||
only (no tabs) and having the opening brace ({) on the same line as the if()
|
||||
or while().
|
||||
|
||||
Also note that we use if() and while() with no space before the parenthesis.
|
||||
|
||||
2.3 Commenting
|
||||
|
||||
Comment your source code extensively using C comments (/* comment */), DO NOT
|
||||
use C++ comments (// this style). Commented code is quality code and enables
|
||||
future modifications much more. Uncommented code risk having to be completely
|
||||
replaced when someone wants to extend things, since other persons' source
|
||||
code can get quite hard to read.
|
||||
|
||||
2.4 Line Lengths
|
||||
|
||||
We write source lines shorter than 80 columns.
|
||||
|
||||
2.5 General Style
|
||||
|
||||
Keep your functions small. If they're small you avoid a lot of mistakes and
|
||||
you don't accidentally mix up variables etc.
|
||||
|
||||
2.6 Non-clobbering All Over
|
||||
|
||||
When you write new functionality or fix bugs, it is important that you don't
|
||||
fiddle all over the source files and functions. Remember that it is likely
|
||||
that other people have done changes in the same source files as you have and
|
||||
possibly even in the same functions. If you bring completely new
|
||||
functionality, try writing it in a new source file. If you fix bugs, try to
|
||||
fix one bug at a time and send them as separate patches.
|
||||
|
||||
2.7 Platform Dependent Code
|
||||
|
||||
Use #ifdef HAVE_FEATURE to do conditional code. We avoid checking for
|
||||
particular operating systems or hardware in the #ifdef lines. The
|
||||
HAVE_FEATURE shall be generated by the configure script for unix-like systems
|
||||
and they are hard-coded in the config-[system].h files for the others.
|
||||
|
||||
2.8 Write Separate Patches
|
||||
|
||||
It is annoying when you get a huge patch from someone that is said to fix 511
|
||||
odd problems, but discussions and opinions don't agree with 510 of them - or
|
||||
509 of them were already fixed in a different way. Then the patcher needs to
|
||||
extract the single interesting patch from somewhere within the huge pile of
|
||||
source, and that gives a lot of extra work. Preferably, all fixes that
|
||||
correct different problems should be in their own patch with an attached
|
||||
description exactly what they correct so that all patches can be selectively
|
||||
applied by the maintainer or other interested parties.
|
||||
|
||||
Also, separate patches enable bisecting much better when we track problems in
|
||||
the future.
|
||||
|
||||
2.9 Patch Against Recent Sources
|
||||
|
||||
Please try to get the latest available sources to make your patches
|
||||
against. It makes the life of the developers so much easier. The very best is
|
||||
if you get the most up-to-date sources from the git repository, but the
|
||||
latest release archive is quite OK as well!
|
||||
|
||||
2.10 Document
|
||||
|
||||
Writing docs is dead boring and one of the big problems with many open source
|
||||
projects. Someone's gotta do it. It makes it a lot easier if you submit a
|
||||
small description of your fix or your new features with every contribution so
|
||||
that it can be swiftly added to the package documentation.
|
||||
|
||||
The documentation is always made in man pages (nroff formatted) or plain
|
||||
ASCII files. All HTML files on the web site and in the release archives are
|
||||
generated from the nroff/ASCII versions.
|
||||
|
||||
2.11 Test Cases
|
||||
|
||||
Since the introduction of the test suite, we can quickly verify that the main
|
||||
features are working as they're supposed to. To maintain this situation and
|
||||
improve it, all new features and functions that are added need to be tested
|
||||
in the test suite. Every feature that is added should get at least one valid
|
||||
test case that verifies that it works as documented. If every submitter also
|
||||
posts a few test cases, it won't end up as a heavy burden on a single person!
|
||||
|
||||
If you don't have test cases or perhaps you have done something that is very
|
||||
hard to write tests for, do explain exactly how you have otherwise tested and
|
||||
verified your changes.
|
||||
|
||||
3. Pushing Out Your Changes
|
||||
|
||||
3.1 Write Access to git Repository
|
||||
|
||||
If you are a frequent contributor, or have another good reason, you can of
|
||||
course get write access to the git repository and then you'll be able to push
|
||||
your changes straight into the git repo instead of sending changes by mail as
|
||||
patches. Just ask if this is what you'd want. You will be required to have
|
||||
posted a few quality patches first, before you can be granted push access.
|
||||
|
||||
3.2 How To Make a Patch with git
|
||||
|
||||
You need to first checkout the repository:
|
||||
|
||||
git clone https://github.com/bagder/curl.git
|
||||
|
||||
You then proceed and edit all the files you like and you commit them to your
|
||||
local repository:
|
||||
|
||||
git commit [file]
|
||||
|
||||
As usual, group your commits so that you commit all changes that at once that
|
||||
constitutes a logical change. See also section "3.5 Write good commit
|
||||
messages".
|
||||
|
||||
Once you have done all your commits and you're happy with what you see, you
|
||||
can make patches out of your changes that are suitable for mailing:
|
||||
|
||||
git format-patch remotes/origin/master
|
||||
|
||||
This creates files in your local directory named NNNN-[name].patch for each
|
||||
commit.
|
||||
|
||||
Now send those patches off to the curl-library list. You can of course opt to
|
||||
do that with the 'git send-email' command.
|
||||
|
||||
3.3 How To Make a Patch without git
|
||||
|
||||
Keep a copy of the unmodified curl sources. Make your changes in a separate
|
||||
source tree. When you think you have something that you want to offer the
|
||||
curl community, use GNU diff to generate patches.
|
||||
|
||||
If you have modified a single file, try something like:
|
||||
|
||||
diff -u unmodified-file.c my-changed-one.c > my-fixes.diff
|
||||
|
||||
If you have modified several files, possibly in different directories, you
|
||||
can use diff recursively:
|
||||
|
||||
diff -ur curl-original-dir curl-modified-sources-dir > my-fixes.diff
|
||||
|
||||
The GNU diff and GNU patch tools exist for virtually all platforms, including
|
||||
all kinds of Unixes and Windows:
|
||||
|
||||
For unix-like operating systems:
|
||||
|
||||
https://savannah.gnu.org/projects/patch/
|
||||
https://www.gnu.org/software/diffutils/
|
||||
|
||||
For Windows:
|
||||
|
||||
http://gnuwin32.sourceforge.net/packages/patch.htm
|
||||
http://gnuwin32.sourceforge.net/packages/diffutils.htm
|
||||
|
||||
3.4 How to get your changes into the main sources
|
||||
|
||||
Submit your patch to the curl-library mailing list.
|
||||
|
||||
Make the patch against as recent sources as possible.
|
||||
|
||||
Make sure your patch adheres to the source indent and coding style of already
|
||||
existing source code. Failing to do so just adds more work for me.
|
||||
|
||||
Respond to replies on the list about the patch and answer questions and/or
|
||||
fix nits/flaws. This is very important. I will take lack of replies as a sign
|
||||
that you're not very anxious to get your patch accepted and I tend to simply
|
||||
drop such patches from my TODO list.
|
||||
|
||||
If you've followed the above paragraphs and your patch still hasn't been
|
||||
incorporated after some weeks, consider resubmitting it to the list.
|
||||
|
||||
3.5 Write good commit messages
|
||||
|
||||
A short guide to how to do fine commit messages in the curl project.
|
||||
|
||||
---- start ----
|
||||
[area]: [short line describing the main effect]
|
||||
|
||||
[separate the above single line from the rest with an empty line]
|
||||
|
||||
[full description, no wider than 72 columns that describe as much as
|
||||
possible as to why this change is made, and possibly what things
|
||||
it fixes and everything else that is related]
|
||||
|
||||
[Bug: link to source of the report or more related discussion]
|
||||
[Reported-by: John Doe - credit the reporter]
|
||||
[whatever-else-by: credit all helpers, finders, doers]
|
||||
---- stop ----
|
||||
|
||||
Don't forget to use commit --author="" if you commit someone else's work,
|
||||
and make sure that you have your own user and email setup correctly in git
|
||||
before you commit
|
||||
|
||||
3.6 About pull requests
|
||||
|
||||
With git (and especially github) it is easy and tempting to send a pull
|
||||
request to the curl project to have changes merged this way instead of
|
||||
mailing patches to the curl-library mailing list.
|
||||
|
||||
We used to dislike this but we're trying to change that and accept that this
|
||||
is a frictionless way for people to contribute to the project. We now welcome
|
||||
pull requests!
|
||||
|
||||
We will continue to avoid using github's merge tools to make the history
|
||||
linear and to make sure commits follow our style guidelines.
|
176
curl/docs/DISTRO-DILEMMA
Normal file
176
curl/docs/DISTRO-DILEMMA
Normal file
@ -0,0 +1,176 @@
|
||||
Date: February 11, 2007
|
||||
Author: Daniel Stenberg <daniel@haxx.se>
|
||||
URL: http://curl.haxx.se/legal/distro-dilemma.html
|
||||
|
||||
Condition
|
||||
|
||||
This document is written to describe the situation as it is right now.
|
||||
libcurl 7.16.1 is currently the latest version available. Things may of
|
||||
course change in the future.
|
||||
|
||||
This document reflects my view and understanding of these things. Please tell
|
||||
me where and how you think I'm wrong, and I'll try to correct my mistakes.
|
||||
|
||||
Background
|
||||
|
||||
The Free Software Foundation has deemed the Original BSD license[1] to be
|
||||
"incompatible"[2] with GPL[3]. I'd rather say it is the other way around, but
|
||||
the point is the same: if you distribute a binary version of a GPL program,
|
||||
it MUST NOT be linked with any Original BSD-licensed parts or libraries.
|
||||
Doing so will violate the GPL license. For a long time, very many GPL
|
||||
licensed programs have avoided this license mess by adding an exception[8] to
|
||||
their license. And many others have just closed their eyes for this problem.
|
||||
|
||||
libcurl is MIT-style[4] licensed - how on earth did this dilemma fall onto
|
||||
our plates?
|
||||
|
||||
libcurl is only a little library. libcurl can be built to use OpenSSL for its
|
||||
SSL/TLS capabilities. OpenSSL is basically Original BSD licensed[5].
|
||||
|
||||
If libcurl built to use OpenSSL is used by a GPL-licensed application and you
|
||||
decide to distribute a binary version of it (Linux distros - for example -
|
||||
tend to), you have a clash. GPL vs Original BSD.
|
||||
|
||||
This dilemma is not libcurl-specific nor is it specific to any particular
|
||||
Linux distro. (This article mentions and refers to Debian several times, but
|
||||
only because Debian seems to be the only Linux distro to have faced this
|
||||
issue yet since no other distro is shipping libcurl built with two SSL
|
||||
libraries.)
|
||||
|
||||
Part of the Operating System
|
||||
|
||||
This would not be a problem if the used lib would be considered part of the
|
||||
underlying operating system, as then the GPL license has an exception
|
||||
clause[6] that allows applications to use such libs without having to be
|
||||
allowed to distribute it or its sources. Possibly some distros will claim
|
||||
that OpenSSL is part of their operating system.
|
||||
|
||||
Debian does however not take this stance and has officially(?) claimed that
|
||||
OpenSSL is not a required part of the Debian operating system
|
||||
|
||||
Some people claim that this paragraph cannot be exploited this way by a Linux
|
||||
distro, but I am not a lawyer and that is a discussion left outside of this
|
||||
document.
|
||||
|
||||
GnuTLS
|
||||
|
||||
Since May 2005 libcurl can get built to use GnuTLS instead of OpenSSL. GnuTLS
|
||||
is an LGPL[7] licensed library that offers a matching set of features as
|
||||
OpenSSL does. Now, you can build and distribute an TLS/SSL capable libcurl
|
||||
without including any Original BSD licensed code.
|
||||
|
||||
I believe Debian is the first (only?) distro that provides libcurl/GnuTLS
|
||||
packages.
|
||||
|
||||
yassl
|
||||
|
||||
libcurl can get also get built to use yassl for the TLS/SSL layer. yassl is a
|
||||
GPL[3] licensed library.
|
||||
|
||||
|
||||
GnuTLS vs OpenSSL vs yassl
|
||||
|
||||
While these three libraries offer similar features, they are not equal.
|
||||
libcurl does not (yet) offer a standardized stable ABI if you decide to
|
||||
switch from using libcurl-openssl to libcurl-gnutls or vice-versa. The GnuTLS
|
||||
and yassl support is very recent in libcurl and it has not been tested nor
|
||||
used very extensively, while the OpenSSL equivalent code has been used and
|
||||
thus matured since 1999.
|
||||
|
||||
GnuTLS
|
||||
- LGPL licensed
|
||||
- supports SRP
|
||||
- lacks SSLv2 support
|
||||
- lacks MD2 support (used by at least some CA certs)
|
||||
- lacks the crypto functions libcurl uses for NTLM
|
||||
|
||||
OpenSSL
|
||||
- Original BSD licensed
|
||||
- lacks SRP
|
||||
- supports SSLv2
|
||||
- older and more widely used
|
||||
- provides crypto functions libcurl uses for NTLM
|
||||
- libcurl can do non-blocking connects with it in 7.15.4 and later
|
||||
|
||||
yassl
|
||||
- GPL licensed
|
||||
- much untested and unproven in the real work by (lib)curl users so we don't
|
||||
know a lot about restrictions or benefits from using this
|
||||
|
||||
The Better License, Original BSD, GPL or LGPL?
|
||||
|
||||
It isn't obvious or without debate to any objective interested party that
|
||||
either of these licenses are the "better" or even the "preferred" one in a
|
||||
generic situation.
|
||||
|
||||
Instead, I think we should accept the fact that the SSL/TLS libraries and
|
||||
their different licenses will fit different applications and their authors
|
||||
differently depending on the applications' licenses and their general usage
|
||||
pattern (considering how GPL and LGPL libraries for example can be burdensome
|
||||
for embedded systems usage).
|
||||
|
||||
In Debian land, there seems to be a common opinion that LGPL is "maximally
|
||||
compatible" with apps while Original BSD is not. Like this:
|
||||
|
||||
https://lists.debian.org/debian-devel/2005/09/msg01417.html
|
||||
|
||||
More SSL Libraries
|
||||
|
||||
In libcurl, there's no stopping us here. There are more Open Source/Free
|
||||
SSL/TLS libraries out there and we would very much like to support them as
|
||||
well, to offer application authors an even wider scope of choice.
|
||||
|
||||
Application Angle of this Problem
|
||||
|
||||
libcurl is built to use one SSL/TLS library. It uses a single fixed name (by
|
||||
default) on the built/created lib file, and applications are built/linked to
|
||||
use that single lib. Replacing one libcurl instance with another one that
|
||||
uses the other SSL/TLS library might break one or more applications (due to
|
||||
ABI differences and/or different feature set). You want your application to
|
||||
use the libcurl it was built for.
|
||||
|
||||
Project cURL Angle of this Problem
|
||||
|
||||
We distribute libcurl and everyone may build libcurl with either library at
|
||||
their choice. This problem is not directly a problem of ours. It merely
|
||||
affects users - GPL application authors only - of our lib as it comes
|
||||
included and delivered on some distros.
|
||||
|
||||
libcurl has different ABI when built with different SSL/TLS libraries due to
|
||||
these reasons:
|
||||
|
||||
1. No one has worked on fixing this. The mutex/lock callbacks should be set
|
||||
with a generic libcurl function that should use the proper underlying
|
||||
functions.
|
||||
|
||||
2. The CURLOPT_SSL_CTX_FUNCTION option is not possible to "emulate" on GnuTLS
|
||||
but simply requires OpenSSL.
|
||||
|
||||
3. There might be some other subtle differences just because nobody has yet
|
||||
tried to make a fixed ABI like this.
|
||||
|
||||
Distro Angle of this Problem
|
||||
|
||||
To my knowledge there is only one distro that ships libcurl built with either
|
||||
OpenSSL or GnuTLS.
|
||||
|
||||
Debian Linux is now (since mid September 2005) providing two different
|
||||
libcurl packages, one for libcurl built with OpenSSL and one built with
|
||||
GnuTLS. They use different .so names and can this both be installed in a
|
||||
single system simultaneously. This has been said to be a transitional system
|
||||
not desired to keep in the long run.
|
||||
|
||||
Footnotes
|
||||
|
||||
[1] = http://www.xfree86.org/3.3.6/COPYRIGHT2.html#6
|
||||
[2] = https://www.gnu.org/philosophy/bsd.html
|
||||
[3] = https://www.gnu.org/licenses/gpl.html
|
||||
[4] = http://curl.haxx.se/docs/copyright.html
|
||||
[5] = https://www.openssl.org/source/license.html
|
||||
[6] = https://www.gnu.org/licenses/gpl.html end of section 3
|
||||
[7] = https://www.gnu.org/licenses/lgpl.html
|
||||
[8] = https://en.wikipedia.org/wiki/OpenSSL_exception
|
||||
|
||||
Feedback/Updates provided by
|
||||
|
||||
Eric Cooper
|
1550
curl/docs/FAQ
Normal file
1550
curl/docs/FAQ
Normal file
File diff suppressed because it is too large
Load Diff
206
curl/docs/FEATURES
Normal file
206
curl/docs/FEATURES
Normal file
@ -0,0 +1,206 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
FEATURES
|
||||
|
||||
curl tool
|
||||
- config file support
|
||||
- multiple URLs in a single command line
|
||||
- range "globbing" support: [0-13], {one,two,three}
|
||||
- multiple file upload on a single command line
|
||||
- custom maximum transfer rate
|
||||
- redirectable stderr
|
||||
- metalink support (*13)
|
||||
|
||||
libcurl
|
||||
- full URL syntax with no length limit
|
||||
- custom maximum download time
|
||||
- custom least download speed acceptable
|
||||
- custom output result after completion
|
||||
- guesses protocol from host name unless specified
|
||||
- uses .netrc
|
||||
- progress bar with time statistics while downloading
|
||||
- "standard" proxy environment variables support
|
||||
- compiles on win32 (reported builds on 40+ operating systems)
|
||||
- selectable network interface for outgoing traffic
|
||||
- IPv6 support on unix and Windows
|
||||
- persistent connections
|
||||
- socks 4 + 5 support, with or without local name resolving
|
||||
- supports user name and password in proxy environment variables
|
||||
- operations through proxy "tunnel" (using CONNECT)
|
||||
- support for large files (>2GB and >4GB) during upload and download
|
||||
- replaceable memory functions (malloc, free, realloc, etc)
|
||||
- asynchronous name resolving (*6)
|
||||
- both a push and a pull style interface
|
||||
- international domain names (*11)
|
||||
|
||||
HTTP
|
||||
- HTTP/1.1 compliant (optionally uses 1.0)
|
||||
- GET
|
||||
- PUT
|
||||
- HEAD
|
||||
- POST
|
||||
- Pipelining
|
||||
- multipart formpost (RFC1867-style)
|
||||
- authentication: Basic, Digest, NTLM (*9) and Negotiate (SPNEGO) (*3)
|
||||
to server and proxy
|
||||
- resume (both GET and PUT)
|
||||
- follow redirects
|
||||
- maximum amount of redirects to follow
|
||||
- custom HTTP request
|
||||
- cookie get/send fully parsed
|
||||
- reads/writes the netscape cookie file format
|
||||
- custom headers (replace/remove internally generated headers)
|
||||
- custom user-agent string
|
||||
- custom referrer string
|
||||
- range
|
||||
- proxy authentication
|
||||
- time conditions
|
||||
- via http-proxy
|
||||
- retrieve file modification date
|
||||
- Content-Encoding support for deflate and gzip
|
||||
- "Transfer-Encoding: chunked" support in uploads
|
||||
- data compression (*12)
|
||||
- HTTP/2 (*5)
|
||||
|
||||
HTTPS (*1)
|
||||
- (all the HTTP features)
|
||||
- using client certificates
|
||||
- verify server certificate
|
||||
- via http-proxy
|
||||
- select desired encryption
|
||||
- force usage of a specific SSL version (SSLv2 (*7), SSLv3 (*10) or TLSv1)
|
||||
|
||||
FTP
|
||||
- download
|
||||
- authentication
|
||||
- Kerberos 5 (*14)
|
||||
- active/passive using PORT, EPRT, PASV or EPSV
|
||||
- single file size information (compare to HTTP HEAD)
|
||||
- 'type=' URL support
|
||||
- dir listing
|
||||
- dir listing names-only
|
||||
- upload
|
||||
- upload append
|
||||
- upload via http-proxy as HTTP PUT
|
||||
- download resume
|
||||
- upload resume
|
||||
- custom ftp commands (before and/or after the transfer)
|
||||
- simple "range" support
|
||||
- via http-proxy
|
||||
- all operations can be tunneled through a http-proxy
|
||||
- customizable to retrieve file modification date
|
||||
- no dir depth limit
|
||||
|
||||
FTPS (*1)
|
||||
- implicit ftps:// support that use SSL on both connections
|
||||
- explicit "AUTH TLS" and "AUTH SSL" usage to "upgrade" plain ftp://
|
||||
connection to use SSL for both or one of the connections
|
||||
|
||||
SCP (*8)
|
||||
- both password and public key auth
|
||||
|
||||
SFTP (*8)
|
||||
- both password and public key auth
|
||||
- with custom commands sent before/after the transfer
|
||||
|
||||
TFTP
|
||||
- download
|
||||
- upload
|
||||
|
||||
TELNET
|
||||
- connection negotiation
|
||||
- custom telnet options
|
||||
- stdin/stdout I/O
|
||||
|
||||
LDAP (*2)
|
||||
- full LDAP URL support
|
||||
|
||||
DICT
|
||||
- extended DICT URL support
|
||||
|
||||
FILE
|
||||
- URL support
|
||||
- upload
|
||||
- resume
|
||||
|
||||
SMB
|
||||
- SMBv1 over TCP and SSL
|
||||
- download
|
||||
- upload
|
||||
- authentication with NTLMv1
|
||||
|
||||
SMTP
|
||||
- authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (*9), Kerberos 5
|
||||
(*4) and External.
|
||||
- send e-mails
|
||||
- mail from support
|
||||
- mail size support
|
||||
- mail auth support for trusted server-to-server relaying
|
||||
- multiple recipients
|
||||
- via http-proxy
|
||||
|
||||
SMTPS (*1)
|
||||
- implicit smtps:// support
|
||||
- explicit "STARTTLS" usage to "upgrade" plain smtp:// connections to use SSL
|
||||
- via http-proxy
|
||||
|
||||
POP3
|
||||
- authentication: Clear Text, APOP and SASL
|
||||
- SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (*9),
|
||||
Kerberos 5 (*4) and External.
|
||||
- list e-mails
|
||||
- retrieve e-mails
|
||||
- enhanced command support for: CAPA, DELE, TOP, STAT, UIDL and NOOP via
|
||||
custom requests
|
||||
- via http-proxy
|
||||
|
||||
POP3S (*1)
|
||||
- implicit pop3s:// support
|
||||
- explicit "STLS" usage to "upgrade" plain pop3:// connections to use SSL
|
||||
- via http-proxy
|
||||
|
||||
IMAP
|
||||
- authentication: Clear Text and SASL
|
||||
- SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (*9),
|
||||
Kerberos 5 (*4) and External.
|
||||
- list the folders of a mailbox
|
||||
- select a mailbox with support for verifying the UIDVALIDITY
|
||||
- fetch e-mails with support for specifying the UID and SECTION
|
||||
- upload e-mails via the append command
|
||||
- enhanced command support for: EXAMINE, CREATE, DELETE, RENAME, STATUS,
|
||||
STORE, COPY and UID via custom requests
|
||||
- via http-proxy
|
||||
|
||||
IMAPS (*1)
|
||||
- implicit imaps:// support
|
||||
- explicit "STARTTLS" usage to "upgrade" plain imap:// connections to use SSL
|
||||
- via http-proxy
|
||||
|
||||
FOOTNOTES
|
||||
=========
|
||||
|
||||
*1 = requires OpenSSL, GnuTLS, NSS, yassl, axTLS, PolarSSL, WinSSL (native
|
||||
Windows), Secure Transport (native iOS/OS X) or GSKit (native IBM i)
|
||||
*2 = requires OpenLDAP
|
||||
*3 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos) or
|
||||
SSPI (native Windows)
|
||||
*4 = requires a GSS-API implementation, however, only Windows SSPI is
|
||||
currently supported
|
||||
*5 = requires nghttp2 and possibly a recent TLS library
|
||||
*6 = requires c-ares
|
||||
*7 = requires OpenSSL, NSS, GSKit, WinSSL or Secure Transport; GnuTLS, for
|
||||
example, only supports SSLv3 and TLSv1
|
||||
*8 = requires libssh2
|
||||
*9 = requires OpenSSL, GnuTLS, NSS, yassl, Secure Transport or SSPI (native
|
||||
Windows)
|
||||
*10 = requires any of the SSL libraries in (*1) above other than axTLS, which
|
||||
does not support SSLv3
|
||||
*11 = requires libidn or Windows
|
||||
*12 = requires libz
|
||||
*13 = requires libmetalink, and either an Apple or Microsoft operating
|
||||
system, or OpenSSL, or GnuTLS, or NSS
|
||||
*14 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos)
|
282
curl/docs/HISTORY
Normal file
282
curl/docs/HISTORY
Normal file
@ -0,0 +1,282 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
How cURL Became Like This
|
||||
=========================
|
||||
|
||||
Towards the end of 1996, Daniel Stenberg was spending time writing an IRC bot
|
||||
for an Amiga related channel on EFnet. He then came up with the idea to make
|
||||
currency-exchange calculations available to Internet Relay Chat (IRC)
|
||||
users. All the necessary data are published on the Web; he just needed to
|
||||
automate their retrieval.
|
||||
|
||||
Daniel simply adopted an existing command-line open-source tool, httpget, that
|
||||
Brazilian Rafael Sagula had written and recently release version 0.1 of. After
|
||||
a few minor adjustments, it did just what he needed.
|
||||
|
||||
1997
|
||||
----
|
||||
|
||||
HttpGet 1.0 was released on April 8th 1997 with brand new HTTP proxy support.
|
||||
|
||||
We soon found and fixed support for getting currencies over GOPHER. Once FTP
|
||||
download support was added, the name of the project was changed and urlget 2.0
|
||||
was released in August 1997. The http-only days were already passed.
|
||||
|
||||
1998
|
||||
----
|
||||
|
||||
The project slowly grew bigger. When upload capabilities were added and the
|
||||
name once again was misleading, a second name change was made and on March 20,
|
||||
1998 curl 4 was released. (The version numbering from the previous names was
|
||||
kept.)
|
||||
|
||||
(Unrelated to this project a company called Curl Corporation registered a US
|
||||
trademark on the name "CURL" on May 18 1998. That company had then already
|
||||
registered the curl.com domain back in November of the previous year. All this
|
||||
was revealed to us much later.)
|
||||
|
||||
SSL support was added, powered by the SSLeay library.
|
||||
|
||||
August, first announcement of curl on freshmeat.net.
|
||||
|
||||
October, with the curl 4.9 release and the introduction of cookie support,
|
||||
curl was no longer released under the GPL license. Now we're at 4000 lines of
|
||||
code, we switched over to the MPL license to restrict the effects of
|
||||
"copyleft".
|
||||
|
||||
November, configure script and reported successful compiles on several
|
||||
major operating systems. The never-quite-understood -F option was added and
|
||||
curl could now simulate quite a lot of a browser. TELNET support was added.
|
||||
|
||||
Curl 5 was released in December 1998 and introduced the first ever curl man
|
||||
page. People started making Linux RPM packages out of it.
|
||||
|
||||
1999
|
||||
----
|
||||
|
||||
January, DICT support added.
|
||||
|
||||
OpenSSL took over where SSLeay was abandoned.
|
||||
|
||||
May, first Debian package.
|
||||
|
||||
August, LDAP:// and FILE:// support added. The curl web site gets 1300 visits
|
||||
weekly.
|
||||
|
||||
Released curl 6.0 in September. 15000 lines of code.
|
||||
|
||||
December 28, added the project on Sourceforge and started using its services
|
||||
for managing the project.
|
||||
|
||||
2000
|
||||
----
|
||||
|
||||
Spring 2000, major internal overhaul to provide a suitable library interface.
|
||||
The first non-beta release was named 7.1 and arrived in August. This offered
|
||||
the easy interface and turned out to be the beginning of actually getting
|
||||
other software and programs to get based on and powered by libcurl. Almost
|
||||
20000 lines of code.
|
||||
|
||||
August, the curl web site gets 4000 visits weekly.
|
||||
|
||||
The PHP guys adopted libcurl already the same month, when the first ever third
|
||||
party libcurl binding showed up. CURL has been a supported module in PHP since
|
||||
the release of PHP 4.0.2. This would soon get followers. More than 16
|
||||
different bindings exist at the time of this writing.
|
||||
|
||||
September, kerberos4 support was added.
|
||||
|
||||
In November started the work on a test suite for curl. It was later re-written
|
||||
from scratch again. The libcurl major SONAME number was set to 1.
|
||||
|
||||
2001
|
||||
----
|
||||
|
||||
January, Daniel released curl 7.5.2 under a new license again: MIT (or
|
||||
MPL). The MIT license is extremely liberal and can be used combined with GPL
|
||||
in other projects. This would finally put an end to the "complaints" from
|
||||
people involved in GPLed projects that previously were prohibited from using
|
||||
libcurl while it was released under MPL only. (Due to the fact that MPL is
|
||||
deemed "GPL incompatible".)
|
||||
|
||||
curl supports HTTP 1.1 starting with the release of 7.7, March 22 2001. This
|
||||
also introduced libcurl's ability to do persistent connections. 24000 lines of
|
||||
code. The libcurl major SONAME number was bumped to 2 due to this overhaul.
|
||||
|
||||
The first experimental ftps:// support was added in March 2001.
|
||||
|
||||
August. curl is bundled in Mac OS X, 10.1. It was already becoming more and
|
||||
more of a standard utility of Linux distributions and a regular in the BSD
|
||||
ports collections. The curl web site gets 8000 visits weekly. Curl Corporation
|
||||
contacted Daniel to discuss "the name issue". After Daniel's reply, they have
|
||||
never since got in touch again.
|
||||
|
||||
September, libcurl 7.9 introduces cookie jar and curl_formadd(). During the
|
||||
forthcoming 7.9.x releases, we introduced the multi interface slowly and
|
||||
without much whistles.
|
||||
|
||||
2002
|
||||
----
|
||||
|
||||
June, the curl web site gets 13000 visits weekly. curl and libcurl is
|
||||
35000 lines of code. Reported successful compiles on more than 40 combinations
|
||||
of CPUs and operating systems.
|
||||
|
||||
To estimate number of users of the curl tool or libcurl library is next to
|
||||
impossible. Around 5000 downloaded packages each week from the main site gives
|
||||
a hint, but the packages are mirrored extensively, bundled with numerous OS
|
||||
distributions and otherwise retrieved as part of other software.
|
||||
|
||||
September, with the release of curl 7.10 it is released under the MIT license
|
||||
only.
|
||||
|
||||
2003
|
||||
----
|
||||
|
||||
January. Started working on the distributed curl tests. The autobuilds.
|
||||
|
||||
February, the curl site averages at 20000 visits weekly. At any given moment,
|
||||
there's an average of 3 people browsing the curl.haxx.se site.
|
||||
|
||||
Multiple new authentication schemes are supported: Digest (May), NTLM (June)
|
||||
and Negotiate (June).
|
||||
|
||||
November: curl 7.10.8 is released. 45000 lines of code. ~55000 unique visitors
|
||||
to the curl.haxx.se site. Five official web mirrors.
|
||||
|
||||
December, full-fledged SSL for FTP is supported.
|
||||
|
||||
2004
|
||||
----
|
||||
|
||||
January: curl 7.11.0 introduced large file support.
|
||||
|
||||
June: curl 7.12.0 introduced IDN support. 10 official web mirrors.
|
||||
|
||||
This release bumped the major SONAME to 3 due to the removal of the
|
||||
curl_formparse() function
|
||||
|
||||
August: Curl and libcurl 7.12.1
|
||||
|
||||
Public curl release number: 82
|
||||
Releases counted from the very beginning: 109
|
||||
Available command line options: 96
|
||||
Available curl_easy_setopt() options: 120
|
||||
Number of public functions in libcurl: 36
|
||||
Amount of public web site mirrors: 12
|
||||
Number of known libcurl bindings: 26
|
||||
|
||||
2005
|
||||
----
|
||||
|
||||
April. GnuTLS can now optionally be used for the secure layer when curl is
|
||||
built.
|
||||
|
||||
September: TFTP support was added.
|
||||
|
||||
More than 100,000 unique visitors of the curl web site. 25 mirrors.
|
||||
|
||||
December: security vulnerability: libcurl URL Buffer Overflow
|
||||
|
||||
2006
|
||||
----
|
||||
|
||||
January. We dropped support for Gopher. We found bugs in the implementation
|
||||
that turned out having been introduced years ago, so with the conclusion that
|
||||
nobody had found out in all this time we removed it instead of fixing it.
|
||||
|
||||
March: security vulnerability: libcurl TFTP Packet Buffer Overflow
|
||||
|
||||
April: Added the multi_socket() API
|
||||
|
||||
September: The major SONAME number for libcurl was bumped to 4 due to the
|
||||
removal of ftp third party transfer support.
|
||||
|
||||
November: Added SCP and SFTP support
|
||||
|
||||
2007
|
||||
----
|
||||
|
||||
February: Added support for the Mozilla NSS library to do the SSL/TLS stuff
|
||||
|
||||
July: security vulnerability: libcurl GnuTLS insufficient cert verification
|
||||
|
||||
2008
|
||||
----
|
||||
|
||||
November:
|
||||
|
||||
Command line options: 128
|
||||
curl_easy_setopt() options: 158
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 37
|
||||
Contributors: 683
|
||||
|
||||
145,000 unique visitors. >100 GB downloaded.
|
||||
|
||||
2009
|
||||
----
|
||||
|
||||
March: security vulnerability: libcurl Arbitrary File Access
|
||||
|
||||
August: security vulnerability: libcurl embedded zero in cert name
|
||||
|
||||
December: Added support for IMAP, POP3 and SMTP
|
||||
|
||||
2010
|
||||
----
|
||||
|
||||
January: Added support for RTSP
|
||||
|
||||
February: security vulnerability: libcurl data callback excessive length
|
||||
|
||||
March: The project switched over to use git (hosted by github) instead of CVS
|
||||
for source code control
|
||||
|
||||
May: Added support for RTMP
|
||||
|
||||
Added support for PolarSSL to do the SSL/TLS stuff
|
||||
|
||||
August:
|
||||
|
||||
Public curl releases: 117
|
||||
Command line options: 138
|
||||
curl_easy_setopt() options: 180
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 39
|
||||
Contributors: 808
|
||||
|
||||
Gopher support added (re-added actually)
|
||||
|
||||
2012
|
||||
----
|
||||
|
||||
July: Added support for Schannel (native Windows TLS backend) and Darwin SSL
|
||||
(Native Mac OS X and iOS TLS backend).
|
||||
|
||||
Supports metalink
|
||||
|
||||
October: SSH-agent support.
|
||||
|
||||
2013
|
||||
----
|
||||
|
||||
February: Cleaned up internals to always uses the "multi" non-blocking
|
||||
approach internally and only expose the blocking API with a wrapper.
|
||||
|
||||
September: First small steps on supporting HTTP/2 with nghttp2.
|
||||
|
||||
October: Removed krb4 support.
|
||||
|
||||
December: Happy eyeballs.
|
||||
|
||||
2014
|
||||
----
|
||||
|
||||
March: first real release supporting HTTP/2
|
||||
|
||||
September: Web site had 245,000 unique visitors and served 236GB data
|
123
curl/docs/HTTP-COOKIES
Normal file
123
curl/docs/HTTP-COOKIES
Normal file
@ -0,0 +1,123 @@
|
||||
Updated: July 3, 2012 (http://curl.haxx.se/docs/http-cookies.html)
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
|
||||
HTTP Cookies
|
||||
|
||||
1. HTTP Cookies
|
||||
1.1 Cookie overview
|
||||
1.2 Cookies saved to disk
|
||||
1.3 Cookies with curl the command line tool
|
||||
1.4 Cookies with libcurl
|
||||
1.5 Cookies with javascript
|
||||
|
||||
==============================================================================
|
||||
|
||||
1. HTTP Cookies
|
||||
|
||||
1.1 Cookie overview
|
||||
|
||||
HTTP cookies are pieces of 'name=contents' snippets that a server tells the
|
||||
client to hold and then the client sends back those the server on subsequent
|
||||
requests to the same domains/paths for which the cookies were set.
|
||||
|
||||
Cookies are either "session cookies" which typically are forgotten when the
|
||||
session is over which is often translated to equal when browser quits, or
|
||||
the cookies aren't session cookies they have expiration dates after which
|
||||
the client will throw them away.
|
||||
|
||||
Cookies are set to the client with the Set-Cookie: header and are sent to
|
||||
servers with the Cookie: header.
|
||||
|
||||
For a very long time, the only spec explaining how to use cookies was the
|
||||
original Netscape spec from 1994: http://curl.haxx.se/rfc/cookie_spec.html
|
||||
|
||||
In 2011, RFC6265 (https://www.ietf.org/rfc/rfc6265.txt) was finally published
|
||||
and details how cookies work within HTTP.
|
||||
|
||||
1.2 Cookies saved to disk
|
||||
|
||||
Netscape once created a file format for storing cookies on disk so that they
|
||||
would survive browser restarts. curl adopted that file format to allow
|
||||
sharing the cookies with browsers, only to see browsers move away from that
|
||||
format. Modern browsers no longer use it, while curl still does.
|
||||
|
||||
The netscape cookie file format stores one cookie per physical line in the
|
||||
file with a bunch of associated meta data, each field separated with
|
||||
TAB. That file is called the cookiejar in curl terminology.
|
||||
|
||||
When libcurl saves a cookiejar, it creates a file header of its own in which
|
||||
there is a URL mention that will link to the web version of this document.
|
||||
|
||||
1.3 Cookies with curl the command line tool
|
||||
|
||||
curl has a full cookie "engine" built in. If you just activate it, you can
|
||||
have curl receive and send cookies exactly as mandated in the specs.
|
||||
|
||||
Command line options:
|
||||
|
||||
-b, --cookie
|
||||
|
||||
tell curl a file to read cookies from and start the cookie engine, or if
|
||||
it isn't a file it will pass on the given string. -b name=var works and so
|
||||
does -b cookiefile.
|
||||
|
||||
-j, --junk-session-cookies
|
||||
|
||||
when used in combination with -b, it will skip all "session cookies" on
|
||||
load so as to appear to start a new cookie session.
|
||||
|
||||
-c, --cookie-jar
|
||||
|
||||
tell curl to start the cookie engine and write cookies to the given file
|
||||
after the request(s)
|
||||
|
||||
1.4 Cookies with libcurl
|
||||
|
||||
libcurl offers several ways to enable and interface the cookie engine. These
|
||||
options are the ones provided by the native API. libcurl bindings may offer
|
||||
access to them using other means.
|
||||
|
||||
CURLOPT_COOKIE
|
||||
|
||||
Is used when you want to specify the exact contents of a cookie header to
|
||||
send to the server.
|
||||
|
||||
CURLOPT_COOKIEFILE
|
||||
|
||||
Tell libcurl to activate the cookie engine, and to read the initial set of
|
||||
cookies from the given file. Read-only.
|
||||
|
||||
CURLOPT_COOKIEJAR
|
||||
|
||||
Tell libcurl to activate the cookie engine, and when the easy handle is
|
||||
closed save all known cookies to the given cookiejar file. Write-only.
|
||||
|
||||
CURLOPT_COOKIELIST
|
||||
|
||||
Provide detailed information about a single cookie to add to the internal
|
||||
storage of cookies. Pass in the cookie as a HTTP header with all the
|
||||
details set, or pass in a line from a netscape cookie file. This option
|
||||
can also be used to flush the cookies etc.
|
||||
|
||||
CURLINFO_COOKIELIST
|
||||
|
||||
Extract cookie information from the internal cookie storage as a linked
|
||||
list.
|
||||
|
||||
1.5 Cookies with javascript
|
||||
|
||||
These days a lot of the web is built up by javascript. The webbrowser loads
|
||||
complete programs that render the page you see. These javascript programs
|
||||
can also set and access cookies.
|
||||
|
||||
Since curl and libcurl are plain HTTP clients without any knowledge of or
|
||||
capability to handle javascript, such cookies will not be detected or used.
|
||||
|
||||
Often, if you want to mimic what a browser does on such web sites, you can
|
||||
record web browser HTTP traffic when using such a site and then repeat the
|
||||
cookie operations using curl or libcurl.
|
107
curl/docs/HTTP2.md
Normal file
107
curl/docs/HTTP2.md
Normal file
@ -0,0 +1,107 @@
|
||||
HTTP/2 with curl
|
||||
================
|
||||
|
||||
[HTTP/2 Spec](https://www.rfc-editor.org/rfc/rfc7540.txt)
|
||||
[http2 explained](http://daniel.haxx.se/http2/)
|
||||
|
||||
Build prerequisites
|
||||
-------------------
|
||||
- nghttp2
|
||||
- OpenSSL, NSS, GnutTLS or PolarSSL with a new enough version
|
||||
|
||||
[nghttp2](https://nghttp2.org/)
|
||||
-------------------------------
|
||||
|
||||
libcurl uses this 3rd party library for the low level protocol handling
|
||||
parts. The reason for this is that HTTP/2 is much more complex at that layer
|
||||
than HTTP/1.1 (which we implement on our own) and that nghttp2 is an already
|
||||
existing and well functional library.
|
||||
|
||||
We require at least version 1.0.0.
|
||||
|
||||
Over an http:// URL
|
||||
-------------------
|
||||
|
||||
If `CURLOPT_HTTP_VERSION` is set to `CURL_HTTP_VERSION_2_0`, libcurl will
|
||||
include an upgrade header in the initial request to the host to allow
|
||||
upgrading to HTTP/2.
|
||||
|
||||
Possibly we can later introduce an option that will cause libcurl to fail if
|
||||
not possible to upgrade. Possibly we introduce an option that makes libcurl
|
||||
use HTTP/2 at once over http://
|
||||
|
||||
Over an https:// URL
|
||||
--------------------
|
||||
|
||||
If `CURLOPT_HTTP_VERSION` is set to `CURL_HTTP_VERSION_2_0`, libcurl will use
|
||||
ALPN (or NPN) to negotiate which protocol to continue with. Possibly introduce
|
||||
an option that will cause libcurl to fail if not possible to use HTTP/2.
|
||||
Consider options to explicitly disable ALPN and/or NPN.
|
||||
|
||||
ALPN is the TLS extension that HTTP/2 is expected to use. The NPN extension is
|
||||
for a similar purpose, was made prior to ALPN and is used for SPDY so early
|
||||
HTTP/2 servers are implemented using NPN before ALPN support is widespread.
|
||||
|
||||
SSL libs
|
||||
--------
|
||||
|
||||
The challenge is the ALPN and NPN support and all our different SSL
|
||||
backends. You may need a fairly updated SSL library version for it to
|
||||
provide the necessary TLS features. Right now we support:
|
||||
|
||||
- OpenSSL: ALPN and NPN
|
||||
- NSS: ALPN and NPN
|
||||
- GnuTLS: ALPN
|
||||
- PolarSSL: ALPN
|
||||
|
||||
Multiplexing
|
||||
------------
|
||||
|
||||
Starting in 7.43.0, libcurl fully supports HTTP/2 multiplexing, which is the
|
||||
term for doing multiple independent transfers over the same physical TCP
|
||||
connection.
|
||||
|
||||
To take advantage of multiplexing, you need to use the multi interface and set
|
||||
`CURLMOPT_PIPELINING` to `CURLPIPE_MULTIPLEX`. With that bit set, libcurl will
|
||||
attempt to re-use existing HTTP/2 connections and just add a new stream over
|
||||
that when doing subsequent parallel requests.
|
||||
|
||||
While libcurl sets up a connection to a HTTP server there is a period during
|
||||
which it doesn't know if it can pipeline or do multiplexing and if you add new
|
||||
transfers in that period, libcurl will default to start new connections for
|
||||
those transfers. With the new option `CURLOPT_PIPEWAIT` (added in 7.43.0), you
|
||||
can ask that a transfer should rather wait and see in case there's a
|
||||
connection for the same host in progress that might end up being possible to
|
||||
multiplex on. It favours keeping the number of connections low to the cost of
|
||||
slightly longer time to first byte transferred.
|
||||
|
||||
Applications
|
||||
------------
|
||||
|
||||
We hide HTTP/2's binary nature and convert received HTTP/2 traffic to headers
|
||||
in HTTP 1.1 style. This allows applications to work unmodified.
|
||||
|
||||
curl tool
|
||||
---------
|
||||
|
||||
curl offers the `--http2` command line option to enable use of HTTP/2
|
||||
|
||||
HTTP Alternative Services
|
||||
-------------------------
|
||||
|
||||
Alt-Svc is a suggested extension with a corresponding frame (ALTSVC) in HTTP/2
|
||||
that tells the client about an alternative "route" to the same content for the
|
||||
same origin server that you get the response from. A browser or long-living
|
||||
client can use that hint to create a new connection asynchronously. For
|
||||
libcurl, we may introduce a way to bring such clues to the applicaton and/or
|
||||
let a subsequent request use the alternate route
|
||||
automatically. [Spec](https://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-05)
|
||||
|
||||
TODO
|
||||
----
|
||||
|
||||
- Provide API to set priorities / dependencies of individual streams
|
||||
|
||||
- Implement "prior-knowledge" HTTP/2 connecitons over clear text so that
|
||||
curl can connect with HTTP/2 at once without 1.1+Upgrade.
|
||||
|
1103
curl/docs/INSTALL
Normal file
1103
curl/docs/INSTALL
Normal file
File diff suppressed because it is too large
Load Diff
302
curl/docs/INSTALL.devcpp
Normal file
302
curl/docs/INSTALL.devcpp
Normal file
@ -0,0 +1,302 @@
|
||||
DevCpp-Mingw Install & Compilation Sept 2005
|
||||
==================================
|
||||
|
||||
Reference Emails available at curl@haxx.se:
|
||||
|
||||
Libcurl Install and Use Issues
|
||||
Awaiting an Answer for Win 32 Install
|
||||
res = curl_easy_perform(curl); Error
|
||||
Makefile Issues
|
||||
|
||||
|
||||
Having previously done a thorough review of what was available that met my
|
||||
requirements under GPL, I settled for Libcurl as the software of choice for
|
||||
many reasons not the least of which was the support.
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
This quest started when I innocently tried to incorporate the libcurl library
|
||||
into my simple source code. I figured that a few easy steps would accomplish
|
||||
this without major headaches. I had no idea that I would be facing an almost
|
||||
insurmountable challenge.
|
||||
|
||||
The main problem lies in two areas. First the bulk of support for libcurl
|
||||
exists for a Unix/linux command line environments. This is of little help when
|
||||
it comes to Windows O/S.
|
||||
|
||||
Secondly the help that does exist for the Windows O/S focused around mingw
|
||||
through a command line argument environment.
|
||||
|
||||
You may ask "Why is this a problem?"
|
||||
|
||||
I'm using a Windows O/S with DevCpp. For those of you who are unfamiliar with
|
||||
DevCpp, it is a window shell GUI that replaces the command line environment
|
||||
for gcc. A definite improvement that I am unwilling to give up. However using
|
||||
DevCpp presented its own set of issues. Inadvertently I also made some
|
||||
careless errors such as compiling the 7.14 version of Makefile with an older
|
||||
version of source code. Thanks to Dan Fandrich for picking this up.
|
||||
|
||||
I did eventually with the help of Daniel, Phillipe and others manage to
|
||||
implement successfully (the only mingw available version)
|
||||
curl-7.13.0-win32-ssl-devel-mingw32 into the DevCpp environment. Only the
|
||||
dynamic libcurl.dll libcurldll.a libraries worked. The static library which I
|
||||
was interested in did not. Furthermore when I tried to implement one of the
|
||||
examples included with the curl package (get info.c) it caused the executable
|
||||
to crash. Tracing the bug I found it in the code and function res =
|
||||
curl_easy_perform(curl);.
|
||||
|
||||
At this point I had to make a choice as to whether invest my limited
|
||||
time-energy resource to fixing the bug or to compile the new version
|
||||
available. After searching the archives I found a very similar or the same bug
|
||||
reported from version 7.12x on. Daniel did inform me that he thought that this
|
||||
bug had been fixed with the latest version. So I proceeded to compile the
|
||||
latest SSL version where I faced other challenges.
|
||||
|
||||
In order to make this process unremarkable for others using the same
|
||||
environment I decided to document the process so that others will find it
|
||||
routine. It would be a shame if newbies could not implement this excellent
|
||||
package for their use.
|
||||
|
||||
I would like to thank the many others in this forum and in the DevCpp forum
|
||||
for their help. Without your help I may either have given up or it would have
|
||||
taken me many times longer to achieve success.
|
||||
|
||||
The Cookbook Approach
|
||||
---------------------
|
||||
|
||||
This discussion will be confined to a SSL static library compilation and
|
||||
installation. Limited mention and comments will be inserted where appropriate
|
||||
to help with non-SSL, dynamic libraries and executables.
|
||||
|
||||
|
||||
Using Makefile from DevCpp to compile Libcurl libraries
|
||||
|
||||
Preamble
|
||||
--------
|
||||
|
||||
Using the latest version release - curl-7.14.0.tar.gz. Curl source code is
|
||||
platform independent. This simply means that the source code can be compiled
|
||||
for any Operating System (Linux/Unix Windows etc. and variations of thereof).
|
||||
|
||||
The first thing to note is that inside curl-7.14.0 you will find two folders
|
||||
lib and src. Both contain Makefile.m32 (required for win mingw library or exe
|
||||
compilation) files which are different. The main difference between these two
|
||||
folders and the makefiles is that the src folder contents are used to compile
|
||||
an executable file(curl.exe) while the lib folder contents are used to compile
|
||||
a static (libcurl.a) and dynamic (libcurl.dll & libcurldll.a) file that can be
|
||||
used to compile libcurl with your own source code so that one can use and
|
||||
access all libcurl functions.
|
||||
|
||||
Before we start please make sure that DevCpp is installed properly. In
|
||||
particular make sure you have no spaces in the name of any of the directories
|
||||
and subdirectories where DevCpp is installed. Failure to comply with the
|
||||
install instructions may produce erratic behaviour in DevCpp. For further info
|
||||
check the following sites
|
||||
|
||||
http://aditsu.freeunixhost.com/dev-cpp-faq.html
|
||||
https://sourceforge.net/p/dev-cpp/discussion/48211/thread/2a85ea46
|
||||
|
||||
As I have mentioned before I will confine this to the SSL Library compilations
|
||||
but the process is very similar for compilation of the executable - curl.exe;
|
||||
just substitute the src folder makefile in its stead.
|
||||
|
||||
First use a text processor Notepad, or your own favourite text processor. To
|
||||
engage your favourite text processor, select Makefile.m32 click once with your
|
||||
mouse on file icon; icon turns blue, press the shift key and right-click on
|
||||
mouse, menu appears select "Open with", select your favourite text processor.
|
||||
|
||||
Next read the contents of Makefile.m32. It includes instructions on its use.
|
||||
|
||||
Method I - DOS Command Line
|
||||
---------------------------
|
||||
|
||||
Note - The only reason I have included this method is that Method II which is
|
||||
the preferred method for compiling does not allow for the setting of option
|
||||
switches (e.g. SSL = 1 or SSL =0). At least that's what they tell me at the
|
||||
Dev-Cpp forum.
|
||||
|
||||
1 - Make a copy of (D:\Dev-Cpp\bin) bin folder and name it "bin Original"
|
||||
place it in the Dev-Cpp installed directory (D:\Dev-Cpp\ for this example)
|
||||
|
||||
2 - Copy the entire contents of the LIB folder of curl-7.14.0.tar.gz or zip
|
||||
version into the bin folder above (D:\Dev-Cpp\bin). The reason being is that
|
||||
the make.exe file resides in this folder. Make.exe will use - Makefile.m32,
|
||||
Makefile.inc, and the source code included in the lib folder to compile the
|
||||
source code. There is a PATH issue with make.exe that remains unresolved at
|
||||
least for me. Unless the entire source code to be compiled is placed entirely
|
||||
within the directory of make.exe an error message will be generated - "file
|
||||
xxxx.yyy not available".
|
||||
|
||||
3- Go to Dev-Cpp\bin and double click on make .exe. You will see a DOS window
|
||||
quickly pop up and close very quickly. Not to worry! Please do not skip this
|
||||
step.
|
||||
|
||||
4- Click on the start button\Programs\MS-DOS Prompt.Once the DOS Window is up
|
||||
Type the disk drive letter (e.g. E: ) engage the enter button. The path should
|
||||
automatically take you to the directory of the make.exe file.
|
||||
|
||||
5- To compile the source code simply type at the DOS prompt make -f
|
||||
Makefile.m32 as per instructions contained in the Makefile.m32 file (use any
|
||||
text processor to read instructions). I don't believe that this makefile
|
||||
allows for the option of non SSL. Ignore any warnings.
|
||||
|
||||
6- Collect and make copies of libcurl.a, libcurl.dll, libcurldll.a and any *.o
|
||||
compilations you might need in another directory outside of the bin directory
|
||||
as you will need this files shortly to set up libcurl for use with
|
||||
Dev-cpp. For most apps *.o is not required. Later on we will show what to do
|
||||
with these files.
|
||||
|
||||
7- You are finished but before closing we need to do cleanup - erase the bin
|
||||
folder and rename the "bin Original" folder created in step 1 to bin.
|
||||
|
||||
Note to compile a curl executable the process is probably similar but instead
|
||||
of using the LIB folder contents use the SRC folder contents and Makefiles in
|
||||
curl-7.14.0.tar.gz. File directories relative placements must be respected for
|
||||
compiling to take place successfully. This may not be possible with the PATH
|
||||
problem that make.exe experiences. If anyone has solved this PATH issue and
|
||||
please make sure it actually works on Win 9x/2000/XP before letting me
|
||||
know. Then please let me or Daniel in on the solution so that it can be
|
||||
included with these instructions. Thanks.
|
||||
|
||||
or
|
||||
|
||||
Method II - Dev-Cpp GUI
|
||||
-----------------------
|
||||
|
||||
1- Copy the entire contents of the LIB folder of curl-7.14.0.tar.gz or zip
|
||||
version into any folder outside of (Dev-Cpp\bin).
|
||||
|
||||
2- Drop the File/New/click on Project.
|
||||
|
||||
3- New Project Dialogue box appears. Double click on the Static Library.
|
||||
|
||||
4- Create Project Dialogue box appears. Select the LIB folder location to
|
||||
place and locate your Project File Name. Placing the Project File Name
|
||||
elsewhere may cause problems (PATH issue problem again).
|
||||
|
||||
5- Drop down the Project/Project Options. Project Options Dialogue box
|
||||
appears.
|
||||
|
||||
6- Select the Makefile tab in the Project Options Dialogue Box. Check Box -
|
||||
Use Custom Makefile. Click on the Folder icon at the extreme right of the
|
||||
Check Box. Select Makefile.m32 in the folder wherever you have placed the
|
||||
contents of the LIB Folder. Press OK and close the Dialogue Box.
|
||||
|
||||
7- Drop the Menu Project/Click on Add to Project. Open File Dialogue Box
|
||||
appears. The Dialogue Box should open in the folder wherever you have placed
|
||||
the contents of the LIB Folder. If not go there.
|
||||
|
||||
8- Select Crtl-A to select all files in the LIB folder. Click on open to add
|
||||
files and close box. Wait till all files are added. This may take 30 seconds
|
||||
or longer.
|
||||
|
||||
9- Drop the Menu Execute/Click on Compile.
|
||||
|
||||
10- That's it.
|
||||
|
||||
|
||||
The following steps must be completed if Curl is to work properly
|
||||
=================================================================
|
||||
|
||||
LIB folder inclusions (*.a placement)
|
||||
-------------------------------------
|
||||
|
||||
1- Refer to Method I - DOS Command Line point # 6 Take libcurl.a, libcurldll.a
|
||||
and install it in the directory C( or whichever drive Dev is installed)
|
||||
:\Dev-Cpp\lib.
|
||||
|
||||
|
||||
Include Folder
|
||||
--------------
|
||||
|
||||
1- Create a new folder by the name of curl (do not change the name curl to
|
||||
some other name as it will cause major issues) in the directory
|
||||
C:\Dev-Cpp\include.
|
||||
|
||||
2- Copy the entire contents of the curl folder of curl-7.14.0.tar.gz or zip
|
||||
version into the newly created curl directory - C:\Dev-Cpp\include\curl.
|
||||
|
||||
Links To Include And Lib Folder
|
||||
-------------------------------
|
||||
|
||||
1- Drop the Menu - Tools\Compiler Options\Directories\Libraries. Make sure
|
||||
that C( or whichever drive Dev is installed):\DEV-CPP\lib is included.
|
||||
|
||||
2- Next select the Menu - Tools\Compiler Options\Directories\C Includes. Make
|
||||
sure that C:\DEV-CPP\include and C:\Dev-Cpp\include\curl are included.
|
||||
|
||||
3- Next select the Menu - Tools\Compiler Options\Directories\C++
|
||||
Includes. Make sure that C:\DEV-CPP\include and C:\Dev-Cpp\include\curl are
|
||||
included.
|
||||
|
||||
Linker Links
|
||||
------------
|
||||
|
||||
1- Drop the Menu - Tools\Compiler Options\Directories\Compiler.
|
||||
|
||||
2- Make sure that the box "Add these commands to the linker command line" is
|
||||
checked.
|
||||
|
||||
3- Include in the white space immediately below the box referred in 2 -lcurl
|
||||
-lws2_32.
|
||||
|
||||
SSL Files
|
||||
---------
|
||||
|
||||
1- Get the latest openSSL (as of time of this writing)
|
||||
openssl-0.9.7e-win32-bin.zip for the minimalist package of the openssl-0.9.7e
|
||||
binaries ported to MS Windows 95/98/NT/XP using the MingW32/GCC-3.1
|
||||
development environment. The file may be downloaded at
|
||||
http://curl.haxx.se/download/.
|
||||
|
||||
2- Open the above zip file. You will find two files - SDL.dll,
|
||||
SDL_mixer.dll. Install them in the directory C:\WINDOWS\SYSTEM32 for Win 9x
|
||||
users and c:\winnt\system32 for NT-family users.
|
||||
|
||||
Multithreading Files
|
||||
--------------------
|
||||
|
||||
To be completed
|
||||
|
||||
#define
|
||||
-------
|
||||
|
||||
1- Make sure that your program includes the following - #define CURL_STATICLIB
|
||||
must be declared FIRST before any other define functions may be
|
||||
added. Otherwise you may experience link errors.
|
||||
|
||||
2- Don't forget to include #include "curl/curl.h".
|
||||
|
||||
e.g.
|
||||
#define CURL_STATICLIB
|
||||
#include <windows.h>
|
||||
#include "curl/curl.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
etc...
|
||||
|
||||
|
||||
Static or Dynamic Library
|
||||
-------------------------
|
||||
|
||||
The above steps apply for the use by a static library. Should you choose to
|
||||
use a dynamic library you will be required to perform these additional steps.
|
||||
|
||||
1- Refer to Method I - DOS Command Line point # 6. Install libcurl.dll in the
|
||||
directory C:\WINDOWS\SYSTEM32 for Win 9x users and c:\winnt\system32 for
|
||||
NT-family users.
|
||||
|
||||
2- Refer to Linker Links point 3 - Replace -lcurl with -lcurldll.
|
||||
|
||||
Voila you're done.
|
||||
|
||||
The non-SSL static Library build may not be possible to use at least as of the
|
||||
time of this writing - v7.14. Check reference emails - Phillipe and I found it
|
||||
impossible to fully compile as certain files were missing for linking. No big
|
||||
loss as SSL is a major plus.
|
||||
|
||||
Hope this Helps
|
||||
|
||||
Tom
|
1095
curl/docs/INTERNALS
Normal file
1095
curl/docs/INTERNALS
Normal file
File diff suppressed because it is too large
Load Diff
257
curl/docs/KNOWN_BUGS
Normal file
257
curl/docs/KNOWN_BUGS
Normal file
@ -0,0 +1,257 @@
|
||||
These are problems known to exist at the time of this release. Feel free to
|
||||
join in and help us correct one or more of these! Also be sure to check the
|
||||
changelog of the current development status, as one or more of these problems
|
||||
may have been fixed since this was written!
|
||||
|
||||
90. IMAP "SEARCH ALL" truncates output on large boxes. "A quick search of the
|
||||
code reveals that pingpong.c contains some truncation code, at line 408,
|
||||
when it deems the server response to be too large truncating it to 40
|
||||
characters"
|
||||
http://curl.haxx.se/bug/view.cgi?id=1366
|
||||
|
||||
89. Disabling HTTP Pipelining when there are ongoing transfers can lead to
|
||||
heap corruption and crash. http://curl.haxx.se/bug/view.cgi?id=1411
|
||||
|
||||
88. libcurl doesn't support CURLINFO_FILETIME for SFTP transfers and thus
|
||||
curl's -R option also doesn't work then.
|
||||
|
||||
87. -J/--remote-header-name doesn't decode %-encoded file names. RFC6266
|
||||
details how it should be done. The can of worm is basically that we have no
|
||||
charset handling in curl and ascii >=128 is a challenge for us. Not to
|
||||
mention that decoding also means that we need to check for nastiness that is
|
||||
attempted, like "../" sequences and the like. Probably everything to the left
|
||||
of any embedded slashes should be cut off.
|
||||
http://curl.haxx.se/bug/view.cgi?id=1294
|
||||
|
||||
86. The disconnect commands (LOGOUT and QUIT) may not be sent by IMAP, POP3
|
||||
and SMTP if a failure occurs during the authentication phase of a
|
||||
connection.
|
||||
|
||||
85. Wrong STARTTRANSFER timer accounting for POST requests
|
||||
Timer works fine with GET requests, but while using POST the time for
|
||||
CURLINFO_STARTTRANSFER_TIME is wrong. While using POST
|
||||
CURLINFO_STARTTRANSFER_TIME minus CURLINFO_PRETRANSFER_TIME is near to zero
|
||||
every time.
|
||||
http://curl.haxx.se/bug/view.cgi?id=1213
|
||||
|
||||
84. CURLINFO_SSL_VERIFYRESULT is only implemented for the OpenSSL and NSS
|
||||
backends, so relying on this information in a generic app is flaky.
|
||||
|
||||
82. When building with the Windows Borland compiler, it fails because the
|
||||
"tlib" tool doesn't support hyphens (minus signs) in file names and we have
|
||||
such in the build.
|
||||
http://curl.haxx.se/bug/view.cgi?id=1222
|
||||
|
||||
81. When using -J (with -O), automatically resumed downloading together with
|
||||
"-C -" fails. Without -J the same command line works! This happens because
|
||||
the resume logic is worked out before the target file name (and thus its
|
||||
pre-transfer size) has been figured out!
|
||||
http://curl.haxx.se/bug/view.cgi?id=1169
|
||||
|
||||
80. Curl doesn't recognize certificates in DER format in keychain, but it
|
||||
works with PEM.
|
||||
http://curl.haxx.se/bug/view.cgi?id=1065
|
||||
|
||||
79. SMTP. When sending data to multiple recipients, curl will abort and return
|
||||
failure if one of the recipients indicate failure (on the "RCPT TO"
|
||||
command). Ordinary mail programs would proceed and still send to the ones
|
||||
that can receive data. This is subject for change in the future.
|
||||
http://curl.haxx.se/bug/view.cgi?id=1116
|
||||
|
||||
78. curl and libcurl don't always signal the client properly when "sending"
|
||||
zero bytes files - it makes for example the command line client not creating
|
||||
any file at all. Like when using FTP.
|
||||
http://curl.haxx.se/bug/view.cgi?id=1063
|
||||
|
||||
76. The SOCKET type in Win64 is 64 bits large (and thus so is curl_socket_t on
|
||||
that platform), and long is only 32 bits. It makes it impossible for
|
||||
curl_easy_getinfo() to return a socket properly with the CURLINFO_LASTSOCKET
|
||||
option as for all other operating systems.
|
||||
|
||||
75. NTLM authentication involving unicode user name or password only works
|
||||
properly if built with UNICODE defined together with the WinSSL/schannel
|
||||
backend. The original problem was mentioned in:
|
||||
http://curl.haxx.se/mail/lib-2009-10/0024.html
|
||||
http://curl.haxx.se/bug/view.cgi?id=896
|
||||
|
||||
The WinSSL/schannel version verified to work as mentioned in
|
||||
http://curl.haxx.se/mail/lib-2012-07/0073.html
|
||||
|
||||
73. if a connection is made to a FTP server but the server then just never
|
||||
sends the 220 response or otherwise is dead slow, libcurl will not
|
||||
acknowledge the connection timeout during that phase but only the "real"
|
||||
timeout - which may surprise users as it is probably considered to be the
|
||||
connect phase to most people. Brought up (and is being misunderstood) in:
|
||||
http://curl.haxx.se/bug/view.cgi?id=856
|
||||
|
||||
72. "Pausing pipeline problems."
|
||||
http://curl.haxx.se/mail/lib-2009-07/0214.html
|
||||
|
||||
70. Problem re-using easy handle after call to curl_multi_remove_handle
|
||||
http://curl.haxx.se/mail/lib-2009-07/0249.html
|
||||
|
||||
68. "More questions about ares behavior".
|
||||
http://curl.haxx.se/mail/lib-2009-08/0012.html
|
||||
|
||||
67. When creating multipart formposts. The file name part can be encoded with
|
||||
something beyond ascii but currently libcurl will only pass in the verbatim
|
||||
string the app provides. There are several browsers that already do this
|
||||
encoding. The key seems to be the updated draft to RFC2231:
|
||||
https://tools.ietf.org/html/draft-reschke-rfc2231-in-http-02
|
||||
|
||||
66. When using telnet, the time limitation options don't work.
|
||||
http://curl.haxx.se/bug/view.cgi?id=846
|
||||
|
||||
65. When doing FTP over a socks proxy or CONNECT through HTTP proxy and the
|
||||
multi interface is used, libcurl will fail if the (passive) TCP connection
|
||||
for the data transfer isn't more or less instant as the code does not
|
||||
properly wait for the connect to be confirmed. See test case 564 for a first
|
||||
shot at a test case.
|
||||
|
||||
63. When CURLOPT_CONNECT_ONLY is used, the handle cannot reliably be re-used
|
||||
for any further requests or transfers. The work-around is then to close that
|
||||
handle with curl_easy_cleanup() and create a new. Some more details:
|
||||
http://curl.haxx.se/mail/lib-2009-04/0300.html
|
||||
|
||||
61. If an upload using Expect: 100-continue receives an HTTP 417 response,
|
||||
it ought to be automatically resent without the Expect:. A workaround is
|
||||
for the client application to redo the transfer after disabling Expect:.
|
||||
http://curl.haxx.se/mail/archive-2008-02/0043.html
|
||||
|
||||
60. libcurl closes the connection if an HTTP 401 reply is received while it
|
||||
is waiting for the the 100-continue response.
|
||||
http://curl.haxx.se/mail/lib-2008-08/0462.html
|
||||
|
||||
58. It seems sensible to be able to use CURLOPT_NOBODY and
|
||||
CURLOPT_FAILONERROR with FTP to detect if a file exists or not, but it is
|
||||
not working: http://curl.haxx.se/mail/lib-2008-07/0295.html
|
||||
|
||||
56. When libcurl sends CURLOPT_POSTQUOTE commands when connected to a SFTP
|
||||
server using the multi interface, the commands are not being sent correctly
|
||||
and instead the connection is "cancelled" (the operation is considered done)
|
||||
prematurely. There is a half-baked (busy-looping) patch provided in the bug
|
||||
report but it cannot be accepted as-is. See
|
||||
http://curl.haxx.se/bug/view.cgi?id=748
|
||||
|
||||
55. libcurl fails to build with MIT Kerberos for Windows (KfW) due to KfW's
|
||||
library header files exporting symbols/macros that should be kept private
|
||||
to the KfW library. See ticket #5601 at http://krbdev.mit.edu/rt/
|
||||
|
||||
52. Gautam Kachroo's issue that identifies a problem with the multi interface
|
||||
where a connection can be re-used without actually being properly
|
||||
SSL-negotiated:
|
||||
http://curl.haxx.se/mail/lib-2008-01/0277.html
|
||||
|
||||
49. If using --retry and the transfer timeouts (possibly due to using -m or
|
||||
-y/-Y) the next attempt doesn't resume the transfer properly from what was
|
||||
downloaded in the previous attempt but will truncate and restart at the
|
||||
original position where it was at before the previous failed attempt. See
|
||||
http://curl.haxx.se/mail/lib-2008-01/0080.html and Mandriva bug report
|
||||
https://qa.mandriva.com/show_bug.cgi?id=22565
|
||||
|
||||
48. If a CONNECT response-headers are larger than BUFSIZE (16KB) when the
|
||||
connection is meant to be kept alive (like for NTLM proxy auth), the
|
||||
function will return prematurely and will confuse the rest of the HTTP
|
||||
protocol code. This should be very rare.
|
||||
|
||||
43. There seems to be a problem when connecting to the Microsoft telnet server.
|
||||
http://curl.haxx.se/bug/view.cgi?id=649
|
||||
|
||||
41. When doing an operation over FTP that requires the ACCT command (but not
|
||||
when logging in), the operation will fail since libcurl doesn't detect this
|
||||
and thus fails to issue the correct command:
|
||||
http://curl.haxx.se/bug/view.cgi?id=635
|
||||
|
||||
39. Steffen Rumler's Race Condition in Curl_proxyCONNECT:
|
||||
http://curl.haxx.se/mail/lib-2007-01/0045.html
|
||||
|
||||
38. Kumar Swamy Bhatt's problem in ftp/ssl "LIST" operation:
|
||||
http://curl.haxx.se/mail/lib-2007-01/0103.html
|
||||
|
||||
35. Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very
|
||||
bad when used with the multi interface.
|
||||
|
||||
34. The SOCKS4 connection codes don't properly acknowledge (connect) timeouts.
|
||||
Also see #12. According to bug #1556528, even the SOCKS5 connect code does
|
||||
not do it right: http://curl.haxx.se/bug/view.cgi?id=604
|
||||
|
||||
31. "curl-config --libs" will include details set in LDFLAGS when configure is
|
||||
run that might be needed only for building libcurl. Further, curl-config
|
||||
--cflags suffers from the same effects with CFLAGS/CPPFLAGS.
|
||||
|
||||
26. NTLM authentication using SSPI (on Windows) when (lib)curl is running in
|
||||
"system context" will make it use wrong(?) user name - at least when compared
|
||||
to what winhttp does. See http://curl.haxx.se/bug/view.cgi?id=535
|
||||
|
||||
23. SOCKS-related problems:
|
||||
B) libcurl doesn't support FTPS over a SOCKS proxy.
|
||||
E) libcurl doesn't support active FTP over a SOCKS proxy
|
||||
|
||||
We probably have even more bugs and lack of features when a SOCKS proxy is
|
||||
used.
|
||||
|
||||
21. FTP ASCII transfers do not follow RFC959. They don't convert the data
|
||||
accordingly (not for sending nor for receiving). RFC 959 section 3.1.1.1
|
||||
clearly describes how this should be done:
|
||||
|
||||
The sender converts the data from an internal character representation to
|
||||
the standard 8-bit NVT-ASCII representation (see the Telnet
|
||||
specification). The receiver will convert the data from the standard
|
||||
form to his own internal form.
|
||||
|
||||
Since 7.15.4 at least line endings are converted.
|
||||
|
||||
16. FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>,
|
||||
<password>, and <fpath> components, encoded as "%00". The problem is that
|
||||
curl_unescape does not detect this, but instead returns a shortened C
|
||||
string. From a strict FTP protocol standpoint, NUL is a valid character
|
||||
within RFC 959 <string>, so the way to handle this correctly in curl would
|
||||
be to use a data structure other than a plain C string, one that can handle
|
||||
embedded NUL characters. From a practical standpoint, most FTP servers
|
||||
would not meaningfully support NUL characters within RFC 959 <string>,
|
||||
anyway (e.g., Unix pathnames may not contain NUL).
|
||||
|
||||
14. Test case 165 might fail on a system which has libidn present, but with an
|
||||
old iconv version (2.1.3 is a known bad version), since it doesn't recognize
|
||||
the charset when named ISO8859-1. Changing the name to ISO-8859-1 makes the
|
||||
test pass, but instead makes it fail on Solaris hosts that use its native
|
||||
iconv.
|
||||
|
||||
13. curl version 7.12.2 fails on AIX if compiled with --enable-ares.
|
||||
The workaround is to combine --enable-ares with --disable-shared
|
||||
|
||||
12. When connecting to a SOCKS proxy, the (connect) timeout is not properly
|
||||
acknowledged after the actual TCP connect (during the SOCKS "negotiate"
|
||||
phase).
|
||||
|
||||
10. To get HTTP Negotiate (SPNEGO) authentication to work fine, you need to
|
||||
provide a (fake) user name (this concerns both curl and the lib) because the
|
||||
code wrongly only considers authentication if there's a user name provided.
|
||||
http://curl.haxx.se/bug/view.cgi?id=440 How?
|
||||
http://curl.haxx.se/mail/lib-2004-08/0182.html
|
||||
|
||||
8. Doing resumed upload over HTTP does not work with '-C -', because curl
|
||||
doesn't do a HEAD first to get the initial size. This needs to be done
|
||||
manually for HTTP PUT resume to work, and then '-C [index]'.
|
||||
|
||||
6. libcurl ignores empty path parts in FTP URLs, whereas RFC1738 states that
|
||||
such parts should be sent to the server as 'CWD ' (without an argument).
|
||||
The only exception to this rule, is that we knowingly break this if the
|
||||
empty part is first in the path, as then we use the double slashes to
|
||||
indicate that the user wants to reach the root dir (this exception SHALL
|
||||
remain even when this bug is fixed).
|
||||
|
||||
5. libcurl doesn't treat the content-length of compressed data properly, as
|
||||
it seems HTTP servers send the *uncompressed* length in that header and
|
||||
libcurl thinks of it as the *compressed* length. Some explanations are here:
|
||||
http://curl.haxx.se/mail/lib-2003-06/0146.html
|
||||
|
||||
2. If a HTTP server responds to a HEAD request and includes a body (thus
|
||||
violating the RFC2616), curl won't wait to read the response but just stop
|
||||
reading and return back. If a second request (let's assume a GET) is then
|
||||
immediately made to the same server again, the connection will be re-used
|
||||
fine of course, and the second request will be sent off but when the
|
||||
response is to get read, the previous response-body is what curl will read
|
||||
and havoc is what happens.
|
||||
More details on this is found in this libcurl mailing list thread:
|
||||
http://curl.haxx.se/mail/lib-2002-08/0000.html
|
130
curl/docs/LICENSE-MIXING
Normal file
130
curl/docs/LICENSE-MIXING
Normal file
@ -0,0 +1,130 @@
|
||||
License Mixing with apps, libcurl and Third Party Libraries
|
||||
===========================================================
|
||||
|
||||
libcurl can be built to use a fair amount of various third party libraries,
|
||||
libraries that are written and provided by other parties that are distributed
|
||||
using their own licenses. Even libcurl itself contains code that may cause
|
||||
problems to some. This document attempts to describe what licenses libcurl and
|
||||
the other libraries use and what possible dilemmas linking and mixing them all
|
||||
can lead to for end users.
|
||||
|
||||
I am not a lawyer and this is not legal advice!
|
||||
|
||||
One common dilemma is that GPL[1]-licensed code is not allowed to be linked
|
||||
with code licensed under the Original BSD license (with the announcement
|
||||
clause). You may still build your own copies that use them all, but
|
||||
distributing them as binaries would be to violate the GPL license - unless you
|
||||
accompany your license with an exception[2]. This particular problem was
|
||||
addressed when the Modified BSD license was created, which does not have the
|
||||
announcement clause that collides with GPL.
|
||||
|
||||
libcurl http://curl.haxx.se/docs/copyright.html
|
||||
|
||||
Uses an MIT (or Modified BSD)-style license that is as liberal as
|
||||
possible.
|
||||
|
||||
OpenSSL https://www.openssl.org/source/license.html
|
||||
|
||||
(May be used for SSL/TLS support) Uses an Original BSD-style license
|
||||
with an announcement clause that makes it "incompatible" with GPL. You
|
||||
are not allowed to ship binaries that link with OpenSSL that includes
|
||||
GPL code (unless that specific GPL code includes an exception for
|
||||
OpenSSL - a habit that is growing more and more common). If OpenSSL's
|
||||
licensing is a problem for you, consider using another TLS library.
|
||||
|
||||
GnuTLS http://www.gnutls.org/
|
||||
|
||||
(May be used for SSL/TLS support) Uses the LGPL[3] license. If this is
|
||||
a problem for you, consider using another TLS library. Also note that
|
||||
GnuTLS itself depends on and uses other libs (libgcrypt and
|
||||
libgpg-error) and they too are LGPL- or GPL-licensed.
|
||||
|
||||
WolfSSL https://www.wolfssl.com/
|
||||
|
||||
(May be used for SSL/TLS support) Uses the GPL[1] license or a
|
||||
propietary license. If this is a problem for you, consider using
|
||||
another TLS library.
|
||||
|
||||
NSS https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS
|
||||
|
||||
(May be used for SSL/TLS support) Is covered by the MPL[4] license,
|
||||
the GPL[1] license and the LGPL[3] license. You may choose to license
|
||||
the code under MPL terms, GPL terms, or LGPL terms. These licenses
|
||||
grant you different permissions and impose different obligations. You
|
||||
should select the license that best meets your needs.
|
||||
|
||||
axTLS http://axtls.sourceforge.net/
|
||||
|
||||
(May be used for SSL/TLS support) Uses a Modified BSD-style license.
|
||||
|
||||
mbedTLS https://tls.mbed.org/
|
||||
|
||||
(May be used for SSL/TLS support) Uses the GPL[1] license or a
|
||||
propietary license. If this is a problem for you, consider using
|
||||
another TLS library.
|
||||
|
||||
BoringSSL https://boringssl.googlesource.com/
|
||||
|
||||
(May be used for SSL/TLS support) As an OpenSSL fork, it has the same
|
||||
license as that.
|
||||
|
||||
libressl http://www.libressl.org/
|
||||
|
||||
(May be used for SSL/TLS support) As an OpenSSL fork, it has the same
|
||||
license as that.
|
||||
|
||||
c-ares http://daniel.haxx.se/projects/c-ares/license.html
|
||||
|
||||
(Used for asynchronous name resolves) Uses an MIT license that is very
|
||||
liberal and imposes no restrictions on any other library or part you
|
||||
may link with.
|
||||
|
||||
zlib http://www.zlib.net/zlib_license.html
|
||||
|
||||
(Used for compressed Transfer-Encoding support) Uses an MIT-style
|
||||
license that shouldn't collide with any other library.
|
||||
|
||||
MIT Kerberos http://web.mit.edu/kerberos/www/dist/
|
||||
|
||||
(May be used for GSS support) MIT licensed, that shouldn't collide
|
||||
with any other parts.
|
||||
|
||||
Heimdal http://www.h5l.org
|
||||
|
||||
(May be used for GSS support) Heimdal is Original BSD licensed with
|
||||
the announcement clause.
|
||||
|
||||
GNU GSS https://www.gnu.org/software/gss/
|
||||
|
||||
(May be used for GSS support) GNU GSS is GPL licensed. Note that you
|
||||
may not distribute binary curl packages that uses this if you build
|
||||
curl to also link and use any Original BSD licensed libraries!
|
||||
|
||||
libidn http://josefsson.org/libidn/
|
||||
|
||||
(Used for IDNA support) Uses the GNU Lesser General Public
|
||||
License [3]. LGPL is a variation of GPL with slightly less aggressive
|
||||
"copyleft". This license requires more requirements to be met when
|
||||
distributing binaries, see the license for details. Also note that if
|
||||
you distribute a binary that includes this library, you must also
|
||||
include the full LGPL license text. Please properly point out what
|
||||
parts of the distributed package that the license addresses.
|
||||
|
||||
OpenLDAP http://www.openldap.org/software/release/license.html
|
||||
|
||||
(Used for LDAP support) Uses a Modified BSD-style license. Since
|
||||
libcurl uses OpenLDAP as a shared library only, I have not heard of
|
||||
anyone that ships OpenLDAP linked with libcurl in an app.
|
||||
|
||||
libssh2 http://www.libssh2.org/
|
||||
|
||||
(Used for scp and sftp support) libssh2 uses a Modified BSD-style
|
||||
license.
|
||||
|
||||
[1] = GPL - GNU General Public License: https://www.gnu.org/licenses/gpl.html
|
||||
[2] = https://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs details on
|
||||
how to write such an exception to the GPL
|
||||
[3] = LGPL - GNU Lesser General Public License:
|
||||
https://www.gnu.org/licenses/lgpl.html
|
||||
[4] = MPL - Mozilla Public License:
|
||||
https://www.mozilla.org/MPL/
|
265
curl/docs/MAIL-ETIQUETTE
Normal file
265
curl/docs/MAIL-ETIQUETTE
Normal file
@ -0,0 +1,265 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
MAIL ETIQUETTE
|
||||
|
||||
1. About the lists
|
||||
1.1 Mailing Lists
|
||||
1.2 Netiquette
|
||||
1.3 Do Not Mail a Single Individual
|
||||
1.4 Subscription Required
|
||||
1.5 Moderation of new posters
|
||||
1.6 Handling trolls and spam
|
||||
1.7 How to unsubscribe
|
||||
1.8 I posted, now what?
|
||||
|
||||
2. Sending mail
|
||||
2.1 Reply or New Mail
|
||||
2.2 Reply to the List
|
||||
2.3 Use a Sensible Subject
|
||||
2.4 Do Not Top-Post
|
||||
2.5 HTML is not for mails
|
||||
2.6 Quoting
|
||||
2.7 Digest
|
||||
2.8 Please Tell Us How You Solved The Problem!
|
||||
|
||||
==============================================================================
|
||||
|
||||
1. About the lists
|
||||
|
||||
1.1 Mailing Lists
|
||||
|
||||
The mailing lists we have are all listed and described at
|
||||
http://curl.haxx.se/mail/
|
||||
|
||||
Each mailing list is targeted to a specific set of users and subjects,
|
||||
please use the one or the ones that suit you the most.
|
||||
|
||||
Each mailing list have hundreds up to thousands of readers, meaning that
|
||||
each mail sent will be received and read by a very large amount of people.
|
||||
People from various cultures, regions, religions and continents.
|
||||
|
||||
1.2 Netiquette
|
||||
|
||||
Netiquette is a common name for how to behave on the internet. Of course, in
|
||||
each particular group and subculture there will be differences in what is
|
||||
acceptable and what is considered good manners.
|
||||
|
||||
This document outlines what we in the cURL project considers to be good
|
||||
etiquette, and primarily this focus on how to behave on and how to use our
|
||||
mailing lists.
|
||||
|
||||
1.3 Do Not Mail a Single Individual
|
||||
|
||||
Many people send one question to one person. One person gets many mails, and
|
||||
there is only one person who can give you a reply. The question may be
|
||||
something that other people are also wanting to ask. These other people have
|
||||
no way to read the reply, but to ask the one person the question. The one
|
||||
person consequently gets overloaded with mail.
|
||||
|
||||
If you really want to contact an individual and perhaps pay for his or her
|
||||
services, by all means go ahead, but if it's just another curl question,
|
||||
take it to a suitable list instead.
|
||||
|
||||
1.4 Subscription Required
|
||||
|
||||
All curl mailing lists require that you are subscribed to allow a mail to go
|
||||
through to all the subscribers.
|
||||
|
||||
If you post without being subscribed (or from a different mail address than
|
||||
the one you are subscribed with), your mail will simply be silently
|
||||
discarded. You have to subscribe first, then post.
|
||||
|
||||
The reason for this unfortunate and strict subscription policy is of course
|
||||
to stop spam from pestering the lists.
|
||||
|
||||
1.5 Moderation of new posters
|
||||
|
||||
Several of the curl mailing lists automatically make all posts from new
|
||||
subscribers require moderation. This means that after you've subscribed and
|
||||
send your first mail to a list, that mail will not be let through to the
|
||||
list until a mailing list administrator has verified that it is OK and
|
||||
permits it to get posted.
|
||||
|
||||
Once a first post has been made that proves the sender is actually talking
|
||||
about curl-related subjects, the moderation "flag" will be switched off and
|
||||
future posts will go through without being moderated.
|
||||
|
||||
The reason for this moderation policy is that we do suffer from spammers who
|
||||
actually subscribe and send spam to our lists.
|
||||
|
||||
1.6 Handling trolls and spam
|
||||
|
||||
Despite our good intentions and hard work to keep spam off the lists and to
|
||||
maintain a friendly and positive atmosphere, there will be times when spam
|
||||
and or trolls get through.
|
||||
|
||||
Troll - "someone who posts inflammatory, extraneous, or off-topic messages
|
||||
in an online community"
|
||||
|
||||
Spam - "use of electronic messaging systems to send unsolicited bulk
|
||||
messages"
|
||||
|
||||
No matter what, we NEVER EVER respond to trolls or spammers on the list. If
|
||||
you believe the list admin should do something particular, contact him/her
|
||||
off-list. The subject will be taken care of as good as possible to prevent
|
||||
repeated offenses, but responding on the list to such messages never lead to
|
||||
anything good and only puts the light even more on the offender: which was
|
||||
the entire purpose of it getting to the list in the first place.
|
||||
|
||||
Don't feed the trolls!
|
||||
|
||||
1.7 How to unsubscribe
|
||||
|
||||
You unsubscribe the same way you subscribed in the first place. You go to
|
||||
the page for the particular mailing list you're subscribed to and you enter
|
||||
your email address and password and press the unsubscribe button.
|
||||
|
||||
Also, this information is included in the headers of every mail that is sent
|
||||
out to all curl related mailing lists and there's footer in each mail that
|
||||
links to the "admin" page on which you can unsubscribe and change other
|
||||
options.
|
||||
|
||||
You NEVER EVER email the mailing list requesting someone else to get you off
|
||||
the list.
|
||||
|
||||
1.8 I posted, now what?
|
||||
|
||||
If you aren't subscribed with the exact same email address that you used to
|
||||
send the email, your post will just be silently discarded.
|
||||
|
||||
If you posted for the first time to the mailing list, you first need to wait
|
||||
for an administrator to allow your email to go through. This normally
|
||||
happens very quickly but in case we're asleep, you may have to wait a few
|
||||
hours.
|
||||
|
||||
Once your email goes through it is sent out to several hundred or even
|
||||
thousand recipients. Your email may cover an area that not that many people
|
||||
know about or are interested in. Or possibly the person who knows about it
|
||||
is on vacation or under a very heavy work load right now. You have to wait
|
||||
for a response and you must not expect to get a response at all, but
|
||||
hopefully you get an answer within a couple of days.
|
||||
|
||||
You do yourself and all of us a service when you include as many details as
|
||||
possible already in your first email. Mention your operating system and
|
||||
environment. Tell us which curl version you're using and tell us what you
|
||||
did, what happened and what you expected would happen. Preferably, show us
|
||||
what you did in details enough to allow others to help point out the problem
|
||||
or repeat the same steps in their places.
|
||||
|
||||
Failing to include details will only delay responses and make people respond
|
||||
and ask for the details and you have to send a follow-up email that includes
|
||||
them.
|
||||
|
||||
Expect the responses to primarily help YOU debug the issue, or ask you
|
||||
questions that can lead you or others towards a solution or explanation to
|
||||
whatever you experience.
|
||||
|
||||
If you are a repeat offender to the guidelines outlined in this document,
|
||||
chances are that people will ignore you at will and your chances to get
|
||||
responses will greatly diminish.
|
||||
|
||||
|
||||
2. Sending mail
|
||||
|
||||
2.1 Reply or New Mail
|
||||
|
||||
Please do not reply to an existing message as a short-cut to post a message
|
||||
to the lists.
|
||||
|
||||
Many mail programs and web archivers use information within mails to keep
|
||||
them together as "threads", as collections of posts that discuss a certain
|
||||
subject. If you don't intend to reply on the same or similar subject, don't
|
||||
just hit reply on an existing mail and change subject, create a new mail.
|
||||
|
||||
2.2 Reply to the List
|
||||
|
||||
When replying to a message from the list, make sure that you do "group
|
||||
reply" or "reply to all", and not just reply to the author of the single
|
||||
mail you reply to.
|
||||
|
||||
We're actively discouraging replying back to the single person by setting
|
||||
the Reply-To: field in outgoing mails back to the mailing list address,
|
||||
making it harder for people to mail the author only by mistake.
|
||||
|
||||
2.3 Use a Sensible Subject
|
||||
|
||||
Please use a subject of the mail that makes sense and that is related to the
|
||||
contents of your mail. It makes it a lot easier to find your mail afterwards
|
||||
and it makes it easier to track mail threads and topics.
|
||||
|
||||
2.4 Do Not Top-Post
|
||||
|
||||
If you reply to a message, don't use top-posting. Top-posting is when you
|
||||
write the new text at the top of a mail and you insert the previous quoted
|
||||
mail conversation below. It forces users to read the mail in a backwards
|
||||
order to properly understand it.
|
||||
|
||||
This is why top posting is so bad:
|
||||
|
||||
A: Because it messes up the order in which people normally read
|
||||
text.
|
||||
Q: Why is top-posting such a bad thing?
|
||||
A: Top-posting.
|
||||
Q: What is the most annoying thing in e-mail?
|
||||
|
||||
Apart from the screwed up read order (especially when mixed together in a
|
||||
thread when someone responds using the mandated bottom-posting style), it
|
||||
also makes it impossible to quote only parts of the original mail.
|
||||
|
||||
When you reply to a mail. You let the mail client insert the previous mail
|
||||
quoted. Then you put the cursor on the first line of the mail and you move
|
||||
down through the mail, deleting all parts of the quotes that don't add
|
||||
context for your comments. When you want to add a comment you do so, inline,
|
||||
right after the quotes that relate to your comment. Then you continue
|
||||
downwards again.
|
||||
|
||||
When most of the quotes have been removed and you've added your own words,
|
||||
you're done!
|
||||
|
||||
2.5 HTML is not for mails
|
||||
|
||||
Please switch off those HTML encoded messages. You can mail all those funny
|
||||
mails to your friends. We speak plain text mails.
|
||||
|
||||
2.6 Quoting
|
||||
|
||||
Quote as little as possible. Just enough to provide the context you cannot
|
||||
leave out. A lengthy description can be found here:
|
||||
|
||||
https://www.netmeister.org/news/learn2quote.html
|
||||
|
||||
2.7 Digest
|
||||
|
||||
We allow subscribers to subscribe to the "digest" version of the mailing
|
||||
lists. A digest is a collection of mails lumped together in one single mail.
|
||||
|
||||
Should you decide to reply to a mail sent out as a digest, there are two
|
||||
things you MUST consider if you really really cannot subscribe normally
|
||||
instead:
|
||||
|
||||
Cut off all mails and chatter that is not related to the mail you want to
|
||||
reply to.
|
||||
|
||||
Change the subject name to something sensible and related to the subject,
|
||||
preferably even the actual subject of the single mail you wanted to reply to
|
||||
|
||||
2.8 Please Tell Us How You Solved The Problem!
|
||||
|
||||
Many people mail questions to the list, people spend some of their time and
|
||||
make an effort in providing good answers to these questions.
|
||||
|
||||
If you are the one who asks, please consider responding once more in case
|
||||
one of the hints was what solved your problems. The guys who write answers
|
||||
feel good to know that they provided a good answer and that you fixed the
|
||||
problem. Far too often, the person who asked the question is never heard of
|
||||
again, and we never get to know if he/she is gone because the problem was
|
||||
solved or perhaps because the problem was unsolvable!
|
||||
|
||||
Getting the solution posted also helps other users that experience the same
|
||||
problem(s). They get to see (possibly in the web archives) that the
|
||||
suggested fixes actually has helped at least one person.
|
||||
|
1042
curl/docs/MANUAL
Normal file
1042
curl/docs/MANUAL
Normal file
File diff suppressed because it is too large
Load Diff
62
curl/docs/Makefile.am
Normal file
62
curl/docs/Makefile.am
Normal file
@ -0,0 +1,62 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
|
||||
man_MANS = curl.1 curl-config.1
|
||||
noinst_man_MANS = mk-ca-bundle.1
|
||||
GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html
|
||||
PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf
|
||||
|
||||
HTMLPAGES = $(GENHTMLPAGES) index.html
|
||||
|
||||
SUBDIRS = examples libcurl
|
||||
|
||||
CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES)
|
||||
|
||||
EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
|
||||
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
|
||||
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
|
||||
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \
|
||||
MAIL-ETIQUETTE HTTP-COOKIES SECURITY RELEASE-PROCEDURE \
|
||||
SSL-PROBLEMS HTTP2.md ROADMAP.md
|
||||
|
||||
MAN2HTML= roffit < $< >$@
|
||||
|
||||
SUFFIXES = .1 .html .pdf
|
||||
|
||||
html: $(HTMLPAGES)
|
||||
cd libcurl; make html
|
||||
|
||||
pdf: $(PDFPAGES)
|
||||
cd libcurl; make pdf
|
||||
|
||||
.1.html:
|
||||
$(MAN2HTML)
|
||||
|
||||
.1.pdf:
|
||||
@(foo=`echo $@ | sed -e 's/\.[0-9]$$//g'`; \
|
||||
groff -Tps -man $< >$$foo.ps; \
|
||||
ps2pdf $$foo.ps $@; \
|
||||
rm $$foo.ps; \
|
||||
echo "converted $< to $@")
|
||||
|
822
curl/docs/Makefile.in
Normal file
822
curl/docs/Makefile.in
Normal file
@ -0,0 +1,822 @@
|
||||
# Makefile.in generated by automake 1.14.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
subdir = docs
|
||||
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am INSTALL \
|
||||
THANKS TODO
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/curl-compilers.m4 \
|
||||
$(top_srcdir)/m4/curl-confopts.m4 \
|
||||
$(top_srcdir)/m4/curl-functions.m4 \
|
||||
$(top_srcdir)/m4/curl-openssl.m4 \
|
||||
$(top_srcdir)/m4/curl-override.m4 \
|
||||
$(top_srcdir)/m4/curl-reentrant.m4 $(top_srcdir)/m4/libtool.m4 \
|
||||
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
|
||||
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
|
||||
$(top_srcdir)/m4/xc-am-iface.m4 \
|
||||
$(top_srcdir)/m4/xc-cc-check.m4 \
|
||||
$(top_srcdir)/m4/xc-lt-iface.m4 \
|
||||
$(top_srcdir)/m4/xc-translit.m4 \
|
||||
$(top_srcdir)/m4/xc-val-flgs.m4 \
|
||||
$(top_srcdir)/m4/zz40-xc-ovr.m4 \
|
||||
$(top_srcdir)/m4/zz50-xc-ovr.m4 \
|
||||
$(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/lib/curl_config.h \
|
||||
$(top_builddir)/include/curl/curlbuild.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
depcomp =
|
||||
am__depfiles_maybe =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
|
||||
ctags-recursive dvi-recursive html-recursive info-recursive \
|
||||
install-data-recursive install-dvi-recursive \
|
||||
install-exec-recursive install-html-recursive \
|
||||
install-info-recursive install-pdf-recursive \
|
||||
install-ps-recursive install-recursive installcheck-recursive \
|
||||
installdirs-recursive pdf-recursive ps-recursive \
|
||||
tags-recursive uninstall-recursive
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
man1dir = $(mandir)/man1
|
||||
am__installdirs = "$(DESTDIR)$(man1dir)"
|
||||
MANS = $(man_MANS)
|
||||
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
|
||||
distclean-recursive maintainer-clean-recursive
|
||||
am__recursive_targets = \
|
||||
$(RECURSIVE_TARGETS) \
|
||||
$(RECURSIVE_CLEAN_TARGETS) \
|
||||
$(am__extra_recursive_targets)
|
||||
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
|
||||
distdir
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
am__uniquify_input = $(AWK) '\
|
||||
BEGIN { nonempty = 0; } \
|
||||
{ items[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in items) print i; }; } \
|
||||
'
|
||||
# Make sure the list of sources is unique. This is necessary because,
|
||||
# e.g., the same source file might be shared among _SOURCES variables
|
||||
# for different programs/libraries.
|
||||
am__define_uniq_tagged_files = \
|
||||
list='$(am__tagged_files)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DIST_SUBDIRS = $(SUBDIRS)
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
am__relativize = \
|
||||
dir0=`pwd`; \
|
||||
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
|
||||
sed_rest='s,^[^/]*/*,,'; \
|
||||
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
|
||||
sed_butlast='s,/*[^/]*$$,,'; \
|
||||
while test -n "$$dir1"; do \
|
||||
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
|
||||
if test "$$first" != "."; then \
|
||||
if test "$$first" = ".."; then \
|
||||
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
|
||||
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
|
||||
else \
|
||||
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
|
||||
if test "$$first2" = "$$first"; then \
|
||||
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
|
||||
else \
|
||||
dir2="../$$dir2"; \
|
||||
fi; \
|
||||
dir0="$$dir0"/"$$first"; \
|
||||
fi; \
|
||||
fi; \
|
||||
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
|
||||
done; \
|
||||
reldir="$$dir2"
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
AS = @AS@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BLANK_AT_MAKETIME = @BLANK_AT_MAKETIME@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@
|
||||
CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@
|
||||
CURLVERSION = @CURLVERSION@
|
||||
CURL_CA_BUNDLE = @CURL_CA_BUNDLE@
|
||||
CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@
|
||||
CURL_DISABLE_DICT = @CURL_DISABLE_DICT@
|
||||
CURL_DISABLE_FILE = @CURL_DISABLE_FILE@
|
||||
CURL_DISABLE_FTP = @CURL_DISABLE_FTP@
|
||||
CURL_DISABLE_GOPHER = @CURL_DISABLE_GOPHER@
|
||||
CURL_DISABLE_HTTP = @CURL_DISABLE_HTTP@
|
||||
CURL_DISABLE_IMAP = @CURL_DISABLE_IMAP@
|
||||
CURL_DISABLE_LDAP = @CURL_DISABLE_LDAP@
|
||||
CURL_DISABLE_LDAPS = @CURL_DISABLE_LDAPS@
|
||||
CURL_DISABLE_POP3 = @CURL_DISABLE_POP3@
|
||||
CURL_DISABLE_PROXY = @CURL_DISABLE_PROXY@
|
||||
CURL_DISABLE_RTSP = @CURL_DISABLE_RTSP@
|
||||
CURL_DISABLE_SMB = @CURL_DISABLE_SMB@
|
||||
CURL_DISABLE_SMTP = @CURL_DISABLE_SMTP@
|
||||
CURL_DISABLE_TELNET = @CURL_DISABLE_TELNET@
|
||||
CURL_DISABLE_TFTP = @CURL_DISABLE_TFTP@
|
||||
CURL_LT_SHLIB_VERSIONED_FLAVOUR = @CURL_LT_SHLIB_VERSIONED_FLAVOUR@
|
||||
CURL_NETWORK_AND_TIME_LIBS = @CURL_NETWORK_AND_TIME_LIBS@
|
||||
CURL_NETWORK_LIBS = @CURL_NETWORK_LIBS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ENABLE_SHARED = @ENABLE_SHARED@
|
||||
ENABLE_STATIC = @ENABLE_STATIC@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@
|
||||
HAVE_LDAP_SSL = @HAVE_LDAP_SSL@
|
||||
HAVE_LIBZ = @HAVE_LIBZ@
|
||||
HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@
|
||||
IDN_ENABLED = @IDN_ENABLED@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
IPV6_ENABLED = @IPV6_ENABLED@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBCURL_LIBS = @LIBCURL_LIBS@
|
||||
LIBMETALINK_CPPFLAGS = @LIBMETALINK_CPPFLAGS@
|
||||
LIBMETALINK_LDFLAGS = @LIBMETALINK_LDFLAGS@
|
||||
LIBMETALINK_LIBS = @LIBMETALINK_LIBS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MANOPT = @MANOPT@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
NROFF = @NROFF@
|
||||
NSS_LIBS = @NSS_LIBS@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PERL = @PERL@
|
||||
PKGADD_NAME = @PKGADD_NAME@
|
||||
PKGADD_PKG = @PKGADD_PKG@
|
||||
PKGADD_VENDOR = @PKGADD_VENDOR@
|
||||
PKGCONFIG = @PKGCONFIG@
|
||||
RANDOM_FILE = @RANDOM_FILE@
|
||||
RANLIB = @RANLIB@
|
||||
REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
SSL_ENABLED = @SSL_ENABLED@
|
||||
SSL_LIBS = @SSL_LIBS@
|
||||
STRIP = @STRIP@
|
||||
SUPPORT_FEATURES = @SUPPORT_FEATURES@
|
||||
SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@
|
||||
USE_ARES = @USE_ARES@
|
||||
USE_AXTLS = @USE_AXTLS@
|
||||
USE_CYASSL = @USE_CYASSL@
|
||||
USE_DARWINSSL = @USE_DARWINSSL@
|
||||
USE_GNUTLS = @USE_GNUTLS@
|
||||
USE_GNUTLS_NETTLE = @USE_GNUTLS_NETTLE@
|
||||
USE_LIBRTMP = @USE_LIBRTMP@
|
||||
USE_LIBSSH2 = @USE_LIBSSH2@
|
||||
USE_NGHTTP2 = @USE_NGHTTP2@
|
||||
USE_NSS = @USE_NSS@
|
||||
USE_OPENLDAP = @USE_OPENLDAP@
|
||||
USE_POLARSSL = @USE_POLARSSL@
|
||||
USE_SCHANNEL = @USE_SCHANNEL@
|
||||
USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@
|
||||
USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@
|
||||
VERSION = @VERSION@
|
||||
VERSIONNUM = @VERSIONNUM@
|
||||
ZLIB_LIBS = @ZLIB_LIBS@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
libext = @libext@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
subdirs = @subdirs@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
man_MANS = curl.1 curl-config.1
|
||||
noinst_man_MANS = mk-ca-bundle.1
|
||||
GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html
|
||||
PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf
|
||||
HTMLPAGES = $(GENHTMLPAGES) index.html
|
||||
SUBDIRS = examples libcurl
|
||||
CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES)
|
||||
EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
|
||||
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
|
||||
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
|
||||
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \
|
||||
MAIL-ETIQUETTE HTTP-COOKIES SECURITY RELEASE-PROCEDURE \
|
||||
SSL-PROBLEMS HTTP2.md ROADMAP.md
|
||||
|
||||
MAN2HTML = roffit < $< >$@
|
||||
SUFFIXES = .1 .html .pdf
|
||||
all: all-recursive
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .1 .html .pdf
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign docs/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign docs/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
install-man1: $(man_MANS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list1=''; \
|
||||
list2='$(man_MANS)'; \
|
||||
test -n "$(man1dir)" \
|
||||
&& test -n "`echo $$list1$$list2`" \
|
||||
|| exit 0; \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
|
||||
{ for i in $$list1; do echo "$$i"; done; \
|
||||
if test -n "$$list2"; then \
|
||||
for i in $$list2; do echo "$$i"; done \
|
||||
| sed -n '/\.1[a-z]*$$/p'; \
|
||||
fi; \
|
||||
} | while read p; do \
|
||||
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; echo "$$p"; \
|
||||
done | \
|
||||
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
|
||||
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
|
||||
sed 'N;N;s,\n, ,g' | { \
|
||||
list=; while read file base inst; do \
|
||||
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
|
||||
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
|
||||
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
|
||||
fi; \
|
||||
done; \
|
||||
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
test -z "$$files" || { \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
|
||||
done; }
|
||||
|
||||
uninstall-man1:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list=''; test -n "$(man1dir)" || exit 0; \
|
||||
files=`{ for i in $$list; do echo "$$i"; done; \
|
||||
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
|
||||
sed -n '/\.1[a-z]*$$/p'; \
|
||||
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
|
||||
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
|
||||
dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run 'make' without going through this Makefile.
|
||||
# To change the values of 'make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in 'config.status', edit 'config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run 'make');
|
||||
# (2) otherwise, pass the desired values on the 'make' command line.
|
||||
$(am__recursive_targets):
|
||||
@fail=; \
|
||||
if $(am__make_keepgoing); then \
|
||||
failcom='fail=yes'; \
|
||||
else \
|
||||
failcom='exit 1'; \
|
||||
fi; \
|
||||
dot_seen=no; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
case "$@" in \
|
||||
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||
*) list='$(SUBDIRS)' ;; \
|
||||
esac; \
|
||||
for subdir in $$list; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
dot_seen=yes; \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| eval $$failcom; \
|
||||
done; \
|
||||
if test "$$dot_seen" = "no"; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||
fi; test -z "$$fail"
|
||||
|
||||
ID: $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||
tags: tags-recursive
|
||||
TAGS: tags
|
||||
|
||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
|
||||
include_option=--etags-include; \
|
||||
empty_fix=.; \
|
||||
else \
|
||||
include_option=--include; \
|
||||
empty_fix=; \
|
||||
fi; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test ! -f $$subdir/TAGS || \
|
||||
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
|
||||
fi; \
|
||||
done; \
|
||||
$(am__define_uniq_tagged_files); \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: ctags-recursive
|
||||
|
||||
CTAGS: ctags
|
||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
cscopelist: cscopelist-recursive
|
||||
|
||||
cscopelist-am: $(am__tagged_files)
|
||||
list='$(am__tagged_files)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
$(am__make_dryrun) \
|
||||
|| test -d "$(distdir)/$$subdir" \
|
||||
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|
||||
|| exit 1; \
|
||||
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
|
||||
$(am__relativize); \
|
||||
new_distdir=$$reldir; \
|
||||
dir1=$$subdir; dir2="$(top_distdir)"; \
|
||||
$(am__relativize); \
|
||||
new_top_distdir=$$reldir; \
|
||||
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
|
||||
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
|
||||
($(am__cd) $$subdir && \
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$$new_top_distdir" \
|
||||
distdir="$$new_distdir" \
|
||||
am__remove_distdir=: \
|
||||
am__skip_length_check=: \
|
||||
am__skip_mode_fix=: \
|
||||
distdir) \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-recursive
|
||||
all-am: Makefile $(MANS)
|
||||
installdirs: installdirs-recursive
|
||||
installdirs-am:
|
||||
for dir in "$(DESTDIR)$(man1dir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-recursive
|
||||
install-exec: install-exec-recursive
|
||||
install-data: install-data-recursive
|
||||
uninstall: uninstall-recursive
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-recursive
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-recursive
|
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-recursive
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic distclean-tags
|
||||
|
||||
dvi: dvi-recursive
|
||||
|
||||
dvi-am:
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-recursive
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-man
|
||||
|
||||
install-dvi: install-dvi-recursive
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-recursive
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-recursive
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man: install-man1
|
||||
|
||||
install-pdf: install-pdf-recursive
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-recursive
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-recursive
|
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-recursive
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-man
|
||||
|
||||
uninstall-man: uninstall-man1
|
||||
|
||||
.MAKE: $(am__recursive_targets) install-am install-strip
|
||||
|
||||
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
|
||||
check-am clean clean-generic clean-libtool cscopelist-am ctags \
|
||||
ctags-am distclean distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-man1 install-pdf install-pdf-am install-ps \
|
||||
install-ps-am install-strip installcheck installcheck-am \
|
||||
installdirs installdirs-am maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-generic \
|
||||
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
|
||||
uninstall-am uninstall-man uninstall-man1
|
||||
|
||||
|
||||
html: $(HTMLPAGES)
|
||||
cd libcurl; make html
|
||||
|
||||
pdf: $(PDFPAGES)
|
||||
cd libcurl; make pdf
|
||||
|
||||
.1.html:
|
||||
$(MAN2HTML)
|
||||
|
||||
.1.pdf:
|
||||
@(foo=`echo $@ | sed -e 's/\.[0-9]$$//g'`; \
|
||||
groff -Tps -man $< >$$foo.ps; \
|
||||
ps2pdf $$foo.ps $@; \
|
||||
rm $$foo.ps; \
|
||||
echo "converted $< to $@")
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
27
curl/docs/README.netware
Normal file
27
curl/docs/README.netware
Normal file
@ -0,0 +1,27 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
README.netware
|
||||
|
||||
Read the README file first.
|
||||
|
||||
Curl has been successfully compiled with gcc / nlmconv on different flavours
|
||||
of Linux as well as with the official Metrowerks CodeWarrior compiler.
|
||||
While not being the main development target, a continuously growing share of
|
||||
curl users are NetWare-based, specially also consuming the lib from PHP.
|
||||
|
||||
The unix-style man pages are tricky to read on windows, so therefore are all
|
||||
those pages converted to HTML as well as pdf, and included in the release
|
||||
archives.
|
||||
|
||||
The main curl.1 man page is also "built-in" in the command line tool. Use a
|
||||
command line similar to this in order to extract a separate text file:
|
||||
|
||||
curl -M >manual.txt
|
||||
|
||||
Read the INSTALL file for instructions how to compile curl self.
|
||||
|
||||
|
26
curl/docs/README.win32
Normal file
26
curl/docs/README.win32
Normal file
@ -0,0 +1,26 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
README.win32
|
||||
|
||||
Read the README file first.
|
||||
|
||||
Curl has been compiled, built and run on all sorts of Windows and win32
|
||||
systems. While not being the main develop target, a fair share of curl users
|
||||
are win32-based.
|
||||
|
||||
The unix-style man pages are tricky to read on windows, so therefore are all
|
||||
those pages converted to HTML as well as pdf, and included in the release
|
||||
archives.
|
||||
|
||||
The main curl.1 man page is also "built-in" in the command line tool. Use a
|
||||
command line similar to this in order to extract a separate text file:
|
||||
|
||||
curl -M >manual.txt
|
||||
|
||||
Read the INSTALL file for instructions how to compile curl self.
|
||||
|
||||
|
89
curl/docs/RELEASE-PROCEDURE
Normal file
89
curl/docs/RELEASE-PROCEDURE
Normal file
@ -0,0 +1,89 @@
|
||||
curl release procedure - how to do a release
|
||||
============================================
|
||||
|
||||
in the source code repo
|
||||
-----------------------
|
||||
|
||||
- edit `RELEASE-NOTES` to be accurate
|
||||
|
||||
- update `docs/THANKS`
|
||||
|
||||
- make sure all relevant changes are committed on the master branch
|
||||
|
||||
- tag the git repo in this style: `git tag -a curl-7_34_0`. -a annotates the
|
||||
tag and we use underscores instead of dots in the version number.
|
||||
|
||||
- run "./maketgz 7.34.0" to build the release tarballs. It is important that
|
||||
you run this on a machine with the correct set of autotools etc installed
|
||||
as this is what then will be shipped and used by most users on *nix like
|
||||
systems.
|
||||
|
||||
- push the git commits and the new tag
|
||||
|
||||
- gpg sign the 4 tarballs as maketgz suggests
|
||||
|
||||
- upload the 8 resulting files to the primary download directory
|
||||
|
||||
in the curl-www repo
|
||||
--------------------
|
||||
|
||||
- edit `Makefile` (version number and date),
|
||||
|
||||
- edit `_newslog.html` (announce the new release) and
|
||||
|
||||
- edit `_changes.html` (insert changes+bugfixes from RELEASE-NOTES)
|
||||
|
||||
- commit all local changes
|
||||
|
||||
- tag the repo with the same tag as used for the source repo
|
||||
|
||||
- make sure all relevant changes are committed and pushed on the master branch
|
||||
|
||||
(the web site then updates its contents automatically)
|
||||
|
||||
inform
|
||||
------
|
||||
|
||||
- send an email to curl-users, curl-announce and curl-library. Insert the
|
||||
RELEASE-NOTES into the mail.
|
||||
|
||||
celebrate
|
||||
---------
|
||||
|
||||
- suitable beverage intake is encouraged for the festivities
|
||||
|
||||
curl release scheduling
|
||||
=======================
|
||||
|
||||
Basics
|
||||
------
|
||||
|
||||
We do releases every 8 weeks on Wednesdays. If critical problems arise, we can
|
||||
insert releases outside of the schedule or we can move the release date - but
|
||||
this is very rare.
|
||||
|
||||
Each 8 week release cycle is split in two 4-week periods.
|
||||
|
||||
- During the first 4 weeks after a release, we allow new features and changes
|
||||
to curl and libcurl. If we accept any such changes, we bump the minor number
|
||||
used for the next release.
|
||||
|
||||
- During the second 4-week period we do not merge any features or changes, we
|
||||
then only focus on fixing bugs and polishing things to make a solid coming
|
||||
release.
|
||||
|
||||
Coming dates
|
||||
------------
|
||||
|
||||
Based on the description above, here are some planned release dates (at the
|
||||
time of this writing):
|
||||
|
||||
- June 17, 2015 (version 7.43.0)
|
||||
- August 12, 2015
|
||||
- October 7, 2015
|
||||
- December 2, 2015
|
||||
- January 27, 2016
|
||||
- March 23, 2016
|
||||
- May 18, 2016
|
||||
- July 13, 2016
|
||||
- September 7, 2016
|
83
curl/docs/RESOURCES
Normal file
83
curl/docs/RESOURCES
Normal file
@ -0,0 +1,83 @@
|
||||
_ _ ____ _
|
||||
Project ___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
|
||||
This document lists documents and standards used by curl.
|
||||
|
||||
RFC 959 - The FTP protocol
|
||||
|
||||
RFC 1635 - How to Use Anonymous FTP
|
||||
|
||||
RFC 1738 - Uniform Resource Locators
|
||||
|
||||
RFC 1777 - defines the LDAP protocol
|
||||
|
||||
RFC 1808 - Relative Uniform Resource Locators
|
||||
|
||||
RFC 1867 - Form-based File Upload in HTML
|
||||
|
||||
RFC 1950 - ZLIB Compressed Data Format Specification
|
||||
|
||||
RFC 1951 - DEFLATE Compressed Data Format Specification
|
||||
|
||||
RFC 1952 - gzip compression format
|
||||
|
||||
RFC 1959 - LDAP URL syntax
|
||||
|
||||
RFC 2045-2049 - Everything you need to know about MIME! (needed for form
|
||||
based upload)
|
||||
|
||||
RFC 2068 - HTTP 1.1 (obsoleted by RFC 2616)
|
||||
|
||||
RFC 2104 - Keyed-Hashing for Message Authentication
|
||||
|
||||
RFC 2109 - HTTP State Management Mechanism (cookie stuff)
|
||||
- Also, read Netscape's specification at
|
||||
http://curl.haxx.se/rfc/cookie_spec.html
|
||||
|
||||
RFC 2183 - The Content-Disposition Header Field
|
||||
|
||||
RFC 2195 - CRAM-MD5 authentication
|
||||
|
||||
RFC 2229 - A Dictionary Server Protocol
|
||||
|
||||
RFC 2255 - Newer LDAP URL syntax document.
|
||||
|
||||
RFC 2231 - MIME Parameter Value and Encoded Word Extensions:
|
||||
Character Sets, Languages, and Continuations
|
||||
|
||||
RFC 2388 - "Returning Values from Forms: multipart/form-data"
|
||||
Use this as an addition to the RFC1867
|
||||
|
||||
RFC 2396 - "Uniform Resource Identifiers: Generic Syntax and Semantics" This
|
||||
one obsoletes RFC 1738, but since RFC 1738 is often mentioned
|
||||
I've left it in this list.
|
||||
|
||||
RFC 2428 - FTP Extensions for IPv6 and NATs
|
||||
|
||||
RFC 2577 - FTP Security Considerations
|
||||
|
||||
RFC 2616 - HTTP 1.1, the latest
|
||||
|
||||
RFC 2617 - HTTP Authentication
|
||||
|
||||
RFC 2718 - Guidelines for new URL Schemes
|
||||
|
||||
RFC 2732 - Format for Literal IPv6 Addresses in URL's
|
||||
|
||||
RFC 2818 - HTTP Over TLS (TLS is the successor to SSL)
|
||||
|
||||
RFC 2821 - SMTP protocol
|
||||
|
||||
RFC 2964 - Use of HTTP State Management
|
||||
|
||||
RFC 2965 - HTTP State Management Mechanism. Cookies. Obsoletes RFC2109
|
||||
|
||||
RFC 3207 - SMTP over TLS
|
||||
|
||||
RFC 4616 - PLAIN authentication
|
||||
|
||||
RFC 4954 - SMTP Authentication
|
139
curl/docs/ROADMAP.md
Normal file
139
curl/docs/ROADMAP.md
Normal file
@ -0,0 +1,139 @@
|
||||
curl the next few years - perhaps
|
||||
=================================
|
||||
|
||||
Roadmap of things Daniel Stenberg and Steve Holme want to work on next. It is
|
||||
intended to serve as a guideline for others for information, feedback and
|
||||
possible participation.
|
||||
|
||||
HTTP/2
|
||||
------
|
||||
|
||||
- test suite
|
||||
|
||||
Base this on existing nghttp2 server to start with to make functional
|
||||
tests. Later on we can adopt that code or work with nghttp2 to provide ways
|
||||
to have the http2 server respond with broken responses to make sure we deal
|
||||
with that nicely as well.
|
||||
|
||||
To decide: if we need to bundle parts of the nghttp2 stuff that probably
|
||||
won't be shipped by many distros.
|
||||
|
||||
- stream properties API
|
||||
|
||||
Provide options for setting priorities and dependencies among the streams
|
||||
(easy handles). They are mostly information set for the stream and sent to
|
||||
the server so we don't have to add much logic for this.
|
||||
|
||||
- server push
|
||||
|
||||
Not exactly clear exactly how to support this API-wise, but by adding
|
||||
handles without asking for a resource it could be a way to be prepared to
|
||||
receive pushes in case such are sent. We probably need it to still specify
|
||||
a URL with host name, port etc but we probably need a special option to
|
||||
tell libcurl it is for server push purposes.
|
||||
|
||||
- provide option for HTTP/2 "prior knowledge" over clear text
|
||||
|
||||
As it would avoid the roundtrip-heavy Upgrade: procedures when you _know_
|
||||
it speaks HTTP/2.
|
||||
|
||||
- provide option to allow curl to default to HTTP/2 only when using HTTPS
|
||||
|
||||
We could switch on HTTP/2 by-default for HTTPS quite easily and it
|
||||
shouldn't hurt anyone, while HTTP/2 for HTTP by default could introduce
|
||||
lots of Upgrade: roundtrips that users won't like. So a separated option
|
||||
alternative makes sense.
|
||||
|
||||
SRV records
|
||||
-----------
|
||||
|
||||
How to find services for specific domains/hosts.
|
||||
|
||||
HTTPS to proxy
|
||||
--------------
|
||||
|
||||
To avoid network traffic to/from the proxy getting snooped on.
|
||||
|
||||
curl_formadd()
|
||||
--------------
|
||||
|
||||
make sure there's an easy handle passed in to `curl_formadd()`,
|
||||
`curl_formget()` and `curl_formfree()` by adding replacement functions and
|
||||
deprecating the old ones to allow custom mallocs and more
|
||||
|
||||
third-party SASL
|
||||
----------------
|
||||
|
||||
add support for third-party SASL libraries such as Cyrus SASL - may need to
|
||||
move existing native and SSPI based authentication into vsasl folder after
|
||||
reworking HTTP and SASL code
|
||||
|
||||
SASL authentication in LDAP
|
||||
---------------------------
|
||||
|
||||
...
|
||||
|
||||
Simplify the SMTP email
|
||||
-----------------------
|
||||
|
||||
Simplify the SMTP email interface so that programmers don't have to
|
||||
construct the body of an email that contains all the headers, alternative
|
||||
content, images and attachments - maintain raw interface so that
|
||||
programmers that want to do this can
|
||||
|
||||
email capabilities
|
||||
------------------
|
||||
|
||||
Allow the email protocols to return the capabilities before
|
||||
authenticating. This will allow an application to decide on the best
|
||||
authentication mechanism
|
||||
|
||||
Win32 pthreads
|
||||
--------------
|
||||
|
||||
Allow Windows threading model to be replaced by Win32 pthreads port
|
||||
|
||||
dynamic buffer size
|
||||
-------------------
|
||||
|
||||
Implement a dynamic buffer size to allow SFTP to use much larger buffers and
|
||||
possibly allow the size to be customizable by applications. Use less memory
|
||||
when handles are not in use?
|
||||
|
||||
New stuff - curl
|
||||
----------------
|
||||
|
||||
1. Embed a language interpreter (lua?). For that middle ground where curl
|
||||
isn’t enough and a libcurl binding feels “too much”. Build-time conditional
|
||||
of course.
|
||||
|
||||
2. Simplify the SMTP command line so that the headers and multi-part content
|
||||
don't have to be constructed before calling curl
|
||||
|
||||
Improve
|
||||
-------
|
||||
|
||||
1. build for windows (considered hard by many users)
|
||||
|
||||
2. curl -h output (considered overwhelming to users)
|
||||
|
||||
3. we have > 160 command line options, is there a way to redo things to
|
||||
simplify or improve the situation as we are likely to keep adding
|
||||
features/options in the future too
|
||||
|
||||
4. docs (considered "bad" by users but how do we make it better?)
|
||||
|
||||
- split up curl.1
|
||||
|
||||
5. authentication framework (consider merging HTTP and SASL authentication to
|
||||
give one API for protocols to call)
|
||||
|
||||
6. Perform some of the clean up from the TODO document, removing old
|
||||
definitions and such like that are currently earmarked to be removed years
|
||||
ago
|
||||
|
||||
Remove
|
||||
------
|
||||
|
||||
1. makefile.vc files as there is no point in maintaining two sets of Windows
|
||||
makefiles. Note: These are currently being used by the Windows autobuilds
|
107
curl/docs/SECURITY
Normal file
107
curl/docs/SECURITY
Normal file
@ -0,0 +1,107 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
curl security for developers
|
||||
============================
|
||||
|
||||
This document is intended to provide guidance to curl developers on how
|
||||
security vulnerabilities should be handled.
|
||||
|
||||
Publishing Information
|
||||
----------------------
|
||||
|
||||
All known and public curl or libcurl related vulnerabilities are listed on
|
||||
[the curl web site security page](http://curl.haxx.se/docs/security.html).
|
||||
|
||||
Security vulnerabilities should not be entered in the project's public bug
|
||||
tracker unless the necessary configuration is in place to limit access to the
|
||||
issue to only the reporter and the project's security team.
|
||||
|
||||
Vulnerability Handling
|
||||
----------------------
|
||||
|
||||
The typical process for handling a new security vulnerability is as follows.
|
||||
|
||||
No information should be made public about a vulnerability until it is
|
||||
formally announced at the end of this process. That means, for example that a
|
||||
bug tracker entry must NOT be created to track the issue since that will make
|
||||
the issue public and it should not be discussed on any of the project's public
|
||||
mailing lists. Also messages associated with any commits should not make
|
||||
any reference to the security nature of the commit if done prior to the public
|
||||
announcement.
|
||||
|
||||
- The person discovering the issue, the reporter, reports the vulnerability
|
||||
privately to `curl-security@haxx.se`. That's an email alias that reaches a
|
||||
handful of selected and trusted people.
|
||||
|
||||
- Messages that do not relate to the reporting or managing of an undisclosed
|
||||
security vulnerability in curl or libcurl are ignored and no further action
|
||||
is required.
|
||||
|
||||
- A person in the security team sends an e-mail to the original reporter to
|
||||
acknowledge the report.
|
||||
|
||||
- The security team investigates the report and either rejects it or accepts
|
||||
it.
|
||||
|
||||
- If the report is rejected, the team writes to the reporter to explain why.
|
||||
|
||||
- If the report is accepted, the team writes to the reporter to let him/her
|
||||
know it is accepted and that they are working on a fix.
|
||||
|
||||
- The security team discusses the problem, works out a fix, considers the
|
||||
impact of the problem and suggests a release schedule. This discussion
|
||||
should involve the reporter as much as possible.
|
||||
|
||||
- The release of the information should be "as soon as possible" and is most
|
||||
often synced with an upcoming release that contains the fix. If the
|
||||
reporter, or anyone else, thinks the next planned release is too far away
|
||||
then a separate earlier release for security reasons should be considered.
|
||||
|
||||
- Write a security advisory draft about the problem that explains what the
|
||||
problem is, its impact, which versions it affects, solutions or
|
||||
workarounds, when the release is out and make sure to credit all
|
||||
contributors properly.
|
||||
|
||||
- Request a CVE number from distros@openwall[1] when also informing and
|
||||
preparing them for the upcoming public security vulnerability announcement -
|
||||
attach the advisory draft for information. Note that 'distros' won't accept
|
||||
an embargo longer than 19 days.
|
||||
|
||||
- Update the "security advisory" with the CVE number.
|
||||
|
||||
- The security team commits the fix in a private branch. The commit message
|
||||
should ideally contain the CVE number. This fix is usually also distributed
|
||||
to the 'distros' mailing list to allow them to use the fix prior to the
|
||||
public announcement.
|
||||
|
||||
- At the day of the next release, the private branch is merged into the master
|
||||
branch and pushed. Once pushed, the information is accessible to the public
|
||||
and the actual release should follow suit immediately afterwards.
|
||||
|
||||
- The project team creates a release that includes the fix.
|
||||
|
||||
- The project team announces the release and the vulnerability to the world in
|
||||
the same manner we always announce releases. It gets sent to the
|
||||
curl-announce, curl-library and curl-users mailing lists.
|
||||
|
||||
- The security web page on the web site should get the new vulnerability
|
||||
mentioned.
|
||||
|
||||
[1] = http://oss-security.openwall.org/wiki/mailing-lists/distros
|
||||
|
||||
CURL-SECURITY (at haxx dot se)
|
||||
------------------------------
|
||||
|
||||
Who is on this list? There are a couple of criteria you must meet, and then we
|
||||
might ask you to join the list or you can ask to join it. It really isn't very
|
||||
formal. We basically only require that you have a long-term presence in the
|
||||
curl project and you have shown an understanding for the project and its way
|
||||
of working. You must've been around for a good while and you should have no
|
||||
plans in vanishing in the near future.
|
||||
|
||||
We do not make the list of partipants public mostly because it tends to vary
|
||||
somewhat over time and a list somewhere will only risk getting outdated.
|
67
curl/docs/SSL-PROBLEMS
Normal file
67
curl/docs/SSL-PROBLEMS
Normal file
@ -0,0 +1,67 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
SSL problems
|
||||
|
||||
First, let's establish that we often refer to TLS and SSL interchangeably as
|
||||
SSL here. The current protocol is called TLS, it was called SSL a long time
|
||||
ago.
|
||||
|
||||
There are several known reasons why a connection that involves SSL might
|
||||
fail. This is a document that attempts to details the most common ones and
|
||||
how to mitigate them.
|
||||
|
||||
CA certs
|
||||
|
||||
CA certs are used to digitally verify the server's certificate. You need a
|
||||
"ca bundle" for this. See lots of more details on this in the SSLCERTS
|
||||
document.
|
||||
|
||||
CA bundle missing intermediate certificates
|
||||
|
||||
When using said CA bundle to verify a server cert, you will experience
|
||||
problems if your CA cert does not have the certificates for the
|
||||
intermediates in the whole trust chain.
|
||||
|
||||
SSL version
|
||||
|
||||
Some broken servers fail to support the protocol negotiation properly that
|
||||
SSL servers are supposed to handle. This may cause the connection to fail
|
||||
completely. Sometimes you may need to explicitly select a SSL version to use
|
||||
when connecting to make the connection succeed.
|
||||
|
||||
An additional complication can be that modern SSL libraries sometimes are
|
||||
built with support for older SSL and TLS versions disabled!
|
||||
|
||||
SSL ciphers
|
||||
|
||||
Clients give servers a list of ciphers to select from. If the list doesn't
|
||||
include any ciphers the server wants/can use, the connection handshake
|
||||
fails.
|
||||
|
||||
curl has recently disabled the user of a whole bunch of seriously insecure
|
||||
ciphers from its default set (slightly depending on SSL backend in use).
|
||||
|
||||
You may have to explicitly provide an alternative list of ciphers for curl
|
||||
to use to allow the server to use a WEAK cipher for you.
|
||||
|
||||
Note that these weak ciphers are identified as flawed. For example, this
|
||||
includes symmetric ciphers with less than 128 bit keys and RC4.
|
||||
|
||||
References:
|
||||
|
||||
https://tools.ietf.org/html/draft-popov-tls-prohibiting-rc4-01
|
||||
|
||||
Allow BEAST
|
||||
|
||||
BEAST is the name of a TLS 1.0 attack that surfaced 2011. When adding means
|
||||
to mitigate this attack, it turned out that some broken servers out there in
|
||||
the wild didn't work properly with the BEAST mitigation in place.
|
||||
|
||||
To make such broken servers work, the --ssl-allow-beast option was
|
||||
introduced. Exactly as it sounds, it re-introduces the BEAST vulnerability
|
||||
but on the other hand it allows curl to connect to that kind of strange
|
||||
servers.
|
153
curl/docs/SSLCERTS
Normal file
153
curl/docs/SSLCERTS
Normal file
@ -0,0 +1,153 @@
|
||||
SSL Certificate Verification
|
||||
============================
|
||||
|
||||
SSL is TLS
|
||||
----------
|
||||
|
||||
SSL is the old name. It is called TLS these days.
|
||||
|
||||
|
||||
Native SSL
|
||||
----------
|
||||
|
||||
If libcurl was built with Schannel or Secure Transport support (the native SSL
|
||||
libraries included in Windows and Mac OS X), then this does not apply to
|
||||
you. Scroll down for details on how the OS-native engines handle SSL
|
||||
certificates. If you're not sure, then run "curl -V" and read the results. If
|
||||
the version string says "WinSSL" in it, then it was built with Schannel
|
||||
support.
|
||||
|
||||
It is about trust
|
||||
-----------------
|
||||
|
||||
This system is about trust. In your local CA cert bundle you have certs from
|
||||
*trusted* Certificate Authorities that you then can use to verify that the
|
||||
server certificates you see are valid. They're signed by one of the CAs you
|
||||
trust.
|
||||
|
||||
Which CAs do you trust? You can decide to trust the same set of companies your
|
||||
operating system trusts, or the set one of the known browsers trust. That's
|
||||
basically trust via someone else you trust. You should just be aware that
|
||||
modern operating systems and browsers are setup to trust *hundreds* of
|
||||
companies and recent years several such CAs have been found untrustworthy.
|
||||
|
||||
Certificate Verification
|
||||
------------------------
|
||||
|
||||
libcurl performs peer SSL certificate verification by default. This is done
|
||||
by using CA cert bundle that the SSL library can use to make sure the peer's
|
||||
server certificate is valid.
|
||||
|
||||
If you communicate with HTTPS, FTPS or other TLS-using servers using
|
||||
certificates that are signed by CAs present in the bundle, you can be sure
|
||||
that the remote server really is the one it claims to be.
|
||||
|
||||
If the remote server uses a self-signed certificate, if you don't install a CA
|
||||
cert bundle, if the server uses a certificate signed by a CA that isn't
|
||||
included in the bundle you use or if the remote host is an impostor
|
||||
impersonating your favorite site, and you want to transfer files from this
|
||||
server, do one of the following:
|
||||
|
||||
1. Tell libcurl to *not* verify the peer. With libcurl you disable this with
|
||||
`curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);`
|
||||
|
||||
With the curl command line tool, you disable this with -k/--insecure.
|
||||
|
||||
2. Get a CA certificate that can verify the remote server and use the proper
|
||||
option to point out this CA cert for verification when connecting. For
|
||||
libcurl hackers: `curl_easy_setopt(curl, CURLOPT_CAPATH, capath);`
|
||||
|
||||
With the curl command line tool: --cacert [file]
|
||||
|
||||
3. Add the CA cert for your server to the existing default CA cert bundle.
|
||||
The default path of the CA bundle used can be changed by running configure
|
||||
with the --with-ca-bundle option pointing out the path of your choice.
|
||||
|
||||
To do this, you need to get the CA cert for your server in PEM format and
|
||||
then append that to your CA cert bundle.
|
||||
|
||||
If you use Internet Explorer, this is one way to get extract the CA cert
|
||||
for a particular server:
|
||||
|
||||
- View the certificate by double-clicking the padlock
|
||||
- Find out where the CA certificate is kept (Certificate>
|
||||
Authority Information Access>URL)
|
||||
- Get a copy of the crt file using curl
|
||||
- Convert it from crt to PEM using the openssl tool:
|
||||
openssl x509 -inform DES -in yourdownloaded.crt \
|
||||
-out outcert.pem -text
|
||||
- Append the 'outcert.pem' to the CA cert bundle or use it stand-alone
|
||||
as described below.
|
||||
|
||||
If you use the 'openssl' tool, this is one way to get extract the CA cert
|
||||
for a particular server:
|
||||
|
||||
- `openssl s_client -connect xxxxx.com:443 |tee logfile`
|
||||
- type "QUIT", followed by the "ENTER" key
|
||||
- The certificate will have "BEGIN CERTIFICATE" and "END CERTIFICATE"
|
||||
markers.
|
||||
- If you want to see the data in the certificate, you can do: "openssl
|
||||
x509 -inform PEM -in certfile -text -out certdata" where certfile is
|
||||
the cert you extracted from logfile. Look in certdata.
|
||||
- If you want to trust the certificate, you can append it to your
|
||||
cert bundle or use it stand-alone as described. Just remember that the
|
||||
security is no better than the way you obtained the certificate.
|
||||
|
||||
4. If you're using the curl command line tool, you can specify your own CA
|
||||
cert path by setting the environment variable `CURL_CA_BUNDLE` to the path
|
||||
of your choice.
|
||||
|
||||
If you're using the curl command line tool on Windows, curl will search
|
||||
for a CA cert file named "curl-ca-bundle.crt" in these directories and in
|
||||
this order:
|
||||
1. application's directory
|
||||
2. current working directory
|
||||
3. Windows System directory (e.g. C:\windows\system32)
|
||||
4. Windows Directory (e.g. C:\windows)
|
||||
5. all directories along %PATH%
|
||||
|
||||
5. Get a better/different/newer CA cert bundle! One option is to extract the
|
||||
one a recent Firefox browser uses by running 'make ca-bundle' in the curl
|
||||
build tree root, or possibly download a version that was generated this
|
||||
way for you: [CA Extract](http://curl.haxx.se/docs/caextract.html)
|
||||
|
||||
Neglecting to use one of the above methods when dealing with a server using a
|
||||
certificate that isn't signed by one of the certificates in the installed CA
|
||||
cert bundle, will cause SSL to report an error ("certificate verify failed")
|
||||
during the handshake and SSL will then refuse further communication with that
|
||||
server.
|
||||
|
||||
Certificate Verification with NSS
|
||||
---------------------------------
|
||||
|
||||
If libcurl was built with NSS support, then depending on the OS distribution,
|
||||
it is probably required to take some additional steps to use the system-wide
|
||||
CA cert db. RedHat ships with an additional module, libnsspem.so, which
|
||||
enables NSS to read the OpenSSL PEM CA bundle. This library is missing in
|
||||
OpenSuSE, and without it, NSS can only work with its own internal formats. NSS
|
||||
also has a new [database format](https://wiki.mozilla.org/NSS_Shared_DB).
|
||||
|
||||
Starting with version 7.19.7, libcurl automatically adds the 'sql:' prefix to
|
||||
the certdb directory (either the hardcoded default /etc/pki/nssdb or the
|
||||
directory configured with SSL_DIR environment variable). To check which certdb
|
||||
format your distribution provides, examine the default certdb location:
|
||||
/etc/pki/nssdb; the new certdb format can be identified by the filenames
|
||||
cert9.db, key4.db, pkcs11.txt; filenames of older versions are cert8.db,
|
||||
key3.db, secmod.db.
|
||||
|
||||
Certificate Verification with Schannel and Secure Transport
|
||||
-----------------------------------------------------------
|
||||
|
||||
If libcurl was built with Schannel (Microsoft's native TLS engine) or Secure
|
||||
Transport (Apple's native TLS engine) support, then libcurl will still perform
|
||||
peer certificate verification, but instead of using a CA cert bundle, it will
|
||||
use the certificates that are built into the OS. These are the same
|
||||
certificates that appear in the Internet Options control panel (under Windows)
|
||||
or Keychain Access application (under OS X). Any custom security rules for
|
||||
certificates will be honored.
|
||||
|
||||
Schannel will run CRL checks on certificates unless peer verification is
|
||||
disabled. Secure Transport on iOS will run OCSP checks on certificates unless
|
||||
peer verification is disabled. Secure Transport on OS X will run either OCSP
|
||||
or CRL checks on certificates if those features are enabled, and this behavior
|
||||
can be adjusted in the preferences of Keychain Access.
|
1297
curl/docs/THANKS
Normal file
1297
curl/docs/THANKS
Normal file
File diff suppressed because it is too large
Load Diff
805
curl/docs/TODO
Normal file
805
curl/docs/TODO
Normal file
@ -0,0 +1,805 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
Things that could be nice to do in the future
|
||||
|
||||
Things to do in project cURL. Please tell us what you think, contribute and
|
||||
send us patches that improve things!
|
||||
|
||||
Be aware that these are things that we could do, or have once been considered
|
||||
things we could do. If you want to work on any of these areas, please
|
||||
consider bringing it up for discussions first on the mailing list so that we
|
||||
all agree it is still a good idea for the project!
|
||||
|
||||
All bugs documented in the KNOWN_BUGS document are subject for fixing!
|
||||
|
||||
1. libcurl
|
||||
1.2 More data sharing
|
||||
1.3 struct lifreq
|
||||
1.4 signal-based resolver timeouts
|
||||
1.5 get rid of PATH_MAX
|
||||
1.6 Modified buffer size approach
|
||||
1.7 Detect when called from within callbacks
|
||||
1.8 Allow SSL (HTTPS) to proxy
|
||||
1.9 Cache negative name resolves
|
||||
|
||||
2. libcurl - multi interface
|
||||
2.1 More non-blocking
|
||||
2.2 Fix HTTP Pipelining for PUT
|
||||
2.3 Better support for same name resolves
|
||||
|
||||
3. Documentation
|
||||
3.1 Update date and version in man pages
|
||||
|
||||
4. FTP
|
||||
4.1 HOST
|
||||
4.2 Alter passive/active on failure and retry
|
||||
4.3 Earlier bad letter detection
|
||||
4.4 REST for large files
|
||||
4.5 ASCII support
|
||||
4.6 GSSAPI via Windows SSPI
|
||||
4.7 STAT for LIST without data connection
|
||||
|
||||
5. HTTP
|
||||
5.1 Better persistency for HTTP 1.0
|
||||
5.2 support FF3 sqlite cookie files
|
||||
5.3 Rearrange request header order
|
||||
5.4 SPDY
|
||||
5.5 auth= in URLs
|
||||
5.6 Refuse "downgrade" redirects
|
||||
|
||||
6. TELNET
|
||||
6.1 ditch stdin
|
||||
6.2 ditch telnet-specific select
|
||||
6.3 feature negotiation debug data
|
||||
6.4 send data in chunks
|
||||
|
||||
7. SMTP
|
||||
7.1 Pipelining
|
||||
7.2 Enhanced capability support
|
||||
|
||||
8. POP3
|
||||
8.1 Pipelining
|
||||
8.2 Enhanced capability support
|
||||
|
||||
9. IMAP
|
||||
9.1 Enhanced capability support
|
||||
|
||||
10. LDAP
|
||||
10.1 SASL based authentication mechanisms
|
||||
|
||||
11. SMB
|
||||
11.1 File listing support
|
||||
11.2 Honor file timestamps
|
||||
11.3 Use NTLMv2
|
||||
|
||||
12. New protocols
|
||||
12.1 RSYNC
|
||||
|
||||
13. SSL
|
||||
13.1 Disable specific versions
|
||||
13.2 Provide mutex locking API
|
||||
13.3 Evaluate SSL patches
|
||||
13.4 Cache OpenSSL contexts
|
||||
13.5 Export session ids
|
||||
13.6 Provide callback for cert verification
|
||||
13.7 improve configure --with-ssl
|
||||
13.8 Support DANE
|
||||
|
||||
14. GnuTLS
|
||||
14.1 SSL engine stuff
|
||||
14.2 check connection
|
||||
|
||||
15. WinSSL/SChannel
|
||||
15.1 Add support for client certificate authentication
|
||||
15.2 Add support for custom server certificate validation
|
||||
15.3 Add support for the --ciphers option
|
||||
|
||||
16. SASL
|
||||
16.1 Other authentication mechanisms
|
||||
16.2 Add QOP support to GSSAPI authentication
|
||||
|
||||
17. Client
|
||||
17.1 sync
|
||||
17.2 glob posts
|
||||
17.3 prevent file overwriting
|
||||
17.4 simultaneous parallel transfers
|
||||
17.5 provide formpost headers
|
||||
17.6 warning when setting an option
|
||||
17.7 warning when sending binary output to terminal
|
||||
17.8 offer color-coded HTTP header output
|
||||
17.9 Choose the name of file in braces for complex URLs
|
||||
|
||||
18. Build
|
||||
18.1 roffit
|
||||
|
||||
19. Test suite
|
||||
19.1 SSL tunnel
|
||||
19.2 nicer lacking perl message
|
||||
19.3 more protocols supported
|
||||
19.4 more platforms supported
|
||||
19.5 Add support for concurrent connections
|
||||
|
||||
20. Next SONAME bump
|
||||
20.1 http-style HEAD output for FTP
|
||||
20.2 combine error codes
|
||||
20.3 extend CURLOPT_SOCKOPTFUNCTION prototype
|
||||
|
||||
21. Next major release
|
||||
21.1 cleanup return codes
|
||||
21.2 remove obsolete defines
|
||||
21.3 size_t
|
||||
21.4 remove several functions
|
||||
21.5 remove CURLOPT_FAILONERROR
|
||||
21.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
21.7 remove progress meter from libcurl
|
||||
21.8 remove 'curl_httppost' from public
|
||||
21.9 have form functions use CURL handle argument
|
||||
21.10 Add CURLOPT_MAIL_CLIENT option
|
||||
|
||||
==============================================================================
|
||||
|
||||
1. libcurl
|
||||
|
||||
1.2 More data sharing
|
||||
|
||||
curl_share_* functions already exist and work, and they can be extended to
|
||||
share more. For example, enable sharing of the ares channel and the
|
||||
connection cache.
|
||||
|
||||
1.3 struct lifreq
|
||||
|
||||
Use 'struct lifreq' and SIOCGLIFADDR instead of 'struct ifreq' and
|
||||
SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
|
||||
To support IPv6 interface addresses for network interfaces properly.
|
||||
|
||||
1.4 signal-based resolver timeouts
|
||||
|
||||
libcurl built without an asynchronous resolver library uses alarm() to time
|
||||
out DNS lookups. When a timeout occurs, this causes libcurl to jump from the
|
||||
signal handler back into the library with a sigsetjmp, which effectively
|
||||
causes libcurl to continue running within the signal handler. This is
|
||||
non-portable and could cause problems on some platforms. A discussion on the
|
||||
problem is available at http://curl.haxx.se/mail/lib-2008-09/0197.html
|
||||
|
||||
Also, alarm() provides timeout resolution only to the nearest second. alarm
|
||||
ought to be replaced by setitimer on systems that support it.
|
||||
|
||||
1.5 get rid of PATH_MAX
|
||||
|
||||
Having code use and rely on PATH_MAX is not nice:
|
||||
http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
|
||||
|
||||
Currently the SSH based code uses it a bit, but to remove PATH_MAX from there
|
||||
we need libssh2 to properly tell us when we pass in a too small buffer and
|
||||
its current API (as of libssh2 1.2.7) doesn't.
|
||||
|
||||
1.6 Modified buffer size approach
|
||||
|
||||
Current libcurl allocates a fixed 16K size buffer for download and an
|
||||
additional 16K for upload. They are always unconditionally part of the easy
|
||||
handle. If CRLF translations are requested, an additional 32K "scratch
|
||||
buffer" is allocated. A total of 64K transfer buffers in the worst case.
|
||||
|
||||
First, while the handles are not actually in use these buffers could be freed
|
||||
so that lingering handles just kept in queues or whatever waste less memory.
|
||||
|
||||
Secondly, SFTP is a protocol that needs to handle many ~30K blocks at once
|
||||
since each need to be individually acked and therefore libssh2 must be
|
||||
allowed to send (or receive) many separate ones in parallel to achieve high
|
||||
transfer speeds. A current libcurl build with a 16K buffer makes that
|
||||
impossible, but one with a 512K buffer will reach MUCH faster transfers. But
|
||||
allocating 512K unconditionally for all buffers just in case they would like
|
||||
to do fast SFTP transfers at some point is not a good solution either.
|
||||
|
||||
Dynamically allocate buffer size depending on protocol in use in combination
|
||||
with freeing it after each individual transfer? Other suggestions?
|
||||
|
||||
1.7 Detect when called from within callbacks
|
||||
|
||||
We should set a state variable before calling callbacks, so that we
|
||||
subsequently can add code within libcurl that returns error if called within
|
||||
callbacks for when that's not supported.
|
||||
|
||||
1.8 Allow SSL (HTTPS) to proxy
|
||||
|
||||
To prevent local users from snooping on your traffic to the proxy. Supported
|
||||
by Chrome already:
|
||||
https://www.chromium.org/developers/design-documents/secure-web-proxy
|
||||
|
||||
...and by Firefox soon:
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=378637
|
||||
|
||||
1.9 Cache negative name resolves
|
||||
|
||||
A name resolve that has failed is likely to fail when made again within a
|
||||
short period of time. Currently we only cache positive responses.
|
||||
|
||||
|
||||
2. libcurl - multi interface
|
||||
|
||||
2.1 More non-blocking
|
||||
|
||||
Make sure we don't ever loop because of non-blocking sockets returning
|
||||
EWOULDBLOCK or similar. Blocking cases include:
|
||||
|
||||
- Name resolves on non-windows unless c-ares is used
|
||||
- NSS SSL connections
|
||||
- HTTP proxy CONNECT operations
|
||||
- SOCKS proxy handshakes
|
||||
- file:// transfers
|
||||
- TELNET transfers
|
||||
- The "DONE" operation (post transfer protocol-specific actions) for the
|
||||
protocols SFTP, SMTP, FTP. Fixing Curl_done() for this is a worthy task.
|
||||
|
||||
2.2 Fix HTTP Pipelining for PUT
|
||||
|
||||
HTTP Pipelining can be a way to greatly enhance performance for multiple
|
||||
serial requests and currently libcurl only supports that for HEAD and GET
|
||||
requests but it should also be possible for PUT.
|
||||
|
||||
2.3 Better support for same name resolves
|
||||
|
||||
If a name resolve has been initiated for name NN and a second easy handle
|
||||
wants to resolve that name as well, make it wait for the first resolve to end
|
||||
up in the cache instead of doing a second separate resolve. This is
|
||||
especially needed when adding many simultaneous handles using the same host
|
||||
name when the DNS resolver can get flooded.
|
||||
|
||||
|
||||
3. Documentation
|
||||
|
||||
3.1 Update date and version in man pages
|
||||
|
||||
'maketgz' or another suitable script could update the .TH sections of the man
|
||||
pages at release time to use the current date and curl/libcurl version
|
||||
number.
|
||||
|
||||
4. FTP
|
||||
|
||||
4.1 HOST
|
||||
|
||||
HOST is a command for a client to tell which host name to use, to offer FTP
|
||||
servers named-based virtual hosting:
|
||||
|
||||
https://tools.ietf.org/html/rfc7151
|
||||
|
||||
4.2 Alter passive/active on failure and retry
|
||||
|
||||
When trying to connect passively to a server which only supports active
|
||||
connections, libcurl returns CURLE_FTP_WEIRD_PASV_REPLY and closes the
|
||||
connection. There could be a way to fallback to an active connection (and
|
||||
vice versa). http://curl.haxx.se/bug/feature.cgi?id=1754793
|
||||
|
||||
4.3 Earlier bad letter detection
|
||||
|
||||
Make the detection of (bad) %0d and %0a codes in FTP URL parts earlier in the
|
||||
process to avoid doing a resolve and connect in vain.
|
||||
|
||||
4.4 REST for large files
|
||||
|
||||
REST fix for servers not behaving well on >2GB requests. This should fail if
|
||||
the server doesn't set the pointer to the requested index. The tricky
|
||||
(impossible?) part is to figure out if the server did the right thing or not.
|
||||
|
||||
4.5 ASCII support
|
||||
|
||||
FTP ASCII transfers do not follow RFC959. They don't convert the data
|
||||
accordingly.
|
||||
|
||||
4.6 GSSAPI via Windows SSPI
|
||||
|
||||
In addition to currently supporting the SASL GSSAPI mechanism (Kerberos V5)
|
||||
via third-party GSS-API libraries, such as Heimdal or MIT Kerberos, also add
|
||||
support for GSSAPI authentication via Windows SSPI.
|
||||
|
||||
4.7 STAT for LIST without data connection
|
||||
|
||||
Some FTP servers allow STAT for listing directories instead of using LIST, and
|
||||
the response is then sent over the control connection instead of as the
|
||||
otherwise usedw data connection: http://www.nsftools.com/tips/RawFTP.htm#STAT
|
||||
|
||||
This is not detailed in any FTP specification.
|
||||
|
||||
5. HTTP
|
||||
|
||||
5.1 Better persistency for HTTP 1.0
|
||||
|
||||
"Better" support for persistent connections over HTTP 1.0
|
||||
http://curl.haxx.se/bug/feature.cgi?id=1089001
|
||||
|
||||
5.2 support FF3 sqlite cookie files
|
||||
|
||||
Firefox 3 is changing from its former format to a a sqlite database instead.
|
||||
We should consider how (lib)curl can/should support this.
|
||||
http://curl.haxx.se/bug/feature.cgi?id=1871388
|
||||
|
||||
5.3 Rearrange request header order
|
||||
|
||||
Server implementors often make an effort to detect browser and to reject
|
||||
clients it can detect to not match. One of the last details we cannot yet
|
||||
control in libcurl's HTTP requests, which also can be exploited to detect
|
||||
that libcurl is in fact used even when it tries to impersonate a browser, is
|
||||
the order of the request headers. I propose that we introduce a new option in
|
||||
which you give headers a value, and then when the HTTP request is built it
|
||||
sorts the headers based on that number. We could then have internally created
|
||||
headers use a default value so only headers that need to be moved have to be
|
||||
specified.
|
||||
|
||||
5.4 SPDY
|
||||
|
||||
Chrome and Firefox already support SPDY and lots of web services do. There's
|
||||
a library for us to use for this (spdylay) that has a similar API and the
|
||||
same author as nghttp2.
|
||||
|
||||
spdylay: https://github.com/tatsuhiro-t/spdylay
|
||||
|
||||
5.5 auth= in URLs
|
||||
|
||||
Add the ability to specify the preferred authentication mechanism to use by
|
||||
using ;auth=<mech> in the login part of the URL.
|
||||
|
||||
For example:
|
||||
|
||||
http://test:pass;auth=NTLM@example.com would be equivalent to specifying --user
|
||||
test:pass;auth=NTLM or --user test:pass --ntlm from the command line.
|
||||
|
||||
Additionally this should be implemented for proxy base URLs as well.
|
||||
|
||||
5.6 Refuse "downgrade" redirects
|
||||
|
||||
See https://github.com/bagder/curl/issues/226
|
||||
|
||||
Consider a way to tell curl to refuse to "downgrade" protocol with a redirect
|
||||
and/or possibly a bit that refuses redirect to change protocol completely.
|
||||
|
||||
|
||||
6. TELNET
|
||||
|
||||
6.1 ditch stdin
|
||||
|
||||
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.
|
||||
|
||||
6.2 ditch telnet-specific select
|
||||
|
||||
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.
|
||||
|
||||
6.3 feature negotiation debug data
|
||||
|
||||
Add telnet feature negotiation data to the debug callback as header data.
|
||||
|
||||
6.4 send data in chunks
|
||||
|
||||
Currently, telnet sends data one byte at a time. This is fine for interactive
|
||||
use, but inefficient for any other. Sent data should be sent in larger
|
||||
chunks.
|
||||
|
||||
7. SMTP
|
||||
|
||||
7.1 Pipelining
|
||||
|
||||
Add support for pipelining emails.
|
||||
|
||||
7.2 Enhanced capability support
|
||||
|
||||
Add the ability, for an application that uses libcurl, to obtain the list of
|
||||
capabilities returned from the EHLO command.
|
||||
|
||||
8. POP3
|
||||
|
||||
8.1 Pipelining
|
||||
|
||||
Add support for pipelining commands.
|
||||
|
||||
8.2 Enhanced capability support
|
||||
|
||||
Add the ability, for an application that uses libcurl, to obtain the list of
|
||||
capabilities returned from the CAPA command.
|
||||
|
||||
9. IMAP
|
||||
|
||||
9.1 Enhanced capability support
|
||||
|
||||
Add the ability, for an application that uses libcurl, to obtain the list of
|
||||
capabilities returned from the CAPABILITY command.
|
||||
|
||||
10. LDAP
|
||||
|
||||
10.1 SASL based authentication mechanisms
|
||||
|
||||
Currently the LDAP module only supports ldap_simple_bind_s() in order to bind
|
||||
to an LDAP server. However, this function sends username and password details
|
||||
using the simple authentication mechanism (as clear text). However, it should
|
||||
be possible to use ldap_bind_s() instead specifying the security context
|
||||
information ourselves.
|
||||
|
||||
11. SMB
|
||||
|
||||
11.1 File listing support
|
||||
|
||||
Add support for listing the contents of a SMB share. The output should probably
|
||||
be the same as/similar to FTP.
|
||||
|
||||
11.2 Honor file timestamps
|
||||
|
||||
The timestamp of the transferred file should reflect that of the original file.
|
||||
|
||||
11.3 Use NTLMv2
|
||||
|
||||
Currently the SMB authentication uses NTLMv1.
|
||||
|
||||
12. New protocols
|
||||
|
||||
12.1 RSYNC
|
||||
|
||||
There's no RFC for the protocol or an URI/URL format. An implementation
|
||||
should most probably use an existing rsync library, such as librsync.
|
||||
|
||||
13. SSL
|
||||
|
||||
13.1 Disable specific versions
|
||||
|
||||
Provide an option that allows for disabling specific SSL versions, such as
|
||||
SSLv2 http://curl.haxx.se/bug/feature.cgi?id=1767276
|
||||
|
||||
13.2 Provide mutex locking API
|
||||
|
||||
Provide a libcurl API for setting mutex callbacks in the underlying SSL
|
||||
library, so that the same application code can use mutex-locking
|
||||
independently of OpenSSL or GnutTLS being used.
|
||||
|
||||
13.3 Evaluate SSL patches
|
||||
|
||||
Evaluate/apply Gertjan van Wingerde's SSL patches:
|
||||
http://curl.haxx.se/mail/lib-2004-03/0087.html
|
||||
|
||||
13.4 Cache OpenSSL contexts
|
||||
|
||||
"Look at SSL cafile - quick traces look to me like these are done on every
|
||||
request as well, when they should only be necessary once per SSL context (or
|
||||
once per handle)". The major improvement we can rather easily do is to make
|
||||
sure we don't create and kill a new SSL "context" for every request, but
|
||||
instead make one for every connection and re-use that SSL context in the same
|
||||
style connections are re-used. It will make us use slightly more memory but
|
||||
it will libcurl do less creations and deletions of SSL contexts.
|
||||
|
||||
13.5 Export session ids
|
||||
|
||||
Add an interface to libcurl that enables "session IDs" to get
|
||||
exported/imported. Cris Bailiff said: "OpenSSL has functions which can
|
||||
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 by mod_ssl for
|
||||
apache to implement and SSL session ID cache".
|
||||
|
||||
13.6 Provide callback for cert verification
|
||||
|
||||
OpenSSL supports a callback for customised verification of the peer
|
||||
certificate, but this doesn't seem to be exposed in the libcurl APIs. Could
|
||||
it be? There's so much that could be done if it were!
|
||||
|
||||
13.7 improve configure --with-ssl
|
||||
|
||||
make the configure --with-ssl option first check for OpenSSL, then GnuTLS,
|
||||
then NSS...
|
||||
|
||||
13.8 Support DANE
|
||||
|
||||
DNS-Based Authentication of Named Entities (DANE) is a way to provide SSL
|
||||
keys and certs over DNS using DNSSEC as an alternative to the CA model.
|
||||
https://www.rfc-editor.org/rfc/rfc6698.txt
|
||||
|
||||
An initial patch was posted by Suresh Krishnaswamy on March 7th 2013
|
||||
(http://curl.haxx.se/mail/lib-2013-03/0075.html) but it was a too simple
|
||||
approach. See Daniel's comments:
|
||||
http://curl.haxx.se/mail/lib-2013-03/0103.html . libunbound may be the
|
||||
correct library to base this development on.
|
||||
|
||||
14. GnuTLS
|
||||
|
||||
14.1 SSL engine stuff
|
||||
|
||||
Is this even possible?
|
||||
|
||||
14.2 check connection
|
||||
|
||||
Add a way to check if the connection seems to be alive, to correspond to the
|
||||
SSL_peak() way we use with OpenSSL.
|
||||
|
||||
15. WinSSL/SChannel
|
||||
|
||||
15.1 Add support for client certificate authentication
|
||||
|
||||
WinSSL/SChannel currently makes use of the OS-level system and user
|
||||
certificate and private key stores. This does not allow the application
|
||||
or the user to supply a custom client certificate using curl or libcurl.
|
||||
|
||||
Therefore support for the existing -E/--cert and --key options should be
|
||||
implemented by supplying a custom certificate to the SChannel APIs, see:
|
||||
- Getting a Certificate for Schannel
|
||||
https://msdn.microsoft.com/en-us/library/windows/desktop/aa375447.aspx
|
||||
|
||||
15.2 Add support for custom server certificate validation
|
||||
|
||||
WinSSL/SChannel currently makes use of the OS-level system and user
|
||||
certificate trust store. This does not allow the application or user to
|
||||
customize the server certificate validation process using curl or libcurl.
|
||||
|
||||
Therefore support for the existing --cacert or --capath options should be
|
||||
implemented by supplying a custom certificate to the SChannel APIs, see:
|
||||
- Getting a Certificate for Schannel
|
||||
https://msdn.microsoft.com/en-us/library/windows/desktop/aa375447.aspx
|
||||
|
||||
15.3 Add support for the --ciphers option
|
||||
|
||||
The cipher suites used by WinSSL/SChannel are configured on an OS-level
|
||||
instead of an application-level. This does not allow the application or
|
||||
the user to customize the configured cipher suites using curl or libcurl.
|
||||
|
||||
Therefore support for the existing --ciphers option should be implemented
|
||||
by mapping the OpenSSL/GnuTLS cipher suites to the SChannel APIs, see
|
||||
- Specifying Schannel Ciphers and Cipher Strengths
|
||||
https://msdn.microsoft.com/en-us/library/windows/desktop/aa380161.aspx
|
||||
|
||||
16. SASL
|
||||
|
||||
16.1 Other authentication mechanisms
|
||||
|
||||
Add support for other authentication mechanisms such as OLP,
|
||||
GSS-SPNEGO and others.
|
||||
|
||||
16.2 Add QOP support to GSSAPI authentication
|
||||
|
||||
Currently the GSSAPI authentication only supports the default QOP of auth
|
||||
(Authentication), whilst Kerberos V5 supports both auth-int (Authentication
|
||||
with integrity protection) and auth-conf (Authentication with integrity and
|
||||
privacy protection).
|
||||
|
||||
17. Client
|
||||
|
||||
17.1 sync
|
||||
|
||||
"curl --sync http://example.com/feed[1-100].rss" or
|
||||
"curl --sync http://example.net/{index,calendar,history}.html"
|
||||
|
||||
Downloads a range or set of URLs using the remote name, but only if the
|
||||
remote file is newer than the local file. A Last-Modified HTTP date header
|
||||
should also be used to set the mod date on the downloaded file.
|
||||
|
||||
17.2 glob posts
|
||||
|
||||
Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'.
|
||||
This is easily scripted though.
|
||||
|
||||
17.3 prevent file overwriting
|
||||
|
||||
Add an option that prevents cURL from overwriting existing local files. When
|
||||
used, and there already is an existing file with the target file name
|
||||
(either -O or -o), a number should be appended (and increased if already
|
||||
existing). So that index.html becomes first index.html.1 and then
|
||||
index.html.2 etc.
|
||||
|
||||
17.4 simultaneous parallel transfers
|
||||
|
||||
The client could be told to use maximum N simultaneous parallel transfers and
|
||||
then just make sure that happens. It should of course not make more than one
|
||||
connection to the same remote host. This would require the client to use the
|
||||
multi interface. http://curl.haxx.se/bug/feature.cgi?id=1558595
|
||||
|
||||
17.5 provide formpost headers
|
||||
|
||||
Extending the capabilities of the multipart formposting. How about leaving
|
||||
the ';type=foo' syntax as it is and adding an extra tag (headers) which
|
||||
works like this: curl -F "coolfiles=@fil1.txt;headers=@fil1.hdr" where
|
||||
fil1.hdr contains extra headers like
|
||||
|
||||
Content-Type: text/plain; charset=KOI8-R"
|
||||
Content-Transfer-Encoding: base64
|
||||
X-User-Comment: Please don't use browser specific HTML code
|
||||
|
||||
which should overwrite the program reasonable defaults (plain/text,
|
||||
8bit...)
|
||||
|
||||
17.6 warning when setting an option
|
||||
|
||||
Display a warning when libcurl returns an error when setting an option.
|
||||
This can be useful to tell when support for a particular feature hasn't been
|
||||
compiled into the library.
|
||||
|
||||
17.7 warning when sending binary output to terminal
|
||||
|
||||
Provide a way that prompts the user for confirmation before binary data is
|
||||
sent to the terminal, much in the style 'less' does it.
|
||||
|
||||
17.8 offer color-coded HTTP header output
|
||||
|
||||
By offering different color output on the header name and the header
|
||||
contents, they could be made more readable and thus help users working on
|
||||
HTTP services.
|
||||
|
||||
17.9 Choose the name of file in braces for complex URLs
|
||||
|
||||
When using braces to download a list of URLs and you use complicated names
|
||||
in the list of alternatives, it could be handy to allow curl to use other
|
||||
names when saving.
|
||||
|
||||
Consider a way to offer that. Possibly like
|
||||
{partURL1:name1,partURL2:name2,partURL3:name3} where the name following the
|
||||
colon is the output name.
|
||||
|
||||
See https://github.com/bagder/curl/issues/221
|
||||
|
||||
|
||||
18. Build
|
||||
|
||||
18.1 roffit
|
||||
|
||||
Consider extending 'roffit' to produce decent ASCII output, and use that
|
||||
instead of (g)nroff when building src/tool_hugehelp.c
|
||||
|
||||
19. Test suite
|
||||
|
||||
19.1 SSL tunnel
|
||||
|
||||
Make our own version of stunnel for simple port forwarding to enable HTTPS
|
||||
and FTP-SSL tests without the stunnel dependency, and it could allow us to
|
||||
provide test tools built with either OpenSSL or GnuTLS
|
||||
|
||||
19.2 nicer lacking perl message
|
||||
|
||||
If perl wasn't found by the configure script, don't attempt to run the tests
|
||||
but explain something nice why it doesn't.
|
||||
|
||||
19.3 more protocols supported
|
||||
|
||||
Extend the test suite to include more protocols. The telnet could just do FTP
|
||||
or http operations (for which we have test servers).
|
||||
|
||||
19.4 more platforms supported
|
||||
|
||||
Make the test suite work on more platforms. OpenBSD and Mac OS. Remove
|
||||
fork()s and it should become even more portable.
|
||||
|
||||
19.5 Add support for concurrent connections
|
||||
|
||||
Tests 836, 882 and 938 were designed to verify that separate connections aren't
|
||||
used when using different login credentials in protocols that shouldn't re-use
|
||||
a connection under such circumstances.
|
||||
|
||||
Unfortunately, ftpserver.pl doesn't appear to support multiple concurrent
|
||||
connections. The read while() loop seems to loop until it receives a disconnect
|
||||
from the client, where it then enters the waiting for connections loop. When
|
||||
the client opens a second connection to the server, the first connection hasn't
|
||||
been dropped (unless it has been forced - which we shouldn't do in these tests)
|
||||
and thus the wait for connections loop is never entered to receive the second
|
||||
connection.
|
||||
|
||||
20. Next SONAME bump
|
||||
|
||||
20.1 http-style HEAD output for FTP
|
||||
|
||||
#undef CURL_FTP_HTTPSTYLE_HEAD in lib/ftp.c to remove the HTTP-style headers
|
||||
from being output in NOBODY requests over FTP
|
||||
|
||||
20.2 combine error codes
|
||||
|
||||
Combine some of the error codes to remove duplicates. The original
|
||||
numbering should not be changed, and the old identifiers would be
|
||||
macroed to the new ones in an CURL_NO_OLDIES section to help with
|
||||
backward compatibility.
|
||||
|
||||
Candidates for removal and their replacements:
|
||||
|
||||
CURLE_FILE_COULDNT_READ_FILE => CURLE_REMOTE_FILE_NOT_FOUND
|
||||
|
||||
CURLE_FTP_COULDNT_RETR_FILE => CURLE_REMOTE_FILE_NOT_FOUND
|
||||
|
||||
CURLE_FTP_COULDNT_USE_REST => CURLE_RANGE_ERROR
|
||||
|
||||
CURLE_FUNCTION_NOT_FOUND => CURLE_FAILED_INIT
|
||||
|
||||
CURLE_LDAP_INVALID_URL => CURLE_URL_MALFORMAT
|
||||
|
||||
CURLE_TFTP_NOSUCHUSER => CURLE_TFTP_ILLEGAL
|
||||
|
||||
CURLE_TFTP_NOTFOUND => CURLE_REMOTE_FILE_NOT_FOUND
|
||||
|
||||
CURLE_TFTP_PERM => CURLE_REMOTE_ACCESS_DENIED
|
||||
|
||||
20.3 extend CURLOPT_SOCKOPTFUNCTION prototype
|
||||
|
||||
The current prototype only provides 'purpose' that tells what the
|
||||
connection/socket is for, but not any protocol or similar. It makes it hard
|
||||
for applications to differentiate on TCP vs UDP and even HTTP vs FTP and
|
||||
similar.
|
||||
|
||||
21. Next major release
|
||||
|
||||
21.1 cleanup return codes
|
||||
|
||||
curl_easy_cleanup() returns void, but curl_multi_cleanup() returns a
|
||||
CURLMcode. These should be changed to be the same.
|
||||
|
||||
21.2 remove obsolete defines
|
||||
|
||||
remove obsolete defines from curl/curl.h
|
||||
|
||||
21.3 size_t
|
||||
|
||||
make several functions use size_t instead of int in their APIs
|
||||
|
||||
21.4 remove several functions
|
||||
|
||||
remove the following functions from the public API:
|
||||
|
||||
curl_getenv
|
||||
|
||||
curl_mprintf (and variations)
|
||||
|
||||
curl_strequal
|
||||
|
||||
curl_strnequal
|
||||
|
||||
They will instead become curlx_ - alternatives. That makes the curl app
|
||||
still capable of using them, by building with them from source.
|
||||
|
||||
These functions have no purpose anymore:
|
||||
|
||||
curl_multi_socket
|
||||
|
||||
curl_multi_socket_all
|
||||
|
||||
21.5 remove CURLOPT_FAILONERROR
|
||||
|
||||
Remove support for CURLOPT_FAILONERROR, it has gotten too kludgy and weird
|
||||
internally. Let the app judge success or not for itself.
|
||||
|
||||
21.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
|
||||
Remove support for a global DNS cache. Anything global is silly, and we
|
||||
already offer the share interface for the same functionality but done
|
||||
"right".
|
||||
|
||||
21.7 remove progress meter from libcurl
|
||||
|
||||
The internally provided progress meter output doesn't belong in the library.
|
||||
Basically no application wants it (apart from curl) but instead applications
|
||||
can and should do their own progress meters using the progress callback.
|
||||
|
||||
The progress callback should then be bumped as well to get proper 64bit
|
||||
variable types passed to it instead of doubles so that big files work
|
||||
correctly.
|
||||
|
||||
21.8 remove 'curl_httppost' from public
|
||||
|
||||
curl_formadd() was made to fill in a public struct, but the fact that the
|
||||
struct is public is never really used by application for their own advantage
|
||||
but instead often restricts how the form functions can or can't be modified.
|
||||
|
||||
Changing them to return a private handle will benefit the implementation and
|
||||
allow us much greater freedoms while still maintaining a solid API and ABI.
|
||||
|
||||
21.9 have form functions use CURL handle argument
|
||||
|
||||
curl_formadd() and curl_formget() both currently have no CURL handle
|
||||
argument, but both can use a callback that is set in the easy handle, and
|
||||
thus curl_formget() with callback cannot function without first having
|
||||
curl_easy_perform() (or similar) called - which is hard to grasp and a design
|
||||
mistake.
|
||||
|
||||
21.10 Add CURLOPT_MAIL_CLIENT option
|
||||
|
||||
Rather than use the URL to specify the mail client string to present in the
|
||||
HELO and EHLO commands, libcurl should support a new CURLOPT specifically for
|
||||
specifying this data as the URL is non-standard and to be honest a bit of a
|
||||
hack ;-)
|
||||
|
||||
Please see the following thread for more information:
|
||||
http://curl.haxx.se/mail/lib-2012-05/0178.html
|
||||
|
758
curl/docs/TheArtOfHttpScripting
Normal file
758
curl/docs/TheArtOfHttpScripting
Normal file
@ -0,0 +1,758 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
|
||||
The Art Of Scripting HTTP Requests Using Curl
|
||||
|
||||
1. HTTP Scripting
|
||||
1.1 Background
|
||||
1.2 The HTTP Protocol
|
||||
1.3 See the Protocol
|
||||
1.4 See the Timing
|
||||
1.5 See the Response
|
||||
2. URL
|
||||
2.1 Spec
|
||||
2.2 Host
|
||||
2.3 Port number
|
||||
2.4 User name and password
|
||||
2.5 Path part
|
||||
3. Fetch a page
|
||||
3.1 GET
|
||||
3.2 HEAD
|
||||
3.3 Multiple URLs in a single command line
|
||||
3.4 Multiple HTTP methods in a single command line
|
||||
4. HTML forms
|
||||
4.1 Forms explained
|
||||
4.2 GET
|
||||
4.3 POST
|
||||
4.4 File Upload POST
|
||||
4.5 Hidden Fields
|
||||
4.6 Figure Out What A POST Looks Like
|
||||
5. HTTP upload
|
||||
5.1 PUT
|
||||
6. HTTP Authentication
|
||||
6.1 Basic Authentication
|
||||
6.2 Other Authentication
|
||||
6.3 Proxy Authentication
|
||||
6.4 Hiding credentials
|
||||
7. More HTTP Headers
|
||||
7.1 Referer
|
||||
7.2 User Agent
|
||||
8. Redirects
|
||||
8.1 Location header
|
||||
8.2 Other redirects
|
||||
9. Cookies
|
||||
9.1 Cookie Basics
|
||||
9.2 Cookie options
|
||||
10. HTTPS
|
||||
10.1 HTTPS is HTTP secure
|
||||
10.2 Certificates
|
||||
11. Custom Request Elements
|
||||
11.1 Modify method and headers
|
||||
11.2 More on changed methods
|
||||
12. Web Login
|
||||
12.1 Some login tricks
|
||||
13. Debug
|
||||
13.1 Some debug tricks
|
||||
14. References
|
||||
14.1 Standards
|
||||
14.2 Sites
|
||||
|
||||
==============================================================================
|
||||
|
||||
1. HTTP Scripting
|
||||
|
||||
1.1 Background
|
||||
|
||||
This document assumes that you're familiar with HTML and general networking.
|
||||
|
||||
The increasing amount of applications moving to the web has made "HTTP
|
||||
Scripting" more frequently requested and wanted. To be able to automatically
|
||||
extract information from the web, to fake users, to post or upload data to
|
||||
web servers are all important tasks today.
|
||||
|
||||
Curl is a command line tool for doing all sorts of URL manipulations and
|
||||
transfers, but this particular document will focus on how to use it when
|
||||
doing HTTP requests for fun and profit. I'll assume that you know how to
|
||||
invoke 'curl --help' or 'curl --manual' to get basic information about it.
|
||||
|
||||
Curl is not written to do everything for you. It makes the requests, it gets
|
||||
the data, it sends data and it retrieves the information. You probably need
|
||||
to glue everything together using some kind of script language or repeated
|
||||
manual invokes.
|
||||
|
||||
1.2 The HTTP Protocol
|
||||
|
||||
HTTP is the protocol used to fetch data from web servers. It is a very simple
|
||||
protocol that is built upon TCP/IP. The protocol also allows information to
|
||||
get sent to the server from the client using a few different methods, as will
|
||||
be shown here.
|
||||
|
||||
HTTP is plain ASCII text lines being sent by the client to a server to
|
||||
request a particular action, and then the server replies a few text lines
|
||||
before the actual requested content is sent to the client.
|
||||
|
||||
The client, curl, sends a HTTP request. The request contains a method (like
|
||||
GET, POST, HEAD etc), a number of request headers and sometimes a request
|
||||
body. The HTTP server responds with a status line (indicating if things went
|
||||
well), response headers and most often also a response body. The "body" part
|
||||
is the plain data you requested, like the actual HTML or the image etc.
|
||||
|
||||
1.3 See the Protocol
|
||||
|
||||
Using curl's option --verbose (-v as a short option) will display what kind
|
||||
of commands curl sends to the server, as well as a few other informational
|
||||
texts.
|
||||
|
||||
--verbose is the single most useful option when it comes to debug or even
|
||||
understand the curl<->server interaction.
|
||||
|
||||
Sometimes even --verbose is not enough. Then --trace and --trace-ascii offer
|
||||
even more details as they show EVERYTHING curl sends and receives. Use it
|
||||
like this:
|
||||
|
||||
curl --trace-ascii debugdump.txt http://www.example.com/
|
||||
|
||||
1.4 See the Timing
|
||||
|
||||
Many times you may wonder what exactly is taking all the time, or you just
|
||||
want to know the amount of milliseconds between two points in a
|
||||
transfer. For those, and other similar situations, the --trace-time option
|
||||
is what you need. It'll prepend the time to each trace output line:
|
||||
|
||||
curl --trace-ascii d.txt --trace-time http://example.com/
|
||||
|
||||
1.5 See the Response
|
||||
|
||||
By default curl sends the response to stdout. You need to redirect it
|
||||
somewhere to avoid that, most often that is done with -o or -O.
|
||||
|
||||
2. URL
|
||||
|
||||
2.1 Spec
|
||||
|
||||
The Uniform Resource Locator format is how you specify the address of a
|
||||
particular resource on the Internet. You know these, you've seen URLs like
|
||||
http://curl.haxx.se or https://yourbank.com a million times. RFC 3986 is the
|
||||
canonical spec. And yeah, the formal name is not URL, it is URI.
|
||||
|
||||
2.2 Host
|
||||
|
||||
The host name is usually resolved using DNS or your /etc/hosts file to an IP
|
||||
address and that's what curl will communicate with. Alternatively you specify
|
||||
the IP address directly in the URL instead of a name.
|
||||
|
||||
For development and other trying out situation, you can point out a different
|
||||
IP address for a host name than what would otherwise be used, by using curl's
|
||||
--resolve option:
|
||||
|
||||
curl --resolve www.example.org:80:127.0.0.1 http://www.example.org/
|
||||
|
||||
2.3 Port number
|
||||
|
||||
Each protocol curl supports operate on a default port number, be it over TCP
|
||||
or in some cases UDP. Normally you don't have to take that into
|
||||
consideration, but at times you run test servers on other ports or
|
||||
similar. Then you can specify the port number in the URL with a colon and a
|
||||
number immediately following the host name. Like when doing HTTP to port
|
||||
1234:
|
||||
|
||||
curl http://www.example.org:1234/
|
||||
|
||||
The port number you specify in the URL is the number that the server uses to
|
||||
offer its services. Sometimes you may use a local proxy, and then you may
|
||||
need to specify that proxy's port number separate on what curl needs to
|
||||
connect to locally. Like when using a HTTP proxy on port 4321:
|
||||
|
||||
curl --proxy http://proxy.example.org:4321 http://remote.example.org/
|
||||
|
||||
2.4 User name and password
|
||||
|
||||
Some services are setup to require HTTP authentication and then you need to
|
||||
provide name and password which then is transferred to the remote site in
|
||||
various ways depending on the exact authentication protocol used.
|
||||
|
||||
You can opt to either insert the user and password in the URL or you can
|
||||
provide them separately:
|
||||
|
||||
curl http://user:password@example.org/
|
||||
|
||||
or
|
||||
|
||||
curl -u user:password http://example.org/
|
||||
|
||||
You need to pay attention that this kind of HTTP authentication is not what
|
||||
is usually done and requested by user-oriented web sites these days. They
|
||||
tend to use forms and cookies instead.
|
||||
|
||||
2.5 Path part
|
||||
|
||||
The path part is just sent off to the server to request that it sends back
|
||||
the associated response. The path is what is to the right side of the slash
|
||||
that follows the host name and possibly port number.
|
||||
|
||||
3. Fetch a page
|
||||
|
||||
3.1 GET
|
||||
|
||||
The simplest and most common request/operation made using HTTP is to get a
|
||||
URL. The URL could itself refer to a web page, an image or a file. The client
|
||||
issues a GET request to the server and receives the document it asked for.
|
||||
If you issue the command line
|
||||
|
||||
curl http://curl.haxx.se
|
||||
|
||||
you get a web page returned in your terminal window. The entire HTML document
|
||||
that that URL holds.
|
||||
|
||||
All HTTP replies contain a set of response headers that are normally hidden,
|
||||
use curl's --include (-i) option to display them as well as the rest of the
|
||||
document.
|
||||
|
||||
3.2 HEAD
|
||||
|
||||
You can ask the remote server for ONLY the headers by using the --head (-I)
|
||||
option which will make curl issue a HEAD request. In some special cases
|
||||
servers deny the HEAD method while others still work, which is a particular
|
||||
kind of annoyance.
|
||||
|
||||
The HEAD method is defined and made so that the server returns the headers
|
||||
exactly the way it would do for a GET, but without a body. It means that you
|
||||
may see a Content-Length: in the response headers, but there must not be an
|
||||
actual body in the HEAD response.
|
||||
|
||||
3.3 Multiple URLs in a single command line
|
||||
|
||||
A single curl command line may involve one or many URLs. The most common case
|
||||
is probably to just use one, but you can specify any amount of URLs. Yes
|
||||
any. No limits. You'll then get requests repeated over and over for all the
|
||||
given URLs.
|
||||
|
||||
Example, send two GETs:
|
||||
|
||||
curl http://url1.example.com http://url2.example.com
|
||||
|
||||
If you use --data to POST to the URL, using multiple URLs means that you send
|
||||
that same POST to all the given URLs.
|
||||
|
||||
Example, send two POSTs:
|
||||
|
||||
curl --data name=curl http://url1.example.com http://url2.example.com
|
||||
|
||||
|
||||
3.4 Multiple HTTP methods in a single command line
|
||||
|
||||
Sometimes you need to operate on several URLs in a single command line and do
|
||||
different HTTP methods on each. For this, you'll enjoy the --next option. It
|
||||
is basically a separator that separates a bunch of options from the next. All
|
||||
the URLs before --next will get the same method and will get all the POST
|
||||
data merged into one.
|
||||
|
||||
When curl reaches the --next on the command line, it'll sort of reset the
|
||||
method and the POST data and allow a new set.
|
||||
|
||||
Perhaps this is best shown with a few examples. To send first a HEAD and then
|
||||
a GET:
|
||||
|
||||
curl -I http://example.com --next http://example.com
|
||||
|
||||
To first send a POST and then a GET:
|
||||
|
||||
curl -d score=10 http://example.com/post.cgi --next http://example.com/results.html
|
||||
|
||||
|
||||
4. HTML forms
|
||||
|
||||
4.1 Forms explained
|
||||
|
||||
Forms are the general way a web site can present a HTML page with fields for
|
||||
the user to enter data in, and then press some kind of 'OK' or 'submit'
|
||||
button to get that data sent to the server. The server then typically uses
|
||||
the posted data to decide how to act. Like using the entered words to search
|
||||
in a database, or to add the info in a bug track system, display the entered
|
||||
address on a map or using the info as a login-prompt verifying that the user
|
||||
is allowed to see what it is about to see.
|
||||
|
||||
Of course there has to be some kind of program in the server end to receive
|
||||
the data you send. You cannot just invent something out of the air.
|
||||
|
||||
4.2 GET
|
||||
|
||||
A GET-form uses the method GET, as specified in HTML like:
|
||||
|
||||
<form method="GET" action="junk.cgi">
|
||||
<input type=text name="birthyear">
|
||||
<input type=submit name=press value="OK">
|
||||
</form>
|
||||
|
||||
In your favorite browser, this form will appear with a text box to fill in
|
||||
and a press-button labeled "OK". If you fill in '1905' and press the OK
|
||||
button, your browser will then create a new URL to get for you. The URL will
|
||||
get "junk.cgi?birthyear=1905&press=OK" appended to the path part of the
|
||||
previous URL.
|
||||
|
||||
If the original form was seen on the page "www.hotmail.com/when/birth.html",
|
||||
the second page you'll get will become
|
||||
"www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK".
|
||||
|
||||
Most search engines work this way.
|
||||
|
||||
To make curl do the GET form post for you, just enter the expected created
|
||||
URL:
|
||||
|
||||
curl "http://www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK"
|
||||
|
||||
4.3 POST
|
||||
|
||||
The GET method makes all input field names get displayed in the URL field of
|
||||
your browser. That's generally a good thing when you want to be able to
|
||||
bookmark that page with your given data, but it is an obvious disadvantage
|
||||
if you entered secret information in one of the fields or if there are a
|
||||
large amount of fields creating a very long and unreadable URL.
|
||||
|
||||
The HTTP protocol then offers the POST method. This way the client sends the
|
||||
data separated from the URL and thus you won't see any of it in the URL
|
||||
address field.
|
||||
|
||||
The form would look very similar to the previous one:
|
||||
|
||||
<form method="POST" action="junk.cgi">
|
||||
<input type=text name="birthyear">
|
||||
<input type=submit name=press value=" OK ">
|
||||
</form>
|
||||
|
||||
And to use curl to post this form with the same data filled in as before, we
|
||||
could do it like:
|
||||
|
||||
curl --data "birthyear=1905&press=%20OK%20" \
|
||||
http://www.example.com/when.cgi
|
||||
|
||||
This kind of POST will use the Content-Type
|
||||
application/x-www-form-urlencoded and is the most widely used POST kind.
|
||||
|
||||
The data you send to the server MUST already be properly encoded, curl will
|
||||
not do that for you. For example, if you want the data to contain a space,
|
||||
you need to replace that space with %20 etc. Failing to comply with this
|
||||
will most likely cause your data to be received wrongly and messed up.
|
||||
|
||||
Recent curl versions can in fact url-encode POST data for you, like this:
|
||||
|
||||
curl --data-urlencode "name=I am Daniel" http://www.example.com
|
||||
|
||||
If you repeat --data several times on the command line, curl will
|
||||
concatenate all the given data pieces - and put a '&' symbol between each
|
||||
data segment.
|
||||
|
||||
4.4 File Upload POST
|
||||
|
||||
Back in late 1995 they defined an additional way to post data over HTTP. It
|
||||
is documented in the RFC 1867, why this method sometimes is referred to as
|
||||
RFC1867-posting.
|
||||
|
||||
This method is mainly designed to better support file uploads. A form that
|
||||
allows a user to upload a file could be written like this in HTML:
|
||||
|
||||
<form method="POST" enctype='multipart/form-data' action="upload.cgi">
|
||||
<input type=file name=upload>
|
||||
<input type=submit name=press value="OK">
|
||||
</form>
|
||||
|
||||
This clearly shows that the Content-Type about to be sent is
|
||||
multipart/form-data.
|
||||
|
||||
To post to a form like this with curl, you enter a command line like:
|
||||
|
||||
curl --form upload=@localfilename --form press=OK [URL]
|
||||
|
||||
4.5 Hidden Fields
|
||||
|
||||
A very common way for HTML based application to pass state information
|
||||
between pages is to add hidden fields to the forms. Hidden fields are
|
||||
already filled in, they aren't displayed to the user and they get passed
|
||||
along just as all the other fields.
|
||||
|
||||
A similar example form with one visible field, one hidden field and one
|
||||
submit button could look like:
|
||||
|
||||
<form method="POST" action="foobar.cgi">
|
||||
<input type=text name="birthyear">
|
||||
<input type=hidden name="person" value="daniel">
|
||||
<input type=submit name="press" value="OK">
|
||||
</form>
|
||||
|
||||
To post this with curl, you won't have to think about if the fields are
|
||||
hidden or not. To curl they're all the same:
|
||||
|
||||
curl --data "birthyear=1905&press=OK&person=daniel" [URL]
|
||||
|
||||
4.6 Figure Out What A POST Looks Like
|
||||
|
||||
When you're about fill in a form and send to a server by using curl instead
|
||||
of a browser, you're of course very interested in sending a POST exactly the
|
||||
way your browser does.
|
||||
|
||||
An easy way to get to see this, is to save the HTML page with the form on
|
||||
your local disk, modify the 'method' to a GET, and press the submit button
|
||||
(you could also change the action URL if you want to).
|
||||
|
||||
You will then clearly see the data get appended to the URL, separated with a
|
||||
'?'-letter as GET forms are supposed to.
|
||||
|
||||
5. HTTP upload
|
||||
|
||||
5.1 PUT
|
||||
|
||||
The perhaps best way to upload data to a HTTP server is to use PUT. Then
|
||||
again, this of course requires that someone put a program or script on the
|
||||
server end that knows how to receive a HTTP PUT stream.
|
||||
|
||||
Put a file to a HTTP server with curl:
|
||||
|
||||
curl --upload-file uploadfile http://www.example.com/receive.cgi
|
||||
|
||||
6. HTTP Authentication
|
||||
|
||||
6.1 Basic Authentication
|
||||
|
||||
HTTP Authentication is the ability to tell the server your username and
|
||||
password so that it can verify that you're allowed to do the request you're
|
||||
doing. The Basic authentication used in HTTP (which is the type curl uses by
|
||||
default) is *plain* *text* based, which means it sends username and password
|
||||
only slightly obfuscated, but still fully readable by anyone that sniffs on
|
||||
the network between you and the remote server.
|
||||
|
||||
To tell curl to use a user and password for authentication:
|
||||
|
||||
curl --user name:password http://www.example.com
|
||||
|
||||
6.2 Other Authentication
|
||||
|
||||
The site might require a different authentication method (check the headers
|
||||
returned by the server), and then --ntlm, --digest, --negotiate or even
|
||||
--anyauth might be options that suit you.
|
||||
|
||||
6.3 Proxy Authentication
|
||||
|
||||
Sometimes your HTTP access is only available through the use of a HTTP
|
||||
proxy. This seems to be especially common at various companies. A HTTP proxy
|
||||
may require its own user and password to allow the client to get through to
|
||||
the Internet. To specify those with curl, run something like:
|
||||
|
||||
curl --proxy-user proxyuser:proxypassword curl.haxx.se
|
||||
|
||||
If your proxy requires the authentication to be done using the NTLM method,
|
||||
use --proxy-ntlm, if it requires Digest use --proxy-digest.
|
||||
|
||||
If you use any one these user+password options but leave out the password
|
||||
part, curl will prompt for the password interactively.
|
||||
|
||||
6.4 Hiding credentials
|
||||
|
||||
Do note that when a program is run, its parameters might be possible to see
|
||||
when listing the running processes of the system. Thus, other users may be
|
||||
able to watch your passwords if you pass them as plain command line
|
||||
options. There are ways to circumvent this.
|
||||
|
||||
It is worth noting that while this is how HTTP Authentication works, very
|
||||
many web sites will not use this concept when they provide logins etc. See
|
||||
the Web Login chapter further below for more details on that.
|
||||
|
||||
7. More HTTP Headers
|
||||
|
||||
7.1 Referer
|
||||
|
||||
A HTTP request may include a 'referer' field (yes it is misspelled), which
|
||||
can be used to tell from which URL the client got to this particular
|
||||
resource. Some programs/scripts check the referer field of requests to verify
|
||||
that this wasn't arriving from an external site or an unknown page. While
|
||||
this is a stupid way to check something so easily forged, many scripts still
|
||||
do it. Using curl, you can put anything you want in the referer-field and
|
||||
thus more easily be able to fool the server into serving your request.
|
||||
|
||||
Use curl to set the referer field with:
|
||||
|
||||
curl --referer http://www.example.come http://www.example.com
|
||||
|
||||
7.2 User Agent
|
||||
|
||||
Very similar to the referer field, all HTTP requests may set the User-Agent
|
||||
field. It names what user agent (client) that is being used. Many
|
||||
applications use this information to decide how to display pages. Silly web
|
||||
programmers try to make different pages for users of different browsers to
|
||||
make them look the best possible for their particular browsers. They usually
|
||||
also do different kinds of javascript, vbscript etc.
|
||||
|
||||
At times, you will see that getting a page with curl will not return the same
|
||||
page that you see when getting the page with your browser. Then you know it
|
||||
is time to set the User Agent field to fool the server into thinking you're
|
||||
one of those browsers.
|
||||
|
||||
To make curl look like Internet Explorer 5 on a Windows 2000 box:
|
||||
|
||||
curl --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL]
|
||||
|
||||
Or why not look like you're using Netscape 4.73 on an old Linux box:
|
||||
|
||||
curl --user-agent "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL]
|
||||
|
||||
8. Redirects
|
||||
|
||||
8.1 Location header
|
||||
|
||||
When a resource is requested from a server, the reply from the server may
|
||||
include a hint about where the browser should go next to find this page, or a
|
||||
new page keeping newly generated output. The header that tells the browser
|
||||
to redirect is Location:.
|
||||
|
||||
Curl does not follow Location: headers by default, but will simply display
|
||||
such pages in the same manner it display all HTTP replies. It does however
|
||||
feature an option that will make it attempt to follow the Location: pointers.
|
||||
|
||||
To tell curl to follow a Location:
|
||||
|
||||
curl --location http://www.example.com
|
||||
|
||||
If you use curl to POST to a site that immediately redirects you to another
|
||||
page, you can safely use --location (-L) and --data/--form together. Curl will
|
||||
only use POST in the first request, and then revert to GET in the following
|
||||
operations.
|
||||
|
||||
8.2 Other redirects
|
||||
|
||||
Browser typically support at least two other ways of redirects that curl
|
||||
doesn't: first the html may contain a meta refresh tag that asks the browser
|
||||
to load a specific URL after a set number of seconds, or it may use
|
||||
javascript to do it.
|
||||
|
||||
9. Cookies
|
||||
|
||||
9.1 Cookie Basics
|
||||
|
||||
The way the web browsers do "client side state control" is by using
|
||||
cookies. Cookies are just names with associated contents. The cookies are
|
||||
sent to the client by the server. The server tells the client for what path
|
||||
and host name it wants the cookie sent back, and it also sends an expiration
|
||||
date and a few more properties.
|
||||
|
||||
When a client communicates with a server with a name and path as previously
|
||||
specified in a received cookie, the client sends back the cookies and their
|
||||
contents to the server, unless of course they are expired.
|
||||
|
||||
Many applications and servers use this method to connect a series of requests
|
||||
into a single logical session. To be able to use curl in such occasions, we
|
||||
must be able to record and send back cookies the way the web application
|
||||
expects them. The same way browsers deal with them.
|
||||
|
||||
9.2 Cookie options
|
||||
|
||||
The simplest way to send a few cookies to the server when getting a page with
|
||||
curl is to add them on the command line like:
|
||||
|
||||
curl --cookie "name=Daniel" http://www.example.com
|
||||
|
||||
Cookies are sent as common HTTP headers. This is practical as it allows curl
|
||||
to record cookies simply by recording headers. Record cookies with curl by
|
||||
using the --dump-header (-D) option like:
|
||||
|
||||
curl --dump-header headers_and_cookies http://www.example.com
|
||||
|
||||
(Take note that the --cookie-jar option described below is a better way to
|
||||
store cookies.)
|
||||
|
||||
Curl has a full blown cookie parsing engine built-in that comes to use if you
|
||||
want to reconnect to a server and use cookies that were stored from a
|
||||
previous connection (or hand-crafted manually to fool the server into
|
||||
believing you had a previous connection). To use previously stored cookies,
|
||||
you run curl like:
|
||||
|
||||
curl --cookie stored_cookies_in_file http://www.example.com
|
||||
|
||||
Curl's "cookie engine" gets enabled when you use the --cookie option. If you
|
||||
only want curl to understand received cookies, use --cookie with a file that
|
||||
doesn't exist. Example, if you want to let curl understand cookies from a
|
||||
page and follow a location (and thus possibly send back cookies it received),
|
||||
you can invoke it like:
|
||||
|
||||
curl --cookie nada --location http://www.example.com
|
||||
|
||||
Curl has the ability to read and write cookie files that use the same file
|
||||
format that Netscape and Mozilla once used. It is a convenient way to share
|
||||
cookies between scripts or invokes. The --cookie (-b) switch automatically
|
||||
detects if a given file is such a cookie file and parses it, and by using the
|
||||
--cookie-jar (-c) option you'll make curl write a new cookie file at the end
|
||||
of an operation:
|
||||
|
||||
curl --cookie cookies.txt --cookie-jar newcookies.txt \
|
||||
http://www.example.com
|
||||
|
||||
10. HTTPS
|
||||
|
||||
10.1 HTTPS is HTTP secure
|
||||
|
||||
There are a few ways to do secure HTTP transfers. The by far most common
|
||||
protocol for doing this is what is generally known as HTTPS, HTTP over
|
||||
SSL. SSL encrypts all the data that is sent and received over the network and
|
||||
thus makes it harder for attackers to spy on sensitive information.
|
||||
|
||||
SSL (or TLS as the latest version of the standard is called) offers a
|
||||
truckload of advanced features to allow all those encryptions and key
|
||||
infrastructure mechanisms encrypted HTTP requires.
|
||||
|
||||
Curl supports encrypted fetches when built to use a TLS library and it can be
|
||||
built to use one out of a fairly large set of libraries - "curl -V" will show
|
||||
which one your curl was built to use (if any!). To get a page from a HTTPS
|
||||
server, simply run curl like:
|
||||
|
||||
curl https://secure.example.com
|
||||
|
||||
10.2 Certificates
|
||||
|
||||
In the HTTPS world, you use certificates to validate that you are the one
|
||||
you claim to be, as an addition to normal passwords. Curl supports client-
|
||||
side certificates. All certificates are locked with a pass phrase, which you
|
||||
need to enter before the certificate can be used by curl. The pass phrase
|
||||
can be specified on the command line or if not, entered interactively when
|
||||
curl queries for it. Use a certificate with curl on a HTTPS server like:
|
||||
|
||||
curl --cert mycert.pem https://secure.example.com
|
||||
|
||||
curl also tries to verify that the server is who it claims to be, by
|
||||
verifying the server's certificate against a locally stored CA cert
|
||||
bundle. Failing the verification will cause curl to deny the connection. You
|
||||
must then use --insecure (-k) in case you want to tell curl to ignore that
|
||||
the server can't be verified.
|
||||
|
||||
More about server certificate verification and ca cert bundles can be read
|
||||
in the SSLCERTS document, available online here:
|
||||
|
||||
http://curl.haxx.se/docs/sslcerts.html
|
||||
|
||||
At times you may end up with your own CA cert store and then you can tell
|
||||
curl to use that to verify the server's certificate:
|
||||
|
||||
curl --cacert ca-bundle.pem https://example.com/
|
||||
|
||||
|
||||
11. Custom Request Elements
|
||||
|
||||
11.1 Modify method and headers
|
||||
|
||||
Doing fancy stuff, you may need to add or change elements of a single curl
|
||||
request.
|
||||
|
||||
For example, you can change the POST request to a PROPFIND and send the data
|
||||
as "Content-Type: text/xml" (instead of the default Content-Type) like this:
|
||||
|
||||
curl --data "<xml>" --header "Content-Type: text/xml" \
|
||||
--request PROPFIND url.com
|
||||
|
||||
You can delete a default header by providing one without content. Like you
|
||||
can ruin the request by chopping off the Host: header:
|
||||
|
||||
curl --header "Host:" http://www.example.com
|
||||
|
||||
You can add headers the same way. Your server may want a "Destination:"
|
||||
header, and you can add it:
|
||||
|
||||
curl --header "Destination: http://nowhere" http://example.com
|
||||
|
||||
11.2 More on changed methods
|
||||
|
||||
It should be noted that curl selects which methods to use on its own
|
||||
depending on what action to ask for. -d will do POST, -I will do HEAD and so
|
||||
on. If you use the --request / -X option you can change the method keyword
|
||||
curl selects, but you will not modify curl's behavior. This means that if you
|
||||
for example use -d "data" to do a POST, you can modify the method to a
|
||||
PROPFIND with -X and curl will still think it sends a POST. You can change
|
||||
the normal GET to a POST method by simply adding -X POST in a command line
|
||||
like:
|
||||
|
||||
curl -X POST http://example.org/
|
||||
|
||||
... but curl will still think and act as if it sent a GET so it won't send any
|
||||
request body etc.
|
||||
|
||||
|
||||
12. Web Login
|
||||
|
||||
12.1 Some login tricks
|
||||
|
||||
While not strictly just HTTP related, it still cause a lot of people problems
|
||||
so here's the executive run-down of how the vast majority of all login forms
|
||||
work and how to login to them using curl.
|
||||
|
||||
It can also be noted that to do this properly in an automated fashion, you
|
||||
will most certainly need to script things and do multiple curl invokes etc.
|
||||
|
||||
First, servers mostly use cookies to track the logged-in status of the
|
||||
client, so you will need to capture the cookies you receive in the
|
||||
responses. Then, many sites also set a special cookie on the login page (to
|
||||
make sure you got there through their login page) so you should make a habit
|
||||
of first getting the login-form page to capture the cookies set there.
|
||||
|
||||
Some web-based login systems features various amounts of javascript, and
|
||||
sometimes they use such code to set or modify cookie contents. Possibly they
|
||||
do that to prevent programmed logins, like this manual describes how to...
|
||||
Anyway, if reading the code isn't enough to let you repeat the behavior
|
||||
manually, capturing the HTTP requests done by your browsers and analyzing the
|
||||
sent cookies is usually a working method to work out how to shortcut the
|
||||
javascript need.
|
||||
|
||||
In the actual <form> tag for the login, lots of sites fill-in random/session
|
||||
or otherwise secretly generated hidden tags and you may need to first capture
|
||||
the HTML code for the login form and extract all the hidden fields to be able
|
||||
to do a proper login POST. Remember that the contents need to be URL encoded
|
||||
when sent in a normal POST.
|
||||
|
||||
13. Debug
|
||||
|
||||
13.1 Some debug tricks
|
||||
|
||||
Many times when you run curl on a site, you'll notice that the site doesn't
|
||||
seem to respond the same way to your curl requests as it does to your
|
||||
browser's.
|
||||
|
||||
Then you need to start making your curl requests more similar to your
|
||||
browser's requests:
|
||||
|
||||
* Use the --trace-ascii option to store fully detailed logs of the requests
|
||||
for easier analyzing and better understanding
|
||||
|
||||
* Make sure you check for and use cookies when needed (both reading with
|
||||
--cookie and writing with --cookie-jar)
|
||||
|
||||
* Set user-agent to one like a recent popular browser does
|
||||
|
||||
* Set referer like it is set by the browser
|
||||
|
||||
* If you use POST, make sure you send all the fields and in the same order as
|
||||
the browser does it.
|
||||
|
||||
A very good helper to make sure you do this right, is the LiveHTTPHeader tool
|
||||
that lets you view all headers you send and receive with Mozilla/Firefox
|
||||
(even when using HTTPS). Chrome features similar functionality out of the box
|
||||
among the developer's tools.
|
||||
|
||||
A more raw approach is to capture the HTTP traffic on the network with tools
|
||||
such as ethereal or tcpdump and check what headers that were sent and
|
||||
received by the browser. (HTTPS makes this technique inefficient.)
|
||||
|
||||
14. References
|
||||
|
||||
14.1 Standards
|
||||
|
||||
RFC 7230 is a must to read if you want in-depth understanding of the HTTP
|
||||
protocol
|
||||
|
||||
RFC 3986 explains the URL syntax
|
||||
|
||||
RFC 1867 defines the HTTP post upload format
|
||||
|
||||
RFC 6525 defines how HTTP cookies work
|
||||
|
||||
14.2 Sites
|
||||
|
||||
http://curl.haxx.se is the home of the cURL project
|
56
curl/docs/VERSIONS
Normal file
56
curl/docs/VERSIONS
Normal file
@ -0,0 +1,56 @@
|
||||
Version Numbers and Releases
|
||||
============================
|
||||
|
||||
Curl is not only curl. Curl is also libcurl. They're actually individually
|
||||
versioned, but they mostly follow each other rather closely.
|
||||
|
||||
The version numbering is always built up using the same system:
|
||||
|
||||
X.Y.Z
|
||||
|
||||
- X is main version number
|
||||
- Y is release number
|
||||
- Z is patch number
|
||||
|
||||
## Bumping numbers
|
||||
|
||||
One of these numbers will get bumped in each new release. The numbers to the
|
||||
right of a bumped number will be reset to zero. If Z is zero, it may not be
|
||||
included in the version number.
|
||||
|
||||
The main version number will get bumped when *really* big, world colliding
|
||||
changes are made. The release number is bumped when changes are performed or
|
||||
things/features are added. The patch number is bumped when the changes are
|
||||
mere bugfixes.
|
||||
|
||||
It means that after release 1.2.3, we can release 2.0 if something really big
|
||||
has been made, 1.3 if not that big changes were made or 1.2.4 if mostly bugs
|
||||
were fixed.
|
||||
|
||||
Bumping, as in increasing the number with 1, is unconditionally only
|
||||
affecting one of the numbers (except the ones to the right of it, that may be
|
||||
set to zero). 1 becomes 2, 3 becomes 4, 9 becomes 10, 88 becomes 89 and 99
|
||||
becomes 100. So, after 1.2.9 comes 1.2.10. After 3.99.3, 3.100 might come.
|
||||
|
||||
All original curl source release archives are named according to the libcurl
|
||||
version (not according to the curl client version that, as said before, might
|
||||
differ).
|
||||
|
||||
As a service to any application that might want to support new libcurl
|
||||
features while still being able to build with older versions, all releases
|
||||
have the libcurl version stored in the curl/curlver.h file using a static
|
||||
numbering scheme that can be used for comparison. The version number is
|
||||
defined as:
|
||||
|
||||
#define LIBCURL_VERSION_NUM 0xXXYYZZ
|
||||
|
||||
Where XX, YY and ZZ are the main version, release and patch numbers in
|
||||
hexadecimal. All three number fields are always represented using two digits
|
||||
(eight bits each). 1.2 would appear as "0x010200" while version 9.11.7
|
||||
appears as "0x090b07".
|
||||
|
||||
This 6-digit hexadecimal number is always a greater number in a more recent
|
||||
release. It makes comparisons with greater than and less than work.
|
||||
|
||||
This number is also available as three separate defines:
|
||||
`LIBCURL_VERSION_MAJOR`, `LIBCURL_VERSION_MINOR` and `LIBCURL_VERSION_PATCH`.
|
98
curl/docs/curl-config.1
Normal file
98
curl/docs/curl-config.1
Normal file
@ -0,0 +1,98 @@
|
||||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
.\" *
|
||||
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
.\" * copies of the Software, and permit persons to whom the Software is
|
||||
.\" * furnished to do so, under the terms of the COPYING file.
|
||||
.\" *
|
||||
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
.\" * KIND, either express or implied.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl-config 1 "25 Oct 2007" "Curl 7.17.1" "curl-config manual"
|
||||
.SH NAME
|
||||
curl-config \- Get information about a libcurl installation
|
||||
.SH SYNOPSIS
|
||||
.B curl-config [options]
|
||||
.SH DESCRIPTION
|
||||
.B curl-config
|
||||
displays information about the curl and libcurl installation.
|
||||
.SH OPTIONS
|
||||
.IP "--ca"
|
||||
Displays the built-in path to the CA cert bundle this libcurl uses.
|
||||
.IP "--cc"
|
||||
Displays the compiler used to build libcurl.
|
||||
.IP "--cflags"
|
||||
Set of compiler options (CFLAGS) to use when compiling files that use
|
||||
libcurl. Currently that is only the include path to the curl include files.
|
||||
.IP "--checkfor [version]"
|
||||
Specify the oldest possible libcurl version string you want, and this
|
||||
script will return 0 if the current installation is new enough or it
|
||||
returns 1 and outputs a text saying that the current version is not new
|
||||
enough. (Added in 7.15.4)
|
||||
.IP "--configure"
|
||||
Displays the arguments given to configure when building curl.
|
||||
.IP "--feature"
|
||||
Lists what particular main features the installed libcurl was built with. At
|
||||
the time of writing, this list may include SSL, KRB4 or IPv6. Do not assume
|
||||
any particular order. The keywords will be separated by newlines. There may be
|
||||
none, one, or several keywords in the list.
|
||||
.IP "--help"
|
||||
Displays the available options.
|
||||
.IP "--libs"
|
||||
Shows the complete set of libs and other linker options you will need in order
|
||||
to link your application with libcurl.
|
||||
.IP "--prefix"
|
||||
This is the prefix used when libcurl was installed. Libcurl is then installed
|
||||
in $prefix/lib and its header files are installed in $prefix/include and so
|
||||
on. The prefix is set with "configure --prefix".
|
||||
.IP "--protocols"
|
||||
Lists what particular protocols the installed libcurl was built to support. At
|
||||
the time of writing, this list may include HTTP, HTTPS, FTP, FTPS, FILE,
|
||||
TELNET, LDAP, DICT. Do not assume any particular order. The protocols will
|
||||
be listed using uppercase and are separated by newlines. There may be none,
|
||||
one, or several protocols in the list. (Added in 7.13.0)
|
||||
.IP "--static-libs"
|
||||
Shows the complete set of libs and other linker options you will need in order
|
||||
to link your application with libcurl statically. (Added in 7.17.1)
|
||||
.IP "--version"
|
||||
Outputs version information about the installed libcurl.
|
||||
.IP "--vernum"
|
||||
Outputs version information about the installed libcurl, in numerical mode.
|
||||
This outputs the version number, in hexadecimal, with 8 bits for each part;
|
||||
major, minor, patch. So that libcurl 7.7.4 would appear as 070704 and libcurl
|
||||
12.13.14 would appear as 0c0d0e... Note that the initial zero might be
|
||||
omitted. (This option was broken in the 7.15.0 release.)
|
||||
.SH "EXAMPLES"
|
||||
What linker options do I need when I link with libcurl?
|
||||
|
||||
$ curl-config --libs
|
||||
|
||||
What compiler options do I need when I compile using libcurl functions?
|
||||
|
||||
$ curl-config --cflags
|
||||
|
||||
How do I know if libcurl was built with SSL support?
|
||||
|
||||
$ curl-config --feature | grep SSL
|
||||
|
||||
What's the installed libcurl version?
|
||||
|
||||
$ curl-config --version
|
||||
|
||||
How do I build a single file with a one-line command?
|
||||
|
||||
$ `curl-config --cc --cflags` -o example example.c `curl-config --libs`
|
||||
.SH "SEE ALSO"
|
||||
.BR curl (1)
|
96
curl/docs/curl-config.html
Normal file
96
curl/docs/curl-config.html
Normal file
@ -0,0 +1,96 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head>
|
||||
<title>curl-config man page</title>
|
||||
<meta name="generator" content="roffit">
|
||||
<STYLE type="text/css">
|
||||
pre {
|
||||
overflow: auto;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
P.level0, pre.level0 {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
P.level1, pre.level1 {
|
||||
padding-left: 4em;
|
||||
}
|
||||
|
||||
P.level2, pre.level2 {
|
||||
padding-left: 6em;
|
||||
}
|
||||
|
||||
span.emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
span.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
span.manpage {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h2.nroffsh {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
span.nroffip {
|
||||
font-weight: bold;
|
||||
font-size: 120%;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
p.roffit {
|
||||
text-align: center;
|
||||
font-size: 80%;
|
||||
}
|
||||
</STYLE>
|
||||
</head><body>
|
||||
|
||||
<p class="level0"><a name="NAME"></a><h2 class="nroffsh">NAME</h2>
|
||||
<p class="level0">curl-config - Get information about a libcurl installation <a name="SYNOPSIS"></a><h2 class="nroffsh">SYNOPSIS</h2>
|
||||
<p class="level0"><span Class="bold">curl-config [options]</span> <a name="DESCRIPTION"></a><h2 class="nroffsh">DESCRIPTION</h2>
|
||||
<p class="level0"><span Class="bold">curl-config</span> displays information about the curl and libcurl installation. <a name="OPTIONS"></a><h2 class="nroffsh">OPTIONS</h2>
|
||||
<p class="level0">
|
||||
<p class="level0"><a name="--ca"></a><span class="nroffip">--ca</span>
|
||||
<p class="level1">Displays the built-in path to the CA cert bundle this libcurl uses.
|
||||
<p class="level0"><a name="--cc"></a><span class="nroffip">--cc</span>
|
||||
<p class="level1">Displays the compiler used to build libcurl.
|
||||
<p class="level0"><a name="--cflags"></a><span class="nroffip">--cflags</span>
|
||||
<p class="level1">Set of compiler options (CFLAGS) to use when compiling files that use libcurl. Currently that is only the include path to the curl include files.
|
||||
<p class="level0"><a name="--checkfor"></a><span class="nroffip">--checkfor [version]</span>
|
||||
<p class="level1">Specify the oldest possible libcurl version string you want, and this script will return 0 if the current installation is new enough or it returns 1 and outputs a text saying that the current version is not new enough. (Added in 7.15.4)
|
||||
<p class="level0"><a name="--configure"></a><span class="nroffip">--configure</span>
|
||||
<p class="level1">Displays the arguments given to configure when building curl.
|
||||
<p class="level0"><a name="--feature"></a><span class="nroffip">--feature</span>
|
||||
<p class="level1">Lists what particular main features the installed libcurl was built with. At the time of writing, this list may include SSL, KRB4 or IPv6. Do not assume any particular order. The keywords will be separated by newlines. There may be none, one, or several keywords in the list.
|
||||
<p class="level0"><a name="--help"></a><span class="nroffip">--help</span>
|
||||
<p class="level1">Displays the available options.
|
||||
<p class="level0"><a name="--libs"></a><span class="nroffip">--libs</span>
|
||||
<p class="level1">Shows the complete set of libs and other linker options you will need in order to link your application with libcurl.
|
||||
<p class="level0"><a name="--prefix"></a><span class="nroffip">--prefix</span>
|
||||
<p class="level1">This is the prefix used when libcurl was installed. Libcurl is then installed in $prefix/lib and its header files are installed in $prefix/include and so on. The prefix is set with "configure --prefix".
|
||||
<p class="level0"><a name="--protocols"></a><span class="nroffip">--protocols</span>
|
||||
<p class="level1">Lists what particular protocols the installed libcurl was built to support. At the time of writing, this list may include HTTP, HTTPS, FTP, FTPS, FILE, TELNET, LDAP, DICT. Do not assume any particular order. The protocols will be listed using uppercase and are separated by newlines. There may be none, one, or several protocols in the list. (Added in 7.13.0)
|
||||
<p class="level0"><a name="--static-libs"></a><span class="nroffip">--static-libs</span>
|
||||
<p class="level1">Shows the complete set of libs and other linker options you will need in order to link your application with libcurl statically. (Added in 7.17.1)
|
||||
<p class="level0"><a name="--version"></a><span class="nroffip">--version</span>
|
||||
<p class="level1">Outputs version information about the installed libcurl.
|
||||
<p class="level0"><a name="--vernum"></a><span class="nroffip">--vernum</span>
|
||||
<p class="level1">Outputs version information about the installed libcurl, in numerical mode. This outputs the version number, in hexadecimal, with 8 bits for each part; major, minor, patch. So that libcurl 7.7.4 would appear as 070704 and libcurl 12.13.14 would appear as 0c0d0e... Note that the initial zero might be omitted. (This option was broken in the 7.15.0 release.) <a name="EXAMPLES"></a><h2 class="nroffsh">EXAMPLES</h2>
|
||||
<p class="level0">What linker options do I need when I link with libcurl?
|
||||
<p class="level0"> $ curl-config --libs
|
||||
<p class="level0">What compiler options do I need when I compile using libcurl functions?
|
||||
<p class="level0"> $ curl-config --cflags
|
||||
<p class="level0">How do I know if libcurl was built with SSL support?
|
||||
<p class="level0"> $ curl-config --feature | grep SSL
|
||||
<p class="level0">What's the installed libcurl version?
|
||||
<p class="level0"> $ curl-config --version
|
||||
<p class="level0">How do I build a single file with a one-line command?
|
||||
<p class="level0"> $ `curl-config --cc --cflags` -o example example.c `curl-config --libs` <a name="SEE"></a><h2 class="nroffsh">SEE ALSO</h2>
|
||||
<p class="level0"><span Class="manpage">curl (1)</span> <p class="roffit">
|
||||
This HTML page was made with <a href="http://daniel.haxx.se/projects/roffit/">roffit</a>.
|
||||
</body></html>
|
BIN
curl/docs/curl-config.pdf
Normal file
BIN
curl/docs/curl-config.pdf
Normal file
Binary file not shown.
2277
curl/docs/curl.1
Normal file
2277
curl/docs/curl.1
Normal file
File diff suppressed because it is too large
Load Diff
1055
curl/docs/curl.html
Normal file
1055
curl/docs/curl.html
Normal file
File diff suppressed because it is too large
Load Diff
BIN
curl/docs/curl.pdf
Normal file
BIN
curl/docs/curl.pdf
Normal file
Binary file not shown.
196
curl/docs/examples/10-at-a-time.c
Normal file
196
curl/docs/examples/10-at-a-time.c
Normal file
@ -0,0 +1,196 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* Example application source code using the multi interface to download many
|
||||
* files, but with a capped maximum amount of simultaneous transfers.
|
||||
*
|
||||
* Written by Michael Wallner
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef WIN32
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <curl/multi.h>
|
||||
|
||||
static const char *urls[] = {
|
||||
"http://www.microsoft.com",
|
||||
"http://www.opensource.org",
|
||||
"http://www.google.com",
|
||||
"http://www.yahoo.com",
|
||||
"http://www.ibm.com",
|
||||
"http://www.mysql.com",
|
||||
"http://www.oracle.com",
|
||||
"http://www.ripe.net",
|
||||
"http://www.iana.org",
|
||||
"http://www.amazon.com",
|
||||
"http://www.netcraft.com",
|
||||
"http://www.heise.de",
|
||||
"http://www.chip.de",
|
||||
"http://www.ca.com",
|
||||
"http://www.cnet.com",
|
||||
"http://www.news.com",
|
||||
"http://www.cnn.com",
|
||||
"http://www.wikipedia.org",
|
||||
"http://www.dell.com",
|
||||
"http://www.hp.com",
|
||||
"http://www.cert.org",
|
||||
"http://www.mit.edu",
|
||||
"http://www.nist.gov",
|
||||
"http://www.ebay.com",
|
||||
"http://www.playstation.com",
|
||||
"http://www.uefa.com",
|
||||
"http://www.ieee.org",
|
||||
"http://www.apple.com",
|
||||
"http://www.symantec.com",
|
||||
"http://www.zdnet.com",
|
||||
"http://www.fujitsu.com",
|
||||
"http://www.supermicro.com",
|
||||
"http://www.hotmail.com",
|
||||
"http://www.ecma.com",
|
||||
"http://www.bbc.co.uk",
|
||||
"http://news.google.com",
|
||||
"http://www.foxnews.com",
|
||||
"http://www.msn.com",
|
||||
"http://www.wired.com",
|
||||
"http://www.sky.com",
|
||||
"http://www.usatoday.com",
|
||||
"http://www.cbs.com",
|
||||
"http://www.nbc.com",
|
||||
"http://slashdot.org",
|
||||
"http://www.bloglines.com",
|
||||
"http://www.techweb.com",
|
||||
"http://www.newslink.org",
|
||||
"http://www.un.org",
|
||||
};
|
||||
|
||||
#define MAX 10 /* number of simultaneous transfers */
|
||||
#define CNT sizeof(urls)/sizeof(char*) /* total number of transfers to do */
|
||||
|
||||
static size_t cb(char *d, size_t n, size_t l, void *p)
|
||||
{
|
||||
/* take care of the data here, ignored in this example */
|
||||
(void)d;
|
||||
(void)p;
|
||||
return n*l;
|
||||
}
|
||||
|
||||
static void init(CURLM *cm, int i)
|
||||
{
|
||||
CURL *eh = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, cb);
|
||||
curl_easy_setopt(eh, CURLOPT_HEADER, 0L);
|
||||
curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
|
||||
curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
|
||||
curl_easy_setopt(eh, CURLOPT_VERBOSE, 0L);
|
||||
|
||||
curl_multi_add_handle(cm, eh);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURLM *cm;
|
||||
CURLMsg *msg;
|
||||
long L;
|
||||
unsigned int C=0;
|
||||
int M, Q, U = -1;
|
||||
fd_set R, W, E;
|
||||
struct timeval T;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
cm = curl_multi_init();
|
||||
|
||||
/* we can optionally limit the total amount of connections this multi handle
|
||||
uses */
|
||||
curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)MAX);
|
||||
|
||||
for (C = 0; C < MAX; ++C) {
|
||||
init(cm, C);
|
||||
}
|
||||
|
||||
while (U) {
|
||||
curl_multi_perform(cm, &U);
|
||||
|
||||
if (U) {
|
||||
FD_ZERO(&R);
|
||||
FD_ZERO(&W);
|
||||
FD_ZERO(&E);
|
||||
|
||||
if (curl_multi_fdset(cm, &R, &W, &E, &M)) {
|
||||
fprintf(stderr, "E: curl_multi_fdset\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (curl_multi_timeout(cm, &L)) {
|
||||
fprintf(stderr, "E: curl_multi_timeout\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (L == -1)
|
||||
L = 100;
|
||||
|
||||
if (M == -1) {
|
||||
#ifdef WIN32
|
||||
Sleep(L);
|
||||
#else
|
||||
sleep(L / 1000);
|
||||
#endif
|
||||
} else {
|
||||
T.tv_sec = L/1000;
|
||||
T.tv_usec = (L%1000)*1000;
|
||||
|
||||
if (0 > select(M+1, &R, &W, &E, &T)) {
|
||||
fprintf(stderr, "E: select(%i,,,,%li): %i: %s\n",
|
||||
M+1, L, errno, strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ((msg = curl_multi_info_read(cm, &Q))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
char *url;
|
||||
CURL *e = msg->easy_handle;
|
||||
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
|
||||
fprintf(stderr, "R: %d - %s <%s>\n",
|
||||
msg->data.result, curl_easy_strerror(msg->data.result), url);
|
||||
curl_multi_remove_handle(cm, e);
|
||||
curl_easy_cleanup(e);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
|
||||
}
|
||||
if (C < CNT) {
|
||||
init(cm, C++);
|
||||
U++; /* just to prevent it from remaining at 0 if there are more
|
||||
URLs to get */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(cm);
|
||||
curl_global_cleanup();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
63
curl/docs/examples/Makefile.am
Normal file
63
curl/docs/examples/Makefile.am
Normal file
@ -0,0 +1,63 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
EXTRA_DIST = README Makefile.example Makefile.inc Makefile.m32 \
|
||||
Makefile.netware makefile.dj $(COMPLICATED_EXAMPLES)
|
||||
|
||||
# Specify our include paths here, and do it relative to $(top_srcdir) and
|
||||
# $(top_builddir), to ensure that these paths which belong to the library
|
||||
# being currently built and tested are searched before the library which
|
||||
# might possibly already be installed in the system.
|
||||
#
|
||||
# $(top_builddir)/include/curl for generated curlbuild.h included from curl.h
|
||||
# $(top_builddir)/include for generated curlbuild.h inc. from lib/curl_setup.h
|
||||
# $(top_srcdir)/include is for libcurl's external include files
|
||||
|
||||
AM_CPPFLAGS = -I$(top_builddir)/include/curl \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/include
|
||||
|
||||
LIBDIR = $(top_builddir)/lib
|
||||
|
||||
# Avoid libcurl obsolete stuff
|
||||
AM_CPPFLAGS += -DCURL_NO_OLDIES
|
||||
|
||||
if USE_CPPFLAG_CURL_STATICLIB
|
||||
AM_CPPFLAGS += -DCURL_STATICLIB
|
||||
endif
|
||||
|
||||
# Prevent LIBS from being used for all link targets
|
||||
LIBS = $(BLANK_AT_MAKETIME)
|
||||
|
||||
# Dependencies
|
||||
if USE_EXPLICIT_LIB_DEPS
|
||||
LDADD = $(LIBDIR)/libcurl.la @LIBCURL_LIBS@
|
||||
else
|
||||
LDADD = $(LIBDIR)/libcurl.la
|
||||
endif
|
||||
|
||||
# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines
|
||||
include Makefile.inc
|
||||
|
||||
all: $(check_PROGRAMS)
|
53
curl/docs/examples/Makefile.example
Normal file
53
curl/docs/examples/Makefile.example
Normal file
@ -0,0 +1,53 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# What to call the final executable
|
||||
TARGET = example
|
||||
|
||||
# Which object files that the executable consists of
|
||||
OBJS= ftpget.o
|
||||
|
||||
# What compiler to use
|
||||
CC = gcc
|
||||
|
||||
# Compiler flags, -g for debug, -c to make an object file
|
||||
CFLAGS = -c -g
|
||||
|
||||
# This should point to a directory that holds libcurl, if it isn't
|
||||
# in the system's standard lib dir
|
||||
# We also set a -L to include the directory where we have the openssl
|
||||
# libraries
|
||||
LDFLAGS = -L/home/dast/lib -L/usr/local/ssl/lib
|
||||
|
||||
# We need -lcurl for the curl stuff
|
||||
# We need -lsocket and -lnsl when on Solaris
|
||||
# We need -lssl and -lcrypto when using libcurl with SSL support
|
||||
# We need -lpthread for the pthread example
|
||||
LIBS = -lcurl -lsocket -lnsl -lssl -lcrypto
|
||||
|
||||
# Link the target with all objects and libraries
|
||||
$(TARGET) : $(OBJS)
|
||||
$(CC) -o $(TARGET) $(OBJS) $(LDFLAGS) $(LIBS)
|
||||
|
||||
# Compile the source files into object files
|
||||
ftpget.o : ftpget.c
|
||||
$(CC) $(CFLAGS) $<
|
1645
curl/docs/examples/Makefile.in
Normal file
1645
curl/docs/examples/Makefile.in
Normal file
File diff suppressed because it is too large
Load Diff
43
curl/docs/examples/Makefile.inc
Normal file
43
curl/docs/examples/Makefile.inc
Normal file
@ -0,0 +1,43 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# These are all libcurl example programs to be test compiled
|
||||
check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
|
||||
fopen ftpget ftpgetresp ftpupload getinfo getinmemory http-post httpput \
|
||||
https multi-app multi-debugcallback multi-double multi-post multi-single \
|
||||
persistant post-callback postit2 sepheaders simple simplepost simplessl \
|
||||
sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
|
||||
smtp-mail smtp-multi smtp-ssl smtp-tls smtp-vrfy smtp-expn rtsp \
|
||||
externalsocket resolve progressfunc pop3-retr pop3-list pop3-uidl \
|
||||
pop3-dele pop3-top pop3-stat pop3-noop pop3-ssl pop3-tls pop3-multi \
|
||||
imap-list imap-lsub imap-fetch imap-store imap-append imap-examine \
|
||||
imap-search imap-create imap-delete imap-copy imap-noop imap-ssl \
|
||||
imap-tls imap-multi url2file sftpget ftpsget postinmemory http2-download \
|
||||
http2-upload
|
||||
|
||||
# These examples require external dependencies that may not be commonly
|
||||
# available on POSIX systems, so don't bother attempting to compile them here.
|
||||
COMPLICATED_EXAMPLES = curlgtk.c curlx.c htmltitle.cpp cacertinmem.c \
|
||||
ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \
|
||||
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
|
||||
smooth-gtk-thread.c version-check.pl href_extractor.c asiohiper.cpp \
|
||||
multi-uv.c xmlstream.c usercertinmem.c sessioninfo.c
|
297
curl/docs/examples/Makefile.m32
Normal file
297
curl/docs/examples/Makefile.m32
Normal file
@ -0,0 +1,297 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
#
|
||||
## Makefile for building curl examples with MingW (GCC-3.2 or later)
|
||||
## and optionally OpenSSL (1.0.2a), libssh2 (1.5), zlib (1.2.8), librtmp (2.4)
|
||||
##
|
||||
## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...]
|
||||
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-spi-winidn
|
||||
##
|
||||
## Hint: you can also set environment vars to control the build, f.e.:
|
||||
## set ZLIB_PATH=c:/zlib-1.2.8
|
||||
## set ZLIB=1
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../../zlib-1.2.8
|
||||
endif
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../../openssl-1.0.2a
|
||||
endif
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../../libssh2-1.5.0
|
||||
endif
|
||||
# Edit the path below to point to the base of your librtmp package.
|
||||
ifndef LIBRTMP_PATH
|
||||
LIBRTMP_PATH = ../../../librtmp-2.4
|
||||
endif
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../../libidn-1.30
|
||||
endif
|
||||
# Edit the path below to point to the base of your MS IDN package.
|
||||
# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1
|
||||
# https://www.microsoft.com/en-us/download/details.aspx?id=734
|
||||
ifndef WINIDN_PATH
|
||||
WINIDN_PATH = ../../../Microsoft IDN Mitigation APIs
|
||||
endif
|
||||
# Edit the path below to point to the base of your Novell LDAP NDK.
|
||||
ifndef LDAP_SDK
|
||||
LDAP_SDK = c:/novell/ndk/cldapsdk/win32
|
||||
endif
|
||||
# Edit the path below to point to the base of your nghttp2 package.
|
||||
ifndef NGHTTP2_PATH
|
||||
NGHTTP2_PATH = ../../../nghttp2-1.0.0
|
||||
endif
|
||||
|
||||
PROOT = ../..
|
||||
|
||||
# Edit the path below to point to the base of your c-ares package.
|
||||
ifndef LIBCARES_PATH
|
||||
LIBCARES_PATH = $(PROOT)/ares
|
||||
endif
|
||||
|
||||
# Edit the var below to set to your architecture or set environment var.
|
||||
ifndef ARCH
|
||||
ifeq ($(findstring x86_64,$(shell $(CC) -dumpmachine)),x86_64)
|
||||
ARCH = w64
|
||||
else
|
||||
ARCH = w32
|
||||
endif
|
||||
endif
|
||||
|
||||
CC = $(CROSSPREFIX)gcc
|
||||
CFLAGS = -g -O2 -Wall
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
ifeq ($(ARCH),w64)
|
||||
CFLAGS += -m64 -D_AMD64_
|
||||
LDFLAGS += -m64
|
||||
RCFLAGS += -F pe-x86-64
|
||||
else
|
||||
CFLAGS += -m32
|
||||
LDFLAGS += -m32
|
||||
RCFLAGS += -F pe-i386
|
||||
endif
|
||||
# comment LDFLAGS below to keep debug info
|
||||
LDFLAGS = -s
|
||||
RC = $(CROSSPREFIX)windres
|
||||
RCFLAGS = --include-dir=$(PROOT)/include -O COFF -i
|
||||
|
||||
# Platform-dependent helper tool macros
|
||||
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||
DEL = rm -f $1
|
||||
RMDIR = rm -fr $1
|
||||
MKDIR = mkdir -p $1
|
||||
COPY = -cp -afv $1 $2
|
||||
#COPYR = -cp -afr $1/* $2
|
||||
COPYR = -rsync -aC $1/* $2
|
||||
TOUCH = touch $1
|
||||
CAT = cat
|
||||
ECHONL = echo ""
|
||||
DL = '
|
||||
else
|
||||
ifeq "$(OS)" "Windows_NT"
|
||||
DEL = -del 2>NUL /q /f $(subst /,\,$1)
|
||||
RMDIR = -rd 2>NUL /q /s $(subst /,\,$1)
|
||||
else
|
||||
DEL = -del 2>NUL $(subst /,\,$1)
|
||||
RMDIR = -deltree 2>NUL /y $(subst /,\,$1)
|
||||
endif
|
||||
MKDIR = -md 2>NUL $(subst /,\,$1)
|
||||
COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2)
|
||||
COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2)
|
||||
TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,,
|
||||
CAT = type
|
||||
ECHONL = $(ComSpec) /c echo.
|
||||
endif
|
||||
|
||||
########################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
ifeq ($(findstring -dyn,$(CFG)),-dyn)
|
||||
DYN = 1
|
||||
endif
|
||||
ifeq ($(findstring -ares,$(CFG)),-ares)
|
||||
ARES = 1
|
||||
endif
|
||||
ifeq ($(findstring -rtmp,$(CFG)),-rtmp)
|
||||
RTMP = 1
|
||||
SSL = 1
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -ssh2,$(CFG)),-ssh2)
|
||||
SSH2 = 1
|
||||
SSL = 1
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -ssl,$(CFG)),-ssl)
|
||||
SSL = 1
|
||||
endif
|
||||
ifeq ($(findstring -zlib,$(CFG)),-zlib)
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -idn,$(CFG)),-idn)
|
||||
IDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -winidn,$(CFG)),-winidn)
|
||||
WINIDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -sspi,$(CFG)),-sspi)
|
||||
SSPI = 1
|
||||
endif
|
||||
ifeq ($(findstring -ldaps,$(CFG)),-ldaps)
|
||||
LDAPS = 1
|
||||
endif
|
||||
ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
|
||||
IPV6 = 1
|
||||
endif
|
||||
ifeq ($(findstring -metalink,$(CFG)),-metalink)
|
||||
METALINK = 1
|
||||
endif
|
||||
ifeq ($(findstring -winssl,$(CFG)),-winssl)
|
||||
WINSSL = 1
|
||||
SSPI = 1
|
||||
endif
|
||||
ifeq ($(findstring -nghttp2,$(CFG)),-nghttp2)
|
||||
NGHTTP2 = 1
|
||||
endif
|
||||
|
||||
INCLUDES = -I. -I$(PROOT) -I$(PROOT)/include -I$(PROOT)/lib
|
||||
|
||||
ifdef DYN
|
||||
curl_DEPENDENCIES = $(PROOT)/lib/libcurldll.a $(PROOT)/lib/libcurl.dll
|
||||
curl_LDADD = -L$(PROOT)/lib -lcurldll
|
||||
else
|
||||
curl_DEPENDENCIES = $(PROOT)/lib/libcurl.a
|
||||
curl_LDADD = -L$(PROOT)/lib -lcurl
|
||||
CFLAGS += -DCURL_STATICLIB
|
||||
LDFLAGS += -static
|
||||
endif
|
||||
ifdef ARES
|
||||
ifndef DYN
|
||||
curl_DEPENDENCIES += $(LIBCARES_PATH)/libcares.a
|
||||
endif
|
||||
CFLAGS += -DUSE_ARES
|
||||
curl_LDADD += -L"$(LIBCARES_PATH)" -lcares
|
||||
endif
|
||||
ifdef RTMP
|
||||
CFLAGS += -DUSE_LIBRTMP
|
||||
curl_LDADD += -L"$(LIBRTMP_PATH)/librtmp" -lrtmp -lwinmm
|
||||
endif
|
||||
ifdef NGHTTP2
|
||||
CFLAGS += -DUSE_NGHTTP2
|
||||
curl_LDADD += -L"$(NGHTTP2_PATH)/lib" -lnghttp2
|
||||
endif
|
||||
ifdef SSH2
|
||||
CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H
|
||||
curl_LDADD += -L"$(LIBSSH2_PATH)/win32" -lssh2
|
||||
endif
|
||||
ifdef SSL
|
||||
ifndef OPENSSL_LIBPATH
|
||||
OPENSSL_LIBS = -lssl -lcrypto
|
||||
ifeq "$(wildcard $(OPENSSL_PATH)/out)" "$(OPENSSL_PATH)/out"
|
||||
OPENSSL_LIBPATH = $(OPENSSL_PATH)/out
|
||||
ifdef DYN
|
||||
OPENSSL_LIBS = -lssl32 -leay32
|
||||
endif
|
||||
endif
|
||||
ifeq "$(wildcard $(OPENSSL_PATH)/lib)" "$(OPENSSL_PATH)/lib"
|
||||
OPENSSL_LIBPATH = $(OPENSSL_PATH)/lib
|
||||
endif
|
||||
endif
|
||||
ifndef DYN
|
||||
OPENSSL_LIBS += -lgdi32 -lcrypt32
|
||||
endif
|
||||
CFLAGS += -DUSE_OPENSSL
|
||||
curl_LDADD += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS)
|
||||
endif
|
||||
ifdef ZLIB
|
||||
INCLUDES += -I"$(ZLIB_PATH)"
|
||||
CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
|
||||
curl_LDADD += -L"$(ZLIB_PATH)" -lz
|
||||
endif
|
||||
ifdef IDN
|
||||
CFLAGS += -DUSE_LIBIDN
|
||||
curl_LDADD += -L"$(LIBIDN_PATH)/lib" -lidn
|
||||
else
|
||||
ifdef WINIDN
|
||||
CFLAGS += -DUSE_WIN32_IDN
|
||||
curl_LDADD += -L"$(WINIDN_PATH)" -lnormaliz
|
||||
endif
|
||||
endif
|
||||
ifdef SSPI
|
||||
CFLAGS += -DUSE_WINDOWS_SSPI
|
||||
ifdef WINSSL
|
||||
CFLAGS += -DUSE_SCHANNEL
|
||||
endif
|
||||
endif
|
||||
ifdef IPV6
|
||||
CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501
|
||||
endif
|
||||
ifdef LDAPS
|
||||
CFLAGS += -DHAVE_LDAP_SSL
|
||||
endif
|
||||
ifdef USE_LDAP_NOVELL
|
||||
CFLAGS += -DCURL_HAS_NOVELL_LDAPSDK
|
||||
curl_LDADD += -L"$(LDAP_SDK)/lib/mscvc" -lldapsdk -lldapssl -lldapx
|
||||
endif
|
||||
ifdef USE_LDAP_OPENLDAP
|
||||
CFLAGS += -DCURL_HAS_OPENLDAP_LDAPSDK
|
||||
curl_LDADD += -L"$(LDAP_SDK)/lib" -lldap -llber
|
||||
endif
|
||||
ifndef USE_LDAP_NOVELL
|
||||
ifndef USE_LDAP_OPENLDAP
|
||||
curl_LDADD += -lwldap32
|
||||
endif
|
||||
endif
|
||||
curl_LDADD += -lws2_32
|
||||
|
||||
# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines
|
||||
include Makefile.inc
|
||||
|
||||
check_PROGRAMS := $(patsubst %,%.exe,$(strip $(check_PROGRAMS)))
|
||||
check_PROGRAMS += ftpuploadresume.exe synctime.exe
|
||||
|
||||
.PRECIOUS: %.o
|
||||
|
||||
|
||||
all: $(check_PROGRAMS)
|
||||
|
||||
%.exe: %.o $(curl_DEPENDENCIES)
|
||||
$(CC) $(LDFLAGS) -o $@ $< $(curl_LDADD)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
%.res: %.rc
|
||||
$(RC) $(RCFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
@$(call DEL, $(check_PROGRAMS:.exe=.o))
|
||||
|
||||
distclean vclean: clean
|
||||
@$(call DEL, $(check_PROGRAMS))
|
||||
|
434
curl/docs/examples/Makefile.netware
Normal file
434
curl/docs/examples/Makefile.netware
Normal file
@ -0,0 +1,434 @@
|
||||
#################################################################
|
||||
#
|
||||
## Makefile for building curl.nlm (NetWare version - gnu make)
|
||||
## Use: make -f Makefile.netware
|
||||
##
|
||||
## Comments to: Guenter Knauf http://www.gknw.net/phpbb
|
||||
#
|
||||
#################################################################
|
||||
|
||||
# Edit the path below to point to the base of your Novell NDK.
|
||||
ifndef NDKBASE
|
||||
NDKBASE = c:/novell
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../../zlib-1.2.8
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../../openssl-1.0.2a
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../../libssh2-1.5.0
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your axTLS package.
|
||||
ifndef AXTLS_PATH
|
||||
AXTLS_PATH = ../../../axTLS-1.2.7
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../../libidn-1.30
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your librtmp package.
|
||||
ifndef LIBRTMP_PATH
|
||||
LIBRTMP_PATH = ../../../librtmp-2.4
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your fbopenssl package.
|
||||
ifndef FBOPENSSL_PATH
|
||||
FBOPENSSL_PATH = ../../fbopenssl-0.4
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your c-ares package.
|
||||
ifndef LIBCARES_PATH
|
||||
LIBCARES_PATH = ../../ares
|
||||
endif
|
||||
|
||||
ifndef INSTDIR
|
||||
INSTDIR = ..$(DS)..$(DS)curl-$(LIBCURL_VERSION_STR)-bin-nw
|
||||
endif
|
||||
|
||||
# Edit the vars below to change NLM target settings.
|
||||
TARGET = examples
|
||||
VERSION = $(LIBCURL_VERSION)
|
||||
COPYR = Copyright (C) $(LIBCURL_COPYRIGHT_STR)
|
||||
DESCR = cURL ($(LIBARCH))
|
||||
MTSAFE = YES
|
||||
STACK = 8192
|
||||
SCREEN = Example Program
|
||||
# Comment the line below if you dont want to load protected automatically.
|
||||
# LDRING = 3
|
||||
|
||||
# Uncomment the next line to enable linking with POSIX semantics.
|
||||
# POSIXFL = 1
|
||||
|
||||
# Edit the var below to point to your lib architecture.
|
||||
ifndef LIBARCH
|
||||
LIBARCH = LIBC
|
||||
endif
|
||||
|
||||
# must be equal to NDEBUG or DEBUG, CURLDEBUG
|
||||
ifndef DB
|
||||
DB = NDEBUG
|
||||
endif
|
||||
# Optimization: -O<n> or debugging: -g
|
||||
ifeq ($(DB),NDEBUG)
|
||||
OPT = -O2
|
||||
OBJDIR = release
|
||||
else
|
||||
OPT = -g
|
||||
OBJDIR = debug
|
||||
endif
|
||||
|
||||
# The following lines defines your compiler.
|
||||
ifdef CWFolder
|
||||
METROWERKS = $(CWFolder)
|
||||
endif
|
||||
ifdef METROWERKS
|
||||
# MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support
|
||||
MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support
|
||||
CC = mwccnlm
|
||||
else
|
||||
CC = gcc
|
||||
endif
|
||||
PERL = perl
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk-20100523.zip
|
||||
AWK = awk
|
||||
CP = cp -afv
|
||||
MKDIR = mkdir
|
||||
# RM = rm -f
|
||||
# If you want to mark the target as MTSAFE you will need a tool for
|
||||
# generating the xdc data for the linker; here's a minimal tool:
|
||||
# http://www.gknw.net/development/prgtools/mkxdc.zip
|
||||
MPKXDC = mkxdc
|
||||
|
||||
# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH))
|
||||
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
|
||||
|
||||
# Include the version info retrieved from curlver.h
|
||||
-include $(OBJDIR)/version.inc
|
||||
|
||||
# Global flags for all compilers
|
||||
CFLAGS += $(OPT) -D$(DB) -DNETWARE -DHAVE_CONFIG_H -nostdinc
|
||||
|
||||
ifeq ($(CC),mwccnlm)
|
||||
LD = mwldnlm
|
||||
LDFLAGS = -nostdlib $< $(PRELUDE) $(LDLIBS) -o $@ -commandfile
|
||||
LIBEXT = lib
|
||||
CFLAGS += -gccinc -inline off -opt nointrinsics -proc 586
|
||||
CFLAGS += -relax_pointers
|
||||
#CFLAGS += -w on
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
ifeq ($(POSIXFL),1)
|
||||
PRELUDE = $(NDK_LIBC)/imports/posixpre.o
|
||||
else
|
||||
PRELUDE = $(NDK_LIBC)/imports/libcpre.o
|
||||
endif
|
||||
CFLAGS += -align 4
|
||||
else
|
||||
# PRELUDE = $(NDK_CLIB)/imports/clibpre.o
|
||||
# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
|
||||
PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj"
|
||||
# CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h"
|
||||
CFLAGS += -align 1
|
||||
endif
|
||||
else
|
||||
LD = nlmconv
|
||||
LDFLAGS = -T
|
||||
LIBEXT = a
|
||||
CFLAGS += -m32
|
||||
CFLAGS += -fno-builtin -fno-strict-aliasing
|
||||
ifeq ($(findstring gcc,$(CC)),gcc)
|
||||
CFLAGS += -fpcc-struct-return
|
||||
endif
|
||||
CFLAGS += -Wall # -pedantic
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
ifeq ($(POSIXFL),1)
|
||||
PRELUDE = $(NDK_LIBC)/imports/posixpre.gcc.o
|
||||
else
|
||||
PRELUDE = $(NDK_LIBC)/imports/libcpre.gcc.o
|
||||
endif
|
||||
else
|
||||
# PRELUDE = $(NDK_CLIB)/imports/clibpre.gcc.o
|
||||
# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
|
||||
# http://www.gknw.net/development/mk_nlm/gcc_pre.zip
|
||||
PRELUDE = $(NDK_ROOT)/pre/prelude.o
|
||||
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
|
||||
endif
|
||||
endif
|
||||
|
||||
NDK_ROOT = $(NDKBASE)/ndk
|
||||
ifndef NDK_CLIB
|
||||
NDK_CLIB = $(NDK_ROOT)/nwsdk
|
||||
endif
|
||||
ifndef NDK_LIBC
|
||||
NDK_LIBC = $(NDK_ROOT)/libc
|
||||
endif
|
||||
ifndef NDK_LDAP
|
||||
NDK_LDAP = $(NDK_ROOT)/cldapsdk/netware
|
||||
endif
|
||||
CURL_INC = ../../include
|
||||
CURL_LIB = ../../lib
|
||||
|
||||
INCLUDES = -I$(CURL_INC)
|
||||
|
||||
ifeq ($(findstring -static,$(CFG)),-static)
|
||||
LINK_STATIC = 1
|
||||
endif
|
||||
ifeq ($(findstring -ares,$(CFG)),-ares)
|
||||
WITH_ARES = 1
|
||||
endif
|
||||
ifeq ($(findstring -rtmp,$(CFG)),-rtmp)
|
||||
WITH_RTMP = 1
|
||||
WITH_SSL = 1
|
||||
WITH_ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -ssh2,$(CFG)),-ssh2)
|
||||
WITH_SSH2 = 1
|
||||
WITH_SSL = 1
|
||||
WITH_ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -axtls,$(CFG)),-axtls)
|
||||
WITH_AXTLS = 1
|
||||
WITH_SSL =
|
||||
else
|
||||
ifeq ($(findstring -ssl,$(CFG)),-ssl)
|
||||
WITH_SSL = 1
|
||||
endif
|
||||
endif
|
||||
ifeq ($(findstring -zlib,$(CFG)),-zlib)
|
||||
WITH_ZLIB = 1
|
||||
endif
|
||||
ifeq ($(findstring -idn,$(CFG)),-idn)
|
||||
WITH_IDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
|
||||
ENABLE_IPV6 = 1
|
||||
endif
|
||||
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS = $(CURL_LIB)/libcurl.$(LIBEXT)
|
||||
ifdef WITH_ARES
|
||||
LDLIBS += $(LIBCARES_PATH)/libcares.$(LIBEXT)
|
||||
endif
|
||||
else
|
||||
MODULES = libcurl.nlm
|
||||
IMPORTS = @$(CURL_LIB)/libcurl.imp
|
||||
endif
|
||||
ifdef WITH_SSH2
|
||||
# INCLUDES += -I$(LIBSSH2_PATH)/include
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(LIBSSH2_PATH)/nw/libssh2.$(LIBEXT)
|
||||
else
|
||||
MODULES += libssh2.nlm
|
||||
IMPORTS += @$(LIBSSH2_PATH)/nw/libssh2.imp
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_RTMP
|
||||
# INCLUDES += -I$(LIBRTMP_PATH)
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(LIBRTMP_PATH)/librtmp/librtmp.$(LIBEXT)
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_SSL
|
||||
INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L)
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT)
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
|
||||
IMPORTS += GetProcessSwitchCount RunningProcess
|
||||
else
|
||||
ifdef WITH_AXTLS
|
||||
INCLUDES += -I$(AXTLS_PATH)/inc
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(AXTLS_PATH)/lib/libaxtls.$(LIBEXT)
|
||||
else
|
||||
MODULES += libaxtls.nlm
|
||||
IMPORTS += $(AXTLS_PATH)/lib/libaxtls.imp
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_ZLIB
|
||||
# INCLUDES += -I$(ZLIB_PATH)
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(ZLIB_PATH)/nw/$(LIBARCH)/libz.$(LIBEXT)
|
||||
else
|
||||
MODULES += libz.nlm
|
||||
IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_IDN
|
||||
# INCLUDES += -I$(LIBIDN_PATH)/include
|
||||
LDLIBS += $(LIBIDN_PATH)/lib/libidn.$(LIBEXT)
|
||||
endif
|
||||
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
INCLUDES += -I$(NDK_LIBC)/include
|
||||
# INCLUDES += -I$(NDK_LIBC)/include/nks
|
||||
# INCLUDES += -I$(NDK_LIBC)/include/winsock
|
||||
CFLAGS += -D_POSIX_SOURCE
|
||||
else
|
||||
INCLUDES += -I$(NDK_CLIB)/include/nlm
|
||||
# INCLUDES += -I$(NDK_CLIB)/include
|
||||
endif
|
||||
ifndef DISABLE_LDAP
|
||||
# INCLUDES += -I$(NDK_LDAP)/$(LIBARCH_L)/inc
|
||||
endif
|
||||
CFLAGS += $(INCLUDES)
|
||||
|
||||
ifeq ($(MTSAFE),YES)
|
||||
XDCOPT = -n
|
||||
endif
|
||||
ifeq ($(MTSAFE),NO)
|
||||
XDCOPT = -u
|
||||
endif
|
||||
ifdef XDCOPT
|
||||
XDCDATA = $(OBJDIR)/$(TARGET).xdc
|
||||
endif
|
||||
|
||||
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||
DL = '
|
||||
DS = /
|
||||
PCT = %
|
||||
#-include $(NDKBASE)/nlmconv/ncpfs.inc
|
||||
else
|
||||
DS = \\
|
||||
PCT = %%
|
||||
endif
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include Makefile.inc
|
||||
|
||||
check_PROGRAMS := $(patsubst %,%.nlm,$(strip $(check_PROGRAMS)))
|
||||
|
||||
.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc
|
||||
|
||||
|
||||
all: prebuild $(check_PROGRAMS)
|
||||
|
||||
prebuild: $(OBJDIR) $(OBJDIR)/version.inc
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
@echo Compiling $<
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJDIR)/version.inc: $(CURL_INC)/curl/curlver.h $(OBJDIR)
|
||||
@echo Creating $@
|
||||
@$(AWK) -f ../../packages/NetWare/get_ver.awk $< > $@
|
||||
|
||||
install: $(INSTDIR) all
|
||||
@$(CP) $(check_PROGRAMS) $(INSTDIR)
|
||||
|
||||
clean:
|
||||
-$(RM) -r $(OBJDIR)
|
||||
|
||||
distclean vclean: clean
|
||||
-$(RM) $(check_PROGRAMS)
|
||||
|
||||
$(OBJDIR) $(INSTDIR):
|
||||
@$(MKDIR) $@
|
||||
|
||||
%.nlm: $(OBJDIR)/%.o $(OBJDIR)/%.def $(XDCDATA)
|
||||
@echo Linking $@
|
||||
@-$(RM) $@
|
||||
@$(LD) $(LDFLAGS) $(OBJDIR)/$(@:.nlm=.def)
|
||||
|
||||
$(OBJDIR)/%.xdc: Makefile.netware
|
||||
@echo Creating $@
|
||||
@$(MPKXDC) $(XDCOPT) $@
|
||||
|
||||
$(OBJDIR)/%.def: Makefile.netware
|
||||
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
|
||||
@echo $(DL)# Do not edit this file - it is created by Make!$(DL) >> $@
|
||||
@echo $(DL)# All your changes will be lost!!$(DL) >> $@
|
||||
@echo $(DL)#$(DL) >> $@
|
||||
@echo $(DL)copyright "$(COPYR)"$(DL) >> $@
|
||||
@echo $(DL)description "$(DESCR) $(notdir $(@:.def=)) Example"$(DL) >> $@
|
||||
@echo $(DL)version $(VERSION)$(DL) >> $@
|
||||
ifdef NLMTYPE
|
||||
@echo $(DL)type $(NLMTYPE)$(DL) >> $@
|
||||
endif
|
||||
ifdef STACK
|
||||
@echo $(DL)stack $(STACK)$(DL) >> $@
|
||||
endif
|
||||
ifdef SCREEN
|
||||
@echo $(DL)screenname "$(DESCR) $(notdir $(@:.def=)) $(SCREEN)"$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)screenname "DEFAULT"$(DL) >> $@
|
||||
endif
|
||||
ifneq ($(DB),NDEBUG)
|
||||
@echo $(DL)debug$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)threadname "_$(notdir $(@:.def=))"$(DL) >> $@
|
||||
ifdef XDCDATA
|
||||
@echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(LDRING),0)
|
||||
@echo $(DL)flag_on 16$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(LDRING),3)
|
||||
@echo $(DL)flag_on 512$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(LIBARCH),CLIB)
|
||||
@echo $(DL)start _Prelude$(DL) >> $@
|
||||
@echo $(DL)exit _Stop$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_CLIB)/imports/clib.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_CLIB)/imports/threads.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_CLIB)/imports/nlmlib.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_CLIB)/imports/socklib.imp$(DL) >> $@
|
||||
@echo $(DL)module clib$(DL) >> $@
|
||||
ifndef DISABLE_LDAP
|
||||
@echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@
|
||||
# @echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@
|
||||
@echo $(DL)module ldapsdk ldapssl$(DL) >> $@
|
||||
endif
|
||||
else
|
||||
ifeq ($(POSIXFL),1)
|
||||
@echo $(DL)flag_on 4194304$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)flag_on 64$(DL) >> $@
|
||||
@echo $(DL)pseudopreemption$(DL) >> $@
|
||||
ifeq ($(findstring posixpre,$(PRELUDE)),posixpre)
|
||||
@echo $(DL)start POSIX_Start$(DL) >> $@
|
||||
@echo $(DL)exit POSIX_Stop$(DL) >> $@
|
||||
@echo $(DL)check POSIX_CheckUnload$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)start _LibCPrelude$(DL) >> $@
|
||||
@echo $(DL)exit _LibCPostlude$(DL) >> $@
|
||||
@echo $(DL)check _LibCCheckUnload$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)import @$(NDK_LIBC)/imports/libc.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_LIBC)/imports/netware.imp$(DL) >> $@
|
||||
@echo $(DL)module libc$(DL) >> $@
|
||||
ifndef DISABLE_LDAP
|
||||
@echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@
|
||||
# @echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@
|
||||
@echo $(DL)module lldapsdk lldapssl$(DL) >> $@
|
||||
endif
|
||||
endif
|
||||
ifdef MODULES
|
||||
@echo $(DL)module $(MODULES)$(DL) >> $@
|
||||
endif
|
||||
ifdef EXPORTS
|
||||
@echo $(DL)export $(EXPORTS)$(DL) >> $@
|
||||
endif
|
||||
ifdef IMPORTS
|
||||
@echo $(DL)import $(IMPORTS)$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(findstring nlmconv,$(LD)),nlmconv)
|
||||
@echo $(DL)input $(PRELUDE)$(DL) >> $@
|
||||
@echo $(DL)input $(@:.def=.o)$(DL) >> $@
|
||||
ifdef LDLIBS
|
||||
@echo $(DL)input $(LDLIBS)$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
|
||||
endif
|
82
curl/docs/examples/README
Normal file
82
curl/docs/examples/README
Normal file
@ -0,0 +1,82 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
This directory is for libcurl programming examples. They are meant to show
|
||||
some simple steps on how you can build your own application to take full
|
||||
advantage of libcurl.
|
||||
|
||||
If you end up with other small but still useful example sources, please mail
|
||||
them for submission in future packages and on the web site.
|
||||
|
||||
BUILDING
|
||||
|
||||
The Makefile.example is an example makefile that could be used to build these
|
||||
examples. Just edit the file according to your system and requirements first.
|
||||
|
||||
Most examples should build fine using a command line like this:
|
||||
|
||||
$ `curl-config --cc --cflags --libs` -o example example.c
|
||||
|
||||
Some compilers don't like having the arguments in this order but instead
|
||||
want you do reorganize them like:
|
||||
|
||||
$ `curl-config --cc` -o example example.c `curl-config --cflags --libs`
|
||||
|
||||
*PLEASE* do not use the curl.haxx.se site as a test target for your libcurl
|
||||
applications/experiments. Even if some of the examples use that site as a URL
|
||||
at some places, it doesn't mean that the URLs work or that we expect you to
|
||||
actually torture our web site with your tests! Thanks.
|
||||
|
||||
EXAMPLES
|
||||
|
||||
anyauthput.c - HTTP PUT using "any" authentication method
|
||||
cacertinmem.c - Use a built-in PEM certificate to retrieve a https page
|
||||
cookie_interface.c - shows usage of simple cookie interface
|
||||
curlgtk.c - download using a GTK progress bar
|
||||
curlx.c - getting file info from the remote cert data
|
||||
debug.c - showing how to use the debug callback
|
||||
fileupload.c - uploading to a file:// URL
|
||||
fopen.c - fopen() layer that supports opening URLs and files
|
||||
ftpget.c - simple getting a file from FTP
|
||||
ftpgetresp.c - get the response strings from the FTP server
|
||||
ftpupload.c - upload a file to an FTP server
|
||||
ftpuploadresume.c - resume an upload to an FTP server
|
||||
getinfo.c - get the Content-Type from the recent transfer
|
||||
getinmemory.c - download a file to memory only
|
||||
ghiper.c - curl_multi_socket() using code with glib-2
|
||||
hiperfifo.c - downloads all URLs written to the fifo, using
|
||||
curl_multi_socket() and libevent
|
||||
htmltidy.c - download a document and use libtidy to parse the HTML
|
||||
htmltitle.cc - download a HTML file and extract the <title> tag from a HTML
|
||||
page using libxml
|
||||
http-post.c - HTTP POST
|
||||
httpput.c - HTTP PUT a local file
|
||||
https.c - simple HTTPS transfer
|
||||
imap.c - simple IMAP transfer
|
||||
multi-app.c - a multi-interface app
|
||||
multi-debugcallback.c - a multi-interface app using the debug callback
|
||||
multi-double.c - a multi-interface app doing two simultaneous transfers
|
||||
multi-post.c - a multi-interface app doing a multipart formpost
|
||||
multi-single.c - a multi-interface app getting a single file
|
||||
multi-uv.c - a multi-interface app using libuv
|
||||
multithread.c - an example using multi-treading transferring multiple files
|
||||
opensslthreadlock.c - show how to do locking when using OpenSSL multi-threaded
|
||||
persistant.c - request two URLs with a persistent connection
|
||||
pop3s.c - POP3S transfer
|
||||
pop3slist.c - POP3S LIST
|
||||
post-callback.c - send a HTTP POST using a callback
|
||||
postit2.c - send a HTTP multipart formpost
|
||||
sampleconv.c - showing how a program on a non-ASCII platform would invoke
|
||||
callbacks to do its own codeset conversions instead of using
|
||||
the built-in iconv functions in libcurl
|
||||
sepheaders.c - download headers to a separate file
|
||||
simple.c - the most simple download a URL source
|
||||
simplepost.c - HTTP POST
|
||||
simplessl.c - HTTPS example with certificates many options set
|
||||
synctime.c - Sync local time by extracting date from remote HTTP servers
|
||||
url2file.c - download a document and store it in a file
|
||||
xmlstream.c - Stream-parse a document using the streaming Expat parser
|
||||
10-at-a-time.c - Download many files simultaneously, 10 at a time.
|
185
curl/docs/examples/anyauthput.c
Normal file
185
curl/docs/examples/anyauthput.c
Normal file
@ -0,0 +1,185 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef WIN32
|
||||
# include <io.h>
|
||||
#else
|
||||
# ifdef __VMS
|
||||
typedef int intptr_t;
|
||||
# endif
|
||||
# if !defined(_AIX) && !defined(__sgi) && !defined(__osf__)
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# ifdef _WIN64
|
||||
typedef __int64 intptr_t;
|
||||
# else
|
||||
typedef int intptr_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#if LIBCURL_VERSION_NUM < 0x070c03
|
||||
#error "upgrade your libcurl to no less than 7.12.3"
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#if defined(_AIX) || defined(__sgi) || defined(__osf__)
|
||||
#ifndef intptr_t
|
||||
#define intptr_t long
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This example shows a HTTP PUT operation with authentiction using "any"
|
||||
* type. It PUTs a file given as a command line argument to the URL also given
|
||||
* on the command line.
|
||||
*
|
||||
* Since libcurl 7.12.3, using "any" auth and POST/PUT requires a set ioctl
|
||||
* function.
|
||||
*
|
||||
* This example also uses its own read callback.
|
||||
*/
|
||||
|
||||
/* ioctl callback function */
|
||||
static curlioerr my_ioctl(CURL *handle, curliocmd cmd, void *userp)
|
||||
{
|
||||
intptr_t fd = (intptr_t)userp;
|
||||
|
||||
(void)handle; /* not used in here */
|
||||
|
||||
switch(cmd) {
|
||||
case CURLIOCMD_RESTARTREAD:
|
||||
/* mr libcurl kindly asks as to rewind the read data stream to start */
|
||||
if(-1 == lseek(fd, 0, SEEK_SET))
|
||||
/* couldn't rewind */
|
||||
return CURLIOE_FAILRESTART;
|
||||
|
||||
break;
|
||||
|
||||
default: /* ignore unknown commands */
|
||||
return CURLIOE_UNKNOWNCMD;
|
||||
}
|
||||
return CURLIOE_OK; /* success! */
|
||||
}
|
||||
|
||||
/* read callback function, fread() look alike */
|
||||
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
size_t retcode;
|
||||
curl_off_t nread;
|
||||
|
||||
intptr_t fd = (intptr_t)stream;
|
||||
|
||||
retcode = read(fd, ptr, size * nmemb);
|
||||
|
||||
nread = (curl_off_t)retcode;
|
||||
|
||||
fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T
|
||||
" bytes from file\n", nread);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
intptr_t hd ;
|
||||
struct stat file_info;
|
||||
|
||||
char *file;
|
||||
char *url;
|
||||
|
||||
if(argc < 3)
|
||||
return 1;
|
||||
|
||||
file= argv[1];
|
||||
url = argv[2];
|
||||
|
||||
/* get the file size of the local file */
|
||||
hd = open(file, O_RDONLY) ;
|
||||
fstat(hd, &file_info);
|
||||
|
||||
/* In windows, this will init the winsock stuff */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* which file to upload */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, (void*)hd);
|
||||
|
||||
/* set the ioctl function */
|
||||
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
|
||||
|
||||
/* pass the file descriptor to the ioctl callback as well */
|
||||
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, (void*)hd);
|
||||
|
||||
/* enable "uploading" (which means PUT when doing HTTP) */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L) ;
|
||||
|
||||
/* specify target URL, and note that this URL should also include a file
|
||||
name, not only a directory (as you can do with GTP uploads) */
|
||||
curl_easy_setopt(curl,CURLOPT_URL, url);
|
||||
|
||||
/* and give the size of the upload, this supports large file sizes
|
||||
on systems that have general support for it */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)file_info.st_size);
|
||||
|
||||
/* tell libcurl we can use "any" auth, which lets the lib pick one, but it
|
||||
also costs one extra round-trip and possibly sending of all the PUT
|
||||
data twice!!! */
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
|
||||
|
||||
/* set user name and password for the authentication */
|
||||
curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
|
||||
|
||||
/* Now run off and do what you've been told! */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
close(hd); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
467
curl/docs/examples/asiohiper.cpp
Normal file
467
curl/docs/examples/asiohiper.cpp
Normal file
@ -0,0 +1,467 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* file: asiohiper.cpp
|
||||
* Example program to demonstrate the use of multi socket interface
|
||||
* with boost::asio
|
||||
*
|
||||
* This program is in c++ and uses boost::asio instead of libevent/libev.
|
||||
* Requires boost::asio, boost::bind and boost::system
|
||||
*
|
||||
* This is an adaptation of libcurl's "hiperfifo.c" and "evhiperfifo.c"
|
||||
* sample programs. This example implements a subset of the functionality from
|
||||
* hiperfifo.c, for full functionality refer hiperfifo.c or evhiperfifo.c
|
||||
*
|
||||
* Written by Lijo Antony based on hiperfifo.c by Jeff Pohlmeyer
|
||||
*
|
||||
* When running, the program creates an easy handle for a URL and
|
||||
* uses the curl_multi API to fetch it.
|
||||
*
|
||||
* Note:
|
||||
* For the sake of simplicity, URL is hard coded to "www.google.com"
|
||||
*
|
||||
* This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
* callback.
|
||||
*/
|
||||
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
|
||||
|
||||
/* boost::asio related objects
|
||||
* using global variables for simplicity
|
||||
*/
|
||||
boost::asio::io_service io_service;
|
||||
boost::asio::deadline_timer timer(io_service);
|
||||
std::map<curl_socket_t, boost::asio::ip::tcp::socket *> socket_map;
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo
|
||||
{
|
||||
CURLM *multi;
|
||||
int still_running;
|
||||
} GlobalInfo;
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo
|
||||
{
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
static void timer_cb(const boost::system::error_code & error, GlobalInfo *g);
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
|
||||
{
|
||||
fprintf(MSG_OUT, "\nmulti_timer_cb: timeout_ms %ld", timeout_ms);
|
||||
|
||||
/* cancel running timer */
|
||||
timer.cancel();
|
||||
|
||||
if(timeout_ms > 0)
|
||||
{
|
||||
/* update timer */
|
||||
timer.expires_from_now(boost::posix_time::millisec(timeout_ms));
|
||||
timer.async_wait(boost::bind(&timer_cb, _1, g));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* call timeout function immediately */
|
||||
boost::system::error_code error; /*success*/
|
||||
timer_cb(error, g);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(const char *where, CURLMcode code)
|
||||
{
|
||||
if(CURLM_OK != code)
|
||||
{
|
||||
const char *s;
|
||||
switch(code)
|
||||
{
|
||||
case CURLM_CALL_MULTI_PERFORM:
|
||||
s = "CURLM_CALL_MULTI_PERFORM";
|
||||
break;
|
||||
case CURLM_BAD_HANDLE:
|
||||
s = "CURLM_BAD_HANDLE";
|
||||
break;
|
||||
case CURLM_BAD_EASY_HANDLE:
|
||||
s = "CURLM_BAD_EASY_HANDLE";
|
||||
break;
|
||||
case CURLM_OUT_OF_MEMORY:
|
||||
s = "CURLM_OUT_OF_MEMORY";
|
||||
break;
|
||||
case CURLM_INTERNAL_ERROR:
|
||||
s = "CURLM_INTERNAL_ERROR";
|
||||
break;
|
||||
case CURLM_UNKNOWN_OPTION:
|
||||
s = "CURLM_UNKNOWN_OPTION";
|
||||
break;
|
||||
case CURLM_LAST:
|
||||
s = "CURLM_LAST";
|
||||
break;
|
||||
default:
|
||||
s = "CURLM_unknown";
|
||||
break;
|
||||
case CURLM_BAD_SOCKET:
|
||||
s = "CURLM_BAD_SOCKET";
|
||||
fprintf(MSG_OUT, "\nERROR: %s returns %s", where, s);
|
||||
/* ignore this error */
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(MSG_OUT, "\nERROR: %s returns %s", where, s);
|
||||
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn;
|
||||
CURL *easy;
|
||||
CURLcode res;
|
||||
|
||||
fprintf(MSG_OUT, "\nREMAINING: %d", g->still_running);
|
||||
|
||||
while((msg = curl_multi_info_read(g->multi, &msgs_left)))
|
||||
{
|
||||
if(msg->msg == CURLMSG_DONE)
|
||||
{
|
||||
easy = msg->easy_handle;
|
||||
res = msg->data.result;
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
fprintf(MSG_OUT, "\nDONE: %s => (%d) %s", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by asio when there is an action on a socket */
|
||||
static void event_cb(GlobalInfo *g, boost::asio::ip::tcp::socket *tcp_socket,
|
||||
int action)
|
||||
{
|
||||
fprintf(MSG_OUT, "\nevent_cb: action=%d", action);
|
||||
|
||||
CURLMcode rc;
|
||||
rc = curl_multi_socket_action(g->multi, tcp_socket->native_handle(), action,
|
||||
&g->still_running);
|
||||
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
|
||||
if(g->still_running <= 0)
|
||||
{
|
||||
fprintf(MSG_OUT, "\nlast transfer done, kill timeout");
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by asio when our timeout expires */
|
||||
static void timer_cb(const boost::system::error_code & error, GlobalInfo *g)
|
||||
{
|
||||
if(!error)
|
||||
{
|
||||
fprintf(MSG_OUT, "\ntimer_cb: ");
|
||||
|
||||
CURLMcode rc;
|
||||
rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, &g->still_running);
|
||||
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up any data */
|
||||
static void remsock(int *f, GlobalInfo *g)
|
||||
{
|
||||
fprintf(MSG_OUT, "\nremsock: ");
|
||||
|
||||
if(f)
|
||||
{
|
||||
free(f);
|
||||
}
|
||||
}
|
||||
|
||||
static void setsock(int *fdp, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
|
||||
{
|
||||
fprintf(MSG_OUT, "\nsetsock: socket=%d, act=%d, fdp=%p", s, act, fdp);
|
||||
|
||||
std::map<curl_socket_t, boost::asio::ip::tcp::socket *>::iterator it = socket_map.find(s);
|
||||
|
||||
if(it == socket_map.end())
|
||||
{
|
||||
fprintf(MSG_OUT, "\nsocket %d is a c-ares socket, ignoring", s);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::socket * tcp_socket = it->second;
|
||||
|
||||
*fdp = act;
|
||||
|
||||
if(act == CURL_POLL_IN)
|
||||
{
|
||||
fprintf(MSG_OUT, "\nwatching for socket to become readable");
|
||||
|
||||
tcp_socket->async_read_some(boost::asio::null_buffers(),
|
||||
boost::bind(&event_cb, g, tcp_socket, act));
|
||||
}
|
||||
else if (act == CURL_POLL_OUT)
|
||||
{
|
||||
fprintf(MSG_OUT, "\nwatching for socket to become writable");
|
||||
|
||||
tcp_socket->async_write_some(boost::asio::null_buffers(),
|
||||
boost::bind(&event_cb, g, tcp_socket, act));
|
||||
}
|
||||
else if(act == CURL_POLL_INOUT)
|
||||
{
|
||||
fprintf(MSG_OUT, "\nwatching for socket to become readable & writable");
|
||||
|
||||
tcp_socket->async_read_some(boost::asio::null_buffers(),
|
||||
boost::bind(&event_cb, g, tcp_socket, act));
|
||||
|
||||
tcp_socket->async_write_some(boost::asio::null_buffers(),
|
||||
boost::bind(&event_cb, g, tcp_socket, act));
|
||||
}
|
||||
}
|
||||
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
|
||||
{
|
||||
/* fdp is used to store current action */
|
||||
int *fdp = (int *) calloc(sizeof(int), 1);
|
||||
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
fprintf(MSG_OUT, "\nsock_cb: socket=%d, what=%d, sockp=%p", s, what, sockp);
|
||||
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
int *actionp = (int *) sockp;
|
||||
const char *whatstr[] = { "none", "IN", "OUT", "INOUT", "REMOVE"};
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"\nsocket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
|
||||
if(what == CURL_POLL_REMOVE)
|
||||
{
|
||||
fprintf(MSG_OUT, "\n");
|
||||
remsock(actionp, g);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!actionp)
|
||||
{
|
||||
fprintf(MSG_OUT, "\nAdding data: %s", whatstr[what]);
|
||||
addsock(s, e, what, g);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(MSG_OUT,
|
||||
"\nChanging action from %s to %s",
|
||||
whatstr[*actionp], whatstr[what]);
|
||||
setsock(actionp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
|
||||
size_t written = size * nmemb;
|
||||
char* pBuffer = (char *) malloc(written + 1);
|
||||
|
||||
strncpy(pBuffer, (const char *)ptr, written);
|
||||
pBuffer[written] = '\0';
|
||||
|
||||
fprintf(MSG_OUT, "%s", pBuffer);
|
||||
|
||||
free(pBuffer);
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
static int prog_cb(void *p, double dltotal, double dlnow, double ult,
|
||||
double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
|
||||
(void)ult;
|
||||
(void)uln;
|
||||
|
||||
fprintf(MSG_OUT, "\nProgress: %s (%g/%g)", conn->url, dlnow, dltotal);
|
||||
fprintf(MSG_OUT, "\nProgress: %s (%g)", conn->url, ult);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* CURLOPT_OPENSOCKETFUNCTION */
|
||||
static curl_socket_t opensocket(void *clientp, curlsocktype purpose,
|
||||
struct curl_sockaddr *address)
|
||||
{
|
||||
fprintf(MSG_OUT, "\nopensocket :");
|
||||
|
||||
curl_socket_t sockfd = CURL_SOCKET_BAD;
|
||||
|
||||
/* restrict to IPv4 */
|
||||
if(purpose == CURLSOCKTYPE_IPCXN && address->family == AF_INET)
|
||||
{
|
||||
/* create a tcp socket object */
|
||||
boost::asio::ip::tcp::socket *tcp_socket = new boost::asio::ip::tcp::socket(io_service);
|
||||
|
||||
/* open it and get the native handle*/
|
||||
boost::system::error_code ec;
|
||||
tcp_socket->open(boost::asio::ip::tcp::v4(), ec);
|
||||
|
||||
if(ec)
|
||||
{
|
||||
/* An error occurred */
|
||||
std::cout << std::endl << "Couldn't open socket [" << ec << "][" << ec.message() << "]";
|
||||
fprintf(MSG_OUT, "\nERROR: Returning CURL_SOCKET_BAD to signal error");
|
||||
}
|
||||
else
|
||||
{
|
||||
sockfd = tcp_socket->native_handle();
|
||||
fprintf(MSG_OUT, "\nOpened socket %d", sockfd);
|
||||
|
||||
/* save it for monitoring */
|
||||
socket_map.insert(std::pair<curl_socket_t, boost::asio::ip::tcp::socket *>(sockfd, tcp_socket));
|
||||
}
|
||||
}
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
/* CURLOPT_CLOSESOCKETFUNCTION */
|
||||
static int closesocket(void *clientp, curl_socket_t item)
|
||||
{
|
||||
fprintf(MSG_OUT, "\nclosesocket : %d", item);
|
||||
|
||||
std::map<curl_socket_t, boost::asio::ip::tcp::socket *>::iterator it = socket_map.find(item);
|
||||
|
||||
if(it != socket_map.end())
|
||||
{
|
||||
delete it->second;
|
||||
socket_map.erase(it);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
static void new_conn(char *url, GlobalInfo *g)
|
||||
{
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = (ConnInfo *) calloc(1, sizeof(ConnInfo));
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
if(!conn->easy)
|
||||
{
|
||||
fprintf(MSG_OUT, "\ncurl_easy_init() failed, exiting!");
|
||||
|
||||
exit(2);
|
||||
}
|
||||
|
||||
conn->global = g;
|
||||
conn->url = strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 3L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 10L);
|
||||
|
||||
/* call this function to get a socket */
|
||||
curl_easy_setopt(conn->easy, CURLOPT_OPENSOCKETFUNCTION, opensocket);
|
||||
|
||||
/* call this function to close a socket */
|
||||
curl_easy_setopt(conn->easy, CURLOPT_CLOSESOCKETFUNCTION, closesocket);
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"\nAdding easy %p to multi %p (%s)", conn->easy, g->multi, url);
|
||||
rc = curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
|
||||
/* note that the add_handle() will set a time-out to trigger very soon so
|
||||
that the necessary socket_action() call will be called by this app */
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo g;
|
||||
CURLMcode rc;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
memset(&g, 0, sizeof(GlobalInfo));
|
||||
g.multi = curl_multi_init();
|
||||
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
|
||||
|
||||
new_conn((char *)"www.google.com", &g); /* add a URL */
|
||||
|
||||
/* enter io_service run loop */
|
||||
io_service.run();
|
||||
|
||||
curl_multi_cleanup(g.multi);
|
||||
|
||||
fprintf(MSG_OUT, "\ndone.\n");
|
||||
|
||||
return 0;
|
||||
}
|
155
curl/docs/examples/cacertinmem.c
Normal file
155
curl/docs/examples/cacertinmem.c
Normal file
@ -0,0 +1,155 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* Example using a "in core" PEM certificate to retrieve a https page.
|
||||
* Written by Theo Borm
|
||||
*/
|
||||
|
||||
/* on a netBSD system with OPENSSL& LIBCURL installed from
|
||||
* pkgsrc (using default paths) this program can be compiled using:
|
||||
* gcc -I/usr/pkg/include -L/usr/pkg/lib -lcurl -Wl,-R/usr/pkg/lib -lssl
|
||||
* -lcrypto -lz -o curlcacerttest curlcacerttest.c
|
||||
* on other operating systems you may want to change paths to headers
|
||||
* and libraries
|
||||
*/
|
||||
#include <openssl/ssl.h>
|
||||
#include <curl/curl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
size_t writefunction( void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
fwrite(ptr,size,nmemb,stream);
|
||||
return(nmemb*size);
|
||||
}
|
||||
|
||||
static CURLcode sslctx_function(CURL * curl, void * sslctx, void * parm)
|
||||
{
|
||||
X509_STORE * store;
|
||||
X509 * cert=NULL;
|
||||
BIO * bio;
|
||||
char * mypem = /* www.cacert.org */
|
||||
"-----BEGIN CERTIFICATE-----\n"\
|
||||
"MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\
|
||||
"IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\
|
||||
"IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n"\
|
||||
"Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n"\
|
||||
"BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi\n"\
|
||||
"MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ\n"\
|
||||
"ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC\n"\
|
||||
"CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ\n"\
|
||||
"8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6\n"\
|
||||
"zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y\n"\
|
||||
"fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7\n"\
|
||||
"w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc\n"\
|
||||
"G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k\n"\
|
||||
"epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q\n"\
|
||||
"laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ\n"\
|
||||
"QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU\n"\
|
||||
"fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826\n"\
|
||||
"YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w\n"\
|
||||
"ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY\n"\
|
||||
"gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe\n"\
|
||||
"MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0\n"\
|
||||
"IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy\n"\
|
||||
"dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw\n"\
|
||||
"czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0\n"\
|
||||
"dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl\n"\
|
||||
"aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC\n"\
|
||||
"AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg\n"\
|
||||
"b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB\n"\
|
||||
"ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc\n"\
|
||||
"nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg\n"\
|
||||
"18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c\n"\
|
||||
"gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl\n"\
|
||||
"Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY\n"\
|
||||
"sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T\n"\
|
||||
"SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF\n"\
|
||||
"CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum\n"\
|
||||
"GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n"\
|
||||
"zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n"\
|
||||
"omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\
|
||||
"-----END CERTIFICATE-----\n";
|
||||
/* get a BIO */
|
||||
bio=BIO_new_mem_buf(mypem, -1);
|
||||
/* use it to read the PEM formatted certificate from memory into an X509
|
||||
* structure that SSL can use
|
||||
*/
|
||||
PEM_read_bio_X509(bio, &cert, 0, NULL);
|
||||
if (cert == NULL)
|
||||
printf("PEM_read_bio_X509 failed...\n");
|
||||
|
||||
/* get a pointer to the X509 certificate store (which may be empty!) */
|
||||
store=SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
|
||||
|
||||
/* add our certificate to this store */
|
||||
if (X509_STORE_add_cert(store, cert)==0)
|
||||
printf("error adding certificate\n");
|
||||
|
||||
/* decrease reference counts */
|
||||
X509_free(cert);
|
||||
BIO_free(bio);
|
||||
|
||||
/* all set to go */
|
||||
return CURLE_OK ;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL * ch;
|
||||
CURLcode rv;
|
||||
|
||||
rv=curl_global_init(CURL_GLOBAL_ALL);
|
||||
ch=curl_easy_init();
|
||||
rv=curl_easy_setopt(ch,CURLOPT_VERBOSE, 0L);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_HEADER, 0L);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_NOPROGRESS, 1L);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_NOSIGNAL, 1L);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_WRITEFUNCTION, *writefunction);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_WRITEDATA, stdout);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_HEADERFUNCTION, *writefunction);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_HEADERDATA, stderr);
|
||||
rv=curl_easy_setopt(ch,CURLOPT_SSLCERTTYPE,"PEM");
|
||||
rv=curl_easy_setopt(ch,CURLOPT_SSL_VERIFYPEER,1L);
|
||||
rv=curl_easy_setopt(ch, CURLOPT_URL, "https://www.example.com/");
|
||||
|
||||
/* first try: retrieve page without cacerts' certificate -> will fail
|
||||
*/
|
||||
rv=curl_easy_perform(ch);
|
||||
if (rv==CURLE_OK)
|
||||
printf("*** transfer succeeded ***\n");
|
||||
else
|
||||
printf("*** transfer failed ***\n");
|
||||
|
||||
/* second try: retrieve page using cacerts' certificate -> will succeed
|
||||
* load the certificate by installing a function doing the nescessary
|
||||
* "modifications" to the SSL CONTEXT just before link init
|
||||
*/
|
||||
rv=curl_easy_setopt(ch,CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);
|
||||
rv=curl_easy_perform(ch);
|
||||
if (rv==CURLE_OK)
|
||||
printf("*** transfer succeeded ***\n");
|
||||
else
|
||||
printf("*** transfer failed ***\n");
|
||||
|
||||
curl_easy_cleanup(ch);
|
||||
curl_global_cleanup();
|
||||
return rv;
|
||||
}
|
86
curl/docs/examples/certinfo.c
Normal file
86
curl/docs/examples/certinfo.c
Normal file
@ -0,0 +1,86 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
static size_t wrfu(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
(void)stream;
|
||||
(void)ptr;
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/");
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, wrfu);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(!res) {
|
||||
union {
|
||||
struct curl_slist *to_info;
|
||||
struct curl_certinfo *to_certinfo;
|
||||
} ptr;
|
||||
|
||||
ptr.to_info = NULL;
|
||||
|
||||
res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &ptr.to_info);
|
||||
|
||||
if(!res && ptr.to_info) {
|
||||
int i;
|
||||
|
||||
printf("%d certs!\n", ptr.to_certinfo->num_of_certs);
|
||||
|
||||
for(i = 0; i < ptr.to_certinfo->num_of_certs; i++) {
|
||||
struct curl_slist *slist;
|
||||
|
||||
for(slist = ptr.to_certinfo->certinfo[i]; slist; slist = slist->next)
|
||||
printf("%s\n", slist->data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
190
curl/docs/examples/chkspeed.c
Normal file
190
curl/docs/examples/chkspeed.c
Normal file
@ -0,0 +1,190 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* Example source code to show how the callback function can be used to
|
||||
* download data into a chunk of memory instead of storing it in a file.
|
||||
* After successful download we use curl_easy_getinfo() calls to get the
|
||||
* amount of downloaded bytes, the time used for the whole download, and
|
||||
* the average download speed.
|
||||
* On Linux you can create the download test files with:
|
||||
* dd if=/dev/urandom of=file_1M.bin bs=1M count=1
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define URL_BASE "http://speedtest.your.domain/"
|
||||
#define URL_1M URL_BASE "file_1M.bin"
|
||||
#define URL_2M URL_BASE "file_2M.bin"
|
||||
#define URL_5M URL_BASE "file_5M.bin"
|
||||
#define URL_10M URL_BASE "file_10M.bin"
|
||||
#define URL_20M URL_BASE "file_20M.bin"
|
||||
#define URL_50M URL_BASE "file_50M.bin"
|
||||
#define URL_100M URL_BASE "file_100M.bin"
|
||||
|
||||
#define CHKSPEED_VERSION "1.0"
|
||||
|
||||
static size_t WriteCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
/* we are not interested in the downloaded bytes itself,
|
||||
so we only return the size we would have saved ... */
|
||||
(void)ptr; /* unused */
|
||||
(void)data; /* unused */
|
||||
return (size_t)(size * nmemb);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CURL *curl_handle;
|
||||
CURLcode res;
|
||||
int prtall = 0, prtsep = 0, prttime = 0;
|
||||
const char *url = URL_1M;
|
||||
char *appname = argv[0];
|
||||
|
||||
if (argc > 1) {
|
||||
/* parse input parameters */
|
||||
for (argc--, argv++; *argv; argc--, argv++) {
|
||||
if (strncasecmp(*argv, "-", 1) == 0) {
|
||||
if (strncasecmp(*argv, "-H", 2) == 0) {
|
||||
fprintf(stderr,
|
||||
"\rUsage: %s [-m=1|2|5|10|20|50|100] [-t] [-x] [url]\n",
|
||||
appname);
|
||||
exit(1);
|
||||
} else if (strncasecmp(*argv, "-V", 2) == 0) {
|
||||
fprintf(stderr, "\r%s %s - %s\n",
|
||||
appname, CHKSPEED_VERSION, curl_version());
|
||||
exit(1);
|
||||
} else if (strncasecmp(*argv, "-A", 2) == 0) {
|
||||
prtall = 1;
|
||||
} else if (strncasecmp(*argv, "-X", 2) == 0) {
|
||||
prtsep = 1;
|
||||
} else if (strncasecmp(*argv, "-T", 2) == 0) {
|
||||
prttime = 1;
|
||||
} else if (strncasecmp(*argv, "-M=", 3) == 0) {
|
||||
long m = strtol((*argv)+3, NULL, 10);
|
||||
switch(m) {
|
||||
case 1: url = URL_1M;
|
||||
break;
|
||||
case 2: url = URL_2M;
|
||||
break;
|
||||
case 5: url = URL_5M;
|
||||
break;
|
||||
case 10: url = URL_10M;
|
||||
break;
|
||||
case 20: url = URL_20M;
|
||||
break;
|
||||
case 50: url = URL_50M;
|
||||
break;
|
||||
case 100: url = URL_100M;
|
||||
break;
|
||||
default: fprintf(stderr, "\r%s: invalid parameter %s\n",
|
||||
appname, *argv + 3);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "\r%s: invalid or unknown option %s\n",
|
||||
appname, *argv);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
url = *argv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* print separator line */
|
||||
if (prtsep) {
|
||||
printf("-------------------------------------------------\n");
|
||||
}
|
||||
/* print localtime */
|
||||
if (prttime) {
|
||||
time_t t = time(NULL);
|
||||
printf("Localtime: %s", ctime(&t));
|
||||
}
|
||||
|
||||
/* init libcurl */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* init the curl session */
|
||||
curl_handle = curl_easy_init();
|
||||
|
||||
/* specify URL to get */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_URL, url);
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteCallback);
|
||||
|
||||
/* some servers don't like requests that are made without a user-agent
|
||||
field, so we provide one */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT,
|
||||
"libcurl-speedchecker/" CHKSPEED_VERSION);
|
||||
|
||||
/* get it! */
|
||||
res = curl_easy_perform(curl_handle);
|
||||
|
||||
if(CURLE_OK == res) {
|
||||
double val;
|
||||
|
||||
/* check for bytes downloaded */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_SIZE_DOWNLOAD, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Data downloaded: %0.0f bytes.\n", val);
|
||||
|
||||
/* check for total download time */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_TOTAL_TIME, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Total download time: %0.3f sec.\n", val);
|
||||
|
||||
/* check for average download speed */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_SPEED_DOWNLOAD, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Average download speed: %0.3f kbyte/sec.\n", val / 1024);
|
||||
|
||||
if (prtall) {
|
||||
/* check for name resolution time */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_NAMELOOKUP_TIME, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Name lookup time: %0.3f sec.\n", val);
|
||||
|
||||
/* check for connect time */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_CONNECT_TIME, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Connect time: %0.3f sec.\n", val);
|
||||
}
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "Error while fetching '%s' : %s\n",
|
||||
url, curl_easy_strerror(res));
|
||||
}
|
||||
|
||||
/* cleanup curl stuff */
|
||||
curl_easy_cleanup(curl_handle);
|
||||
|
||||
/* we're done with libcurl, so clean it up */
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
129
curl/docs/examples/cookie_interface.c
Normal file
129
curl/docs/examples/cookie_interface.c
Normal file
@ -0,0 +1,129 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* This example shows usage of simple cookie interface. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
static void
|
||||
print_cookies(CURL *curl)
|
||||
{
|
||||
CURLcode res;
|
||||
struct curl_slist *cookies;
|
||||
struct curl_slist *nc;
|
||||
int i;
|
||||
|
||||
printf("Cookies, curl knows:\n");
|
||||
res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl curl_easy_getinfo failed: %s\n", curl_easy_strerror(res));
|
||||
exit(1);
|
||||
}
|
||||
nc = cookies, i = 1;
|
||||
while (nc) {
|
||||
printf("[%d]: %s\n", i, nc->data);
|
||||
nc = nc->next;
|
||||
i++;
|
||||
}
|
||||
if (i == 1) {
|
||||
printf("(none)\n");
|
||||
}
|
||||
curl_slist_free_all(cookies);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl = curl_easy_init();
|
||||
if (curl) {
|
||||
char nline[256];
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/");
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); /* just to start the cookie engine */
|
||||
res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_cookies(curl);
|
||||
|
||||
printf("Erasing curl's knowledge of cookies!\n");
|
||||
curl_easy_setopt(curl, CURLOPT_COOKIELIST, "ALL");
|
||||
|
||||
print_cookies(curl);
|
||||
|
||||
printf("-----------------------------------------------\n"
|
||||
"Setting a cookie \"PREF\" via cookie interface:\n");
|
||||
#ifdef WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
/* Netscape format cookie */
|
||||
snprintf(nline, sizeof(nline), "%s\t%s\t%s\t%s\t%lu\t%s\t%s",
|
||||
".google.com", "TRUE", "/", "FALSE", (unsigned long)time(NULL) + 31337UL, "PREF", "hello google, i like you very much!");
|
||||
res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl curl_easy_setopt failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* HTTP-header style cookie. If you use the Set-Cookie format and don't
|
||||
specify a domain then the cookie is sent for any domain and will not be
|
||||
modified, likely not what you intended. Starting in 7.43.0 any-domain
|
||||
cookies will not be exported either. For more information refer to the
|
||||
CURLOPT_COOKIELIST documentation.
|
||||
*/
|
||||
snprintf(nline, sizeof(nline),
|
||||
"Set-Cookie: OLD_PREF=3d141414bf4209321; "
|
||||
"expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com");
|
||||
res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl curl_easy_setopt failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_cookies(curl);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Curl init failed!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
106
curl/docs/examples/curlgtk.c
Normal file
106
curl/docs/examples/curlgtk.c
Normal file
@ -0,0 +1,106 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
/* Copyright (c) 2000 David Odin (aka DindinX) for MandrakeSoft */
|
||||
/* an attempt to use the curl library in concert with a gtk-threaded application */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
GtkWidget *Bar;
|
||||
|
||||
size_t my_write_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
return fwrite(ptr, size, nmemb, stream);
|
||||
}
|
||||
|
||||
size_t my_read_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
return fread(ptr, size, nmemb, stream);
|
||||
}
|
||||
|
||||
int my_progress_func(GtkWidget *bar,
|
||||
double t, /* dltotal */
|
||||
double d, /* dlnow */
|
||||
double ultotal,
|
||||
double ulnow)
|
||||
{
|
||||
/* printf("%d / %d (%g %%)\n", d, t, d*100.0/t);*/
|
||||
gdk_threads_enter();
|
||||
gtk_progress_set_value(GTK_PROGRESS(bar), d*100.0/t);
|
||||
gdk_threads_leave();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *my_thread(void *ptr)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *outfile;
|
||||
gchar *url = ptr;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl)
|
||||
{
|
||||
outfile = fopen("test.curl", "w");
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_write_func);
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_read_func);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress_func);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, Bar);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
fclose(outfile);
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GtkWidget *Window, *Frame, *Frame2;
|
||||
GtkAdjustment *adj;
|
||||
|
||||
/* Must initialize libcurl before any threads are started */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* Init thread */
|
||||
g_thread_init(NULL);
|
||||
|
||||
gtk_init(&argc, &argv);
|
||||
Window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
Frame = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(Frame), GTK_SHADOW_OUT);
|
||||
gtk_container_add(GTK_CONTAINER(Window), Frame);
|
||||
Frame2 = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(Frame2), GTK_SHADOW_IN);
|
||||
gtk_container_add(GTK_CONTAINER(Frame), Frame2);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(Frame2), 5);
|
||||
adj = (GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
|
||||
Bar = gtk_progress_bar_new_with_adjustment(adj);
|
||||
gtk_container_add(GTK_CONTAINER(Frame2), Bar);
|
||||
gtk_widget_show_all(Window);
|
||||
|
||||
if (!g_thread_create(&my_thread, argv[1], FALSE, NULL) != 0)
|
||||
g_warning("can't create the thread");
|
||||
|
||||
|
||||
gdk_threads_enter();
|
||||
gtk_main();
|
||||
gdk_threads_leave();
|
||||
return 0;
|
||||
}
|
||||
|
513
curl/docs/examples/curlx.c
Normal file
513
curl/docs/examples/curlx.c
Normal file
@ -0,0 +1,513 @@
|
||||
/*
|
||||
curlx.c Authors: Peter Sylvester, Jean-Paul Merlin
|
||||
|
||||
This is a little program to demonstrate the usage of
|
||||
|
||||
- an ssl initialisation callback setting a user key and trustbases
|
||||
coming from a pkcs12 file
|
||||
- using an ssl application callback to find a URI in the
|
||||
certificate presented during ssl session establishment.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 The OpenEvidence Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, the following disclaimer,
|
||||
* and the original OpenSSL and SSLeay Licences below.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions, the following disclaimer
|
||||
* and the original OpenSSL and SSLeay Licences below in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgments:
|
||||
* "This product includes software developed by the Openevidence Project
|
||||
* for use in the OpenEvidence Toolkit. (http://www.openevidence.org/)"
|
||||
* This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com)."
|
||||
*
|
||||
* 4. The names "OpenEvidence Toolkit" and "OpenEvidence Project" must not be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openevidence-core@openevidence.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenEvidence"
|
||||
* nor may "OpenEvidence" appear in their names without prior written
|
||||
* permission of the OpenEvidence Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgments:
|
||||
* "This product includes software developed by the OpenEvidence Project
|
||||
* for use in the OpenEvidence Toolkit (http://www.openevidence.org/)
|
||||
* This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com)."
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenEvidence PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenEvidence PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/x509_vfy.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
static const char *curlx_usage[]={
|
||||
"usage: curlx args\n",
|
||||
" -p12 arg - tia file ",
|
||||
" -envpass arg - environement variable which content the tia private key password",
|
||||
" -out arg - output file (response)- default stdout",
|
||||
" -in arg - input file (request)- default stdin",
|
||||
" -connect arg - URL of the server for the connection ex: www.openevidence.org",
|
||||
" -mimetype arg - MIME type for data in ex : application/timestamp-query or application/dvcs -default application/timestamp-query",
|
||||
" -acceptmime arg - MIME type acceptable for the response ex : application/timestamp-response or application/dvcs -default none",
|
||||
" -accesstype arg - an Object identifier in an AIA/SIA method, e.g. AD_DVCS or ad_timestamping",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
./curlx -p12 psy.p12 -envpass XX -in request -verbose -accesstype AD_DVCS
|
||||
-mimetype application/dvcs -acceptmime application/dvcs -out response
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* We use this ZERO_NULL to avoid picky compiler warnings,
|
||||
* when assigning a NULL pointer to a function pointer var.
|
||||
*/
|
||||
|
||||
#define ZERO_NULL 0
|
||||
|
||||
/* This is a context that we pass to all callbacks */
|
||||
|
||||
typedef struct sslctxparm_st {
|
||||
unsigned char * p12file ;
|
||||
const char * pst ;
|
||||
PKCS12 * p12 ;
|
||||
EVP_PKEY * pkey ;
|
||||
X509 * usercert ;
|
||||
STACK_OF(X509) * ca ;
|
||||
CURL * curl;
|
||||
BIO * errorbio;
|
||||
int accesstype ;
|
||||
int verbose;
|
||||
|
||||
} sslctxparm;
|
||||
|
||||
/* some helper function. */
|
||||
|
||||
static char *i2s_ASN1_IA5STRING( ASN1_IA5STRING *ia5)
|
||||
{
|
||||
char *tmp;
|
||||
if(!ia5 || !ia5->length)
|
||||
return NULL;
|
||||
tmp = OPENSSL_malloc(ia5->length + 1);
|
||||
memcpy(tmp, ia5->data, ia5->length);
|
||||
tmp[ia5->length] = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* A conveniance routine to get an access URI. */
|
||||
|
||||
static unsigned char *my_get_ext(X509 * cert, const int type, int extensiontype) {
|
||||
|
||||
int i;
|
||||
STACK_OF(ACCESS_DESCRIPTION) * accessinfo ;
|
||||
accessinfo = X509_get_ext_d2i(cert, extensiontype, NULL, NULL) ;
|
||||
|
||||
if (!sk_ACCESS_DESCRIPTION_num(accessinfo))
|
||||
return NULL;
|
||||
for (i = 0; i < sk_ACCESS_DESCRIPTION_num(accessinfo); i++) {
|
||||
ACCESS_DESCRIPTION * ad = sk_ACCESS_DESCRIPTION_value(accessinfo, i);
|
||||
if (OBJ_obj2nid(ad->method) == type) {
|
||||
if (ad->location->type == GEN_URI) {
|
||||
return i2s_ASN1_IA5STRING(ad->location->d.ia5);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This is an application verification call back, it does not
|
||||
perform any addition verification but tries to find a URL
|
||||
in the presented certificat. If found, this will become
|
||||
the URL to be used in the POST.
|
||||
*/
|
||||
|
||||
static int ssl_app_verify_callback(X509_STORE_CTX *ctx, void *arg)
|
||||
{
|
||||
sslctxparm * p = (sslctxparm *) arg;
|
||||
int ok;
|
||||
|
||||
if (p->verbose > 2)
|
||||
BIO_printf(p->errorbio,"entering ssl_app_verify_callback\n");
|
||||
|
||||
if ((ok= X509_verify_cert(ctx)) && ctx->cert) {
|
||||
unsigned char * accessinfo ;
|
||||
if (p->verbose > 1)
|
||||
X509_print_ex(p->errorbio,ctx->cert,0,0);
|
||||
|
||||
if (accessinfo = my_get_ext(ctx->cert,p->accesstype ,NID_sinfo_access)) {
|
||||
if (p->verbose)
|
||||
BIO_printf(p->errorbio,"Setting URL from SIA to: %s\n", accessinfo);
|
||||
|
||||
curl_easy_setopt(p->curl, CURLOPT_URL,accessinfo);
|
||||
}
|
||||
else if (accessinfo = my_get_ext(ctx->cert,p->accesstype,
|
||||
NID_info_access)) {
|
||||
if (p->verbose)
|
||||
BIO_printf(p->errorbio,"Setting URL from AIA to: %s\n", accessinfo);
|
||||
|
||||
curl_easy_setopt(p->curl, CURLOPT_URL,accessinfo);
|
||||
}
|
||||
}
|
||||
if (p->verbose > 2)
|
||||
BIO_printf(p->errorbio,"leaving ssl_app_verify_callback with %d\n", ok);
|
||||
return(ok);
|
||||
}
|
||||
|
||||
|
||||
/* This is an example of an curl SSL initialisation call back. The callback sets:
|
||||
- a private key and certificate
|
||||
- a trusted ca certificate
|
||||
- a preferred cipherlist
|
||||
- an application verification callback (the function above)
|
||||
*/
|
||||
|
||||
static CURLcode sslctxfun(CURL * curl, void * sslctx, void * parm) {
|
||||
|
||||
sslctxparm * p = (sslctxparm *) parm;
|
||||
SSL_CTX * ctx = (SSL_CTX *) sslctx ;
|
||||
|
||||
if (!SSL_CTX_use_certificate(ctx,p->usercert)) {
|
||||
BIO_printf(p->errorbio, "SSL_CTX_use_certificate problem\n"); goto err;
|
||||
}
|
||||
if (!SSL_CTX_use_PrivateKey(ctx,p->pkey)) {
|
||||
BIO_printf(p->errorbio, "SSL_CTX_use_PrivateKey\n"); goto err;
|
||||
}
|
||||
|
||||
if (!SSL_CTX_check_private_key(ctx)) {
|
||||
BIO_printf(p->errorbio, "SSL_CTX_check_private_key\n"); goto err;
|
||||
}
|
||||
|
||||
SSL_CTX_set_quiet_shutdown(ctx,1);
|
||||
SSL_CTX_set_cipher_list(ctx,"RC4-MD5");
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
|
||||
|
||||
X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), sk_X509_value(p->ca, sk_X509_num(p->ca)-1));
|
||||
|
||||
SSL_CTX_set_verify_depth(ctx,2);
|
||||
|
||||
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,ZERO_NULL);
|
||||
|
||||
SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback, parm);
|
||||
|
||||
|
||||
return CURLE_OK ;
|
||||
err:
|
||||
ERR_print_errors(p->errorbio);
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
BIO* in=NULL;
|
||||
BIO* out=NULL;
|
||||
|
||||
char * outfile = NULL;
|
||||
char * infile = NULL ;
|
||||
|
||||
int tabLength=100;
|
||||
char *binaryptr;
|
||||
char* mimetype;
|
||||
char* mimetypeaccept=NULL;
|
||||
char* contenttype;
|
||||
const char** pp;
|
||||
unsigned char* hostporturl = NULL;
|
||||
BIO * p12bio ;
|
||||
char **args = argv + 1;
|
||||
unsigned char * serverurl;
|
||||
sslctxparm p;
|
||||
char *response;
|
||||
|
||||
CURLcode res;
|
||||
struct curl_slist * headers=NULL;
|
||||
int badarg=0;
|
||||
|
||||
binaryptr = malloc(tabLength);
|
||||
|
||||
p.verbose = 0;
|
||||
p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE);
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
/* we need some more for the P12 decoding */
|
||||
|
||||
OpenSSL_add_all_ciphers();
|
||||
OpenSSL_add_all_digests();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
|
||||
|
||||
while (*args && *args[0] == '-') {
|
||||
if (!strcmp (*args, "-in")) {
|
||||
if (args[1]) {
|
||||
infile=*(++args);
|
||||
} else badarg=1;
|
||||
} else if (!strcmp (*args, "-out")) {
|
||||
if (args[1]) {
|
||||
outfile=*(++args);
|
||||
} else badarg=1;
|
||||
} else if (!strcmp (*args, "-p12")) {
|
||||
if (args[1]) {
|
||||
p.p12file = *(++args);
|
||||
} else badarg=1;
|
||||
} else if (strcmp(*args,"-envpass") == 0) {
|
||||
if (args[1]) {
|
||||
p.pst = getenv(*(++args));
|
||||
} else badarg=1;
|
||||
} else if (strcmp(*args,"-connect") == 0) {
|
||||
if (args[1]) {
|
||||
hostporturl = *(++args);
|
||||
} else badarg=1;
|
||||
} else if (strcmp(*args,"-mimetype") == 0) {
|
||||
if (args[1]) {
|
||||
mimetype = *(++args);
|
||||
} else badarg=1;
|
||||
} else if (strcmp(*args,"-acceptmime") == 0) {
|
||||
if (args[1]) {
|
||||
mimetypeaccept = *(++args);
|
||||
} else badarg=1;
|
||||
} else if (strcmp(*args,"-accesstype") == 0) {
|
||||
if (args[1]) {
|
||||
if ((p.accesstype = OBJ_obj2nid(OBJ_txt2obj(*++args,0))) == 0) badarg=1;
|
||||
} else badarg=1;
|
||||
} else if (strcmp(*args,"-verbose") == 0) {
|
||||
p.verbose++;
|
||||
} else badarg=1;
|
||||
args++;
|
||||
}
|
||||
|
||||
if (mimetype==NULL || mimetypeaccept == NULL) badarg = 1;
|
||||
|
||||
if (badarg) {
|
||||
for (pp=curlx_usage; (*pp != NULL); pp++)
|
||||
BIO_printf(p.errorbio,"%s\n",*pp);
|
||||
BIO_printf(p.errorbio,"\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* set input */
|
||||
|
||||
if ((in=BIO_new(BIO_s_file())) == NULL) {
|
||||
BIO_printf(p.errorbio, "Error setting input bio\n");
|
||||
goto err;
|
||||
} else if (infile == NULL)
|
||||
BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT);
|
||||
else if (BIO_read_filename(in,infile) <= 0) {
|
||||
BIO_printf(p.errorbio, "Error opening input file %s\n", infile);
|
||||
BIO_free(in);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* set output */
|
||||
|
||||
if ((out=BIO_new(BIO_s_file())) == NULL) {
|
||||
BIO_printf(p.errorbio, "Error setting output bio.\n");
|
||||
goto err;
|
||||
} else if (outfile == NULL)
|
||||
BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
|
||||
else if (BIO_write_filename(out,outfile) <= 0) {
|
||||
BIO_printf(p.errorbio, "Error opening output file %s\n", outfile);
|
||||
BIO_free(out);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE);
|
||||
|
||||
if (!(p.curl = curl_easy_init())) {
|
||||
BIO_printf(p.errorbio, "Cannot init curl lib\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!(p12bio = BIO_new_file(p.p12file , "rb"))) {
|
||||
BIO_printf(p.errorbio, "Error opening P12 file %s\n", p.p12file); goto err;
|
||||
}
|
||||
if (!(p.p12 = d2i_PKCS12_bio (p12bio, NULL))) {
|
||||
BIO_printf(p.errorbio, "Cannot decode P12 structure %s\n", p.p12file); goto err;
|
||||
}
|
||||
|
||||
p.ca= NULL;
|
||||
if (!(PKCS12_parse (p.p12, p.pst, &(p.pkey), &(p.usercert), &(p.ca) ) )) {
|
||||
BIO_printf(p.errorbio,"Invalid P12 structure in %s\n", p.p12file); goto err;
|
||||
}
|
||||
|
||||
if (sk_X509_num(p.ca) <= 0) {
|
||||
BIO_printf(p.errorbio,"No trustworthy CA given.%s\n", p.p12file); goto err;
|
||||
}
|
||||
|
||||
if (p.verbose > 1)
|
||||
X509_print_ex(p.errorbio,p.usercert,0,0);
|
||||
|
||||
/* determine URL to go */
|
||||
|
||||
if (hostporturl) {
|
||||
serverurl = malloc(9+strlen(hostporturl));
|
||||
sprintf(serverurl,"https://%s",hostporturl);
|
||||
}
|
||||
else if (p.accesstype != 0) { /* see whether we can find an AIA or SIA for a given access type */
|
||||
if (!(serverurl = my_get_ext(p.usercert,p.accesstype,NID_info_access))) {
|
||||
int j=0;
|
||||
BIO_printf(p.errorbio,"no service URL in user cert "
|
||||
"cherching in others certificats\n");
|
||||
for (j=0;j<sk_X509_num(p.ca);j++) {
|
||||
if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype,
|
||||
NID_info_access)))
|
||||
break;
|
||||
if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype,
|
||||
NID_sinfo_access)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!serverurl) {
|
||||
BIO_printf(p.errorbio, "no service URL in certificats,"
|
||||
" check '-accesstype (AD_DVCS | ad_timestamping)'"
|
||||
" or use '-connect'\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (p.verbose)
|
||||
BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl);
|
||||
|
||||
curl_easy_setopt(p.curl, CURLOPT_URL, serverurl);
|
||||
|
||||
/* Now specify the POST binary data */
|
||||
|
||||
curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr);
|
||||
curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,(long)tabLength);
|
||||
|
||||
/* pass our list of custom made headers */
|
||||
|
||||
contenttype = malloc(15+strlen(mimetype));
|
||||
sprintf(contenttype,"Content-type: %s",mimetype);
|
||||
headers = curl_slist_append(headers,contenttype);
|
||||
curl_easy_setopt(p.curl, CURLOPT_HTTPHEADER, headers);
|
||||
|
||||
if (p.verbose)
|
||||
BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl);
|
||||
|
||||
{
|
||||
FILE *outfp;
|
||||
BIO_get_fp(out,&outfp);
|
||||
curl_easy_setopt(p.curl, CURLOPT_WRITEDATA, outfp);
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun) ;
|
||||
|
||||
if (res != CURLE_OK)
|
||||
BIO_printf(p.errorbio,"%d %s=%d %d\n", __LINE__, "CURLOPT_SSL_CTX_FUNCTION",CURLOPT_SSL_CTX_FUNCTION,res);
|
||||
|
||||
curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_DATA, &p);
|
||||
|
||||
{
|
||||
int lu; int i=0;
|
||||
while ((lu = BIO_read (in,&binaryptr[i],tabLength-i)) >0 ) {
|
||||
i+=lu;
|
||||
if (i== tabLength) {
|
||||
tabLength+=100;
|
||||
binaryptr=realloc(binaryptr,tabLength); /* should be more careful */
|
||||
}
|
||||
}
|
||||
tabLength = i;
|
||||
}
|
||||
/* Now specify the POST binary data */
|
||||
|
||||
curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr);
|
||||
curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,(long)tabLength);
|
||||
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
|
||||
BIO_printf(p.errorbio,"%d %s %d\n", __LINE__, "curl_easy_perform",
|
||||
res = curl_easy_perform(p.curl));
|
||||
{
|
||||
int result =curl_easy_getinfo(p.curl,CURLINFO_CONTENT_TYPE,&response);
|
||||
if( mimetypeaccept && p.verbose)
|
||||
if(!strcmp(mimetypeaccept,response))
|
||||
BIO_printf(p.errorbio,"the response has a correct mimetype : %s\n",
|
||||
response);
|
||||
else
|
||||
BIO_printf(p.errorbio,"the response doesn\'t have an acceptable "
|
||||
"mime type, it is %s instead of %s\n",
|
||||
response,mimetypeaccept);
|
||||
}
|
||||
|
||||
/*** code d'erreur si accept mime ***, egalement code return HTTP != 200 ***/
|
||||
|
||||
/* free the header list*/
|
||||
|
||||
curl_slist_free_all(headers);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(p.curl);
|
||||
|
||||
BIO_free(in);
|
||||
BIO_free(out);
|
||||
return (EXIT_SUCCESS);
|
||||
|
||||
err: BIO_printf(p.errorbio,"error");
|
||||
exit(1);
|
||||
}
|
147
curl/docs/examples/debug.c
Normal file
147
curl/docs/examples/debug.c
Normal file
@ -0,0 +1,147 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
struct data {
|
||||
char trace_ascii; /* 1 or 0 */
|
||||
};
|
||||
|
||||
static
|
||||
void dump(const char *text,
|
||||
FILE *stream, unsigned char *ptr, size_t size,
|
||||
char nohex)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
|
||||
unsigned int width=0x10;
|
||||
|
||||
if(nohex)
|
||||
/* without the hex output, we can fit more on screen */
|
||||
width = 0x40;
|
||||
|
||||
fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n",
|
||||
text, (long)size, (long)size);
|
||||
|
||||
for(i=0; i<size; i+= width) {
|
||||
|
||||
fprintf(stream, "%4.4lx: ", (long)i);
|
||||
|
||||
if(!nohex) {
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++)
|
||||
if(i+c < size)
|
||||
fprintf(stream, "%02x ", ptr[i+c]);
|
||||
else
|
||||
fputs(" ", stream);
|
||||
}
|
||||
|
||||
for(c = 0; (c < width) && (i+c < size); c++) {
|
||||
/* check for 0D0A; if found, skip past and start a new line of output */
|
||||
if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
|
||||
i+=(c+2-width);
|
||||
break;
|
||||
}
|
||||
fprintf(stream, "%c",
|
||||
(ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
|
||||
/* check again for 0D0A, to avoid an extra \n if it's at width */
|
||||
if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
|
||||
i+=(c+3-width);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fputc('\n', stream); /* newline */
|
||||
}
|
||||
fflush(stream);
|
||||
}
|
||||
|
||||
static
|
||||
int my_trace(CURL *handle, curl_infotype type,
|
||||
char *data, size_t size,
|
||||
void *userp)
|
||||
{
|
||||
struct data *config = (struct data *)userp;
|
||||
const char *text;
|
||||
(void)handle; /* prevent compiler warning */
|
||||
|
||||
switch (type) {
|
||||
case CURLINFO_TEXT:
|
||||
fprintf(stderr, "== Info: %s", data);
|
||||
default: /* in case a new one is introduced to shock us */
|
||||
return 0;
|
||||
|
||||
case CURLINFO_HEADER_OUT:
|
||||
text = "=> Send header";
|
||||
break;
|
||||
case CURLINFO_DATA_OUT:
|
||||
text = "=> Send data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_OUT:
|
||||
text = "=> Send SSL data";
|
||||
break;
|
||||
case CURLINFO_HEADER_IN:
|
||||
text = "<= Recv header";
|
||||
break;
|
||||
case CURLINFO_DATA_IN:
|
||||
text = "<= Recv data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_IN:
|
||||
text = "<= Recv SSL data";
|
||||
break;
|
||||
}
|
||||
|
||||
dump(text, stderr, (unsigned char *)data, size, config->trace_ascii);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct data config;
|
||||
|
||||
config.trace_ascii = 1; /* enable ascii tracing */
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &config);
|
||||
|
||||
/* the DEBUGFUNCTION has no effect until we enable VERBOSE */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* example.com is redirected, so we tell libcurl to follow redirection */
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
441
curl/docs/examples/evhiperfifo.c
Normal file
441
curl/docs/examples/evhiperfifo.c
Normal file
@ -0,0 +1,441 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* Example application source code using the multi socket interface to
|
||||
* download many files at once.
|
||||
*
|
||||
* This example features the same basic functionality as hiperfifo.c does,
|
||||
* but this uses libev instead of libevent.
|
||||
*
|
||||
* Written by Jeff Pohlmeyer, converted to use libev by Markus Koetter
|
||||
|
||||
Requires libev and a (POSIX?) system that has mkfifo().
|
||||
|
||||
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
|
||||
sample programs.
|
||||
|
||||
When running, the program creates the named pipe "hiper.fifo"
|
||||
|
||||
Whenever there is input into the fifo, the program reads the input as a list
|
||||
of URL's and creates some new easy handles to fetch each URL via the
|
||||
curl_multi "hiper" API.
|
||||
|
||||
|
||||
Thus, you can try a single URL:
|
||||
% echo http://www.yahoo.com > hiper.fifo
|
||||
|
||||
Or a whole bunch of them:
|
||||
% cat my-url-list > hiper.fifo
|
||||
|
||||
The fifo buffer is handled almost instantly, so you can even add more URL's
|
||||
while the previous requests are still being downloaded.
|
||||
|
||||
Note:
|
||||
For the sake of simplicity, URL length is limited to 1023 char's !
|
||||
|
||||
This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
callback.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/poll.h>
|
||||
#include <curl/curl.h>
|
||||
#include <ev.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define DPRINT(x...) printf(x)
|
||||
|
||||
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
|
||||
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo
|
||||
{
|
||||
struct ev_loop *loop;
|
||||
struct ev_io fifo_event;
|
||||
struct ev_timer timer_event;
|
||||
CURLM *multi;
|
||||
int still_running;
|
||||
FILE* input;
|
||||
} GlobalInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo
|
||||
{
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific socket */
|
||||
typedef struct _SockInfo
|
||||
{
|
||||
curl_socket_t sockfd;
|
||||
CURL *easy;
|
||||
int action;
|
||||
long timeout;
|
||||
struct ev_io ev;
|
||||
int evset;
|
||||
GlobalInfo *global;
|
||||
} SockInfo;
|
||||
|
||||
static void timer_cb(EV_P_ struct ev_timer *w, int revents);
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
|
||||
{
|
||||
DPRINT("%s %li\n", __PRETTY_FUNCTION__, timeout_ms);
|
||||
ev_timer_stop(g->loop, &g->timer_event);
|
||||
if (timeout_ms > 0)
|
||||
{
|
||||
double t = timeout_ms / 1000;
|
||||
ev_timer_init(&g->timer_event, timer_cb, t, 0.);
|
||||
ev_timer_start(g->loop, &g->timer_event);
|
||||
}else
|
||||
timer_cb(g->loop, &g->timer_event, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(const char *where, CURLMcode code)
|
||||
{
|
||||
if ( CURLM_OK != code )
|
||||
{
|
||||
const char *s;
|
||||
switch ( code )
|
||||
{
|
||||
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
|
||||
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
|
||||
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
|
||||
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
|
||||
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
|
||||
case CURLM_LAST: s="CURLM_LAST"; break;
|
||||
default: s="CURLM_unknown";
|
||||
break;
|
||||
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET";
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
/* ignore this error */
|
||||
return;
|
||||
}
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn;
|
||||
CURL *easy;
|
||||
CURLcode res;
|
||||
|
||||
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
|
||||
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
easy = msg->easy_handle;
|
||||
res = msg->data.result;
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by libevent when we get action on a multi socket */
|
||||
static void event_cb(EV_P_ struct ev_io *w, int revents)
|
||||
{
|
||||
DPRINT("%s w %p revents %i\n", __PRETTY_FUNCTION__, w, revents);
|
||||
GlobalInfo *g = (GlobalInfo*) w->data;
|
||||
CURLMcode rc;
|
||||
|
||||
int action = (revents&EV_READ?CURL_POLL_IN:0)|
|
||||
(revents&EV_WRITE?CURL_POLL_OUT:0);
|
||||
rc = curl_multi_socket_action(g->multi, w->fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
if ( g->still_running <= 0 )
|
||||
{
|
||||
fprintf(MSG_OUT, "last transfer done, kill timeout\n");
|
||||
ev_timer_stop(g->loop, &g->timer_event);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by libevent when our timeout expires */
|
||||
static void timer_cb(EV_P_ struct ev_timer *w, int revents)
|
||||
{
|
||||
DPRINT("%s w %p revents %i\n", __PRETTY_FUNCTION__, w, revents);
|
||||
|
||||
GlobalInfo *g = (GlobalInfo *)w->data;
|
||||
CURLMcode rc;
|
||||
|
||||
rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, &g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
}
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(SockInfo *f, GlobalInfo *g)
|
||||
{
|
||||
printf("%s \n", __PRETTY_FUNCTION__);
|
||||
if ( f )
|
||||
{
|
||||
if ( f->evset )
|
||||
ev_io_stop(g->loop, &f->ev);
|
||||
free(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Assign information to a SockInfo structure */
|
||||
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
|
||||
{
|
||||
printf("%s \n", __PRETTY_FUNCTION__);
|
||||
|
||||
int kind = (act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0);
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
f->easy = e;
|
||||
if ( f->evset )
|
||||
ev_io_stop(g->loop, &f->ev);
|
||||
ev_io_init(&f->ev, event_cb, f->sockfd, kind);
|
||||
f->ev.data = g;
|
||||
f->evset=1;
|
||||
ev_io_start(g->loop, &f->ev);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize a new SockInfo structure */
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
|
||||
{
|
||||
SockInfo *fdp = calloc(sizeof(SockInfo), 1);
|
||||
|
||||
fdp->global = g;
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
DPRINT("%s e %p s %i what %i cbp %p sockp %p\n",
|
||||
__PRETTY_FUNCTION__, e, s, what, cbp, sockp);
|
||||
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
SockInfo *fdp = (SockInfo*) sockp;
|
||||
const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE"};
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
if ( what == CURL_POLL_REMOVE )
|
||||
{
|
||||
fprintf(MSG_OUT, "\n");
|
||||
remsock(fdp, g);
|
||||
} else
|
||||
{
|
||||
if ( !fdp )
|
||||
{
|
||||
fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]);
|
||||
addsock(s, e, what, g);
|
||||
} else
|
||||
{
|
||||
fprintf(MSG_OUT,
|
||||
"Changing action from %s to %s\n",
|
||||
whatstr[fdp->action], whatstr[what]);
|
||||
setsock(fdp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
ConnInfo *conn = (ConnInfo*) data;
|
||||
(void)ptr;
|
||||
(void)conn;
|
||||
return realsize;
|
||||
}
|
||||
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
static int prog_cb (void *p, double dltotal, double dlnow, double ult,
|
||||
double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
(void)ult;
|
||||
(void)uln;
|
||||
|
||||
fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
static void new_conn(char *url, GlobalInfo *g )
|
||||
{
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = calloc(1, sizeof(ConnInfo));
|
||||
memset(conn, 0, sizeof(ConnInfo));
|
||||
conn->error[0]='\0';
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
if ( !conn->easy )
|
||||
{
|
||||
fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
|
||||
exit(2);
|
||||
}
|
||||
conn->global = g;
|
||||
conn->url = strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 3L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 10L);
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc = curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
|
||||
/* note that the add_handle() will set a time-out to trigger very soon so
|
||||
that the necessary socket_action() call will be called by this app */
|
||||
}
|
||||
|
||||
/* This gets called whenever data is received from the fifo */
|
||||
static void fifo_cb(EV_P_ struct ev_io *w, int revents)
|
||||
{
|
||||
char s[1024];
|
||||
long int rv=0;
|
||||
int n=0;
|
||||
GlobalInfo *g = (GlobalInfo *)w->data;
|
||||
|
||||
do
|
||||
{
|
||||
s[0]='\0';
|
||||
rv=fscanf(g->input, "%1023s%n", s, &n);
|
||||
s[n]='\0';
|
||||
if ( n && s[0] )
|
||||
{
|
||||
new_conn(s,g); /* if we read a URL, go get it! */
|
||||
} else break;
|
||||
} while ( rv != EOF );
|
||||
}
|
||||
|
||||
/* Create a named pipe and tell libevent to monitor it */
|
||||
static int init_fifo (GlobalInfo *g)
|
||||
{
|
||||
struct stat st;
|
||||
static const char *fifo = "hiper.fifo";
|
||||
curl_socket_t sockfd;
|
||||
|
||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||
if ( lstat (fifo, &st) == 0 )
|
||||
{
|
||||
if ( (st.st_mode & S_IFMT) == S_IFREG )
|
||||
{
|
||||
errno = EEXIST;
|
||||
perror("lstat");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
unlink(fifo);
|
||||
if ( mkfifo (fifo, 0600) == -1 )
|
||||
{
|
||||
perror("mkfifo");
|
||||
exit (1);
|
||||
}
|
||||
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||
if ( sockfd == -1 )
|
||||
{
|
||||
perror("open");
|
||||
exit (1);
|
||||
}
|
||||
g->input = fdopen(sockfd, "r");
|
||||
|
||||
fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo);
|
||||
ev_io_init(&g->fifo_event, fifo_cb, sockfd, EV_READ);
|
||||
ev_io_start(g->loop, &g->fifo_event);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo g;
|
||||
CURLMcode rc;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
memset(&g, 0, sizeof(GlobalInfo));
|
||||
g.loop = ev_default_loop(0);
|
||||
|
||||
init_fifo(&g);
|
||||
g.multi = curl_multi_init();
|
||||
|
||||
ev_timer_init(&g.timer_event, timer_cb, 0., 0.);
|
||||
g.timer_event.data = &g;
|
||||
g.fifo_event.data = &g;
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
|
||||
|
||||
/* we don't call any curl_multi_socket*() function yet as we have no handles
|
||||
added! */
|
||||
|
||||
ev_loop(g.loop, 0);
|
||||
curl_multi_cleanup(g.multi);
|
||||
return 0;
|
||||
}
|
153
curl/docs/examples/externalsocket.c
Normal file
153
curl/docs/examples/externalsocket.c
Normal file
@ -0,0 +1,153 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/*
|
||||
* This is an example demonstrating how an application can pass in a custom
|
||||
* socket to libcurl to use. This example also handles the connect itself.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#define close closesocket
|
||||
#else
|
||||
#include <sys/types.h> /* socket types */
|
||||
#include <sys/socket.h> /* socket definitions */
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h> /* inet (3) funtions */
|
||||
#include <unistd.h> /* misc. Unix functions */
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* The IP address and port number to connect to */
|
||||
#define IPADDR "127.0.0.1"
|
||||
#define PORTNUM 80
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE 0xffffffff
|
||||
#endif
|
||||
|
||||
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
int written = fwrite(ptr, size, nmemb, (FILE *)stream);
|
||||
return written;
|
||||
}
|
||||
|
||||
static curl_socket_t opensocket(void *clientp,
|
||||
curlsocktype purpose,
|
||||
struct curl_sockaddr *address)
|
||||
{
|
||||
curl_socket_t sockfd;
|
||||
(void)purpose;
|
||||
(void)address;
|
||||
sockfd = *(curl_socket_t *)clientp;
|
||||
/* the actual externally set socket is passed in via the OPENSOCKETDATA
|
||||
option */
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
static int sockopt_callback(void *clientp, curl_socket_t curlfd,
|
||||
curlsocktype purpose)
|
||||
{
|
||||
(void)clientp;
|
||||
(void)curlfd;
|
||||
(void)purpose;
|
||||
/* This return code was added in libcurl 7.21.5 */
|
||||
return CURL_SOCKOPT_ALREADY_CONNECTED;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct sockaddr_in servaddr; /* socket address structure */
|
||||
curl_socket_t sockfd;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsaData;
|
||||
int initwsa;
|
||||
|
||||
if((initwsa = WSAStartup(MAKEWORD(2,0), &wsaData)) != 0) {
|
||||
printf("WSAStartup failed: %d\n", initwsa);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/*
|
||||
* Note that libcurl will internally think that you connect to the host
|
||||
* and port that you specify in the URL option.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999");
|
||||
|
||||
/* Create the socket "manually" */
|
||||
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == CURL_SOCKET_BAD ) {
|
||||
printf("Error creating listening socket.\n");
|
||||
return 3;
|
||||
}
|
||||
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_port = htons(PORTNUM);
|
||||
|
||||
if (INADDR_NONE == (servaddr.sin_addr.s_addr = inet_addr(IPADDR)))
|
||||
return 2;
|
||||
|
||||
if(connect(sockfd,(struct sockaddr *) &servaddr, sizeof(servaddr)) ==
|
||||
-1) {
|
||||
close(sockfd);
|
||||
printf("client error: connect: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* no progress meter please */
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
|
||||
|
||||
/* call this function to get a socket */
|
||||
curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket);
|
||||
curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd);
|
||||
|
||||
/* call this function to set options for the socket */
|
||||
curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(res) {
|
||||
printf("libcurl error: %d\n", res);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
86
curl/docs/examples/fileupload.c
Normal file
86
curl/docs/examples/fileupload.c
Normal file
@ -0,0 +1,86 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct stat file_info;
|
||||
double speed_upload, total_time;
|
||||
FILE *fd;
|
||||
|
||||
fd = fopen("debugit", "rb"); /* open file to upload */
|
||||
if(!fd) {
|
||||
|
||||
return 1; /* can't continue */
|
||||
}
|
||||
|
||||
/* to get the file size */
|
||||
if(fstat(fileno(fd), &file_info) != 0) {
|
||||
|
||||
return 1; /* can't continue */
|
||||
}
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* upload to this place */
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"file:///home/dast/src/curl/debug/new");
|
||||
|
||||
/* tell it to "upload" to the URL */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* set where to read from (on Windows you need to use READFUNCTION too) */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, fd);
|
||||
|
||||
/* and give the size of the upload (optional) */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)file_info.st_size);
|
||||
|
||||
/* enable verbose for easier tracing */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK) {
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
}
|
||||
else {
|
||||
/* now extract transfer info */
|
||||
curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed_upload);
|
||||
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time);
|
||||
|
||||
fprintf(stderr, "Speed: %.3f bytes/sec during %.3f seconds\n",
|
||||
speed_upload, total_time);
|
||||
|
||||
}
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
542
curl/docs/examples/fopen.c
Normal file
542
curl/docs/examples/fopen.c
Normal file
@ -0,0 +1,542 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This example source code introduces a c library buffered I/O interface to
|
||||
* URL reads it supports fopen(), fread(), fgets(), feof(), fclose(),
|
||||
* rewind(). Supported functions have identical prototypes to their normal c
|
||||
* lib namesakes and are preceaded by url_ .
|
||||
*
|
||||
* Using this code you can replace your program's fopen() with url_fopen()
|
||||
* and fread() with url_fread() and it become possible to read remote streams
|
||||
* instead of (only) local files. Local files (ie those that can be directly
|
||||
* fopened) will drop back to using the underlying clib implementations
|
||||
*
|
||||
* See the main() function at the bottom that shows an app that retrives from a
|
||||
* specified url using fgets() and fread() and saves as two output files.
|
||||
*
|
||||
* Copyright (c) 2003 Simtec Electronics
|
||||
*
|
||||
* Re-implemented by Vincent Sanders <vince@kyllikki.org> with extensive
|
||||
* reference to original curl example code
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This example requires libcurl 7.9.7 or later.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifndef WIN32
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
enum fcurl_type_e {
|
||||
CFTYPE_NONE=0,
|
||||
CFTYPE_FILE=1,
|
||||
CFTYPE_CURL=2
|
||||
};
|
||||
|
||||
struct fcurl_data
|
||||
{
|
||||
enum fcurl_type_e type; /* type of handle */
|
||||
union {
|
||||
CURL *curl;
|
||||
FILE *file;
|
||||
} handle; /* handle */
|
||||
|
||||
char *buffer; /* buffer to store cached data*/
|
||||
size_t buffer_len; /* currently allocated buffers length */
|
||||
size_t buffer_pos; /* end of data in buffer*/
|
||||
int still_running; /* Is background url fetch still in progress */
|
||||
};
|
||||
|
||||
typedef struct fcurl_data URL_FILE;
|
||||
|
||||
/* exported functions */
|
||||
URL_FILE *url_fopen(const char *url,const char *operation);
|
||||
int url_fclose(URL_FILE *file);
|
||||
int url_feof(URL_FILE *file);
|
||||
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file);
|
||||
char * url_fgets(char *ptr, size_t size, URL_FILE *file);
|
||||
void url_rewind(URL_FILE *file);
|
||||
|
||||
/* we use a global one for convenience */
|
||||
CURLM *multi_handle;
|
||||
|
||||
/* curl calls this routine to get more data */
|
||||
static size_t write_callback(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
void *userp)
|
||||
{
|
||||
char *newbuff;
|
||||
size_t rembuff;
|
||||
|
||||
URL_FILE *url = (URL_FILE *)userp;
|
||||
size *= nitems;
|
||||
|
||||
rembuff=url->buffer_len - url->buffer_pos; /* remaining space in buffer */
|
||||
|
||||
if(size > rembuff) {
|
||||
/* not enough space in buffer */
|
||||
newbuff=realloc(url->buffer,url->buffer_len + (size - rembuff));
|
||||
if(newbuff==NULL) {
|
||||
fprintf(stderr,"callback buffer grow failed\n");
|
||||
size=rembuff;
|
||||
}
|
||||
else {
|
||||
/* realloc succeeded increase buffer size*/
|
||||
url->buffer_len+=size - rembuff;
|
||||
url->buffer=newbuff;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&url->buffer[url->buffer_pos], buffer, size);
|
||||
url->buffer_pos += size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* use to attempt to fill the read buffer up to requested number of bytes */
|
||||
static int fill_buffer(URL_FILE *file, size_t want)
|
||||
{
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
CURLMcode mc; /* curl_multi_fdset() return code */
|
||||
|
||||
/* only attempt to fill buffer if transactions still running and buffer
|
||||
* doesn't exceed required size already
|
||||
*/
|
||||
if((!file->still_running) || (file->buffer_pos > want))
|
||||
return 0;
|
||||
|
||||
/* attempt to fill buffer */
|
||||
do {
|
||||
int maxfd = -1;
|
||||
long curl_timeo = -1;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to fail on */
|
||||
timeout.tv_sec = 60; /* 1 minute */
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
curl_multi_timeout(multi_handle, &curl_timeo);
|
||||
if(curl_timeo >= 0) {
|
||||
timeout.tv_sec = curl_timeo / 1000;
|
||||
if(timeout.tv_sec > 1)
|
||||
timeout.tv_sec = 1;
|
||||
else
|
||||
timeout.tv_usec = (curl_timeo % 1000) * 1000;
|
||||
}
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
if(mc != CURLM_OK)
|
||||
{
|
||||
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
|
||||
break;
|
||||
}
|
||||
|
||||
/* On success the value of maxfd is guaranteed to be >= -1. We call
|
||||
select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
|
||||
no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
|
||||
to sleep 100ms, which is the minimum suggested value in the
|
||||
curl_multi_fdset() doc. */
|
||||
|
||||
if(maxfd == -1) {
|
||||
#ifdef _WIN32
|
||||
Sleep(100);
|
||||
rc = 0;
|
||||
#else
|
||||
/* Portable sleep for platforms other than Windows. */
|
||||
struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
|
||||
rc = select(0, NULL, NULL, NULL, &wait);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* Note that on some platforms 'timeout' may be modified by select().
|
||||
If you need access to the original value save a copy beforehand. */
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
}
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
break;
|
||||
|
||||
case 0:
|
||||
default:
|
||||
/* timeout or readable/writable sockets */
|
||||
curl_multi_perform(multi_handle, &file->still_running);
|
||||
break;
|
||||
}
|
||||
} while(file->still_running && (file->buffer_pos < want));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* use to remove want bytes from the front of a files buffer */
|
||||
static int use_buffer(URL_FILE *file, size_t want)
|
||||
{
|
||||
/* sort out buffer */
|
||||
if((file->buffer_pos - want) <=0) {
|
||||
/* ditch buffer - write will recreate */
|
||||
free(file->buffer);
|
||||
file->buffer=NULL;
|
||||
file->buffer_pos=0;
|
||||
file->buffer_len=0;
|
||||
}
|
||||
else {
|
||||
/* move rest down make it available for later */
|
||||
memmove(file->buffer,
|
||||
&file->buffer[want],
|
||||
(file->buffer_pos - want));
|
||||
|
||||
file->buffer_pos -= want;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
URL_FILE *url_fopen(const char *url,const char *operation)
|
||||
{
|
||||
/* this code could check for URLs or types in the 'url' and
|
||||
basically use the real fopen() for standard files */
|
||||
|
||||
URL_FILE *file;
|
||||
(void)operation;
|
||||
|
||||
file = malloc(sizeof(URL_FILE));
|
||||
if(!file)
|
||||
return NULL;
|
||||
|
||||
memset(file, 0, sizeof(URL_FILE));
|
||||
|
||||
if((file->handle.file=fopen(url,operation)))
|
||||
file->type = CFTYPE_FILE; /* marked as URL */
|
||||
|
||||
else {
|
||||
file->type = CFTYPE_CURL; /* marked as URL */
|
||||
file->handle.curl = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(file->handle.curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(file->handle.curl, CURLOPT_WRITEDATA, file);
|
||||
curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, 0L);
|
||||
curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||
|
||||
if(!multi_handle)
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
curl_multi_add_handle(multi_handle, file->handle.curl);
|
||||
|
||||
/* lets start the fetch */
|
||||
curl_multi_perform(multi_handle, &file->still_running);
|
||||
|
||||
if((file->buffer_pos == 0) && (!file->still_running)) {
|
||||
/* if still_running is 0 now, we should return NULL */
|
||||
|
||||
/* make sure the easy handle is not in the multi handle anymore */
|
||||
curl_multi_remove_handle(multi_handle, file->handle.curl);
|
||||
|
||||
/* cleanup */
|
||||
curl_easy_cleanup(file->handle.curl);
|
||||
|
||||
free(file);
|
||||
|
||||
file = NULL;
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
int url_fclose(URL_FILE *file)
|
||||
{
|
||||
int ret=0;/* default is good return */
|
||||
|
||||
switch(file->type) {
|
||||
case CFTYPE_FILE:
|
||||
ret=fclose(file->handle.file); /* passthrough */
|
||||
break;
|
||||
|
||||
case CFTYPE_CURL:
|
||||
/* make sure the easy handle is not in the multi handle anymore */
|
||||
curl_multi_remove_handle(multi_handle, file->handle.curl);
|
||||
|
||||
/* cleanup */
|
||||
curl_easy_cleanup(file->handle.curl);
|
||||
break;
|
||||
|
||||
default: /* unknown or supported type - oh dear */
|
||||
ret=EOF;
|
||||
errno=EBADF;
|
||||
break;
|
||||
}
|
||||
|
||||
free(file->buffer);/* free any allocated buffer space */
|
||||
free(file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int url_feof(URL_FILE *file)
|
||||
{
|
||||
int ret=0;
|
||||
|
||||
switch(file->type) {
|
||||
case CFTYPE_FILE:
|
||||
ret=feof(file->handle.file);
|
||||
break;
|
||||
|
||||
case CFTYPE_CURL:
|
||||
if((file->buffer_pos == 0) && (!file->still_running))
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
default: /* unknown or supported type - oh dear */
|
||||
ret=-1;
|
||||
errno=EBADF;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
|
||||
{
|
||||
size_t want;
|
||||
|
||||
switch(file->type) {
|
||||
case CFTYPE_FILE:
|
||||
want=fread(ptr,size,nmemb,file->handle.file);
|
||||
break;
|
||||
|
||||
case CFTYPE_CURL:
|
||||
want = nmemb * size;
|
||||
|
||||
fill_buffer(file,want);
|
||||
|
||||
/* check if theres data in the buffer - if not fill_buffer()
|
||||
* either errored or EOF */
|
||||
if(!file->buffer_pos)
|
||||
return 0;
|
||||
|
||||
/* ensure only available data is considered */
|
||||
if(file->buffer_pos < want)
|
||||
want = file->buffer_pos;
|
||||
|
||||
/* xfer data to caller */
|
||||
memcpy(ptr, file->buffer, want);
|
||||
|
||||
use_buffer(file,want);
|
||||
|
||||
want = want / size; /* number of items */
|
||||
break;
|
||||
|
||||
default: /* unknown or supported type - oh dear */
|
||||
want=0;
|
||||
errno=EBADF;
|
||||
break;
|
||||
|
||||
}
|
||||
return want;
|
||||
}
|
||||
|
||||
char *url_fgets(char *ptr, size_t size, URL_FILE *file)
|
||||
{
|
||||
size_t want = size - 1;/* always need to leave room for zero termination */
|
||||
size_t loop;
|
||||
|
||||
switch(file->type) {
|
||||
case CFTYPE_FILE:
|
||||
ptr = fgets(ptr, (int)size, file->handle.file);
|
||||
break;
|
||||
|
||||
case CFTYPE_CURL:
|
||||
fill_buffer(file,want);
|
||||
|
||||
/* check if theres data in the buffer - if not fill either errored or
|
||||
* EOF */
|
||||
if(!file->buffer_pos)
|
||||
return NULL;
|
||||
|
||||
/* ensure only available data is considered */
|
||||
if(file->buffer_pos < want)
|
||||
want = file->buffer_pos;
|
||||
|
||||
/*buffer contains data */
|
||||
/* look for newline or eof */
|
||||
for(loop=0;loop < want;loop++) {
|
||||
if(file->buffer[loop] == '\n') {
|
||||
want=loop+1;/* include newline */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* xfer data to caller */
|
||||
memcpy(ptr, file->buffer, want);
|
||||
ptr[want]=0;/* allways null terminate */
|
||||
|
||||
use_buffer(file,want);
|
||||
|
||||
break;
|
||||
|
||||
default: /* unknown or supported type - oh dear */
|
||||
ptr=NULL;
|
||||
errno=EBADF;
|
||||
break;
|
||||
}
|
||||
|
||||
return ptr;/*success */
|
||||
}
|
||||
|
||||
void url_rewind(URL_FILE *file)
|
||||
{
|
||||
switch(file->type) {
|
||||
case CFTYPE_FILE:
|
||||
rewind(file->handle.file); /* passthrough */
|
||||
break;
|
||||
|
||||
case CFTYPE_CURL:
|
||||
/* halt transaction */
|
||||
curl_multi_remove_handle(multi_handle, file->handle.curl);
|
||||
|
||||
/* restart */
|
||||
curl_multi_add_handle(multi_handle, file->handle.curl);
|
||||
|
||||
/* ditch buffer - write will recreate - resets stream pos*/
|
||||
free(file->buffer);
|
||||
file->buffer=NULL;
|
||||
file->buffer_pos=0;
|
||||
file->buffer_len=0;
|
||||
|
||||
break;
|
||||
|
||||
default: /* unknown or supported type - oh dear */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Small main program to retrive from a url using fgets and fread saving the
|
||||
* output to two test files (note the fgets method will corrupt binary files if
|
||||
* they contain 0 chars */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
URL_FILE *handle;
|
||||
FILE *outf;
|
||||
|
||||
size_t nread;
|
||||
char buffer[256];
|
||||
const char *url;
|
||||
|
||||
if(argc < 2)
|
||||
url="http://192.168.7.3/testfile";/* default to testurl */
|
||||
else
|
||||
url=argv[1];/* use passed url */
|
||||
|
||||
/* copy from url line by line with fgets */
|
||||
outf=fopen("fgets.test","w+");
|
||||
if(!outf) {
|
||||
perror("couldn't open fgets output file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
handle = url_fopen(url, "r");
|
||||
if(!handle) {
|
||||
printf("couldn't url_fopen() %s\n", url);
|
||||
fclose(outf);
|
||||
return 2;
|
||||
}
|
||||
|
||||
while(!url_feof(handle)) {
|
||||
url_fgets(buffer,sizeof(buffer),handle);
|
||||
fwrite(buffer,1,strlen(buffer),outf);
|
||||
}
|
||||
|
||||
url_fclose(handle);
|
||||
|
||||
fclose(outf);
|
||||
|
||||
|
||||
/* Copy from url with fread */
|
||||
outf=fopen("fread.test","w+");
|
||||
if(!outf) {
|
||||
perror("couldn't open fread output file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
handle = url_fopen("testfile", "r");
|
||||
if(!handle) {
|
||||
printf("couldn't url_fopen() testfile\n");
|
||||
fclose(outf);
|
||||
return 2;
|
||||
}
|
||||
|
||||
do {
|
||||
nread = url_fread(buffer, 1, sizeof(buffer), handle);
|
||||
fwrite(buffer,1,nread,outf);
|
||||
} while(nread);
|
||||
|
||||
url_fclose(handle);
|
||||
|
||||
fclose(outf);
|
||||
|
||||
|
||||
/* Test rewind */
|
||||
outf=fopen("rewind.test","w+");
|
||||
if(!outf) {
|
||||
perror("couldn't open fread output file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
handle = url_fopen("testfile", "r");
|
||||
if(!handle) {
|
||||
printf("couldn't url_fopen() testfile\n");
|
||||
fclose(outf);
|
||||
return 2;
|
||||
}
|
||||
|
||||
nread = url_fread(buffer, 1,sizeof(buffer), handle);
|
||||
fwrite(buffer,1,nread,outf);
|
||||
url_rewind(handle);
|
||||
|
||||
buffer[0]='\n';
|
||||
fwrite(buffer,1,1,outf);
|
||||
|
||||
nread = url_fread(buffer, 1,sizeof(buffer), handle);
|
||||
fwrite(buffer,1,nread,outf);
|
||||
|
||||
|
||||
url_fclose(handle);
|
||||
|
||||
fclose(outf);
|
||||
|
||||
|
||||
return 0;/* all done */
|
||||
}
|
148
curl/docs/examples/ftp-wildcard.c
Normal file
148
curl/docs/examples/ftp-wildcard.c
Normal file
@ -0,0 +1,148 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <curl/curl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct callback_data {
|
||||
FILE *output;
|
||||
};
|
||||
|
||||
static long file_is_coming(struct curl_fileinfo *finfo,
|
||||
struct callback_data *data,
|
||||
int remains);
|
||||
|
||||
static long file_is_downloaded(struct callback_data *data);
|
||||
|
||||
static size_t write_it(char *buff, size_t size, size_t nmemb,
|
||||
void *cb_data);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc = CURLE_OK;
|
||||
|
||||
/* curl easy handle */
|
||||
CURL *handle;
|
||||
|
||||
/* help data */
|
||||
struct callback_data data = { 0 };
|
||||
|
||||
/* global initialization */
|
||||
rc = curl_global_init(CURL_GLOBAL_ALL);
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
/* initialization of easy handle */
|
||||
handle = curl_easy_init();
|
||||
if(!handle) {
|
||||
curl_global_cleanup();
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* turn on wildcard matching */
|
||||
curl_easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
|
||||
|
||||
/* callback is called before download of concrete file started */
|
||||
curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_coming);
|
||||
|
||||
/* callback is called after data from the file have been transferred */
|
||||
curl_easy_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded);
|
||||
|
||||
/* this callback will write contents into files */
|
||||
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_it);
|
||||
|
||||
/* put transfer data into callbacks */
|
||||
curl_easy_setopt(handle, CURLOPT_CHUNK_DATA, &data);
|
||||
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);
|
||||
|
||||
/* curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L); */
|
||||
|
||||
/* set an URL containing wildcard pattern (only in the last part) */
|
||||
if(argc == 2)
|
||||
curl_easy_setopt(handle, CURLOPT_URL, argv[1]);
|
||||
else
|
||||
curl_easy_setopt(handle, CURLOPT_URL, "ftp://example.com/test/*");
|
||||
|
||||
/* and start transfer! */
|
||||
rc = curl_easy_perform(handle);
|
||||
|
||||
curl_easy_cleanup(handle);
|
||||
curl_global_cleanup();
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long file_is_coming(struct curl_fileinfo *finfo,
|
||||
struct callback_data *data,
|
||||
int remains)
|
||||
{
|
||||
printf("%3d %40s %10luB ", remains, finfo->filename,
|
||||
(unsigned long)finfo->size);
|
||||
|
||||
switch(finfo->filetype) {
|
||||
case CURLFILETYPE_DIRECTORY:
|
||||
printf(" DIR\n");
|
||||
break;
|
||||
case CURLFILETYPE_FILE:
|
||||
printf("FILE ");
|
||||
break;
|
||||
default:
|
||||
printf("OTHER\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if(finfo->filetype == CURLFILETYPE_FILE) {
|
||||
/* do not transfer files >= 50B */
|
||||
if(finfo->size > 50) {
|
||||
printf("SKIPPED\n");
|
||||
return CURL_CHUNK_BGN_FUNC_SKIP;
|
||||
}
|
||||
|
||||
data->output = fopen(finfo->filename, "w");
|
||||
if(!data->output) {
|
||||
return CURL_CHUNK_BGN_FUNC_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return CURL_CHUNK_BGN_FUNC_OK;
|
||||
}
|
||||
|
||||
static long file_is_downloaded(struct callback_data *data)
|
||||
{
|
||||
if(data->output) {
|
||||
printf("DOWNLOADED\n");
|
||||
fclose(data->output);
|
||||
data->output = 0x0;
|
||||
}
|
||||
return CURL_CHUNK_END_FUNC_OK;
|
||||
}
|
||||
|
||||
static size_t write_it(char *buff, size_t size, size_t nmemb,
|
||||
void *cb_data)
|
||||
{
|
||||
struct callback_data *data = cb_data;
|
||||
size_t written = 0;
|
||||
if(data->output)
|
||||
written = fwrite(buff, size, nmemb, data->output);
|
||||
else
|
||||
/* listing output */
|
||||
written = fwrite(buff, size, nmemb, stdout);
|
||||
return written;
|
||||
}
|
94
curl/docs/examples/ftpget.c
Normal file
94
curl/docs/examples/ftpget.c
Normal file
@ -0,0 +1,94 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* This is an example showing how to get a single file from an FTP server.
|
||||
* It delays the actual destination file creation until the first write
|
||||
* callback so that it won't create an empty file in case the remote file
|
||||
* doesn't exist or something else fails.
|
||||
*/
|
||||
|
||||
struct FtpFile {
|
||||
const char *filename;
|
||||
FILE *stream;
|
||||
};
|
||||
|
||||
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
struct FtpFile *out=(struct FtpFile *)stream;
|
||||
if(out && !out->stream) {
|
||||
/* open file for writing */
|
||||
out->stream=fopen(out->filename, "wb");
|
||||
if(!out->stream)
|
||||
return -1; /* failure, can't open file to write */
|
||||
}
|
||||
return fwrite(buffer, size, nmemb, out->stream);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct FtpFile ftpfile={
|
||||
"curl.tar.gz", /* name to store the file as if successful */
|
||||
NULL
|
||||
};
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/*
|
||||
* You better replace the URL with one that works!
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"ftp://ftp.example.com/pub/www/utilities/curl/curl-7.9.2.tar.gz");
|
||||
/* Define our callback to get called when there's data to be written */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
|
||||
/* Set a pointer to our struct to pass to the callback */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
|
||||
|
||||
/* Switch on full protocol/debug output */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(CURLE_OK != res) {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
if(ftpfile.stream)
|
||||
fclose(ftpfile.stream); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
89
curl/docs/examples/ftpgetinfo.c
Normal file
89
curl/docs/examples/ftpgetinfo.c
Normal file
@ -0,0 +1,89 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* This is an example showing how to check a single file's size and mtime
|
||||
* from an FTP server.
|
||||
*/
|
||||
|
||||
static size_t throw_away(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
(void)ptr;
|
||||
(void)data;
|
||||
/* we are not interested in the headers itself,
|
||||
so we only return the size we would have saved ... */
|
||||
return (size_t)(size * nmemb);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char ftpurl[] = "ftp://ftp.example.com/gnu/binutils/binutils-2.19.1.tar.bz2";
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
long filetime = -1;
|
||||
double filesize = 0.0;
|
||||
const char *filename = strrchr(ftpurl, '/') + 1;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, ftpurl);
|
||||
/* No download if the file */
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
||||
/* Ask for filetime */
|
||||
curl_easy_setopt(curl, CURLOPT_FILETIME, 1L);
|
||||
/* No header output: TODO 14.1 http-style HEAD output for ftp */
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, throw_away);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 0L);
|
||||
/* Switch on full protocol/debug output */
|
||||
/* curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); */
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(CURLE_OK == res) {
|
||||
/* http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html */
|
||||
res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
|
||||
if((CURLE_OK == res) && (filetime >= 0)) {
|
||||
time_t file_time = (time_t)filetime;
|
||||
printf("filetime %s: %s", filename, ctime(&file_time));
|
||||
}
|
||||
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize);
|
||||
if((CURLE_OK == res) && (filesize>0.0))
|
||||
printf("filesize %s: %0.0f bytes\n", filename, filesize);
|
||||
} else {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
76
curl/docs/examples/ftpgetresp.c
Normal file
76
curl/docs/examples/ftpgetresp.c
Normal file
@ -0,0 +1,76 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* Similar to ftpget.c but this also stores the received response-lines
|
||||
* in a separate file using our own callback!
|
||||
*
|
||||
* This functionality was introduced in libcurl 7.9.3.
|
||||
*/
|
||||
|
||||
static size_t
|
||||
write_response(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
FILE *writehere = (FILE *)data;
|
||||
return fwrite(ptr, size, nmemb, writehere);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *ftpfile;
|
||||
FILE *respfile;
|
||||
|
||||
/* local file name to store the file as */
|
||||
ftpfile = fopen("ftp-list", "wb"); /* b is binary, needed on win32 */
|
||||
|
||||
/* local file name to store the FTP server's response lines in */
|
||||
respfile = fopen("ftp-responses", "wb"); /* b is binary, needed on win32 */
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Get a file listing from sunet */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/");
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, ftpfile);
|
||||
/* If you intend to use this on windows with a libcurl DLL, you must use
|
||||
CURLOPT_WRITEFUNCTION as well */
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_response);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERDATA, respfile);
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
fclose(ftpfile); /* close the local file */
|
||||
fclose(respfile); /* close the response file */
|
||||
|
||||
return 0;
|
||||
}
|
101
curl/docs/examples/ftpsget.c
Normal file
101
curl/docs/examples/ftpsget.c
Normal file
@ -0,0 +1,101 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* This is an example showing how to get a single file from an FTPS server.
|
||||
* It delays the actual destination file creation until the first write
|
||||
* callback so that it won't create an empty file in case the remote file
|
||||
* doesn't exist or something else fails.
|
||||
*/
|
||||
|
||||
struct FtpFile {
|
||||
const char *filename;
|
||||
FILE *stream;
|
||||
};
|
||||
|
||||
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb,
|
||||
void *stream)
|
||||
{
|
||||
struct FtpFile *out=(struct FtpFile *)stream;
|
||||
if(out && !out->stream) {
|
||||
/* open file for writing */
|
||||
out->stream=fopen(out->filename, "wb");
|
||||
if(!out->stream)
|
||||
return -1; /* failure, can't open file to write */
|
||||
}
|
||||
return fwrite(buffer, size, nmemb, out->stream);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct FtpFile ftpfile={
|
||||
"yourfile.bin", /* name to store the file as if successful */
|
||||
NULL
|
||||
};
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/*
|
||||
* You better replace the URL with one that works! Note that we use an
|
||||
* FTP:// URL with standard explicit FTPS. You can also do FTPS:// URLs if
|
||||
* you want to do the rarer kind of transfers: implicit.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"ftp://user@server/home/user/file.txt");
|
||||
/* Define our callback to get called when there's data to be written */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
|
||||
/* Set a pointer to our struct to pass to the callback */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
|
||||
|
||||
/* We activate SSL and we require it for both control and data */
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
|
||||
|
||||
/* Switch on full protocol/debug output */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(CURLE_OK != res) {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
if(ftpfile.stream)
|
||||
fclose(ftpfile.stream); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
140
curl/docs/examples/ftpupload.c
Normal file
140
curl/docs/examples/ftpupload.c
Normal file
@ -0,0 +1,140 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This example shows an FTP upload, with a rename of the file just after
|
||||
* a successful upload.
|
||||
*
|
||||
* Example based on source code provided by Erick Nuwendam. Thanks!
|
||||
*/
|
||||
|
||||
#define LOCAL_FILE "/tmp/uploadthis.txt"
|
||||
#define UPLOAD_FILE_AS "while-uploading.txt"
|
||||
#define REMOTE_URL "ftp://example.com/" UPLOAD_FILE_AS
|
||||
#define RENAME_FILE_TO "renamed-and-fine.txt"
|
||||
|
||||
/* NOTE: if you want this example to work on Windows with libcurl as a
|
||||
DLL, you MUST also provide a read callback with CURLOPT_READFUNCTION.
|
||||
Failing to do so will give you a crash since a DLL may not use the
|
||||
variable's memory when passed in to it from an app like this. */
|
||||
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
curl_off_t nread;
|
||||
/* in real-world cases, this would probably get this data differently
|
||||
as this fread() stuff is exactly what the library already would do
|
||||
by default internally */
|
||||
size_t retcode = fread(ptr, size, nmemb, stream);
|
||||
|
||||
nread = (curl_off_t)retcode;
|
||||
|
||||
fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T
|
||||
" bytes from file\n", nread);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *hd_src;
|
||||
struct stat file_info;
|
||||
curl_off_t fsize;
|
||||
|
||||
struct curl_slist *headerlist=NULL;
|
||||
static const char buf_1 [] = "RNFR " UPLOAD_FILE_AS;
|
||||
static const char buf_2 [] = "RNTO " RENAME_FILE_TO;
|
||||
|
||||
/* get the file size of the local file */
|
||||
if(stat(LOCAL_FILE, &file_info)) {
|
||||
printf("Couldnt open '%s': %s\n", LOCAL_FILE, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
fsize = (curl_off_t)file_info.st_size;
|
||||
|
||||
printf("Local file size: %" CURL_FORMAT_CURL_OFF_T " bytes.\n", fsize);
|
||||
|
||||
/* get a FILE * of the same file */
|
||||
hd_src = fopen(LOCAL_FILE, "rb");
|
||||
|
||||
/* In windows, this will init the winsock stuff */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* build a list of commands to pass to libcurl */
|
||||
headerlist = curl_slist_append(headerlist, buf_1);
|
||||
headerlist = curl_slist_append(headerlist, buf_2);
|
||||
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* enable uploading */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* specify target */
|
||||
curl_easy_setopt(curl,CURLOPT_URL, REMOTE_URL);
|
||||
|
||||
/* pass in that last of FTP commands to run after the transfer */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
|
||||
|
||||
/* now specify which file to upload */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
|
||||
|
||||
/* Set the size of the file to upload (optional). If you give a *_LARGE
|
||||
option you MUST make sure that the type of the passed-in argument is a
|
||||
curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
|
||||
make sure that to pass in a type 'long' argument. */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)fsize);
|
||||
|
||||
/* Now run off and do what you've been told! */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* clean up the FTP commands list */
|
||||
curl_slist_free_all (headerlist);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
fclose(hd_src); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
174
curl/docs/examples/ftpuploadresume.c
Normal file
174
curl/docs/examples/ftpuploadresume.c
Normal file
@ -0,0 +1,174 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* Upload to FTP, resuming failed transfers
|
||||
*
|
||||
* Compile for MinGW like this:
|
||||
* gcc -Wall -pedantic -std=c99 ftpuploadwithresume.c -o ftpuploadresume.exe
|
||||
* -lcurl -lmsvcr70
|
||||
*
|
||||
* Written by Philip Bock
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1300)
|
||||
# error _snscanf requires MSVC 7.0 or later.
|
||||
#endif
|
||||
|
||||
/* The MinGW headers are missing a few Win32 function definitions,
|
||||
you shouldn't need this if you use VC++ */
|
||||
#if defined(__MINGW32__) && !defined(__MINGW64__)
|
||||
int __cdecl _snscanf(const char * input, size_t length, const char * format, ...);
|
||||
#endif
|
||||
|
||||
|
||||
/* parse headers for Content-Length */
|
||||
size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
int r;
|
||||
long len = 0;
|
||||
|
||||
/* _snscanf() is Win32 specific */
|
||||
r = _snscanf(ptr, size * nmemb, "Content-Length: %ld\n", &len);
|
||||
|
||||
if (r) /* Microsoft: we don't read the specs */
|
||||
*((long *) stream) = len;
|
||||
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
/* discard downloaded data */
|
||||
size_t discardfunc(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
/* read data to upload */
|
||||
size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
FILE *f = stream;
|
||||
size_t n;
|
||||
|
||||
if (ferror(f))
|
||||
return CURL_READFUNC_ABORT;
|
||||
|
||||
n = fread(ptr, size, nmemb, f) * size;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
|
||||
long timeout, long tries)
|
||||
{
|
||||
FILE *f;
|
||||
long uploaded_len = 0;
|
||||
CURLcode r = CURLE_GOT_NOTHING;
|
||||
int c;
|
||||
|
||||
f = fopen(localpath, "rb");
|
||||
if (f == NULL) {
|
||||
perror(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);
|
||||
|
||||
if (timeout)
|
||||
curl_easy_setopt(curlhandle, CURLOPT_FTP_RESPONSE_TIMEOUT, timeout);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &uploaded_len);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, discardfunc);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_READDATA, f);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_FTPPORT, "-"); /* disable passive mode */
|
||||
curl_easy_setopt(curlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
for (c = 0; (r != CURLE_OK) && (c < tries); c++) {
|
||||
/* are we resuming? */
|
||||
if (c) { /* yes */
|
||||
/* determine the length of the file already written */
|
||||
|
||||
/*
|
||||
* With NOBODY and NOHEADER, libcurl will issue a SIZE
|
||||
* command, but the only way to retrieve the result is
|
||||
* to parse the returned Content-Length header. Thus,
|
||||
* getcontentlengthfunc(). We need discardfunc() above
|
||||
* because HEADER will dump the headers to stdout
|
||||
* without it.
|
||||
*/
|
||||
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 1L);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HEADER, 1L);
|
||||
|
||||
r = curl_easy_perform(curlhandle);
|
||||
if (r != CURLE_OK)
|
||||
continue;
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 0L);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HEADER, 0L);
|
||||
|
||||
fseek(f, uploaded_len, SEEK_SET);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_APPEND, 1L);
|
||||
}
|
||||
else { /* no */
|
||||
curl_easy_setopt(curlhandle, CURLOPT_APPEND, 0L);
|
||||
}
|
||||
|
||||
r = curl_easy_perform(curlhandle);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
if (r == CURLE_OK)
|
||||
return 1;
|
||||
else {
|
||||
fprintf(stderr, "%s\n", curl_easy_strerror(r));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int c, char **argv)
|
||||
{
|
||||
CURL *curlhandle = NULL;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curlhandle = curl_easy_init();
|
||||
|
||||
upload(curlhandle, "ftp://user:pass@example.com/path/file", "C:\\file", 0, 3);
|
||||
|
||||
curl_easy_cleanup(curlhandle);
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
53
curl/docs/examples/getinfo.c
Normal file
53
curl/docs/examples/getinfo.c
Normal file
@ -0,0 +1,53 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
/* http://curl.haxx.se/libcurl/c/curl_easy_init.html */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTURL */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/");
|
||||
/* http://curl.haxx.se/libcurl/c/curl_easy_perform.html */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(CURLE_OK == res) {
|
||||
char *ct;
|
||||
/* ask for the content-type */
|
||||
/* http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html */
|
||||
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
|
||||
|
||||
if((CURLE_OK == res) && ct)
|
||||
printf("We received Content-Type: %s\n", ct);
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
/* http://curl.haxx.se/libcurl/c/curl_easy_cleanup.html */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
115
curl/docs/examples/getinmemory.c
Normal file
115
curl/docs/examples/getinmemory.c
Normal file
@ -0,0 +1,115 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* Example source code to show how the callback function can be used to
|
||||
* download data into a chunk of memory instead of storing it in a file.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
struct MemoryStruct {
|
||||
char *memory;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
|
||||
static size_t
|
||||
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
|
||||
|
||||
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
|
||||
if(mem->memory == NULL) {
|
||||
/* out of memory! */
|
||||
printf("not enough memory (realloc returned NULL)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&(mem->memory[mem->size]), contents, realsize);
|
||||
mem->size += realsize;
|
||||
mem->memory[mem->size] = 0;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl_handle;
|
||||
CURLcode res;
|
||||
|
||||
struct MemoryStruct chunk;
|
||||
|
||||
chunk.memory = malloc(1); /* will be grown as needed by the realloc above */
|
||||
chunk.size = 0; /* no data at this point */
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* init the curl session */
|
||||
curl_handle = curl_easy_init();
|
||||
|
||||
/* specify URL to get */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_URL, "http://www.example.com/");
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
|
||||
|
||||
/* we pass our 'chunk' struct to the callback function */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
|
||||
|
||||
/* some servers don't like requests that are made without a user-agent
|
||||
field, so we provide one */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
|
||||
|
||||
/* get it! */
|
||||
res = curl_easy_perform(curl_handle);
|
||||
|
||||
/* check for errors */
|
||||
if(res != CURLE_OK) {
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Now, our chunk.memory points to a memory block that is chunk.size
|
||||
* bytes big and contains the remote file.
|
||||
*
|
||||
* Do something nice with it!
|
||||
*/
|
||||
|
||||
printf("%lu bytes retrieved\n", (long)chunk.size);
|
||||
}
|
||||
|
||||
/* cleanup curl stuff */
|
||||
curl_easy_cleanup(curl_handle);
|
||||
|
||||
free(chunk.memory);
|
||||
|
||||
/* we're done with libcurl, so clean it up */
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
451
curl/docs/examples/ghiper.c
Normal file
451
curl/docs/examples/ghiper.c
Normal file
@ -0,0 +1,451 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* Example application source code using the multi socket interface to
|
||||
* download many files at once.
|
||||
*
|
||||
* Written by Jeff Pohlmeyer
|
||||
|
||||
Requires glib-2.x and a (POSIX?) system that has mkfifo().
|
||||
|
||||
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
|
||||
sample programs, adapted to use glib's g_io_channel in place of libevent.
|
||||
|
||||
When running, the program creates the named pipe "hiper.fifo"
|
||||
|
||||
Whenever there is input into the fifo, the program reads the input as a list
|
||||
of URL's and creates some new easy handles to fetch each URL via the
|
||||
curl_multi "hiper" API.
|
||||
|
||||
|
||||
Thus, you can try a single URL:
|
||||
% echo http://www.yahoo.com > hiper.fifo
|
||||
|
||||
Or a whole bunch of them:
|
||||
% cat my-url-list > hiper.fifo
|
||||
|
||||
The fifo buffer is handled almost instantly, so you can even add more URL's
|
||||
while the previous requests are still being downloaded.
|
||||
|
||||
This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
callback.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <glib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
#define MSG_OUT g_print /* Change to "g_error" to write to stderr */
|
||||
#define SHOW_VERBOSE 0 /* Set to non-zero for libcurl messages */
|
||||
#define SHOW_PROGRESS 0 /* Set to non-zero to enable progress callback */
|
||||
|
||||
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo {
|
||||
CURLM *multi;
|
||||
guint timer_event;
|
||||
int still_running;
|
||||
} GlobalInfo;
|
||||
|
||||
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo {
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific socket */
|
||||
typedef struct _SockInfo {
|
||||
curl_socket_t sockfd;
|
||||
CURL *easy;
|
||||
int action;
|
||||
long timeout;
|
||||
GIOChannel *ch;
|
||||
guint ev;
|
||||
GlobalInfo *global;
|
||||
} SockInfo;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(const char *where, CURLMcode code) {
|
||||
if ( CURLM_OK != code ) {
|
||||
const char *s;
|
||||
switch (code) {
|
||||
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
|
||||
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
|
||||
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
|
||||
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
|
||||
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET"; break;
|
||||
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
|
||||
case CURLM_LAST: s="CURLM_LAST"; break;
|
||||
default: s="CURLM_unknown";
|
||||
}
|
||||
MSG_OUT("ERROR: %s returns %s\n", where, s);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn;
|
||||
CURL *easy;
|
||||
CURLcode res;
|
||||
|
||||
MSG_OUT("REMAINING: %d\n", g->still_running);
|
||||
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
easy = msg->easy_handle;
|
||||
res = msg->data.result;
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
MSG_OUT("DONE: %s => (%d) %s\n", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by glib when our timeout expires */
|
||||
static gboolean timer_cb(gpointer data)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo *)data;
|
||||
CURLMcode rc;
|
||||
|
||||
rc = curl_multi_socket_action(g->multi,
|
||||
CURL_SOCKET_TIMEOUT, 0, &g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp)
|
||||
{
|
||||
struct timeval timeout;
|
||||
GlobalInfo *g=(GlobalInfo *)userp;
|
||||
timeout.tv_sec = timeout_ms/1000;
|
||||
timeout.tv_usec = (timeout_ms%1000)*1000;
|
||||
|
||||
MSG_OUT("*** update_timeout_cb %ld => %ld:%ld ***\n",
|
||||
timeout_ms, timeout.tv_sec, timeout.tv_usec);
|
||||
|
||||
g->timer_event = g_timeout_add(timeout_ms, timer_cb, g);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Called by glib when we get action on a multi socket */
|
||||
static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) data;
|
||||
CURLMcode rc;
|
||||
int fd=g_io_channel_unix_get_fd(ch);
|
||||
|
||||
int action =
|
||||
(condition & G_IO_IN ? CURL_CSELECT_IN : 0) |
|
||||
(condition & G_IO_OUT ? CURL_CSELECT_OUT : 0);
|
||||
|
||||
rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
|
||||
check_multi_info(g);
|
||||
if(g->still_running) {
|
||||
return TRUE;
|
||||
} else {
|
||||
MSG_OUT("last transfer done, kill timeout\n");
|
||||
if (g->timer_event) { g_source_remove(g->timer_event); }
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(SockInfo *f)
|
||||
{
|
||||
if (!f) { return; }
|
||||
if (f->ev) { g_source_remove(f->ev); }
|
||||
g_free(f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Assign information to a SockInfo structure */
|
||||
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
|
||||
{
|
||||
GIOCondition kind =
|
||||
(act&CURL_POLL_IN?G_IO_IN:0)|(act&CURL_POLL_OUT?G_IO_OUT:0);
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
f->easy = e;
|
||||
if (f->ev) { g_source_remove(f->ev); }
|
||||
f->ev=g_io_add_watch(f->ch, kind, event_cb,g);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize a new SockInfo structure */
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
|
||||
{
|
||||
SockInfo *fdp = g_malloc0(sizeof(SockInfo));
|
||||
|
||||
fdp->global = g;
|
||||
fdp->ch=g_io_channel_unix_new(s);
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
SockInfo *fdp = (SockInfo*) sockp;
|
||||
static const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
|
||||
|
||||
MSG_OUT("socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
if (what == CURL_POLL_REMOVE) {
|
||||
MSG_OUT("\n");
|
||||
remsock(fdp);
|
||||
} else {
|
||||
if (!fdp) {
|
||||
MSG_OUT("Adding data: %s%s\n",
|
||||
what&CURL_POLL_IN?"READ":"",
|
||||
what&CURL_POLL_OUT?"WRITE":"" );
|
||||
addsock(s, e, what, g);
|
||||
}
|
||||
else {
|
||||
MSG_OUT(
|
||||
"Changing action from %d to %d\n", fdp->action, what);
|
||||
setsock(fdp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
ConnInfo *conn = (ConnInfo*) data;
|
||||
(void)ptr;
|
||||
(void)conn;
|
||||
return realsize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
static int prog_cb (void *p, double dltotal, double dlnow, double ult, double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
MSG_OUT("Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
static void new_conn(char *url, GlobalInfo *g )
|
||||
{
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = g_malloc0(sizeof(ConnInfo));
|
||||
|
||||
conn->error[0]='\0';
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
if (!conn->easy) {
|
||||
MSG_OUT("curl_easy_init() failed, exiting!\n");
|
||||
exit(2);
|
||||
}
|
||||
conn->global = g;
|
||||
conn->url = g_strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, (long)SHOW_VERBOSE);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, SHOW_PROGRESS?0L:1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_CONNECTTIMEOUT, 30L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30L);
|
||||
|
||||
MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc =curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
|
||||
/* note that the add_handle() will set a time-out to trigger very soon so
|
||||
that the necessary socket_action() call will be called by this app */
|
||||
}
|
||||
|
||||
|
||||
/* This gets called by glib whenever data is received from the fifo */
|
||||
static gboolean fifo_cb (GIOChannel *ch, GIOCondition condition, gpointer data)
|
||||
{
|
||||
#define BUF_SIZE 1024
|
||||
gsize len, tp;
|
||||
gchar *buf, *tmp, *all=NULL;
|
||||
GIOStatus rv;
|
||||
|
||||
do {
|
||||
GError *err=NULL;
|
||||
rv = g_io_channel_read_line (ch,&buf,&len,&tp,&err);
|
||||
if ( buf ) {
|
||||
if (tp) { buf[tp]='\0'; }
|
||||
new_conn(buf,(GlobalInfo*)data);
|
||||
g_free(buf);
|
||||
} else {
|
||||
buf = g_malloc(BUF_SIZE+1);
|
||||
while (TRUE) {
|
||||
buf[BUF_SIZE]='\0';
|
||||
g_io_channel_read_chars(ch,buf,BUF_SIZE,&len,&err);
|
||||
if (len) {
|
||||
buf[len]='\0';
|
||||
if (all) {
|
||||
tmp=all;
|
||||
all=g_strdup_printf("%s%s", tmp, buf);
|
||||
g_free(tmp);
|
||||
} else {
|
||||
all = g_strdup(buf);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (all) {
|
||||
new_conn(all,(GlobalInfo*)data);
|
||||
g_free(all);
|
||||
}
|
||||
g_free(buf);
|
||||
}
|
||||
if ( err ) {
|
||||
g_error("fifo_cb: %s", err->message);
|
||||
g_free(err);
|
||||
break;
|
||||
}
|
||||
} while ( (len) && (rv == G_IO_STATUS_NORMAL) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int init_fifo(void)
|
||||
{
|
||||
struct stat st;
|
||||
const char *fifo = "hiper.fifo";
|
||||
int socket;
|
||||
|
||||
if (lstat (fifo, &st) == 0) {
|
||||
if ((st.st_mode & S_IFMT) == S_IFREG) {
|
||||
errno = EEXIST;
|
||||
perror("lstat");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
unlink (fifo);
|
||||
if (mkfifo (fifo, 0600) == -1) {
|
||||
perror("mkfifo");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
socket = open (fifo, O_RDWR | O_NONBLOCK, 0);
|
||||
|
||||
if (socket == -1) {
|
||||
perror("open");
|
||||
exit (1);
|
||||
}
|
||||
MSG_OUT("Now, pipe some URL's into > %s\n", fifo);
|
||||
|
||||
return socket;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo *g;
|
||||
CURLMcode rc;
|
||||
GMainLoop*gmain;
|
||||
int fd;
|
||||
GIOChannel* ch;
|
||||
g=g_malloc0(sizeof(GlobalInfo));
|
||||
|
||||
fd=init_fifo();
|
||||
ch=g_io_channel_unix_new(fd);
|
||||
g_io_add_watch(ch,G_IO_IN,fifo_cb,g);
|
||||
gmain=g_main_loop_new(NULL,FALSE);
|
||||
g->multi = curl_multi_init();
|
||||
curl_multi_setopt(g->multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g->multi, CURLMOPT_SOCKETDATA, g);
|
||||
curl_multi_setopt(g->multi, CURLMOPT_TIMERFUNCTION, update_timeout_cb);
|
||||
curl_multi_setopt(g->multi, CURLMOPT_TIMERDATA, g);
|
||||
|
||||
/* we don't call any curl_multi_socket*() function yet as we have no handles
|
||||
added! */
|
||||
|
||||
g_main_loop_run(gmain);
|
||||
curl_multi_cleanup(g->multi);
|
||||
return 0;
|
||||
}
|
435
curl/docs/examples/hiperfifo.c
Normal file
435
curl/docs/examples/hiperfifo.c
Normal file
@ -0,0 +1,435 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* Example application source code using the multi socket interface to
|
||||
download many files at once.
|
||||
|
||||
Written by Jeff Pohlmeyer
|
||||
|
||||
Requires libevent version 2 and a (POSIX?) system that has mkfifo().
|
||||
|
||||
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
|
||||
sample programs.
|
||||
|
||||
When running, the program creates the named pipe "hiper.fifo"
|
||||
|
||||
Whenever there is input into the fifo, the program reads the input as a list
|
||||
of URL's and creates some new easy handles to fetch each URL via the
|
||||
curl_multi "hiper" API.
|
||||
|
||||
|
||||
Thus, you can try a single URL:
|
||||
% echo http://www.yahoo.com > hiper.fifo
|
||||
|
||||
Or a whole bunch of them:
|
||||
% cat my-url-list > hiper.fifo
|
||||
|
||||
The fifo buffer is handled almost instantly, so you can even add more URL's
|
||||
while the previous requests are still being downloaded.
|
||||
|
||||
Note:
|
||||
For the sake of simplicity, URL length is limited to 1023 char's !
|
||||
|
||||
This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
callback.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/poll.h>
|
||||
#include <curl/curl.h>
|
||||
#include <event2/event.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
|
||||
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo
|
||||
{
|
||||
struct event_base *evbase;
|
||||
struct event *fifo_event;
|
||||
struct event *timer_event;
|
||||
CURLM *multi;
|
||||
int still_running;
|
||||
FILE* input;
|
||||
} GlobalInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo
|
||||
{
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific socket */
|
||||
typedef struct _SockInfo
|
||||
{
|
||||
curl_socket_t sockfd;
|
||||
CURL *easy;
|
||||
int action;
|
||||
long timeout;
|
||||
struct event *ev;
|
||||
int evset;
|
||||
GlobalInfo *global;
|
||||
} SockInfo;
|
||||
|
||||
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
|
||||
{
|
||||
struct timeval timeout;
|
||||
(void)multi; /* unused */
|
||||
|
||||
timeout.tv_sec = timeout_ms/1000;
|
||||
timeout.tv_usec = (timeout_ms%1000)*1000;
|
||||
fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
|
||||
evtimer_add(g->timer_event, &timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(const char *where, CURLMcode code)
|
||||
{
|
||||
if ( CURLM_OK != code ) {
|
||||
const char *s;
|
||||
switch (code) {
|
||||
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
|
||||
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
|
||||
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
|
||||
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
|
||||
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
|
||||
case CURLM_LAST: s="CURLM_LAST"; break;
|
||||
default: s="CURLM_unknown";
|
||||
break;
|
||||
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET";
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
/* ignore this error */
|
||||
return;
|
||||
}
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn;
|
||||
CURL *easy;
|
||||
CURLcode res;
|
||||
|
||||
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
|
||||
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
easy = msg->easy_handle;
|
||||
res = msg->data.result;
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by libevent when we get action on a multi socket */
|
||||
static void event_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) userp;
|
||||
CURLMcode rc;
|
||||
|
||||
int action =
|
||||
(kind & EV_READ ? CURL_CSELECT_IN : 0) |
|
||||
(kind & EV_WRITE ? CURL_CSELECT_OUT : 0);
|
||||
|
||||
rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
|
||||
check_multi_info(g);
|
||||
if ( g->still_running <= 0 ) {
|
||||
fprintf(MSG_OUT, "last transfer done, kill timeout\n");
|
||||
if (evtimer_pending(g->timer_event, NULL)) {
|
||||
evtimer_del(g->timer_event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by libevent when our timeout expires */
|
||||
static void timer_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo *)userp;
|
||||
CURLMcode rc;
|
||||
(void)fd;
|
||||
(void)kind;
|
||||
|
||||
rc = curl_multi_socket_action(g->multi,
|
||||
CURL_SOCKET_TIMEOUT, 0, &g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(SockInfo *f)
|
||||
{
|
||||
if (f) {
|
||||
if (f->evset)
|
||||
event_free(f->ev);
|
||||
free(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Assign information to a SockInfo structure */
|
||||
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
|
||||
{
|
||||
int kind =
|
||||
(act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0)|EV_PERSIST;
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
f->easy = e;
|
||||
if (f->evset)
|
||||
event_free(f->ev);
|
||||
f->ev = event_new(g->evbase, f->sockfd, kind, event_cb, g);
|
||||
f->evset = 1;
|
||||
event_add(f->ev, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize a new SockInfo structure */
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
|
||||
{
|
||||
SockInfo *fdp = calloc(sizeof(SockInfo), 1);
|
||||
|
||||
fdp->global = g;
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
SockInfo *fdp = (SockInfo*) sockp;
|
||||
const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
if (what == CURL_POLL_REMOVE) {
|
||||
fprintf(MSG_OUT, "\n");
|
||||
remsock(fdp);
|
||||
}
|
||||
else {
|
||||
if (!fdp) {
|
||||
fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]);
|
||||
addsock(s, e, what, g);
|
||||
}
|
||||
else {
|
||||
fprintf(MSG_OUT,
|
||||
"Changing action from %s to %s\n",
|
||||
whatstr[fdp->action], whatstr[what]);
|
||||
setsock(fdp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
ConnInfo *conn = (ConnInfo*) data;
|
||||
(void)ptr;
|
||||
(void)conn;
|
||||
return realsize;
|
||||
}
|
||||
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
static int prog_cb (void *p, double dltotal, double dlnow, double ult,
|
||||
double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
(void)ult;
|
||||
(void)uln;
|
||||
|
||||
fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
static void new_conn(char *url, GlobalInfo *g )
|
||||
{
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = calloc(1, sizeof(ConnInfo));
|
||||
memset(conn, 0, sizeof(ConnInfo));
|
||||
conn->error[0]='\0';
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
if (!conn->easy) {
|
||||
fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
|
||||
exit(2);
|
||||
}
|
||||
conn->global = g;
|
||||
conn->url = strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
fprintf(MSG_OUT,
|
||||
"Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc = curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
|
||||
/* note that the add_handle() will set a time-out to trigger very soon so
|
||||
that the necessary socket_action() call will be called by this app */
|
||||
}
|
||||
|
||||
/* This gets called whenever data is received from the fifo */
|
||||
static void fifo_cb(int fd, short event, void *arg)
|
||||
{
|
||||
char s[1024];
|
||||
long int rv=0;
|
||||
int n=0;
|
||||
GlobalInfo *g = (GlobalInfo *)arg;
|
||||
(void)fd; /* unused */
|
||||
(void)event; /* unused */
|
||||
|
||||
do {
|
||||
s[0]='\0';
|
||||
rv=fscanf(g->input, "%1023s%n", s, &n);
|
||||
s[n]='\0';
|
||||
if ( n && s[0] ) {
|
||||
new_conn(s,arg); /* if we read a URL, go get it! */
|
||||
} else break;
|
||||
} while ( rv != EOF);
|
||||
}
|
||||
|
||||
/* Create a named pipe and tell libevent to monitor it */
|
||||
static const char *fifo = "hiper.fifo";
|
||||
static int init_fifo (GlobalInfo *g)
|
||||
{
|
||||
struct stat st;
|
||||
curl_socket_t sockfd;
|
||||
|
||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||
if (lstat (fifo, &st) == 0) {
|
||||
if ((st.st_mode & S_IFMT) == S_IFREG) {
|
||||
errno = EEXIST;
|
||||
perror("lstat");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
unlink(fifo);
|
||||
if (mkfifo (fifo, 0600) == -1) {
|
||||
perror("mkfifo");
|
||||
exit (1);
|
||||
}
|
||||
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||
if (sockfd == -1) {
|
||||
perror("open");
|
||||
exit (1);
|
||||
}
|
||||
g->input = fdopen(sockfd, "r");
|
||||
|
||||
fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo);
|
||||
g->fifo_event = event_new(g->evbase, sockfd, EV_READ|EV_PERSIST, fifo_cb, g);
|
||||
event_add(g->fifo_event, NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void clean_fifo(GlobalInfo *g)
|
||||
{
|
||||
event_free(g->fifo_event);
|
||||
fclose(g->input);
|
||||
unlink(fifo);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo g;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
memset(&g, 0, sizeof(GlobalInfo));
|
||||
g.evbase = event_base_new();
|
||||
init_fifo(&g);
|
||||
g.multi = curl_multi_init();
|
||||
g.timer_event = evtimer_new(g.evbase, timer_cb, &g);
|
||||
|
||||
/* setup the generic multi interface options we want */
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
|
||||
|
||||
/* we don't call any curl_multi_socket*() function yet as we have no handles
|
||||
added! */
|
||||
|
||||
event_base_dispatch(g.evbase);
|
||||
|
||||
/* this, of course, won't get called since only way to stop this program is
|
||||
via ctrl-C, but it is here to show how cleanup /would/ be done. */
|
||||
clean_fifo(&g);
|
||||
event_free(g.timer_event);
|
||||
event_base_free(g.evbase);
|
||||
curl_multi_cleanup(g.multi);
|
||||
return 0;
|
||||
}
|
86
curl/docs/examples/href_extractor.c
Normal file
86
curl/docs/examples/href_extractor.c
Normal file
@ -0,0 +1,86 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* This example uses the "Streaming HTML parser" to extract the href pieces in
|
||||
* a streaming manner from a downloaded HTML. Kindly donated by Michał
|
||||
* Kowalczyk.
|
||||
*
|
||||
* The parser is found at
|
||||
* http://code.google.com/p/htmlstreamparser/
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
#include <htmlstreamparser.h>
|
||||
|
||||
|
||||
static size_t write_callback(void *buffer, size_t size, size_t nmemb,
|
||||
void *hsp)
|
||||
{
|
||||
size_t realsize = size * nmemb, p;
|
||||
for (p = 0; p < realsize; p++) {
|
||||
html_parser_char_parse(hsp, ((char *)buffer)[p]);
|
||||
if (html_parser_cmp_tag(hsp, "a", 1))
|
||||
if (html_parser_cmp_attr(hsp, "href", 4))
|
||||
if (html_parser_is_in(hsp, HTML_VALUE_ENDED)) {
|
||||
html_parser_val(hsp)[html_parser_val_length(hsp)] = '\0';
|
||||
printf("%s\n", html_parser_val(hsp));
|
||||
}
|
||||
}
|
||||
return realsize;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char tag[1], attr[4], val[128];
|
||||
CURL *curl;
|
||||
HTMLSTREAMPARSER *hsp;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s URL\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
curl = curl_easy_init();
|
||||
|
||||
hsp = html_parser_init();
|
||||
|
||||
html_parser_set_tag_to_lower(hsp, 1);
|
||||
html_parser_set_attr_to_lower(hsp, 1);
|
||||
html_parser_set_tag_buffer(hsp, tag, sizeof(tag));
|
||||
html_parser_set_attr_buffer(hsp, attr, sizeof(attr));
|
||||
html_parser_set_val_buffer(hsp, val, sizeof(val)-1);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, hsp);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
|
||||
curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
html_parser_cleanup(hsp);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
130
curl/docs/examples/htmltidy.c
Normal file
130
curl/docs/examples/htmltidy.c
Normal file
@ -0,0 +1,130 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/* Download a document and use libtidy to parse the HTML.
|
||||
* Written by Jeff Pohlmeyer
|
||||
*
|
||||
* LibTidy => http://tidy.sourceforge.net
|
||||
*
|
||||
* gcc -Wall -I/usr/local/include tidycurl.c -lcurl -ltidy -o tidycurl
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tidy/tidy.h>
|
||||
#include <tidy/buffio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* curl write callback, to fill tidy's input buffer... */
|
||||
uint write_cb(char *in, uint size, uint nmemb, TidyBuffer *out)
|
||||
{
|
||||
uint r;
|
||||
r = size * nmemb;
|
||||
tidyBufAppend( out, in, r );
|
||||
return(r);
|
||||
}
|
||||
|
||||
/* Traverse the document tree */
|
||||
void dumpNode(TidyDoc doc, TidyNode tnod, int indent )
|
||||
{
|
||||
TidyNode child;
|
||||
for ( child = tidyGetChild(tnod); child; child = tidyGetNext(child) )
|
||||
{
|
||||
ctmbstr name = tidyNodeGetName( child );
|
||||
if ( name )
|
||||
{
|
||||
/* if it has a name, then it's an HTML tag ... */
|
||||
TidyAttr attr;
|
||||
printf( "%*.*s%s ", indent, indent, "<", name);
|
||||
/* walk the attribute list */
|
||||
for ( attr=tidyAttrFirst(child); attr; attr=tidyAttrNext(attr) ) {
|
||||
printf(tidyAttrName(attr));
|
||||
tidyAttrValue(attr)?printf("=\"%s\" ",
|
||||
tidyAttrValue(attr)):printf(" ");
|
||||
}
|
||||
printf( ">\n");
|
||||
}
|
||||
else {
|
||||
/* if it doesn't have a name, then it's probably text, cdata, etc... */
|
||||
TidyBuffer buf;
|
||||
tidyBufInit(&buf);
|
||||
tidyNodeGetText(doc, child, &buf);
|
||||
printf("%*.*s\n", indent, indent, buf.bp?(char *)buf.bp:"");
|
||||
tidyBufFree(&buf);
|
||||
}
|
||||
dumpNode( doc, child, indent + 4 ); /* recursive */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv )
|
||||
{
|
||||
CURL *curl;
|
||||
char curl_errbuf[CURL_ERROR_SIZE];
|
||||
TidyDoc tdoc;
|
||||
TidyBuffer docbuf = {0};
|
||||
TidyBuffer tidy_errbuf = {0};
|
||||
int err;
|
||||
if ( argc == 2) {
|
||||
curl = curl_easy_init();
|
||||
curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
|
||||
tdoc = tidyCreate();
|
||||
tidyOptSetBool(tdoc, TidyForceOutput, yes); /* try harder */
|
||||
tidyOptSetInt(tdoc, TidyWrapLen, 4096);
|
||||
tidySetErrorBuffer( tdoc, &tidy_errbuf );
|
||||
tidyBufInit(&docbuf);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &docbuf);
|
||||
err=curl_easy_perform(curl);
|
||||
if ( !err ) {
|
||||
err = tidyParseBuffer(tdoc, &docbuf); /* parse the input */
|
||||
if ( err >= 0 ) {
|
||||
err = tidyCleanAndRepair(tdoc); /* fix any problems */
|
||||
if ( err >= 0 ) {
|
||||
err = tidyRunDiagnostics(tdoc); /* load tidy error buffer */
|
||||
if ( err >= 0 ) {
|
||||
dumpNode( tdoc, tidyGetRoot(tdoc), 0 ); /* walk the tree */
|
||||
fprintf(stderr, "%s\n", tidy_errbuf.bp); /* show errors */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "%s\n", curl_errbuf);
|
||||
|
||||
/* clean-up */
|
||||
curl_easy_cleanup(curl);
|
||||
tidyBufFree(&docbuf);
|
||||
tidyBufFree(&tidy_errbuf);
|
||||
tidyRelease(tdoc);
|
||||
return(err);
|
||||
|
||||
}
|
||||
else
|
||||
printf( "usage: %s <url>\n", argv[0] );
|
||||
|
||||
return(0);
|
||||
}
|
313
curl/docs/examples/htmltitle.cpp
Normal file
313
curl/docs/examples/htmltitle.cpp
Normal file
@ -0,0 +1,313 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
// Get a web page, parse it with libxml.
|
||||
//
|
||||
// Written by Lars Nilsson
|
||||
//
|
||||
// GNU C++ compile command line suggestion (edit paths accordingly):
|
||||
//
|
||||
// g++ -Wall -I/opt/curl/include -I/opt/libxml/include/libxml2 htmltitle.cpp \
|
||||
// -o htmltitle -L/opt/curl/lib -L/opt/libxml/lib -lcurl -lxml2
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <curl/curl.h>
|
||||
#include <libxml/HTMLparser.h>
|
||||
|
||||
//
|
||||
// Case-insensitive string comparison
|
||||
//
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define COMPARE(a, b) (!stricmp((a), (b)))
|
||||
#else
|
||||
#define COMPARE(a, b) (!strcasecmp((a), (b)))
|
||||
#endif
|
||||
|
||||
//
|
||||
// libxml callback context structure
|
||||
//
|
||||
|
||||
struct Context
|
||||
{
|
||||
Context(): addTitle(false) { }
|
||||
|
||||
bool addTitle;
|
||||
std::string title;
|
||||
};
|
||||
|
||||
//
|
||||
// libcurl variables for error strings and returned data
|
||||
|
||||
static char errorBuffer[CURL_ERROR_SIZE];
|
||||
static std::string buffer;
|
||||
|
||||
//
|
||||
// libcurl write callback function
|
||||
//
|
||||
|
||||
static int writer(char *data, size_t size, size_t nmemb,
|
||||
std::string *writerData)
|
||||
{
|
||||
if (writerData == NULL)
|
||||
return 0;
|
||||
|
||||
writerData->append(data, size*nmemb);
|
||||
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
//
|
||||
// libcurl connection initialization
|
||||
//
|
||||
|
||||
static bool init(CURL *&conn, char *url)
|
||||
{
|
||||
CURLcode code;
|
||||
|
||||
conn = curl_easy_init();
|
||||
|
||||
if (conn == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to create CURL connection\n");
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set error buffer [%d]\n", code);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_URL, url);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set URL [%s]\n", errorBuffer);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, &buffer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// libxml start element callback function
|
||||
//
|
||||
|
||||
static void StartElement(void *voidContext,
|
||||
const xmlChar *name,
|
||||
const xmlChar **attributes)
|
||||
{
|
||||
Context *context = (Context *)voidContext;
|
||||
|
||||
if (COMPARE((char *)name, "TITLE"))
|
||||
{
|
||||
context->title = "";
|
||||
context->addTitle = true;
|
||||
}
|
||||
(void) attributes;
|
||||
}
|
||||
|
||||
//
|
||||
// libxml end element callback function
|
||||
//
|
||||
|
||||
static void EndElement(void *voidContext,
|
||||
const xmlChar *name)
|
||||
{
|
||||
Context *context = (Context *)voidContext;
|
||||
|
||||
if (COMPARE((char *)name, "TITLE"))
|
||||
context->addTitle = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Text handling helper function
|
||||
//
|
||||
|
||||
static void handleCharacters(Context *context,
|
||||
const xmlChar *chars,
|
||||
int length)
|
||||
{
|
||||
if (context->addTitle)
|
||||
context->title.append((char *)chars, length);
|
||||
}
|
||||
|
||||
//
|
||||
// libxml PCDATA callback function
|
||||
//
|
||||
|
||||
static void Characters(void *voidContext,
|
||||
const xmlChar *chars,
|
||||
int length)
|
||||
{
|
||||
Context *context = (Context *)voidContext;
|
||||
|
||||
handleCharacters(context, chars, length);
|
||||
}
|
||||
|
||||
//
|
||||
// libxml CDATA callback function
|
||||
//
|
||||
|
||||
static void cdata(void *voidContext,
|
||||
const xmlChar *chars,
|
||||
int length)
|
||||
{
|
||||
Context *context = (Context *)voidContext;
|
||||
|
||||
handleCharacters(context, chars, length);
|
||||
}
|
||||
|
||||
//
|
||||
// libxml SAX callback structure
|
||||
//
|
||||
|
||||
static htmlSAXHandler saxHandler =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
StartElement,
|
||||
EndElement,
|
||||
NULL,
|
||||
Characters,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
cdata,
|
||||
NULL
|
||||
};
|
||||
|
||||
//
|
||||
// Parse given (assumed to be) HTML text and return the title
|
||||
//
|
||||
|
||||
static void parseHtml(const std::string &html,
|
||||
std::string &title)
|
||||
{
|
||||
htmlParserCtxtPtr ctxt;
|
||||
Context context;
|
||||
|
||||
ctxt = htmlCreatePushParserCtxt(&saxHandler, &context, "", 0, "",
|
||||
XML_CHAR_ENCODING_NONE);
|
||||
|
||||
htmlParseChunk(ctxt, html.c_str(), html.size(), 0);
|
||||
htmlParseChunk(ctxt, "", 0, 1);
|
||||
|
||||
htmlFreeParserCtxt(ctxt);
|
||||
|
||||
title = context.title;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CURL *conn = NULL;
|
||||
CURLcode code;
|
||||
std::string title;
|
||||
|
||||
// Ensure one argument is given
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <url>\n", argv[0]);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
// Initialize CURL connection
|
||||
|
||||
if (!init(conn, argv[1]))
|
||||
{
|
||||
fprintf(stderr, "Connection initializion failed\n");
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Retrieve content for the URL
|
||||
|
||||
code = curl_easy_perform(conn);
|
||||
curl_easy_cleanup(conn);
|
||||
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to get '%s' [%s]\n", argv[1], errorBuffer);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Parse the (assumed) HTML code
|
||||
|
||||
parseHtml(buffer, title);
|
||||
|
||||
// Display the extracted title
|
||||
|
||||
printf("Title: %s\n", title.c_str());
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user