From 557d769340921920129011fcdc255968f735c02a Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Mon, 9 Oct 2023 14:35:23 -0400 Subject: [PATCH] lib: add ability to template repo urls with {arch} {arch} will be replaced with XBPS_TARGET_ARCH (if set) or XBPS_ARCH --- include/xbps.h.in | 10 ++++++++ lib/initend.c | 9 +++++++ lib/repo.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/include/xbps.h.in b/include/xbps.h.in index 780673b9..71f68a56 100644 --- a/include/xbps.h.in +++ b/include/xbps.h.in @@ -1601,6 +1601,16 @@ bool xbps_repo_store(struct xbps_handle *xhp, const char *url); */ bool xbps_repo_remove(struct xbps_handle *xhp, const char *url); +/** + * Converts \a {arch} in a repository URI to the correct architecture. + * + * @param[in] xhp Pointer to the xbps_handle struct. + * @param[in] url Repository URI to format. + * + * @return The formatted repository URI. + */ +char *xbps_repo_format(struct xbps_handle *xhp, const char *url); + /** * Creates a lock for a local repository to obtain exclusive access (write). * diff --git a/lib/initend.c b/lib/initend.c index 70ee26cb..1c3ea62e 100644 --- a/lib/initend.c +++ b/lib/initend.c @@ -163,6 +163,15 @@ xbps_init(struct xbps_handle *xhp) xhp->flags |= XBPS_FLAG_DISABLE_SYSLOG; } + for (unsigned int i = 0; i < xbps_array_count(xhp->repositories); i++) { + const char *url = NULL; + xbps_array_get_cstring_nocopy(xhp->repositories, i, &url); + xbps_array_set_cstring_nocopy(xhp->repositories, i, xbps_repo_format(xhp, url)); + } + + xbps_dbg_printf("Native architecture is %s\n", xhp->native_arch); + xbps_dbg_printf("Target architecture is %s\n", xhp->target_arch); + if (xhp->flags & XBPS_FLAG_DEBUG) { const char *repodir; for (unsigned int i = 0; i < xbps_array_count(xhp->repositories); i++) { diff --git a/lib/repo.c b/lib/repo.c index 95acd906..724b1c4d 100644 --- a/lib/repo.c +++ b/lib/repo.c @@ -37,6 +37,7 @@ #include #include +#include "xbps/fmt.h" #include "xbps_api_impl.h" /** @@ -193,6 +194,65 @@ repo_open_remote(struct xbps_repo *repo) return rv; } +static int +repo_fmt(FILE *fp, const struct xbps_fmt_var *var, void *data) +{ + struct xbps_handle *xhp = data; + const char *arch; + + if (xhp->target_arch) + arch = xhp->target_arch; + else + arch = xhp->native_arch; + + if (strcmp(var->name, "arch") == 0) { + return xbps_fmt_print_string(var, arch, 0, fp); + } + return 0; +} + +char * +xbps_repo_format(struct xbps_handle *xhp, const char *url) +{ + struct xbps_fmt *fmt = NULL; + FILE *fmt_stream; + char *fmt_buf; + size_t len; + int r; + + assert(xhp); + assert(url); + + if (!strstr(url, "{arch}")) + return strdup(url); + + xbps_dbg_printf("Processing templated repository: %s\n", url); + + fmt_stream = open_memstream(&fmt_buf, &len); + if (!fmt_stream) { + xbps_error_printf("failed to open buffer: %s\n", strerror(errno)); + goto fmtout; + } + fmt = xbps_fmt_parse(url); + if (!fmt) { + xbps_error_printf("failed to parse format for repo '%s': %s\n", url, strerror(errno)); + goto fmtout; + } + r = xbps_fmt(fmt, repo_fmt, xhp, fmt_stream); + if (r < 0) { + xbps_error_printf("failed to format repo '%s': %s\n", url, strerror(-r)); + goto fmtout; + } + fflush(fmt_stream); + return fmt_buf; + +fmtout: + fclose(fmt_stream); + xbps_fmt_free(fmt); + free(fmt_buf); + return NULL; +} + static struct xbps_repo * repo_open_with_type(struct xbps_handle *xhp, const char *url, const char *name) {