[Rpm-maint] [PATCH] Add API to add arbitrary tags to headers saved to rpmdb

Aleksei Nikiforov darktemplar at altlinux.org
Fri Apr 13 07:49:20 UTC 2018


---
 lib/depends.c        | 23 +++++++++++++++++------
 lib/rpmte.c          | 28 +++++++++++++++++++++++++---
 lib/rpmte_internal.h |  3 ++-
 lib/rpmts.h          | 30 ++++++++++++++++++++++++++++++
 lib/verify.c         |  2 +-
 5 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/lib/depends.c b/lib/depends.c
index fc413a9..60282d0 100644
--- a/lib/depends.c
+++ b/lib/depends.c
@@ -123,7 +123,7 @@ static int removePackage(rpmts ts, Header h, rpmte depends)
 	return 0;
     }
 
-    p = rpmteNew(ts, h, TR_REMOVED, NULL, NULL);
+    p = rpmteNew(ts, h, TR_REMOVED, NULL, NULL, NULL);
     if (p == NULL)
 	return 1;
 
@@ -410,7 +410,7 @@ rpmal rpmtsCreateAl(rpmts ts, rpmElementTypes types)
 }
 
 static int addPackage(rpmts ts, Header h,
-		    fnpyKey key, int op, rpmRelocation * relocs)
+		    fnpyKey key, int op, rpmRelocation * relocs, Header tags)
 {
     tsMembers tsmem = rpmtsMembers(ts);
     rpm_color_t tscolor = rpmtsColor(ts);
@@ -435,7 +435,7 @@ static int addPackage(rpmts ts, Header h,
 	    goto exit;
     }
 
-    p = rpmteNew(ts, h, TR_ADDED, key, relocs);
+    p = rpmteNew(ts, h, TR_ADDED, key, relocs, tags);
     if (p == NULL) {
 	ec = 1;
 	goto exit;
@@ -487,19 +487,30 @@ exit:
 int rpmtsAddInstallElement(rpmts ts, Header h,
 			fnpyKey key, int upgrade, rpmRelocation * relocs)
 {
+	return rpmtsAddInstallElementWithTags(ts, h, key, upgrade, relocs, NULL);
+}
+
+int rpmtsAddReinstallElement(rpmts ts, Header h, fnpyKey key)
+{
+	return rpmtsAddReinstallElementWithTags(ts, h, key, NULL);
+}
+
+int rpmtsAddInstallElementWithTags(rpmts ts, Header h,
+	fnpyKey key, int upgrade, rpmRelocation * relocs, Header tags)
+{
     int op = (upgrade == 0) ? RPMTE_INSTALL : RPMTE_UPGRADE;
     if (rpmtsSetupTransactionPlugins(ts) == RPMRC_FAIL)
 	return 1;
-    return addPackage(ts, h, key, op, relocs);
+    return addPackage(ts, h, key, op, relocs, tags);
 }
 
-int rpmtsAddReinstallElement(rpmts ts, Header h, fnpyKey key)
+int rpmtsAddReinstallElementWithTags(rpmts ts, Header h, fnpyKey key, Header tags)
 {
     if (rpmtsSetupTransactionPlugins(ts) == RPMRC_FAIL)
 	return 1;
     /* TODO: pull relocations from installed package */
     /* TODO: should reinstall of non-installed package fail? */
-    return addPackage(ts, h, key, RPMTE_REINSTALL, NULL);
+    return addPackage(ts, h, key, RPMTE_REINSTALL, NULL, tags);
 }
 
 int rpmtsAddEraseElement(rpmts ts, Header h, int dboffset)
diff --git a/lib/rpmte.c b/lib/rpmte.c
index f05c2e2..3ed9f48 100644
--- a/lib/rpmte.c
+++ b/lib/rpmte.c
@@ -77,6 +77,8 @@ struct rpmte_s {
     int transscripts;		/*!< pre/posttrans script existence */
     int failed;			/*!< (parent) install/erase failed */
 
+    Header extra_tags;		/*! extra tags to be saved */
+
     rpmfs fs;
 };
 
@@ -122,8 +124,9 @@ static rpmfiles getFiles(rpmte p, Header h)
  * @param h		header
  * @param key		(TR_ADDED) package retrieval key (e.g. file name)
  * @param relocs	(TR_ADDED) package file relocations
+ * @param tags		additional tags to be saved
  */
-static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
+static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs, Header tags)
 {
     rpmstrPool tspool = rpmtsPool(p->ts);
     struct rpmtd_s bnames;
@@ -197,6 +200,8 @@ static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
     if (p->type == TR_ADDED)
 	p->pkgFileSize = headerGetNumber(h, RPMTAG_LONGSIGSIZE) + 96 + 256;
 
+	p->extra_tags = headerLink(tags);
+
     rc = 0;
 
 exit:
@@ -224,6 +229,7 @@ rpmte rpmteFree(rpmte te)
 	free(te->NEVR);
 	free(te->NEVRA);
 
+	headerFree(te->extra_tags);
 	fdFree(te->fd);
 	rpmfiFree(te->fi);
 	rpmfilesFree(te->files);
@@ -239,13 +245,13 @@ rpmte rpmteFree(rpmte te)
 }
 
 rpmte rpmteNew(rpmts ts, Header h, rpmElementType type, fnpyKey key,
-	       rpmRelocation * relocs)
+	       rpmRelocation * relocs, Header tags)
 {
     rpmte p = xcalloc(1, sizeof(*p));
     p->ts = ts;
     p->type = type;
 
-    if (addTE(p, h, key, relocs)) {
+    if (addTE(p, h, key, relocs, tags)) {
 	rpmteFree(p);
 	return NULL;
     }
@@ -564,6 +570,9 @@ static int rpmteOpen(rpmte te, int reload_fi)
 {
     int rc = 0; /* assume failure */
     Header h = NULL;
+    HeaderIterator h_iter;
+    struct rpmtd_s td;
+
     if (te == NULL || te->ts == NULL || rpmteFailed(te))
 	goto exit;
 
@@ -586,6 +595,19 @@ static int rpmteOpen(rpmte te, int reload_fi)
 	    rc = 1;
 	}
 	
+	if (te->extra_tags != NULL)
+	{
+		h_iter = headerInitIterator(te->extra_tags);
+
+		while (headerNext(h_iter, &td))
+		{
+			headerPut(h, &td, HEADERPUT_DEFAULT);
+			rpmtdFreeData(&td);
+		}
+
+		headerFreeIterator(h_iter);
+	}
+
 	rpmteSetHeader(te, h);
 	headerFree(h);
     }
diff --git a/lib/rpmte_internal.h b/lib/rpmte_internal.h
index 464f476..14bc612 100644
--- a/lib/rpmte_internal.h
+++ b/lib/rpmte_internal.h
@@ -34,11 +34,12 @@ extern "C" {
  * @param type		TR_ADDED/TR_REMOVED
  * @param key		(TR_ADDED) package retrieval key (e.g. file name)
  * @param relocs	(TR_ADDED) package file relocations
+ * @param tags		additional tags to be saved
  * @return		new transaction element
  */
 RPM_GNUC_INTERNAL
 rpmte rpmteNew(rpmts ts, Header h, rpmElementType type, fnpyKey key,
-	       rpmRelocation * relocs);
+	       rpmRelocation * relocs, Header tags);
 
 /** \ingroup rpmte
  * Destroy a transaction element.
diff --git a/lib/rpmts.h b/lib/rpmts.h
index 5231c80..3836f84 100644
--- a/lib/rpmts.h
+++ b/lib/rpmts.h
@@ -572,6 +572,36 @@ int rpmtsAddInstallElement(rpmts ts, Header h,
 int rpmtsAddReinstallElement(rpmts ts, Header h, const fnpyKey key);
 
 /** \ingroup rpmts
+ * Add package to be installed to transaction set.
+ *
+ * The transaction set is checked for duplicate package names.
+ * If found, the package with the "newest" EVR will be replaced.
+ *
+ * @param ts		transaction set
+ * @param h		header
+ * @param key		package retrieval key (e.g. file name)
+ * @param upgrade	is package being upgraded?
+ * @param relocs	package file relocations
+ * @param tags		additional tags to be saved
+ * @return		0 on success, 1 on I/O error, 2 needs capabilities
+ */
+int rpmtsAddInstallElementWithTags(rpmts ts, Header h,
+		const fnpyKey key, int upgrade,
+		rpmRelocation * relocs,
+		Header tags);
+
+/** \ingroup rpmts
+ * Add package to be reinstalled to transaction set.
+ *
+ * @param ts		transaction set
+ * @param h		header
+ * @param key		package retrieval key (e.g. file name)
+ * @param tags		additional tags to be saved
+ * @return		0 on success
+ */
+int rpmtsAddReinstallElementWithTags(rpmts ts, Header h, const fnpyKey key, Header tags);
+
+/** \ingroup rpmts
  * Add package to be erased to transaction set.
  * @param ts		transaction set
  * @param h		header
diff --git a/lib/verify.c b/lib/verify.c
index 1a8ce8d..83f1106 100644
--- a/lib/verify.c
+++ b/lib/verify.c
@@ -297,7 +297,7 @@ static int rpmVerifyScript(rpmts ts, Header h)
 
     if (headerIsEntry(h, RPMTAG_VERIFYSCRIPT)) {
 	/* fake up a erasure transaction element */
-	rpmte p = rpmteNew(ts, h, TR_REMOVED, NULL, NULL);
+	rpmte p = rpmteNew(ts, h, TR_REMOVED, NULL, NULL, NULL);
 
 	if (p != NULL) {
 	    rpmteSetHeader(p, h);
-- 
2.10.5



More information about the Rpm-maint mailing list