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
cac8c38960
unnecessary
This commit is contained in:
parent
172af97d77
commit
3a309d8f1b
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
@ -273,6 +287,22 @@ static int triggertypeTag(Header h, rpmtd td, headerGetFlags hgflags)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -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 }
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -124,6 +124,7 @@ ICON
|
|||
INSTALLCOLOR
|
||||
INSTALLTID
|
||||
INSTALLTIME
|
||||
INSTFILENAMES
|
||||
INSTPREFIXES
|
||||
LICENSE
|
||||
LONGARCHIVESIZE
|
||||
|
|
Loading…
Reference in New Issue