From 00f1a6e0b1805c2c0f9ff314aabce8f9ca209f4c Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Fri, 28 May 2010 12:21:34 +0300 Subject: Add header extension tag RPMTAG_FILESTATUS for file verification - Permits basic file verification with just a headerGet(), with some caveats: there's no way to control which attributes get verified, and there's no filtering of mtime differences of shared files. Those aside, rpm -q --qf "[%{filestates:vflags} %{filenames}\n] " now performs the same as "rpm -V --nodeps --noscripts " --- doc/rpm.8 | 3 +++ lib/formats.c | 15 +++++++++++++-- lib/rpmtag.h | 1 + lib/rpmtd.h | 1 + lib/tagexts.c | 23 +++++++++++++++++++++++ tests/rpmgeneral.at | 1 + 6 files changed, 42 insertions(+), 2 deletions(-) diff --git a/doc/rpm.8 b/doc/rpm.8 index 47c7ee7f1..d93b9c692 100644 --- a/doc/rpm.8 +++ b/doc/rpm.8 @@ -478,6 +478,9 @@ Format file flags. \fB:fstate\fR Format file state. .TP +\fB:fstatus\fR +Format file verify status. +.TP \fB:hex\fR Format in hexadecimal. .TP diff --git a/lib/formats.c b/lib/formats.c index be8a83c05..3fff34f53 100644 --- a/lib/formats.c +++ b/lib/formats.c @@ -636,7 +636,7 @@ static char * fstateFormat(rpmtd td, char * formatPrefix) return val; } -static char * vflagsFormat(rpmtd td, char * formatPrefix) +static char * verifyFlags(rpmtd td, char * formatPrefix, const char *pad) { char * val = NULL; @@ -644,13 +644,23 @@ static char * vflagsFormat(rpmtd td, char * formatPrefix) val = xstrdup(_("(not a number)")); } else { strcat(formatPrefix, "s"); - char *buf = rpmVerifyString(rpmtdGetNumber(td), ""); + char *buf = rpmVerifyString(rpmtdGetNumber(td), pad); rasprintf(&val, formatPrefix, buf); buf = _free(buf); } return val; } +static char * vflagsFormat(rpmtd td, char * formatPrefix) +{ + return verifyFlags(td, formatPrefix, ""); +} + +static char * fstatusFormat(rpmtd td, char * formatPrefix) +{ + return verifyFlags(td, formatPrefix, "."); +} + static char * expandFormat(rpmtd td, char * formatPrefix) { char *val = NULL; @@ -712,5 +722,6 @@ static const struct headerFormatFunc_s rpmHeaderFormats[] = { { RPMTD_FORMAT_FSTATE, "fstate", fstateFormat }, { RPMTD_FORMAT_VFLAGS, "vflags", vflagsFormat }, { RPMTD_FORMAT_EXPAND, "expand", expandFormat }, + { RPMTD_FORMAT_FSTATUS, "fstatus", fstatusFormat }, { -1, NULL, NULL } }; diff --git a/lib/rpmtag.h b/lib/rpmtag.h index 5ea483365..6fd4b0f37 100644 --- a/lib/rpmtag.h +++ b/lib/rpmtag.h @@ -293,6 +293,7 @@ typedef enum rpmTag_e { RPMTAG_POSTTRANSFLAGS = 5025, /* i */ RPMTAG_VERIFYSCRIPTFLAGS = 5026, /* i */ RPMTAG_TRIGGERSCRIPTFLAGS = 5027, /* i[] */ + RPMTAG_FILESTATUS = 5028, /* i[] extension */ RPMTAG_FIRSTFREE_TAG /*!< internal */ } rpmTag; diff --git a/lib/rpmtd.h b/lib/rpmtd.h index 879af264a..d02287f1f 100644 --- a/lib/rpmtd.h +++ b/lib/rpmtd.h @@ -217,6 +217,7 @@ typedef enum rpmtdFormats_e { RPMTD_FORMAT_FSTATE = 16, /* file states (int types) */ RPMTD_FORMAT_VFLAGS = 17, /* file verify flags (int types) */ RPMTD_FORMAT_EXPAND = 18, /* macro expansion (string types) */ + RPMTD_FORMAT_FSTATUS = 19, /* file verify status (int types) */ } rpmtdFormats; /** \ingroup rpmtd diff --git a/lib/tagexts.c b/lib/tagexts.c index bdd2e57d6..22e2c7ed7 100644 --- a/lib/tagexts.c +++ b/lib/tagexts.c @@ -693,6 +693,28 @@ static int epochnumTag(Header h, rpmtd td, headerGetFlags hgflags) return 1; } +static int filestatusTag(Header h, rpmtd td, headerGetFlags hgflags) +{ + rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, RPMFI_FLAGS_VERIFY); + int fc = rpmfiFC(fi); + uint32_t *stats = (fc > 0) ? xcalloc(fc, sizeof(*stats)) : NULL; + int ix; + + while ((ix = rpmfiNext(fi)) >= 0) { + rpmVerifyAttrs verifyResult = 0; + (void) rpmVerifyFile(NULL, fi, &verifyResult, RPMVERIFY_NONE); + stats[ix] = verifyResult; + } + rpmfiFree(fi); + + td->type = RPM_INT32_TYPE; + td->count = fc; + td->data = stats; + td->flags = RPMTD_ALLOCED; + + return (fc > 0); +} + void *rpmHeaderTagFunc(rpmTag tag) { const struct headerTagFunc_s * ext; @@ -732,6 +754,7 @@ static const struct headerTagFunc_s rpmHeaderTagExtensions[] = { { RPMTAG_HEADERCOLOR, headercolorTag }, { RPMTAG_VERBOSE, verboseTag }, { RPMTAG_EPOCHNUM, epochnumTag }, + { RPMTAG_FILESTATUS, filestatusTag }, { 0, NULL } }; diff --git a/tests/rpmgeneral.at b/tests/rpmgeneral.at index 59322f50d..86e4537d3 100644 --- a/tests/rpmgeneral.at +++ b/tests/rpmgeneral.at @@ -125,6 +125,7 @@ FILERDEVS FILEREQUIRE FILESIZES FILESTATES +FILESTATUS FILEUSERNAME FILEVERIFYFLAGS FSCONTEXTS -- cgit v1.2.3