mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-26 06:20:48 +00:00
Load libcurl.so at runtime.
Loading libcurl at runtime instead of linking it at compile time makes things a lot easier and more reliable on Windows. On other platform libcurl can be installed as optional dependency instead as an hard one.
This commit is contained in:
parent
cd1b67e489
commit
c0a6e4270f
4 changed files with 349 additions and 33 deletions
6
Makefile
6
Makefile
|
@ -352,6 +352,10 @@ build/client/%.o: %.c
|
|||
|
||||
release/yquake2.exe : LDFLAGS += -mwindows
|
||||
|
||||
ifeq ($(WITH_CURL),yes)
|
||||
release/quake2 : CFLAGS += -DUSE_CURL
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_OPENAL),yes)
|
||||
release/yquake2.exe : CFLAGS += -DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER='"openal32.dll"'
|
||||
endif
|
||||
|
@ -379,7 +383,6 @@ release/quake2 : CFLAGS += -Wno-unused-result
|
|||
|
||||
ifeq ($(WITH_CURL),yes)
|
||||
release/quake2 : CFLAGS += -DUSE_CURL
|
||||
release/quake2 : LDFLAGS += -lcurl
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_OPENAL),yes)
|
||||
|
@ -690,6 +693,7 @@ CLIENT_OBJS_ := \
|
|||
src/client/cl_screen.o \
|
||||
src/client/cl_tempentities.o \
|
||||
src/client/cl_view.o \
|
||||
src/client/curl/qcurl.o \
|
||||
src/client/input/sdl.o \
|
||||
src/client/menu/menu.o \
|
||||
src/client/menu/qmenu.o \
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <ctype.h>
|
||||
#include "header/client.h"
|
||||
#include "curl/header/qcurl.h"
|
||||
|
||||
#ifdef USE_CURL
|
||||
|
||||
|
@ -66,7 +67,7 @@ static size_t CL_HTTP_Recv(void *ptr, size_t size, size_t nmemb, void *stream)
|
|||
{
|
||||
double length = 0;
|
||||
|
||||
curl_easy_getinfo(dl->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &length);
|
||||
qcurl_easy_getinfo(dl->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &length);
|
||||
|
||||
// Mkay, the remote file should be at least one byte long.
|
||||
// Since this is used for paclists only we assume that the
|
||||
|
@ -198,33 +199,33 @@ static void CL_StartHTTPDownload (dlqueue_t *entry, dlhandle_t *dl)
|
|||
// Setup and configure the CURL part of our download handle.
|
||||
if (!dl->curl)
|
||||
{
|
||||
dl->curl = curl_easy_init();
|
||||
dl->curl = qcurl_easy_init();
|
||||
}
|
||||
|
||||
Com_sprintf(dl->URL, sizeof(dl->URL), "%s%s", cls.downloadServer, escapedFilePath);
|
||||
|
||||
curl_easy_setopt(dl->curl, CURLOPT_ENCODING, "");
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_ENCODING, "");
|
||||
|
||||
if (dl->file)
|
||||
{
|
||||
curl_easy_setopt(dl->curl, CURLOPT_WRITEDATA, dl->file);
|
||||
curl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, NULL);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_WRITEDATA, dl->file);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
curl_easy_setopt(dl->curl, CURLOPT_WRITEDATA, dl);
|
||||
curl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, CL_HTTP_Recv);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_WRITEDATA, dl);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, CL_HTTP_Recv);
|
||||
}
|
||||
|
||||
curl_easy_setopt(dl->curl, CURLOPT_PROXY, cl_http_proxy->string);
|
||||
curl_easy_setopt(dl->curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(dl->curl, CURLOPT_MAXREDIRS, 5);
|
||||
curl_easy_setopt(dl->curl, CURLOPT_PROGRESSDATA, dl);
|
||||
curl_easy_setopt(dl->curl, CURLOPT_USERAGENT, Cvar_VariableString ("version"));
|
||||
curl_easy_setopt(dl->curl, CURLOPT_REFERER, cls.downloadReferer);
|
||||
curl_easy_setopt(dl->curl, CURLOPT_URL, dl->URL);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_PROXY, cl_http_proxy->string);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_MAXREDIRS, 5);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_PROGRESSDATA, dl);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_USERAGENT, Cvar_VariableString ("version"));
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_REFERER, cls.downloadReferer);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_URL, dl->URL);
|
||||
|
||||
if (curl_multi_add_handle (multi, dl->curl) != CURLM_OK)
|
||||
if (qcurl_multi_add_handle(multi, dl->curl) != CURLM_OK)
|
||||
{
|
||||
Com_Printf("HTTP download: cURL error\n");
|
||||
dl->queueEntry->state = DLQ_STATE_DONE;
|
||||
|
@ -473,7 +474,7 @@ static void CL_FinishHTTPDownload(void)
|
|||
do
|
||||
{
|
||||
// Get a message from CURL.
|
||||
CURLMsg *msg = curl_multi_info_read(multi, &msgs_in_queue);
|
||||
CURLMsg *msg = qcurl_multi_info_read(multi, &msgs_in_queue);
|
||||
|
||||
if (!msg)
|
||||
{
|
||||
|
@ -551,7 +552,7 @@ static void CL_FinishHTTPDownload(void)
|
|||
{
|
||||
case CURLE_HTTP_RETURNED_ERROR:
|
||||
case CURLE_OK:
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||
qcurl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||
|
||||
if (responseCode == 404)
|
||||
{
|
||||
|
@ -564,7 +565,7 @@ static void CL_FinishHTTPDownload(void)
|
|||
}
|
||||
|
||||
// ...and remove it from the CURL multihandle.
|
||||
curl_multi_remove_handle(multi, dl->curl);
|
||||
qcurl_multi_remove_handle(multi, dl->curl);
|
||||
|
||||
Com_Printf("HTTP download: %s - File Not Found\n", dl->queueEntry->quakePath);
|
||||
|
||||
|
@ -597,7 +598,7 @@ static void CL_FinishHTTPDownload(void)
|
|||
}
|
||||
|
||||
// ...and the handle from CURLs mutihandle.
|
||||
curl_multi_remove_handle (multi, dl->curl);
|
||||
qcurl_multi_remove_handle(multi, dl->curl);
|
||||
|
||||
// Special case: We're already aborting HTTP downloading,
|
||||
// so we can't just kill everything. Otherwise we'll get
|
||||
|
@ -614,7 +615,7 @@ static void CL_FinishHTTPDownload(void)
|
|||
break;
|
||||
|
||||
default:
|
||||
Com_Printf ("HTTP download: cURL error - %s\n", curl_easy_strerror(result));
|
||||
Com_Printf ("HTTP download: cURL error - %s\n", qcurl_easy_strerror(result));
|
||||
|
||||
i = strlen(dl->queueEntry->quakePath);
|
||||
|
||||
|
@ -625,7 +626,7 @@ static void CL_FinishHTTPDownload(void)
|
|||
}
|
||||
|
||||
// ...and the handle from CURLs mutihandle.
|
||||
curl_multi_remove_handle (multi, dl->curl);
|
||||
qcurl_multi_remove_handle (multi, dl->curl);
|
||||
|
||||
continue;
|
||||
break;
|
||||
|
@ -651,7 +652,7 @@ static void CL_FinishHTTPDownload(void)
|
|||
}
|
||||
|
||||
// Remove the file fo CURLs multihandle.
|
||||
curl_multi_remove_handle (multi, dl->curl);
|
||||
qcurl_multi_remove_handle (multi, dl->curl);
|
||||
|
||||
} while (msgs_in_queue > 0);
|
||||
|
||||
|
@ -736,7 +737,11 @@ static void CL_StartNextHTTPDownload(void)
|
|||
*/
|
||||
void CL_InitHTTPDownloads (void)
|
||||
{
|
||||
curl_global_init (CURL_GLOBAL_NOTHING);
|
||||
// We're initializing the cURL backend here because
|
||||
// currently we're the only user. As soon as there
|
||||
// are other users this must be moved up into the
|
||||
// global client intialization.
|
||||
qcurlInit();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -771,8 +776,11 @@ void CL_HTTP_Cleanup(qboolean fullShutdown)
|
|||
if (dl->curl)
|
||||
{
|
||||
if (multi)
|
||||
curl_multi_remove_handle (multi, dl->curl);
|
||||
curl_easy_cleanup (dl->curl);
|
||||
{
|
||||
qcurl_multi_remove_handle(multi, dl->curl);
|
||||
}
|
||||
|
||||
qcurl_easy_cleanup(dl->curl);
|
||||
dl->curl = NULL;
|
||||
}
|
||||
|
||||
|
@ -782,14 +790,17 @@ void CL_HTTP_Cleanup(qboolean fullShutdown)
|
|||
// Cleanup CURL multihandle.
|
||||
if (multi)
|
||||
{
|
||||
curl_multi_cleanup(multi);
|
||||
qcurl_multi_cleanup(multi);
|
||||
multi = NULL;
|
||||
}
|
||||
|
||||
// Shutdown CURL.
|
||||
if (fullShutdown)
|
||||
{
|
||||
curl_global_cleanup ();
|
||||
// This must be moved up into the generic
|
||||
// client shutdown as soon as there're
|
||||
// other users of the cURL backend.
|
||||
qcurlShutdown();
|
||||
httpDown = true;
|
||||
}
|
||||
}
|
||||
|
@ -807,6 +818,16 @@ void CL_SetHTTPServer (const char *URL)
|
|||
dlqueue_t *last = NULL;
|
||||
dlqueue_t *q = &cls.downloadQueue;
|
||||
|
||||
// This code abuses the download server setting to
|
||||
// determine if HTTP downloads are possible. So if
|
||||
// we don't set a download server, no downloads are
|
||||
// queued and run. :)
|
||||
if (!qcurlInitialized)
|
||||
{
|
||||
cls.downloadServer[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
CL_HTTP_Cleanup(false);
|
||||
|
||||
// Cleanup download queues.
|
||||
|
@ -841,7 +862,7 @@ void CL_SetHTTPServer (const char *URL)
|
|||
Com_Error(ERR_DROP, "HTTP download: Still have old handle?!");
|
||||
}
|
||||
|
||||
multi = curl_multi_init();
|
||||
multi = qcurl_multi_init();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -981,10 +1002,10 @@ qboolean CL_PendingHTTPDownloads(void)
|
|||
*/
|
||||
void CL_RunHTTPDownloads(void)
|
||||
{
|
||||
int newHandleCount;
|
||||
CURLMcode ret;
|
||||
int newHandleCount;
|
||||
CURLMcode ret;
|
||||
|
||||
// No HTTP server given.
|
||||
// No HTTP server given or not initialized.
|
||||
if (!cls.downloadServer[0])
|
||||
{
|
||||
return;
|
||||
|
@ -993,7 +1014,7 @@ void CL_RunHTTPDownloads(void)
|
|||
// Kick CURL into action.
|
||||
do
|
||||
{
|
||||
ret = curl_multi_perform(multi, &newHandleCount);
|
||||
ret = qcurl_multi_perform(multi, &newHandleCount);
|
||||
|
||||
if (newHandleCount < handleCount)
|
||||
{
|
||||
|
|
70
src/client/curl/header/qcurl.h
Normal file
70
src/client/curl/header/qcurl.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (C) 2018 Yamagi
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* CURL backend for Quake II.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#ifdef USE_CURL
|
||||
|
||||
#ifndef QCURL_H
|
||||
#define QCURL_H
|
||||
|
||||
// --------
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "../../../common/header/common.h"
|
||||
|
||||
// --------
|
||||
|
||||
// True if cURL is initialized.
|
||||
extern qboolean qcurlInitialized;
|
||||
|
||||
// Function pointers to cURL.
|
||||
extern void (*qcurl_easy_cleanup)(CURL *curl);
|
||||
extern CURL *(*qcurl_easy_init)(void);
|
||||
extern CURLcode (*qcurl_easy_getinfo)(CURL *curl, CURLINFO info, ...);
|
||||
extern CURLcode (*qcurl_easy_setopt)(CURL *curl, CURLoption option, ...);
|
||||
extern const char *(*qcurl_easy_strerror)(CURLcode);
|
||||
|
||||
extern void (*qcurl_global_cleanup)(void);
|
||||
extern CURLcode (*qcurl_global_init)(long flags);
|
||||
|
||||
extern CURLMcode (*qcurl_multi_add_handle)(CURLM *multi_handle, CURL *curl_handle);
|
||||
extern CURLMcode (*qcurl_multi_cleanup)(CURLM *multi_handle);
|
||||
extern CURLMsg *(*qcurl_multi_info_read)(CURLM *multi_handle, int *msgs_in_queue);
|
||||
extern CURLM *(*qcurl_multi_init)(void);
|
||||
extern CURLMcode (*qcurl_multi_perform)(CURLM *multi_handle, int *running_handles);
|
||||
extern CURLMcode (*qcurl_multi_remove_handle)(CURLM *multi_handle, CURL *curl_handle);
|
||||
|
||||
// --------
|
||||
|
||||
// Loads and initialized cURL.
|
||||
qboolean qcurlInit(void);
|
||||
|
||||
// Shuts cURL down and unloads it.
|
||||
void qcurlShutdown(void);
|
||||
|
||||
// --------
|
||||
|
||||
#endif // QCURL_H
|
||||
#endif // USE_CURL
|
221
src/client/curl/qcurl.c
Normal file
221
src/client/curl/qcurl.c
Normal file
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (C) 2018 Yamagi
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* CURL backend for Quake II.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#ifdef USE_CURL
|
||||
|
||||
// --------
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "header/qcurl.h"
|
||||
#include "../../common/header/common.h"
|
||||
|
||||
// --------
|
||||
|
||||
// True if cURL is initialized.
|
||||
qboolean qcurlInitialized;
|
||||
|
||||
// Pointer to the dynamic library.
|
||||
static void *curlhandle;
|
||||
|
||||
// CVars
|
||||
static cvar_t *cl_libcurl;
|
||||
|
||||
// Function pointers to cURL.
|
||||
void (*qcurl_easy_cleanup)(CURL *curl);
|
||||
CURL *(*qcurl_easy_init)(void);
|
||||
CURLcode (*qcurl_easy_getinfo)(CURL *curl, CURLINFO info, ...);
|
||||
CURLcode (*qcurl_easy_setopt)(CURL *curl, CURLoption option, ...);
|
||||
const char *(*qcurl_easy_strerror)(CURLcode);
|
||||
|
||||
void (*qcurl_global_cleanup)(void);
|
||||
CURLcode (*qcurl_global_init)(long flags);
|
||||
|
||||
CURLMcode (*qcurl_multi_add_handle)(CURLM *multi_handle, CURL *curl_handle);
|
||||
CURLMcode (*qcurl_multi_cleanup)(CURLM *multi_handle);
|
||||
CURLMsg *(*qcurl_multi_info_read)(CURLM *multi_handle, int *msgs_in_queue);
|
||||
CURLM *(*qcurl_multi_init)(void);
|
||||
CURLMcode (*qcurl_multi_perform)(CURLM *multi_handle, int *running_handles);
|
||||
CURLMcode (*qcurl_multi_remove_handle)(CURLM *multi_handle, CURL *curl_handle);
|
||||
|
||||
// --------
|
||||
|
||||
/*
|
||||
* Load libcurl, connect the function pointer
|
||||
* and call cURLs global init function.
|
||||
*/
|
||||
qboolean qcurlInit(void)
|
||||
{
|
||||
Com_Printf("------- curl initialization -------\n");
|
||||
|
||||
assert(!qcurlInitialized && "cURL already initialized?!");
|
||||
|
||||
// Most systems have only one distinct name for the
|
||||
// libcurl, loading that one will be successfull in
|
||||
// at least 99% of all cases. But Linux, the mother
|
||||
// of chaos, is more complicated. Debian / Ubuntu
|
||||
// alone has 6 possible names... So:
|
||||
// - Let's try whatever the user has written into
|
||||
// the cl_libcurl cvar first.
|
||||
// - If that fails try all possible names until we
|
||||
// find a working one.
|
||||
// - If we found one put it into cl_libcurl, so we
|
||||
// don't need to iterate trought the whole list
|
||||
// the next time the game is started.
|
||||
// - If we found none error out.
|
||||
#ifdef __APPLE__
|
||||
const char *libcurl[] = { "libcurl.dylib", NULL };
|
||||
#elif __linux__
|
||||
const char *libcurl[] = { "libcurl.so", "libcurl.so.3", "libcurl.so.4", "libcurl-gnutls.so.3",
|
||||
"libcurl-gnutls.so.4", "libcurl-nss.so.3", "libcurl-nss.so.4", NULL };
|
||||
#elif _WIN32
|
||||
const char *libcurl[] = { "curl.dll", NULL };
|
||||
#else
|
||||
const char *libcurl[] = { "libcurl.so", NULL };
|
||||
#endif
|
||||
|
||||
// Mkay, let's try to find a working libcurl.
|
||||
cl_libcurl = Cvar_Get("cl_libcurl", (char *)libcurl[0], CVAR_ARCHIVE);
|
||||
|
||||
Com_Printf("LoadLibrary(%s)\n", cl_libcurl->string);
|
||||
Sys_LoadLibrary(cl_libcurl->string, NULL, &curlhandle);
|
||||
|
||||
if (!curlhandle)
|
||||
{
|
||||
Com_Printf("Loading %s failed!\n", cl_libcurl->string);
|
||||
|
||||
for (int i = 0; libcurl[i] != NULL; i++)
|
||||
{
|
||||
// Tried that one already.
|
||||
if (!strcmp(cl_libcurl->string, libcurl[i]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Com_Printf("LoadLibrary(%s)\n", libcurl[i]);
|
||||
Sys_LoadLibrary(libcurl[i], NULL, &curlhandle);
|
||||
|
||||
if (!curlhandle)
|
||||
{
|
||||
// No luck with this one.
|
||||
Com_Printf("Loading %s failed!\n", libcurl[i]);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Got one!
|
||||
Cvar_Set("cl_libcurl", (char *)libcurl[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!curlhandle)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
// libcurl loaded sucessfully, connect the pointers.
|
||||
#define CONCURL(var, sym) do { \
|
||||
var = Sys_GetProcAddress(curlhandle, sym); \
|
||||
if (!var) goto error; \
|
||||
} while(0)
|
||||
|
||||
CONCURL(qcurl_easy_cleanup, "curl_easy_cleanup");
|
||||
CONCURL(qcurl_easy_init, "curl_easy_init");
|
||||
CONCURL(qcurl_easy_getinfo, "curl_easy_getinfo");
|
||||
CONCURL(qcurl_easy_setopt, "curl_easy_setopt");
|
||||
CONCURL(qcurl_easy_strerror, "curl_easy_strerror");
|
||||
|
||||
CONCURL(qcurl_global_cleanup, "curl_global_cleanup");
|
||||
CONCURL(qcurl_global_init, "curl_global_init");
|
||||
|
||||
CONCURL(qcurl_multi_add_handle, "curl_multi_add_handle");
|
||||
CONCURL(qcurl_multi_cleanup, "curl_multi_cleanup");
|
||||
CONCURL(qcurl_multi_info_read, "curl_multi_info_read");
|
||||
CONCURL(qcurl_multi_init, "curl_multi_init");
|
||||
CONCURL(qcurl_multi_perform, "curl_multi_perform");
|
||||
CONCURL(qcurl_multi_remove_handle, "curl_multi_remove_handle");
|
||||
|
||||
#undef CONCURL
|
||||
|
||||
// And finally the global cURL initialization.
|
||||
qcurl_global_init(CURL_GLOBAL_NOTHING);
|
||||
qcurlInitialized = true;
|
||||
|
||||
Com_Printf("------------------------------------\n\n");
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
qcurlShutdown();
|
||||
|
||||
Com_Printf("------------------------------------\n\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calls cURLs global shutdown funtion,
|
||||
* unloads libcurl and set the function
|
||||
* pointers to NULL.
|
||||
*/
|
||||
void qcurlShutdown(void)
|
||||
{
|
||||
if (qcurlInitialized)
|
||||
{
|
||||
Com_Printf("Shutting down curl.\n");
|
||||
|
||||
qcurl_global_cleanup();
|
||||
qcurlInitialized = false;
|
||||
}
|
||||
|
||||
qcurl_easy_cleanup = NULL;
|
||||
qcurl_easy_init = NULL;
|
||||
qcurl_easy_getinfo = NULL;
|
||||
qcurl_easy_setopt = NULL;
|
||||
qcurl_easy_strerror = NULL;
|
||||
|
||||
qcurl_global_cleanup = NULL;
|
||||
qcurl_global_init = NULL;
|
||||
|
||||
qcurl_multi_add_handle = NULL;
|
||||
qcurl_multi_cleanup = NULL;
|
||||
qcurl_multi_info_read = NULL;
|
||||
qcurl_multi_init = NULL;
|
||||
qcurl_multi_perform = NULL;
|
||||
qcurl_multi_remove_handle = NULL;
|
||||
|
||||
if (curlhandle)
|
||||
{
|
||||
Sys_FreeLibrary(curlhandle);
|
||||
curlhandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// --------
|
||||
|
||||
#endif // USE_CURL
|
Loading…
Reference in a new issue