The aim of this is to alert a user to system/package breaking updates
before they happen and before they approve the sync install. This is
intended primarily for kernel/initscripts/pacman, etc updates when
things could go really wrong and need to be known beforehand. Example
output below.

This adds an alert="" option to the PKGBUILD. This entry is then
stored in the package and then the db with repo-add. On a pacman sync
operation if any has an alert message it will be displayed before
"Proceed with installation"

This is a really basic implementation that I'm sure could be brushed
up, as I've not used C for a while. However the pacman code is very
clean and easy to read, so that made it pretty trivial to add.

There's an example repo with one package "alert" at
http://mess.iphitus.org/alert-test/

The PKGBUILD for the aforementioned package:
http://mess.iphitus.org/alert-test/PKGBUILD

Attached patch is against latest git.

James

# Example output (note: the format is pkgname: message)
iphitus(~/projects/alert/pacman)$ sudo pacman -S alert
resolving dependencies...
looking for inter-conflicts...

Targets (1): alert-1-1

Total Download Size:    0.00 MB
Total Installed Size:   0.00 MB

alert: This package has an alert message. It may contain tacos.
Proceed with installation? [Y/n]
From 4a88852c72f58b29aecdc130d57a68919c9fe49a Mon Sep 17 00:00:00 2001
From: James Rayner <[email protected]>
Date: Mon, 14 Sep 2009 22:10:09 +1000
Subject: [PATCH] Allow package to display a brief message before sync install

The aim of this is to alert a user to system/package breaking updates
before they happen and before they approve the install.

This adds an alert="" option to the PKGBUILD. This entry is then stored
in the package and then the db with repo-add. On a pacman sync operation
if any has an alert message it will be displayed before "Proceed with
installation"
---
 lib/libalpm/alpm.h       |    1 +
 lib/libalpm/be_files.c   |    5 +++++
 lib/libalpm/be_package.c |    2 ++
 lib/libalpm/package.c    |   16 ++++++++++++++++
 lib/libalpm/package.h    |    1 +
 scripts/makepkg.sh.in    |    1 +
 scripts/repo-add.sh.in   |    3 ++-
 src/pacman/sync.c        |    8 ++++++++
 8 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 661df45..469f05a 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -210,6 +210,7 @@ const char *alpm_pkg_get_url(pmpkg_t *pkg);
 time_t alpm_pkg_get_builddate(pmpkg_t *pkg);
 time_t alpm_pkg_get_installdate(pmpkg_t *pkg);
 const char *alpm_pkg_get_packager(pmpkg_t *pkg);
+const char *alpm_pkg_get_alert(pmpkg_t *pkg);
 const char *alpm_pkg_get_md5sum(pmpkg_t *pkg);
 const char *alpm_pkg_get_arch(pmpkg_t *pkg);
 off_t alpm_pkg_get_size(pmpkg_t *pkg);
diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c
index 03a1463..29cdd16 100644
--- a/lib/libalpm/be_files.c
+++ b/lib/libalpm/be_files.c
@@ -517,6 +517,11 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
 					goto error;
 				}
 				STRDUP(info->packager, _alpm_strtrim(line), goto error);
+			} else if(strcmp(line, "%ALERT%") == 0) {
+				if(fgets(line, 512, fp) == NULL) {
+					goto error;
+				}
+				STRDUP(info->alert, _alpm_strtrim(line), goto error);
 			} else if(strcmp(line, "%REASON%") == 0) {
 				if(fgets(line, 512, fp) == NULL) {
 					goto error;
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index fef4b46..3cdd77f 100644
--- a/lib/libalpm/be_package.c
+++ b/lib/libalpm/be_package.c
@@ -94,6 +94,8 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg)
 				}
 			} else if(!strcmp(key, "packager")) {
 				STRDUP(newpkg->packager, ptr, RET_ERR(PM_ERR_MEMORY, -1));
+			} else if(!strcmp(key, "alert")) {
+				STRDUP(newpkg->alert, ptr, RET_ERR(PM_ERR_MEMORY, -1));
 			} else if(!strcmp(key, "arch")) {
 				STRDUP(newpkg->arch, ptr, RET_ERR(PM_ERR_MEMORY, -1));
 			} else if(!strcmp(key, "size")) {
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index de17166..661b256 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -197,6 +197,20 @@ const char SYMEXPORT *alpm_pkg_get_packager(pmpkg_t *pkg)
 	return pkg->packager;
 }
 
+const char SYMEXPORT *alpm_pkg_get_alert(pmpkg_t *pkg)
+{
+	ALPM_LOG_FUNC;
+
+	/* Sanity checks */
+	ASSERT(handle != NULL, return(NULL));
+	ASSERT(pkg != NULL, return(NULL));
+
+	if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
+		_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
+	}
+	return pkg->alert;
+}
+
 const char SYMEXPORT *alpm_pkg_get_md5sum(pmpkg_t *pkg)
 {
 	ALPM_LOG_FUNC;
@@ -781,6 +795,7 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)
 	newpkg->builddate = pkg->builddate;
 	newpkg->installdate = pkg->installdate;
 	STRDUP(newpkg->packager, pkg->packager, RET_ERR(PM_ERR_MEMORY, newpkg));
+	STRDUP(newpkg->alert, pkg->alert, RET_ERR(PM_ERR_MEMORY, newpkg));
 	STRDUP(newpkg->md5sum, pkg->md5sum, RET_ERR(PM_ERR_MEMORY, newpkg));
 	STRDUP(newpkg->arch, pkg->arch, RET_ERR(PM_ERR_MEMORY, newpkg));
 	newpkg->size = pkg->size;
@@ -830,6 +845,7 @@ void _alpm_pkg_free(pmpkg_t *pkg)
 	FREE(pkg->packager);
 	FREE(pkg->md5sum);
 	FREE(pkg->arch);
+	FREE(pkg->alert);
 	FREELIST(pkg->licenses);
 	FREELIST(pkg->replaces);
 	FREELIST(pkg->groups);
diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
index aea3f39..13defe6 100644
--- a/lib/libalpm/package.h
+++ b/lib/libalpm/package.h
@@ -46,6 +46,7 @@ struct __pmpkg_t {
 	char *packager;
 	char *md5sum;
 	char *arch;
+	char *alert;
 	off_t size;
 	off_t isize;
 	off_t download_size;
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 3e918e6..fd832d5 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -898,6 +898,7 @@ write_pkginfo() {
 	echo "builddate = $builddate" >>.PKGINFO
 	echo "packager = $packager" >>.PKGINFO
 	echo "size = $size" >>.PKGINFO
+	echo "alert = $alert" >>.PKGINFO
 	if [ -n "$CARCH" ]; then
 		echo "arch = $CARCH" >>.PKGINFO
 	fi
diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in
index a1e5f7f..f97f1ff 100644
--- a/scripts/repo-add.sh.in
+++ b/scripts/repo-add.sh.in
@@ -183,7 +183,7 @@ db_write_entry()
 {
 	# blank out all variables
 	local pkgfile="$1"
-	local pkgname pkgver pkgdesc csize size md5sum url arch builddate packager force \
+	local pkgname pkgver pkgdesc csize size md5sum url alert arch builddate packager force \
 		_groups _licenses _replaces _depends _conflicts _provides _optdepends
 
 	local OLDIFS="$IFS"
@@ -258,6 +258,7 @@ db_write_entry()
 	[ -n "$arch" ] && echo -e "%ARCH%\n$arch\n" >>desc
 	[ -n "$builddate" ] && echo -e "%BUILDDATE%\n$builddate\n" >>desc
 	[ -n "$packager" ] && echo -e "%PACKAGER%\n$packager\n" >>desc
+	[ -n "$alert" ] && echo -e "%ALERT%\n$alert\n" >>desc
 	write_list_entry "REPLACES" "$_replaces" "desc"
 	[ -n "$force" ] && echo -e "%FORCE%\n" >>desc
 
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index 180fbb4..9b35907 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -715,6 +715,14 @@ static int sync_trans(alpm_list_t *targets)
 	display_targets(alpm_trans_get_add(), 1);
 	printf("\n");
 
+	for(i = packages; i; i = alpm_list_next(i)) {
+		pmpkg_t *pkg = alpm_list_getdata(i);
+		const char *alert = alpm_pkg_get_alert(pkg);
+		if(alert) {
+			printf("%s: %s\n", alpm_pkg_get_name(pkg), alert);
+		}
+	}
+
 	int confirm;
 	if(config->op_s_downloadonly) {
 		confirm = yesno(_("Proceed with download?"));
-- 
1.6.4.1



Reply via email to