From f518f75149198ed45c1124f646e1351910279d21 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 30 May 2017 20:15:59 -0400 Subject: [PATCH] Don't link directly to libcurl. Lots of Linux distros have different names (libcurl-gnutls.so vs etc), and version the symbols (curl_global_init@@CURL_LIBSSL_3), so it's more compatible to just dlsym the basic entry points we need and just demand that libcurl is installed at all. Alternately: we'll use our own libcurl build, but we'll probably have to dump SSL support to make this sane to do. --- Makefile | 2 +- code/autoupdater/autoupdater.c | 59 +++++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 99f2ffe4..73db3f73 100644 --- a/Makefile +++ b/Makefile @@ -1588,7 +1588,7 @@ $(B)/autoupdater/%.o: $(AUTOUPDATERSRCDIR)/%.c $(B)/$(AUTOUPDATER_BIN): $(Q3AUTOUPDATEROBJ) $(echo_cmd) "AUTOUPDATER_LD $@" - $(Q)$(CC) $(LDFLAGS) -o $@ $(Q3AUTOUPDATEROBJ) $(CURL_LIBS) + $(Q)$(CC) $(LDFLAGS) -o $@ $(Q3AUTOUPDATEROBJ) $(LIBS) ############################################################################# diff --git a/code/autoupdater/autoupdater.c b/code/autoupdater/autoupdater.c index f2e05357..cffbfb52 100644 --- a/code/autoupdater/autoupdater.c +++ b/code/autoupdater/autoupdater.c @@ -151,8 +151,61 @@ static void restoreRollbacks(void) } } - static void die(const char *why) NEVER_RETURNS; + + +#ifndef _WIN32 /* hooray for Unix linker hostility! */ +#undef curl_easy_setopt +#include +typedef void (*CURLFN_curl_easy_cleanup)(CURL *curl); +typedef CURL *(*CURLFN_curl_easy_init)(void); +typedef CURLcode (*CURLFN_curl_easy_setopt)(CURL *curl, CURLoption option, ...); +typedef CURLcode (*CURLFN_curl_easy_perform)(CURL *curl); +typedef CURLcode (*CURLFN_curl_global_init)(long flags); +typedef void (*CURLFN_curl_global_cleanup)(void); + +static CURLFN_curl_easy_cleanup CURL_curl_easy_cleanup; +static CURLFN_curl_easy_init CURL_curl_easy_init; +static CURLFN_curl_easy_setopt CURL_curl_easy_setopt; +static CURLFN_curl_easy_perform CURL_curl_easy_perform; +static CURLFN_curl_global_init CURL_curl_global_init; +static CURLFN_curl_global_cleanup CURL_curl_global_cleanup; + +static void load_libcurl(void) +{ + #ifdef __APPLE__ + const char *libname = "libcurl.4.dylib"; + #else + const char *libname = "libcurl.so.4"; + #endif + + void *handle = dlopen(libname, RTLD_NOW | RTLD_GLOBAL); + if (!handle) { + infof("dlopen(\"%s\") failed: %s", libname, dlerror()); + die("Failed to load libcurl library"); + } + #define LOADCURLSYM(fn) \ + if ((CURL_##fn = (CURLFN_##fn) dlsym(handle, #fn)) == NULL) { \ + die("Failed to load libcurl symbol '" #fn "'"); \ + } + + LOADCURLSYM(curl_easy_cleanup); + LOADCURLSYM(curl_easy_init); + LOADCURLSYM(curl_easy_setopt); + LOADCURLSYM(curl_easy_perform); + LOADCURLSYM(curl_global_init); + LOADCURLSYM(curl_global_cleanup); +} + +#define curl_easy_cleanup CURL_curl_easy_cleanup +#define curl_easy_init CURL_curl_easy_init +#define curl_easy_setopt CURL_curl_easy_setopt +#define curl_easy_perform CURL_curl_easy_perform +#define curl_global_init CURL_curl_global_init +#define curl_global_cleanup CURL_curl_global_cleanup +#endif + + static void die(const char *why) { infof("FAILURE: %s", why); @@ -696,6 +749,10 @@ int main(int argc, char **argv) upgradeSelfAndRestart(argv[0]); } + #ifndef _WIN32 + load_libcurl(); + #endif + if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) { die("curl_global_init() failed!"); }