diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2011-09-01 12:11:13 +0300 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2011-09-01 12:11:13 +0300 |
commit | 3a309d8f1ba80d1b2f1859d188c6639e0d81696b (patch) | |
tree | 577435f3850d88eb7252a6af3da430001f4d21aa /lib | |
parent | 172af97d77fc5a3f3dd265b65c96e3d66bf47adb (diff) | |
download | rpm-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.h | 3 | ||||
-rw-r--r-- | lib/tagexts.c | 61 | ||||
-rw-r--r-- | lib/tagname.c | 5 |
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); |