[pacman-dev] [PATCH 2/3] Check package arch before installing

Xavier Chantry shiningxc at gmail.com
Wed Aug 19 16:23:45 EDT 2009


This implements FS#15622

Signed-off-by: Xavier Chantry <shiningxc at gmail.com>
---
 lib/libalpm/alpm.h          |    1 +
 lib/libalpm/error.c         |    2 ++
 lib/libalpm/trans.c         |   33 +++++++++++++++++++++++++++++++++
 pactest/tests/upgrade080.py |   16 ++++++++++++++++
 pactest/tests/upgrade081.py |   16 ++++++++++++++++
 pactest/tests/upgrade082.py |   19 +++++++++++++++++++
 pactest/tests/upgrade083.py |   19 +++++++++++++++++++
 src/pacman/remove.c         |    6 ++++++
 src/pacman/sync.c           |    6 ++++++
 src/pacman/upgrade.c        |    6 ++++++
 10 files changed, 124 insertions(+), 0 deletions(-)
 create mode 100644 pactest/tests/upgrade080.py
 create mode 100644 pactest/tests/upgrade081.py
 create mode 100644 pactest/tests/upgrade082.py
 create mode 100644 pactest/tests/upgrade083.py

diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index b81b3f8..1a83f72 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -510,6 +510,7 @@ enum _pmerrno_t {
 	PM_ERR_PKG_OPEN,
 	PM_ERR_PKG_CANT_REMOVE,
 	PM_ERR_PKG_INVALID_NAME,
+	PM_ERR_PKG_INVALID_ARCH,
 	PM_ERR_PKG_REPO_NOT_FOUND,
 	/* Deltas */
 	PM_ERR_DLT_INVALID,
diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c
index 81aaa8b..6ff1d67 100644
--- a/lib/libalpm/error.c
+++ b/lib/libalpm/error.c
@@ -117,6 +117,8 @@ const char SYMEXPORT *alpm_strerror(int err)
 			return _("cannot remove all files for package");
 		case PM_ERR_PKG_INVALID_NAME:
 			return _("package filename is not valid");
+		case PM_ERR_PKG_INVALID_ARCH:
+			return _("package architecture is not valid");
 		case PM_ERR_PKG_REPO_NOT_FOUND:
 			return _("no such repository");
 		/* Deltas */
diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c
index 6e847e6..240bf81 100644
--- a/lib/libalpm/trans.c
+++ b/lib/libalpm/trans.c
@@ -317,6 +317,31 @@ int _alpm_trans_addtarget(pmtrans_t *trans, char *target)
 	return(0);
 }
 
+static alpm_list_t *check_arch(alpm_list_t *pkgs)
+{
+	alpm_list_t *i;
+	alpm_list_t *invalid = NULL;
+
+	const char *arch = alpm_option_get_arch();
+	if(!arch) {
+		return(NULL);
+	}
+	for(i = pkgs; i; i = i->next) {
+		pmpkg_t *pkg = i->data;
+		const char *pkgarch = alpm_pkg_get_arch(pkg);
+		if(strcmp(pkgarch,arch) && strcmp(pkgarch,"any")) {
+			char *string;
+			const char *pkgname = alpm_pkg_get_name(pkg);
+			const char *pkgver = alpm_pkg_get_version(pkg);
+			size_t len = strlen(pkgname) + strlen(pkgver) + strlen(pkgarch) + 3;
+			MALLOC(string, len, RET_ERR(PM_ERR_MEMORY, invalid));
+			sprintf(string, "%s-%s-%s", pkgname, pkgver, pkgarch);
+			invalid = alpm_list_add(invalid, string);
+		}
+	}
+	return(invalid);
+}
+
 int _alpm_trans_prepare(pmtrans_t *trans, alpm_list_t **data)
 {
 	if(data) {
@@ -333,6 +358,14 @@ int _alpm_trans_prepare(pmtrans_t *trans, alpm_list_t **data)
 		return(0);
 	}
 
+	alpm_list_t *invalid = check_arch(trans->packages);
+	if(invalid) {
+		if(data) {
+			*data = invalid;
+		}
+		RET_ERR(PM_ERR_PKG_INVALID_ARCH, -1);
+	}
+
 	switch(trans->type) {
 		case PM_TRANS_TYPE_UPGRADE:
 			if(_alpm_add_prepare(trans, handle->db_local, data) == -1) {
diff --git a/pactest/tests/upgrade080.py b/pactest/tests/upgrade080.py
new file mode 100644
index 0000000..9ddbd70
--- /dev/null
+++ b/pactest/tests/upgrade080.py
@@ -0,0 +1,16 @@
+self.description = "Install a package (correct architecture)"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+           "usr/man/man1/dummy.1"]
+p.arch = 'testarch'
+self.addpkg(p)
+
+self.option["Architecture"] = ['testarch']
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+for f in p.files:
+	self.addrule("FILE_EXIST=%s" % f)
diff --git a/pactest/tests/upgrade081.py b/pactest/tests/upgrade081.py
new file mode 100644
index 0000000..99e2231
--- /dev/null
+++ b/pactest/tests/upgrade081.py
@@ -0,0 +1,16 @@
+self.description = "Install a package (wrong architecture)"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+           "usr/man/man1/dummy.1"]
+p.arch = 'testarch'
+self.addpkg(p)
+
+self.option["Architecture"] = ['nottestarch']
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=dummy")
+for f in p.files:
+	self.addrule("!FILE_EXIST=%s" % f)
diff --git a/pactest/tests/upgrade082.py b/pactest/tests/upgrade082.py
new file mode 100644
index 0000000..0bdbdf7
--- /dev/null
+++ b/pactest/tests/upgrade082.py
@@ -0,0 +1,19 @@
+self.description = "Install a package (correct architecture, auto)"
+
+import os
+machine = os.uname()[4]
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+           "usr/man/man1/dummy.1"]
+p.arch = machine
+self.addpkg(p)
+
+self.option["Architecture"] = ['auto']
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+for f in p.files:
+	self.addrule("FILE_EXIST=%s" % f)
diff --git a/pactest/tests/upgrade083.py b/pactest/tests/upgrade083.py
new file mode 100644
index 0000000..097ae02
--- /dev/null
+++ b/pactest/tests/upgrade083.py
@@ -0,0 +1,19 @@
+self.description = "Install a package (wrong architecture, auto)"
+
+import os
+machine = os.uname()[4]
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+           "usr/man/man1/dummy.1"]
+p.arch = machine + 'wrong'
+self.addpkg(p)
+
+self.option["Architecture"] = ['auto']
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=dummy")
+for f in p.files:
+	self.addrule("!FILE_EXIST=%s" % f)
diff --git a/src/pacman/remove.c b/src/pacman/remove.c
index 0efbd94..b5119fa 100644
--- a/src/pacman/remove.c
+++ b/src/pacman/remove.c
@@ -103,6 +103,12 @@ int pacman_remove(alpm_list_t *targets)
 		pm_fprintf(stderr, PM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
 		        alpm_strerrorlast());
 		switch(pm_errno) {
+			case PM_ERR_PKG_INVALID_ARCH:
+				for(i = data; i; i = alpm_list_next(i)) {
+					char *pkg = alpm_list_getdata(i);
+					printf(_(":: package %s does not have a valid architecture\n"), pkg);
+				}
+				break;
 			case PM_ERR_UNSATISFIED_DEPS:
 				for(i = data; i; i = alpm_list_next(i)) {
 					pmdepmissing_t *miss = alpm_list_getdata(i);
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index dc93621..4f101f9 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -639,6 +639,12 @@ static int sync_trans(alpm_list_t *targets)
 		        alpm_strerrorlast());
 		switch(pm_errno) {
 			alpm_list_t *i;
+			case PM_ERR_PKG_INVALID_ARCH:
+				for(i = data; i; i = alpm_list_next(i)) {
+					char *pkg = alpm_list_getdata(i);
+					printf(_(":: package %s does not have a valid architecture\n"), pkg);
+				}
+				break;
 			case PM_ERR_UNSATISFIED_DEPS:
 				for(i = data; i; i = alpm_list_next(i)) {
 					pmdepmissing_t *miss = alpm_list_getdata(i);
diff --git a/src/pacman/upgrade.c b/src/pacman/upgrade.c
index 1570f95..e769118 100644
--- a/src/pacman/upgrade.c
+++ b/src/pacman/upgrade.c
@@ -87,6 +87,12 @@ int pacman_upgrade(alpm_list_t *targets)
 		pm_fprintf(stderr, PM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
 		        alpm_strerrorlast());
 		switch(pm_errno) {
+			case PM_ERR_PKG_INVALID_ARCH:
+				for(i = data; i; i = alpm_list_next(i)) {
+					char *pkg = alpm_list_getdata(i);
+					printf(_(":: package %s does not have a valid architecture\n"), pkg);
+				}
+				break;
 			case PM_ERR_UNSATISFIED_DEPS:
 				for(i = data; i; i = alpm_list_next(i)) {
 					pmdepmissing_t *miss = alpm_list_getdata(i);
-- 
1.6.4



More information about the pacman-dev mailing list