From 3179db108a83104d9de6d1d607f55f8118e92160 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 21 Apr 2021 22:47:13 +1000 Subject: Add support for multiple 'Architecture' values This allows architecture to be multivalued. On x86-64 machines, this could be something like: Architecture = x86-64-v3 x86-64 We use the first specified Architecture value in mirrorlist $arch variable replacement, as this is backwards-compatible and sane. Original-patch-by: Dan McGee Patch-updated-by: Allan McRae Signed-off-by: Allan McRae --- lib/libalpm/alpm.h | 30 +++++++++++++++++++++--------- lib/libalpm/handle.c | 30 ++++++++++++++++++++++++------ lib/libalpm/handle.h | 2 +- lib/libalpm/trans.c | 21 ++++++++++++++++++--- 4 files changed, 64 insertions(+), 19 deletions(-) (limited to 'lib') diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 833df829..2e99d4d8 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -2016,25 +2016,37 @@ int alpm_option_remove_assumeinstalled(alpm_handle_t *handle, const alpm_depend_ /** @} */ -/** @name Accessors for the configured architecture - * - * libalpm will only install packages that match the configured architecture. - * The architecture does not need to match the physical architecture. - * It can just be treated as a label. +/** @name Accessors to the list of allowed architectures. + * libalpm will only install packages that match one of the configured + * architectures. The architectures do not need to match the physical + architecture. They can just be treated as a label. * @{ */ /** Returns the allowed package architecture. * @param handle the context handle - * @return the configured package architecture + * @return the configured package architectures */ -const char *alpm_option_get_arch(alpm_handle_t *handle); +alpm_list_t *alpm_option_get_architectures(alpm_handle_t *handle); -/** Sets the allowed package architecture. +/** Adds an allowed package architecture. * @param handle the context handle * @param arch the architecture to set */ -int alpm_option_set_arch(alpm_handle_t *handle, const char *arch); +int alpm_option_add_architecture(alpm_handle_t *handle, const char *arch); + +/** Sets the allowed package architecture. + * @param handle the context handle + * @param arches the architecture to set + */ +int alpm_option_set_architectures(alpm_handle_t *handle, alpm_list_t *arches); + +/** Removes an allowed package architecture. + * @param handle the context handle + * @param arch the architecture to remove + */ +int alpm_option_remove_architecture(alpm_handle_t *handle, const char *arch); + /* End of arch accessors */ /** @} */ diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index 7b8cb1da..46224a25 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -77,7 +77,7 @@ void _alpm_handle_free(alpm_handle_t *handle) FREELIST(handle->hookdirs); FREE(handle->logfile); FREE(handle->lockfile); - FREE(handle->arch); + FREELIST(handle->architectures); FREE(handle->gpgdir); FREELIST(handle->noupgrade); FREELIST(handle->noextract); @@ -276,10 +276,10 @@ alpm_list_t SYMEXPORT *alpm_option_get_assumeinstalled(alpm_handle_t *handle) return handle->assumeinstalled; } -const char SYMEXPORT *alpm_option_get_arch(alpm_handle_t *handle) +alpm_list_t SYMEXPORT *alpm_option_get_architectures(alpm_handle_t *handle) { CHECK_HANDLE(handle, return NULL); - return handle->arch; + return handle->architectures; } int SYMEXPORT alpm_option_get_checkspace(alpm_handle_t *handle) @@ -720,11 +720,29 @@ int SYMEXPORT alpm_option_remove_assumeinstalled(alpm_handle_t *handle, const al return 0; } -int SYMEXPORT alpm_option_set_arch(alpm_handle_t *handle, const char *arch) +int SYMEXPORT alpm_option_add_architecture(alpm_handle_t *handle, const char *arch) { + handle->architectures = alpm_list_add(handle->architectures, strdup(arch)); + return 0; +} + +int SYMEXPORT alpm_option_set_architectures(alpm_handle_t *handle, alpm_list_t *arches) +{ + CHECK_HANDLE(handle, return -1); + if(handle->architectures) FREELIST(handle->architectures); + handle->architectures = alpm_list_strdup(arches); + return 0; +} + +int SYMEXPORT alpm_option_remove_architecture(alpm_handle_t *handle, const char *arch) +{ + char *vdata = NULL; CHECK_HANDLE(handle, return -1); - if(handle->arch) FREE(handle->arch); - STRDUP(handle->arch, arch, RET_ERR(handle, ALPM_ERR_MEMORY, -1)); + handle->architectures = alpm_list_remove_str(handle->architectures, arch, &vdata); + if(vdata != NULL) { + FREE(vdata); + return 1; + } return 0; } diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 2d8d0f9e..52dc2125 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -96,7 +96,7 @@ struct __alpm_handle_t { alpm_list_t *assumeinstalled; /* List of virtual packages used to satisfy dependencies */ /* options */ - char *arch; /* Architecture of packages we should allow */ + alpm_list_t *architectures; /* Architectures of packages we should allow */ int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */ int checkspace; /* Check disk space before installing */ char *dbext; /* Sync DB extension */ diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index c6ec7eea..939ab05a 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -71,14 +71,29 @@ static alpm_list_t *check_arch(alpm_handle_t *handle, alpm_list_t *pkgs) alpm_list_t *i; alpm_list_t *invalid = NULL; - const char *arch = handle->arch; - if(!arch) { + if(!handle->architectures) { + _alpm_log(handle, ALPM_LOG_DEBUG, "skipping architecture checks\n"); return NULL; } for(i = pkgs; i; i = i->next) { alpm_pkg_t *pkg = i->data; + alpm_list_t *j; + int found = 0; const char *pkgarch = alpm_pkg_get_arch(pkg); - if(pkgarch && strcmp(pkgarch, arch) && strcmp(pkgarch, "any")) { + + /* always allow non-architecture packages and those marked "any" */ + if(!pkgarch || strcmp(pkgarch, "any") == 0) { + continue; + } + + for(j = handle->architectures; j; j = j->next) { + if(strcmp(pkgarch, j->data) == 0) { + found = 1; + break; + } + } + + if(!found) { char *string; const char *pkgname = pkg->name; const char *pkgver = pkg->version; -- cgit v1.2.3-54-g00ecf