Add header extension tag RPMTAG_FILESTATUS for file verification
authorPanu Matilainen <pmatilai@redhat.com>
Fri, 28 May 2010 09:21:34 +0000 (12:21 +0300)
committerPanu Matilainen <pmatilai@redhat.com>
Fri, 28 May 2010 09:21:34 +0000 (12:21 +0300)
- 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] <args>" now
  performs the same as "rpm -V --nodeps --noscripts <args>"

doc/rpm.8
lib/formats.c
lib/rpmtag.h
lib/rpmtd.h
lib/tagexts.c
tests/rpmgeneral.at

index 47c7ee7..d93b9c6 100644 (file)
--- 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
index be8a83c..3fff34f 100644 (file)
@@ -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 }
 };
index 5ea4833..6fd4b0f 100644 (file)
@@ -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;
index 879af26..d02287f 100644 (file)
@@ -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
index bdd2e57..22e2c7e 100644 (file)
@@ -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 }
 };
 
index 59322f5..86e4537 100644 (file)
@@ -125,6 +125,7 @@ FILERDEVS
 FILEREQUIRE
 FILESIZES
 FILESTATES
+FILESTATUS
 FILEUSERNAME
 FILEVERIFYFLAGS
 FSCONTEXTS