From 2af23e813d8e8a1f2ab140a29a0751ac68624fae Mon Sep 17 00:00:00 2001 From: "Tony J. White =" Date: Mon, 11 Sep 2006 16:41:55 +0000 Subject: [PATCH] * add cURL support for HTTP/FTP downloading (bug 2661) --- Makefile | 51 + README | 41 + code/client/cl_curl.c | 358 +++++++ code/client/cl_curl.h | 101 ++ code/client/cl_main.c | 90 +- code/client/cl_parse.c | 22 + code/client/client.h | 15 + code/libcurl/curl/curl.h | 1563 +++++++++++++++++++++++++++++++ code/libcurl/curl/curlver.h | 56 ++ code/libcurl/curl/easy.h | 81 ++ code/libcurl/curl/mprintf.h | 62 ++ code/libcurl/curl/multi.h | 344 +++++++ code/libcurl/curl/stdcheaders.h | 34 + code/libcurl/curl/types.h | 1 + code/libs/win32/libcurl.a | Bin 0 -> 253484 bytes code/qcommon/qcommon.h | 6 + code/server/sv_client.c | 9 +- code/server/sv_init.c | 1 + 18 files changed, 2829 insertions(+), 6 deletions(-) create mode 100644 code/client/cl_curl.c create mode 100644 code/client/cl_curl.h create mode 100644 code/libcurl/curl/curl.h create mode 100644 code/libcurl/curl/curlver.h create mode 100644 code/libcurl/curl/easy.h create mode 100644 code/libcurl/curl/mprintf.h create mode 100644 code/libcurl/curl/multi.h create mode 100644 code/libcurl/curl/stdcheaders.h create mode 100644 code/libcurl/curl/types.h create mode 100644 code/libs/win32/libcurl.a diff --git a/Makefile b/Makefile index 8ade2cd3..c4f743b7 100644 --- a/Makefile +++ b/Makefile @@ -100,6 +100,18 @@ ifndef USE_OPENAL_DLOPEN USE_OPENAL_DLOPEN=0 endif +ifndef USE_CURL +USE_CURL=1 +endif + +ifndef USE_CURL_DLOPEN + ifeq ($(PLATFORM),mingw32) + USE_CURL_DLOPEN=0 + else + USE_CURL_DLOPEN=1 + endif +endif + ifndef USE_CODEC_VORBIS USE_CODEC_VORBIS=0 endif @@ -187,6 +199,13 @@ ifeq ($(PLATFORM),linux) BASE_CFLAGS += -DUSE_OPENAL_DLOPEN=1 endif endif + + ifeq ($(USE_CURL),1) + BASE_CFLAGS += -DUSE_CURL=1 + ifeq ($(USE_CURL_DLOPEN),1) + BASE_CFLAGS += -DUSE_CURL_DLOPEN=1 + endif + endif ifeq ($(USE_CODEC_VORBIS),1) BASE_CFLAGS += -DUSE_CODEC_VORBIS=1 @@ -249,6 +268,12 @@ ifeq ($(PLATFORM),linux) CLIENT_LDFLAGS += -lopenal endif endif + + ifeq ($(USE_CURL),1) + ifneq ($(USE_CURL_DLOPEN),1) + CLIENT_LDFLAGS += -lcurl + endif + endif ifeq ($(USE_CODEC_VORBIS),1) CLIENT_LDFLAGS += -lvorbisfile -lvorbis -logg @@ -348,6 +373,15 @@ ifeq ($(PLATFORM),darwin) BASE_CFLAGS += -DUSE_OPENAL_DLOPEN=1 endif endif + + ifeq ($(USE_CURL),1) + BASE_CFLAGS += -DUSE_CURL=1 + ifneq ($(USE_CURL_DLOPEN),1) + CLIENT_LDFLAGS += -lcurl + else + BASE_CFLAGS += -DUSE_CURL_DLOPEN=1 + endif + endif ifeq ($(USE_CODEC_VORBIS),1) BASE_CFLAGS += -DUSE_CODEC_VORBIS=1 @@ -404,6 +438,13 @@ ifeq ($(PLATFORM),mingw32) ifeq ($(USE_OPENAL),1) BASE_CFLAGS += -DUSE_OPENAL=1 -DUSE_OPENAL_DLOPEN=1 endif + + ifeq ($(USE_CURL),1) + BASE_CFLAGS += -DUSE_CURL=1 + ifneq ($(USE_CURL_DLOPEN),1) + BASE_CFLAGS += -DCURL_STATICLIB + endif + endif ifeq ($(USE_CODEC_VORBIS),1) BASE_CFLAGS += -DUSE_CODEC_VORBIS=1 @@ -430,6 +471,12 @@ ifeq ($(PLATFORM),mingw32) LDFLAGS= -mwindows -lshfolder -lwsock32 -lgdi32 -lwinmm -lole32 CLIENT_LDFLAGS= + ifeq ($(USE_CURL),1) + ifneq ($(USE_CURL_DLOPEN),1) + CLIENT_LDFLAGS += $(LIBSDIR)/win32/libcurl.a + endif + endif + ifeq ($(USE_CODEC_VORBIS),1) CLIENT_LDFLAGS += -lvorbisfile -lvorbis -logg endif @@ -847,6 +894,8 @@ Q3OBJ = \ $(B)/client/qal.o \ $(B)/client/snd_openal.o \ \ + $(B)/client/cl_curl.o \ + \ $(B)/client/sv_bot.o \ $(B)/client/sv_ccmds.o \ $(B)/client/sv_client.o \ @@ -1067,6 +1116,8 @@ $(B)/client/snd_codec_ogg.o : $(CDIR)/snd_codec_ogg.c; $(DO_CC) $(B)/client/qal.o : $(CDIR)/qal.c; $(DO_CC) $(B)/client/snd_openal.o : $(CDIR)/snd_openal.c; $(DO_CC) +$(B)/client/cl_curl.o : $(CDIR)/cl_curl.c; $(DO_CC) + $(B)/client/sv_bot.o : $(SDIR)/sv_bot.c; $(DO_CC) $(B)/client/sv_client.o : $(SDIR)/sv_client.c; $(DO_CC) $(B)/client/sv_ccmds.o : $(SDIR)/sv_ccmds.c; $(DO_CC) diff --git a/README b/README index c731d777..0590785f 100644 --- a/README +++ b/README @@ -23,6 +23,7 @@ for further development. Some of the major features currently implemented are: * Much improved QVM tools * Support for various esoteric operating systems (see http://icculus.org/quake3/?page=status) + * HTTP/FTP download redirection (using cURL) * Many, many bug fixes The map editor and associated compiling tools are not included. We suggest you @@ -140,6 +141,9 @@ New cvars cl_platformSensitivity - read only, indicates the mouse input scaling r_ext_texture_filter_anisotropic - anisotropic texture filtering + cl_cURLLib - filename of cURL library to load + sv_dlURL - the base of the HTTP or FTP site that + holds custom pk3 files for your server New commands video [filename] - start video capture (use with demo command) @@ -192,6 +196,43 @@ Creating mods compatible with Q3 1.32b compiler. See http://www.quakesrc.org/forums/viewtopic.php?t=5665 (if it still exists when you read this) for more details. +Using HTTP/FTP Download Support (Server) + You can enable redirected downloads on your server even if it's not + an ioquake3 server. You simply need to use the 'sets' command to put + the sv_dlURL cvar into your SERVERINFO string and ensure sv_allowDownloads + is set to 1 + + sv_dlURL is the base of the URL that contains your custom .pk3 files + the client will append both fs_game and the filename to the end of + this value. For example, if you have sv_dlURL set to + "http://icculus.org/quake3", fs_game is "baseq3", and the client is + missing "test.pk3", it will attempt to download from the URL + "http://icculus.org/quake3/baseq3/test.pk3" + + sv_allowDownload's value is now a bitmask made up of the following + flags: + 1 - ENABLE + 2 - do not use HTTP/FTP downloads + 4 - do not use UDP downloads + 8 - do not ask the client to disconnect when using HTTP/FTP + + Server operators who are concerned about potential "leeching" from their + HTTP servers from other ioquake3 servers can make use of the HTTP_REFERER + that ioquake3 sets which is "ioQ3://{SERVER_IP}:{SERVER_PORT}". For, + example, Apache's mod_rewrite can restrict access based on HTTP_REFERER. + +Using HTTP/FTP Download Support (Client) + Simply setting cl_allowDownload to 1 will enable HTTP/FTP downloads + assuming ioquake3 was compiled with USE_CURL=1 (the default). + like sv_allowDownload, cl_allowDownload also uses a bitmask value + supporting the following flags: + 1 - ENABLE + 2 - do not use HTTP/FTP downloads + 4 - do not use UDP downloads + + When ioquake3 is built with USE_CURL_DLOPEN=1 (default on some platforms), + it will use the value of the cvar cl_cURLLib as the filename of the cURL + library to dynamically load. ------------------------------------------------------------- Contributing ----- diff --git a/code/client/cl_curl.c b/code/client/cl_curl.c new file mode 100644 index 00000000..38498eeb --- /dev/null +++ b/code/client/cl_curl.c @@ -0,0 +1,358 @@ +/* +=========================================================================== +Copyright (C) 2006 Tony J. White (tjw@tjw.org) + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#if USE_CURL +#include "client.h" +cvar_t *cl_cURLLib; + +#if USE_CURL_DLOPEN + +#if USE_SDL_VIDEO +#include "SDL.h" +#include "SDL_loadso.h" +#define OBJTYPE void * +#define OBJLOAD(x) SDL_LoadObject(x) +#define SYMLOAD(x,y) SDL_LoadFunction(x,y) +#define OBJFREE(x) SDL_UnloadObject(x) + +#elif defined _WIN32 +#include +#define OBJTYPE HMODULE +#define OBJLOAD(x) LoadLibrary(x) +#define SYMLOAD(x,y) GetProcAddress(x,y) +#define OBJFREE(x) FreeLibrary(x) + +#elif defined __linux__ || defined __FreeBSD__ || defined MACOS_X || defined __sun +#include +#define OBJTYPE void * +#define OBJLOAD(x) dlopen(x, RTLD_LAZY | RTLD_GLOBAL) +#define SYMLOAD(x,y) dlsym(x,y) +#define OBJFREE(x) dlclose(x) +#else + +#error "Your platform has no lib loading code or it is disabled" +#endif + +#if defined __linux__ || defined __FreeBSD__ || defined MACOS_X +#include +#include +#endif + +char* (*qcurl_version)(void); + +CURL* (*qcurl_easy_init)(void); +CURLcode (*qcurl_easy_setopt)(CURL *curl, CURLoption option, ...); +CURLcode (*qcurl_easy_perform)(CURL *curl); +void (*qcurl_easy_cleanup)(CURL *curl); +CURLcode (*qcurl_easy_getinfo)(CURL *curl, CURLINFO info, ...); +CURL* (*qcurl_easy_duphandle)(CURL *curl); +void (*qcurl_easy_reset)(CURL *curl); +const char *(*qcurl_easy_strerror)(CURLcode); + +CURLM* (*qcurl_multi_init)(void); +CURLMcode (*qcurl_multi_add_handle)(CURLM *multi_handle, + CURL *curl_handle); +CURLMcode (*qcurl_multi_remove_handle)(CURLM *multi_handle, + CURL *curl_handle); +CURLMcode (*qcurl_multi_fdset)(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); +CURLMcode (*qcurl_multi_perform)(CURLM *multi_handle, + int *running_handles); +CURLMcode (*qcurl_multi_cleanup)(CURLM *multi_handle); +CURLMsg *(*qcurl_multi_info_read)(CURLM *multi_handle, + int *msgs_in_queue); +const char *(*qcurl_multi_strerror)(CURLMcode); + +static OBJTYPE cURLLib = NULL; + +/* +================= +GPA +================= +*/ +static void *GPA(char *str) +{ + void *rv; + + rv = SYMLOAD(cURLLib, str); + if(!rv) + { + Com_Printf("Can't load symbol %s\n", str); + clc.cURLEnabled = qfalse; + return NULL; + } + else + { + Com_DPrintf("Loaded symbol %s (0x%08X)\n", str, rv); + return rv; + } +} +#endif /* USE_CURL_DLOPEN */ + +/* +================= +CL_cURL_Init +================= +*/ +qboolean CL_cURL_Init() +{ +#if USE_CURL_DLOPEN + if(cURLLib) + return qtrue; + + + Com_Printf("Loading \"%s\"...", cl_cURLLib->string); + if( (cURLLib = OBJLOAD(cl_cURLLib->string)) == 0 ) + { +#ifdef _WIN32 + return qfalse; +#else + char fn[1024]; + getcwd(fn, sizeof(fn)); + strncat(fn, "/", sizeof(fn)); + strncat(fn, cl_cURLLib->string, sizeof(fn)); + + if( (cURLLib = OBJLOAD(fn)) == 0 ) + { + return qfalse; + } +#endif /* _WIN32 */ + } + + clc.cURLEnabled = qtrue; + + qcurl_version = GPA("curl_version"); + + qcurl_easy_init = GPA("curl_easy_init"); + qcurl_easy_setopt = GPA("curl_easy_setopt"); + qcurl_easy_perform = GPA("curl_easy_perform"); + qcurl_easy_cleanup = GPA("curl_easy_cleanup"); + qcurl_easy_getinfo = GPA("curl_easy_getinfo"); + qcurl_easy_duphandle = GPA("curl_easy_duphandle"); + qcurl_easy_reset = GPA("curl_easy_reset"); + qcurl_easy_strerror = GPA("curl_easy_strerror"); + + qcurl_multi_init = GPA("curl_multi_init"); + qcurl_multi_add_handle = GPA("curl_multi_add_handle"); + qcurl_multi_remove_handle = GPA("curl_multi_remove_handle"); + qcurl_multi_fdset = GPA("curl_multi_fdset"); + qcurl_multi_perform = GPA("curl_multi_perform"); + qcurl_multi_cleanup = GPA("curl_multi_cleanup"); + qcurl_multi_info_read = GPA("curl_multi_info_read"); + qcurl_multi_strerror = GPA("curl_multi_strerror"); + + if(!clc.cURLEnabled) + { + CL_cURL_Shutdown(); + Com_Printf("FAIL One or more symbols not found\n"); + return qfalse; + } + Com_Printf("OK\n"); + + return qtrue; +#else + clc.cURLEnabled = qtrue; + return qtrue; +#endif /* USE_CURL_DLOPEN */ +} + +/* +================= +CL_cURL_Shutdown +================= +*/ +void CL_cURL_Shutdown( void ) +{ + CL_cURL_Cleanup(); +#if USE_CURL_DLOPEN + if(cURLLib) + { + OBJFREE(cURLLib); + cURLLib = NULL; + } + qcurl_easy_init = NULL; + qcurl_easy_setopt = NULL; + qcurl_easy_perform = NULL; + qcurl_easy_cleanup = NULL; + qcurl_easy_getinfo = NULL; + qcurl_easy_duphandle = NULL; + qcurl_easy_reset = NULL; + + qcurl_multi_init = NULL; + qcurl_multi_add_handle = NULL; + qcurl_multi_remove_handle = NULL; + qcurl_multi_fdset = NULL; + qcurl_multi_perform = NULL; + qcurl_multi_cleanup = NULL; + qcurl_multi_info_read = NULL; + qcurl_multi_strerror = NULL; +#endif /* USE_CURL_DLOPEN */ +} + +void CL_cURL_Cleanup(void) +{ + if(clc.downloadCURLM) { + if(clc.downloadCURL) { + qcurl_multi_remove_handle(clc.downloadCURLM, + clc.downloadCURL); + qcurl_easy_cleanup(clc.downloadCURL); + } + qcurl_multi_cleanup(clc.downloadCURLM); + clc.downloadCURLM = NULL; + clc.downloadCURL = NULL; + } + else if(clc.downloadCURL) { + qcurl_easy_cleanup(clc.downloadCURL); + clc.downloadCURL = NULL; + } +} + +static int CL_cURL_CallbackProgress( void *dummy, double dltotal, double dlnow, + double ultotal, double ulnow ) +{ + clc.downloadSize = (int)dltotal; + Cvar_SetValue( "cl_downloadSize", clc.downloadSize ); + clc.downloadCount = (int)dlnow; + Cvar_SetValue( "cl_downloadCount", clc.downloadCount ); + return 0; +} + +static int CL_cURL_CallbackWrite(void *buffer, size_t size, size_t nmemb, + void *stream) +{ + FS_Write( buffer, size*nmemb, ((fileHandle_t*)stream)[0] ); + return size*nmemb; +} + +void CL_cURL_BeginDownload( const char *localName, const char *remoteURL ) +{ + clc.cURLUsed = qtrue; + Com_Printf("URL: %s\n", remoteURL); + Com_DPrintf("***** CL_cURL_BeginDownload *****\n" + "Localname: %s\n" + "RemoteURL: %s\n" + "****************************\n", localName, remoteURL); + CL_cURL_Cleanup(); + Q_strncpyz(clc.downloadURL, remoteURL, sizeof(clc.downloadURL)); + Q_strncpyz(clc.downloadName, localName, sizeof(clc.downloadName)); + Com_sprintf(clc.downloadTempName, sizeof(clc.downloadTempName), + "%s.tmp", localName); + + // Set so UI gets access to it + Cvar_Set("cl_downloadName", localName); + Cvar_Set("cl_downloadSize", "0"); + Cvar_Set("cl_downloadCount", "0"); + Cvar_SetValue("cl_downloadTime", cls.realtime); + + clc.downloadBlock = 0; // Starting new file + clc.downloadCount = 0; + + clc.downloadCURL = qcurl_easy_init(); + if(!clc.downloadCURL) { + Com_Error(ERR_DROP, "CL_cURL_BeginDownload: qcurl_easy_init() " + "failed\n"); + return; + } + clc.download = FS_SV_FOpenFileWrite(clc.downloadTempName); + if(!clc.download) { + Com_Error(ERR_DROP, "CL_cURL_BeginDownload: failed to open " + "%s for writing\n", clc.downloadTempName); + return; + } + qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEDATA, clc.download); + if(com_developer->integer) + qcurl_easy_setopt(clc.downloadCURL, CURLOPT_VERBOSE, 1); + qcurl_easy_setopt(clc.downloadCURL, CURLOPT_URL, clc.downloadURL); + qcurl_easy_setopt(clc.downloadCURL, CURLOPT_TRANSFERTEXT, 0); + qcurl_easy_setopt(clc.downloadCURL, CURLOPT_REFERER, va("ioQ3://%s", + NET_AdrToString(clc.serverAddress))); + qcurl_easy_setopt(clc.downloadCURL, CURLOPT_USERAGENT, va("%s %s", + Q3_VERSION, qcurl_version())); + qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEFUNCTION, + CL_cURL_CallbackWrite); + qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEDATA, &clc.download); + qcurl_easy_setopt(clc.downloadCURL, CURLOPT_NOPROGRESS, 0); + qcurl_easy_setopt(clc.downloadCURL, CURLOPT_PROGRESSFUNCTION, + CL_cURL_CallbackProgress); + qcurl_easy_setopt(clc.downloadCURL, CURLOPT_PROGRESSDATA, NULL); + qcurl_easy_setopt(clc.downloadCURL, CURLOPT_FAILONERROR, 1); + clc.downloadCURLM = qcurl_multi_init(); + if(!clc.downloadCURLM) { + qcurl_easy_cleanup(clc.downloadCURL); + clc.downloadCURL = NULL; + Com_Error(ERR_DROP, "CL_cURL_BeginDownload: qcurl_multi_init() " + "failed\n"); + return; + } + qcurl_multi_add_handle(clc.downloadCURLM, clc.downloadCURL); + + if(!(clc.sv_allowDownload & DLF_NO_DISCONNECT) && + !clc.cURLDisconnected) { + + CL_AddReliableCommand("disconnect"); + CL_WritePacket(); + CL_WritePacket(); + CL_WritePacket(); + clc.cURLDisconnected = qtrue; + } +} + +void CL_cURL_PerformDownload(void) +{ + CURLMcode res; + CURLMsg *msg; + int c; + int i = 0; + + res = qcurl_multi_perform(clc.downloadCURLM, &c); + while(res == CURLM_CALL_MULTI_PERFORM && i < 100) { + res = qcurl_multi_perform(clc.downloadCURLM, &c); + i++; + } + if(res == CURLM_CALL_MULTI_PERFORM) + return; + msg = qcurl_multi_info_read(clc.downloadCURLM, &c); + if(msg == NULL) { + return; + } + FS_FCloseFile(clc.download); + if(msg->msg == CURLMSG_DONE && msg->data.result == CURLE_OK) { + FS_SV_Rename(clc.downloadTempName, clc.downloadName); + clc.downloadRestart = qtrue; + } + else { + long code; + + qcurl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, + &code); + Com_Error(ERR_DROP, "Download Error: %s Code: %d URL: %s", + qcurl_easy_strerror(msg->data.result), + code, clc.downloadURL); + } + *clc.downloadTempName = *clc.downloadName = 0; + Cvar_Set( "cl_downloadName", "" ); + CL_NextDownload(); +} +#endif /* USE_CURL */ diff --git a/code/client/cl_curl.h b/code/client/cl_curl.h new file mode 100644 index 00000000..57ed2161 --- /dev/null +++ b/code/client/cl_curl.h @@ -0,0 +1,101 @@ +/* +=========================================================================== +Copyright (C) 2006 Tony J. White (tjw@tjw.org) + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + + +#ifndef __QCURL_H__ +#define __QCURL_H__ + +extern cvar_t *cl_cURLLib; + +#include "../qcommon/q_shared.h" +#include "../qcommon/qcommon.h" + +#ifdef WIN32 +#define DEFAULT_CURL_LIB "libcurl-3.dll" +#elif defined(MACOS_X) +#define DEFAULT_CURL_LIB "libcurl.dylib" +#else +#define DEFAULT_CURL_LIB "libcurl.so.3" +#endif + +#if USE_LOCAL_HEADERS + #include "../libcurl/curl/curl.h" +#else + #include +#endif + + +#if USE_CURL_DLOPEN +extern char* (*qcurl_version)(void); + +extern CURL* (*qcurl_easy_init)(void); +extern CURLcode (*qcurl_easy_setopt)(CURL *curl, CURLoption option, ...); +extern CURLcode (*qcurl_easy_perform)(CURL *curl); +extern void (*qcurl_easy_cleanup)(CURL *curl); +extern CURLcode (*qcurl_easy_getinfo)(CURL *curl, CURLINFO info, ...); +extern void (*qcurl_easy_reset)(CURL *curl); +extern const char *(*qcurl_easy_strerror)(CURLcode); + +extern CURLM* (*qcurl_multi_init)(void); +extern CURLMcode (*qcurl_multi_add_handle)(CURLM *multi_handle, + CURL *curl_handle); +extern CURLMcode (*qcurl_multi_remove_handle)(CURLM *multi_handle, + CURL *curl_handle); +extern CURLMcode (*qcurl_multi_fdset)(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); +extern CURLMcode (*qcurl_multi_perform)(CURLM *multi_handle, + int *running_handles); +extern CURLMcode (*qcurl_multi_cleanup)(CURLM *multi_handle); +extern CURLMsg *(*qcurl_multi_info_read)(CURLM *multi_handle, + int *msgs_in_queue); +extern const char *(*qcurl_multi_strerror)(CURLMcode); +#else +#define qcurl_version curl_version + +#define qcurl_easy_init curl_easy_init +#define qcurl_easy_setopt curl_easy_setopt +#define qcurl_easy_perform curl_easy_perform +#define qcurl_easy_cleanup curl_easy_cleanup +#define qcurl_easy_getinfo curl_easy_getinfo +#define qcurl_easy_duphandle curl_easy_duphandle +#define qcurl_easy_reset curl_easy_reset +#define qcurl_easy_strerror curl_easy_strerror + +#define qcurl_multi_init curl_multi_init +#define qcurl_multi_add_handle curl_multi_add_handle +#define qcurl_multi_remove_handle curl_multi_remove_handle +#define qcurl_multi_fdset curl_multi_fdset +#define qcurl_multi_perform curl_multi_perform +#define qcurl_multi_cleanup curl_multi_cleanup +#define qcurl_multi_info_read curl_multi_info_read +#define qcurl_multi_strerror curl_multi_strerror +#endif + +qboolean CL_cURL_Init( void ); +void CL_cURL_Shutdown( void ); +void CL_cURL_BeginDownload( const char *localName, const char *remoteURL ); +void CL_cURL_PerformDownload( void ); +void CL_cURL_Cleanup( void ); +#endif // __QCURL_H__ diff --git a/code/client/cl_main.c b/code/client/cl_main.c index e05a640d..4c5b4038 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -608,6 +608,9 @@ CL_ShutdownAll */ void CL_ShutdownAll(void) { +#if USE_CURL + CL_cURL_Shutdown(); +#endif // clear sounds S_DisableSounds(); // shutdown CGame @@ -1331,6 +1334,23 @@ Called when all downloading has been completed */ void CL_DownloadsComplete( void ) { +#if USE_CURL + // if we downloaded with cURL + if(clc.cURLUsed) { + clc.cURLUsed = qfalse; + CL_cURL_Shutdown(); + if( clc.cURLDisconnected ) { + if(clc.downloadRestart) { + FS_Restart(clc.checksumFeed); + clc.downloadRestart = qfalse; + } + clc.cURLDisconnected = qfalse; + CL_Reconnect_f(); + return; + } + } +#endif + // if we downloaded files we need to restart the file system if (clc.downloadRestart) { clc.downloadRestart = qfalse; @@ -1418,6 +1438,7 @@ A download completed or failed void CL_NextDownload(void) { char *s; char *remoteName, *localName; + qboolean useCURL = qfalse; // We are looking to start a download here if (*clc.downloadList) { @@ -1441,9 +1462,48 @@ void CL_NextDownload(void) { *s++ = 0; else s = localName + strlen(localName); // point at the nul byte - - CL_BeginDownload( localName, remoteName ); - +#if USE_CURL + if(!(cl_allowDownload->integer & DLF_NO_REDIRECT)) { + if(clc.sv_allowDownload & DLF_NO_REDIRECT) { + Com_Printf("WARNING: server does not " + "allow download redirection " + "(sv_allowDownload is %d)\n", + clc.sv_allowDownload); + } + else if(!*clc.sv_dlURL) { + Com_Printf("WARNING: server allows " + "download redirection, but does not " + "have sv_dlURL set\n"); + } + else if(!CL_cURL_Init()) { + Com_Printf("WARNING: could not load " + "cURL library\n"); + } + else { + CL_cURL_BeginDownload(localName, va("%s/%s", + clc.sv_dlURL, remoteName)); + useCURL = qtrue; + } + } + else if(!(clc.sv_allowDownload & DLF_NO_REDIRECT)) { + Com_Printf("WARNING: server allows download " + "redirection, but it disabled by client " + "configuration (cl_allowDownload is %d)\n", + cl_allowDownload->integer); + } +#endif /* USE_CURL */ + if(!useCURL) { + if((cl_allowDownload->integer & DLF_NO_UDP)) { + Com_Error(ERR_DROP, "UDP Downloads are " + "disabled on your client. " + "(cl_allowDownload is %d)", + cl_allowDownload->integer); + return; + } + else { + CL_BeginDownload( localName, remoteName ); + } + } clc.downloadRestart = qtrue; // move over the rest @@ -1466,7 +1526,7 @@ and determine if we need to download them void CL_InitDownloads(void) { char missingfiles[1024]; - if ( !cl_allowDownload->integer ) + if ( !(cl_allowDownload->integer & DLF_ENABLE) ) { // autodownload is disabled on the client // but it's possible that some referenced files on the server are missing @@ -2028,6 +2088,25 @@ void CL_Frame ( int msec ) { return; } +#if USE_CURL + if(clc.downloadCURLM) { + CL_cURL_PerformDownload(); + // we can't process frames normally when in disconnected + // download mode since the ui vm expects cls.state to be + // CA_CONNECTED + if(clc.cURLDisconnected) { + cls.realFrametime = msec; + cls.frametime = msec; + cls.realtime += cls.frametime; + SCR_UpdateScreen(); + S_Update(); + Con_RunConsole(); + cls.framecount++; + return; + } + } +#endif + if ( cls.cddialog ) { // bring up the cd error dialog if needed cls.cddialog = qfalse; @@ -2478,6 +2557,9 @@ void CL_Init( void ) { cl_showMouseRate = Cvar_Get ("cl_showmouserate", "0", 0); cl_allowDownload = Cvar_Get ("cl_allowDownload", "0", CVAR_ARCHIVE); +#if USE_CURL + cl_cURLLib = Cvar_Get("cl_cURLLib", DEFAULT_CURL_LIB, CVAR_ARCHIVE); +#endif cl_conXOffset = Cvar_Get ("cl_conXOffset", "0", 0); #ifdef MACOS_X diff --git a/code/client/cl_parse.c b/code/client/cl_parse.c index d8ad6d73..3039849d 100644 --- a/code/client/cl_parse.c +++ b/code/client/cl_parse.c @@ -412,6 +412,25 @@ void CL_SystemInfoChanged( void ) { cl_connectedToPureServer = Cvar_VariableValue( "sv_pure" ); } +/* +================== +CL_ParseServerInfo +================== +*/ +static void CL_ParseServerInfo(void) +{ + const char *serverInfo; + + serverInfo = cl.gameState.stringData + + cl.gameState.stringOffsets[ CS_SERVERINFO ]; + + clc.sv_allowDownload = atoi(Info_ValueForKey(serverInfo, + "sv_allowDownload")); + Q_strncpyz(clc.sv_dlURL, + Info_ValueForKey(serverInfo, "sv_dlURL"), + sizeof(clc.sv_dlURL)); +} + /* ================== CL_ParseGamestate @@ -479,6 +498,9 @@ void CL_ParseGamestate( msg_t *msg ) { // read the checksum feed clc.checksumFeed = MSG_ReadLong( msg ); + // parse useful values out of CS_SERVERINFO + CL_ParseServerInfo(); + // parse serverId and other cvars CL_SystemInfoChanged(); diff --git a/code/client/client.h b/code/client/client.h index 9db786a8..89cb4776 100644 --- a/code/client/client.h +++ b/code/client/client.h @@ -30,6 +30,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "../cgame/cg_public.h" #include "../game/bg_public.h" +#if USE_CURL +#include "cl_curl.h" +#endif /* USE_CURL */ + // tjw: file full of random crap that gets used to create cl_guid #define QKEY_FILE "qkey" @@ -185,6 +189,16 @@ typedef struct { fileHandle_t download; char downloadTempName[MAX_OSPATH]; char downloadName[MAX_OSPATH]; +#ifdef USE_CURL + qboolean cURLEnabled; + qboolean cURLUsed; + qboolean cURLDisconnected; + char downloadURL[MAX_OSPATH]; + CURL *downloadCURL; + CURLM *downloadCURLM; +#endif /* USE_CURL */ + int sv_allowDownload; + char sv_dlURL[MAX_CVAR_VALUE_STRING]; int downloadNumber; int downloadBlock; // block we are waiting for int downloadCount; // how many bytes we got @@ -351,6 +365,7 @@ extern cvar_t *cl_aviMotionJpeg; extern cvar_t *cl_activeAction; extern cvar_t *cl_allowDownload; +extern cvar_t *cl_downloadMethod; extern cvar_t *cl_conXOffset; extern cvar_t *cl_inGameVideo; diff --git a/code/libcurl/curl/curl.h b/code/libcurl/curl/curl.h new file mode 100644 index 00000000..a0a04148 --- /dev/null +++ b/code/libcurl/curl/curl.h @@ -0,0 +1,1563 @@ +#ifndef __CURL_CURL_H +#define __CURL_CURL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2006, Daniel Stenberg, , 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. + * + * $Id: curl.h,v 1.304 2006-08-04 16:08:41 giva Exp $ + ***************************************************************************/ + +/* If you have problems, all libcurl docs and details are found here: + http://curl.haxx.se/libcurl/ +*/ + +#include "curlver.h" /* the libcurl version defines */ + +#include +#include + +/* The include stuff here below is mainly for time_t! */ +#ifdef vms +# include +# include +#else +# include +# include +#endif /* defined (vms) */ + +typedef void CURL; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Decorate exportable functions for Win32 DLL linking. + * This avoids using a .def file for building libcurl.dll. + */ +#if (defined(WIN32) || defined(_WIN32)) && !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 visibile 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 + +/* + * We want the typedef curl_off_t setup for large file support on all + * platforms. We also provide a CURL_FORMAT_OFF_T define to use in *printf + * format strings when outputting a variable of type curl_off_t. + * + * Note: "pocc -Ze" is MSVC compatibily mode and this sets _MSC_VER! + */ + +#if (defined(_MSC_VER) && !defined(__POCC__)) || (defined(__LCC__) && defined(WIN32)) +/* MSVC */ +#ifdef _WIN32_WCE + typedef long curl_off_t; +#define CURL_FORMAT_OFF_T "%ld" +#else + typedef signed __int64 curl_off_t; +#define CURL_FORMAT_OFF_T "%I64d" +#endif +#else /* (_MSC_VER && !__POCC__) || (__LCC__ && WIN32) */ +#if (defined(__GNUC__) && defined(WIN32)) || defined(__WATCOMC__) +/* gcc on windows or Watcom */ + typedef long long curl_off_t; +#define CURL_FORMAT_OFF_T "%I64d" +#else /* GCC or Watcom on Windows */ + +/* "normal" POSIX approach, do note that this does not necessarily mean that + the type is >32 bits, see the SIZEOF_CURL_OFF_T define for that! */ + typedef off_t curl_off_t; + +/* Check a range of defines to detect large file support. On Linux it seems + none of these are set by default, so if you don't explicitly switches on + large file support, this define will be made for "small file" support. */ +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 0 /* to prevent warnings in the check below */ +#define UNDEF_FILE_OFFSET_BITS +#endif +#ifndef FILESIZEBITS +#define FILESIZEBITS 0 /* to prevent warnings in the check below */ +#define UNDEF_FILESIZEBITS +#endif + +#if defined(_LARGE_FILES) || (_FILE_OFFSET_BITS > 32) || (FILESIZEBITS > 32) \ + || defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) + /* For now, we assume at least one of these to be set for large files to + work! */ +#define CURL_FORMAT_OFF_T "%lld" +#else /* LARGE_FILE support */ +#define CURL_FORMAT_OFF_T "%ld" +#endif +#endif /* GCC or Watcom on Windows */ +#endif /* (_MSC_VER && !__POCC__) || (__LCC__ && WIN32) */ + +#ifdef UNDEF_FILE_OFFSET_BITS +/* this was defined above for our checks, undefine it again */ +#undef _FILE_OFFSET_BITS +#endif + +#ifdef UNDEF_FILESIZEBITS +/* this was defined above for our checks, undefine it again */ +#undef FILESIZEBITS +#endif + +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 */ + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ +}; + +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + + /* 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. */ +#define CURL_MAX_WRITE_SIZE 16384 + +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + +/* 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 +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + + +#ifndef CURL_NO_OLDIES + /* not used since 7.10.8, will be removed in a future release */ +typedef int (*curl_passwd_callback)(void *clientp, + const char *prompt, + char *buffer, + int buflen); +#endif + +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_URL_MALFORMAT_USER, /* 4 - NOT USED */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_FTP_ACCESS_DENIED, /* 9 a service was denied by the FTP server + due to lack of access - when login fails + this is not returned. */ + CURLE_FTP_USER_PASSWORD_INCORRECT, /* 10 - NOT USED */ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_FTP_WEIRD_USER_REPLY, /* 12 */ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_FTP_CANT_RECONNECT, /* 16 */ + CURLE_FTP_COULDNT_SET_BINARY, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_FTP_WRITE_ERROR, /* 20 */ + CURLE_FTP_QUOTE_ERROR, /* 21 */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_MALFORMAT_USER, /* 24 - NOT USED */ + CURLE_FTP_COULDNT_STOR_FILE, /* 25 - failed FTP upload */ + CURLE_READ_ERROR, /* 26 - could 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_TIMEOUTED, /* 28 - the timeout time was reached */ + CURLE_FTP_COULDNT_SET_ASCII, /* 29 - TYPE A failed */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_FTP_COULDNT_GET_SIZE, /* 32 - the SIZE command failed */ + CURLE_HTTP_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_LIBRARY_NOT_FOUND, /* 40 */ + CURLE_FUNCTION_NOT_FOUND, /* 41 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_BAD_CALLING_ORDER, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_BAD_PASSWORD_ENTERED, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ + CURLE_OBSOLETE, /* 50 - NOT USED */ + CURLE_SSL_PEER_CERTIFICATE, /* 51 - peer's certificate wasn't ok */ + 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_SHARE_IN_USE, /* 57 - share is 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 transfer encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_FTP_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_TFTP_DISKFULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_TFTP_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 */ + CURL_LAST /* never use! */ +} CURLcode; + +/* 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); + +/* Make a spelling correction for the operation timed-out define */ +#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ +/* backwards compatibility with older names */ +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#endif + +typedef enum { + CURLPROXY_HTTP = 0, + CURLPROXY_SOCKS4 = 4, + CURLPROXY_SOCKS5 = 5 +} curl_proxytype; + +#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_ANY ~0 /* all types set */ +#define CURLAUTH_ANYSAFE (~CURLAUTH_BASIC) + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ +/* 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 + +/* These are just to make older programs not break: */ +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME +#endif + +#define CURL_ERROR_SIZE 256 + +/* parameter for the CURLOPT_FTP_SSL option */ +typedef enum { + CURLFTPSSL_NONE, /* do not attempt to use SSL */ + 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 */ + CURLFTPSSL_LAST /* not an option, never use */ +} curl_ftpssl; + +/* 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_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; + +/* 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_, + type is one of the defined CURLOPTTYPE_ + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif +/* + * Figure out if we can use the ## 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. We don't use configure-checks + * for these since we want these headers to remain generic and working for all + * platforms. + */ +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) + /* 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 + +#ifdef CURL_ISOCPP +#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number +#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 succcessful. -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 input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referer 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 HttpPost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, OBJECTPOINT, 25), + + /* password for the SSL-private key, keep this for compatibility */ + CINIT(SSLCERTPASSWD, OBJECTPOINT, 26), + /* password for the SSL private key */ + CINIT(SSLKEYPASSWD, 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 specifly 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), + + /* Pass a pointer to string of the output using full variable-replacement + as described elsewhere. */ + CINIT(WRITEINFO, OBJECTPOINT, 40), + + 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(FTPLISTONLY, LONG, 48), /* Use NLST when listing ftp dir */ + + CINIT(FTPAPPEND, 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 referer 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 security level, this also enables krb4 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(KRB4LEVEL, 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), + + /* What policy to use when closing connections when the cache is filled + up */ + CINIT(CLOSEPOLICY, LONG, 72), + + /* 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), + + /* Specificly 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), /* To becomeO BSOLETE soon */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands (Wesley Laxton)*/ + 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 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. */ + CINIT(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 potentionally send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specificly 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 */ + 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), + + /* 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(FTP_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 */ + + /* When doing 3rd party transfer, set the source user and password with + this */ + CINIT(SOURCE_USERPWD, OBJECTPOINT, 123), + + /* 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 */ + + /* When doing 3rd party transfer, set the source pre-quote linked list + of commands with this */ + CINIT(SOURCE_PREQUOTE, OBJECTPOINT, 127), + + /* When doing 3rd party transfer, set the source post-quote linked list + of commands with this */ + CINIT(SOURCE_POSTQUOTE, OBJECTPOINT, 128), + + /* When FTP over SSL/TLS is selected (with CURLOPT_FTP_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), + + /* To make a 3rd party transfer, set the source URL with this */ + CINIT(SOURCE_URL, OBJECTPOINT, 132), + + /* When doing 3rd party transfer, set the source quote linked list of + commands with this */ + CINIT(SOURCE_QUOTE, OBJECTPOINT, 133), + + /* 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), + + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + + /* 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 + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ +#define CURLOPT_HTTPREQUEST -1 +#define CURLOPT_FTPASCII CURLOPT_TRANSFERTEXT +#define CURLOPT_MUTE -2 +#define CURLOPT_PASSWDFUNCTION -3 +#define CURLOPT_PASSWDDATA -4 +#define CURLOPT_CLOSEFUNCTION -5 + +#define CURLOPT_SOURCE_HOST -6 +#define CURLOPT_SOURCE_PATH -7 +#define CURLOPT_SOURCE_PORT -8 +#define CURLOPT_PASV_HOST -9 + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* 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 */ +}; + + /* 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 */ +}; + + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + +#ifdef __BEOS__ +#include +#endif + + +/* 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_ */ +#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), + + CURLFORM_LASTENTRY /* the last unusued */ +} 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 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 advanved 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 + */ +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); + +#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, + /* Fill in new entries below here! */ + + CURLINFO_LASTONE = 30 +} 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 internaly 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, /* out of memory */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify shich 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_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basicly 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_THIRD + +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; + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; +} 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 are + supported */ + +/* + * 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); + +#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" + +#endif /* __CURL_CURL_H */ diff --git a/code/libcurl/curl/curlver.h b/code/libcurl/curl/curlver.h new file mode 100644 index 00000000..1634b172 --- /dev/null +++ b/code/libcurl/curl/curlver.h @@ -0,0 +1,56 @@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2006, Daniel Stenberg, , 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. + * + * $Id: curlver.h,v 1.21 2006-06-12 07:24:14 bagder Exp $ + ***************************************************************************/ + +/* 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 version number of the libcurl package from which this header + file origins: */ +#define LIBCURL_VERSION "7.15.5" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 +#define LIBCURL_VERSION_MINOR 15 +#define LIBCURL_VERSION_PATCH 5 + +/* 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 0x070f05 + +#endif /* __CURL_CURLVER_H */ diff --git a/code/libcurl/curl/easy.h b/code/libcurl/curl/easy.h new file mode 100644 index 00000000..b5867200 --- /dev/null +++ b/code/libcurl/curl/easy.h @@ -0,0 +1,81 @@ +#ifndef __CURL_EASY_H +#define __CURL_EASY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2004, Daniel Stenberg, , 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. + * + * $Id: easy.h,v 1.13 2004/11/09 14:02:58 giva Exp $ + ***************************************************************************/ +#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 persistant connections cannot + * be transfered. 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); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/code/libcurl/curl/mprintf.h b/code/libcurl/curl/mprintf.h new file mode 100644 index 00000000..8d835f13 --- /dev/null +++ b/code/libcurl/curl/mprintf.h @@ -0,0 +1,62 @@ +#ifndef __CURL_MPRINTF_H +#define __CURL_MPRINTF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2006, Daniel Stenberg, , 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. + * + * $Id: mprintf.h,v 1.13 2006-03-28 10:08:54 bagder Exp $ + ***************************************************************************/ + +#include +#include /* needed for FILE */ + +#include "curl.h" + +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 +# 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 + +#endif /* __CURL_MPRINTF_H */ diff --git a/code/libcurl/curl/multi.h b/code/libcurl/curl/multi.h new file mode 100644 index 00000000..05aeafc7 --- /dev/null +++ b/code/libcurl/curl/multi.h @@ -0,0 +1,344 @@ +#ifndef __CURL_MULTI_H +#define __CURL_MULTI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2006, Daniel Stenberg, , 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. + * + * $Id: multi.h,v 1.38 2006-08-04 18:53:48 danf Exp $ + ***************************************************************************/ +/* + 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. + +*/ +#if defined(_WIN32) && !defined(WIN32) +/* Chris Lewis mentioned that he doesn't get WIN32 defined, only _WIN32 so we + make this adjustment to catch this. */ +#define WIN32 1 +#endif + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \ + !defined(__CYGWIN__) || defined(__MINGW32__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +#include +#endif +#else + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on system that are known to + require it! */ +#if defined(_AIX) || defined(NETWARE) || defined(__NetBSD__) || defined(_MINIX) +#include +#endif + +#ifndef _WIN32_WCE +#include +#endif +#include +#include +#endif + +/* + * 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 + * 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; + +#ifndef curl_socket_typedef +/* Public socket typedef */ +#ifdef WIN32 +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 */ + +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 + +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 */ + +CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); + +/* + * 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,number) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + number +#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), + + 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/code/libcurl/curl/stdcheaders.h b/code/libcurl/curl/stdcheaders.h new file mode 100644 index 00000000..024413ac --- /dev/null +++ b/code/libcurl/curl/stdcheaders.h @@ -0,0 +1,34 @@ +#ifndef __STDC_HEADERS_H +#define __STDC_HEADERS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2004, Daniel Stenberg, , 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. + * + * $Id: stdcheaders.h,v 1.8 2004/01/07 09:19:34 bagder Exp $ + ***************************************************************************/ + +#include + +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 diff --git a/code/libcurl/curl/types.h b/code/libcurl/curl/types.h new file mode 100644 index 00000000..d37d6ae9 --- /dev/null +++ b/code/libcurl/curl/types.h @@ -0,0 +1 @@ +/* not used */ diff --git a/code/libs/win32/libcurl.a b/code/libs/win32/libcurl.a new file mode 100644 index 0000000000000000000000000000000000000000..7f6ed2d7a58c61789c291f03a208b423dc296a6f GIT binary patch literal 253484 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
mV$xW#oGe!D=@OCKD~{) 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 || idPack || unreferenced || + if ( !(sv_allowDownload->integer & DLF_ENABLE) || + (sv_allowDownload->integer & DLF_NO_UDP) || + idPack || unreferenced || ( cl->downloadSize = FS_SV_FOpenFileRead( cl->downloadName, &cl->download ) ) <= 0 ) { // cannot auto-download file if(unreferenced) @@ -818,7 +820,10 @@ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg ) else { Com_sprintf(errorMessage, sizeof(errorMessage), "Cannot autodownload id pk3 file \"%s\"", cl->downloadName); } - } else if ( !sv_allowDownload->integer ) { + } + else if ( !(sv_allowDownload->integer & DLF_ENABLE) || + (sv_allowDownload->integer & DLF_NO_UDP) ) { + Com_Printf("clientDownload: %d : \"%s\" download disabled", cl - svs.clients, cl->downloadName); if (sv_pure->integer) { Com_sprintf(errorMessage, sizeof(errorMessage), "Could not download \"%s\" because autodownloading is disabled on the server.\n\n" diff --git a/code/server/sv_init.c b/code/server/sv_init.c index e9f257be..986575ba 100644 --- a/code/server/sv_init.c +++ b/code/server/sv_init.c @@ -606,6 +606,7 @@ void SV_Init (void) { Cvar_Get ("nextmap", "", CVAR_TEMP ); sv_allowDownload = Cvar_Get ("sv_allowDownload", "0", CVAR_SERVERINFO); + Cvar_Get ("sv_dlURL", "", CVAR_SERVERINFO | CVAR_ARCHIVE); sv_master[0] = Cvar_Get ("sv_master1", MASTER_SERVER_NAME, 0 ); sv_master[1] = Cvar_Get ("sv_master2", "", CVAR_ARCHIVE ); sv_master[2] = Cvar_Get ("sv_master3", "", CVAR_ARCHIVE );