From a306cebc96c763aecbe9d8838736034310ab0215 Mon Sep 17 00:00:00 2001
From: Juan RP <xtraeme@gmail.com>
Date: Tue, 22 Feb 2011 11:09:39 +0100
Subject: [PATCH] xbps_set_pkg_state_installed: added two new optional
 arguments: version and pkgver.

This can be used to avoid some rare cases where the pkg dictionary is regpkgdb
is in a state where code can be faulty if those objects are not found.
---
 bin/xbps-uhelper/main.c |  2 +-
 include/xbps_api.h      |  9 +++++++--
 lib/package_configure.c | 11 +++++++++--
 lib/package_remove.c    |  4 +++-
 lib/package_state.c     | 36 ++++++++++++++++++++++++++++--------
 lib/package_unpack.c    |  7 ++++---
 6 files changed, 52 insertions(+), 17 deletions(-)

diff --git a/bin/xbps-uhelper/main.c b/bin/xbps-uhelper/main.c
index 80fc0db9..73cb1a3f 100644
--- a/bin/xbps-uhelper/main.c
+++ b/bin/xbps-uhelper/main.c
@@ -178,7 +178,7 @@ main(int argc, char **argv)
 		prop_dictionary_set_cstring(dict, "pkgver", pkgver);
 		free(pkgver);
 
-		rv = xbps_set_pkg_state_installed(argv[1],
+		rv = xbps_set_pkg_state_installed(argv[1], argv[2], pkgver,
 		    XBPS_PKG_STATE_INSTALLED);
 		if (rv != 0)
 			exit(EXIT_FAILURE);
diff --git a/include/xbps_api.h b/include/xbps_api.h
index acdc4c56..ab085496 100644
--- a/include/xbps_api.h
+++ b/include/xbps_api.h
@@ -53,7 +53,7 @@
  * @def XBPS_RELVER
  * Current library release date.
  */
-#define XBPS_RELVER		"20110221"
+#define XBPS_RELVER		"20110222"
 
 /** 
  * @def XBPS_META_PATH
@@ -1130,11 +1130,16 @@ int xbps_get_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t *state);
  * Sets package state \a state in package \a pkgname.
  *
  * @param[in] pkgname Package name.
+ * @param[in] version Package version (optional).
+ * @param[in] pkgver Package name/version touple (optional).
  * @param[in] state Package state to be set.
  *
  * @return 0 on success, otherwise an errno value.
  */
-int xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state);
+int xbps_set_pkg_state_installed(const char *pkgname,
+				 const char *version,
+				 const char *pkgver,
+				 pkg_state_t state);
 
 /**
  * Sets package state \a state in package dictionary \a dict.
diff --git a/lib/package_configure.c b/lib/package_configure.c
index 6b8b8854..53452223 100644
--- a/lib/package_configure.c
+++ b/lib/package_configure.c
@@ -89,7 +89,7 @@ xbps_configure_pkg(const char *pkgname,
 	const struct xbps_handle *xhp;
 	prop_dictionary_t pkgd;
 	const char *lver;
-	char *buf;
+	char *buf, *pkgver;
 	int rv = 0;
 	pkg_state_t state = 0;
 	bool reconfigure = false;
@@ -147,6 +147,13 @@ xbps_configure_pkg(const char *pkgname,
 		}
 	}
 	free(buf);
+	pkgver = xbps_xasprintf("%s-%s", pkgname, lver);
+	if (pkgver == NULL)
+		return ENOMEM;
 
-	return xbps_set_pkg_state_installed(pkgname, XBPS_PKG_STATE_INSTALLED);
+	rv = xbps_set_pkg_state_installed(pkgname, lver, pkgver,
+	    XBPS_PKG_STATE_INSTALLED);
+	free(pkgver);
+
+	return rv;
 }
diff --git a/lib/package_remove.c b/lib/package_remove.c
index 871d75ed..b1a20b4d 100644
--- a/lib/package_remove.c
+++ b/lib/package_remove.c
@@ -174,6 +174,7 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update)
 {
 	const struct xbps_handle *xhp;
 	prop_dictionary_t dict;
+	const char *pkgver;
 	char *buf;
 	int rv = 0;
 	bool rmfile_exists = false;
@@ -235,6 +236,7 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update)
 		free(buf);
 		return errno;
 	}
+	prop_dictionary_get_cstring_nocopy(dict, "pkgver", &pkgver);
 
 	/* Remove links */
 	if ((rv = xbps_remove_pkg_files(dict, "links")) != 0) {
@@ -278,7 +280,7 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update)
 	/*
 	 * Set package state to "config-files".
 	 */
-	rv = xbps_set_pkg_state_installed(pkgname,
+	rv = xbps_set_pkg_state_installed(pkgname, version, pkgver,
 	     XBPS_PKG_STATE_CONFIG_FILES);
 
 
diff --git a/lib/package_state.c b/lib/package_state.c
index 7925725b..753350a8 100644
--- a/lib/package_state.c
+++ b/lib/package_state.c
@@ -138,8 +138,32 @@ xbps_set_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t state)
 	return set_new_state(dict, state);
 }
 
+static int
+set_pkg_objs(prop_dictionary_t pkgd,
+	     const char *pkgname,
+	     const char *version,
+	     const char *pkgver)
+{
+	if (!prop_dictionary_set_cstring_nocopy(pkgd, "pkgname", pkgname))
+		return EINVAL;
+
+	if (version != NULL)
+		if (!prop_dictionary_set_cstring_nocopy(pkgd,
+		    "version", version))
+			return EINVAL;
+	if (pkgver != NULL)
+		if (!prop_dictionary_set_cstring_nocopy(pkgd,
+		    "pkgver", pkgver))
+			return EINVAL;
+
+	return 0;
+}
+
 int
-xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
+xbps_set_pkg_state_installed(const char *pkgname,
+			     const char *version,
+			     const char *pkgver,
+			     pkg_state_t state)
 {
 	const struct xbps_handle *xhp;
 	prop_dictionary_t dict = NULL, pkgd;
@@ -173,10 +197,7 @@ xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
 			prop_object_release(array);
 			goto out;
 		}
-
-		if (!prop_dictionary_set_cstring_nocopy(pkgd, "pkgname",
-		    pkgname)) {
-			rv = EINVAL;
+		if ((rv = set_pkg_objs(pkgd, pkgname, version, pkgver)) != 0) {
 			prop_object_release(array);
 			prop_object_release(pkgd);
 			goto out;
@@ -209,9 +230,8 @@ xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
 
 			newpkg = true;
 			pkgd = prop_dictionary_create();
-			if (!prop_dictionary_set_cstring_nocopy(pkgd,
-			    "pkgname", pkgname)) {
-				rv = EINVAL;
+			if ((rv = set_pkg_objs(pkgd, pkgname,
+			    version, pkgver)) != 0) {
 				prop_object_release(pkgd);
 				goto out;
 			}
diff --git a/lib/package_unpack.c b/lib/package_unpack.c
index d2865b2d..c289c373 100644
--- a/lib/package_unpack.c
+++ b/lib/package_unpack.c
@@ -463,7 +463,7 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg_repod)
 {
 	const struct xbps_handle *xhp;
 	struct archive *ar;
-	const char *pkgname, *version, *repoloc;
+	const char *pkgname, *version, *repoloc, *pkgver;
 	char *bpkg;
 	int rv = 0;
 
@@ -471,6 +471,7 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg_repod)
 
 	prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname);
 	prop_dictionary_get_cstring_nocopy(pkg_repod, "version", &version);
+	prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &pkgver);
 	prop_dictionary_get_cstring_nocopy(pkg_repod, "repository", &repoloc);
 
 	bpkg = xbps_get_binpkg_repo_uri(pkg_repod, repoloc);
@@ -514,11 +515,11 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg_repod)
 		    bpkg, strerror(rv));
 		goto out;
 	}
-
 	/*
 	 * Set package state to unpacked.
 	 */
-	rv = xbps_set_pkg_state_installed(pkgname, XBPS_PKG_STATE_UNPACKED);
+	rv = xbps_set_pkg_state_installed(pkgname, version, pkgver,
+	    XBPS_PKG_STATE_UNPACKED);
 	if (rv != 0) {
 		xbps_error_printf("failed to set `%s-%s' to unpacked "
 		    "state: %s\n", pkgname, version, strerror(rv));