aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstephanie sappho lenzo <sappho@sappho.io>2023-07-13 06:11:48 -0400
committerstephanie sappho lenzo <sappho@sappho.io>2023-07-13 06:11:48 -0400
commitd643bdb4bd5cda1bed5c8de79de456782c785dff (patch)
tree014d40ad802c2495ee36212be40dab75c623d754
inital commit
-rw-r--r--.hgignore1
-rw-r--r--Makefile113
-rw-r--r--curl/curl.h2179
-rw-r--r--curl/curlbuild.h583
-rw-r--r--curl/curlrules.h261
-rw-r--r--curl/curlver.h69
-rw-r--r--curl/easy.h102
-rw-r--r--curl/mprintf.h81
-rw-r--r--curl/multi.h345
-rw-r--r--curl/stdcheaders.h33
-rw-r--r--curl/typecheck-gcc.h603
-rw-r--r--curlmanager.cpp897
-rw-r--r--curlmanager.h48
-rw-r--r--curlthread.cpp315
-rw-r--r--curlthread.h49
-rw-r--r--define.h177
-rw-r--r--extension.cpp172
-rw-r--r--extension.h43
-rw-r--r--lib/libcrypto.abin0 -> 2328762 bytes
-rw-r--r--lib/libcurl.abin0 -> 497622 bytes
-rw-r--r--lib/libcurl.libbin0 -> 6169770 bytes
-rw-r--r--lib/libcurld.libbin0 -> 7805426 bytes
-rw-r--r--lib/libssh2.abin0 -> 894528 bytes
-rw-r--r--lib/libssl.abin0 -> 413464 bytes
-rw-r--r--lib/libz.abin0 -> 98906 bytes
-rw-r--r--natives.cpp598
-rw-r--r--opensslmanager.cpp362
-rw-r--r--opensslmanager.h23
-rw-r--r--opensslthread.cpp100
-rw-r--r--opensslthread.h29
-rw-r--r--sdk/smsdk_config.h83
-rw-r--r--sdk/smsdk_ext.cpp465
-rw-r--r--sdk/smsdk_ext.h339
33 files changed, 8070 insertions, 0 deletions
diff --git a/.hgignore b/.hgignore
new file mode 100644
index 0000000..fd66f07
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1 @@
+relre:msvc8
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5f017f6
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,113 @@
+# (C)2004-2008 SourceMod Development Team
+# Makefile written by David "BAILOPAN" Anderson
+
+SMSDK = ../..
+SRCDS_BASE = ~/srcds
+MMSOURCE17 = ../../../mmsource-central
+
+#####################################
+### EDIT BELOW FOR OTHER PROJECTS ###
+#####################################
+
+PROJECT = curl
+
+#Uncomment for Metamod: Source enabled extension
+USEMETA = false
+
+OBJECTS = \
+ sdk/smsdk_ext.cpp \
+ extension.cpp \
+ curlmanager.cpp \
+ curlthread.cpp \
+ natives.cpp \
+ opensslmanager.cpp \
+ opensslthread.cpp
+
+##############################################
+### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
+##############################################
+
+C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
+C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
+C_GCC4_FLAGS = -fvisibility=hidden
+CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
+CPP = gcc
+
+
+METAMOD = $(MMSOURCE17)/core-legacy
+
+INCLUDE += -I. -I.. -Isdk -I../ \
+ -I$(METAMOD)/sourcehook -I$(SMSDK)/public -I$(SMSDK)/public/extensions \
+ -I$(SMSDK)/public/sourcepawn \
+ -I/opt/Source/lib/openssl/include \
+
+CFLAGS += -DSE_EPISODEONE=1 -DSE_DARKMESSIAH=2 -DSE_ORANGEBOX=3 -DSE_ORANGEBOXVALVE=4 -DSE_LEFT4DEAD=5 -DSE_LEFT4DEAD2=6
+
+CFLAGS += -DCURL_STATIC_LIB
+
+LINK += -L./lib -lcurl -lrt -lssh2 -lssl -lcrypto -lz
+
+LINK += -m32 -ldl -lm
+
+CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
+ -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror -Wno-switch \
+ -Wno-unused -mfpmath=sse -msse -DSOURCEMOD_BUILD -DHAVE_STDINT_H -m32
+
+CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti -fno-threadsafe-statics
+
+################################################
+### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
+################################################
+
+ifeq "$(DEBUG)" "true"
+ BIN_DIR = Debug
+ CFLAGS += $(C_DEBUG_FLAGS)
+else
+ BIN_DIR = Release
+ CFLAGS += $(C_OPT_FLAGS)
+endif
+
+ifeq "$(USEMETA)" "true"
+ BIN_DIR := $(BIN_DIR).$(ENGINE)
+endif
+
+OS := $(shell uname -s)
+ifeq "$(OS)" "Darwin"
+ LINK += -dynamiclib
+ BINARY = $(PROJECT).ext.dylib
+else
+ LINK += -static-libgcc -shared
+ BINARY = $(PROJECT).ext.so
+endif
+
+GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
+ifeq "$(GCC_VERSION)" "4"
+ CFLAGS += $(C_GCC4_FLAGS)
+ CPPFLAGS += $(CPP_GCC4_FLAGS)
+endif
+
+OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
+
+$(BIN_DIR)/%.o: %.cpp
+ $(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
+
+all: check
+ mkdir -p $(BIN_DIR)/sdk
+
+ $(MAKE) -f Makefile extension
+
+check:
+
+
+extension: check $(OBJ_LINUX)
+ $(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -o $(BIN_DIR)/$(BINARY)
+
+debug:
+ $(MAKE) -f Makefile all DEBUG=true
+
+default: all
+
+clean: check
+ rm -rf $(BIN_DIR)/*.o
+ rm -rf $(BIN_DIR)/sdk/*.o
+ rm -rf $(BIN_DIR)/$(BINARY)
diff --git a/curl/curl.h b/curl/curl.h
new file mode 100644
index 0000000..f4aa17f
--- /dev/null
+++ b/curl/curl.h
@@ -0,0 +1,2179 @@
+#ifndef __CURL_CURL_H
+#define __CURL_CURL_H
+/***************************************************************************
+ * _ _ ____ _
+ * 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.
+ *
+ ***************************************************************************/
+
+/*
+ * If you have libcurl problems, all docs and details are found here:
+ * http://curl.haxx.se/libcurl/
+ *
+ * curl-library mailing list subscription and unsubscription web interface:
+ * http://cool.haxx.se/mailman/listinfo/curl-library/
+ */
+
+#include "curlver.h" /* libcurl version defines */
+#include "curlbuild.h" /* libcurl build definitions */
+#include "curlrules.h" /* libcurl rules enforcement */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && \
+ !defined(WIN32) && !defined(__SYMBIAN32__)
+#define WIN32
+#endif
+
+#include <stdio.h>
+#include <limits.h>
+
+#if defined(__FreeBSD__) && (__FreeBSD__ >= 2)
+/* Needed for __FreeBSD_version symbol definition */
+#include <osreldate.h>
+#endif
+
+/* The include stuff here below is mainly for time_t! */
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__)
+#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || defined(__LWIP_OPT_H__))
+/* The check above prevents the winsock2 inclusion if winsock.h already was
+ included, since they can't co-exist without problems */
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
+#endif
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+ libc5-based Linux systems. Only include it on systems that are known to
+ require it! */
+#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
+ defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
+ defined(ANDROID) || \
+ (defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
+#include <sys/select.h>
+#endif
+
+#if !defined(WIN32) && !defined(_WIN32_WCE)
+#include <sys/socket.h>
+#endif
+
+#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
+#include <sys/time.h>
+#endif
+
+#ifdef __BEOS__
+#include <support/SupportDefs.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void CURL;
+
+/*
+ * Decorate exportable functions for Win32 and Symbian OS DLL linking.
+ * This avoids using a .def file for building libcurl.dll.
+ */
+#if (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) && \
+ !defined(CURL_STATICLIB)
+#if defined(BUILDING_LIBCURL)
+#define CURL_EXTERN __declspec(dllexport)
+#else
+#define CURL_EXTERN __declspec(dllimport)
+#endif
+#else
+
+#ifdef CURL_HIDDEN_SYMBOLS
+/*
+ * This definition is used to make external definitions visible in the
+ * shared library when symbols are hidden by default. It makes no
+ * difference when compiling applications whether this is set or not,
+ * only when compiling the library.
+ */
+#define CURL_EXTERN CURL_EXTERN_SYMBOL
+#else
+#define CURL_EXTERN
+#endif
+#endif
+
+#ifndef curl_socket_typedef
+/* socket typedef */
+#if defined(WIN32) && !defined(__LWIP_OPT_H__)
+typedef SOCKET curl_socket_t;
+#define CURL_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int curl_socket_t;
+#define CURL_SOCKET_BAD -1
+#endif
+#define curl_socket_typedef
+#endif /* curl_socket_typedef */
+
+struct curl_httppost {
+ struct curl_httppost *next; /* next entry in the list */
+ char *name; /* pointer to allocated name */
+ long namelength; /* length of name length */
+ char *contents; /* pointer to allocated data contents */
+ long contentslength; /* length of contents field */
+ char *buffer; /* pointer to allocated buffer contents */
+ long bufferlength; /* length of buffer field */
+ char *contenttype; /* Content-Type */
+ struct curl_slist* contentheader; /* list of extra headers for this form */
+ struct curl_httppost *more; /* if one field name has more than one
+ file, this link should link to following
+ files */
+ long flags; /* as defined below */
+#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
+#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */
+#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer
+ do not free in formfree */
+#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
+ do not free in formfree */
+#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
+#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
+#define HTTPPOST_CALLBACK (1<<6) /* upload file contents by using the
+ regular read callback to get the data
+ and pass the given pointer as custom
+ pointer */
+
+ char *showfilename; /* The file name to show. If not set, the
+ actual file name will be used (if this
+ is a file part) */
+ void *userp; /* custom pointer used for
+ HTTPPOST_CALLBACK posts */
+};
+
+typedef int (*curl_progress_callback)(void *clientp,
+ double dltotal,
+ double dlnow,
+ double ultotal,
+ double ulnow);
+
+#ifndef CURL_MAX_WRITE_SIZE
+ /* Tests have proven that 20K is a very bad buffer size for uploads on
+ Windows, while 16K for some odd reason performed a lot better.
+ We do the ifndef check to allow this value to easier be changed at build
+ time for those who feel adventurous. The practical minimum is about
+ 400 bytes since libcurl uses a buffer of this size as a scratch area
+ (unrelated to network send operations). */
+#define CURL_MAX_WRITE_SIZE 16384
+#endif
+
+#ifndef CURL_MAX_HTTP_HEADER
+/* The only reason to have a max limit for this is to avoid the risk of a bad
+ server feeding libcurl with a never-ending header that will cause reallocs
+ infinitely */
+#define CURL_MAX_HTTP_HEADER (100*1024)
+#endif
+
+/* This is a magic return code for the write callback that, when returned,
+ will signal libcurl to pause receiving on the current transfer. */
+#define CURL_WRITEFUNC_PAUSE 0x10000001
+
+typedef size_t (*curl_write_callback)(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *outstream);
+
+
+
+/* enumeration of file types */
+typedef enum {
+ CURLFILETYPE_FILE = 0,
+ CURLFILETYPE_DIRECTORY,
+ CURLFILETYPE_SYMLINK,
+ CURLFILETYPE_DEVICE_BLOCK,
+ CURLFILETYPE_DEVICE_CHAR,
+ CURLFILETYPE_NAMEDPIPE,
+ CURLFILETYPE_SOCKET,
+ CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */
+
+ CURLFILETYPE_UNKNOWN /* should never occur */
+} curlfiletype;
+
+#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0)
+#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1)
+#define CURLFINFOFLAG_KNOWN_TIME (1<<2)
+#define CURLFINFOFLAG_KNOWN_PERM (1<<3)
+#define CURLFINFOFLAG_KNOWN_UID (1<<4)
+#define CURLFINFOFLAG_KNOWN_GID (1<<5)
+#define CURLFINFOFLAG_KNOWN_SIZE (1<<6)
+#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7)
+
+/* Content of this structure depends on information which is known and is
+ achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man
+ page for callbacks returning this structure -- some fields are mandatory,
+ some others are optional. The FLAG field has special meaning. */
+struct curl_fileinfo {
+ char *filename;
+ curlfiletype filetype;
+ time_t time;
+ unsigned int perm;
+ int uid;
+ int gid;
+ curl_off_t size;
+ long int hardlinks;
+
+ struct {
+ /* If some of these fields is not NULL, it is a pointer to b_data. */
+ char *time;
+ char *perm;
+ char *user;
+ char *group;
+ char *target; /* pointer to the target filename of a symlink */
+ } strings;
+
+ unsigned int flags;
+
+ /* used internally */
+ char * b_data;
+ size_t b_size;
+ size_t b_used;
+};
+
+/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */
+#define CURL_CHUNK_BGN_FUNC_OK 0
+#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */
+#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */
+
+/* if splitting of data transfer is enabled, this callback is called before
+ download of an individual chunk started. Note that parameter "remains" works
+ only for FTP wildcard downloading (for now), otherwise is not used */
+typedef long (*curl_chunk_bgn_callback)(const void *transfer_info,
+ void *ptr,
+ int remains);
+
+/* return codes for CURLOPT_CHUNK_END_FUNCTION */
+#define CURL_CHUNK_END_FUNC_OK 0
+#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */
+
+/* If splitting of data transfer is enabled this callback is called after
+ download of an individual chunk finished.
+ Note! After this callback was set then it have to be called FOR ALL chunks.
+ Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC.
+ This is the reason why we don't need "transfer_info" parameter in this
+ callback and we are not interested in "remains" parameter too. */
+typedef long (*curl_chunk_end_callback)(void *ptr);
+
+/* return codes for FNMATCHFUNCTION */
+#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */
+#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */
+#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */
+
+/* callback type for wildcard downloading pattern matching. If the
+ string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */
+typedef int (*curl_fnmatch_callback)(void *ptr,
+ const char *pattern,
+ const char *string);
+
+/* These are the return codes for the seek callbacks */
+#define CURL_SEEKFUNC_OK 0
+#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */
+#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so
+ libcurl might try other means instead */
+typedef int (*curl_seek_callback)(void *instream,
+ curl_off_t offset,
+ int origin); /* 'whence' */
+
+/* This is a return code for the read callback that, when returned, will
+ signal libcurl to immediately abort the current transfer. */
+#define CURL_READFUNC_ABORT 0x10000000
+/* This is a return code for the read callback that, when returned, will
+ signal libcurl to pause sending data on the current transfer. */
+#define CURL_READFUNC_PAUSE 0x10000001
+
+typedef size_t (*curl_read_callback)(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *instream);
+
+typedef enum {
+ CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
+ CURLSOCKTYPE_LAST /* never use */
+} curlsocktype;
+
+/* The return code from the sockopt_callback can signal information back
+ to libcurl: */
+#define CURL_SOCKOPT_OK 0
+#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return
+ CURLE_ABORTED_BY_CALLBACK */
+#define CURL_SOCKOPT_ALREADY_CONNECTED 2
+
+typedef int (*curl_sockopt_callback)(void *clientp,
+ curl_socket_t curlfd,
+ curlsocktype purpose);
+
+struct curl_sockaddr {
+ int family;
+ int socktype;
+ int protocol;
+ unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it
+ turned really ugly and painful on the systems that
+ lack this type */
+ struct sockaddr addr;
+};
+
+typedef curl_socket_t
+(*curl_opensocket_callback)(void *clientp,
+ curlsocktype purpose,
+ struct curl_sockaddr *address);
+
+typedef int
+(*curl_closesocket_callback)(void *clientp, curl_socket_t item);
+
+typedef enum {
+ CURLIOE_OK, /* I/O operation successful */
+ CURLIOE_UNKNOWNCMD, /* command was unknown to callback */
+ CURLIOE_FAILRESTART, /* failed to restart the read */
+ CURLIOE_LAST /* never use */
+} curlioerr;
+
+typedef enum {
+ CURLIOCMD_NOP, /* no operation */
+ CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
+ CURLIOCMD_LAST /* never use */
+} curliocmd;
+
+typedef curlioerr (*curl_ioctl_callback)(CURL *handle,
+ int cmd,
+ void *clientp);
+
+/*
+ * The following typedef's are signatures of malloc, free, realloc, strdup and
+ * calloc respectively. Function pointers of these types can be passed to the
+ * curl_global_init_mem() function to set user defined memory management
+ * callback routines.
+ */
+typedef void *(*curl_malloc_callback)(size_t size);
+typedef void (*curl_free_callback)(void *ptr);
+typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
+typedef char *(*curl_strdup_callback)(const char *str);
+typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
+
+/* the kind of data that is passed to information_callback*/
+typedef enum {
+ CURLINFO_TEXT = 0,
+ CURLINFO_HEADER_IN, /* 1 */
+ CURLINFO_HEADER_OUT, /* 2 */
+ CURLINFO_DATA_IN, /* 3 */
+ CURLINFO_DATA_OUT, /* 4 */
+ CURLINFO_SSL_DATA_IN, /* 5 */
+ CURLINFO_SSL_DATA_OUT, /* 6 */
+ CURLINFO_END
+} curl_infotype;
+
+typedef int (*curl_debug_callback)
+ (CURL *handle, /* the handle/transfer this concerns */
+ curl_infotype type, /* what kind of data */
+ char *data, /* points to the data */
+ size_t size, /* size of the data pointed to */
+ void *userptr); /* whatever the user please */
+
+/* All possible error codes from all sorts of curl functions. Future versions
+ may return other values, stay prepared.
+
+ Always add new return codes last. Never *EVER* remove any. The return
+ codes must remain the same!
+ */
+
+typedef enum {
+ CURLE_OK = 0,
+ CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
+ CURLE_FAILED_INIT, /* 2 */
+ CURLE_URL_MALFORMAT, /* 3 */
+ CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for
+ 7.17.0, reused in April 2011 for 7.21.5] */
+ CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
+ CURLE_COULDNT_RESOLVE_HOST, /* 6 */
+ CURLE_COULDNT_CONNECT, /* 7 */
+ CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */
+ CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server
+ due to lack of access - when login fails
+ this is not returned. */
+ CURLE_OBSOLETE10, /* 10 - NOT USED */
+ CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
+ CURLE_OBSOLETE12, /* 12 - NOT USED */
+ CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
+ CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
+ CURLE_FTP_CANT_GET_HOST, /* 15 */
+ CURLE_OBSOLETE16, /* 16 - NOT USED */
+ CURLE_FTP_COULDNT_SET_TYPE, /* 17 */
+ CURLE_PARTIAL_FILE, /* 18 */
+ CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
+ CURLE_OBSOLETE20, /* 20 - NOT USED */
+ CURLE_QUOTE_ERROR, /* 21 - quote command failure */
+ CURLE_HTTP_RETURNED_ERROR, /* 22 */
+ CURLE_WRITE_ERROR, /* 23 */
+ CURLE_OBSOLETE24, /* 24 - NOT USED */
+ CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */
+ CURLE_READ_ERROR, /* 26 - couldn't open/read from file */
+ CURLE_OUT_OF_MEMORY, /* 27 */
+ /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
+ instead of a memory allocation error if CURL_DOES_CONVERSIONS
+ is defined
+ */
+ CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */
+ CURLE_OBSOLETE29, /* 29 - NOT USED */
+ CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
+ CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */
+ CURLE_OBSOLETE32, /* 32 - NOT USED */
+ CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */
+ CURLE_HTTP_POST_ERROR, /* 34 */
+ CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */
+ CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */
+ CURLE_FILE_COULDNT_READ_FILE, /* 37 */
+ CURLE_LDAP_CANNOT_BIND, /* 38 */
+ CURLE_LDAP_SEARCH_FAILED, /* 39 */
+ CURLE_OBSOLETE40, /* 40 - NOT USED */
+ CURLE_FUNCTION_NOT_FOUND, /* 41 */
+ CURLE_ABORTED_BY_CALLBACK, /* 42 */
+ CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */
+ CURLE_OBSOLETE44, /* 44 - NOT USED */
+ CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */
+ CURLE_OBSOLETE46, /* 46 - NOT USED */
+ CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */
+ CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */
+ CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */
+ CURLE_OBSOLETE50, /* 50 - NOT USED */
+ CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint
+ wasn't verified fine */
+ CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
+ CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */
+ CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as
+ default */
+ CURLE_SEND_ERROR, /* 55 - failed sending network data */
+ CURLE_RECV_ERROR, /* 56 - failure in receiving network data */
+ CURLE_OBSOLETE57, /* 57 - NOT IN USE */
+ CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */
+ CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */
+ CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */
+ CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */
+ CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */
+ CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */
+ CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */
+ CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind
+ that failed */
+ CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */
+ CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not
+ accepted and we failed to login */
+ CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */
+ CURLE_TFTP_PERM, /* 69 - permission problem on server */
+ CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */
+ CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */
+ CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
+ CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */
+ CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
+ CURLE_CONV_FAILED, /* 75 - conversion failed */
+ CURLE_CONV_REQD, /* 76 - caller must register conversion
+ callbacks using curl_easy_setopt options
+ CURLOPT_CONV_FROM_NETWORK_FUNCTION,
+ CURLOPT_CONV_TO_NETWORK_FUNCTION, and
+ CURLOPT_CONV_FROM_UTF8_FUNCTION */
+ CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
+ or wrong format */
+ CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */
+ CURLE_SSH, /* 79 - error from the SSH layer, somewhat
+ generic so the error message will be of
+ interest when this has happened */
+
+ CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
+ connection */
+ CURLE_AGAIN, /* 81 - socket is not ready for send/recv,
+ wait till it's ready and try again (Added
+ in 7.18.2) */
+ CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or
+ wrong format (Added in 7.19.0) */
+ CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in
+ 7.19.0) */
+ CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */
+ CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */
+ CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */
+ CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */
+ CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
+
+ CURL_LAST /* never use! */
+} CURLcode;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* compatibility with older names */
+#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
+
+/* The following were added in 7.21.5, April 2011 */
+#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
+
+/* The following were added in 7.17.1 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION
+
+/* The following were added in 7.17.0 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */
+#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46
+#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44
+#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10
+#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16
+#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32
+#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29
+#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12
+#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20
+#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40
+#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24
+#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57
+#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN
+
+#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED
+#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE
+#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR
+#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL
+#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS
+#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR
+#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED
+
+/* The following were added earlier */
+
+#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT
+
+#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
+#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
+#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED
+
+#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
+#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
+
+/* This was the error code 50 in 7.7.3 and a few earlier versions, this
+ is no longer used by libcurl but is instead #defined here only to not
+ make programs break */
+#define CURLE_ALREADY_COMPLETE 99999
+
+#endif /*!CURL_NO_OLDIES*/
+
+/* This prototype applies to all conversion callbacks */
+typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
+
+typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
+ void *ssl_ctx, /* actually an
+ OpenSSL SSL_CTX */
+ void *userptr);
+
+typedef enum {
+ CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use
+ CONNECT HTTP/1.1 */
+ CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT
+ HTTP/1.0 */
+ CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
+ in 7.10 */
+ CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
+ CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */
+ CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the
+ host name rather than the IP address. added
+ in 7.18.0 */
+} curl_proxytype; /* this enum was added in 7.10 */
+
+#define CURLAUTH_NONE 0 /* nothing */
+#define CURLAUTH_BASIC (1<<0) /* Basic (default) */
+#define CURLAUTH_DIGEST (1<<1) /* Digest */
+#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */
+#define CURLAUTH_NTLM (1<<3) /* NTLM */
+#define CURLAUTH_DIGEST_IE (1<<4) /* Digest with IE flavour */
+#define CURLAUTH_NTLM_WB (1<<5) /* NTLM delegating to winbind helper */
+#define CURLAUTH_ONLY (1<<31) /* used together with a single other
+ type to force no auth or just that
+ single type */
+#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) /* all fine types set */
+#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
+
+#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */
+#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */
+#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
+#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */
+#define CURLSSH_AUTH_HOST (1<<2) /* host key files */
+#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */
+#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
+
+#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */
+#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */
+#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */
+
+#define CURL_ERROR_SIZE 256
+
+struct curl_khkey {
+ const char *key; /* points to a zero-terminated string encoded with base64
+ if len is zero, otherwise to the "raw" data */
+ size_t len;
+ enum type {
+ CURLKHTYPE_UNKNOWN,
+ CURLKHTYPE_RSA1,
+ CURLKHTYPE_RSA,
+ CURLKHTYPE_DSS
+ } keytype;
+};
+
+/* this is the set of return values expected from the curl_sshkeycallback
+ callback */
+enum curl_khstat {
+ CURLKHSTAT_FINE_ADD_TO_FILE,
+ CURLKHSTAT_FINE,
+ CURLKHSTAT_REJECT, /* reject the connection, return an error */
+ CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so
+ this causes a CURLE_DEFER error but otherwise the
+ connection will be left intact etc */
+ CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */
+};
+
+/* this is the set of status codes pass in to the callback */
+enum curl_khmatch {
+ CURLKHMATCH_OK, /* match */
+ CURLKHMATCH_MISMATCH, /* host found, key mismatch! */
+ CURLKHMATCH_MISSING, /* no matching host/key found */
+ CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */
+};
+
+typedef int
+ (*curl_sshkeycallback) (CURL *easy, /* easy handle */
+ const struct curl_khkey *knownkey, /* known */
+ const struct curl_khkey *foundkey, /* found */
+ enum curl_khmatch, /* libcurl's view on the keys */
+ void *clientp); /* custom pointer passed from app */
+
+/* parameter for the CURLOPT_USE_SSL option */
+typedef enum {
+ CURLUSESSL_NONE, /* do not attempt to use SSL */
+ CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */
+ CURLUSESSL_CONTROL, /* SSL for the control connection or fail */
+ CURLUSESSL_ALL, /* SSL for all communication or fail */
+ CURLUSESSL_LAST /* not an option, never use */
+} curl_usessl;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2009 */
+
+#define CURLFTPSSL_NONE CURLUSESSL_NONE
+#define CURLFTPSSL_TRY CURLUSESSL_TRY
+#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL
+#define CURLFTPSSL_ALL CURLUSESSL_ALL
+#define CURLFTPSSL_LAST CURLUSESSL_LAST
+#define curl_ftpssl curl_usessl
+#endif /*!CURL_NO_OLDIES*/
+
+/* parameter for the CURLOPT_FTP_SSL_CCC option */
+typedef enum {
+ CURLFTPSSL_CCC_NONE, /* do not send CCC */
+ CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
+ CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */
+ CURLFTPSSL_CCC_LAST /* not an option, never use */
+} curl_ftpccc;
+
+/* parameter for the CURLOPT_FTPSSLAUTH option */
+typedef enum {
+ CURLFTPAUTH_DEFAULT, /* let libcurl decide */
+ CURLFTPAUTH_SSL, /* use "AUTH SSL" */
+ CURLFTPAUTH_TLS, /* use "AUTH TLS" */
+ CURLFTPAUTH_LAST /* not an option, never use */
+} curl_ftpauth;
+
+/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
+typedef enum {
+ CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */
+ CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD
+ again if MKD succeeded, for SFTP this does
+ similar magic */
+ CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
+ again even if MKD failed! */
+ CURLFTP_CREATE_DIR_LAST /* not an option, never use */
+} curl_ftpcreatedir;
+
+/* parameter for the CURLOPT_FTP_FILEMETHOD option */
+typedef enum {
+ CURLFTPMETHOD_DEFAULT, /* let libcurl pick */
+ CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */
+ CURLFTPMETHOD_NOCWD, /* no CWD at all */
+ CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
+ CURLFTPMETHOD_LAST /* not an option, never use */
+} curl_ftpmethod;
+
+/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+#define CURLPROTO_HTTP (1<<0)
+#define CURLPROTO_HTTPS (1<<1)
+#define CURLPROTO_FTP (1<<2)
+#define CURLPROTO_FTPS (1<<3)
+#define CURLPROTO_SCP (1<<4)
+#define CURLPROTO_SFTP (1<<5)
+#define CURLPROTO_TELNET (1<<6)
+#define CURLPROTO_LDAP (1<<7)
+#define CURLPROTO_LDAPS (1<<8)
+#define CURLPROTO_DICT (1<<9)
+#define CURLPROTO_FILE (1<<10)
+#define CURLPROTO_TFTP (1<<11)
+#define CURLPROTO_IMAP (1<<12)
+#define CURLPROTO_IMAPS (1<<13)
+#define CURLPROTO_POP3 (1<<14)
+#define CURLPROTO_POP3S (1<<15)
+#define CURLPROTO_SMTP (1<<16)
+#define CURLPROTO_SMTPS (1<<17)
+#define CURLPROTO_RTSP (1<<18)
+#define CURLPROTO_RTMP (1<<19)
+#define CURLPROTO_RTMPT (1<<20)
+#define CURLPROTO_RTMPE (1<<21)
+#define CURLPROTO_RTMPTE (1<<22)
+#define CURLPROTO_RTMPS (1<<23)
+#define CURLPROTO_RTMPTS (1<<24)
+#define CURLPROTO_GOPHER (1<<25)
+#define CURLPROTO_ALL (~0) /* enable everything */
+
+/* long may be 32 or 64 bits, but we should never depend on anything else
+ but 32 */
+#define CURLOPTTYPE_LONG 0
+#define CURLOPTTYPE_OBJECTPOINT 10000
+#define CURLOPTTYPE_FUNCTIONPOINT 20000
+#define CURLOPTTYPE_OFF_T 30000
+
+/* name is uppercase CURLOPT_<name>,
+ type is one of the defined CURLOPTTYPE_<type>
+ number is unique identifier */
+#ifdef CINIT
+#undef CINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG CURLOPTTYPE_LONG
+#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLOPT_/**/name = type + number
+#endif
+
+/*
+ * This macro-mania below setups the CURLOPT_[what] enum, to be used with
+ * curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
+ * word.
+ */
+
+typedef enum {
+ /* This is the FILE * or void * the regular output should be written to. */
+ CINIT(FILE, OBJECTPOINT, 1),
+
+ /* The full URL to get/put */
+ CINIT(URL, OBJECTPOINT, 2),
+
+ /* Port number to connect to, if other than default. */
+ CINIT(PORT, LONG, 3),
+
+ /* Name of proxy to use. */
+ CINIT(PROXY, OBJECTPOINT, 4),
+
+ /* "name:password" to use when fetching. */
+ CINIT(USERPWD, OBJECTPOINT, 5),
+
+ /* "name:password" to use with proxy. */
+ CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
+
+ /* Range to get, specified as an ASCII string. */
+ CINIT(RANGE, OBJECTPOINT, 7),
+
+ /* not used */
+
+ /* Specified file stream to upload from (use as input): */
+ CINIT(INFILE, OBJECTPOINT, 9),
+
+ /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
+ * bytes big. If this is not used, error messages go to stderr instead: */
+ CINIT(ERRORBUFFER, OBJECTPOINT, 10),
+
+ /* Function that will be called to store the output (instead of fwrite). The
+ * parameters will use fwrite() syntax, make sure to follow them. */
+ CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
+
+ /* Function that will be called to read the input (instead of fread). The
+ * parameters will use fread() syntax, make sure to follow them. */
+ CINIT(READFUNCTION, FUNCTIONPOINT, 12),
+
+ /* Time-out the read operation after this amount of seconds */
+ CINIT(TIMEOUT, LONG, 13),
+
+ /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
+ * how large the file being sent really is. That allows better error
+ * checking and better verifies that the upload was successful. -1 means
+ * unknown size.
+ *
+ * For large file support, there is also a _LARGE version of the key
+ * which takes an off_t type, allowing platforms with larger off_t
+ * sizes to handle larger files. See below for INFILESIZE_LARGE.
+ */
+ CINIT(INFILESIZE, LONG, 14),
+
+ /* POST static input fields. */
+ CINIT(POSTFIELDS, OBJECTPOINT, 15),
+
+ /* Set the referrer page (needed by some CGIs) */
+ CINIT(REFERER, OBJECTPOINT, 16),
+
+ /* Set the FTP PORT string (interface name, named or numerical IP address)
+ Use i.e '-' to use default address. */
+ CINIT(FTPPORT, OBJECTPOINT, 17),
+
+ /* Set the User-Agent string (examined by some CGIs) */
+ CINIT(USERAGENT, OBJECTPOINT, 18),
+
+ /* If the download receives less than "low speed limit" bytes/second
+ * during "low speed time" seconds, the operations is aborted.
+ * You could i.e if you have a pretty high speed connection, abort if
+ * it is less than 2000 bytes/sec during 20 seconds.
+ */
+
+ /* Set the "low speed limit" */
+ CINIT(LOW_SPEED_LIMIT, LONG, 19),
+
+ /* Set the "low speed time" */
+ CINIT(LOW_SPEED_TIME, LONG, 20),
+
+ /* Set the continuation offset.
+ *
+ * Note there is also a _LARGE version of this key which uses
+ * off_t types, allowing for large file offsets on platforms which
+ * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE.
+ */
+ CINIT(RESUME_FROM, LONG, 21),
+
+ /* Set cookie in request: */
+ CINIT(COOKIE, OBJECTPOINT, 22),
+
+ /* This points to a linked list of headers, struct curl_slist kind */
+ CINIT(HTTPHEADER, OBJECTPOINT, 23),
+
+ /* This points to a linked list of post entries, struct curl_httppost */
+ CINIT(HTTPPOST, OBJECTPOINT, 24),
+
+ /* name of the file keeping your private SSL-certificate */
+ CINIT(SSLCERT, OBJECTPOINT, 25),
+
+ /* password for the SSL or SSH private key */
+ CINIT(KEYPASSWD, OBJECTPOINT, 26),
+
+ /* send TYPE parameter? */
+ CINIT(CRLF, LONG, 27),
+
+ /* send linked-list of QUOTE commands */
+ CINIT(QUOTE, OBJECTPOINT, 28),
+
+ /* send FILE * or void * to store headers to, if you use a callback it
+ is simply passed to the callback unmodified */
+ CINIT(WRITEHEADER, OBJECTPOINT, 29),
+
+ /* point to a file to read the initial cookies from, also enables
+ "cookie awareness" */
+ CINIT(COOKIEFILE, OBJECTPOINT, 31),
+
+ /* What version to specifically try to use.
+ See CURL_SSLVERSION defines below. */
+ CINIT(SSLVERSION, LONG, 32),
+
+ /* What kind of HTTP time condition to use, see defines */
+ CINIT(TIMECONDITION, LONG, 33),
+
+ /* Time to use with the above condition. Specified in number of seconds
+ since 1 Jan 1970 */
+ CINIT(TIMEVALUE, LONG, 34),
+
+ /* 35 = OBSOLETE */
+
+ /* Custom request, for customizing the get command like
+ HTTP: DELETE, TRACE and others
+ FTP: to use a different list command
+ */
+ CINIT(CUSTOMREQUEST, OBJECTPOINT, 36),
+
+ /* HTTP request, for odd commands like DELETE, TRACE and others */
+ CINIT(STDERR, OBJECTPOINT, 37),
+
+ /* 38 is not used */
+
+ /* send linked-list of post-transfer QUOTE commands */
+ CINIT(POSTQUOTE, OBJECTPOINT, 39),
+
+ CINIT(WRITEINFO, OBJECTPOINT, 40), /* DEPRECATED, do not use! */
+
+ CINIT(VERBOSE, LONG, 41), /* talk a lot */
+ CINIT(HEADER, LONG, 42), /* throw the header out too */
+ CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
+ CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */
+ CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */
+ CINIT(UPLOAD, LONG, 46), /* this is an upload */
+ CINIT(POST, LONG, 47), /* HTTP POST method */
+ CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */
+
+ CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */
+
+ /* Specify whether to read the user+password from the .netrc or the URL.
+ * This must be one of the CURL_NETRC_* enums below. */
+ CINIT(NETRC, LONG, 51),
+
+ CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */
+
+ CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
+ CINIT(PUT, LONG, 54), /* HTTP PUT */
+
+ /* 55 = OBSOLETE */
+
+ /* Function that will be called instead of the internal progress display
+ * function. This function should be defined as the curl_progress_callback
+ * prototype defines. */
+ CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
+
+ /* Data passed to the progress callback */
+ CINIT(PROGRESSDATA, OBJECTPOINT, 57),
+
+ /* We want the referrer field set automatically when following locations */
+ CINIT(AUTOREFERER, LONG, 58),
+
+ /* Port of the proxy, can be set in the proxy string as well with:
+ "[host]:[port]" */
+ CINIT(PROXYPORT, LONG, 59),
+
+ /* size of the POST input data, if strlen() is not good to use */
+ CINIT(POSTFIELDSIZE, LONG, 60),
+
+ /* tunnel non-http operations through a HTTP proxy */
+ CINIT(HTTPPROXYTUNNEL, LONG, 61),
+
+ /* Set the interface string to use as outgoing network interface */
+ CINIT(INTERFACE, OBJECTPOINT, 62),
+
+ /* Set the krb4/5 security level, this also enables krb4/5 awareness. This
+ * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string
+ * is set but doesn't match one of these, 'private' will be used. */
+ CINIT(KRBLEVEL, OBJECTPOINT, 63),
+
+ /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
+ CINIT(SSL_VERIFYPEER, LONG, 64),
+
+ /* The CApath or CAfile used to validate the peer certificate
+ this option is used only if SSL_VERIFYPEER is true */
+ CINIT(CAINFO, OBJECTPOINT, 65),
+
+ /* 66 = OBSOLETE */
+ /* 67 = OBSOLETE */
+
+ /* Maximum number of http redirects to follow */
+ CINIT(MAXREDIRS, LONG, 68),
+
+ /* Pass a long set to 1 to get the date of the requested document (if
+ possible)! Pass a zero to shut it off. */
+ CINIT(FILETIME, LONG, 69),
+
+ /* This points to a linked list of telnet options */
+ CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
+
+ /* Max amount of cached alive connections */
+ CINIT(MAXCONNECTS, LONG, 71),
+
+ CINIT(CLOSEPOLICY, LONG, 72), /* DEPRECATED, do not use! */
+
+ /* 73 = OBSOLETE */
+
+ /* Set to explicitly use a new connection for the upcoming transfer.
+ Do not use this unless you're absolutely sure of this, as it makes the
+ operation slower and is less friendly for the network. */
+ CINIT(FRESH_CONNECT, LONG, 74),
+
+ /* Set to explicitly forbid the upcoming transfer's connection to be re-used
+ when done. Do not use this unless you're absolutely sure of this, as it
+ makes the operation slower and is less friendly for the network. */
+ CINIT(FORBID_REUSE, LONG, 75),
+
+ /* Set to a file name that contains random data for libcurl to use to
+ seed the random engine when doing SSL connects. */
+ CINIT(RANDOM_FILE, OBJECTPOINT, 76),
+
+ /* Set to the Entropy Gathering Daemon socket pathname */
+ CINIT(EGDSOCKET, OBJECTPOINT, 77),
+
+ /* Time-out connect operations after this amount of seconds, if connects
+ are OK within this time, then fine... This only aborts the connect
+ phase. [Only works on unix-style/SIGALRM operating systems] */
+ CINIT(CONNECTTIMEOUT, LONG, 78),
+
+ /* Function that will be called to store headers (instead of fwrite). The
+ * parameters will use fwrite() syntax, make sure to follow them. */
+ CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
+
+ /* Set this to force the HTTP request to get back to GET. Only really usable
+ if POST, PUT or a custom request have been used first.
+ */
+ CINIT(HTTPGET, LONG, 80),
+
+ /* Set if we should verify the Common name from the peer certificate in ssl
+ * handshake, set 1 to check existence, 2 to ensure that it matches the
+ * provided hostname. */
+ CINIT(SSL_VERIFYHOST, LONG, 81),
+
+ /* Specify which file name to write all known cookies in after completed
+ operation. Set file name to "-" (dash) to make it go to stdout. */
+ CINIT(COOKIEJAR, OBJECTPOINT, 82),
+
+ /* Specify which SSL ciphers to use */
+ CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83),
+
+ /* Specify which HTTP version to use! This must be set to one of the
+ CURL_HTTP_VERSION* enums set below. */
+ CINIT(HTTP_VERSION, LONG, 84),
+
+ /* Specifically switch on or off the FTP engine's use of the EPSV command. By
+ default, that one will always be attempted before the more traditional
+ PASV command. */
+ CINIT(FTP_USE_EPSV, LONG, 85),
+
+ /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
+ CINIT(SSLCERTTYPE, OBJECTPOINT, 86),
+
+ /* name of the file keeping your private SSL-key */
+ CINIT(SSLKEY, OBJECTPOINT, 87),
+
+ /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
+ CINIT(SSLKEYTYPE, OBJECTPOINT, 88),
+
+ /* crypto engine for the SSL-sub system */
+ CINIT(SSLENGINE, OBJECTPOINT, 89),
+
+ /* set the crypto engine for the SSL-sub system as default
+ the param has no meaning...
+ */
+ CINIT(SSLENGINE_DEFAULT, LONG, 90),
+
+ /* Non-zero value means to use the global dns cache */
+ CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */
+
+ /* DNS cache timeout */
+ CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
+
+ /* send linked-list of pre-transfer QUOTE commands */
+ CINIT(PREQUOTE, OBJECTPOINT, 93),
+
+ /* set the debug function */
+ CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),
+
+ /* set the data for the debug function */
+ CINIT(DEBUGDATA, OBJECTPOINT, 95),
+
+ /* mark this as start of a cookie session */
+ CINIT(COOKIESESSION, LONG, 96),
+
+ /* The CApath directory used to validate the peer certificate
+ this option is used only if SSL_VERIFYPEER is true */
+ CINIT(CAPATH, OBJECTPOINT, 97),
+
+ /* Instruct libcurl to use a smaller receive buffer */
+ CINIT(BUFFERSIZE, LONG, 98),
+
+ /* Instruct libcurl to not use any signal/alarm handlers, even when using
+ timeouts. This option is useful for multi-threaded applications.
+ See libcurl-the-guide for more background information. */
+ CINIT(NOSIGNAL, LONG, 99),
+
+ /* Provide a CURLShare for mutexing non-ts data */
+ CINIT(SHARE, OBJECTPOINT, 100),
+
+ /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
+ CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */
+ CINIT(PROXYTYPE, LONG, 101),
+
+ /* Set the Accept-Encoding string. Use this to tell a server you would like
+ the response to be compressed. Before 7.21.6, this was known as
+ CURLOPT_ENCODING */
+ CINIT(ACCEPT_ENCODING, OBJECTPOINT, 102),
+
+ /* Set pointer to private data */
+ CINIT(PRIVATE, OBJECTPOINT, 103),
+
+ /* Set aliases for HTTP 200 in the HTTP Response header */
+ CINIT(HTTP200ALIASES, OBJECTPOINT, 104),
+
+ /* Continue to send authentication (user+password) when following locations,
+ even when hostname changed. This can potentially send off the name
+ and password to whatever host the server decides. */
+ CINIT(UNRESTRICTED_AUTH, LONG, 105),
+
+ /* Specifically switch on or off the FTP engine's use of the EPRT command (
+ it also disables the LPRT attempt). By default, those ones will always be
+ attempted before the good old traditional PORT command. */
+ CINIT(FTP_USE_EPRT, LONG, 106),
+
+ /* Set this to a bitmask value to enable the particular authentications
+ methods you like. Use this in combination with CURLOPT_USERPWD.
+ Note that setting multiple bits may cause extra network round-trips. */
+ CINIT(HTTPAUTH, LONG, 107),
+
+ /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
+ in second argument. The function must be matching the
+ curl_ssl_ctx_callback proto. */
+ CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
+
+ /* Set the userdata for the ssl context callback function's third
+ argument */
+ CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
+
+ /* FTP Option that causes missing dirs to be created on the remote server.
+ In 7.19.4 we introduced the convenience enums for this option using the
+ CURLFTP_CREATE_DIR prefix.
+ */
+ CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),
+
+ /* Set this to a bitmask value to enable the particular authentications
+ methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
+ Note that setting multiple bits may cause extra network round-trips. */
+ CINIT(PROXYAUTH, LONG, 111),
+
+ /* FTP option that changes the timeout, in seconds, associated with
+ getting a response. This is different from transfer timeout time and
+ essentially places a demand on the FTP server to acknowledge commands
+ in a timely manner. */
+ CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112),
+#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT
+
+ /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
+ tell libcurl to resolve names to those IP versions only. This only has
+ affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
+ CINIT(IPRESOLVE, LONG, 113),
+
+ /* Set this option to limit the size of a file that will be downloaded from
+ an HTTP or FTP server.
+
+ Note there is also _LARGE version which adds large file support for
+ platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */
+ CINIT(MAXFILESIZE, LONG, 114),
+
+ /* See the comment for INFILESIZE above, but in short, specifies
+ * the size of the file being uploaded. -1 means unknown.
+ */
+ CINIT(INFILESIZE_LARGE, OFF_T, 115),
+
+ /* Sets the continuation offset. There is also a LONG version of this;
+ * look above for RESUME_FROM.
+ */
+ CINIT(RESUME_FROM_LARGE, OFF_T, 116),
+
+ /* Sets the maximum size of data that will be downloaded from
+ * an HTTP or FTP server. See MAXFILESIZE above for the LONG version.
+ */
+ CINIT(MAXFILESIZE_LARGE, OFF_T, 117),
+
+ /* Set this option to the file name of your .netrc file you want libcurl
+ to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
+ a poor attempt to find the user's home directory and check for a .netrc
+ file in there. */
+ CINIT(NETRC_FILE, OBJECTPOINT, 118),
+
+ /* Enable SSL/TLS for FTP, pick one of:
+ CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise
+ CURLFTPSSL_CONTROL - SSL for the control connection or fail
+ CURLFTPSSL_ALL - SSL for all communication or fail
+ */
+ CINIT(USE_SSL, LONG, 119),
+
+ /* The _LARGE version of the standard POSTFIELDSIZE option */
+ CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
+
+ /* Enable/disable the TCP Nagle algorithm */
+ CINIT(TCP_NODELAY, LONG, 121),
+
+ /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 123 OBSOLETE. Gone in 7.16.0 */
+ /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 127 OBSOLETE. Gone in 7.16.0 */
+ /* 128 OBSOLETE. Gone in 7.16.0 */
+
+ /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option
+ can be used to change libcurl's default action which is to first try
+ "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK
+ response has been received.
+
+ Available parameters are:
+ CURLFTPAUTH_DEFAULT - let libcurl decide
+ CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS
+ CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL
+ */
+ CINIT(FTPSSLAUTH, LONG, 129),
+
+ CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
+ CINIT(IOCTLDATA, OBJECTPOINT, 131),
+
+ /* 132 OBSOLETE. Gone in 7.16.0 */
+ /* 133 OBSOLETE. Gone in 7.16.0 */
+
+ /* zero terminated string for pass on to the FTP server when asked for
+ "account" info */
+ CINIT(FTP_ACCOUNT, OBJECTPOINT, 134),
+
+ /* feed cookies into cookie engine */
+ CINIT(COOKIELIST, OBJECTPOINT, 135),
+
+ /* ignore Content-Length */
+ CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),
+
+ /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
+ response. Typically used for FTP-SSL purposes but is not restricted to
+ that. libcurl will then instead use the same IP address it used for the
+ control connection. */
+ CINIT(FTP_SKIP_PASV_IP, LONG, 137),
+
+ /* Select "file method" to use when doing FTP, see the curl_ftpmethod
+ above. */
+ CINIT(FTP_FILEMETHOD, LONG, 138),
+
+ /* Local port number to bind the socket to */
+ CINIT(LOCALPORT, LONG, 139),
+
+ /* Number of ports to try, including the first one set with LOCALPORT.
+ Thus, setting it to 1 will make no additional attempts but the first.
+ */
+ CINIT(LOCALPORTRANGE, LONG, 140),
+
+ /* no transfer, set up connection and let application use the socket by
+ extracting it with CURLINFO_LASTSOCKET */
+ CINIT(CONNECT_ONLY, LONG, 141),
+
+ /* Function that will be called to convert from the
+ network encoding (instead of using the iconv calls in libcurl) */
+ CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),
+
+ /* Function that will be called to convert to the
+ network encoding (instead of using the iconv calls in libcurl) */
+ CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),
+
+ /* Function that will be called to convert from UTF8
+ (instead of using the iconv calls in libcurl)
+ Note that this is used only for SSL certificate processing */
+ CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),
+
+ /* if the connection proceeds too quickly then need to slow it down */
+ /* limit-rate: maximum number of bytes per second to send or receive */
+ CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145),
+ CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146),
+
+ /* Pointer to command string to send if USER/PASS fails. */
+ CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147),
+
+ /* callback function for setting socket options */
+ CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
+ CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
+
+ /* set to 0 to disable session ID re-use for this transfer, default is
+ enabled (== 1) */
+ CINIT(SSL_SESSIONID_CACHE, LONG, 150),
+
+ /* allowed SSH authentication methods */
+ CINIT(SSH_AUTH_TYPES, LONG, 151),
+
+ /* Used by scp/sftp to do public/private key authentication */
+ CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152),
+ CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153),
+
+ /* Send CCC (Clear Command Channel) after authentication */
+ CINIT(FTP_SSL_CCC, LONG, 154),
+
+ /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
+ CINIT(TIMEOUT_MS, LONG, 155),
+ CINIT(CONNECTTIMEOUT_MS, LONG, 156),
+
+ /* set to zero to disable the libcurl's decoding and thus pass the raw body
+ data to the application even when it is encoded/compressed */
+ CINIT(HTTP_TRANSFER_DECODING, LONG, 157),
+ CINIT(HTTP_CONTENT_DECODING, LONG, 158),
+
+ /* Permission used when creating new files and directories on the remote
+ server for protocols that support it, SFTP/SCP/FILE */
+ CINIT(NEW_FILE_PERMS, LONG, 159),
+ CINIT(NEW_DIRECTORY_PERMS, LONG, 160),
+
+ /* Set the behaviour of POST when redirecting. Values must be set to one
+ of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
+ CINIT(POSTREDIR, LONG, 161),
+
+ /* used by scp/sftp to verify the host's public key */
+ CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162),
+
+ /* Callback function for opening socket (instead of socket(2)). Optionally,
+ callback is able change the address or refuse to connect returning
+ CURL_SOCKET_BAD. The callback should have type
+ curl_opensocket_callback */
+ CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163),
+ CINIT(OPENSOCKETDATA, OBJECTPOINT, 164),
+
+ /* POST volatile input fields. */
+ CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165),
+
+ /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */
+ CINIT(PROXY_TRANSFER_MODE, LONG, 166),
+
+ /* Callback function for seeking in the input stream */
+ CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167),
+ CINIT(SEEKDATA, OBJECTPOINT, 168),
+
+ /* CRL file */
+ CINIT(CRLFILE, OBJECTPOINT, 169),
+
+ /* Issuer certificate */
+ CINIT(ISSUERCERT, OBJECTPOINT, 170),
+
+ /* (IPv6) Address scope */
+ CINIT(ADDRESS_SCOPE, LONG, 171),
+
+ /* Collect certificate chain info and allow it to get retrievable with
+ CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only
+ working with OpenSSL-powered builds. */
+ CINIT(CERTINFO, LONG, 172),
+
+ /* "name" and "pwd" to use when fetching. */
+ CINIT(USERNAME, OBJECTPOINT, 173),
+ CINIT(PASSWORD, OBJECTPOINT, 174),
+
+ /* "name" and "pwd" to use with Proxy when fetching. */
+ CINIT(PROXYUSERNAME, OBJECTPOINT, 175),
+ CINIT(PROXYPASSWORD, OBJECTPOINT, 176),
+
+ /* Comma separated list of hostnames defining no-proxy zones. These should
+ match both hostnames directly, and hostnames within a domain. For
+ example, local.com will match local.com and www.local.com, but NOT
+ notlocal.com or www.notlocal.com. For compatibility with other
+ implementations of this, .local.com will be considered to be the same as
+ local.com. A single * is the only valid wildcard, and effectively
+ disables the use of proxy. */
+ CINIT(NOPROXY, OBJECTPOINT, 177),
+
+ /* block size for TFTP transfers */
+ CINIT(TFTP_BLKSIZE, LONG, 178),
+
+ /* Socks Service */
+ CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179),
+
+ /* Socks Service */
+ CINIT(SOCKS5_GSSAPI_NEC, LONG, 180),
+
+ /* set the bitmask for the protocols that are allowed to be used for the
+ transfer, which thus helps the app which takes URLs from users or other
+ external inputs and want to restrict what protocol(s) to deal
+ with. Defaults to CURLPROTO_ALL. */
+ CINIT(PROTOCOLS, LONG, 181),
+
+ /* set the bitmask for the protocols that libcurl is allowed to follow to,
+ as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+ to be set in both bitmasks to be allowed to get redirected to. Defaults
+ to all protocols except FILE and SCP. */
+ CINIT(REDIR_PROTOCOLS, LONG, 182),
+
+ /* set the SSH knownhost file name to use */
+ CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183),
+
+ /* set the SSH host key callback, must point to a curl_sshkeycallback
+ function */
+ CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184),
+
+ /* set the SSH host key callback custom pointer */
+ CINIT(SSH_KEYDATA, OBJECTPOINT, 185),
+
+ /* set the SMTP mail originator */
+ CINIT(MAIL_FROM, OBJECTPOINT, 186),
+
+ /* set the SMTP mail receiver(s) */
+ CINIT(MAIL_RCPT, OBJECTPOINT, 187),
+
+ /* FTP: send PRET before PASV */
+ CINIT(FTP_USE_PRET, LONG, 188),
+
+ /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
+ CINIT(RTSP_REQUEST, LONG, 189),
+
+ /* The RTSP session identifier */
+ CINIT(RTSP_SESSION_ID, OBJECTPOINT, 190),
+
+ /* The RTSP stream URI */
+ CINIT(RTSP_STREAM_URI, OBJECTPOINT, 191),
+
+ /* The Transport: header to use in RTSP requests */
+ CINIT(RTSP_TRANSPORT, OBJECTPOINT, 192),
+
+ /* Manually initialize the client RTSP CSeq for this handle */
+ CINIT(RTSP_CLIENT_CSEQ, LONG, 193),
+
+ /* Manually initialize the server RTSP CSeq for this handle */
+ CINIT(RTSP_SERVER_CSEQ, LONG, 194),
+
+ /* The stream to pass to INTERLEAVEFUNCTION. */
+ CINIT(INTERLEAVEDATA, OBJECTPOINT, 195),
+
+ /* Let the application define a custom write method for RTP data */
+ CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196),
+
+ /* Turn on wildcard matching */
+ CINIT(WILDCARDMATCH, LONG, 197),
+
+ /* Directory matching callback called before downloading of an
+ individual file (chunk) started */
+ CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198),
+
+ /* Directory matching callback called after the file (chunk)
+ was downloaded, or skipped */
+ CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199),
+
+ /* Change match (fnmatch-like) callback for wildcard matching */
+ CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200),
+
+ /* Let the application define custom chunk data pointer */
+ CINIT(CHUNK_DATA, OBJECTPOINT, 201),
+
+ /* FNMATCH_FUNCTION user pointer */
+ CINIT(FNMATCH_DATA, OBJECTPOINT, 202),
+
+ /* send linked-list of name:port:address sets */
+ CINIT(RESOLVE, OBJECTPOINT, 203),
+
+ /* Set a username for authenticated TLS */
+ CINIT(TLSAUTH_USERNAME, OBJECTPOINT, 204),
+
+ /* Set a password for authenticated TLS */
+ CINIT(TLSAUTH_PASSWORD, OBJECTPOINT, 205),
+
+ /* Set authentication type for authenticated TLS */
+ CINIT(TLSAUTH_TYPE, OBJECTPOINT, 206),
+
+ /* Set to 1 to enable the "TE:" header in HTTP requests to ask for
+ compressed transfer-encoded responses. Set to 0 to disable the use of TE:
+ in outgoing requests. The current default is 0, but it might change in a
+ future libcurl release.
+
+ libcurl will ask for the compressed methods it knows of, and if that
+ isn't any, it will not ask for transfer-encoding at all even if this
+ option is set to 1.
+
+ */
+ CINIT(TRANSFER_ENCODING, LONG, 207),
+
+ /* Callback function for closing socket (instead of close(2)). The callback
+ should have type curl_closesocket_callback */
+ CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
+ CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),
+
+ /* allow GSSAPI credential delegation */
+ CINIT(GSSAPI_DELEGATION, LONG, 210),
+
+ CURLOPT_LASTENTRY /* the last unused */
+} CURLoption;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2011 */
+
+/* This was added in version 7.19.1 */
+#define CURLOPT_POST301 CURLOPT_POSTREDIR
+
+/* These are scheduled to disappear by 2009 */
+
+/* The following were added in 7.17.0 */
+#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_FTPAPPEND CURLOPT_APPEND
+#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY
+#define CURLOPT_FTP_SSL CURLOPT_USE_SSL
+
+/* The following were added earlier */
+
+#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL
+
+#else
+/* This is set if CURL_NO_OLDIES is defined at compile-time */
+#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
+#endif
+
+
+ /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
+ name resolves addresses using more than one IP protocol version, this
+ option might be handy to force libcurl to use a specific IP version. */
+#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
+ versions that your system allows */
+#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */
+#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */
+
+ /* three convenient "aliases" that follow the name scheme better */
+#define CURLOPT_WRITEDATA CURLOPT_FILE
+#define CURLOPT_READDATA CURLOPT_INFILE
+#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER
+#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
+
+ /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
+enum {
+ CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
+ like the library to choose the best possible
+ for us! */
+ CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */
+ CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */
+
+ CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
+};
+
+/*
+ * Public API enums for RTSP requests
+ */
+enum {
+ CURL_RTSPREQ_NONE, /* first in list */
+ CURL_RTSPREQ_OPTIONS,
+ CURL_RTSPREQ_DESCRIBE,
+ CURL_RTSPREQ_ANNOUNCE,
+ CURL_RTSPREQ_SETUP,
+ CURL_RTSPREQ_PLAY,
+ CURL_RTSPREQ_PAUSE,
+ CURL_RTSPREQ_TEARDOWN,
+ CURL_RTSPREQ_GET_PARAMETER,
+ CURL_RTSPREQ_SET_PARAMETER,
+ CURL_RTSPREQ_RECORD,
+ CURL_RTSPREQ_RECEIVE,
+ CURL_RTSPREQ_LAST /* last in list */
+};
+
+ /* These enums are for use with the CURLOPT_NETRC option. */
+enum CURL_NETRC_OPTION {
+ CURL_NETRC_IGNORED, /* The .netrc will never be read.
+ * This is the default. */
+ CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred
+ * to one in the .netrc. */
+ CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored.
+ * Unless one is set programmatically, the .netrc
+ * will be queried. */
+ CURL_NETRC_LAST
+};
+
+enum {
+ CURL_SSLVERSION_DEFAULT,
+ CURL_SSLVERSION_TLSv1,
+ CURL_SSLVERSION_SSLv2,
+ CURL_SSLVERSION_SSLv3,
+
+ CURL_SSLVERSION_LAST /* never use, keep last */
+};
+
+enum CURL_TLSAUTH {
+ CURL_TLSAUTH_NONE,
+ CURL_TLSAUTH_SRP,
+ CURL_TLSAUTH_LAST /* never use, keep last */
+};
+
+/* symbols to use with CURLOPT_POSTREDIR.
+ CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that
+ CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */
+
+#define CURL_REDIR_GET_ALL 0
+#define CURL_REDIR_POST_301 1
+#define CURL_REDIR_POST_302 2
+#define CURL_REDIR_POST_ALL (CURL_REDIR_POST_301|CURL_REDIR_POST_302)
+
+typedef enum {
+ CURL_TIMECOND_NONE,
+
+ CURL_TIMECOND_IFMODSINCE,
+ CURL_TIMECOND_IFUNMODSINCE,
+ CURL_TIMECOND_LASTMOD,
+
+ CURL_TIMECOND_LAST
+} curl_TimeCond;
+
+
+/* curl_strequal() and curl_strnequal() are subject for removal in a future
+ libcurl, see lib/README.curlx for details */
+CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2);
+CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n);
+
+/* name is uppercase CURLFORM_<name> */
+#ifdef CFINIT
+#undef CFINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CFINIT(name) CURLFORM_ ## name
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define CFINIT(name) CURLFORM_/**/name
+#endif
+
+typedef enum {
+ CFINIT(NOTHING), /********* the first one is unused ************/
+
+ /* */
+ CFINIT(COPYNAME),
+ CFINIT(PTRNAME),
+ CFINIT(NAMELENGTH),
+ CFINIT(COPYCONTENTS),
+ CFINIT(PTRCONTENTS),
+ CFINIT(CONTENTSLENGTH),
+ CFINIT(FILECONTENT),
+ CFINIT(ARRAY),
+ CFINIT(OBSOLETE),
+ CFINIT(FILE),
+
+ CFINIT(BUFFER),
+ CFINIT(BUFFERPTR),
+ CFINIT(BUFFERLENGTH),
+
+ CFINIT(CONTENTTYPE),
+ CFINIT(CONTENTHEADER),
+ CFINIT(FILENAME),
+ CFINIT(END),
+ CFINIT(OBSOLETE2),
+
+ CFINIT(STREAM),
+
+ CURLFORM_LASTENTRY /* the last unused */
+} CURLformoption;
+
+#undef CFINIT /* done */
+
+/* structure to be used as parameter for CURLFORM_ARRAY */
+struct curl_forms {
+ CURLformoption option;
+ const char *value;
+};
+
+/* use this for multipart formpost building */
+/* Returns code for curl_formadd()
+ *
+ * Returns:
+ * CURL_FORMADD_OK on success
+ * CURL_FORMADD_MEMORY if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
+ * CURL_FORMADD_NULL if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated
+ * CURL_FORMADD_MEMORY if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
+ *
+ ***************************************************************************/
+typedef enum {
+ CURL_FORMADD_OK, /* first, no error */
+
+ CURL_FORMADD_MEMORY,
+ CURL_FORMADD_OPTION_TWICE,
+ CURL_FORMADD_NULL,
+ CURL_FORMADD_UNKNOWN_OPTION,
+ CURL_FORMADD_INCOMPLETE,
+ CURL_FORMADD_ILLEGAL_ARRAY,
+ CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */
+
+ CURL_FORMADD_LAST /* last */
+} CURLFORMcode;
+
+/*
+ * NAME curl_formadd()
+ *
+ * DESCRIPTION
+ *
+ * Pretty advanced function for building multi-part formposts. Each invoke
+ * adds one part that together construct a full post. Then use
+ * CURLOPT_HTTPPOST to send it off to libcurl.
+ */
+CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+ struct curl_httppost **last_post,
+ ...);
+
+/*
+ * callback function for curl_formget()
+ * The void *arg pointer will be the one passed as second argument to
+ * curl_formget().
+ * The character buffer passed to it must not be freed.
+ * Should return the buffer length passed to it as the argument "len" on
+ * success.
+ */
+typedef size_t (*curl_formget_callback)(void *arg, const char *buf,
+ size_t len);
+
+/*
+ * NAME curl_formget()
+ *
+ * DESCRIPTION
+ *
+ * Serialize a curl_httppost struct built with curl_formadd().
+ * Accepts a void pointer as second argument which will be passed to
+ * the curl_formget_callback function.
+ * Returns 0 on success.
+ */
+CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg,
+ curl_formget_callback append);
+/*
+ * NAME curl_formfree()
+ *
+ * DESCRIPTION
+ *
+ * Free a multipart formpost previously built with curl_formadd().
+ */
+CURL_EXTERN void curl_formfree(struct curl_httppost *form);
+
+/*
+ * NAME curl_getenv()
+ *
+ * DESCRIPTION
+ *
+ * Returns a malloc()'ed string that MUST be curl_free()ed after usage is
+ * complete. DEPRECATED - see lib/README.curlx
+ */
+CURL_EXTERN char *curl_getenv(const char *variable);
+
+/*
+ * NAME curl_version()
+ *
+ * DESCRIPTION
+ *
+ * Returns a static ascii string of the libcurl version.
+ */
+CURL_EXTERN char *curl_version(void);
+
+/*
+ * NAME curl_easy_escape()
+ *
+ * DESCRIPTION
+ *
+ * Escapes URL strings (converts all letters consider illegal in URLs to their
+ * %XX versions). This function returns a new allocated string or NULL if an
+ * error occurred.
+ */
+CURL_EXTERN char *curl_easy_escape(CURL *handle,
+ const char *string,
+ int length);
+
+/* the previous version: */
+CURL_EXTERN char *curl_escape(const char *string,
+ int length);
+
+
+/*
+ * NAME curl_easy_unescape()
+ *
+ * DESCRIPTION
+ *
+ * Unescapes URL encoding in strings (converts all %XX codes to their 8bit
+ * versions). This function returns a new allocated string or NULL if an error
+ * occurred.
+ * Conversion Note: On non-ASCII platforms the ASCII %XX codes are
+ * converted into the host encoding.
+ */
+CURL_EXTERN char *curl_easy_unescape(CURL *handle,
+ const char *string,
+ int length,
+ int *outlength);
+
+/* the previous version */
+CURL_EXTERN char *curl_unescape(const char *string,
+ int length);
+
+/*
+ * NAME curl_free()
+ *
+ * DESCRIPTION
+ *
+ * Provided for de-allocation in the same translation unit that did the
+ * allocation. Added in libcurl 7.10
+ */
+CURL_EXTERN void curl_free(void *p);
+
+/*
+ * NAME curl_global_init()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() should be invoked exactly once for each application that
+ * uses libcurl and before any call of other libcurl functions.
+ *
+ * This function is not thread-safe!
+ */
+CURL_EXTERN CURLcode curl_global_init(long flags);
+
+/*
+ * NAME curl_global_init_mem()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() or curl_global_init_mem() should be invoked exactly once
+ * for each application that uses libcurl. This function can be used to
+ * initialize libcurl and set user defined memory management callback
+ * functions. Users can implement memory management routines to check for
+ * memory leaks, check for mis-use of the curl library etc. User registered
+ * callback routines with be invoked by this library instead of the system
+ * memory management routines like malloc, free etc.
+ */
+CURL_EXTERN CURLcode curl_global_init_mem(long flags,
+ curl_malloc_callback m,
+ curl_free_callback f,
+ curl_realloc_callback r,
+ curl_strdup_callback s,
+ curl_calloc_callback c);
+
+/*
+ * NAME curl_global_cleanup()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_cleanup() should be invoked exactly once for each application
+ * that uses libcurl
+ */
+CURL_EXTERN void curl_global_cleanup(void);
+
+/* linked-list structure for the CURLOPT_QUOTE option (and other) */
+struct curl_slist {
+ char *data;
+ struct curl_slist *next;
+};
+
+/*
+ * NAME curl_slist_append()
+ *
+ * DESCRIPTION
+ *
+ * Appends a string to a linked list. If no list exists, it will be created
+ * first. Returns the new list, after appending.
+ */
+CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,
+ const char *);
+
+/*
+ * NAME curl_slist_free_all()
+ *
+ * DESCRIPTION
+ *
+ * free a previously built curl_slist.
+ */
+CURL_EXTERN void curl_slist_free_all(struct curl_slist *);
+
+/*
+ * NAME curl_getdate()
+ *
+ * DESCRIPTION
+ *
+ * Returns the time, in seconds since 1 Jan 1970 of the time string given in
+ * the first argument. The time argument in the second parameter is unused
+ * and should be set to NULL.
+ */
+CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
+
+/* info about the certificate chain, only for OpenSSL builds. Asked
+ for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+struct curl_certinfo {
+ int num_of_certs; /* number of certificates with information */
+ struct curl_slist **certinfo; /* for each index in this array, there's a
+ linked list with textual information in the
+ format "name: value" */
+};
+
+#define CURLINFO_STRING 0x100000
+#define CURLINFO_LONG 0x200000
+#define CURLINFO_DOUBLE 0x300000
+#define CURLINFO_SLIST 0x400000
+#define CURLINFO_MASK 0x0fffff
+#define CURLINFO_TYPEMASK 0xf00000
+
+typedef enum {
+ CURLINFO_NONE, /* first, never use this */
+ CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1,
+ CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2,
+ CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3,
+ CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4,
+ CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5,
+ CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6,
+ CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7,
+ CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8,
+ CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9,
+ CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10,
+ CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11,
+ CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12,
+ CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13,
+ CURLINFO_FILETIME = CURLINFO_LONG + 14,
+ CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15,
+ CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16,
+ CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
+ CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18,
+ CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19,
+ CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20,
+ CURLINFO_PRIVATE = CURLINFO_STRING + 21,
+ CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22,
+ CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23,
+ CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24,
+ CURLINFO_OS_ERRNO = CURLINFO_LONG + 25,
+ CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26,
+ CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
+ CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
+ CURLINFO_LASTSOCKET = CURLINFO_LONG + 29,
+ CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30,
+ CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31,
+ CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32,
+ CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33,
+ CURLINFO_CERTINFO = CURLINFO_SLIST + 34,
+ CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35,
+ CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36,
+ CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37,
+ CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38,
+ CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39,
+ CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40,
+ CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
+ CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
+ /* Fill in new entries below here! */
+
+ CURLINFO_LASTONE = 42
+} CURLINFO;
+
+/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
+ CURLINFO_HTTP_CODE */
+#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE
+
+typedef enum {
+ CURLCLOSEPOLICY_NONE, /* first, never use this */
+
+ CURLCLOSEPOLICY_OLDEST,
+ CURLCLOSEPOLICY_LEAST_RECENTLY_USED,
+ CURLCLOSEPOLICY_LEAST_TRAFFIC,
+ CURLCLOSEPOLICY_SLOWEST,
+ CURLCLOSEPOLICY_CALLBACK,
+
+ CURLCLOSEPOLICY_LAST /* last, never use this */
+} curl_closepolicy;
+
+#define CURL_GLOBAL_SSL (1<<0)
+#define CURL_GLOBAL_WIN32 (1<<1)
+#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
+#define CURL_GLOBAL_NOTHING 0
+#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
+
+
+/*****************************************************************************
+ * Setup defines, protos etc for the sharing stuff.
+ */
+
+/* Different data locks for a single share */
+typedef enum {
+ CURL_LOCK_DATA_NONE = 0,
+ /* CURL_LOCK_DATA_SHARE is used internally to say that
+ * the locking is just made to change the internal state of the share
+ * itself.
+ */
+ CURL_LOCK_DATA_SHARE,
+ CURL_LOCK_DATA_COOKIE,
+ CURL_LOCK_DATA_DNS,
+ CURL_LOCK_DATA_SSL_SESSION,
+ CURL_LOCK_DATA_CONNECT,
+ CURL_LOCK_DATA_LAST
+} curl_lock_data;
+
+/* Different lock access types */
+typedef enum {
+ CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */
+ CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
+ CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
+ CURL_LOCK_ACCESS_LAST /* never use */
+} curl_lock_access;
+
+typedef void (*curl_lock_function)(CURL *handle,
+ curl_lock_data data,
+ curl_lock_access locktype,
+ void *userptr);
+typedef void (*curl_unlock_function)(CURL *handle,
+ curl_lock_data data,
+ void *userptr);
+
+typedef void CURLSH;
+
+typedef enum {
+ CURLSHE_OK, /* all is fine */
+ CURLSHE_BAD_OPTION, /* 1 */
+ CURLSHE_IN_USE, /* 2 */
+ CURLSHE_INVALID, /* 3 */
+ CURLSHE_NOMEM, /* 4 out of memory */
+ CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */
+ CURLSHE_LAST /* never use */
+} CURLSHcode;
+
+typedef enum {
+ CURLSHOPT_NONE, /* don't use */
+ CURLSHOPT_SHARE, /* specify a data type to share */
+ CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */
+ CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */
+ CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */
+ CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock
+ callback functions */
+ CURLSHOPT_LAST /* never use */
+} CURLSHoption;
+
+CURL_EXTERN CURLSH *curl_share_init(void);
+CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...);
+CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *);
+
+/****************************************************************************
+ * Structures for querying information about the curl library at runtime.
+ */
+
+typedef enum {
+ CURLVERSION_FIRST,
+ CURLVERSION_SECOND,
+ CURLVERSION_THIRD,
+ CURLVERSION_FOURTH,
+ CURLVERSION_LAST /* never actually use this */
+} CURLversion;
+
+/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
+ basically all programs ever that want to get version information. It is
+ meant to be a built-in version number for what kind of struct the caller
+ expects. If the struct ever changes, we redefine the NOW to another enum
+ from above. */
+#define CURLVERSION_NOW CURLVERSION_FOURTH
+
+typedef struct {
+ CURLversion age; /* age of the returned struct */
+ const char *version; /* LIBCURL_VERSION */
+ unsigned int version_num; /* LIBCURL_VERSION_NUM */
+ const char *host; /* OS/host/cpu/machine when configured */
+ int features; /* bitmask, see defines below */
+ const char *ssl_version; /* human readable string */
+ long ssl_version_num; /* not used anymore, always 0 */
+ const char *libz_version; /* human readable string */
+ /* protocols is terminated by an entry with a NULL protoname */
+ const char * const *protocols;
+
+ /* The fields below this were added in CURLVERSION_SECOND */
+ const char *ares;
+ int ares_num;
+
+ /* This field was added in CURLVERSION_THIRD */
+ const char *libidn;
+
+ /* These field were added in CURLVERSION_FOURTH */
+
+ /* Same as '_libiconv_version' if built with HAVE_ICONV */
+ int iconv_ver_num;
+
+ const char *libssh_version; /* human readable string */
+
+} curl_version_info_data;
+
+#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */
+#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */
+#define CURL_VERSION_SSL (1<<2) /* SSL options are present */
+#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */
+#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */
+#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */
+#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */
+#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */
+#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */
+#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */
+#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */
+#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */
+#define CURL_VERSION_CONV (1<<12) /* character conversions supported */
+#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */
+#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
+#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegating to winbind helper */
+
+ /*
+ * NAME curl_version_info()
+ *
+ * DESCRIPTION
+ *
+ * This function returns a pointer to a static copy of the version info
+ * struct. See above.
+ */
+CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion);
+
+/*
+ * NAME curl_easy_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_strerror function may be used to turn a CURLcode value
+ * into the equivalent human readable error string. This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_easy_strerror(CURLcode);
+
+/*
+ * NAME curl_share_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_share_strerror function may be used to turn a CURLSHcode value
+ * into the equivalent human readable error string. This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_share_strerror(CURLSHcode);
+
+/*
+ * NAME curl_easy_pause()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_pause function pauses or unpauses transfers. Select the new
+ * state by setting the bitmask, use the convenience defines below.
+ *
+ */
+CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
+
+#define CURLPAUSE_RECV (1<<0)
+#define CURLPAUSE_RECV_CONT (0)
+
+#define CURLPAUSE_SEND (1<<2)
+#define CURLPAUSE_SEND_CONT (0)
+
+#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND)
+#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)
+
+#ifdef __cplusplus
+}
+#endif
+
+/* unfortunately, the easy.h and multi.h include files need options and info
+ stuff before they can be included! */
+#include "easy.h" /* nothing in curl is fun without the easy stuff */
+#include "multi.h"
+
+/* the typechecker doesn't work in C++ (yet) */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
+ ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \
+ !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK)
+#include "typecheck-gcc.h"
+#else
+#if defined(__STDC__) && (__STDC__ >= 1)
+/* This preprocessor magic that replaces a call with the exact same call is
+ only done to make sure application authors pass exactly three arguments
+ to these functions. */
+#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
+#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg)
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+#endif /* __STDC__ >= 1 */
+#endif /* gcc >= 4.3 && !__cplusplus */
+
+#endif /* __CURL_CURL_H */
diff --git a/curl/curlbuild.h b/curl/curlbuild.h
new file mode 100644
index 0000000..d0b32ac
--- /dev/null
+++ b/curl/curlbuild.h
@@ -0,0 +1,583 @@
+#ifndef __CURL_CURLBUILD_H
+#define __CURL_CURLBUILD_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, 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.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * See file include/curl/curlbuild.h.in, run configure, and forget
+ * that this file exists it is only used for non-configure systems.
+ * But you can keep reading if you want ;-)
+ *
+ */
+
+/* ================================================================ */
+/* NOTES FOR NON-CONFIGURE SYSTEMS */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * curl library user nor by the curl library builder.
+ *
+ * If you think that something actually needs to be changed, adjusted
+ * or fixed in this file, then, report it on the libcurl development
+ * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/
+ *
+ * Try to keep one section per platform, compiler and architecture,
+ * otherwise, if an existing section is reused for a different one and
+ * later on the original is adjusted, probably the piggybacking one can
+ * be adversely changed.
+ *
+ * In order to differentiate between platforms/compilers/architectures
+ * use only compiler built in predefined preprocessor symbols.
+ *
+ * This header file shall only export symbols which are 'curl' or 'CURL'
+ * prefixed, otherwise public name space would be polluted.
+ *
+ * NOTE 2:
+ * -------
+ *
+ * For any given platform/compiler curl_off_t must be typedef'ed to a
+ * 64-bit wide signed integral data type. The width of this data type
+ * must remain constant and independent of any possible large file
+ * support settings.
+ *
+ * As an exception to the above, curl_off_t shall be typedef'ed to a
+ * 32-bit wide signed integral data type if there is no 64-bit type.
+ *
+ * As a general rule, curl_off_t shall not be mapped to off_t. This
+ * rule shall only be violated if off_t is the only 64-bit data type
+ * available and the size of off_t is independent of large file support
+ * settings. Keep your build on the safe side avoiding an off_t gating.
+ * If you have a 64-bit off_t then take for sure that another 64-bit
+ * data type exists, dig deeper and you will find it.
+ *
+ * NOTE 3:
+ * -------
+ *
+ * Right now you might be staring at file include/curl/curlbuild.h.dist or
+ * at file include/curl/curlbuild.h, this is due to the following reason:
+ * file include/curl/curlbuild.h.dist is renamed to include/curl/curlbuild.h
+ * when the libcurl source code distribution archive file is created.
+ *
+ * File include/curl/curlbuild.h.dist is not included in the distribution
+ * archive. File include/curl/curlbuild.h is not present in the git tree.
+ *
+ * The distributed include/curl/curlbuild.h file is only intended to be used
+ * on systems which can not run the also distributed configure script.
+ *
+ * On systems capable of running the configure script, the configure process
+ * will overwrite the distributed include/curl/curlbuild.h file with one that
+ * is suitable and specific to the library being configured and built, which
+ * is generated from the include/curl/curlbuild.h.in template file.
+ *
+ * If you check out from git on a non-configure platform, you must run the
+ * appropriate buildconf* script to set up curlbuild.h and other local files.
+ *
+ */
+
+/* ================================================================ */
+/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */
+/* ================================================================ */
+
+#ifdef CURL_SIZEOF_LONG
+# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
+# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_OFF_T
+# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_T
+# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_TU
+# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
+#endif
+
+#ifdef CURL_FORMAT_OFF_T
+# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_OFF_T
+# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_T
+# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_TU
+# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
+#endif
+
+/* ================================================================ */
+/* EXTERNAL INTERFACE SETTINGS FOR NON-CONFIGURE SYSTEMS ONLY */
+/* ================================================================ */
+
+#if defined(__DJGPP__) || defined(__GO32__)
+# if defined(__DJGPP__) && (__DJGPP__ > 1)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_FORMAT_OFF_T "%lld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# else
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 4
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__SALFORDC__)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 4
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__BORLANDC__)
+# if (__BORLANDC__ < 0x520)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 4
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_FORMAT_OFF_T "%I64d"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__TURBOC__)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 4
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__WATCOMC__)
+# if defined(__386__)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_FORMAT_OFF_T "%I64d"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# else
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 4
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__POCC__)
+# if (__POCC__ < 280)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 4
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# elif defined(_MSC_VER)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_FORMAT_OFF_T "%I64d"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# else
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_FORMAT_OFF_T "%lld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__LCC__)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 4
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__SYMBIAN32__)
+# if defined(__EABI__) /* Treat all ARM compilers equally */
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_FORMAT_OFF_T "%lld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(__CW32__)
+# pragma longlong on
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_FORMAT_OFF_T "%lld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(__VC32__)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_FORMAT_OFF_T "%lld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__MWERKS__)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_FORMAT_OFF_T "%lld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(_WIN32_WCE)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_FORMAT_OFF_T "%I64d"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__MINGW32__)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_FORMAT_OFF_T "%I64d"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__VMS)
+# if defined(__VAX)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 4
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_FORMAT_OFF_T "%lld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__OS400__)
+# if defined(__ILEC400__)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_FORMAT_OFF_T "%lld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+# endif
+
+#elif defined(__MVS__)
+# if defined(__IBMC__) || defined(__IBMCPP__)
+# if defined(_ILP32)
+# define CURL_SIZEOF_LONG 4
+# elif defined(_LP64)
+# define CURL_SIZEOF_LONG 8
+# endif
+# if defined(_LONG_LONG)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_FORMAT_OFF_T "%lld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(_LP64)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 4
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+# endif
+
+#elif defined(__370__)
+# if defined(__IBMC__) || defined(__IBMCPP__)
+# if defined(_ILP32)
+# define CURL_SIZEOF_LONG 4
+# elif defined(_LP64)
+# define CURL_SIZEOF_LONG 8
+# endif
+# if defined(_LONG_LONG)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_FORMAT_OFF_T "%lld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(_LP64)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 4
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+# endif
+
+#elif defined(TPF)
+# define CURL_SIZEOF_LONG 8
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+/* ===================================== */
+/* KEEP MSVC THE PENULTIMATE ENTRY */
+/* ===================================== */
+
+#elif defined(_MSC_VER)
+# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_FORMAT_OFF_T "%I64d"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# else
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 4
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+/* ===================================== */
+/* KEEP GENERIC GCC THE LAST ENTRY */
+/* ===================================== */
+
+#elif defined(__GNUC__)
+# if defined(__i386__) || defined(__ppc__)
+# define CURL_SIZEOF_LONG 4
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_FORMAT_OFF_T "%lld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(__x86_64__) || defined(__ppc64__)
+# define CURL_SIZEOF_LONG 8
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_SIZEOF_CURL_SOCKLEN_T 4
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+
+#else
+# error "Unknown non-configure build target!"
+ Error Compilation_aborted_Unknown_non_configure_build_target
+#endif
+
+/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */
+/* sys/types.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */
+/* sys/socket.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+
+/* Data type definition of curl_socklen_t. */
+
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+ typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
+#endif
+
+/* Data type definition of curl_off_t. */
+
+#ifdef CURL_TYPEOF_CURL_OFF_T
+ typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
+#endif
+
+#endif /* __CURL_CURLBUILD_H */
diff --git a/curl/curlrules.h b/curl/curlrules.h
new file mode 100644
index 0000000..cbc12fd
--- /dev/null
+++ b/curl/curlrules.h
@@ -0,0 +1,261 @@
+#ifndef __CURL_CURLRULES_H
+#define __CURL_CURLRULES_H
+/***************************************************************************
+ * _ _ ____ _
+ * 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.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/* COMPILE TIME SANITY CHECKS */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * All checks done in this file are intentionally placed in a public
+ * header file which is pulled by curl/curl.h when an application is
+ * being built using an already built libcurl library. Additionally
+ * this file is also included and used when building the library.
+ *
+ * If compilation fails on this file it is certainly sure that the
+ * problem is elsewhere. It could be a problem in the curlbuild.h
+ * header file, or simply that you are using different compilation
+ * settings than those used to build the library.
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * curl library user nor by the curl library builder.
+ *
+ * Do not deactivate any check, these are done to make sure that the
+ * library is properly built and used.
+ *
+ * You can find further help on the libcurl development mailing list:
+ * http://cool.haxx.se/mailman/listinfo/curl-library/
+ *
+ * NOTE 2
+ * ------
+ *
+ * Some of the following compile time checks are based on the fact
+ * that the dimension of a constant array can not be a negative one.
+ * In this way if the compile time verification fails, the compilation
+ * will fail issuing an error. The error description wording is compiler
+ * dependent but it will be quite similar to one of the following:
+ *
+ * "negative subscript or subscript is too large"
+ * "array must have at least one element"
+ * "-1 is an illegal array size"
+ * "size of array is negative"
+ *
+ * If you are building an application which tries to use an already
+ * built libcurl library and you are getting this kind of errors on
+ * this file, it is a clear indication that there is a mismatch between
+ * how the library was built and how you are trying to use it for your
+ * application. Your already compiled or binary library provider is the
+ * only one who can give you the details you need to properly use it.
+ */
+
+/*
+ * Verify that some macros are actually defined.
+ */
+
+#ifndef CURL_SIZEOF_LONG
+# error "CURL_SIZEOF_LONG definition is missing!"
+ Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing
+#endif
+
+#ifndef CURL_TYPEOF_CURL_SOCKLEN_T
+# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing
+#endif
+
+#ifndef CURL_SIZEOF_CURL_SOCKLEN_T
+# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing
+#endif
+
+#ifndef CURL_TYPEOF_CURL_OFF_T
+# error "CURL_TYPEOF_CURL_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_FORMAT_CURL_OFF_T
+# error "CURL_FORMAT_CURL_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_FORMAT_CURL_OFF_TU
+# error "CURL_FORMAT_CURL_OFF_TU definition is missing!"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing
+#endif
+
+#ifndef CURL_FORMAT_OFF_T
+# error "CURL_FORMAT_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SIZEOF_CURL_OFF_T
+# error "CURL_SIZEOF_CURL_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SUFFIX_CURL_OFF_T
+# error "CURL_SUFFIX_CURL_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SUFFIX_CURL_OFF_TU
+# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing
+#endif
+
+/*
+ * Macros private to this header file.
+ */
+
+#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1
+
+#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1
+
+/*
+ * Verify that the size previously defined and expected for long
+ * is the same as the one reported by sizeof() at compile time.
+ */
+
+typedef char
+ __curl_rule_01__
+ [CurlchkszEQ(long, CURL_SIZEOF_LONG)];
+
+/*
+ * Verify that the size previously defined and expected for
+ * curl_off_t is actually the the same as the one reported
+ * by sizeof() at compile time.
+ */
+
+typedef char
+ __curl_rule_02__
+ [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)];
+
+/*
+ * Verify at compile time that the size of curl_off_t as reported
+ * by sizeof() is greater or equal than the one reported for long
+ * for the current compilation.
+ */
+
+typedef char
+ __curl_rule_03__
+ [CurlchkszGE(curl_off_t, long)];
+
+/*
+ * Verify that the size previously defined and expected for
+ * curl_socklen_t is actually the the same as the one reported
+ * by sizeof() at compile time.
+ */
+
+typedef char
+ __curl_rule_04__
+ [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)];
+
+/*
+ * Verify at compile time that the size of curl_socklen_t as reported
+ * by sizeof() is greater or equal than the one reported for int for
+ * the current compilation.
+ */
+
+typedef char
+ __curl_rule_05__
+ [CurlchkszGE(curl_socklen_t, int)];
+
+/* ================================================================ */
+/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */
+/* ================================================================ */
+
+/*
+ * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
+ * these to be visible and exported by the external libcurl interface API,
+ * while also making them visible to the library internals, simply including
+ * setup.h, without actually needing to include curl.h internally.
+ * If some day this section would grow big enough, all this should be moved
+ * to its own header file.
+ */
+
+/*
+ * Figure out if we can use the ## preprocessor operator, which is supported
+ * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
+ * or __cplusplus so we need to carefully check for them too.
+ */
+
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
+ defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
+ defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
+ defined(__ILEC400__)
+ /* This compiler is believed to have an ISO compatible preprocessor */
+#define CURL_ISOCPP
+#else
+ /* This compiler is believed NOT to have an ISO compatible preprocessor */
+#undef CURL_ISOCPP
+#endif
+
+/*
+ * Macros for minimum-width signed and unsigned curl_off_t integer constants.
+ */
+
+#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
+# define __CURL_OFF_T_C_HLPR2(x) x
+# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x)
+# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
+ __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
+# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
+ __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
+#else
+# ifdef CURL_ISOCPP
+# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
+# else
+# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
+# endif
+# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix)
+# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
+# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
+#endif
+
+/*
+ * Get rid of macros private to this header file.
+ */
+
+#undef CurlchkszEQ
+#undef CurlchkszGE
+
+/*
+ * Get rid of macros not intended to exist beyond this point.
+ */
+
+#undef CURL_PULL_WS2TCPIP_H
+#undef CURL_PULL_SYS_TYPES_H
+#undef CURL_PULL_SYS_SOCKET_H
+#undef CURL_PULL_STDINT_H
+#undef CURL_PULL_INTTYPES_H
+
+#undef CURL_TYPEOF_CURL_SOCKLEN_T
+#undef CURL_TYPEOF_CURL_OFF_T
+
+#ifdef CURL_NO_OLDIES
+#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */
+#endif
+
+#endif /* __CURL_CURLRULES_H */
diff --git a/curl/curlver.h b/curl/curlver.h
new file mode 100644
index 0000000..f9476e4
--- /dev/null
+++ b/curl/curlver.h
@@ -0,0 +1,69 @@
+#ifndef __CURL_CURLVER_H
+#define __CURL_CURLVER_H
+/***************************************************************************
+ * _ _ ____ _
+ * 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.
+ *
+ ***************************************************************************/
+
+/* This header file contains nothing but libcurl version info, generated by
+ a script at release-time. This was made its own header file in 7.11.2 */
+
+/* This is the global package copyright */
+#define LIBCURL_COPYRIGHT "1996 - 2011 Daniel Stenberg, <daniel@haxx.se>."
+
+/* This is the version number of the libcurl package from which this header
+ file origins: */
+#define LIBCURL_VERSION "7.23.1"
+
+/* The numeric version number is also available "in parts" by using these
+ defines: */
+#define LIBCURL_VERSION_MAJOR 7
+#define LIBCURL_VERSION_MINOR 23
+#define LIBCURL_VERSION_PATCH 1
+
+/* This is the numeric version of the libcurl version number, meant for easier
+ parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
+ always follow this syntax:
+
+ 0xXXYYZZ
+
+ Where XX, YY and ZZ are the main version, release and patch numbers in
+ hexadecimal (using 8 bits each). All three numbers are always represented
+ using two digits. 1.2 would appear as "0x010200" while version 9.11.7
+ appears as "0x090b07".
+
+ This 6-digit (24 bits) hexadecimal number does not show pre-release number,
+ and it is always a greater number in a more recent release. It makes
+ comparisons with greater than and less than work.
+*/
+#define LIBCURL_VERSION_NUM 0x071701
+
+/*
+ * This is the date and time when the full source package was created. The
+ * timestamp is not stored in git, as the timestamp is properly set in the
+ * tarballs by the maketgz script.
+ *
+ * The format of the date should follow this template:
+ *
+ * "Mon Feb 12 11:35:33 UTC 2007"
+ */
+#define LIBCURL_TIMESTAMP "Thu Nov 17 17:17:45 UTC 2011"
+
+#endif /* __CURL_CURLVER_H */
diff --git a/curl/easy.h b/curl/easy.h
new file mode 100644
index 0000000..c1e3e76
--- /dev/null
+++ b/curl/easy.h
@@ -0,0 +1,102 @@
+#ifndef __CURL_EASY_H
+#define __CURL_EASY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2008, 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 __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN CURL *curl_easy_init(void);
+CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
+CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
+CURL_EXTERN void curl_easy_cleanup(CURL *curl);
+
+/*
+ * NAME curl_easy_getinfo()
+ *
+ * DESCRIPTION
+ *
+ * Request internal information from the curl session with this function. The
+ * third argument MUST be a pointer to a long, a pointer to a char * or a
+ * pointer to a double (as the documentation describes elsewhere). The data
+ * pointed to will be filled in accordingly and can be relied upon only if the
+ * function returns CURLE_OK. This function is intended to get used *AFTER* a
+ * performed transfer, all results from this function are undefined until the
+ * transfer is completed.
+ */
+CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
+
+
+/*
+ * NAME curl_easy_duphandle()
+ *
+ * DESCRIPTION
+ *
+ * Creates a new curl session handle with the same options set for the handle
+ * passed in. Duplicating a handle could only be a matter of cloning data and
+ * options, internal state info and things like persistent connections cannot
+ * be transferred. It is useful in multithreaded applications when you can run
+ * curl_easy_duphandle() for each new thread to avoid a series of identical
+ * curl_easy_setopt() invokes in every thread.
+ */
+CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
+
+/*
+ * NAME curl_easy_reset()
+ *
+ * DESCRIPTION
+ *
+ * Re-initializes a CURL handle to the default values. This puts back the
+ * handle to the same state as it was in when it was just created.
+ *
+ * It does keep: live connections, the Session ID cache, the DNS cache and the
+ * cookies.
+ */
+CURL_EXTERN void curl_easy_reset(CURL *curl);
+
+/*
+ * NAME curl_easy_recv()
+ *
+ * DESCRIPTION
+ *
+ * Receives data from the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
+ size_t *n);
+
+/*
+ * NAME curl_easy_send()
+ *
+ * DESCRIPTION
+ *
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
+ size_t buflen, size_t *n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/curl/mprintf.h b/curl/mprintf.h
new file mode 100644
index 0000000..de7dd2f
--- /dev/null
+++ b/curl/mprintf.h
@@ -0,0 +1,81 @@
+#ifndef __CURL_MPRINTF_H
+#define __CURL_MPRINTF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2006, 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 <stdarg.h>
+#include <stdio.h> /* needed for FILE */
+
+#include "curl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN int curl_mprintf(const char *format, ...);
+CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
+CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
+CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
+ const char *format, ...);
+CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
+CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
+CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
+CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
+ const char *format, va_list args);
+CURL_EXTERN char *curl_maprintf(const char *format, ...);
+CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
+
+#ifdef _MPRINTF_REPLACE
+# undef printf
+# undef fprintf
+# undef sprintf
+# undef vsprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+# define printf curl_mprintf
+# define fprintf curl_mfprintf
+#ifdef CURLDEBUG
+/* When built with CURLDEBUG we define away the sprintf() functions since we
+ don't want internal code to be using them */
+# define sprintf sprintf_was_used
+# define vsprintf vsprintf_was_used
+#else
+# define sprintf curl_msprintf
+# define vsprintf curl_mvsprintf
+#endif
+# define snprintf curl_msnprintf
+# define vprintf curl_mvprintf
+# define vfprintf curl_mvfprintf
+# define vsnprintf curl_mvsnprintf
+# define aprintf curl_maprintf
+# define vaprintf curl_mvaprintf
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CURL_MPRINTF_H */
diff --git a/curl/multi.h b/curl/multi.h
new file mode 100644
index 0000000..f965666
--- /dev/null
+++ b/curl/multi.h
@@ -0,0 +1,345 @@
+#ifndef __CURL_MULTI_H
+#define __CURL_MULTI_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, 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 "external" header file. Don't give away any internals here!
+
+ GOALS
+
+ o Enable a "pull" interface. The application that uses libcurl decides where
+ and when to ask libcurl to get/send data.
+
+ o Enable multiple simultaneous transfers in the same thread without making it
+ complicated for the application.
+
+ o Enable the application to select() on its own file descriptors and curl's
+ file descriptors simultaneous easily.
+
+*/
+
+/*
+ * This header file should not really need to include "curl.h" since curl.h
+ * itself includes this file and we expect user applications to do #include
+ * <curl/curl.h> without the need for especially including multi.h.
+ *
+ * For some reason we added this include here at one point, and rather than to
+ * break existing (wrongly written) libcurl applications, we leave it as-is
+ * but with this warning attached.
+ */
+#include "curl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void CURLM;
+
+typedef enum {
+ CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
+ curl_multi_socket*() soon */
+ CURLM_OK,
+ CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
+ CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
+ CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
+ CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
+ CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
+ CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
+ CURLM_LAST
+} CURLMcode;
+
+/* just to make code nicer when using curl_multi_socket() you can now check
+ for CURLM_CALL_MULTI_SOCKET too in the same style it works for
+ curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
+#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
+
+typedef enum {
+ CURLMSG_NONE, /* first, not used */
+ CURLMSG_DONE, /* This easy handle has completed. 'result' contains
+ the CURLcode of the transfer */
+ CURLMSG_LAST /* last, not used */
+} CURLMSG;
+
+struct CURLMsg {
+ CURLMSG msg; /* what this message means */
+ CURL *easy_handle; /* the handle it concerns */
+ union {
+ void *whatever; /* message-specific data */
+ CURLcode result; /* return code for transfer */
+ } data;
+};
+typedef struct CURLMsg CURLMsg;
+
+/*
+ * Name: curl_multi_init()
+ *
+ * Desc: inititalize multi-style curl usage
+ *
+ * Returns: a new CURLM handle to use in all 'curl_multi' functions.
+ */
+CURL_EXTERN CURLM *curl_multi_init(void);
+
+/*
+ * Name: curl_multi_add_handle()
+ *
+ * Desc: add a standard curl handle to the multi stack
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
+ CURL *curl_handle);
+
+ /*
+ * Name: curl_multi_remove_handle()
+ *
+ * Desc: removes a curl handle from the multi stack again
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
+ CURL *curl_handle);
+
+ /*
+ * Name: curl_multi_fdset()
+ *
+ * Desc: Ask curl for its fd_set sets. The app can use these to select() or
+ * poll() on. We want curl_multi_perform() called as soon as one of
+ * them are ready.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *exc_fd_set,
+ int *max_fd);
+
+ /*
+ * Name: curl_multi_perform()
+ *
+ * Desc: When the app thinks there's data available for curl it calls this
+ * function to read/write whatever there is right now. This returns
+ * as soon as the reads and writes are done. This function does not
+ * require that there actually is data available for reading or that
+ * data can be written, it can be called just in case. It returns
+ * the number of handles that still transfer data in the second
+ * argument's integer-pointer.
+ *
+ * Returns: CURLMcode type, general multi error code. *NOTE* that this only
+ * returns errors etc regarding the whole multi stack. There might
+ * still have occurred problems on invidual transfers even when this
+ * returns OK.
+ */
+CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
+ int *running_handles);
+
+ /*
+ * Name: curl_multi_cleanup()
+ *
+ * Desc: Cleans up and removes a whole multi stack. It does not free or
+ * touch any individual easy handles in any way. We need to define
+ * in what state those handles will be if this function is called
+ * in the middle of a transfer.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
+
+/*
+ * Name: curl_multi_info_read()
+ *
+ * Desc: Ask the multi handle if there's any messages/informationals from
+ * the individual transfers. Messages include informationals such as
+ * error code from the transfer or just the fact that a transfer is
+ * completed. More details on these should be written down as well.
+ *
+ * Repeated calls to this function will return a new struct each
+ * time, until a special "end of msgs" struct is returned as a signal
+ * that there is no more to get at this point.
+ *
+ * The data the returned pointer points to will not survive calling
+ * curl_multi_cleanup().
+ *
+ * The 'CURLMsg' struct is meant to be very simple and only contain
+ * very basic informations. If more involved information is wanted,
+ * we will provide the particular "transfer handle" in that struct
+ * and that should/could/would be used in subsequent
+ * curl_easy_getinfo() calls (or similar). The point being that we
+ * must never expose complex structs to applications, as then we'll
+ * undoubtably get backwards compatibility problems in the future.
+ *
+ * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
+ * of structs. It also writes the number of messages left in the
+ * queue (after this read) in the integer the second argument points
+ * to.
+ */
+CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
+ int *msgs_in_queue);
+
+/*
+ * Name: curl_multi_strerror()
+ *
+ * Desc: The curl_multi_strerror function may be used to turn a CURLMcode
+ * value into the equivalent human readable error string. This is
+ * useful for printing meaningful error messages.
+ *
+ * Returns: A pointer to a zero-terminated error message.
+ */
+CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
+
+/*
+ * Name: curl_multi_socket() and
+ * curl_multi_socket_all()
+ *
+ * Desc: An alternative version of curl_multi_perform() that allows the
+ * application to pass in one of the file descriptors that have been
+ * detected to have "action" on them and let libcurl perform.
+ * See man page for details.
+ */
+#define CURL_POLL_NONE 0
+#define CURL_POLL_IN 1
+#define CURL_POLL_OUT 2
+#define CURL_POLL_INOUT 3
+#define CURL_POLL_REMOVE 4
+
+#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
+
+#define CURL_CSELECT_IN 0x01
+#define CURL_CSELECT_OUT 0x02
+#define CURL_CSELECT_ERR 0x04
+
+typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
+ curl_socket_t s, /* socket */
+ int what, /* see above */
+ void *userp, /* private callback
+ pointer */
+ void *socketp); /* private socket
+ pointer */
+/*
+ * Name: curl_multi_timer_callback
+ *
+ * Desc: Called by libcurl whenever the library detects a change in the
+ * maximum number of milliseconds the app is allowed to wait before
+ * curl_multi_socket() or curl_multi_perform() must be called
+ * (to allow libcurl's timed events to take place).
+ *
+ * Returns: The callback should return zero.
+ */
+typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
+ long timeout_ms, /* see above */
+ void *userp); /* private callback
+ pointer */
+
+CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
+ int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
+ curl_socket_t s,
+ int ev_bitmask,
+ int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
+ int *running_handles);
+
+#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
+/* This macro below was added in 7.16.3 to push users who recompile to use
+ the new curl_multi_socket_action() instead of the old curl_multi_socket()
+*/
+#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
+#endif
+
+/*
+ * Name: curl_multi_timeout()
+ *
+ * Desc: Returns the maximum number of milliseconds the app is allowed to
+ * wait before curl_multi_socket() or curl_multi_perform() must be
+ * called (to allow libcurl's timed events to take place).
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
+ long *milliseconds);
+
+#undef CINIT /* re-using the same name as in curl.h */
+
+#ifdef CURL_ISOCPP
+#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG CURLOPTTYPE_LONG
+#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
+#endif
+
+typedef enum {
+ /* This is the socket callback function pointer */
+ CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
+
+ /* This is the argument passed to the socket callback */
+ CINIT(SOCKETDATA, OBJECTPOINT, 2),
+
+ /* set to 1 to enable pipelining for this multi handle */
+ CINIT(PIPELINING, LONG, 3),
+
+ /* This is the timer callback function pointer */
+ CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
+
+ /* This is the argument passed to the timer callback */
+ CINIT(TIMERDATA, OBJECTPOINT, 5),
+
+ /* maximum number of entries in the connection cache */
+ CINIT(MAXCONNECTS, LONG, 6),
+
+ CURLMOPT_LASTENTRY /* the last unused */
+} CURLMoption;
+
+
+/*
+ * Name: curl_multi_setopt()
+ *
+ * Desc: Sets options for the multi handle.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
+ CURLMoption option, ...);
+
+
+/*
+ * Name: curl_multi_assign()
+ *
+ * Desc: This function sets an association in the multi handle between the
+ * given socket and a private pointer of the application. This is
+ * (only) useful for curl_multi_socket uses.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
+ curl_socket_t sockfd, void *sockp);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif
diff --git a/curl/stdcheaders.h b/curl/stdcheaders.h
new file mode 100644
index 0000000..ad82ef6
--- /dev/null
+++ b/curl/stdcheaders.h
@@ -0,0 +1,33 @@
+#ifndef __STDC_HEADERS_H
+#define __STDC_HEADERS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, 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 <sys/types.h>
+
+size_t fread (void *, size_t, size_t, FILE *);
+size_t fwrite (const void *, size_t, size_t, FILE *);
+
+int strcasecmp(const char *, const char *);
+int strncasecmp(const char *, const char *, size_t);
+
+#endif /* __STDC_HEADERS_H */
diff --git a/curl/typecheck-gcc.h b/curl/typecheck-gcc.h
new file mode 100644
index 0000000..5c584b0
--- /dev/null
+++ b/curl/typecheck-gcc.h
@@ -0,0 +1,603 @@
+#ifndef __CURL_TYPECHECK_GCC_H
+#define __CURL_TYPECHECK_GCC_H
+/***************************************************************************
+ * _ _ ____ _
+ * 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.
+ *
+ ***************************************************************************/
+
+/* wraps curl_easy_setopt() with typechecking */
+
+/* To add a new kind of warning, add an
+ * if(_curl_is_sometype_option(_curl_opt))
+ * if(!_curl_is_sometype(value))
+ * _curl_easy_setopt_err_sometype();
+ * block and define _curl_is_sometype_option, _curl_is_sometype and
+ * _curl_easy_setopt_err_sometype below
+ *
+ * NOTE: We use two nested 'if' statements here instead of the && operator, in
+ * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x
+ * when compiling with -Wlogical-op.
+ *
+ * To add an option that uses the same type as an existing option, you'll just
+ * need to extend the appropriate _curl_*_option macro
+ */
+#define curl_easy_setopt(handle, option, value) \
+__extension__ ({ \
+ __typeof__ (option) _curl_opt = option; \
+ if(__builtin_constant_p(_curl_opt)) { \
+ if(_curl_is_long_option(_curl_opt)) \
+ if(!_curl_is_long(value)) \
+ _curl_easy_setopt_err_long(); \
+ if(_curl_is_off_t_option(_curl_opt)) \
+ if(!_curl_is_off_t(value)) \
+ _curl_easy_setopt_err_curl_off_t(); \
+ if(_curl_is_string_option(_curl_opt)) \
+ if(!_curl_is_string(value)) \
+ _curl_easy_setopt_err_string(); \
+ if(_curl_is_write_cb_option(_curl_opt)) \
+ if(!_curl_is_write_cb(value)) \
+ _curl_easy_setopt_err_write_callback(); \
+ if((_curl_opt) == CURLOPT_READFUNCTION) \
+ if(!_curl_is_read_cb(value)) \
+ _curl_easy_setopt_err_read_cb(); \
+ if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
+ if(!_curl_is_ioctl_cb(value)) \
+ _curl_easy_setopt_err_ioctl_cb(); \
+ if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
+ if(!_curl_is_sockopt_cb(value)) \
+ _curl_easy_setopt_err_sockopt_cb(); \
+ if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
+ if(!_curl_is_opensocket_cb(value)) \
+ _curl_easy_setopt_err_opensocket_cb(); \
+ if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
+ if(!_curl_is_progress_cb(value)) \
+ _curl_easy_setopt_err_progress_cb(); \
+ if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
+ if(!_curl_is_debug_cb(value)) \
+ _curl_easy_setopt_err_debug_cb(); \
+ if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
+ if(!_curl_is_ssl_ctx_cb(value)) \
+ _curl_easy_setopt_err_ssl_ctx_cb(); \
+ if(_curl_is_conv_cb_option(_curl_opt)) \
+ if(!_curl_is_conv_cb(value)) \
+ _curl_easy_setopt_err_conv_cb(); \
+ if((_curl_opt) == CURLOPT_SEEKFUNCTION) \
+ if(!_curl_is_seek_cb(value)) \
+ _curl_easy_setopt_err_seek_cb(); \
+ if(_curl_is_cb_data_option(_curl_opt)) \
+ if(!_curl_is_cb_data(value)) \
+ _curl_easy_setopt_err_cb_data(); \
+ if((_curl_opt) == CURLOPT_ERRORBUFFER) \
+ if(!_curl_is_error_buffer(value)) \
+ _curl_easy_setopt_err_error_buffer(); \
+ if((_curl_opt) == CURLOPT_STDERR) \
+ if(!_curl_is_FILE(value)) \
+ _curl_easy_setopt_err_FILE(); \
+ if(_curl_is_postfields_option(_curl_opt)) \
+ if(!_curl_is_postfields(value)) \
+ _curl_easy_setopt_err_postfields(); \
+ if((_curl_opt) == CURLOPT_HTTPPOST) \
+ if(!_curl_is_arr((value), struct curl_httppost)) \
+ _curl_easy_setopt_err_curl_httpost(); \
+ if(_curl_is_slist_option(_curl_opt)) \
+ if(!_curl_is_arr((value), struct curl_slist)) \
+ _curl_easy_setopt_err_curl_slist(); \
+ if((_curl_opt) == CURLOPT_SHARE) \
+ if(!_curl_is_ptr((value), CURLSH)) \
+ _curl_easy_setopt_err_CURLSH(); \
+ } \
+ curl_easy_setopt(handle, _curl_opt, value); \
+})
+
+/* wraps curl_easy_getinfo() with typechecking */
+/* FIXME: don't allow const pointers */
+#define curl_easy_getinfo(handle, info, arg) \
+__extension__ ({ \
+ __typeof__ (info) _curl_info = info; \
+ if(__builtin_constant_p(_curl_info)) { \
+ if(_curl_is_string_info(_curl_info)) \
+ if(!_curl_is_arr((arg), char *)) \
+ _curl_easy_getinfo_err_string(); \
+ if(_curl_is_long_info(_curl_info)) \
+ if(!_curl_is_arr((arg), long)) \
+ _curl_easy_getinfo_err_long(); \
+ if(_curl_is_double_info(_curl_info)) \
+ if(!_curl_is_arr((arg), double)) \
+ _curl_easy_getinfo_err_double(); \
+ if(_curl_is_slist_info(_curl_info)) \
+ if(!_curl_is_arr((arg), struct curl_slist *)) \
+ _curl_easy_getinfo_err_curl_slist(); \
+ } \
+ curl_easy_getinfo(handle, _curl_info, arg); \
+})
+
+/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
+ * for now just make sure that the functions are called with three
+ * arguments
+ */
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+
+
+/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
+ * functions */
+
+/* To define a new warning, use _CURL_WARNING(identifier, "message") */
+#define _CURL_WARNING(id, message) \
+ static void __attribute__((warning(message))) __attribute__((unused)) \
+ __attribute__((noinline)) id(void) { __asm__(""); }
+
+_CURL_WARNING(_curl_easy_setopt_err_long,
+ "curl_easy_setopt expects a long argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
+ "curl_easy_setopt expects a curl_off_t argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_string,
+ "curl_easy_setopt expects a "
+ "string (char* or char[]) argument for this option"
+ )
+_CURL_WARNING(_curl_easy_setopt_err_write_callback,
+ "curl_easy_setopt expects a curl_write_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_read_cb,
+ "curl_easy_setopt expects a curl_read_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
+ "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
+ "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
+ "curl_easy_setopt expects a "
+ "curl_opensocket_callback argument for this option"
+ )
+_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
+ "curl_easy_setopt expects a curl_progress_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
+ "curl_easy_setopt expects a curl_debug_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
+ "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
+ "curl_easy_setopt expects a curl_conv_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
+ "curl_easy_setopt expects a curl_seek_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_cb_data,
+ "curl_easy_setopt expects a "
+ "private data pointer as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
+ "curl_easy_setopt expects a "
+ "char buffer of CURL_ERROR_SIZE as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_FILE,
+ "curl_easy_setopt expects a FILE* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_postfields,
+ "curl_easy_setopt expects a void* or char* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
+ "curl_easy_setopt expects a struct curl_httppost* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
+ "curl_easy_setopt expects a struct curl_slist* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
+ "curl_easy_setopt expects a CURLSH* argument for this option")
+
+_CURL_WARNING(_curl_easy_getinfo_err_string,
+ "curl_easy_getinfo expects a pointer to char * for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_long,
+ "curl_easy_getinfo expects a pointer to long for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_double,
+ "curl_easy_getinfo expects a pointer to double for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
+ "curl_easy_getinfo expects a pointer to struct curl_slist * for this info")
+
+/* groups of curl_easy_setops options that take the same type of argument */
+
+/* To add a new option to one of the groups, just add
+ * (option) == CURLOPT_SOMETHING
+ * to the or-expression. If the option takes a long or curl_off_t, you don't
+ * have to do anything
+ */
+
+/* evaluates to true if option takes a long argument */
+#define _curl_is_long_option(option) \
+ (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
+
+#define _curl_is_off_t_option(option) \
+ ((option) > CURLOPTTYPE_OFF_T)
+
+/* evaluates to true if option takes a char* argument */
+#define _curl_is_string_option(option) \
+ ((option) == CURLOPT_URL || \
+ (option) == CURLOPT_PROXY || \
+ (option) == CURLOPT_INTERFACE || \
+ (option) == CURLOPT_NETRC_FILE || \
+ (option) == CURLOPT_USERPWD || \
+ (option) == CURLOPT_USERNAME || \
+ (option) == CURLOPT_PASSWORD || \
+ (option) == CURLOPT_PROXYUSERPWD || \
+ (option) == CURLOPT_PROXYUSERNAME || \
+ (option) == CURLOPT_PROXYPASSWORD || \
+ (option) == CURLOPT_NOPROXY || \
+ (option) == CURLOPT_ACCEPT_ENCODING || \
+ (option) == CURLOPT_REFERER || \
+ (option) == CURLOPT_USERAGENT || \
+ (option) == CURLOPT_COOKIE || \
+ (option) == CURLOPT_COOKIEFILE || \
+ (option) == CURLOPT_COOKIEJAR || \
+ (option) == CURLOPT_COOKIELIST || \
+ (option) == CURLOPT_FTPPORT || \
+ (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
+ (option) == CURLOPT_FTP_ACCOUNT || \
+ (option) == CURLOPT_RANGE || \
+ (option) == CURLOPT_CUSTOMREQUEST || \
+ (option) == CURLOPT_SSLCERT || \
+ (option) == CURLOPT_SSLCERTTYPE || \
+ (option) == CURLOPT_SSLKEY || \
+ (option) == CURLOPT_SSLKEYTYPE || \
+ (option) == CURLOPT_KEYPASSWD || \
+ (option) == CURLOPT_SSLENGINE || \
+ (option) == CURLOPT_CAINFO || \
+ (option) == CURLOPT_CAPATH || \
+ (option) == CURLOPT_RANDOM_FILE || \
+ (option) == CURLOPT_EGDSOCKET || \
+ (option) == CURLOPT_SSL_CIPHER_LIST || \
+ (option) == CURLOPT_KRBLEVEL || \
+ (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \
+ (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \
+ (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \
+ (option) == CURLOPT_CRLFILE || \
+ (option) == CURLOPT_ISSUERCERT || \
+ (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \
+ (option) == CURLOPT_SSH_KNOWNHOSTS || \
+ (option) == CURLOPT_MAIL_FROM || \
+ (option) == CURLOPT_RTSP_SESSION_ID || \
+ (option) == CURLOPT_RTSP_STREAM_URI || \
+ (option) == CURLOPT_RTSP_TRANSPORT || \
+ 0)
+
+/* evaluates to true if option takes a curl_write_callback argument */
+#define _curl_is_write_cb_option(option) \
+ ((option) == CURLOPT_HEADERFUNCTION || \
+ (option) == CURLOPT_WRITEFUNCTION)
+
+/* evaluates to true if option takes a curl_conv_callback argument */
+#define _curl_is_conv_cb_option(option) \
+ ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \
+ (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \
+ (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
+
+/* evaluates to true if option takes a data argument to pass to a callback */
+#define _curl_is_cb_data_option(option) \
+ ((option) == CURLOPT_WRITEDATA || \
+ (option) == CURLOPT_READDATA || \
+ (option) == CURLOPT_IOCTLDATA || \
+ (option) == CURLOPT_SOCKOPTDATA || \
+ (option) == CURLOPT_OPENSOCKETDATA || \
+ (option) == CURLOPT_PROGRESSDATA || \
+ (option) == CURLOPT_WRITEHEADER || \
+ (option) == CURLOPT_DEBUGDATA || \
+ (option) == CURLOPT_SSL_CTX_DATA || \
+ (option) == CURLOPT_SEEKDATA || \
+ (option) == CURLOPT_PRIVATE || \
+ (option) == CURLOPT_SSH_KEYDATA || \
+ (option) == CURLOPT_INTERLEAVEDATA || \
+ (option) == CURLOPT_CHUNK_DATA || \
+ (option) == CURLOPT_FNMATCH_DATA || \
+ 0)
+
+/* evaluates to true if option takes a POST data argument (void* or char*) */
+#define _curl_is_postfields_option(option) \
+ ((option) == CURLOPT_POSTFIELDS || \
+ (option) == CURLOPT_COPYPOSTFIELDS || \
+ 0)
+
+/* evaluates to true if option takes a struct curl_slist * argument */
+#define _curl_is_slist_option(option) \
+ ((option) == CURLOPT_HTTPHEADER || \
+ (option) == CURLOPT_HTTP200ALIASES || \
+ (option) == CURLOPT_QUOTE || \
+ (option) == CURLOPT_POSTQUOTE || \
+ (option) == CURLOPT_PREQUOTE || \
+ (option) == CURLOPT_TELNETOPTIONS || \
+ (option) == CURLOPT_MAIL_RCPT || \
+ 0)
+
+/* groups of curl_easy_getinfo infos that take the same type of argument */
+
+/* evaluates to true if info expects a pointer to char * argument */
+#define _curl_is_string_info(info) \
+ (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
+
+/* evaluates to true if info expects a pointer to long argument */
+#define _curl_is_long_info(info) \
+ (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
+
+/* evaluates to true if info expects a pointer to double argument */
+#define _curl_is_double_info(info) \
+ (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
+
+/* true if info expects a pointer to struct curl_slist * argument */
+#define _curl_is_slist_info(info) \
+ (CURLINFO_SLIST < (info))
+
+
+/* typecheck helpers -- check whether given expression has requested type*/
+
+/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
+ * otherwise define a new macro. Search for __builtin_types_compatible_p
+ * in the GCC manual.
+ * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
+ * the actual expression passed to the curl_easy_setopt macro. This
+ * means that you can only apply the sizeof and __typeof__ operators, no
+ * == or whatsoever.
+ */
+
+/* XXX: should evaluate to true iff expr is a pointer */
+#define _curl_is_any_ptr(expr) \
+ (sizeof(expr) == sizeof(void*))
+
+/* evaluates to true if expr is NULL */
+/* XXX: must not evaluate expr, so this check is not accurate */
+#define _curl_is_NULL(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
+
+/* evaluates to true if expr is type*, const type* or NULL */
+#define _curl_is_ptr(expr, type) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), type *) || \
+ __builtin_types_compatible_p(__typeof__(expr), const type *))
+
+/* evaluates to true if expr is one of type[], type*, NULL or const type* */
+#define _curl_is_arr(expr, type) \
+ (_curl_is_ptr((expr), type) || \
+ __builtin_types_compatible_p(__typeof__(expr), type []))
+
+/* evaluates to true if expr is a string */
+#define _curl_is_string(expr) \
+ (_curl_is_arr((expr), char) || \
+ _curl_is_arr((expr), signed char) || \
+ _curl_is_arr((expr), unsigned char))
+
+/* evaluates to true if expr is a long (no matter the signedness)
+ * XXX: for now, int is also accepted (and therefore short and char, which
+ * are promoted to int when passed to a variadic function) */
+#define _curl_is_long(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), long) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed long) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \
+ __builtin_types_compatible_p(__typeof__(expr), int) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed int) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \
+ __builtin_types_compatible_p(__typeof__(expr), short) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed short) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \
+ __builtin_types_compatible_p(__typeof__(expr), char) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed char) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned char))
+
+/* evaluates to true if expr is of type curl_off_t */
+#define _curl_is_off_t(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
+
+/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
+/* XXX: also check size of an char[] array? */
+#define _curl_is_error_buffer(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), char *) || \
+ __builtin_types_compatible_p(__typeof__(expr), char[]))
+
+/* evaluates to true if expr is of type (const) void* or (const) FILE* */
+#if 0
+#define _curl_is_cb_data(expr) \
+ (_curl_is_ptr((expr), void) || \
+ _curl_is_ptr((expr), FILE))
+#else /* be less strict */
+#define _curl_is_cb_data(expr) \
+ _curl_is_any_ptr(expr)
+#endif
+
+/* evaluates to true if expr is of type FILE* */
+#define _curl_is_FILE(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), FILE *))
+
+/* evaluates to true if expr can be passed as POST data (void* or char*) */
+#define _curl_is_postfields(expr) \
+ (_curl_is_ptr((expr), void) || \
+ _curl_is_arr((expr), char))
+
+/* FIXME: the whole callback checking is messy...
+ * The idea is to tolerate char vs. void and const vs. not const
+ * pointers in arguments at least
+ */
+/* helper: __builtin_types_compatible_p distinguishes between functions and
+ * function pointers, hide it */
+#define _curl_callback_compatible(func, type) \
+ (__builtin_types_compatible_p(__typeof__(func), type) || \
+ __builtin_types_compatible_p(__typeof__(func), type*))
+
+/* evaluates to true if expr is of type curl_read_callback or "similar" */
+#define _curl_is_read_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \
+ _curl_callback_compatible((expr), _curl_read_callback1) || \
+ _curl_callback_compatible((expr), _curl_read_callback2) || \
+ _curl_callback_compatible((expr), _curl_read_callback3) || \
+ _curl_callback_compatible((expr), _curl_read_callback4) || \
+ _curl_callback_compatible((expr), _curl_read_callback5) || \
+ _curl_callback_compatible((expr), _curl_read_callback6))
+typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*);
+typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*);
+typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*);
+typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*);
+typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*);
+typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
+
+/* evaluates to true if expr is of type curl_write_callback or "similar" */
+#define _curl_is_write_cb(expr) \
+ (_curl_is_read_cb(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \
+ _curl_callback_compatible((expr), _curl_write_callback1) || \
+ _curl_callback_compatible((expr), _curl_write_callback2) || \
+ _curl_callback_compatible((expr), _curl_write_callback3) || \
+ _curl_callback_compatible((expr), _curl_write_callback4) || \
+ _curl_callback_compatible((expr), _curl_write_callback5) || \
+ _curl_callback_compatible((expr), _curl_write_callback6))
+typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback2)(const char *, size_t, size_t,
+ const void*);
+typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*);
+typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback5)(const void *, size_t, size_t,
+ const void*);
+typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
+
+/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
+#define _curl_is_ioctl_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \
+ _curl_callback_compatible((expr), _curl_ioctl_callback1) || \
+ _curl_callback_compatible((expr), _curl_ioctl_callback2) || \
+ _curl_callback_compatible((expr), _curl_ioctl_callback3) || \
+ _curl_callback_compatible((expr), _curl_ioctl_callback4))
+typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*);
+typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*);
+typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*);
+typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*);
+
+/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
+#define _curl_is_sockopt_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \
+ _curl_callback_compatible((expr), _curl_sockopt_callback1) || \
+ _curl_callback_compatible((expr), _curl_sockopt_callback2))
+typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
+typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t,
+ curlsocktype);
+
+/* evaluates to true if expr is of type curl_opensocket_callback or
+ "similar" */
+#define _curl_is_opensocket_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\
+ _curl_callback_compatible((expr), _curl_opensocket_callback1) || \
+ _curl_callback_compatible((expr), _curl_opensocket_callback2) || \
+ _curl_callback_compatible((expr), _curl_opensocket_callback3) || \
+ _curl_callback_compatible((expr), _curl_opensocket_callback4))
+typedef curl_socket_t (_curl_opensocket_callback1)
+ (void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback2)
+ (void *, curlsocktype, const struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback3)
+ (const void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback4)
+ (const void *, curlsocktype, const struct curl_sockaddr *);
+
+/* evaluates to true if expr is of type curl_progress_callback or "similar" */
+#define _curl_is_progress_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \
+ _curl_callback_compatible((expr), _curl_progress_callback1) || \
+ _curl_callback_compatible((expr), _curl_progress_callback2))
+typedef int (_curl_progress_callback1)(void *,
+ double, double, double, double);
+typedef int (_curl_progress_callback2)(const void *,
+ double, double, double, double);
+
+/* evaluates to true if expr is of type curl_debug_callback or "similar" */
+#define _curl_is_debug_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \
+ _curl_callback_compatible((expr), _curl_debug_callback1) || \
+ _curl_callback_compatible((expr), _curl_debug_callback2) || \
+ _curl_callback_compatible((expr), _curl_debug_callback3) || \
+ _curl_callback_compatible((expr), _curl_debug_callback4) || \
+ _curl_callback_compatible((expr), _curl_debug_callback5) || \
+ _curl_callback_compatible((expr), _curl_debug_callback6) || \
+ _curl_callback_compatible((expr), _curl_debug_callback7) || \
+ _curl_callback_compatible((expr), _curl_debug_callback8))
+typedef int (_curl_debug_callback1) (CURL *,
+ curl_infotype, char *, size_t, void *);
+typedef int (_curl_debug_callback2) (CURL *,
+ curl_infotype, char *, size_t, const void *);
+typedef int (_curl_debug_callback3) (CURL *,
+ curl_infotype, const char *, size_t, void *);
+typedef int (_curl_debug_callback4) (CURL *,
+ curl_infotype, const char *, size_t, const void *);
+typedef int (_curl_debug_callback5) (CURL *,
+ curl_infotype, unsigned char *, size_t, void *);
+typedef int (_curl_debug_callback6) (CURL *,
+ curl_infotype, unsigned char *, size_t, const void *);
+typedef int (_curl_debug_callback7) (CURL *,
+ curl_infotype, const unsigned char *, size_t, void *);
+typedef int (_curl_debug_callback8) (CURL *,
+ curl_infotype, const unsigned char *, size_t, const void *);
+
+/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
+/* this is getting even messier... */
+#define _curl_is_ssl_ctx_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
+typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *);
+typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
+typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
+typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *);
+#ifdef HEADER_SSL_H
+/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
+ * this will of course break if we're included before OpenSSL headers...
+ */
+typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
+typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
+typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
+typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX,
+ const void *);
+#else
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
+#endif
+
+/* evaluates to true if expr is of type curl_conv_callback or "similar" */
+#define _curl_is_conv_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \
+ _curl_callback_compatible((expr), _curl_conv_callback1) || \
+ _curl_callback_compatible((expr), _curl_conv_callback2) || \
+ _curl_callback_compatible((expr), _curl_conv_callback3) || \
+ _curl_callback_compatible((expr), _curl_conv_callback4))
+typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
+typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
+typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
+typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
+
+/* evaluates to true if expr is of type curl_seek_callback or "similar" */
+#define _curl_is_seek_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \
+ _curl_callback_compatible((expr), _curl_seek_callback1) || \
+ _curl_callback_compatible((expr), _curl_seek_callback2))
+typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
+typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
+
+
+#endif /* __CURL_TYPECHECK_GCC_H */
diff --git a/curlmanager.cpp b/curlmanager.cpp
new file mode 100644
index 0000000..973d133
--- /dev/null
+++ b/curlmanager.cpp
@@ -0,0 +1,897 @@
+#include "curlmanager.h"
+
+#ifdef PLATFORM_LINUX
+#include <netinet/in.h>
+#endif
+
+
+cURLManager g_cURLManager;
+
+
+struct data_t {
+ data_t(cURLHandle *_handle, size_t _bytes, size_t _nmemb):
+ handle(_handle), buffer(NULL), bytes(_bytes), nmemb(_nmemb)
+ {
+ }
+ cURLHandle *handle;
+ char *buffer;
+ size_t bytes;
+ size_t nmemb;
+ size_t return_value;
+};
+
+/* Write Function */
+static size_t curl_write_function_default(void *ptr, size_t bytes, size_t nmemb, void *stream)
+{
+ FILE *file = (FILE *)stream;
+#ifdef WIN32
+ if(file->_file >= 3)
+#else
+ if(file->_fileno >= 3)
+#endif
+ {
+ return fwrite(ptr, bytes, nmemb, file);
+ }
+ return (bytes * nmemb);
+}
+
+static size_t Call_Write_Function(cURLHandle *handle, const char *buffer, size_t bytes, size_t nmemb)
+{
+ IPluginFunction *pFunc = handle->callback_Function[cURL_CallBack_WRITE_FUNCTION];
+ assert((pFunc != NULL));
+ cell_t result = bytes * nmemb;
+ if(pFunc != NULL)
+ {
+ pFunc->PushCell(handle->hndl);
+ pFunc->PushStringEx((char *)buffer, nmemb+1, SM_PARAM_STRING_COPY|SM_PARAM_STRING_BINARY, 0);
+ pFunc->PushCell(bytes);
+ pFunc->PushCell(nmemb);
+ pFunc->PushCell(handle->UserData[UserData_Type_Write_Func]);
+ pFunc->Execute(&result);
+ }
+ return result;
+}
+
+static void sm_write_function_FrameAction(void *data)
+{
+ if(data == NULL)
+ return;
+
+ data_t *wdata = (data_t*)data;
+ wdata->return_value = Call_Write_Function(wdata->handle, wdata->buffer, wdata->bytes, wdata->nmemb);
+ wdata->handle->thread->EventSignal();
+}
+
+static size_t curl_write_function_SM(void *ptr, size_t bytes, size_t nmemb, void *stream)
+{
+ cURLHandle *handle = (cURLHandle *)stream;
+
+ size_t ret;
+ if(handle->thread == NULL)
+ {
+ char *buffer = new char[nmemb+1];
+ memcpy(buffer,ptr, nmemb);
+ buffer[nmemb] = '\0';
+ ret = Call_Write_Function(handle, buffer, bytes, nmemb);
+ delete [] buffer;
+ } else {
+ if(g_cURL_SM.IsShutdown())
+ return (bytes * nmemb);
+
+ data_t *data = new data_t(handle, bytes, nmemb);
+ data->buffer = new char[nmemb+1];
+ memcpy(data->buffer,ptr, nmemb);
+ data->buffer[nmemb] = '\0';
+
+ smutils->AddFrameAction(sm_write_function_FrameAction, data);
+ handle->thread->EventWait();
+
+ ret = data->return_value;
+ delete [] data->buffer;
+ delete data;
+
+ if(g_cURL_SM.IsShutdown())
+ return (bytes * nmemb);
+ }
+
+ return ret;
+}
+
+/* Read Function */
+static size_t Call_Read_Function(cURLHandle *handle, size_t bytes, size_t nmemb)
+{
+ IPluginFunction *pFunc = handle->callback_Function[cURL_CallBack_READ_FUNCTION];
+ assert((pFunc != NULL));
+ cell_t result = bytes * nmemb;
+ if(pFunc != NULL)
+ {
+ pFunc->PushCell(handle->hndl);
+ pFunc->PushCell(bytes);
+ pFunc->PushCell(nmemb);
+ pFunc->PushCell(handle->UserData[UserData_Type_Read_Func]);
+ pFunc->Execute(&result);
+ }
+ return result;
+}
+
+static void sm_read_function_FrameAction(void *data)
+{
+ if(data == NULL)
+ return;
+
+ data_t *rdata = (data_t*)data;
+ rdata->return_value = Call_Read_Function(rdata->handle, rdata->bytes, rdata->nmemb);
+ rdata->handle->thread->EventSignal();
+}
+
+
+static size_t curl_read_function_SM(char *ptr, size_t bytes, size_t nmemb, void *stream)
+{
+ cURLHandle *handle = (cURLHandle *)stream;
+
+ size_t ret = 0;
+ if(handle->thread == NULL)
+ {
+ ret = Call_Read_Function(handle, bytes, nmemb);
+ } else {
+ if(g_cURL_SM.IsShutdown())
+ return 0;
+
+ data_t *data = new data_t(handle, bytes, nmemb);
+
+ smutils->AddFrameAction(sm_read_function_FrameAction, data);
+ handle->thread->EventWait();
+
+ ret = data->return_value;
+ delete data;
+
+ if(g_cURL_SM.IsShutdown())
+ return 0;
+ }
+
+ if(ret > 0)
+ {
+ memcpy(ptr,handle->send_buffer.data(), handle->send_buffer.size());
+ }
+
+ return ret;
+}
+
+static curl_socket_t curl_opensocket_function(void *clientp, curlsocktype purpose, struct curl_sockaddr *address)
+{
+ cURLHandle *handle = (cURLHandle *)clientp;
+ if(handle->is_udp)
+ {
+ address->socktype = SOCK_DGRAM;
+ address->protocol = IPPROTO_UDP;
+ address->family = AF_INET;
+ }
+
+ return socket(address->family, address->socktype, address->protocol);
+}
+
+void cURLManager::SDK_OnLoad()
+{
+ curlhandle_list_mutex = threader->MakeMutex();
+ shutdown_event = threader->MakeEventSignal();
+ closehelper_list_mutex = threader->MakeMutex();
+
+ waiting = false;
+}
+
+void cURLManager::SDK_OnUnload()
+{
+ curlhandle_list_mutex->Lock();
+ if(g_cURLThread_List.size() > 0)
+ {
+ printf("[%s] Waiting %d cURL Threads Terminate...\n",SMEXT_CONF_LOGTAG,g_cURLThread_List.size());
+
+ SourceHook::List<cURLThread *>::iterator iter = g_cURLThread_List.begin();
+ cURLThread *pInfo;
+ while (iter != g_cURLThread_List.end())
+ {
+ pInfo = (*iter);
+ if(pInfo->waiting) {
+ pInfo->event->Signal();
+ }
+ iter++;
+ }
+
+ curlhandle_list_mutex->Unlock();
+
+ waiting = true;
+ shutdown_event->Wait();
+
+ printf("[%s] All cURL Thread Terminated !!!\n",SMEXT_CONF_LOGTAG);
+ } else {
+ curlhandle_list_mutex->Unlock();
+ }
+
+ shutdown_event->DestroyThis();
+ curlhandle_list_mutex->DestroyThis();
+
+ shutdown_event = NULL;
+ curlhandle_list_mutex = NULL;
+ g_cURLThread_List.clear();
+
+ g_CloseHelper_List.clear();
+}
+
+void cURLManager::CreatecURLThread(cURLThread *thread)
+{
+ if(g_cURL_SM.IsShutdown())
+ {
+ delete thread;
+ return;
+ }
+ curlhandle_list_mutex->Lock();
+ g_cURLThread_List.push_back(thread);
+ curlhandle_list_mutex->Unlock();
+
+ threader->MakeThread(thread);
+}
+
+void cURLManager::RemovecURLThread(cURLThread *thread)
+{
+ if(g_cURL_SM.IsShutdown())
+ {
+ RemovecURLHandle(thread->handle);
+ }
+
+ curlhandle_list_mutex->Lock();
+ g_cURLThread_List.remove(thread);
+
+ if(waiting)
+ {
+ if(g_cURLThread_List.size() == 0)
+ {
+ curlhandle_list_mutex->Unlock();
+ shutdown_event->Signal();
+ return;
+ }
+ }
+ curlhandle_list_mutex->Unlock();
+}
+
+void cURLManager::AddCloseHelperHandle(ICloseHelper *helper)
+{
+ closehelper_list_mutex->Lock();
+ if(g_CloseHelper_List.find(helper) == g_CloseHelper_List.end())
+ {
+ g_CloseHelper_List.push_back(helper);
+ }
+ closehelper_list_mutex->Unlock();
+}
+
+void cURLManager::RemoveCloseHelperHandle(ICloseHelper *helper)
+{
+ closehelper_list_mutex->Lock();
+ g_CloseHelper_List.remove(helper);
+ closehelper_list_mutex->Unlock();
+}
+
+void cURLManager::RemoveLinkedICloseHelper(cURLHandle *handle)
+{
+ closehelper_list_mutex->Lock();
+
+ SourceHook::List<ICloseHelper *>::iterator iter;
+ ICloseHelper *pInfo;
+ for (iter=g_CloseHelper_List.begin(); iter!=g_CloseHelper_List.end(); iter++)
+ {
+ pInfo = (*iter);
+ if(pInfo->_handle == handle)
+ {
+ pInfo->_handle = NULL;
+ if(pInfo->_marked_delete)
+ {
+ pInfo->Delete();
+ iter = g_CloseHelper_List.erase(iter);
+ }
+ }
+ }
+
+ closehelper_list_mutex->Unlock();
+}
+
+void cURLManager::RemovecURLHandle(cURLHandle *handle)
+{
+ if(!handle || handle->running)
+ return;
+
+ if(handle->thread != NULL)
+ {
+ handle->thread->handle = NULL;
+ }
+ curl_easy_cleanup(handle->curl);
+ handle->curl = NULL;
+
+ SourceHook::List<cURLOpt_string *>::iterator iter;
+ cURLOpt_string *pInfo;
+ for (iter=handle->opt_string_list.begin(); iter!=handle->opt_string_list.end(); iter++)
+ {
+ pInfo = (*iter);
+ delete [] pInfo->value;
+ delete pInfo;
+ }
+ handle->opt_string_list.clear();
+
+ SourceHook::List<cURLOpt_int *>::iterator iter2;
+ cURLOpt_int*pInfo2;
+ for (iter2=handle->opt_int_list.begin(); iter2!=handle->opt_int_list.end(); iter2++)
+ {
+ pInfo2 = (*iter2);
+ delete pInfo2;
+ }
+ handle->opt_int_list.clear();
+
+ SourceHook::List<cURLOpt_pointer *>::iterator iter3;
+ cURLOpt_pointer *pInfo3;
+ for(iter3=handle->opt_pointer_list.begin(); iter3!=handle->opt_pointer_list.end(); iter3++)
+ {
+ pInfo3 = (*iter3);
+ delete pInfo3;
+ }
+ handle->opt_pointer_list.clear();
+
+ SourceHook::List<cURLOpt_int64 *>::iterator iter4;
+ cURLOpt_int64 *pInfo4;
+ for(iter4=handle->opt_int64_list.begin(); iter4!=handle->opt_int64_list.end(); iter4++)
+ {
+ pInfo4 = (*iter4);
+ delete pInfo4;
+ }
+ handle->opt_int64_list.clear();
+
+ handle->send_buffer.clear();
+
+ RemoveLinkedICloseHelper(handle);
+
+ delete handle;
+}
+
+bool cURLManager::AddcURLOptionString(cURLHandle *handle, CURLoption opt, char *value)
+{
+ if(!handle || handle->running || !value)
+ return false;
+
+ std::string value_str;
+
+ bool supported = false;
+ switch(opt)
+ {
+ case CURLOPT_URL:
+ {
+ char *lowercase_value = UTIL_ToLowerCase(value);
+ std::string value_str_lower(lowercase_value);
+ delete [] lowercase_value;
+
+ if(!value_str_lower.compare(0,6, "udp://"))
+ {
+ handle->is_udp = true;
+ value_str.assign(&value[6]);
+ } else {
+ value_str = value;
+ handle->is_udp = false;
+ }
+ supported = true;
+ break;
+ }
+ case CURLOPT_PROXY:
+ case CURLOPT_PROXYUSERPWD:
+ case CURLOPT_RANGE:
+ case CURLOPT_USERPWD:
+ case CURLOPT_KEYPASSWD:
+ case CURLOPT_POSTFIELDS:
+ case CURLOPT_REFERER:
+ case CURLOPT_FTPPORT:
+ case CURLOPT_USERAGENT:
+ case CURLOPT_COOKIE:
+ case CURLOPT_ENCODING:
+ case CURLOPT_CUSTOMREQUEST:
+ case CURLOPT_WRITEINFO:
+ case CURLOPT_INTERFACE:
+ case CURLOPT_KRBLEVEL:
+ case CURLOPT_SSL_CIPHER_LIST:
+ case CURLOPT_SSLCERTTYPE:
+ case CURLOPT_SSLKEYTYPE:
+ case CURLOPT_SSLENGINE:
+ case CURLOPT_FTP_ACCOUNT:
+ case CURLOPT_COOKIELIST:
+ case CURLOPT_FTP_ALTERNATIVE_TO_USER:
+ case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
+ case CURLOPT_USERNAME:
+ case CURLOPT_PASSWORD:
+ case CURLOPT_PROXYUSERNAME:
+ case CURLOPT_PROXYPASSWORD:
+ case CURLOPT_NOPROXY:
+ case CURLOPT_SOCKS5_GSSAPI_SERVICE:
+ case CURLOPT_MAIL_FROM:
+ case CURLOPT_RTSP_SESSION_ID:
+ case CURLOPT_RTSP_STREAM_URI:
+ case CURLOPT_RTSP_TRANSPORT:
+ value_str.assign(value);
+ supported = true;
+ break;
+ case CURLOPT_COOKIEFILE:
+ case CURLOPT_COOKIEJAR:
+ case CURLOPT_RANDOM_FILE:
+ case CURLOPT_EGDSOCKET:
+ case CURLOPT_SSLCERT:
+ case CURLOPT_SSLKEY:
+ case CURLOPT_CAINFO:
+ case CURLOPT_CAPATH:
+ case CURLOPT_NETRC_FILE:
+ case CURLOPT_SSH_PUBLIC_KEYFILE:
+ case CURLOPT_SSH_PRIVATE_KEYFILE:
+ case CURLOPT_CRLFILE:
+ case CURLOPT_ISSUERCERT:
+ case CURLOPT_SSH_KNOWNHOSTS:
+ {
+ char realpath[PLATFORM_MAX_PATH];
+ g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", value);
+ value_str.assign(realpath);
+ supported = true;
+ break;
+ }
+ }
+
+ assert((supported != false));
+ if(!supported)
+ return false;
+
+ cURLOpt_string *stringopt = new cURLOpt_string();
+ stringopt->opt = opt;
+ stringopt->value = new char[value_str.size()+1];
+ memset(stringopt->value, 0, value_str.size()+1);
+ memcpy(stringopt->value,value_str.c_str(), value_str.size());
+
+ handle->opt_string_list.push_back(stringopt);
+
+ return true;
+}
+
+bool cURLManager::AddcURLOptionInt(cURLHandle *handle, CURLoption opt, int value)
+{
+ if(!handle || handle->running)
+ return false;
+
+ bool supported = false;
+ switch(opt)
+ {
+ case CURLOPT_PORT:
+ case CURLOPT_NOPROGRESS:
+ case CURLOPT_VERBOSE:
+ case CURLOPT_PROXYTYPE:
+ case CURLOPT_HTTPPROXYTUNNEL:
+ case CURLOPT_TIMEOUT:
+ case CURLOPT_SSL_VERIFYPEER:
+ case CURLOPT_SSL_VERIFYHOST:
+ case CURLOPT_UPLOAD:
+ case CURLOPT_INFILESIZE:
+ case CURLOPT_LOW_SPEED_LIMIT:
+ case CURLOPT_LOW_SPEED_TIME:
+ case CURLOPT_RESUME_FROM:
+ case CURLOPT_CRLF:
+ case CURLOPT_SSLVERSION:
+ case CURLOPT_TIMECONDITION:
+ case CURLOPT_TIMEVALUE:
+ case CURLOPT_HEADER:
+ case CURLOPT_NOBODY:
+ case CURLOPT_FAILONERROR:
+ case CURLOPT_POST:
+ case CURLOPT_DIRLISTONLY:
+ case CURLOPT_APPEND:
+ case CURLOPT_NETRC:
+ case CURLOPT_FOLLOWLOCATION:
+ case CURLOPT_TRANSFERTEXT:
+ case CURLOPT_PUT:
+ case CURLOPT_AUTOREFERER:
+ case CURLOPT_PROXYPORT:
+ case CURLOPT_POSTFIELDSIZE:
+ case CURLOPT_MAXREDIRS:
+ case CURLOPT_FILETIME:
+ case CURLOPT_MAXCONNECTS:
+ case CURLOPT_CLOSEPOLICY:
+ case CURLOPT_FRESH_CONNECT:
+ case CURLOPT_FORBID_REUSE:
+ case CURLOPT_CONNECTTIMEOUT:
+ case CURLOPT_HTTPGET:
+ case CURLOPT_HTTP_VERSION:
+ case CURLOPT_FTP_USE_EPSV:
+ case CURLOPT_SSLENGINE_DEFAULT:
+ case CURLOPT_DNS_USE_GLOBAL_CACHE:
+ case CURLOPT_DNS_CACHE_TIMEOUT:
+ case CURLOPT_COOKIESESSION:
+ case CURLOPT_BUFFERSIZE:
+ case CURLOPT_NOSIGNAL:
+ case CURLOPT_UNRESTRICTED_AUTH:
+ case CURLOPT_FTP_USE_EPRT:
+ case CURLOPT_HTTPAUTH:
+ case CURLOPT_FTP_CREATE_MISSING_DIRS:
+ case CURLOPT_PROXYAUTH:
+ case CURLOPT_FTP_RESPONSE_TIMEOUT:
+ case CURLOPT_IPRESOLVE:
+ case CURLOPT_MAXFILESIZE:
+ case CURLOPT_USE_SSL:
+ case CURLOPT_TCP_NODELAY:
+ case CURLOPT_FTPSSLAUTH:
+ case CURLOPT_IGNORE_CONTENT_LENGTH:
+ case CURLOPT_FTP_SKIP_PASV_IP:
+ case CURLOPT_FTP_FILEMETHOD:
+ case CURLOPT_LOCALPORT:
+ case CURLOPT_LOCALPORTRANGE:
+ case CURLOPT_CONNECT_ONLY:
+ case CURLOPT_SSL_SESSIONID_CACHE:
+ case CURLOPT_SSH_AUTH_TYPES:
+ case CURLOPT_FTP_SSL_CCC:
+ case CURLOPT_TIMEOUT_MS:
+ case CURLOPT_CONNECTTIMEOUT_MS:
+ case CURLOPT_HTTP_TRANSFER_DECODING:
+ case CURLOPT_HTTP_CONTENT_DECODING:
+ case CURLOPT_NEW_FILE_PERMS:
+ case CURLOPT_NEW_DIRECTORY_PERMS:
+ case CURLOPT_POSTREDIR:
+ case CURLOPT_PROXY_TRANSFER_MODE:
+ case CURLOPT_ADDRESS_SCOPE:
+ case CURLOPT_CERTINFO:
+ case CURLOPT_TFTP_BLKSIZE:
+ case CURLOPT_PROTOCOLS:
+ case CURLOPT_REDIR_PROTOCOLS:
+ case CURLOPT_FTP_USE_PRET:
+ case CURLOPT_RTSP_REQUEST:
+ case CURLOPT_RTSP_CLIENT_CSEQ:
+ case CURLOPT_RTSP_SERVER_CSEQ:
+ case CURLOPT_WILDCARDMATCH:
+ case CURLOPT_TRANSFER_ENCODING:
+ case CURLOPT_GSSAPI_DELEGATION:
+ supported = true;
+ break;
+ }
+
+ assert((supported != false));
+ if(!supported)
+ return false;
+
+ cURLOpt_int *intopt = new cURLOpt_int();
+ intopt->opt = opt;
+ intopt->value = value;
+
+ handle->opt_int_list.push_back(intopt);
+
+ return true;
+}
+
+bool cURLManager::AddcURLOptionInt64(cURLHandle *handle, CURLoption opt, long long value)
+{
+ if(!handle || handle->running)
+ return false;
+
+ bool supported = false;
+ switch(opt)
+ {
+ case CURLOPT_INFILESIZE_LARGE:
+ case CURLOPT_RESUME_FROM_LARGE:
+ case CURLOPT_MAXFILESIZE_LARGE:
+ case CURLOPT_POSTFIELDSIZE_LARGE:
+ case CURLOPT_MAX_SEND_SPEED_LARGE:
+ case CURLOPT_MAX_RECV_SPEED_LARGE:
+ supported = true;
+ break;
+ }
+
+ assert((supported != false));
+ if(!supported)
+ return false;
+
+ cURLOpt_int64 *int64opt = new cURLOpt_int64();
+ int64opt->opt = opt;
+ int64opt->value = (curl_off_t)value;
+
+ handle->opt_int64_list.push_back(int64opt);
+ return true;
+}
+
+bool cURLManager::AddcURLOptionFunction(IPluginContext *pContext, cURLHandle *handle, CURLoption opt, IPluginFunction *pFunction, int value)
+{
+ if(!handle || handle->running)
+ return false;
+
+ cURL_CallBack index = cURL_CallBack_NOTHING;
+ switch(opt)
+ {
+ case CURLOPT_WRITEFUNCTION:
+ index = cURL_CallBack_WRITE_FUNCTION;
+ handle->UserData[UserData_Type_Write_Func] = value;
+ break;
+ case CURLOPT_READFUNCTION:
+ index = cURL_CallBack_READ_FUNCTION;
+ handle->UserData[UserData_Type_Read_Func] = value;
+ break;
+ }
+
+ if(index == cURL_CallBack_NOTHING)
+ return false;
+
+ handle->callback_Function[index] = pFunction;
+ return true;
+}
+
+
+bool cURLManager::AddcURLOptionHandle(IPluginContext *pContext, cURLHandle *handle, HandleSecurity *sec, CURLoption opt, Handle_t hndl)
+{
+ if(!handle || handle->running)
+ return false;
+
+ void *pointer = NULL;
+ int err = SP_ERROR_NONE;
+ ICloseHelper *helper = NULL;
+
+ switch(opt)
+ {
+ case CURLOPT_WRITEDATA:
+ case CURLOPT_HEADERDATA:
+ case CURLOPT_READDATA:
+ case CURLOPT_STDERR:
+ case CURLOPT_INTERLEAVEDATA:
+ {
+ cURL_OpenFile *openfile = NULL;
+ err = handlesys->ReadHandle(hndl, g_cURLFile, sec, (void **)&openfile);
+ if(openfile != NULL)
+ {
+ pointer = openfile->pFile;
+ openfile->_handle = handle;
+ helper = openfile;
+ }
+ break;
+ }
+ case CURLOPT_HTTPPOST:
+ {
+ WebForm *webform = NULL;
+ err = handlesys->ReadHandle(hndl, g_WebForm, sec, (void **)&webform);
+ if(webform != NULL) {
+ pointer = webform->first;
+ webform->_handle = handle;
+ helper = webform;
+
+ SourceHook::List<cURL_slist_pack *>::iterator iter;
+ cURL_slist_pack *pInfo;
+ for(iter=webform->slist_record.begin(); iter!=webform->slist_record.end(); iter++)
+ {
+ pInfo = (*iter);
+ pInfo->_handle = handle;
+ AddCloseHelperHandle(pInfo);
+ }
+ }
+ break;
+ }
+ case CURLOPT_HTTPHEADER:
+ case CURLOPT_QUOTE:
+ case CURLOPT_POSTQUOTE:
+ case CURLOPT_TELNETOPTIONS:
+ case CURLOPT_PREQUOTE:
+ case CURLOPT_HTTP200ALIASES:
+ case CURLOPT_MAIL_RCPT:
+ case CURLOPT_RESOLVE:
+ {
+ cURL_slist_pack *slist = NULL;
+ err = handlesys->ReadHandle(hndl, g_cURLSlist, sec, (void **)&slist);
+ if(slist != NULL) {
+ pointer = slist->chunk;
+ slist->_handle = handle;
+ helper = slist;
+ }
+ break;
+ }
+ }
+
+ if(err != SP_ERROR_NONE)
+ {
+ pContext->ThrowNativeErrorEx(err, NULL);
+ return false;
+ }
+
+ assert((pointer != NULL));
+ if(pointer == NULL)
+ return false;
+
+
+ cURLOpt_pointer *pointeropt = new cURLOpt_pointer();
+ pointeropt->opt = opt;
+ pointeropt->value = pointer;
+
+ handle->opt_pointer_list.push_back(pointeropt);
+
+ AddCloseHelperHandle(helper);
+ return true;
+}
+
+void cURLManager::LoadcURLOption(cURLHandle *handle)
+{
+ if(!handle || handle->opt_loaded)
+ return;
+
+ handle->opt_loaded = true;
+
+ curl_easy_setopt(handle->curl, CURLOPT_ERRORBUFFER, handle->errorBuffer);
+
+ curl_easy_setopt(handle->curl, CURLOPT_OPENSOCKETFUNCTION, curl_opensocket_function);
+ curl_easy_setopt(handle->curl, CURLOPT_OPENSOCKETDATA, handle);
+
+ if(handle->callback_Function[cURL_CallBack_WRITE_FUNCTION] == NULL) {
+ curl_easy_setopt(handle->curl, CURLOPT_WRITEFUNCTION, curl_write_function_default);
+ } else {
+ curl_easy_setopt(handle->curl, CURLOPT_WRITEFUNCTION, curl_write_function_SM);
+ curl_easy_setopt(handle->curl, CURLOPT_WRITEDATA, handle);
+ }
+
+ if(handle->callback_Function[cURL_CallBack_READ_FUNCTION] != NULL) {
+ curl_easy_setopt(handle->curl, CURLOPT_READFUNCTION, curl_read_function_SM);
+ curl_easy_setopt(handle->curl, CURLOPT_READDATA, handle);
+ }
+
+
+ SourceHook::List<cURLOpt_string *>::iterator iter;
+ cURLOpt_string *pInfo;
+ for(iter=handle->opt_string_list.begin(); iter!=handle->opt_string_list.end(); iter++)
+ {
+ pInfo = (*iter);
+ if((handle->lasterror = curl_easy_setopt(handle->curl, pInfo->opt, pInfo->value)) != CURLE_OK)
+ return;
+ }
+
+ SourceHook::List<cURLOpt_int *>::iterator iter2;
+ cURLOpt_int *pInfo2;
+ for(iter2=handle->opt_int_list.begin(); iter2!=handle->opt_int_list.end(); iter2++)
+ {
+ pInfo2 = (*iter2);
+ if((handle->lasterror = curl_easy_setopt(handle->curl, pInfo2->opt, pInfo2->value)) != CURLE_OK)
+ return;
+ }
+
+ SourceHook::List<cURLOpt_pointer *>::iterator iter3;
+ cURLOpt_pointer *pInfo3;
+ for(iter3=handle->opt_pointer_list.begin(); iter3!=handle->opt_pointer_list.end(); iter3++)
+ {
+ pInfo3 = (*iter3);
+ //Not allow use CURLOPT_WRITEDATA, CURLOPT_READDATA, if write/read function set
+ if((handle->callback_Function[cURL_CallBack_WRITE_FUNCTION] != NULL && pInfo3->opt == CURLOPT_WRITEDATA)
+ || (handle->callback_Function[cURL_CallBack_READ_FUNCTION] != NULL && pInfo3->opt == CURLOPT_READDATA))
+ {
+ continue;
+ }
+ if((handle->lasterror = curl_easy_setopt(handle->curl, pInfo3->opt, pInfo3->value)) != CURLE_OK)
+ return;
+ }
+
+ SourceHook::List<cURLOpt_int64 *>::iterator iter4;
+ cURLOpt_int64 *pInfo4;
+ for(iter4=handle->opt_int64_list.begin(); iter4!=handle->opt_int64_list.end(); iter4++)
+ {
+ pInfo4 = (*iter4);
+ if((handle->lasterror = curl_easy_setopt(handle->curl, pInfo4->opt, (curl_off_t)pInfo4->value)) != CURLE_OK)
+ return;
+ }
+}
+
+CURLFORMcode cURLManager::cURLFormAdd(IPluginContext *pContext, const cell_t *params, WebForm *handle)
+{
+ assert((handle != NULL));
+ if(handle == NULL)
+ return CURL_FORMADD_INCOMPLETE;
+
+ unsigned int numparams = (unsigned)params[0];
+ unsigned int startparam = 2;
+ if(numparams <= 1 || numparams > 22)
+ return CURL_FORMADD_INCOMPLETE;
+
+ // there are only 10 available/supported CURLFORM_*
+ CURLformoption form_opts[11] = {CURLFORM_NOTHING};
+
+ char *form_data[10];
+ memset(form_data, 0, sizeof(form_data));
+
+ cell_t *addr;
+ int count = 0;
+ int err;
+ int value;
+ for(unsigned int i=startparam;i<=numparams;i++)
+ {
+ if((err=pContext->LocalToPhysAddr(params[i], &addr)) != SP_ERROR_NONE)
+ {
+ pContext->ThrowNativeErrorEx(err, NULL);
+ return CURL_FORMADD_INCOMPLETE;
+ }
+ CURLformoption form_code = (CURLformoption)*addr;
+ switch(form_code)
+ {
+ case CURLFORM_COPYNAME:
+ case CURLFORM_COPYCONTENTS:
+ case CURLFORM_FILECONTENT:
+ case CURLFORM_FILE:
+ case CURLFORM_CONTENTTYPE:
+ case CURLFORM_FILENAME:
+ if((err=pContext->LocalToString(params[i+1], &form_data[count])) != SP_ERROR_NONE)
+ {
+ pContext->ThrowNativeErrorEx(err, NULL);
+ return CURL_FORMADD_INCOMPLETE;
+ }
+ if(form_code == CURLFORM_FILE || form_code == CURLFORM_FILECONTENT) // absolute path
+ {
+ char realpath[PLATFORM_MAX_PATH];
+ g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", form_data[count]);
+
+ form_data[count] = realpath;
+ }
+ form_opts[count] = form_code;
+ count++;
+ i++;
+ break;
+ case CURLFORM_NAMELENGTH:
+ case CURLFORM_CONTENTSLENGTH:
+ if((err=pContext->LocalToPhysAddr(params[i+1], &addr)) != SP_ERROR_NONE)
+ {
+ pContext->ThrowNativeErrorEx(err, NULL);
+ return CURL_FORMADD_INCOMPLETE;
+ }
+ form_opts[count] = form_code;
+ value = *addr;
+ form_data[count] = (char *)value;
+ count++;
+ i++;
+ break;
+ case CURLFORM_CONTENTHEADER:
+ {
+ if((err=pContext->LocalToPhysAddr(params[i+1], &addr)) != SP_ERROR_NONE)
+ {
+ pContext->ThrowNativeErrorEx(err, NULL);
+ return CURL_FORMADD_INCOMPLETE;
+ }
+ cURL_slist_pack *slist;
+ HandleError hndl_err;
+ HandleSecurity sec(pContext->GetIdentity(), myself_Identity);
+ if((hndl_err = handlesys->ReadHandle(*addr, g_cURLSlist, &sec, (void **)&slist)) != HandleError_None)
+ {
+ pContext->ThrowNativeError("Invalid curl_slist Handle %x (error %d)", params[1], hndl_err);
+ return CURL_FORMADD_INCOMPLETE;
+ }
+ form_opts[count] = form_code;
+ form_data[count] = (char *)slist->chunk;
+ handle->slist_record.push_back(slist); // when webform add into curlhandle, will add slist handle to close helper
+ count++;
+ i++;
+ break;
+ }
+ case CURLFORM_END:
+ form_opts[count] = CURLFORM_END;
+ goto end;
+ }
+ }
+
+end:
+ CURLFORMcode ret = curl_formadd(&handle->first, &handle->last,
+ form_opts[0],
+ form_data[0],
+ form_opts[1],
+ form_data[1],
+ form_opts[2],
+ form_data[2],
+ form_opts[3],
+ form_data[3],
+ form_opts[4],
+ form_data[4],
+ form_opts[5],
+ form_data[5],
+ form_opts[6],
+ form_data[6],
+ form_opts[7],
+ form_data[7],
+ form_opts[8],
+ form_data[8],
+ form_opts[9],
+ form_data[9],
+ form_opts[10]
+ );
+ return ret;
+}
+
+
diff --git a/curlmanager.h b/curlmanager.h
new file mode 100644
index 0000000..f1362a4
--- /dev/null
+++ b/curlmanager.h
@@ -0,0 +1,48 @@
+#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CURLMANAGER_H_
+#define _INCLUDE_SOURCEMOD_EXTENSION_CURLMANAGER_H_
+
+#include "extension.h"
+#include "curlthread.h"
+
+class cURLManager
+{
+public:
+ void SDK_OnLoad();
+ void SDK_OnUnload();
+
+public:
+ void CreatecURLThread(cURLThread *thread);
+ void RemovecURLThread(cURLThread *thread);
+
+public:
+ void RemovecURLHandle(cURLHandle *handle);
+ bool AddcURLOptionString(cURLHandle *handle, CURLoption opt, char *value);
+ bool AddcURLOptionInt(cURLHandle *handle, CURLoption opt, int value);
+ bool AddcURLOptionInt64(cURLHandle *handle, CURLoption opt, long long value);
+ bool AddcURLOptionHandle(IPluginContext *pContext, cURLHandle *handle, HandleSecurity *sec, CURLoption opt, Handle_t hndl);
+ bool AddcURLOptionFunction(IPluginContext *pContext, cURLHandle *handle, CURLoption opt, IPluginFunction *pFunction, int value);
+ void LoadcURLOption(cURLHandle *handle);
+
+private:
+ void RemoveLinkedICloseHelper(cURLHandle *handle);
+
+public:
+ CURLFORMcode cURLFormAdd(IPluginContext *pContext, const cell_t *params, WebForm *handle);
+
+public:
+ void AddCloseHelperHandle(ICloseHelper *helper);
+ void RemoveCloseHelperHandle(ICloseHelper *helper);
+
+private:
+ bool waiting;
+ IMutex *curlhandle_list_mutex;
+ IMutex *closehelper_list_mutex;
+ IEventSignal *shutdown_event;
+ SourceHook::List<cURLThread *> g_cURLThread_List;
+ SourceHook::List<ICloseHelper *> g_CloseHelper_List;
+};
+
+extern cURLManager g_cURLManager;
+
+#endif
+
diff --git a/curlthread.cpp b/curlthread.cpp
new file mode 100644
index 0000000..71197ca
--- /dev/null
+++ b/curlthread.cpp
@@ -0,0 +1,315 @@
+#include "curlthread.h"
+#include <string.h>
+
+static int wait_on_socket(curl_socket_t sockfd, bool for_recv, long timeout_ms)
+{
+ struct timeval tv;
+ fd_set infd, outfd, errfd;
+ int res;
+ tv.tv_sec = timeout_ms / 1000;
+ tv.tv_usec= (timeout_ms % 1000) * 1000;
+
+ FD_ZERO(&infd);
+ FD_ZERO(&outfd);
+ FD_ZERO(&errfd);
+
+ FD_SET(sockfd, &errfd); /* always check for error */
+
+ if(for_recv)
+ {
+ FD_SET(sockfd, &infd);
+ } else {
+ FD_SET(sockfd, &outfd);
+ }
+ /* select() returns the number of signalled sockets or -1 */
+ res = select(sockfd + 1, &infd, &outfd, &errfd, &tv);
+ return res;
+}
+
+
+cURLThread::cURLThread(cURLHandle *_handle, cURLThread_Type _type):
+waiting(false),handle(_handle),type(_type),event(threader->MakeEventSignal()),
+recv_buffer(NULL),recv_buffer_size(1024),_current_recv_buffer_size(0),last_iolen(0)
+
+{
+ assert((type > cURLThread_Type_NOTHING && type < cURLThread_Type_LAST));
+ assert((event != NULL));
+ handle->running = true;
+ handle->thread = this;
+}
+
+cURLThread::~cURLThread()
+{
+ waiting = false;
+ if(event != NULL)
+ {
+ event->DestroyThis();
+ event = NULL;
+ }
+ if(recv_buffer != NULL)
+ {
+ delete [] recv_buffer;
+ recv_buffer = NULL;
+ }
+
+ g_cURLManager.RemovecURLThread(this);
+}
+
+cURLHandle *cURLThread::GetHandle()
+{
+ return handle;
+}
+
+cURLThread_Type cURLThread::GetRunType()
+{
+ return type;
+}
+
+void cURLThread::EventSignal()
+{
+ assert((event != NULL));
+ event->Signal();
+}
+
+void cURLThread::EventWait()
+{
+ assert((event != NULL));
+ waiting = true;
+ event->Wait();
+ waiting = false;
+}
+
+bool cURLThread::IsWaiting()
+{
+ return waiting;
+}
+
+char *cURLThread::GetReceiveBuffer()
+{
+ return recv_buffer;
+}
+
+void cURLThread::SetRecvBufferSize(unsigned int size)
+{
+ if(size == 0)
+ size = 1024;
+ else if(size > (64*1024*1024)) // 64MB
+ size = (64*1024*1024);
+
+ recv_buffer_size = size;
+}
+
+void cURLThread::SetSenRecvAction(SendRecv_Act act)
+{
+ assert((act > SendRecv_Act_NOTHING && act < SendRecv_Act_LAST));
+ send_recv_act = act;
+}
+
+void cURLThread::RunThread_Perform()
+{
+ g_cURLManager.LoadcURLOption(handle);
+
+ if(handle->lasterror != CURLE_OK)
+ return;
+
+ if((handle->lasterror = curl_easy_perform(handle->curl)) != CURLE_OK)
+ return;
+
+ handle->lasterror = curl_easy_getinfo(handle->curl, CURLINFO_LASTSOCKET, &handle->sockextr);
+}
+
+static void curl_send_FramAction(void *data)
+{
+ if(data == NULL)
+ return;
+
+ cURLThread *thread = (cURLThread*)data;
+ cURLHandle *handle = thread->GetHandle();
+
+ IPluginFunction *pFunc = handle->callback_Function[cURL_CallBack_SEND];
+ assert((pFunc != NULL));
+ if(pFunc != NULL)
+ {
+ cell_t result;
+ pFunc->PushCell(handle->hndl);
+ pFunc->PushCell(handle->lasterror);
+ pFunc->PushCell(thread->last_iolen);
+ pFunc->PushCell(handle->UserData[UserData_Type_Send_Recv]);
+ pFunc->Execute(&result);
+ thread->SetSenRecvAction((SendRecv_Act)result);
+ }
+
+ thread->EventSignal();
+}
+
+static void curl_recv_FramAction(void *data)
+{
+ if(data == NULL)
+ return;
+
+ cURLThread *thread = (cURLThread*)data;
+ cURLHandle *handle = thread->GetHandle();
+
+ IPluginFunction *pFunc = handle->callback_Function[cURL_CallBack_RECV];
+ assert((pFunc != NULL));
+ if(pFunc != NULL)
+ {
+ cell_t result;
+ pFunc->PushCell(handle->hndl);
+ pFunc->PushCell(handle->lasterror);
+ pFunc->PushStringEx(thread->GetReceiveBuffer(), thread->last_iolen, SM_PARAM_STRING_COPY|SM_PARAM_STRING_BINARY, 0);
+ pFunc->PushCell(thread->last_iolen);
+ pFunc->PushCell(handle->UserData[UserData_Type_Send_Recv]);
+ pFunc->Execute(&result);
+ thread->SetSenRecvAction((SendRecv_Act)result);
+ }
+ thread->EventSignal();
+}
+
+void cURLThread::RunThread_Send_Recv()
+{
+ assert((handle->sockextr != INVALID_SOCKET));
+
+ if(handle->sockextr == INVALID_SOCKET || event == NULL)
+ {
+ handle->lasterror = CURLE_SEND_ERROR;
+ return;
+ }
+
+/* Select Action */
+select_action:
+ if(send_recv_act == SendRecv_Act_GOTO_SEND)
+ goto act_send;
+ else if(send_recv_act == SendRecv_Act_GOTO_RECV)
+ goto act_recv;
+ else if(send_recv_act == SendRecv_Act_GOTO_WAIT)
+ goto act_wait;
+ else if(send_recv_act == SendRecv_Act_GOTO_SEND_NO_WAIT)
+ goto act_send_no_wait;
+ else if(send_recv_act == SendRecv_Act_GOTO_RECV_NO_WAIT)
+ goto act_recv_no_wait;
+ else
+ goto act_end;
+
+
+/* Send Action */
+act_send:
+ if(!wait_on_socket(handle->sockextr, false, handle->send_timeout))
+ {
+ handle->lasterror = CURLE_OPERATION_TIMEDOUT;
+ goto sm_send_frame;
+ }
+
+act_send_no_wait:
+ if(handle->send_buffer.length() == 0)
+ {
+ handle->lasterror = CURLE_SEND_ERROR;
+ goto sm_send_frame;
+ }
+
+ handle->lasterror = curl_easy_send(handle->curl, handle->send_buffer.data(), handle->send_buffer.length(), &last_iolen);
+ handle->send_buffer.clear();
+
+ // put res to frame, let frame do action
+sm_send_frame:
+ smutils->AddFrameAction(curl_send_FramAction, this);
+
+ EventWait();
+
+ if(g_cURL_SM.IsShutdown())
+ goto act_end;
+
+ goto select_action;
+
+
+/* Recv Action */
+act_recv:
+ if(!wait_on_socket(handle->sockextr, true, handle->recv_timeout))
+ {
+ handle->lasterror = CURLE_OPERATION_TIMEDOUT;
+ goto sm_recv_frame;
+ }
+
+act_recv_no_wait:
+ if(_current_recv_buffer_size != recv_buffer_size || recv_buffer == NULL)
+ {
+ if(recv_buffer != NULL)
+ {
+ delete [] recv_buffer;
+ recv_buffer = NULL;
+ }
+ _current_recv_buffer_size = recv_buffer_size;
+ recv_buffer = new char[_current_recv_buffer_size+1];
+ memset(recv_buffer, 0, _current_recv_buffer_size+1);
+ }
+
+ handle->lasterror = curl_easy_recv(handle->curl, recv_buffer, _current_recv_buffer_size, &last_iolen);
+
+sm_recv_frame:
+ smutils->AddFrameAction(curl_recv_FramAction, this);
+ goto act_wait;
+
+
+/* Wait Action */
+act_wait:
+ if(g_cURL_SM.IsShutdown())
+ goto act_end;
+
+ EventWait();
+
+ if(g_cURL_SM.IsShutdown())
+ goto act_end;
+ goto select_action; // select action again
+
+
+
+/* End Action */
+act_end:
+ return;
+}
+
+
+void cURLThread::RunThread(IThreadHandle *pHandle)
+{
+ if(type == cURLThread_Type_PERFORM)
+ {
+ RunThread_Perform();
+ } else if(type == cURLThread_Type_SEND_RECV) {
+ RunThread_Send_Recv();
+ }
+}
+
+
+static void cUrl_Thread_Finish(void *data)
+{
+ if(data == NULL)
+ return;
+
+ cURLThread *thread = (cURLThread*)data;
+ cURLHandle *handle = thread->GetHandle();
+
+ IPluginFunction *pFunc = handle->callback_Function[cURL_CallBack_COMPLETE];
+ assert((pFunc != NULL));
+ if(pFunc != NULL)
+ {
+ pFunc->PushCell(handle->hndl);
+ pFunc->PushCell(handle->lasterror);
+ pFunc->PushCell(handle->UserData[UserData_Type_Complete]);
+ pFunc->Execute(NULL);
+ }
+
+ thread->EventSignal();
+}
+
+void cURLThread::OnTerminate(IThreadHandle *pHandle, bool cancel)
+{
+ handle->running = false;
+ if(!g_cURL_SM.IsShutdown())
+ {
+ smutils->AddFrameAction(cUrl_Thread_Finish, this);
+
+ EventWait();
+ }
+ delete this;
+}
+
diff --git a/curlthread.h b/curlthread.h
new file mode 100644
index 0000000..ddb0c57
--- /dev/null
+++ b/curlthread.h
@@ -0,0 +1,49 @@
+#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CURLTHREAD_H_
+#define _INCLUDE_SOURCEMOD_EXTENSION_CURLTHREAD_H_
+
+#include "extension.h"
+#include "curlmanager.h"
+#include <curl/curl.h>
+
+
+class cURLThread : public IThread
+{
+ friend class cURLManager;
+
+public:
+ cURLThread(cURLHandle *_handle, cURLThread_Type _type);
+ ~cURLThread();
+ cURLHandle *GetHandle();
+ cURLThread_Type GetRunType();
+ void EventSignal();
+ void EventWait();
+ bool IsWaiting();
+ char *GetReceiveBuffer();
+ void SetRecvBufferSize(unsigned int size);
+ void SetSenRecvAction(SendRecv_Act act);
+
+public:
+ void RunThread(IThreadHandle *pHandle);
+ void OnTerminate(IThreadHandle *pHandle, bool cancel);
+
+public:
+ void RunThread_Perform();
+ void RunThread_Send_Recv();
+
+private:
+ bool waiting;
+ cURLHandle *handle;
+ cURLThread_Type type;
+ IEventSignal *event;
+ char *recv_buffer;
+ unsigned int recv_buffer_size;
+ unsigned int _current_recv_buffer_size;
+ SendRecv_Act send_recv_act;
+
+public:
+ size_t last_iolen;
+};
+
+
+#endif
+
diff --git a/define.h b/define.h
new file mode 100644
index 0000000..f56ccda
--- /dev/null
+++ b/define.h
@@ -0,0 +1,177 @@
+#ifndef _INCLUDE_SOURCEMOD_EXTENSION_DEFINE_H_
+#define _INCLUDE_SOURCEMOD_EXTENSION_DEFINE_H_
+
+#include <sh_list.h>
+#include <curl/curl.h>
+
+#ifdef PLATFORM_LINUX
+#define INVALID_SOCKET -1
+#endif
+
+class cURLThread;
+struct cURLHandle;
+
+
+enum SendRecv_Act {
+ SendRecv_Act_NOTHING = 0,
+
+ SendRecv_Act_GOTO_SEND,
+ SendRecv_Act_GOTO_RECV,
+ SendRecv_Act_GOTO_WAIT,
+ SendRecv_Act_GOTO_END,
+ SendRecv_Act_GOTO_SEND_NO_WAIT,
+ SendRecv_Act_GOTO_RECV_NO_WAIT,
+
+ SendRecv_Act_LAST,
+};
+
+enum cURLThread_Type {
+ cURLThread_Type_NOTHING = 0,
+
+ cURLThread_Type_PERFORM,
+ cURLThread_Type_SEND_RECV,
+
+ cURLThread_Type_LAST,
+};
+
+enum cURL_CallBack {
+ cURL_CallBack_NOTHING = 0,
+
+ cURL_CallBack_COMPLETE,
+ cURL_CallBack_SEND,
+ cURL_CallBack_RECV,
+
+ cURL_CallBack_WRITE_FUNCTION,
+ cURL_CallBack_READ_FUNCTION,
+
+ cURL_CallBack_LAST,
+};
+
+struct cURLOpt_string {
+ CURLoption opt;
+ char *value;
+};
+
+struct cURLOpt_int {
+ CURLoption opt;
+ int value;
+};
+
+struct cURLOpt_int64 {
+ CURLoption opt;
+ curl_off_t value;
+};
+
+struct cURLOpt_pointer {
+ CURLoption opt;
+ void *value;
+};
+
+enum UserData_Type
+{
+ UserData_Type_Complete = 0,
+ UserData_Type_Send_Recv,
+ UserData_Type_Write_Func,
+ UserData_Type_Read_Func,
+};
+
+struct cURLHandle {
+ cURLHandle():curl(NULL),running(false),lasterror(CURLE_OK),opt_loaded(false),
+ thread(NULL),is_udp(false),sockextr(INVALID_SOCKET),send_timeout(60000),recv_timeout(60000)
+ {
+ }
+ CURL *curl;
+ char errorBuffer[CURL_ERROR_SIZE];
+ SourceHook::List<cURLOpt_string *> opt_string_list;
+ SourceHook::List<cURLOpt_int *> opt_int_list;
+ SourceHook::List<cURLOpt_int64 *> opt_int64_list;
+ SourceHook::List<cURLOpt_pointer *> opt_pointer_list;
+ bool running;
+ CURLcode lasterror;
+ bool opt_loaded;
+ IPluginFunction *callback_Function[cURL_CallBack_LAST];
+ Handle_t hndl;
+ int UserData[4];
+ cURLThread *thread;
+ bool is_udp;
+
+ /* use for send & recv */
+ long sockextr;
+ long send_timeout;
+ long recv_timeout;
+
+ std::string send_buffer;
+};
+
+class ICloseHelper {
+public:
+ ICloseHelper():_handle(NULL),_marked_delete(false)
+ {
+ }
+ cURLHandle *_handle;
+ bool _marked_delete;
+ bool TryDelete();
+ virtual void Delete() =0;
+};
+
+class cURL_slist_pack : public ICloseHelper {
+public:
+ cURL_slist_pack():chunk(NULL)
+ {
+ }
+ curl_slist *chunk;
+ void Delete();
+};
+
+class WebForm : public ICloseHelper {
+public:
+ WebForm():first(NULL), last(NULL)
+ {
+ }
+ curl_httppost *first;
+ curl_httppost *last;
+ SourceHook::List<cURL_slist_pack *> slist_record;
+ void Delete();
+};
+
+class cURL_OpenFile : public ICloseHelper {
+public:
+ FILE *pFile;
+ void Delete();
+};
+
+
+enum OpensslThread_Type {
+ OpensslThread_Type_NOTHING = 0,
+
+ OpensslThread_Type_HASH_FILE,
+
+ OpensslThread_Type_LAST,
+};
+
+enum Openssl_Hash {
+ Openssl_Hash_MD5 = 0,
+ Openssl_Hash_MD4,
+ Openssl_Hash_MD2,
+ Openssl_Hash_SHA,
+ Openssl_Hash_SHA1,
+ Openssl_Hash_SHA224,
+ Openssl_Hash_SHA256,
+ Openssl_Hash_SHA384,
+ Openssl_Hash_SHA512,
+ Openssl_Hash_RIPEMD160,
+};
+
+struct Openssl_Hash_pack {
+ Openssl_Hash_pack():path(NULL), output(NULL)
+ {
+ }
+ IPluginFunction *hash_callback;
+ int UserData;
+ char *path;
+ Openssl_Hash algorithm;
+ bool success;
+ char *output;
+};
+
+#endif
diff --git a/extension.cpp b/extension.cpp
new file mode 100644
index 0000000..fa82cf1
--- /dev/null
+++ b/extension.cpp
@@ -0,0 +1,172 @@
+#include "extension.h"
+#include "curlmanager.h"
+#include "opensslmanager.h"
+#include <curl/curl.h>
+
+cURL_SM g_cURL_SM;
+
+SMEXT_LINK(&g_cURL_SM);
+
+extern sp_nativeinfo_t g_cURLNatives[];
+
+HandleType_t g_cURLHandle = 0;
+HandleType_t g_cURLFile = 0;
+HandleType_t g_WebForm = 0;
+HandleType_t g_cURLSlist = 0;
+
+IdentityToken_t *myself_Identity = NULL;
+
+
+bool cURL_SM::SDK_OnLoad(char *error, size_t maxlength, bool late)
+{
+ shutdown = false;
+
+ CURLcode code;
+
+ code = curl_global_init(CURL_GLOBAL_ALL);
+
+ if(code)
+ {
+ smutils->Format(error, maxlength, "%s", curl_easy_strerror(code));
+ return false;
+ }
+
+ myself_Identity = myself->GetIdentity();
+
+ bool valid = true;
+
+ HandleError err_file, err_handle, err_webform, err_slist;
+ g_cURLFile = handlesys->CreateType("cURLFile", this, 0, NULL, NULL, myself_Identity, &err_file);
+ g_cURLHandle = handlesys->CreateType("cURLHandle", this, 0, NULL, NULL, myself_Identity, &err_handle);
+ g_WebForm = handlesys->CreateType("cURLWebForm", this, 0, NULL, NULL, myself_Identity, &err_webform);
+ g_cURLSlist = handlesys->CreateType("cURLSlist", this, 0, NULL, NULL, myself_Identity, &err_slist);
+
+ if(g_cURLFile == 0)
+ {
+ handlesys->RemoveType(g_cURLFile, myself_Identity);
+ g_cURLFile = 0;
+ snprintf(error, maxlength, "Could not create CURL file type (err: %d)", err_file);
+ valid = false;
+ }
+
+ if(g_cURLHandle == 0)
+ {
+ handlesys->RemoveType(g_cURLHandle, myself_Identity);
+ g_cURLHandle = 0;
+ snprintf(error, maxlength, "Could not create CURL handle type (err: %d)", err_handle);
+ valid = false;
+ }
+
+ if(g_WebForm == 0)
+ {
+ handlesys->RemoveType(g_WebForm, myself_Identity);
+ g_WebForm = 0;
+ snprintf(error, maxlength, "Could not create CURL WebForm type (err: %d)", err_webform);
+ valid = false;
+ }
+
+ if(g_cURLSlist == 0)
+ {
+ handlesys->RemoveType(g_cURLSlist, myself_Identity);
+ g_cURLSlist = 0;
+ snprintf(error, maxlength, "Could not create CURL Slist type (err: %d)", err_slist);
+ valid = false;
+ }
+
+ if(!valid)
+ return false;
+
+ sharesys->AddNatives(myself, g_cURLNatives);
+
+ g_cURLManager.SDK_OnLoad();
+
+ g_OpensslManager.SDK_OnLoad();
+
+ return true;
+}
+
+void cURL_SM::SDK_OnUnload()
+{
+ shutdown = true;
+
+ g_cURLManager.SDK_OnUnload();
+
+ g_OpensslManager.SDK_OnUnload();
+
+ curl_global_cleanup();
+}
+
+void cURL_SM::SDK_OnAllLoaded()
+{
+}
+
+bool cURL_SM::QueryRunning(char *error, size_t maxlength)
+{
+ return true;
+}
+
+void cURL_SM::OnHandleDestroy(HandleType_t type, void *object)
+{
+ if(type == g_cURLHandle)
+ {
+ g_cURLManager.RemovecURLHandle((cURLHandle *)object);
+ } else if(type == g_cURLFile || type == g_WebForm || type == g_cURLSlist) {
+ ICloseHelper *pointer = (ICloseHelper *)object;
+ if(pointer->TryDelete())
+ {
+ g_cURLManager.RemoveCloseHelperHandle(pointer);
+ pointer->Delete();
+ }
+ }
+}
+
+bool cURL_SM::IsShutdown()
+{
+ return shutdown;
+}
+
+
+bool ICloseHelper::TryDelete()
+{
+ if(_handle == NULL || !_handle->running)
+ {
+ return true;
+ } else {
+ _marked_delete = true;
+ return false;
+ }
+}
+
+void cURL_OpenFile::Delete()
+{
+ fclose(pFile);
+ delete this;
+}
+
+void WebForm::Delete()
+{
+ curl_formfree(first);
+ slist_record.clear();
+ delete this;
+}
+
+void cURL_slist_pack::Delete()
+{
+ curl_slist_free_all(chunk);
+ delete this;
+}
+
+char *UTIL_ToLowerCase(const char *str)
+{
+ size_t len = strlen(str);
+ char *buffer = new char[len + 1];
+ for (size_t i = 0; i < len; i++)
+ {
+ if (str[i] >= 'A' && str[i] <= 'Z')
+ buffer[i] = tolower(str[i]);
+ else
+ buffer[i] = str[i];
+ }
+ buffer[len] = '\0';
+ return buffer;
+}
diff --git a/extension.h b/extension.h
new file mode 100644
index 0000000..ffbea0a
--- /dev/null
+++ b/extension.h
@@ -0,0 +1,43 @@
+#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
+#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
+
+#include "smsdk_ext.h"
+#include <string>
+#include "define.h"
+#include <assert.h>
+#include <cstring>
+
+class cURL_SM :
+ public SDKExtension,
+ public IHandleTypeDispatch
+{
+public:
+ virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
+ virtual void SDK_OnUnload();
+ virtual void SDK_OnAllLoaded();
+ virtual bool QueryRunning(char *error, size_t maxlength);
+
+public:
+ void OnHandleDestroy(HandleType_t type, void *object);
+
+public:
+ bool IsShutdown();
+
+private:
+ bool shutdown;
+
+};
+
+extern cURL_SM g_cURL_SM;
+
+extern HandleType_t g_cURLHandle;
+extern HandleType_t g_cURLFile;
+extern HandleType_t g_WebForm;
+extern HandleType_t g_cURLSlist;
+
+extern IdentityToken_t *myself_Identity ;
+
+extern char *UTIL_ToLowerCase(const char *str);
+
+#endif
+
diff --git a/lib/libcrypto.a b/lib/libcrypto.a
new file mode 100644
index 0000000..52acf17
--- /dev/null
+++ b/lib/libcrypto.a
Binary files differ
diff --git a/lib/libcurl.a b/lib/libcurl.a
new file mode 100644
index 0000000..ddfe4f9
--- /dev/null
+++ b/lib/libcurl.a
Binary files differ
diff --git a/lib/libcurl.lib b/lib/libcurl.lib
new file mode 100644
index 0000000..d832694
--- /dev/null
+++ b/lib/libcurl.lib
Binary files differ
diff --git a/lib/libcurld.lib b/lib/libcurld.lib
new file mode 100644
index 0000000..1462f0b
--- /dev/null
+++ b/lib/libcurld.lib
Binary files differ
diff --git a/lib/libssh2.a b/lib/libssh2.a
new file mode 100644
index 0000000..aacd15f
--- /dev/null
+++ b/lib/libssh2.a
Binary files differ
diff --git a/lib/libssl.a b/lib/libssl.a
new file mode 100644
index 0000000..88445d6
--- /dev/null
+++ b/lib/libssl.a
Binary files differ
diff --git a/lib/libz.a b/lib/libz.a
new file mode 100644
index 0000000..87edfc8
--- /dev/null
+++ b/lib/libz.a
Binary files differ
diff --git a/natives.cpp b/natives.cpp
new file mode 100644
index 0000000..0a02663
--- /dev/null
+++ b/natives.cpp
@@ -0,0 +1,598 @@
+#include <stdlib.h>
+#include "extension.h"
+#include "curlmanager.h"
+#include "opensslmanager.h"
+#include <sh_string.h>
+#include <curl/curl.h>
+
+#define SETUP_CURL_HANDLE()\
+ cURLHandle *handle;\
+ HandleError err;\
+ HandleSecurity sec(pContext->GetIdentity(), myself_Identity);\
+ if((err = handlesys->ReadHandle(params[1], g_cURLHandle, &sec, (void **)&handle)) != HandleError_None)\
+ {\
+ return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);\
+ }
+
+#define SETUP_CURL_WEBFORM()\
+ WebForm *handle;\
+ HandleError err;\
+ HandleSecurity sec(pContext->GetIdentity(), myself_Identity);\
+ if((err = handlesys->ReadHandle(params[1], g_WebForm, &sec, (void **)&handle)) != HandleError_None)\
+ {\
+ return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);\
+ }
+
+#define SETUP_CURL_SLIST()\
+ cURL_slist_pack *handle;\
+ HandleError err;\
+ HandleSecurity sec(pContext->GetIdentity(), myself_Identity);\
+ if((err = handlesys->ReadHandle(params[1], g_cURLSlist, &sec, (void **)&handle)) != HandleError_None)\
+ {\
+ return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);\
+ }
+
+
+static cell_t sm_curl_easy_init(IPluginContext *pContext, const cell_t *params)
+{
+ CURL *curl = curl_easy_init();
+ if(curl == NULL)
+ {
+ return BAD_HANDLE;
+ }
+
+ cURLHandle *handle = new cURLHandle();
+ memset(handle->errorBuffer,0,sizeof(handle->errorBuffer));
+ memset(handle->callback_Function, 0, sizeof(handle->callback_Function));
+ memset(handle->UserData,0,sizeof(handle->UserData));
+ handle->curl = curl;
+
+ Handle_t hndl = handlesys->CreateHandle(g_cURLHandle, handle, pContext->GetIdentity(), myself_Identity, NULL);
+ if(!hndl)
+ {
+ curl_easy_cleanup(handle->curl);
+ delete handle;
+ return BAD_HANDLE;
+ }
+
+ handle->hndl = hndl;
+ return hndl;
+}
+
+static cell_t sm_curl_easy_setopt_string(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ char *buffer;
+ pContext->LocalToString(params[3], &buffer);
+
+ return g_cURLManager.AddcURLOptionString(handle, (CURLoption)params[2], buffer);
+}
+
+static cell_t sm_curl_easy_setopt_int(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ return g_cURLManager.AddcURLOptionInt(handle, (CURLoption)params[2], params[3]);
+}
+
+static cell_t sm_curl_easy_setopt_int_array(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ cell_t *array;
+ cell_t array_size = params[3];
+ pContext->LocalToPhysAddr(params[2], &array);
+
+ bool valid = true;
+ for(int i=0; i<array_size; i++)
+ {
+ cell_t c1_addr = params[2] + (i * sizeof(cell_t)) + array[i];
+ cell_t *c1_r;
+ pContext->LocalToPhysAddr(c1_addr, &c1_r);
+
+ bool ret = g_cURLManager.AddcURLOptionInt(handle, (CURLoption)c1_r[0], c1_r[1]);
+ if(!ret)
+ {
+ valid = false;
+ }
+ }
+ return valid;
+}
+
+static cell_t sm_curl_easy_setopt_int64(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ char *buffer;
+ pContext->LocalToString(params[3], &buffer);
+
+#ifdef WIN32
+ long long int value = _atoi64(buffer);
+#else
+ long long int value = atoll(buffer);
+#endif
+ return g_cURLManager.AddcURLOptionInt64(handle, (CURLoption)params[2], value);
+}
+
+static cell_t sm_curl_easy_setopt_handle(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ return g_cURLManager.AddcURLOptionHandle(pContext, handle, &sec, (CURLoption)params[2], params[3]);
+}
+
+static cell_t sm_curl_easy_setopt_function(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ IPluginFunction *pFunction = pContext->GetFunctionById(params[3]);
+ if(!pFunction)
+ {
+ return pContext->ThrowNativeError("Invalid function %x", params[3]);
+ }
+
+ return g_cURLManager.AddcURLOptionFunction(pContext, handle, (CURLoption)params[2], pFunction, params[4]);
+}
+
+static cell_t sm_curl_easy_perform_thread(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
+ if(!pFunction)
+ {
+ return pContext->ThrowNativeError("Invalid function %x", params[2]);
+ }
+
+ handle->UserData[UserData_Type_Complete] = params[3];
+ handle->callback_Function[cURL_CallBack_COMPLETE] = pFunction;
+ cURLThread *thread = new cURLThread(handle, cURLThread_Type_PERFORM);
+ g_cURLManager.CreatecURLThread(thread);
+
+ return 1;
+}
+
+static cell_t sm_curl_easy_perform(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ handle->running = true;
+ CURLcode code = curl_easy_perform(handle->curl);
+ handle->running = false;
+ curl_easy_getinfo(handle->curl, CURLINFO_LASTSOCKET, &handle->sockextr);
+
+ return code;
+}
+
+static cell_t sm_curl_easy_getinfo_string(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ int type = (CURLINFO_TYPEMASK & (int)params[2]);
+
+ CURLcode code = CURLE_BAD_FUNCTION_ARGUMENT;
+ if(type == CURLINFO_STRING)
+ {
+ char *string_buffer;
+ code = curl_easy_getinfo(handle->curl, (CURLINFO)params[2], &string_buffer);
+ if(code == CURLE_OK)
+ {
+ pContext->StringToLocalUTF8(params[3], params[4], string_buffer, NULL);
+ }
+ }
+
+ return code;
+}
+
+static cell_t sm_curl_easy_getinfo_int(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ int type = (CURLINFO_TYPEMASK & (int)params[2]);
+
+ cell_t *addr;
+ pContext->LocalToPhysAddr(params[3], &addr);
+ CURLcode code = CURLE_BAD_FUNCTION_ARGUMENT;
+
+ switch(type)
+ {
+ case CURLINFO_LONG:
+ long long_buffer;
+ code = curl_easy_getinfo(handle->curl, (CURLINFO)params[2], &long_buffer);
+ if(code == CURLE_OK)
+ {
+ *addr = (cell_t)long_buffer;
+ }
+ break;
+ case CURLINFO_DOUBLE:
+ double double_buffer;
+ code = curl_easy_getinfo(handle->curl, (CURLINFO)params[2], &double_buffer);
+ if(code == CURLE_OK)
+ {
+ *addr = sp_ftoc((float)double_buffer);
+ }
+ break;
+ }
+ return code;
+}
+
+static cell_t sm_curl_load_opt(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ g_cURLManager.LoadcURLOption(handle);
+ return handle->lasterror;
+}
+
+static cell_t sm_curl_get_error_buffer(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ pContext->StringToLocalUTF8(params[2], params[3], handle->errorBuffer, NULL);
+ return 1;
+}
+
+static cell_t sm_curl_easy_escape(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ char *url;
+ pContext->LocalToString(params[2], &url);
+
+ char *buffer = curl_easy_escape(handle->curl, url, strlen(url));
+ if(buffer == NULL)
+ return 0;
+
+ pContext->StringToLocalUTF8(params[3], params[4], buffer, NULL);
+ curl_free(buffer);
+ return 1;
+}
+
+static cell_t sm_curl_easy_unescape(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ char *url;
+ pContext->LocalToString(params[2], &url);
+
+ int outlen;
+ char *buffer = curl_easy_unescape(handle->curl, url, strlen(url), &outlen);
+ if(buffer == NULL)
+ return 0;
+
+ pContext->StringToLocalUTF8(params[3], params[4], buffer, NULL);
+ curl_free(buffer);
+ return outlen;
+}
+
+static cell_t sm_curl_easy_strerror(IPluginContext *pContext, const cell_t *params)
+{
+ const char *error_code = curl_easy_strerror((CURLcode)params[1]);
+ pContext->StringToLocalUTF8(params[2], params[3], error_code, NULL);
+ return 1;
+}
+
+/* send & recv */
+static cell_t sm_curl_easy_send_recv(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ IPluginFunction *pFunction_send = pContext->GetFunctionById(params[2]);
+ if(!pFunction_send)
+ {
+ return pContext->ThrowNativeError("Invalid function %x", params[2]);
+ }
+
+ IPluginFunction *pFunction_recv = pContext->GetFunctionById(params[3]);
+ if(!pFunction_recv)
+ {
+ return pContext->ThrowNativeError("Invalid function %x", params[3]);
+ }
+
+ IPluginFunction *pFunction_complete = pContext->GetFunctionById(params[4]);
+ if(!pFunction_complete)
+ {
+ return pContext->ThrowNativeError("Invalid function %x", params[4]);
+ }
+
+ handle->send_timeout = params[6];
+ handle->recv_timeout = params[7];
+ handle->UserData[UserData_Type_Send_Recv] = params[9];
+ handle->callback_Function[cURL_CallBack_SEND] = pFunction_send;
+ handle->callback_Function[cURL_CallBack_RECV] = pFunction_recv;
+ handle->callback_Function[cURL_CallBack_COMPLETE] = pFunction_complete;
+ cURLThread *thread = new cURLThread(handle, cURLThread_Type_SEND_RECV);
+ thread->SetRecvBufferSize(params[8]);
+ thread->SetSenRecvAction((SendRecv_Act)params[5]);
+ g_cURLManager.CreatecURLThread(thread);
+
+ return 1;
+}
+
+static cell_t sm_curl_send_recv_Signal(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ if(handle->thread == NULL)
+ return 0;
+
+ cURLThread *thread = handle->thread;
+ if(thread->GetRunType() != cURLThread_Type_SEND_RECV ||
+ !handle->running || !thread->IsWaiting()) // is send & recv thread, running, is waiting
+ {
+ return 0;
+ }
+
+ thread->SetSenRecvAction((SendRecv_Act)params[2]);
+ thread->EventSignal();
+
+ return 1;
+}
+
+
+static cell_t sm_curl_send_recv_IsWaiting(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ cURLThread *thread = handle->thread;
+ if(thread == NULL || thread->GetRunType() != cURLThread_Type_SEND_RECV || !handle->running)
+ return 0;
+
+ return (thread->IsWaiting()) ? 1 : 0;
+}
+
+
+static cell_t sm_curl_set_send_buffer(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ char *buffer;
+ pContext->LocalToString(params[2], &buffer);
+
+ if(params[3] == -1)
+ {
+ handle->send_buffer.assign(buffer);
+ } else {
+ handle->send_buffer.assign(buffer,params[3]);
+ }
+
+ return 1;
+}
+
+static cell_t sm_curl_set_receive_size(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ if(handle->thread != NULL)
+ {
+ handle->thread->SetRecvBufferSize((unsigned int)params[2]);
+ }
+ return 1;
+}
+
+static cell_t sm_curl_set_send_timeout(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ if(params[2] > 0)
+ handle->send_timeout = params[2];
+
+ return 1;
+}
+
+static cell_t sm_curl_set_recv_timeout(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_HANDLE();
+
+ if(params[2] > 0)
+ handle->recv_timeout = params[2];
+
+ return 1;
+}
+
+/* Stuff */
+static cell_t sm_curl_version(IPluginContext *pContext, const cell_t *params)
+{
+ pContext->StringToLocalUTF8(params[1], params[2], curl_version(), NULL);
+ return 1;
+}
+
+static cell_t sm_curl_features(IPluginContext *pContext, const cell_t *params)
+{
+ curl_version_info_data *vinfo = curl_version_info(CURLVERSION_NOW);
+ return vinfo->features;
+}
+
+static cell_t sm_curl_protocols(IPluginContext *pContext, const cell_t *params)
+{
+ curl_version_info_data *vinfo = curl_version_info(CURLVERSION_NOW);
+
+ SourceHook::String buffer;
+ const char * const *proto;
+ for(proto=vinfo->protocols; *proto; ++proto) {
+ buffer.append(*proto);
+ buffer.append(" ");
+ }
+ buffer.trim();
+ pContext->StringToLocalUTF8(params[1], params[2], buffer.c_str(), NULL);
+ return 1;
+}
+
+static cell_t sm_curl_OpenFile(IPluginContext *pContext, const cell_t *params)
+{
+ char *name, *mode;
+ int err;
+ if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
+ {
+ pContext->ThrowNativeErrorEx(err, NULL);
+ return 0;
+ }
+ if ((err=pContext->LocalToString(params[2], &mode)) != SP_ERROR_NONE)
+ {
+ pContext->ThrowNativeErrorEx(err, NULL);
+ return 0;
+ }
+
+ char realpath[PLATFORM_MAX_PATH];
+ g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
+
+ FILE *pFile = fopen(realpath, mode);
+ if(!pFile)
+ return 0;
+
+ cURL_OpenFile *openfile = new cURL_OpenFile();
+ openfile->pFile = pFile;
+
+ return handlesys->CreateHandle(g_cURLFile, openfile, pContext->GetIdentity(), myself_Identity, NULL);
+}
+
+static cell_t sm_curl_httppost(IPluginContext *pContext, const cell_t *params)
+{
+ WebForm *webform = new WebForm();
+
+ Handle_t hndl = handlesys->CreateHandle(g_WebForm, webform, pContext->GetIdentity(), myself_Identity, NULL);
+ if(!hndl)
+ {
+ delete webform;
+ return BAD_HANDLE;
+ }
+ return hndl;
+}
+
+static cell_t sm_curl_formadd(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_WEBFORM();
+
+ return (cell_t)g_cURLManager.cURLFormAdd(pContext, params, handle);
+}
+
+static cell_t sm_curl_slist_append(IPluginContext *pContext, const cell_t *params)
+{
+ SETUP_CURL_SLIST();
+
+ char *data;
+ pContext->LocalToString(params[2], &data);
+
+ handle->chunk = curl_slist_append(handle->chunk, data);
+ return 1;
+}
+
+static cell_t sm_curl_slist(IPluginContext *pContext, const cell_t *params)
+{
+ cURL_slist_pack *slist_pack = new cURL_slist_pack();
+
+ Handle_t hndl = handlesys->CreateHandle(g_cURLSlist, slist_pack, pContext->GetIdentity(), myself_Identity, NULL);
+ if(!hndl)
+ {
+ delete slist_pack;
+ return BAD_HANDLE;
+ }
+ return hndl;
+}
+
+static cell_t sm_curl_hash_file(IPluginContext *pContext, const cell_t *params)
+{
+ IPluginFunction *pFunction = pContext->GetFunctionById(params[3]);
+ if(!pFunction)
+ {
+ return pContext->ThrowNativeError("Invalid function %x", params[3]);
+ }
+
+ char *filepath;
+ pContext->LocalToString(params[1], &filepath);
+ int len = strlen(filepath);
+
+ Openssl_Hash_pack *hash_pack = new Openssl_Hash_pack();
+ hash_pack->UserData = params[4];
+ hash_pack->path = new char[len+1];
+ strncpy(hash_pack->path, filepath, len);
+ hash_pack->path[len] = '\0';
+
+ hash_pack->hash_callback = pFunction;
+ hash_pack->algorithm = (Openssl_Hash)params[2];
+
+ OpensslThread *thread = new OpensslThread(hash_pack, OpensslThread_Type_HASH_FILE);
+ threader->MakeThread(thread);
+
+ return 1;
+}
+
+static cell_t sm_curl_hash_string(IPluginContext *pContext, const cell_t *params)
+{
+ char *input;
+ unsigned int data_size = (unsigned int)params[2];
+ if(data_size > 0)
+ {
+ cell_t *addr;
+ pContext->LocalToPhysAddr(params[1], &addr);
+ input = (char *)addr;
+ data_size = params[2];
+ } else {
+ pContext->LocalToString(params[1], &input);
+ data_size = strlen(input);
+ }
+
+ unsigned char output[128];
+ int outlength = 0;
+ bool ret = g_OpensslManager.HashString((Openssl_Hash)params[3], (unsigned char *)input, data_size, &output[0], &outlength);
+ if(!ret || outlength == 0)
+ return 0;
+
+ char buffer[256];
+ int pos = 0;
+ for(int i=0; i<outlength; i++)
+ {
+ sprintf(&buffer[pos],"%02x",(unsigned char)output[i]);
+ pos+=2;
+ }
+ size_t bytes;
+ pContext->StringToLocalUTF8(params[4], params[5], buffer, &bytes);
+ return 1;
+}
+
+sp_nativeinfo_t g_cURLNatives[] =
+{
+ {"curl_easy_init", sm_curl_easy_init},
+ {"curl_easy_setopt_string", sm_curl_easy_setopt_string},
+ {"curl_easy_setopt_int", sm_curl_easy_setopt_int},
+ {"curl_easy_setopt_int_array", sm_curl_easy_setopt_int_array},
+ {"curl_easy_setopt_int64", sm_curl_easy_setopt_int64},
+ {"curl_easy_setopt_handle", sm_curl_easy_setopt_handle},
+ {"curl_easy_setopt_function", sm_curl_easy_setopt_function},
+ {"curl_easy_perform_thread", sm_curl_easy_perform_thread},
+ {"curl_easy_perform", sm_curl_easy_perform},
+ {"curl_easy_getinfo_string", sm_curl_easy_getinfo_string},
+ {"curl_easy_getinfo_int", sm_curl_easy_getinfo_int},
+ {"curl_load_opt", sm_curl_load_opt},
+ {"curl_easy_escape", sm_curl_easy_escape},
+ {"curl_easy_unescape", sm_curl_easy_unescape},
+ {"curl_easy_strerror", sm_curl_easy_strerror},
+ {"curl_get_error_buffer", sm_curl_get_error_buffer},
+
+ {"curl_easy_send_recv", sm_curl_easy_send_recv},
+ {"curl_set_send_buffer", sm_curl_set_send_buffer},
+ {"curl_send_recv_Signal", sm_curl_send_recv_Signal},
+ {"curl_send_recv_IsWaiting", sm_curl_send_recv_IsWaiting},
+ {"curl_set_receive_size", sm_curl_set_receive_size},
+ {"curl_set_send_timeout", sm_curl_set_send_timeout},
+ {"curl_set_recv_timeout", sm_curl_set_recv_timeout},
+
+ {"curl_version", sm_curl_version},
+ {"curl_features", sm_curl_features},
+ {"curl_protocols", sm_curl_protocols},
+ {"curl_OpenFile", sm_curl_OpenFile},
+
+ {"curl_httppost", sm_curl_httppost},
+ {"curl_formadd", sm_curl_formadd},
+
+ {"curl_slist_append", sm_curl_slist_append},
+ {"curl_slist", sm_curl_slist},
+
+ {"curl_hash_file", sm_curl_hash_file},
+ {"curl_hash_string", sm_curl_hash_string},
+
+ {NULL, NULL}
+};
+
+
diff --git a/opensslmanager.cpp b/opensslmanager.cpp
new file mode 100644
index 0000000..058ce51
--- /dev/null
+++ b/opensslmanager.cpp
@@ -0,0 +1,362 @@
+#include "opensslmanager.h"
+#include <openssl/crypto.h>
+#include <openssl/md5.h>
+#include <openssl/md4.h>
+#include <openssl/md2.h>
+#include <openssl/sha.h>
+#include <openssl/ripemd.h>
+
+
+#define MD5_FILE_BUFFER_SIZE 1024*16
+#define MD4_FILE_BUFFER_SIZE 1024*16
+#define MD2_FILE_BUFFER_SIZE 1024*16
+#define SHA_FILE_BUFFER_SIZE 1024*16
+#define SHA1_FILE_BUFFER_SIZE 1024*16
+#define SHA224_FILE_BUFFER_SIZE 1024*16
+#define SHA256_FILE_BUFFER_SIZE 1024*16
+#define SHA384_FILE_BUFFER_SIZE 1024*16
+#define SHA512_FILE_BUFFER_SIZE 1024*16
+#define RIPEMD160_FILE_BUFFER_SIZE 1024*16
+
+
+OpensslManager g_OpensslManager;
+
+static IMutex **ssl_lockarray;
+
+static void MD5_File(FILE *file, unsigned char **output, int *outlength)
+{
+ *output = new unsigned char[MD5_DIGEST_LENGTH];
+ *outlength = MD5_DIGEST_LENGTH;
+
+ MD5_CTX c;
+ int i;
+ unsigned char buf[MD5_FILE_BUFFER_SIZE];
+
+ MD5_Init(&c);
+ for (;;)
+ {
+ i = fread(buf,1,MD5_FILE_BUFFER_SIZE,file);
+ if(i <= 0)
+ break;
+ MD5_Update(&c,buf,(unsigned long)i);
+ }
+ MD5_Final(*output, &c);
+}
+
+static void MD4_File(FILE *file, unsigned char **output, int *outlength)
+{
+ *output = new unsigned char[MD4_DIGEST_LENGTH];
+ *outlength = MD4_DIGEST_LENGTH;
+
+ MD4_CTX c;
+ int i;
+ unsigned char buf[MD4_FILE_BUFFER_SIZE];
+
+ MD4_Init(&c);
+ for (;;)
+ {
+ i = fread(buf,1,MD4_FILE_BUFFER_SIZE,file);
+ if(i <= 0)
+ break;
+ MD4_Update(&c,buf,(unsigned long)i);
+ }
+ MD4_Final(*output, &c);
+}
+
+static void MD2_File(FILE *file, unsigned char **output, int *outlength)
+{
+ *output = new unsigned char[MD2_DIGEST_LENGTH];
+ *outlength = MD2_DIGEST_LENGTH;
+
+ MD2_CTX c;
+ int i;
+ unsigned char buf[MD2_FILE_BUFFER_SIZE];
+
+ MD2_Init(&c);
+ for (;;)
+ {
+ i = fread(buf,1,MD2_FILE_BUFFER_SIZE,file);
+ if(i <= 0)
+ break;
+ MD2_Update(&c,buf,(unsigned long)i);
+ }
+ MD2_Final(*output, &c);
+}
+
+static void SHA_File(FILE *file, unsigned char **output, int *outlength)
+{
+ *output = new unsigned char[SHA_DIGEST_LENGTH];
+ *outlength = SHA_DIGEST_LENGTH;
+
+ SHA_CTX c;
+ int i;
+ unsigned char buf[SHA_FILE_BUFFER_SIZE];
+
+ SHA_Init(&c);
+ for (;;)
+ {
+ i = fread(buf,1,SHA_FILE_BUFFER_SIZE,file);
+ if(i <= 0)
+ break;
+ SHA_Update(&c,buf,(unsigned long)i);
+ }
+ SHA_Final(*output, &c);
+}
+
+static void SHA1_File(FILE *file, unsigned char **output, int *outlength)
+{
+ *output = new unsigned char[SHA_DIGEST_LENGTH];
+ *outlength = SHA_DIGEST_LENGTH;
+
+ SHA_CTX c;
+ int i;
+ unsigned char buf[SHA1_FILE_BUFFER_SIZE];
+
+ SHA1_Init(&c);
+ for (;;)
+ {
+ i = fread(buf,1,SHA1_FILE_BUFFER_SIZE,file);
+ if(i <= 0)
+ break;
+ SHA1_Update(&c,buf,(unsigned long)i);
+ }
+ SHA1_Final(*output, &c);
+}
+
+static void SHA224_File(FILE *file, unsigned char **output, int *outlength)
+{
+ *output = new unsigned char[SHA224_DIGEST_LENGTH];
+ *outlength = SHA224_DIGEST_LENGTH;
+
+ SHA256_CTX c;
+ int i;
+ unsigned char buf[SHA224_FILE_BUFFER_SIZE];
+
+ SHA224_Init(&c);
+ for (;;)
+ {
+ i = fread(buf,1,SHA224_FILE_BUFFER_SIZE,file);
+ if(i <= 0)
+ break;
+ SHA224_Update(&c,buf,(unsigned long)i);
+ }
+ SHA224_Final(*output, &c);
+}
+
+static void SHA256_File(FILE *file, unsigned char **output, int *outlength)
+{
+ *output = new unsigned char[SHA256_DIGEST_LENGTH];
+ *outlength = SHA256_DIGEST_LENGTH;
+
+ SHA256_CTX c;
+ int i;
+ unsigned char buf[SHA256_FILE_BUFFER_SIZE];
+
+ SHA256_Init(&c);
+ for (;;)
+ {
+ i = fread(buf,1,SHA256_FILE_BUFFER_SIZE,file);
+ if(i <= 0)
+ break;
+ SHA256_Update(&c,buf,(unsigned long)i);
+ }
+ SHA256_Final(*output, &c);
+}
+
+static void SHA384_File(FILE *file, unsigned char **output, int *outlength)
+{
+ *output = new unsigned char[SHA384_DIGEST_LENGTH];
+ *outlength = SHA384_DIGEST_LENGTH;
+
+ SHA512_CTX c;
+ int i;
+ unsigned char buf[SHA384_FILE_BUFFER_SIZE];
+
+ SHA384_Init(&c);
+ for (;;)
+ {
+ i = fread(buf,1,SHA384_FILE_BUFFER_SIZE,file);
+ if(i <= 0)
+ break;
+ SHA384_Update(&c,buf,(unsigned long)i);
+ }
+ SHA384_Final(*output, &c);
+}
+
+static void SHA512_File(FILE *file, unsigned char **output, int *outlength)
+{
+ *output = new unsigned char[SHA512_DIGEST_LENGTH];
+ *outlength = SHA512_DIGEST_LENGTH;
+
+ SHA512_CTX c;
+ int i;
+ unsigned char buf[SHA384_FILE_BUFFER_SIZE];
+
+ SHA512_Init(&c);
+ for (;;)
+ {
+ i = fread(buf,1,SHA512_FILE_BUFFER_SIZE,file);
+ if(i <= 0)
+ break;
+ SHA512_Update(&c,buf,(unsigned long)i);
+ }
+ SHA512_Final(*output, &c);
+}
+
+static void RIPEMD160_File(FILE *file, unsigned char **output, int *outlength)
+{
+ *output = new unsigned char[RIPEMD160_DIGEST_LENGTH];
+ *outlength = RIPEMD160_DIGEST_LENGTH;
+
+ RIPEMD160_CTX c;
+ int i;
+ unsigned char buf[RIPEMD160_FILE_BUFFER_SIZE];
+
+ RIPEMD160_Init(&c);
+ for (;;)
+ {
+ i = fread(buf,1,RIPEMD160_FILE_BUFFER_SIZE,file);
+ if(i <= 0)
+ break;
+ RIPEMD160_Update(&c,buf,(unsigned long)i);
+ }
+ RIPEMD160_Final(*output, &c);
+}
+
+static void ssl_locking_callback(int mode, int type, const char *file, int line)
+{
+ if(mode & CRYPTO_LOCK)
+ {
+ ssl_lockarray[type]->Lock();
+ } else {
+ ssl_lockarray[type]->Unlock();
+ }
+}
+
+#ifdef PLATFORM_LINUX
+static unsigned long ssl_id_function(void)
+{
+ return ((unsigned long)getpid());
+}
+#endif
+
+void OpensslManager::SDK_OnLoad()
+{
+ ssl_lockarray = (IMutex **)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(IMutex *));
+ for(int i = 0; i < CRYPTO_num_locks(); i++)
+ {
+ ssl_lockarray[i] = threader->MakeMutex();
+ }
+
+#ifdef PLATFORM_LINUX
+ CRYPTO_set_id_callback(ssl_id_function);
+#endif
+ CRYPTO_set_locking_callback(ssl_locking_callback);
+}
+
+void OpensslManager::SDK_OnUnload()
+{
+#ifdef PLATFORM_LINUX
+ CRYPTO_set_id_callback(NULL);
+#endif
+ CRYPTO_set_locking_callback(NULL);
+ for (int i=0; i<CRYPTO_num_locks(); i++)
+ {
+ ssl_lockarray[i]->DestroyThis();
+ }
+ OPENSSL_free(ssl_lockarray);
+}
+
+
+bool OpensslManager::HashFile(Openssl_Hash algorithm, FILE *pFile, unsigned char **output, int *outlength)
+{
+ if(pFile == NULL)
+ return false;
+
+ switch(algorithm)
+ {
+ case Openssl_Hash_MD5:
+ MD5_File(pFile, output, outlength);
+ return true;
+ case Openssl_Hash_MD4:
+ MD4_File(pFile, output, outlength);
+ return true;
+ case Openssl_Hash_MD2:
+ MD2_File(pFile, output, outlength);
+ return true;
+ case Openssl_Hash_SHA:
+ SHA_File(pFile, output, outlength);
+ return true;
+ case Openssl_Hash_SHA1:
+ SHA1_File(pFile, output, outlength);
+ return true;
+ case Openssl_Hash_SHA224:
+ SHA224_File(pFile, output, outlength);
+ return true;
+ case Openssl_Hash_SHA256:
+ SHA256_File(pFile, output, outlength);
+ return true;
+ case Openssl_Hash_SHA384:
+ SHA384_File(pFile, output, outlength);
+ return true;
+ case Openssl_Hash_SHA512:
+ SHA512_File(pFile, output, outlength);
+ return true;
+ case Openssl_Hash_RIPEMD160:
+ RIPEMD160_File(pFile, output, outlength);
+ return true;
+ }
+
+ return false;
+}
+
+
+bool OpensslManager::HashString(Openssl_Hash algorithm, unsigned char *input, int size, unsigned char *output, int *outlength)
+{
+ switch(algorithm)
+ {
+ case Openssl_Hash_MD5:
+ MD5(input, size, output);
+ *outlength = MD5_DIGEST_LENGTH;
+ return true;
+ case Openssl_Hash_MD4:
+ MD4(input, size, output);
+ *outlength = MD4_DIGEST_LENGTH;
+ return true;
+ case Openssl_Hash_MD2:
+ MD2(input, size, output);
+ *outlength = MD2_DIGEST_LENGTH;
+ return true;
+ case Openssl_Hash_SHA:
+ SHA(input, size, output);
+ *outlength = SHA_DIGEST_LENGTH;
+ return true;
+ case Openssl_Hash_SHA1:
+ SHA1(input, size, output);
+ *outlength = SHA_DIGEST_LENGTH;
+ return true;
+ case Openssl_Hash_SHA224:
+ SHA224(input, size, output);
+ *outlength = SHA224_DIGEST_LENGTH;
+ return true;
+ case Openssl_Hash_SHA256:
+ SHA256(input, size, output);
+ *outlength = SHA256_DIGEST_LENGTH;
+ return true;
+ case Openssl_Hash_SHA384:
+ SHA384(input, size, output);
+ *outlength = SHA384_DIGEST_LENGTH;
+ return true;
+ case Openssl_Hash_SHA512:
+ SHA512(input, size, output);
+ *outlength = SHA512_DIGEST_LENGTH;
+ return true;
+ case Openssl_Hash_RIPEMD160:
+ RIPEMD160(input, size, output);
+ *outlength = RIPEMD160_DIGEST_LENGTH;
+ return true;
+ }
+
+ return false;
+}
+
diff --git a/opensslmanager.h b/opensslmanager.h
new file mode 100644
index 0000000..03c6fc9
--- /dev/null
+++ b/opensslmanager.h
@@ -0,0 +1,23 @@
+#ifndef _INCLUDE_SOURCEMOD_EXTENSION_OPENSSLMANAGER_H_
+#define _INCLUDE_SOURCEMOD_EXTENSION_OPENSSLMANAGER_H_
+
+#include "extension.h"
+#include "opensslthread.h"
+
+class OpensslManager
+{
+public:
+ void SDK_OnLoad();
+ void SDK_OnUnload();
+
+public:
+ bool HashFile(Openssl_Hash algorithm, FILE *pFile, unsigned char **output, int *outlength);
+ bool HashString(Openssl_Hash algorithm, unsigned char *input, int size, unsigned char *output, int *outlength);
+
+};
+
+extern OpensslManager g_OpensslManager;
+
+
+#endif
+
diff --git a/opensslthread.cpp b/opensslthread.cpp
new file mode 100644
index 0000000..84e2286
--- /dev/null
+++ b/opensslthread.cpp
@@ -0,0 +1,100 @@
+#include "opensslthread.h"
+
+
+OpensslThread::OpensslThread(void *_data, OpensslThread_Type _type):
+type(_type),data(_data)
+{
+ assert((type > OpensslThread_Type_NOTHING && type < OpensslThread_Type_LAST));
+ assert((data != NULL));
+}
+
+
+OpensslThread::~OpensslThread()
+{
+
+}
+
+static void openssl_hash_FramAction(void *data)
+{
+ if(data == NULL)
+ return;
+
+ Openssl_Hash_pack *handle = (Openssl_Hash_pack *)data;
+
+ IPluginFunction *pFunc = handle->hash_callback;
+ assert((pFunc != NULL));
+ if(pFunc != NULL)
+ {
+ pFunc->PushCell(handle->success);
+ if(handle->output == NULL)
+ pFunc->PushString("");
+ else
+ pFunc->PushString(handle->output);
+ pFunc->PushCell(handle->UserData);
+ pFunc->Execute(NULL);
+ }
+
+ if(handle->output != NULL)
+ delete handle->output;
+ if(handle->path != NULL)
+ delete handle->path;
+ delete handle;
+}
+
+void OpensslThread::RunFileHash()
+{
+ Openssl_Hash_pack *handle = (Openssl_Hash_pack *)data;
+ handle->success = false;
+
+ assert((handle->path != NULL));
+
+ char realpath[PLATFORM_MAX_PATH];
+ g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", handle->path);
+ FILE *pFile = fopen(realpath, "rb");
+ if(!pFile)
+ return;
+
+ unsigned char *output = NULL;
+ int outlength;
+
+ if(!g_OpensslManager.HashFile(handle->algorithm, pFile, &output, &outlength))
+ goto clean;
+
+ assert((output != NULL));
+ if(output != NULL)
+ {
+ handle->output = new char[outlength*2+1];
+ int pos = 0;
+ for(int i=0; i<outlength; i++)
+ {
+ sprintf(&handle->output[pos],"%02x",(unsigned char)output[i]);
+ pos+=2;
+ }
+ handle->success = true;
+ }
+
+clean:
+ if(output != NULL)
+ delete output;
+
+ fclose(pFile);
+}
+
+void OpensslThread::RunThread(IThreadHandle *pHandle)
+{
+ if(type == OpensslThread_Type_HASH_FILE)
+ {
+ RunFileHash();
+ }
+}
+
+void OpensslThread::OnTerminate(IThreadHandle *pHandle, bool cancel)
+{
+ if(type == OpensslThread_Type_HASH_FILE)
+ {
+ smutils->AddFrameAction(openssl_hash_FramAction, data);
+ }
+
+ delete this;
+}
+
diff --git a/opensslthread.h b/opensslthread.h
new file mode 100644
index 0000000..202beeb
--- /dev/null
+++ b/opensslthread.h
@@ -0,0 +1,29 @@
+#ifndef _INCLUDE_SOURCEMOD_EXTENSION_OPENSSLTHREAD_H_
+#define _INCLUDE_SOURCEMOD_EXTENSION_OPENSSLTHREAD_H_
+
+#include "extension.h"
+#include "opensslmanager.h"
+
+class OpensslThread : public IThread
+{
+ friend class OpensslManager;
+
+public:
+ OpensslThread(void *_data, OpensslThread_Type type);
+ ~OpensslThread();
+
+public:
+ void RunThread(IThreadHandle *pHandle);
+ void OnTerminate(IThreadHandle *pHandle, bool cancel);
+
+private:
+ void RunFileHash();
+
+private:
+ OpensslThread_Type type;
+ void *data;
+};
+
+
+#endif
+
diff --git a/sdk/smsdk_config.h b/sdk/smsdk_config.h
new file mode 100644
index 0000000..8cefb2e
--- /dev/null
+++ b/sdk/smsdk_config.h
@@ -0,0 +1,83 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod cURL Extension
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * 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, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or <http://www.sourcemod.net/license.php>.
+ *
+ * Version: $Id$
+ */
+
+#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
+#define _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
+
+/**
+ * @file smsdk_config.h
+ * @brief Contains macros for configuring basic extension information.
+ */
+
+/* Basic information exposed publicly */
+#define SMEXT_CONF_NAME "cURL Extension"
+#define SMEXT_CONF_DESCRIPTION "cURL Extension"
+#define SMEXT_CONF_VERSION "1.3.0.0"
+#define SMEXT_CONF_AUTHOR "ben"
+#define SMEXT_CONF_URL "http://www.ZombieX2.net/"
+#define SMEXT_CONF_LOGTAG "cURL"
+#define SMEXT_CONF_LICENSE "GPL"
+#define SMEXT_CONF_DATESTRING __DATE__
+
+/**
+ * @brief Exposes plugin's main interface.
+ */
+#define SMEXT_LINK(name) SDKExtension *g_pExtensionIface = name;
+
+/**
+ * @brief Sets whether or not this plugin required Metamod.
+ * NOTE: Uncomment to enable, comment to disable.
+ */
+
+//#define SMEXT_CONF_METAMOD
+
+
+/** Enable interfaces you want to use here by uncommenting lines */
+//#define SMEXT_ENABLE_FORWARDSYS
+#define SMEXT_ENABLE_HANDLESYS
+//#define SMEXT_ENABLE_PLAYERHELPERS
+//#define SMEXT_ENABLE_DBMANAGER
+//#define SMEXT_ENABLE_GAMECONF
+//#define SMEXT_ENABLE_MEMUTILS
+//#define SMEXT_ENABLE_GAMEHELPERS
+//#define SMEXT_ENABLE_TIMERSYS
+#define SMEXT_ENABLE_THREADER
+//#define SMEXT_ENABLE_LIBSYS
+//#define SMEXT_ENABLE_MENUS
+//#define SMEXT_ENABLE_ADTFACTORY
+//#define SMEXT_ENABLE_PLUGINSYS
+//#define SMEXT_ENABLE_ADMINSYS
+//#define SMEXT_ENABLE_TEXTPARSERS
+//#define SMEXT_ENABLE_USERMSGS
+//#define SMEXT_ENABLE_TRANSLATOR
+//#define SMEXT_ENABLE_NINVOKE
+
+#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
diff --git a/sdk/smsdk_ext.cpp b/sdk/smsdk_ext.cpp
new file mode 100644
index 0000000..d9c49d8
--- /dev/null
+++ b/sdk/smsdk_ext.cpp
@@ -0,0 +1,465 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod Base Extension Code
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * 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, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or <http://www.sourcemod.net/license.php>.
+ *
+ * Version: $Id$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "smsdk_ext.h"
+
+/**
+ * @file smsdk_ext.cpp
+ * @brief Contains wrappers for making Extensions easier to write.
+ */
+
+IExtension *myself = NULL; /**< Ourself */
+IShareSys *g_pShareSys = NULL; /**< Share system */
+IShareSys *sharesys = NULL; /**< Share system */
+ISourceMod *g_pSM = NULL; /**< SourceMod helpers */
+ISourceMod *smutils = NULL; /**< SourceMod helpers */
+
+#if defined SMEXT_ENABLE_FORWARDSYS
+IForwardManager *g_pForwards = NULL; /**< Forward system */
+IForwardManager *forwards = NULL; /**< Forward system */
+#endif
+#if defined SMEXT_ENABLE_HANDLESYS
+IHandleSys *g_pHandleSys = NULL; /**< Handle system */
+IHandleSys *handlesys = NULL; /**< Handle system */
+#endif
+#if defined SMEXT_ENABLE_PLAYERHELPERS
+IPlayerManager *playerhelpers = NULL; /**< Player helpers */
+#endif //SMEXT_ENABLE_PLAYERHELPERS
+#if defined SMEXT_ENABLE_DBMANAGER
+IDBManager *dbi = NULL; /**< DB Manager */
+#endif //SMEXT_ENABLE_DBMANAGER
+#if defined SMEXT_ENABLE_GAMECONF
+IGameConfigManager *gameconfs = NULL; /**< Game config manager */
+#endif //SMEXT_ENABLE_DBMANAGER
+#if defined SMEXT_ENABLE_MEMUTILS
+IMemoryUtils *memutils = NULL;
+#endif //SMEXT_ENABLE_DBMANAGER
+#if defined SMEXT_ENABLE_GAMEHELPERS
+IGameHelpers *gamehelpers = NULL;
+#endif
+#if defined SMEXT_ENABLE_TIMERSYS
+ITimerSystem *timersys = NULL;
+#endif
+#if defined SMEXT_ENABLE_ADTFACTORY
+IADTFactory *adtfactory = NULL;
+#endif
+#if defined SMEXT_ENABLE_THREADER
+IThreader *threader = NULL;
+#endif
+#if defined SMEXT_ENABLE_LIBSYS
+ILibrarySys *libsys = NULL;
+#endif
+#if defined SMEXT_ENABLE_PLUGINSYS
+SourceMod::IPluginManager *plsys;
+#endif
+#if defined SMEXT_ENABLE_MENUS
+IMenuManager *menus = NULL;
+#endif
+#if defined SMEXT_ENABLE_ADMINSYS
+IAdminSystem *adminsys = NULL;
+#endif
+#if defined SMEXT_ENABLE_TEXTPARSERS
+ITextParsers *textparsers = NULL;
+#endif
+#if defined SMEXT_ENABLE_USERMSGS
+IUserMessages *usermsgs = NULL;
+#endif
+#if defined SMEXT_ENABLE_TRANSLATOR
+ITranslator *translator = NULL;
+#endif
+#if defined SMEXT_ENABLE_NINVOKE
+INativeInterface *ninvoke = NULL;
+#endif
+
+/** Exports the main interface */
+PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI()
+{
+ return g_pExtensionIface;
+}
+
+SDKExtension::SDKExtension()
+{
+#if defined SMEXT_CONF_METAMOD
+ m_SourceMMLoaded = false;
+ m_WeAreUnloaded = false;
+ m_WeGotPauseChange = false;
+#endif
+}
+
+bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late)
+{
+ g_pShareSys = sharesys = sys;
+ myself = me;
+
+#if defined SMEXT_CONF_METAMOD
+ m_WeAreUnloaded = true;
+
+ if (!m_SourceMMLoaded)
+ {
+ if (error)
+ {
+ snprintf(error, maxlength, "Metamod attach failed");
+ }
+ return false;
+ }
+#endif
+ SM_GET_IFACE(SOURCEMOD, g_pSM);
+ smutils = g_pSM;
+#if defined SMEXT_ENABLE_HANDLESYS
+ SM_GET_IFACE(HANDLESYSTEM, g_pHandleSys);
+ handlesys = g_pHandleSys;
+#endif
+#if defined SMEXT_ENABLE_FORWARDSYS
+ SM_GET_IFACE(FORWARDMANAGER, g_pForwards);
+ forwards = g_pForwards;
+#endif
+#if defined SMEXT_ENABLE_PLAYERHELPERS
+ SM_GET_IFACE(PLAYERMANAGER, playerhelpers);
+#endif
+#if defined SMEXT_ENABLE_DBMANAGER
+ SM_GET_IFACE(DBI, dbi);
+#endif
+#if defined SMEXT_ENABLE_GAMECONF
+ SM_GET_IFACE(GAMECONFIG, gameconfs);
+#endif
+#if defined SMEXT_ENABLE_MEMUTILS
+ SM_GET_IFACE(MEMORYUTILS, memutils);
+#endif
+#if defined SMEXT_ENABLE_GAMEHELPERS
+ SM_GET_IFACE(GAMEHELPERS, gamehelpers);
+#endif
+#if defined SMEXT_ENABLE_TIMERSYS
+ SM_GET_IFACE(TIMERSYS, timersys);
+#endif
+#if defined SMEXT_ENABLE_ADTFACTORY
+ SM_GET_IFACE(ADTFACTORY, adtfactory);
+#endif
+#if defined SMEXT_ENABLE_THREADER
+ SM_GET_IFACE(THREADER, threader);
+#endif
+#if defined SMEXT_ENABLE_LIBSYS
+ SM_GET_IFACE(LIBRARYSYS, libsys);
+#endif
+#if defined SMEXT_ENABLE_PLUGINSYS
+ SM_GET_IFACE(PLUGINSYSTEM, plsys);
+#endif
+#if defined SMEXT_ENABLE_MENUS
+ SM_GET_IFACE(MENUMANAGER, menus);
+#endif
+#if defined SMEXT_ENABLE_ADMINSYS
+ SM_GET_IFACE(ADMINSYS, adminsys);
+#endif
+#if defined SMEXT_ENABLE_TEXTPARSERS
+ SM_GET_IFACE(TEXTPARSERS, textparsers);
+#endif
+#if defined SMEXT_ENABLE_USERMSGS
+ SM_GET_IFACE(USERMSGS, usermsgs);
+#endif
+#if defined SMEXT_ENABLE_TRANSLATOR
+ SM_GET_IFACE(TRANSLATOR, translator);
+#endif
+
+ if (SDK_OnLoad(error, maxlength, late))
+ {
+#if defined SMEXT_CONF_METAMOD
+ m_WeAreUnloaded = true;
+#endif
+ return true;
+ }
+
+ return false;
+}
+
+bool SDKExtension::IsMetamodExtension()
+{
+#if defined SMEXT_CONF_METAMOD
+ return true;
+#else
+ return false;
+#endif
+}
+
+void SDKExtension::OnExtensionPauseChange(bool state)
+{
+#if defined SMEXT_CONF_METAMOD
+ m_WeGotPauseChange = true;
+#endif
+ SDK_OnPauseChange(state);
+}
+
+void SDKExtension::OnExtensionsAllLoaded()
+{
+ SDK_OnAllLoaded();
+}
+
+void SDKExtension::OnExtensionUnload()
+{
+#if defined SMEXT_CONF_METAMOD
+ m_WeAreUnloaded = true;
+#endif
+ SDK_OnUnload();
+}
+
+const char *SDKExtension::GetExtensionAuthor()
+{
+ return SMEXT_CONF_AUTHOR;
+}
+
+const char *SDKExtension::GetExtensionDateString()
+{
+ return SMEXT_CONF_DATESTRING;
+}
+
+const char *SDKExtension::GetExtensionDescription()
+{
+ return SMEXT_CONF_DESCRIPTION;
+}
+
+const char *SDKExtension::GetExtensionVerString()
+{
+ return SMEXT_CONF_VERSION;
+}
+
+const char *SDKExtension::GetExtensionName()
+{
+ return SMEXT_CONF_NAME;
+}
+
+const char *SDKExtension::GetExtensionTag()
+{
+ return SMEXT_CONF_LOGTAG;
+}
+
+const char *SDKExtension::GetExtensionURL()
+{
+ return SMEXT_CONF_URL;
+}
+
+bool SDKExtension::SDK_OnLoad(char *error, size_t maxlength, bool late)
+{
+ return true;
+}
+
+void SDKExtension::SDK_OnUnload()
+{
+}
+
+void SDKExtension::SDK_OnPauseChange(bool paused)
+{
+}
+
+void SDKExtension::SDK_OnAllLoaded()
+{
+}
+
+#if defined SMEXT_CONF_METAMOD
+
+PluginId g_PLID = 0; /**< Metamod plugin ID */
+ISmmPlugin *g_PLAPI = NULL; /**< Metamod plugin API */
+SourceHook::ISourceHook *g_SHPtr = NULL; /**< SourceHook pointer */
+ISmmAPI *g_SMAPI = NULL; /**< SourceMM API pointer */
+
+IVEngineServer *engine = NULL; /**< IVEngineServer pointer */
+IServerGameDLL *gamedll = NULL; /**< IServerGameDLL pointer */
+
+/** Exposes the extension to Metamod */
+SMM_API void *PL_EXPOSURE(const char *name, int *code)
+{
+#if defined METAMOD_PLAPI_VERSION
+ if (name && !strcmp(name, METAMOD_PLAPI_NAME))
+#else
+ if (name && !strcmp(name, PLAPI_NAME))
+#endif
+ {
+ if (code)
+ {
+ *code = IFACE_OK;
+ }
+ return static_cast<void *>(g_pExtensionIface);
+ }
+
+ if (code)
+ {
+ *code = IFACE_FAILED;
+ }
+
+ return NULL;
+}
+
+bool SDKExtension::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
+{
+ PLUGIN_SAVEVARS();
+
+#if !defined METAMOD_PLAPI_VERSION
+ GET_V_IFACE_ANY(serverFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL);
+ GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
+#else
+ GET_V_IFACE_ANY(GetServerFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL);
+ GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
+#endif
+
+ m_SourceMMLoaded = true;
+
+ return SDK_OnMetamodLoad(ismm, error, maxlen, late);
+}
+
+bool SDKExtension::Unload(char *error, size_t maxlen)
+{
+ if (!m_WeAreUnloaded)
+ {
+ if (error)
+ {
+ snprintf(error, maxlen, "This extension must be unloaded by SourceMod.");
+ }
+ return false;
+ }
+
+ return SDK_OnMetamodUnload(error, maxlen);
+}
+
+bool SDKExtension::Pause(char *error, size_t maxlen)
+{
+ if (!m_WeGotPauseChange)
+ {
+ if (error)
+ {
+ snprintf(error, maxlen, "This extension must be paused by SourceMod.");
+ }
+ return false;
+ }
+
+ m_WeGotPauseChange = false;
+
+ return SDK_OnMetamodPauseChange(true, error, maxlen);
+}
+
+bool SDKExtension::Unpause(char *error, size_t maxlen)
+{
+ if (!m_WeGotPauseChange)
+ {
+ if (error)
+ {
+ snprintf(error, maxlen, "This extension must be unpaused by SourceMod.");
+ }
+ return false;
+ }
+
+ m_WeGotPauseChange = false;
+
+ return SDK_OnMetamodPauseChange(false, error, maxlen);
+}
+
+const char *SDKExtension::GetAuthor()
+{
+ return GetExtensionAuthor();
+}
+
+const char *SDKExtension::GetDate()
+{
+ return GetExtensionDateString();
+}
+
+const char *SDKExtension::GetDescription()
+{
+ return GetExtensionDescription();
+}
+
+const char *SDKExtension::GetLicense()
+{
+ return SMEXT_CONF_LICENSE;
+}
+
+const char *SDKExtension::GetLogTag()
+{
+ return GetExtensionTag();
+}
+
+const char *SDKExtension::GetName()
+{
+ return GetExtensionName();
+}
+
+const char *SDKExtension::GetURL()
+{
+ return GetExtensionURL();
+}
+
+const char *SDKExtension::GetVersion()
+{
+ return GetExtensionVerString();
+}
+
+bool SDKExtension::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late)
+{
+ return true;
+}
+
+bool SDKExtension::SDK_OnMetamodUnload(char *error, size_t maxlength)
+{
+ return true;
+}
+
+bool SDKExtension::SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength)
+{
+ return true;
+}
+
+#endif
+
+/* Overload a few things to prevent libstdc++ linking */
+#if defined __linux__ || defined __APPLE__
+extern "C" void __cxa_pure_virtual(void)
+{
+}
+
+void *operator new(size_t size)
+{
+ return malloc(size);
+}
+
+void *operator new[](size_t size)
+{
+ return malloc(size);
+}
+
+void operator delete(void *ptr)
+{
+ free(ptr);
+}
+
+void operator delete[](void * ptr)
+{
+ free(ptr);
+}
+#endif
+
diff --git a/sdk/smsdk_ext.h b/sdk/smsdk_ext.h
new file mode 100644
index 0000000..210db3a
--- /dev/null
+++ b/sdk/smsdk_ext.h
@@ -0,0 +1,339 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod Base Extension Code
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * 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, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or <http://www.sourcemod.net/license.php>.
+ *
+ * Version: $Id$
+ */
+
+#ifndef _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_
+#define _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_
+
+/**
+ * @file smsdk_ext.h
+ * @brief Contains wrappers for making Extensions easier to write.
+ */
+
+#include "smsdk_config.h"
+#include <IExtensionSys.h>
+#include <IHandleSys.h>
+#include <sp_vm_api.h>
+#include <sm_platform.h>
+#include <ISourceMod.h>
+#if defined SMEXT_ENABLE_FORWARDSYS
+#include <IForwardSys.h>
+#endif //SMEXT_ENABLE_FORWARDSYS
+#if defined SMEXT_ENABLE_PLAYERHELPERS
+#include <IPlayerHelpers.h>
+#endif //SMEXT_ENABLE_PlAYERHELPERS
+#if defined SMEXT_ENABLE_DBMANAGER
+#include <IDBDriver.h>
+#endif //SMEXT_ENABLE_DBMANAGER
+#if defined SMEXT_ENABLE_GAMECONF
+#include <IGameConfigs.h>
+#endif
+#if defined SMEXT_ENABLE_MEMUTILS
+#include <IMemoryUtils.h>
+#endif
+#if defined SMEXT_ENABLE_GAMEHELPERS
+#include <IGameHelpers.h>
+#endif
+#if defined SMEXT_ENABLE_TIMERSYS
+#include <ITimerSystem.h>
+#endif
+#if defined SMEXT_ENABLE_ADTFACTORY
+#include <IADTFactory.h>
+#endif
+#if defined SMEXT_ENABLE_THREADER
+#include <IThreader.h>
+#endif
+#if defined SMEXT_ENABLE_LIBSYS
+#include <ILibrarySys.h>
+#endif
+#if defined SMEXT_ENABLE_PLUGINSYS
+#include <IPluginSys.h>
+#endif
+#if defined SMEXT_ENABLE_MENUS
+#include <IMenuManager.h>
+#endif
+#if defined SMEXT_ENABLE_ADMINSYS
+#include <IAdminSystem.h>
+#endif
+#if defined SMEXT_ENABLE_TEXTPARSERS
+#include <ITextParsers.h>
+#endif
+#if defined SMEXT_ENABLE_USERMSGS
+#include <IUserMessages.h>
+#endif
+#if defined SMEXT_ENABLE_TRANSLATOR
+#include <ITranslator.h>
+#endif
+#if defined SMEXT_ENABLE_NINVOKE
+#include <INativeInvoker.h>
+#endif
+
+#if defined SMEXT_CONF_METAMOD
+#include <ISmmPlugin.h>
+#include <eiface.h>
+#endif
+
+using namespace SourceMod;
+using namespace SourcePawn;
+
+class SDKExtension :
+#if defined SMEXT_CONF_METAMOD
+ public ISmmPlugin,
+#endif
+ public IExtensionInterface
+{
+public:
+ /** Constructor */
+ SDKExtension();
+public:
+ /**
+ * @brief This is called after the initial loading sequence has been processed.
+ *
+ * @param error Error message buffer.
+ * @param maxlength Size of error message buffer.
+ * @param late Whether or not the module was loaded after map load.
+ * @return True to succeed loading, false to fail.
+ */
+ virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
+
+ /**
+ * @brief This is called right before the extension is unloaded.
+ */
+ virtual void SDK_OnUnload();
+
+ /**
+ * @brief This is called once all known extensions have been loaded.
+ */
+ virtual void SDK_OnAllLoaded();
+
+ /**
+ * @brief Called when the pause state is changed.
+ */
+ virtual void SDK_OnPauseChange(bool paused);
+
+#if defined SMEXT_CONF_METAMOD
+ /**
+ * @brief Called when Metamod is attached, before the extension version is called.
+ *
+ * @param error Error buffer.
+ * @param maxlength Maximum size of error buffer.
+ * @param late Whether or not Metamod considers this a late load.
+ * @return True to succeed, false to fail.
+ */
+ virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late);
+
+ /**
+ * @brief Called when Metamod is detaching, after the extension version is called.
+ * NOTE: By default this is blocked unless sent from SourceMod.
+ *
+ * @param error Error buffer.
+ * @param maxlength Maximum size of error buffer.
+ * @return True to succeed, false to fail.
+ */
+ virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
+
+ /**
+ * @brief Called when Metamod's pause state is changing.
+ * NOTE: By default this is blocked unless sent from SourceMod.
+ *
+ * @param paused Pause state being set.
+ * @param error Error buffer.
+ * @param maxlength Maximum size of error buffer.
+ * @return True to succeed, false to fail.
+ */
+ virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
+#endif
+
+public: //IExtensionInterface
+ virtual bool OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late);
+ virtual void OnExtensionUnload();
+ virtual void OnExtensionsAllLoaded();
+
+ /** Returns whether or not this is a Metamod-based extension */
+ virtual bool IsMetamodExtension();
+
+ /**
+ * @brief Called when the pause state changes.
+ *
+ * @param state True if being paused, false if being unpaused.
+ */
+ virtual void OnExtensionPauseChange(bool state);
+
+ /** Returns name */
+ virtual const char *GetExtensionName();
+ /** Returns URL */
+ virtual const char *GetExtensionURL();
+ /** Returns log tag */
+ virtual const char *GetExtensionTag();
+ /** Returns author */
+ virtual const char *GetExtensionAuthor();
+ /** Returns version string */
+ virtual const char *GetExtensionVerString();
+ /** Returns description string */
+ virtual const char *GetExtensionDescription();
+ /** Returns date string */
+ virtual const char *GetExtensionDateString();
+#if defined SMEXT_CONF_METAMOD
+public: //ISmmPlugin
+ /** Called when the extension is attached to Metamod. */
+ virtual bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlength, bool late);
+ /** Returns the author to MM */
+ virtual const char *GetAuthor();
+ /** Returns the name to MM */
+ virtual const char *GetName();
+ /** Returns the description to MM */
+ virtual const char *GetDescription();
+ /** Returns the URL to MM */
+ virtual const char *GetURL();
+ /** Returns the license to MM */
+ virtual const char *GetLicense();
+ /** Returns the version string to MM */
+ virtual const char *GetVersion();
+ /** Returns the date string to MM */
+ virtual const char *GetDate();
+ /** Returns the logtag to MM */
+ virtual const char *GetLogTag();
+ /** Called on unload */
+ virtual bool Unload(char *error, size_t maxlength);
+ /** Called on pause */
+ virtual bool Pause(char *error, size_t maxlength);
+ /** Called on unpause */
+ virtual bool Unpause(char *error, size_t maxlength);
+private:
+ bool m_SourceMMLoaded;
+ bool m_WeAreUnloaded;
+ bool m_WeGotPauseChange;
+#endif
+};
+
+extern SDKExtension *g_pExtensionIface;
+extern IExtension *myself;
+
+extern IShareSys *g_pShareSys;
+extern IShareSys *sharesys; /* Note: Newer name */
+extern ISourceMod *g_pSM;
+extern ISourceMod *smutils; /* Note: Newer name */
+
+/* Optional interfaces are below */
+#if defined SMEXT_ENABLE_FORWARDSYS
+extern IForwardManager *g_pForwards;
+extern IForwardManager *forwards; /* Note: Newer name */
+#endif //SMEXT_ENABLE_FORWARDSYS
+#if defined SMEXT_ENABLE_HANDLESYS
+extern IHandleSys *g_pHandleSys;
+extern IHandleSys *handlesys; /* Note: Newer name */
+#endif //SMEXT_ENABLE_HANDLESYS
+#if defined SMEXT_ENABLE_PLAYERHELPERS
+extern IPlayerManager *playerhelpers;
+#endif //SMEXT_ENABLE_PLAYERHELPERS
+#if defined SMEXT_ENABLE_DBMANAGER
+extern IDBManager *dbi;
+#endif //SMEXT_ENABLE_DBMANAGER
+#if defined SMEXT_ENABLE_GAMECONF
+extern IGameConfigManager *gameconfs;
+#endif //SMEXT_ENABLE_DBMANAGER
+#if defined SMEXT_ENABLE_MEMUTILS
+extern IMemoryUtils *memutils;
+#endif
+#if defined SMEXT_ENABLE_GAMEHELPERS
+extern IGameHelpers *gamehelpers;
+#endif
+#if defined SMEXT_ENABLE_TIMERSYS
+extern ITimerSystem *timersys;
+#endif
+#if defined SMEXT_ENABLE_ADTFACTORY
+extern IADTFactory *adtfactory;
+#endif
+#if defined SMEXT_ENABLE_THREADER
+extern IThreader *threader;
+#endif
+#if defined SMEXT_ENABLE_LIBSYS
+extern ILibrarySys *libsys;
+#endif
+#if defined SMEXT_ENABLE_PLUGINSYS
+extern SourceMod::IPluginManager *plsys;
+#endif
+#if defined SMEXT_ENABLE_MENUS
+extern IMenuManager *menus;
+#endif
+#if defined SMEXT_ENABLE_ADMINSYS
+extern IAdminSystem *adminsys;
+#endif
+#if defined SMEXT_ENABLE_USERMSGS
+extern IUserMessages *usermsgs;
+#endif
+#if defined SMEXT_ENABLE_TRANSLATOR
+extern ITranslator *translator;
+#endif
+#if defined SMEXT_ENABLE_NINVOKE
+extern INativeInterface *ninvoke;
+#endif
+
+#if defined SMEXT_CONF_METAMOD
+PLUGIN_GLOBALVARS();
+extern IVEngineServer *engine;
+extern IServerGameDLL *gamedll;
+#endif
+
+/** Creates a SourceMod interface macro pair */
+#define SM_MKIFACE(name) SMINTERFACE_##name##_NAME, SMINTERFACE_##name##_VERSION
+/** Automates retrieving SourceMod interfaces */
+#define SM_GET_IFACE(prefix, addr) \
+ if (!g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr)) \
+ { \
+ if (error != NULL && maxlength) \
+ { \
+ size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \
+ if (len >= maxlength) \
+ { \
+ error[maxlength - 1] = '\0'; \
+ } \
+ } \
+ return false; \
+ }
+/** Automates retrieving SourceMod interfaces when needed outside of SDK_OnLoad() */
+#define SM_GET_LATE_IFACE(prefix, addr) \
+ g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr)
+/** Validates a SourceMod interface pointer */
+#define SM_CHECK_IFACE(prefix, addr) \
+ if (!addr) \
+ { \
+ if (error != NULL && maxlength) \
+ { \
+ size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \
+ if (len >= maxlength) \
+ { \
+ error[maxlength - 1] = '\0'; \
+ } \
+ } \
+ return false; \
+ }
+
+#endif // _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_