Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/lib/libalpm
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2021-04-21 22:47:13 +1000
committerAllan McRae <allan@archlinux.org>2021-04-22 00:15:21 +1000
commit3179db108a83104d9de6d1d607f55f8118e92160 (patch)
tree2141a5a0a565bbfc8261bbc434bcfa53830115a1 /lib/libalpm
parentabdb4d7fa699ae3b8ff09ba79656f6853b9a1357 (diff)
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 <dan@archlinux.org> Patch-updated-by: Allan McRae <allan@archlinux.org> Signed-off-by: Allan McRae <allan@archlinux.org>
Diffstat (limited to 'lib/libalpm')
-rw-r--r--lib/libalpm/alpm.h30
-rw-r--r--lib/libalpm/handle.c30
-rw-r--r--lib/libalpm/handle.h2
-rw-r--r--lib/libalpm/trans.c21
4 files changed, 64 insertions, 19 deletions
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;