libcurl = dependency('libcurl',
version : '>= 7.32.0',
required : get_option('libcurl'))
+libcurl_cflags = libcurl.partial_dependency(includes: true, compile_args: true)
conf.set10('HAVE_LIBCURL', libcurl.found())
conf.set10('CURL_NO_OLDIES', conf.get('BUILD_MODE_DEVELOPER') == 1)
c->curl_data = NULL;
}
- curl_slist_free_all(c->request_header_token);
+ sym_curl_slist_free_all(c->request_header_token);
c->request_header_token = NULL;
- curl_slist_free_all(c->request_header_data);
+ sym_curl_slist_free_all(c->request_header_data);
c->request_header_data = NULL;
c->cache_fd = safe_close(c->cache_fd);
*/
long status;
- CURLcode code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
+ CURLcode code = sym_curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
if (code != CURLE_OK)
- return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", curl_easy_strerror(code));
+ return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", sym_curl_easy_strerror(code));
context_log(c, LOG_DEBUG, "Got HTTP error code %li.", status);
/* Called whenever libcurl did its thing and reports a download being complete or having failed */
Context *c = NULL;
- if (curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char**) &c) != CURLE_OK)
+ if (sym_curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char**) &c) != CURLE_OK)
return;
switch (result) {
case CURLE_GOT_NOTHING:
case CURLE_SEND_ERROR:
case CURLE_RECV_ERROR:
- context_log(c, LOG_INFO, "Connection error from curl: %s", curl_easy_strerror(result));
+ context_log(c, LOG_INFO, "Connection error from curl: %s", sym_curl_easy_strerror(result));
/* Automatically retry on some transient errors from curl itself */
r = context_schedule_retry(c);
default:
return context_fail_full(
c,
- context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EHOSTDOWN), "Transfer failed: %s", curl_easy_strerror(result)),
+ context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EHOSTDOWN), "Transfer failed: %s", sym_curl_easy_strerror(result)),
"io.systemd.InstanceMetadata.CommunicationFailure");
}
return context_log_errno(c, LOG_ERR, r, "Failed to create curl header: %m");
if (c->request_header_data)
- if (curl_easy_setopt(c->curl_data, CURLOPT_HTTPHEADER, c->request_header_data) != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_data, CURLOPT_HTTPHEADER, c->request_header_data) != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set HTTP request header.");
- if (curl_easy_setopt(c->curl_data, CURLOPT_WRITEFUNCTION, data_write_callback) != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_data, CURLOPT_WRITEFUNCTION, data_write_callback) != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set CURL write function.");
- if (curl_easy_setopt(c->curl_data, CURLOPT_WRITEDATA, c) != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_data, CURLOPT_WRITEDATA, c) != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set CURL write function userdata.");
- if (curl_easy_setopt(c->curl_data, CURLOPT_SOCKOPTFUNCTION, setsockopt_callback) != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_data, CURLOPT_SOCKOPTFUNCTION, setsockopt_callback) != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set CURL setsockopt function.");
- if (curl_easy_setopt(c->curl_data, CURLOPT_SOCKOPTDATA, c) != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_data, CURLOPT_SOCKOPTDATA, c) != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set CURL setsockopt function userdata.");
- if (curl_easy_setopt(c->curl_data, CURLOPT_LOCALPORT, 1L) != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_data, CURLOPT_LOCALPORT, 1L) != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set CURL setsockopt local port");
- if (curl_easy_setopt(c->curl_data, CURLOPT_LOCALPORTRANGE, 1023L) != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_data, CURLOPT_LOCALPORTRANGE, 1023L) != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set CURL setsockopt local port range");
r = curl_glue_add(c->glue, c->curl_data);
return context_log_oom(c);
}
- if (curl_easy_setopt(c->curl_token, CURLOPT_HTTPHEADER, c->request_header_token) != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_token, CURLOPT_HTTPHEADER, c->request_header_token) != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set HTTP request header.");
- if (curl_easy_setopt(c->curl_token, CURLOPT_CUSTOMREQUEST, "PUT") != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_token, CURLOPT_CUSTOMREQUEST, "PUT") != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set HTTP request method.");
- if (curl_easy_setopt(c->curl_token, CURLOPT_WRITEFUNCTION, token_write_callback) != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_token, CURLOPT_WRITEFUNCTION, token_write_callback) != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set CURL write function.");
- if (curl_easy_setopt(c->curl_token, CURLOPT_WRITEDATA, c) != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_token, CURLOPT_WRITEDATA, c) != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set CURL write function userdata.");
- if (curl_easy_setopt(c->curl_token, CURLOPT_SOCKOPTFUNCTION, setsockopt_callback) != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_token, CURLOPT_SOCKOPTFUNCTION, setsockopt_callback) != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set CURL setsockopt function.");
- if (curl_easy_setopt(c->curl_token, CURLOPT_SOCKOPTDATA, c) != CURLE_OK)
+ if (sym_curl_easy_setopt(c->curl_token, CURLOPT_SOCKOPTDATA, c) != CURLE_OK)
return context_log_errno(c, LOG_ERR, SYNTHETIC_ERRNO(EIO), "Failed to set CURL setsockopt function userdata.");
r = curl_glue_add(c->glue, c->curl_token);
if (r <= 0)
return r;
+ r = dlopen_curl();
+ if (r < 0)
+ return r;
+
r = environment_server_info();
if (r < 0)
return r;
libexec_template + {
'name' : 'systemd-imdsd',
'public' : true,
- 'sources' : files(
- 'imdsd.c',
- 'imds-util.c'
- ),
- 'link_with' : [libcurlutil_static, libshared],
- 'dependencies' : [libcurl],
+ 'sources' : files('imdsd.c'),
+ 'extract' : files('imds-util.c'),
},
libexec_template + {
'name' : 'systemd-imds',
'public' : true,
- 'sources' : files(
- 'imds-tool.c',
- 'imds-util.c'
- ),
+ 'sources' : files('imds-tool.c'),
+ 'objects' : ['systemd-imdsd'],
},
generator_template + {
'name' : 'systemd-imds-generator',
- 'sources' : files(
- 'imds-generator.c',
- 'imds-util.c'
- ),
+ 'sources' : files('imds-generator.c'),
+ 'objects' : ['systemd-imdsd'],
},
]
subdir_done()
endif
-common_deps = [
- libcurl,
-]
-
executables += [
libexec_template + {
'name' : 'systemd-importd',
'import-common.c',
'qcow2-util.c',
),
- 'dependencies' : [common_deps, threads],
+ 'dependencies' : threads,
},
libexec_template + {
'name' : 'systemd-pull',
'pull-tar.c',
),
'objects' : ['systemd-importd'],
- 'link_with' : [libcurlutil_static, libshared],
- 'dependencies' : common_deps + [
- libopenssl,
- ],
+ 'dependencies' : libopenssl,
},
libexec_template + {
'name' : 'systemd-import',
'import-tar.c',
),
'objects' : ['systemd-importd'],
- 'dependencies' : common_deps,
},
libexec_template + {
'name' : 'systemd-import-fs',
'import-fs.c',
),
'objects' : ['systemd-importd'],
- 'dependencies' : common_deps,
},
libexec_template + {
'name' : 'systemd-export',
'export-raw.c',
),
'objects' : ['systemd-importd'],
- 'dependencies' : common_deps,
},
executable_template + {
'name' : 'importctl',
'public' : true,
'sources' : files('importctl.c'),
'objects': ['systemd-importd'],
- 'dependencies' : common_deps,
},
generator_template + {
'name' : 'systemd-import-generator',
test_template + {
'sources' : files('test-qcow2.c'),
'objects' : ['systemd-importd'],
- 'dependencies' : common_deps,
'type' : 'manual',
},
test_template + {
'sources' : files('test-oci-util.c'),
'objects': ['systemd-importd'],
- 'dependencies' : common_deps,
},
]
pull_job_close_disk_fd(j);
curl_glue_remove_and_free(j->glue, j->curl);
- curl_slist_free_all(j->request_header);
+ sym_curl_slist_free_all(j->request_header);
j->compress = compressor_free(j->compress);
CURLcode code;
int r;
- if (curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&j) != CURLE_OK)
+ if (sym_curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&j) != CURLE_OK)
return;
if (!j || IN_SET(j->state, PULL_JOB_DONE, PULL_JOB_FAILED))
return;
- code = curl_easy_getinfo(curl, CURLINFO_SCHEME, &scheme);
+ code = sym_curl_easy_getinfo(curl, CURLINFO_SCHEME, &scheme);
if (code != CURLE_OK || !scheme) {
r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve URL scheme.");
goto finish;
}
if (result != CURLE_OK) {
- r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Transfer failed: %s", curl_easy_strerror(result));
+ r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Transfer failed: %s", sym_curl_easy_strerror(result));
goto finish;
}
if (STRCASE_IN_SET(scheme, "HTTP", "HTTPS")) {
long status;
- code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
+ code = sym_curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
if (code != CURLE_OK) {
- r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", curl_easy_strerror(code));
+ r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", sym_curl_easy_strerror(code));
goto finish;
}
if (r < 0)
goto finish;
- code = curl_easy_getinfo(j->curl, CURLINFO_RESPONSE_CODE, &status);
+ code = sym_curl_easy_getinfo(j->curl, CURLINFO_RESPONSE_CODE, &status);
if (code != CURLE_OK) {
- r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", curl_easy_strerror(code));
+ r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", sym_curl_easy_strerror(code));
goto finish;
}
assert(j->state == PULL_JOB_ANALYZING);
- code = curl_easy_getinfo(j->curl, CURLINFO_RESPONSE_CODE, &status);
+ code = sym_curl_easy_getinfo(j->curl, CURLINFO_RESPONSE_CODE, &status);
if (code != CURLE_OK) {
- r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", curl_easy_strerror(code));
+ r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", sym_curl_easy_strerror(code));
goto fail;
}
if (j->request_header) {
struct curl_slist *l;
- l = curl_slist_append(j->request_header, hdr);
+ l = sym_curl_slist_append(j->request_header, hdr);
if (!l)
return -ENOMEM;
}
if (j->request_header) {
- if (curl_easy_setopt(j->curl, CURLOPT_HTTPHEADER, j->request_header) != CURLE_OK)
+ if (sym_curl_easy_setopt(j->curl, CURLOPT_HTTPHEADER, j->request_header) != CURLE_OK)
return -EIO;
}
- if (curl_easy_setopt(j->curl, CURLOPT_WRITEFUNCTION, pull_job_write_callback) != CURLE_OK)
+ if (sym_curl_easy_setopt(j->curl, CURLOPT_WRITEFUNCTION, pull_job_write_callback) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(j->curl, CURLOPT_WRITEDATA, j) != CURLE_OK)
+ if (sym_curl_easy_setopt(j->curl, CURLOPT_WRITEDATA, j) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(j->curl, CURLOPT_HEADERFUNCTION, pull_job_header_callback) != CURLE_OK)
+ if (sym_curl_easy_setopt(j->curl, CURLOPT_HEADERFUNCTION, pull_job_header_callback) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(j->curl, CURLOPT_HEADERDATA, j) != CURLE_OK)
+ if (sym_curl_easy_setopt(j->curl, CURLOPT_HEADERDATA, j) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(j->curl, CURLOPT_XFERINFOFUNCTION, pull_job_progress_callback) != CURLE_OK)
+ if (sym_curl_easy_setopt(j->curl, CURLOPT_XFERINFOFUNCTION, pull_job_progress_callback) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(j->curl, CURLOPT_XFERINFODATA, j) != CURLE_OK)
+ if (sym_curl_easy_setopt(j->curl, CURLOPT_XFERINFODATA, j) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(j->curl, CURLOPT_NOPROGRESS, 0L) != CURLE_OK)
+ if (sym_curl_easy_setopt(j->curl, CURLOPT_NOPROGRESS, 0L) != CURLE_OK)
return -EIO;
r = curl_glue_add(j->glue, j->curl);
_cleanup_(curl_slist_free_allp) struct curl_slist *h = NULL;
struct curl_slist *l;
- h = curl_slist_append(NULL, "Content-Type: application/vnd.fdo.journal");
+ h = sym_curl_slist_append(NULL, "Content-Type: application/vnd.fdo.journal");
if (!h)
return log_oom();
- l = curl_slist_append(h, "Transfer-Encoding: chunked");
+ l = sym_curl_slist_append(h, "Transfer-Encoding: chunked");
if (!l)
return log_oom();
h = l;
- l = curl_slist_append(h, "Accept: text/plain");
+ l = sym_curl_slist_append(h, "Accept: text/plain");
if (!l)
return log_oom();
h = l;
if (!header)
return log_oom();
- l = curl_slist_append(h, header);
+ l = sym_curl_slist_append(h, header);
if (!l)
return log_oom();
h = l;
if (!header)
return log_oom();
- l = curl_slist_append(h, header);
+ l = sym_curl_slist_append(h, header);
if (!l)
return log_oom();
h = l;
if (!u->easy) {
_cleanup_(curl_easy_cleanupp) CURL *curl = NULL;
- curl = curl_easy_init();
+ curl = sym_curl_easy_init();
if (!curl)
return log_error_errno(SYNTHETIC_ERRNO(ENOSR),
"Call to curl_easy_init failed.");
static void destroy_uploader(Uploader *u) {
assert(u);
- curl_easy_cleanup(u->easy);
- curl_slist_free_all(u->header);
+ if (sym_curl_easy_cleanup)
+ sym_curl_easy_cleanup(u->easy);
+ if (sym_curl_slist_free_all)
+ sym_curl_slist_free_all(u->header);
free(u->answer);
free(u->last_cursor);
/* If Content-Encoding header is not found, append new one. */
if (!found) {
- struct curl_slist *l = curl_slist_append(u->header, header);
+ struct curl_slist *l = sym_curl_slist_append(u->header, header);
if (!l)
return log_oom();
u->header = l;
else
u->header = TAKE_PTR(l->next);
- curl_slist_free_all(l);
+ sym_curl_slist_free_all(l);
update_header = true;
break;
}
return update_content_encoding_header(u, NULL);
struct curl_header *header;
- CURLHcode hcode = curl_easy_header(u->easy, "Accept-Encoding", 0, CURLH_HEADER, -1, &header);
+ CURLHcode hcode = sym_curl_easy_header(u->easy, "Accept-Encoding", 0, CURLH_HEADER, -1, &header);
if (hcode != CURLHE_OK)
goto not_found;
assert(u);
u->watchdog_timestamp = now(CLOCK_MONOTONIC);
- code = curl_easy_perform(u->easy);
+ code = sym_curl_easy_perform(u->easy);
if (code) {
if (u->error[0])
return log_error_errno(SYNTHETIC_ERRNO(EIO),
else
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Upload to %s failed: %s",
- u->url, curl_easy_strerror(code));
+ u->url, sym_curl_easy_strerror(code));
}
- code = curl_easy_getinfo(u->easy, CURLINFO_RESPONSE_CODE, &status);
+ code = sym_curl_easy_getinfo(u->easy, CURLINFO_RESPONSE_CODE, &status);
if (code)
return log_error_errno(SYNTHETIC_ERRNO(EUCLEAN),
"Failed to retrieve response code: %s",
- curl_easy_strerror(code));
+ sym_curl_easy_strerror(code));
if (status >= 300)
return log_error_errno(SYNTHETIC_ERRNO(EIO),
if (r <= 0)
return r;
+ r = dlopen_curl();
+ if (r < 0)
+ return r;
+
r = compression_configs_mangle(&arg_compression);
if (r < 0)
return r;
'sources' : systemd_journal_upload_sources,
'extract' : systemd_journal_upload_extract_sources,
'objects' : ['systemd-journal-remote'],
- 'dependencies' : common_deps + [libcurl],
+ 'dependencies' : common_deps,
},
test_template + {
'sources' : files('test-journal-header-util.c'),
'report.c',
'report-upload.c',
),
- 'link_with' : [libcurlutil_static, libshared],
- 'dependencies' : [libcurl],
},
libexec_template + {
#if HAVE_LIBCURL
#include "curl-util.h"
-#include <curl/easy.h> /* Sadly this fails if ordered first. */
#define SERVER_ANSWER_MAX (1*1024*1024u)
_cleanup_free_ char *json = NULL;
int r;
+ r = dlopen_curl();
+ if (r < 0)
+ return r;
+
{
/* Convert our variant array to a JSON report.
* We won't need the JSON structure again, so free it quickly. */
if (r < 0)
return log_error_errno(r, "Failed to create curl header: %m");
- _cleanup_(curl_easy_cleanupp) CURL *curl = curl_easy_init();
+ _cleanup_(curl_easy_cleanupp) CURL *curl = sym_curl_easy_init();
if (!curl)
return log_error_errno(SYNTHETIC_ERRNO(ENOSR),
"Call to curl_easy_init failed.");
if (!easy_setopt(curl, LOG_ERR, CURLOPT_POSTFIELDS, json))
return -EXFULL;
- CURLcode code = curl_easy_perform(curl);
+ CURLcode code = sym_curl_easy_perform(curl);
if (code != CURLE_OK)
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Upload to %s failed: %s", arg_url,
- empty_to_null(&error[0]) ?: curl_easy_strerror(code));
+ empty_to_null(&error[0]) ?: sym_curl_easy_strerror(code));
long status;
- code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
+ code = sym_curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
if (code != CURLE_OK)
return log_error_errno(SYNTHETIC_ERRNO(EUCLEAN),
"Failed to retrieve response code: %s",
- curl_easy_strerror(code));
+ sym_curl_easy_strerror(code));
_cleanup_free_ char *ans = iovw_to_cstring(&context->upload_answer);
if (!ans)
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include "curl-util.h"
+
+#if HAVE_LIBCURL
+
+#include "sd-dlopen.h"
#include "sd-event.h"
#include "alloc-util.h"
-#include "curl-util.h"
+#include "dlfcn-util.h"
#include "fd-util.h"
#include "hashmap.h"
#include "log.h"
#include "time-util.h"
#include "version.h"
+static void *curl_dl = NULL;
+
+DLSYM_PROTOTYPE(curl_easy_cleanup) = NULL;
+DLSYM_PROTOTYPE(curl_easy_getinfo) = NULL;
+DLSYM_PROTOTYPE(curl_easy_init) = NULL;
+DLSYM_PROTOTYPE(curl_easy_perform) = NULL;
+DLSYM_PROTOTYPE(curl_easy_setopt) = NULL;
+DLSYM_PROTOTYPE(curl_easy_strerror) = NULL;
+#if LIBCURL_VERSION_NUM >= 0x075300
+DLSYM_PROTOTYPE(curl_easy_header) = NULL;
+#endif
+DLSYM_PROTOTYPE(curl_getdate) = NULL;
+DLSYM_PROTOTYPE(curl_multi_add_handle) = NULL;
+DLSYM_PROTOTYPE(curl_multi_assign) = NULL;
+DLSYM_PROTOTYPE(curl_multi_cleanup) = NULL;
+DLSYM_PROTOTYPE(curl_multi_info_read) = NULL;
+DLSYM_PROTOTYPE(curl_multi_init) = NULL;
+DLSYM_PROTOTYPE(curl_multi_remove_handle) = NULL;
+DLSYM_PROTOTYPE(curl_multi_setopt) = NULL;
+DLSYM_PROTOTYPE(curl_multi_socket_action) = NULL;
+DLSYM_PROTOTYPE(curl_slist_append) = NULL;
+DLSYM_PROTOTYPE(curl_slist_free_all) = NULL;
+
+int dlopen_curl(void) {
+ SD_ELF_NOTE_DLOPEN(
+ "curl",
+ "Support for downloading and uploading files over HTTP",
+ SD_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+ "libcurl.so.4");
+
+ return dlopen_many_sym_or_warn(
+ &curl_dl,
+ "libcurl.so.4",
+ LOG_DEBUG,
+ DLSYM_ARG(curl_easy_cleanup),
+ DLSYM_ARG(curl_easy_getinfo),
+ DLSYM_ARG(curl_easy_init),
+ DLSYM_ARG(curl_easy_perform),
+ DLSYM_ARG(curl_easy_setopt),
+ DLSYM_ARG(curl_easy_strerror),
+#if LIBCURL_VERSION_NUM >= 0x075300
+ DLSYM_ARG(curl_easy_header),
+#endif
+ DLSYM_ARG(curl_getdate),
+ DLSYM_ARG(curl_multi_add_handle),
+ DLSYM_ARG(curl_multi_assign),
+ DLSYM_ARG(curl_multi_cleanup),
+ DLSYM_ARG(curl_multi_info_read),
+ DLSYM_ARG(curl_multi_init),
+ DLSYM_ARG(curl_multi_remove_handle),
+ DLSYM_ARG(curl_multi_setopt),
+ DLSYM_ARG(curl_multi_socket_action),
+ DLSYM_ARG(curl_slist_append),
+ DLSYM_ARG(curl_slist_free_all));
+}
+
static void curl_glue_check_finished(CurlGlue *g) {
int r;
CURLMsg *msg;
int k = 0;
- msg = curl_multi_info_read(g->curl, &k);
+ msg = sym_curl_multi_info_read(g->curl, &k);
if (!msg)
return;
else
action = 0;
- if (curl_multi_socket_action(g->curl, fd, action, &k) != CURLM_OK)
+ if (sym_curl_multi_socket_action(g->curl, fd, action, &k) != CURLM_OK)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"Failed to propagate IO event.");
if (sd_event_add_io(g->event, &io, s, events, curl_glue_on_io, g) < 0)
return -1;
- if (curl_multi_assign(g->curl, s, io) != CURLM_OK)
+ if (sym_curl_multi_assign(g->curl, s, io) != CURLM_OK)
return -1;
(void) sd_event_source_set_description(io, "curl-io");
assert(s);
- if (curl_multi_socket_action(g->curl, CURL_SOCKET_TIMEOUT, 0, &k) != CURLM_OK)
+ if (sym_curl_multi_socket_action(g->curl, CURL_SOCKET_TIMEOUT, 0, &k) != CURLM_OK)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"Failed to propagate timeout.");
return NULL;
if (g->curl)
- curl_multi_cleanup(g->curl);
+ sym_curl_multi_cleanup(g->curl);
while ((io = hashmap_steal_first(g->ios)))
sd_event_source_unref(io);
assert(glue);
+ r = dlopen_curl();
+ if (r < 0)
+ return r;
+
if (event)
e = sd_event_ref(event);
else {
return r;
}
- c = curl_multi_init();
+ c = sym_curl_multi_init();
if (!c)
return -ENOMEM;
.curl = TAKE_PTR(c),
};
- if (curl_multi_setopt(g->curl, CURLMOPT_SOCKETDATA, g) != CURLM_OK)
+ if (sym_curl_multi_setopt(g->curl, CURLMOPT_SOCKETDATA, g) != CURLM_OK)
return -EINVAL;
- if (curl_multi_setopt(g->curl, CURLMOPT_SOCKETFUNCTION, curl_glue_socket_callback) != CURLM_OK)
+ if (sym_curl_multi_setopt(g->curl, CURLMOPT_SOCKETFUNCTION, curl_glue_socket_callback) != CURLM_OK)
return -EINVAL;
- if (curl_multi_setopt(g->curl, CURLMOPT_TIMERDATA, g) != CURLM_OK)
+ if (sym_curl_multi_setopt(g->curl, CURLMOPT_TIMERDATA, g) != CURLM_OK)
return -EINVAL;
- if (curl_multi_setopt(g->curl, CURLMOPT_TIMERFUNCTION, curl_glue_timer_callback) != CURLM_OK)
+ if (sym_curl_multi_setopt(g->curl, CURLMOPT_TIMERFUNCTION, curl_glue_timer_callback) != CURLM_OK)
return -EINVAL;
r = sd_event_add_defer(g->event, &g->defer, curl_glue_on_defer, g);
int curl_glue_make(CURL **ret, const char *url, void *userdata) {
_cleanup_(curl_easy_cleanupp) CURL *c = NULL;
const char *useragent;
+ int r;
assert(ret);
assert(url);
- c = curl_easy_init();
+ r = dlopen_curl();
+ if (r < 0)
+ return r;
+
+ c = sym_curl_easy_init();
if (!c)
return -ENOMEM;
if (DEBUG_LOGGING)
- (void) curl_easy_setopt(c, CURLOPT_VERBOSE, 1L);
+ (void) sym_curl_easy_setopt(c, CURLOPT_VERBOSE, 1L);
- if (curl_easy_setopt(c, CURLOPT_URL, url) != CURLE_OK)
+ if (sym_curl_easy_setopt(c, CURLOPT_URL, url) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(c, CURLOPT_PRIVATE, userdata) != CURLE_OK)
+ if (sym_curl_easy_setopt(c, CURLOPT_PRIVATE, userdata) != CURLE_OK)
return -EIO;
useragent = strjoina(program_invocation_short_name, "/" GIT_VERSION);
- if (curl_easy_setopt(c, CURLOPT_USERAGENT, useragent) != CURLE_OK)
+ if (sym_curl_easy_setopt(c, CURLOPT_USERAGENT, useragent) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(c, CURLOPT_FOLLOWLOCATION, 1L) != CURLE_OK)
+ if (sym_curl_easy_setopt(c, CURLOPT_FOLLOWLOCATION, 1L) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(c, CURLOPT_NOSIGNAL, 1L) != CURLE_OK)
+ if (sym_curl_easy_setopt(c, CURLOPT_NOSIGNAL, 1L) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(c, CURLOPT_LOW_SPEED_TIME, 60L) != CURLE_OK)
+ if (sym_curl_easy_setopt(c, CURLOPT_LOW_SPEED_TIME, 60L) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(c, CURLOPT_LOW_SPEED_LIMIT, 30L) != CURLE_OK)
+ if (sym_curl_easy_setopt(c, CURLOPT_LOW_SPEED_LIMIT, 30L) != CURLE_OK)
return -EIO;
#if LIBCURL_VERSION_NUM >= 0x075500 /* libcurl 7.85.0 */
- if (curl_easy_setopt(c, CURLOPT_PROTOCOLS_STR, "HTTP,HTTPS,FILE") != CURLE_OK)
+ if (sym_curl_easy_setopt(c, CURLOPT_PROTOCOLS_STR, "HTTP,HTTPS,FILE") != CURLE_OK)
#else
- if (curl_easy_setopt(c, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_FILE) != CURLE_OK)
+ if (sym_curl_easy_setopt(c, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_FILE) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(c, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS) != CURLE_OK)
+ if (sym_curl_easy_setopt(c, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS) != CURLE_OK)
#endif
return -EIO;
assert(g);
assert(c);
- if (curl_multi_add_handle(g->curl, c) != CURLM_OK)
+ if (sym_curl_multi_add_handle(g->curl, c) != CURLM_OK)
return -EIO;
return 0;
return;
if (g->curl)
- curl_multi_remove_handle(g->curl, c);
+ sym_curl_multi_remove_handle(g->curl, c);
- curl_easy_cleanup(c);
+ sym_curl_easy_cleanup(c);
}
struct curl_slist *curl_slist_new(const char *first, ...) {
if (!first)
return NULL;
- l = curl_slist_append(NULL, first);
+ l = sym_curl_slist_append(NULL, first);
if (!l)
return NULL;
if (!i)
break;
- n = curl_slist_append(l, i);
+ n = sym_curl_slist_append(l, i);
if (!n) {
va_end(ap);
- curl_slist_free_all(l);
+ sym_curl_slist_free_all(l);
return NULL;
}
assert(t);
assert(ret);
- time_t v = curl_getdate(t, NULL);
+ time_t v = sym_curl_getdate(t, NULL);
if (v == (time_t) -1)
return -EINVAL;
assert(list);
STRV_FOREACH(h, headers) {
- struct curl_slist *l = curl_slist_append(*list, *h);
+ struct curl_slist *l = sym_curl_slist_append(*list, *h);
if (!l)
return -ENOMEM;
*list = l;
return 0;
}
+
+#endif
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
-#include <curl/curl.h>
-
#include "shared-forward.h"
-#define easy_setopt(curl, log_level, opt, value) ({ \
- CURLcode code = curl_easy_setopt(ASSERT_PTR(curl), opt, value); \
- if (code) \
- log_full(log_level, \
- "curl_easy_setopt %s failed: %s", \
- #opt, curl_easy_strerror(code)); \
- code == CURLE_OK; \
-})
+#if HAVE_LIBCURL
+#include <curl/curl.h> /* IWYU pragma: export */
+
+#include "dlfcn-util.h"
+
+extern DLSYM_PROTOTYPE(curl_easy_cleanup);
+extern DLSYM_PROTOTYPE(curl_easy_getinfo);
+extern DLSYM_PROTOTYPE(curl_easy_init);
+extern DLSYM_PROTOTYPE(curl_easy_perform);
+extern DLSYM_PROTOTYPE(curl_easy_setopt);
+extern DLSYM_PROTOTYPE(curl_easy_strerror);
+#if LIBCURL_VERSION_NUM >= 0x075300
+extern DLSYM_PROTOTYPE(curl_easy_header);
+#endif
+extern DLSYM_PROTOTYPE(curl_getdate);
+extern DLSYM_PROTOTYPE(curl_multi_add_handle);
+extern DLSYM_PROTOTYPE(curl_multi_assign);
+extern DLSYM_PROTOTYPE(curl_multi_cleanup);
+extern DLSYM_PROTOTYPE(curl_multi_info_read);
+extern DLSYM_PROTOTYPE(curl_multi_init);
+extern DLSYM_PROTOTYPE(curl_multi_remove_handle);
+extern DLSYM_PROTOTYPE(curl_multi_setopt);
+extern DLSYM_PROTOTYPE(curl_multi_socket_action);
+extern DLSYM_PROTOTYPE(curl_slist_append);
+extern DLSYM_PROTOTYPE(curl_slist_free_all);
+
+int dlopen_curl(void);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(CURL*, curl_easy_cleanup, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(CURLM*, curl_multi_cleanup, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct curl_slist*, curl_slist_free_all, NULL);
+#define easy_setopt(curl, log_level, opt, value) ({ \
+ CURLcode code = sym_curl_easy_setopt(ASSERT_PTR(curl), opt, value); \
+ if (code) \
+ log_full(log_level, \
+ "curl_easy_setopt %s failed: %s", \
+ #opt, sym_curl_easy_strerror(code)); \
+ code == CURLE_OK; \
+})
typedef struct CurlGlue CurlGlue;
int curl_header_strdup(const void *contents, size_t sz, const char *field, char **value);
int curl_parse_http_time(const char *t, usec_t *ret);
int curl_append_to_header(struct curl_slist **list, char **headers);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(CURL*, sym_curl_easy_cleanup, curl_easy_cleanupp, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(CURLM*, sym_curl_multi_cleanup, curl_multi_cleanupp, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct curl_slist*, sym_curl_slist_free_all, curl_slist_free_allp, NULL);
+
+#else
+
+static inline int dlopen_curl(void) {
+ return -EOPNOTSUPP;
+}
+
+#endif
'cryptsetup-fido2.c',
'cryptsetup-tpm2.c',
'cryptsetup-util.c',
+ 'curl-util.c',
'daemon-util.c',
'data-fd-util.c',
'dev-setup.c',
libbpf_cflags,
libcrypt_cflags,
libcryptsetup_cflags,
+ libcurl_cflags,
libdl,
libdw_cflags,
libelf_cflags,
userspace],
c_args : ['-fvisibility=default'],
build_by_default : false)
-
-# A small shared file that is linked into a few places.
-# It is not part of libshared because this code needs libcurl and
-# we don't want to link libshared to libcurl.
-if conf.get('HAVE_LIBCURL') == 1
- libcurlutil_static = static_library(
- 'curl-util',
- 'curl-util.c',
- implicit_include_directories : false,
- dependencies : [userspace, libcurl],
- include_directories : includes,
- build_by_default : false)
-else
- libcurlutil_static = []
-endif
#include "bpf-dlopen.h"
#include "compress.h"
#include "cryptsetup-util.h"
+#include "curl-util.h"
#include "elf-util.h"
#include "gcrypt-util.h"
#include "idn-util.h"
ASSERT_DLOPEN(dlopen_bzip2, HAVE_BZIP2);
ASSERT_DLOPEN(dlopen_bpf, HAVE_LIBBPF);
ASSERT_DLOPEN(dlopen_cryptsetup, HAVE_LIBCRYPTSETUP);
+ ASSERT_DLOPEN(dlopen_curl, HAVE_LIBCURL);
ASSERT_DLOPEN(dlopen_dw, HAVE_ELFUTILS);
ASSERT_DLOPEN(dlopen_elf, HAVE_ELFUTILS);
ASSERT_DLOPEN(dlopen_gcrypt, HAVE_GCRYPT);