summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2011-09-01 12:11:13 +0300
committerPanu Matilainen <pmatilai@redhat.com>2011-09-01 12:11:13 +0300
commit3a309d8f1ba80d1b2f1859d188c6639e0d81696b (patch)
tree577435f3850d88eb7252a6af3da430001f4d21aa /lib
parent172af97d77fc5a3f3dd265b65c96e3d66bf47adb (diff)
downloadrpm-3a309d8f1ba80d1b2f1859d188c6639e0d81696b.tar.gz
rpm-3a309d8f1ba80d1b2f1859d188c6639e0d81696b.tar.bz2
rpm-3a309d8f1ba80d1b2f1859d188c6639e0d81696b.zip
Add RPMTAG_INSTFILENAMES tag extension for state-aware file lists
- For a more consistent experience wrt all the state-awareness stuff, this needs to be easily querifiable too. - Also makes the tagnames kludgery from commit cac8c389607d7a5735b2905035fdfe4404670d06 unnecessary
Diffstat (limited to 'lib')
-rw-r--r--lib/rpmtag.h3
-rw-r--r--lib/tagexts.c61
-rw-r--r--lib/tagname.c5
3 files changed, 48 insertions, 21 deletions
diff --git a/lib/rpmtag.h b/lib/rpmtag.h
index 775d41429..e9878c109 100644
--- a/lib/rpmtag.h
+++ b/lib/rpmtag.h
@@ -301,6 +301,7 @@ typedef enum rpmTag_e {
RPMTAG_ORDERFLAGS = 5037, /* i[] */
RPMTAG_MSSFMANIFEST = 5038, /* s[] reservation (unimplemented) */
RPMTAG_MSSFDOMAIN = 5039, /* s[] reservation (unimplemented) */
+ RPMTAG_INSTFILENAMES = 5040, /* s[] extension */
RPMTAG_FIRSTFREE_TAG /*!< internal */
} rpmTag;
@@ -313,7 +314,6 @@ typedef enum rpmTag_e {
typedef enum rpmDbiTag_e {
RPMDBI_PACKAGES = 0, /* Installed package headers. */
RPMDBI_LABEL = 2, /* NEVRA label pseudo index */
- RPMDBI_INSTFILENAMES = 32, /* Files with inst. state pseudo idx */
RPMDBI_NAME = RPMTAG_NAME,
RPMDBI_BASENAMES = RPMTAG_BASENAMES,
RPMDBI_GROUP = RPMTAG_GROUP,
@@ -326,6 +326,7 @@ typedef enum rpmDbiTag_e {
RPMDBI_INSTALLTID = RPMTAG_INSTALLTID,
RPMDBI_SIGMD5 = RPMTAG_SIGMD5,
RPMDBI_SHA1HEADER = RPMTAG_SHA1HEADER,
+ RPMDBI_INSTFILENAMES = RPMTAG_INSTFILENAMES,
} rpmDbiTag;
/** \ingroup signature
diff --git a/lib/tagexts.c b/lib/tagexts.c
index 4dc6e7576..d316396ff 100644
--- a/lib/tagexts.c
+++ b/lib/tagexts.c
@@ -36,18 +36,18 @@ struct headerTagFunc_s {
* @retval *fnp array of file names
* @retval *fcp number of files
*/
-static void rpmfiBuildFNames(Header h, rpmTag tagN,
+static void rpmfiBuildFNames(Header h, rpmTag tagN, int withstate,
const char *** fnp, rpm_count_t * fcp)
{
- const char **baseNames, **dirNames, **fileNames;
+ const char **baseNames, **dirNames, **fileNames, *fileStates;
uint32_t *dirIndexes;
- rpm_count_t count;
- size_t size;
+ rpm_count_t count, retcount;
+ size_t size = 0;
rpmTag dirNameTag = RPMTAG_DIRNAMES;
rpmTag dirIndexesTag = RPMTAG_DIRINDEXES;
char * t;
- int i;
- struct rpmtd_s bnames, dnames, dixs;
+ int i, j;
+ struct rpmtd_s bnames, dnames, dixs, fstates;
if (tagN == RPMTAG_ORIGBASENAMES) {
dirNameTag = RPMTAG_ORIGDIRNAMES;
@@ -62,33 +62,47 @@ static void rpmfiBuildFNames(Header h, rpmTag tagN,
(void) headerGet(h, dirNameTag, &dnames, HEADERGET_MINMEM);
(void) headerGet(h, dirIndexesTag, &dixs, HEADERGET_MINMEM);
- count = rpmtdCount(&bnames);
+ retcount = count = rpmtdCount(&bnames);
baseNames = bnames.data;
dirNames = dnames.data;
dirIndexes = dixs.data;
+ if (withstate) {
+ headerGet(h, RPMTAG_FILESTATES, &fstates, HEADERGET_MINMEM);
+ fileStates = fstates.data;
+ }
+
/*
* fsm, psm and rpmfi assume the data is stored in a single allocation
* block, until those assumptions are removed we need to jump through
* a few hoops here and precalculate sizes etc
*/
- size = sizeof(*fileNames) * count;
- for (i = 0; i < count; i++)
+ for (i = 0; i < count; i++) {
+ if (withstate && !RPMFILE_IS_INSTALLED(fileStates[i])) {
+ retcount--;
+ continue;
+ }
size += strlen(baseNames[i]) + strlen(dirNames[dirIndexes[i]]) + 1;
+ }
+ size += sizeof(*fileNames) * retcount;
fileNames = xmalloc(size);
- t = ((char *) fileNames) + (sizeof(*fileNames) * count);
- for (i = 0; i < count; i++) {
- fileNames[i] = t;
+ t = ((char *) fileNames) + (sizeof(*fileNames) * retcount);
+ for (i = 0, j = 0; i < count; i++) {
+ if (withstate && !RPMFILE_IS_INSTALLED(fileStates[i]))
+ continue;
+ fileNames[j++] = t;
t = stpcpy( stpcpy(t, dirNames[dirIndexes[i]]), baseNames[i]);
*t++ = '\0';
}
rpmtdFreeData(&bnames);
rpmtdFreeData(&dnames);
rpmtdFreeData(&dixs);
+ if (withstate)
+ rpmtdFreeData(&fstates);
*fnp = fileNames;
- *fcp = count;
+ *fcp = retcount;
}
static int filedepTag(Header h, rpmTag tagN, rpmtd td, headerGetFlags hgflags)
@@ -274,6 +288,22 @@ static int triggertypeTag(Header h, rpmtd td, headerGetFlags hgflags)
}
/**
+ * Retrieve installed file paths.
+ * @param h header
+ * @retval td tag data container
+ * @return 1 on success
+ */
+static int instfilenamesTag(Header h, rpmtd td, headerGetFlags hgflags)
+{
+ rpmfiBuildFNames(h, RPMTAG_BASENAMES, 1,
+ (const char ***) &(td->data), &(td->count));
+ if (td->data) {
+ td->type = RPM_STRING_ARRAY_TYPE;
+ td->flags = RPMTD_ALLOCED;
+ }
+ return (td->data != NULL);
+}
+/**
* Retrieve file paths.
* @param h header
* @retval td tag data container
@@ -281,7 +311,7 @@ static int triggertypeTag(Header h, rpmtd td, headerGetFlags hgflags)
*/
static int filenamesTag(Header h, rpmtd td, headerGetFlags hgflags)
{
- rpmfiBuildFNames(h, RPMTAG_BASENAMES,
+ rpmfiBuildFNames(h, RPMTAG_BASENAMES, 0,
(const char ***) &(td->data), &(td->count));
if (td->data) {
td->type = RPM_STRING_ARRAY_TYPE;
@@ -298,7 +328,7 @@ static int filenamesTag(Header h, rpmtd td, headerGetFlags hgflags)
*/
static int origfilenamesTag(Header h, rpmtd td, headerGetFlags hgflags)
{
- rpmfiBuildFNames(h, RPMTAG_ORIGBASENAMES,
+ rpmfiBuildFNames(h, RPMTAG_ORIGBASENAMES, 0,
(const char ***) &(td->data), &(td->count));
if (td->data) {
td->type = RPM_STRING_ARRAY_TYPE;
@@ -720,6 +750,7 @@ static const struct headerTagFunc_s rpmHeaderTagExtensions[] = {
{ RPMTAG_HEADERCOLOR, headercolorTag },
{ RPMTAG_VERBOSE, verboseTag },
{ RPMTAG_EPOCHNUM, epochnumTag },
+ { RPMTAG_INSTFILENAMES, instfilenamesTag },
{ 0, NULL }
};
diff --git a/lib/tagname.c b/lib/tagname.c
index abcae1c0c..0c2696803 100644
--- a/lib/tagname.c
+++ b/lib/tagname.c
@@ -129,9 +129,6 @@ static const char * _tagName(rpmTagVal tag)
case RPMDBI_PACKAGES:
name = "Packages";
break;
- case RPMDBI_INSTFILENAMES:
- name = "Instfilenames";
- break;
/* XXX make sure rpmdb indices are identically named. */
case RPMTAG_CONFLICTS:
name = "Conflictname";
@@ -212,8 +209,6 @@ static rpmTagVal _tagValue(const char * tagstr)
if (!rstrcasecmp(tagstr, "Packages"))
return RPMDBI_PACKAGES;
- if (!rstrcasecmp(tagstr, "Instfilenames"))
- return RPMDBI_INSTFILENAMES;
if (_rpmTags.byName == NULL)
tagLoadIndex(&_rpmTags.byName, &_rpmTags.byNameSize, tagCmpName);