mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-10 07:12:07 +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
|
release/yquake2.exe : LDFLAGS += -mwindows
|
||||||
|
|
||||||
|
ifeq ($(WITH_CURL),yes)
|
||||||
|
release/quake2 : CFLAGS += -DUSE_CURL
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(WITH_OPENAL),yes)
|
ifeq ($(WITH_OPENAL),yes)
|
||||||
release/yquake2.exe : CFLAGS += -DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER='"openal32.dll"'
|
release/yquake2.exe : CFLAGS += -DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER='"openal32.dll"'
|
||||||
endif
|
endif
|
||||||
|
@ -379,7 +383,6 @@ release/quake2 : CFLAGS += -Wno-unused-result
|
||||||
|
|
||||||
ifeq ($(WITH_CURL),yes)
|
ifeq ($(WITH_CURL),yes)
|
||||||
release/quake2 : CFLAGS += -DUSE_CURL
|
release/quake2 : CFLAGS += -DUSE_CURL
|
||||||
release/quake2 : LDFLAGS += -lcurl
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(WITH_OPENAL),yes)
|
ifeq ($(WITH_OPENAL),yes)
|
||||||
|
@ -690,6 +693,7 @@ CLIENT_OBJS_ := \
|
||||||
src/client/cl_screen.o \
|
src/client/cl_screen.o \
|
||||||
src/client/cl_tempentities.o \
|
src/client/cl_tempentities.o \
|
||||||
src/client/cl_view.o \
|
src/client/cl_view.o \
|
||||||
|
src/client/curl/qcurl.o \
|
||||||
src/client/input/sdl.o \
|
src/client/input/sdl.o \
|
||||||
src/client/menu/menu.o \
|
src/client/menu/menu.o \
|
||||||
src/client/menu/qmenu.o \
|
src/client/menu/qmenu.o \
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "header/client.h"
|
#include "header/client.h"
|
||||||
|
#include "curl/header/qcurl.h"
|
||||||
|
|
||||||
#ifdef USE_CURL
|
#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;
|
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.
|
// Mkay, the remote file should be at least one byte long.
|
||||||
// Since this is used for paclists only we assume that the
|
// 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.
|
// Setup and configure the CURL part of our download handle.
|
||||||
if (!dl->curl)
|
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);
|
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)
|
if (dl->file)
|
||||||
{
|
{
|
||||||
curl_easy_setopt(dl->curl, CURLOPT_WRITEDATA, dl->file);
|
qcurl_easy_setopt(dl->curl, CURLOPT_WRITEDATA, dl->file);
|
||||||
curl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, NULL);
|
qcurl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
curl_easy_setopt(dl->curl, CURLOPT_WRITEDATA, dl);
|
qcurl_easy_setopt(dl->curl, CURLOPT_WRITEDATA, dl);
|
||||||
curl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, CL_HTTP_Recv);
|
qcurl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, CL_HTTP_Recv);
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_easy_setopt(dl->curl, CURLOPT_PROXY, cl_http_proxy->string);
|
qcurl_easy_setopt(dl->curl, CURLOPT_PROXY, cl_http_proxy->string);
|
||||||
curl_easy_setopt(dl->curl, CURLOPT_FOLLOWLOCATION, 1);
|
qcurl_easy_setopt(dl->curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||||
curl_easy_setopt(dl->curl, CURLOPT_MAXREDIRS, 5);
|
qcurl_easy_setopt(dl->curl, CURLOPT_MAXREDIRS, 5);
|
||||||
curl_easy_setopt(dl->curl, CURLOPT_PROGRESSDATA, dl);
|
qcurl_easy_setopt(dl->curl, CURLOPT_PROGRESSDATA, dl);
|
||||||
curl_easy_setopt(dl->curl, CURLOPT_USERAGENT, Cvar_VariableString ("version"));
|
qcurl_easy_setopt(dl->curl, CURLOPT_USERAGENT, Cvar_VariableString ("version"));
|
||||||
curl_easy_setopt(dl->curl, CURLOPT_REFERER, cls.downloadReferer);
|
qcurl_easy_setopt(dl->curl, CURLOPT_REFERER, cls.downloadReferer);
|
||||||
curl_easy_setopt(dl->curl, CURLOPT_URL, dl->URL);
|
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");
|
Com_Printf("HTTP download: cURL error\n");
|
||||||
dl->queueEntry->state = DLQ_STATE_DONE;
|
dl->queueEntry->state = DLQ_STATE_DONE;
|
||||||
|
@ -473,7 +474,7 @@ static void CL_FinishHTTPDownload(void)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// Get a message from CURL.
|
// 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)
|
if (!msg)
|
||||||
{
|
{
|
||||||
|
@ -551,7 +552,7 @@ static void CL_FinishHTTPDownload(void)
|
||||||
{
|
{
|
||||||
case CURLE_HTTP_RETURNED_ERROR:
|
case CURLE_HTTP_RETURNED_ERROR:
|
||||||
case CURLE_OK:
|
case CURLE_OK:
|
||||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
|
qcurl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||||
|
|
||||||
if (responseCode == 404)
|
if (responseCode == 404)
|
||||||
{
|
{
|
||||||
|
@ -564,7 +565,7 @@ static void CL_FinishHTTPDownload(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...and remove it from the CURL multihandle.
|
// ...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);
|
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.
|
// ...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,
|
// Special case: We're already aborting HTTP downloading,
|
||||||
// so we can't just kill everything. Otherwise we'll get
|
// so we can't just kill everything. Otherwise we'll get
|
||||||
|
@ -614,7 +615,7 @@ static void CL_FinishHTTPDownload(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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);
|
i = strlen(dl->queueEntry->quakePath);
|
||||||
|
|
||||||
|
@ -625,7 +626,7 @@ static void CL_FinishHTTPDownload(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...and the handle from CURLs mutihandle.
|
// ...and the handle from CURLs mutihandle.
|
||||||
curl_multi_remove_handle (multi, dl->curl);
|
qcurl_multi_remove_handle (multi, dl->curl);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
|
@ -651,7 +652,7 @@ static void CL_FinishHTTPDownload(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the file fo CURLs multihandle.
|
// 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);
|
} while (msgs_in_queue > 0);
|
||||||
|
|
||||||
|
@ -736,7 +737,11 @@ static void CL_StartNextHTTPDownload(void)
|
||||||
*/
|
*/
|
||||||
void CL_InitHTTPDownloads (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 (dl->curl)
|
||||||
{
|
{
|
||||||
if (multi)
|
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;
|
dl->curl = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,14 +790,17 @@ void CL_HTTP_Cleanup(qboolean fullShutdown)
|
||||||
// Cleanup CURL multihandle.
|
// Cleanup CURL multihandle.
|
||||||
if (multi)
|
if (multi)
|
||||||
{
|
{
|
||||||
curl_multi_cleanup(multi);
|
qcurl_multi_cleanup(multi);
|
||||||
multi = NULL;
|
multi = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown CURL.
|
// Shutdown CURL.
|
||||||
if (fullShutdown)
|
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;
|
httpDown = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -807,6 +818,16 @@ void CL_SetHTTPServer (const char *URL)
|
||||||
dlqueue_t *last = NULL;
|
dlqueue_t *last = NULL;
|
||||||
dlqueue_t *q = &cls.downloadQueue;
|
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);
|
CL_HTTP_Cleanup(false);
|
||||||
|
|
||||||
// Cleanup download queues.
|
// Cleanup download queues.
|
||||||
|
@ -841,7 +862,7 @@ void CL_SetHTTPServer (const char *URL)
|
||||||
Com_Error(ERR_DROP, "HTTP download: Still have old handle?!");
|
Com_Error(ERR_DROP, "HTTP download: Still have old handle?!");
|
||||||
}
|
}
|
||||||
|
|
||||||
multi = curl_multi_init();
|
multi = qcurl_multi_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -984,7 +1005,7 @@ void CL_RunHTTPDownloads(void)
|
||||||
int newHandleCount;
|
int newHandleCount;
|
||||||
CURLMcode ret;
|
CURLMcode ret;
|
||||||
|
|
||||||
// No HTTP server given.
|
// No HTTP server given or not initialized.
|
||||||
if (!cls.downloadServer[0])
|
if (!cls.downloadServer[0])
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -993,7 +1014,7 @@ void CL_RunHTTPDownloads(void)
|
||||||
// Kick CURL into action.
|
// Kick CURL into action.
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ret = curl_multi_perform(multi, &newHandleCount);
|
ret = qcurl_multi_perform(multi, &newHandleCount);
|
||||||
|
|
||||||
if (newHandleCount < handleCount)
|
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