#include "system.h"
-#include <rpmcli.h>
+#include <errno.h>
+#if WITH_CAP
+#include <sys/capability.h>
+#endif
+#if WITH_ACL
+#include <acl/libacl.h>
+#endif
-#include "psm.h"
-#include "rpmfi.h"
-#include "rpmts.h"
+#include <rpm/rpmcli.h>
+#include <rpm/header.h>
+#include <rpm/rpmlog.h>
+#include <rpm/rpmfi.h>
+#include <rpm/rpmts.h>
+#include <rpm/rpmdb.h>
+#include <rpm/rpmfileutil.h>
+
+#include "lib/misc.h"
+#include "lib/rpmchroot.h"
+#include "lib/rpmte_internal.h" /* rpmteProcess() */
+#include "lib/rpmug.h"
-#include "legacy.h" /* XXX domd5() */
-#include "ugid.h" /* uidToUname(), gnameToGid */
#include "debug.h"
#define S_ISDEV(m) (S_ISBLK((m)) || S_ISCHR((m)))
-extern int _rpmds_unspecified_epoch_noise;
-
+/* If cap_compare() (Linux extension) not available, do it the hard way */
+#if WITH_CAP && !defined(HAVE_CAP_COMPARE)
+static int cap_compare(cap_t acap, cap_t bcap)
+{
+ int rc = 0;
+ size_t asize = cap_size(acap);
+ size_t bsize = cap_size(bcap);
+
+ if (asize != bsize) {
+ rc = 1;
+ } else {
+ char *abuf = xcalloc(asize, sizeof(*abuf));
+ char *bbuf = xcalloc(bsize, sizeof(*bbuf));
+ cap_copy_ext(abuf, acap, asize);
+ cap_copy_ext(bbuf, bcap, bsize);
+ rc = memcmp(abuf, bbuf, asize);
+ free(abuf);
+ free(bbuf);
+ }
+ return rc;
+}
+#endif
+
int rpmVerifyFile(const rpmts ts, const rpmfi fi,
rpmVerifyAttrs * res, rpmVerifyAttrs omitMask)
{
- unsigned short fmode = rpmfiFMode(fi);
+ rpm_mode_t fmode = rpmfiFMode(fi);
rpmfileAttrs fileAttrs = rpmfiFFlags(fi);
rpmVerifyAttrs flags = rpmfiVFlags(fi);
const char * fn = rpmfiFN(fi);
- const char * rootDir = rpmtsRootDir(ts);
struct stat sb;
int rc;
- /* Prepend the path to root (if specified). */
- if (rootDir && *rootDir != '\0'
- && !(rootDir[0] == '/' && rootDir[1] == '\0'))
- {
- int nb = strlen(fn) + strlen(rootDir) + 1;
- char * tb = alloca(nb);
- char * t;
-
- t = tb;
- *t = '\0';
- t = stpcpy(t, rootDir);
- while (t > tb && t[-1] == '/') {
- --t;
- *t = '\0';
- }
- t = stpcpy(t, fn);
- fn = tb;
- }
-
*res = RPMVERIFY_NONE;
/*
*/
switch (rpmfiFState(fi)) {
case RPMFILE_STATE_NETSHARED:
- case RPMFILE_STATE_REPLACED:
case RPMFILE_STATE_NOTINSTALLED:
- case RPMFILE_STATE_WRONGCOLOR:
return 0;
break;
+ case RPMFILE_STATE_REPLACED:
+ /* For replaced files we can only verify if it exists at all */
+ flags = RPMVERIFY_LSTATFAIL;
+ break;
+ case RPMFILE_STATE_WRONGCOLOR:
+ /*
+ * Files with wrong color are supposed to share some attributes
+ * with the actually installed file - verify what we can.
+ */
+ flags &= ~(RPMVERIFY_FILEDIGEST | RPMVERIFY_FILESIZE |
+ RPMVERIFY_MTIME | RPMVERIFY_RDEV);
+ break;
case RPMFILE_STATE_NORMAL:
+ /* File from a non-installed package, try to verify nevertheless */
+ case RPMFILE_STATE_MISSING:
break;
}
- if (fn == NULL || Lstat(fn, &sb) != 0) {
+ if (fn == NULL || lstat(fn, &sb) != 0) {
*res |= RPMVERIFY_LSTATFAIL;
return 1;
}
- /*
- * Not all attributes of non-regular files can be verified.
- */
- if (S_ISDIR(sb.st_mode))
- flags &= ~(RPMVERIFY_MD5 | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
- RPMVERIFY_LINKTO);
- else if (S_ISLNK(sb.st_mode)) {
- flags &= ~(RPMVERIFY_MD5 | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
- RPMVERIFY_MODE);
-#if CHOWN_FOLLOWS_SYMLINK
- flags &= ~(RPMVERIFY_USER | RPMVERIFY_GROUP);
-#endif
- }
- else if (S_ISFIFO(sb.st_mode))
- flags &= ~(RPMVERIFY_MD5 | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
- RPMVERIFY_LINKTO);
- else if (S_ISCHR(sb.st_mode))
- flags &= ~(RPMVERIFY_MD5 | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
- RPMVERIFY_LINKTO);
- else if (S_ISBLK(sb.st_mode))
- flags &= ~(RPMVERIFY_MD5 | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
- RPMVERIFY_LINKTO);
- else
+ /* Links have no mode, other types have no linkto */
+ if (S_ISLNK(sb.st_mode))
+ flags &= ~(RPMVERIFY_MODE);
+ else
flags &= ~(RPMVERIFY_LINKTO);
- /*
- * Content checks of %ghost files are meaningless.
- */
+ /* Not all attributes of non-regular files can be verified */
+ if (!S_ISREG(sb.st_mode))
+ flags &= ~(RPMVERIFY_FILEDIGEST | RPMVERIFY_FILESIZE |
+ RPMVERIFY_MTIME | RPMVERIFY_CAPS);
+
+ /* Content checks of %ghost files are meaningless. */
if (fileAttrs & RPMFILE_GHOST)
- flags &= ~(RPMVERIFY_MD5 | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
- RPMVERIFY_LINKTO);
+ flags &= ~(RPMVERIFY_FILEDIGEST | RPMVERIFY_FILESIZE |
+ RPMVERIFY_MTIME | RPMVERIFY_LINKTO);
- /*
- * Don't verify any features in omitMask.
- */
+ /* Don't verify any features in omitMask. */
flags &= ~(omitMask | RPMVERIFY_FAILURES);
- if (flags & RPMVERIFY_MD5) {
- unsigned char md5sum[16];
- size_t fsize;
+ if (flags & RPMVERIFY_FILEDIGEST) {
+ const unsigned char *digest;
+ int algo;
+ size_t diglen;
/* XXX If --nomd5, then prelinked library sizes are not corrected. */
- rc = domd5(fn, md5sum, 0, &fsize);
- sb.st_size = fsize;
- if (rc)
- *res |= (RPMVERIFY_READFAIL|RPMVERIFY_MD5);
- else {
- const unsigned char * MD5 = rpmfiMD5(fi);
- if (MD5 == NULL || memcmp(md5sum, MD5, sizeof(md5sum)))
- *res |= RPMVERIFY_MD5;
- }
+ if ((digest = rpmfiFDigest(fi, &algo, &diglen))) {
+ unsigned char fdigest[diglen];
+ rpm_loff_t fsize;
+
+ rc = rpmDoDigest(algo, fn, 0, fdigest, &fsize);
+ sb.st_size = fsize;
+ if (rc) {
+ *res |= (RPMVERIFY_READFAIL|RPMVERIFY_FILEDIGEST);
+ } else if (memcmp(fdigest, digest, diglen)) {
+ *res |= RPMVERIFY_FILEDIGEST;
+ }
+ } else {
+ *res |= RPMVERIFY_FILEDIGEST;
+ }
}
if (flags & RPMVERIFY_LINKTO) {
char linkto[1024+1];
int size = 0;
- if ((size = Readlink(fn, linkto, sizeof(linkto)-1)) == -1)
+ if ((size = readlink(fn, linkto, sizeof(linkto)-1)) == -1)
*res |= (RPMVERIFY_READLINKFAIL|RPMVERIFY_LINKTO);
else {
const char * flink = rpmfiFLink(fi);
linkto[size] = '\0';
- if (flink == NULL || strcmp(linkto, flink))
+ if (flink == NULL || !rstreq(linkto, flink))
*res |= RPMVERIFY_LINKTO;
}
}
}
if (flags & RPMVERIFY_MODE) {
- unsigned short metamode = fmode;
- unsigned short filemode;
+ rpm_mode_t metamode = fmode;
+ rpm_mode_t filemode;
/*
- * Platforms (like AIX) where sizeof(unsigned short) != sizeof(mode_t)
- * need the (unsigned short) cast here.
+ * Platforms (like AIX) where sizeof(rpm_mode_t) != sizeof(mode_t)
+ * need the (rpm_mode_t) cast here.
*/
- filemode = (unsigned short)sb.st_mode;
+ filemode = (rpm_mode_t)sb.st_mode;
/*
* Comparing the type of %ghost files is meaningless, but perms are OK.
if (metamode != filemode)
*res |= RPMVERIFY_MODE;
+
+#if WITH_ACL
+ /*
+ * For now, any non-default acl's on a file is a difference as rpm
+ * cannot have set them.
+ */
+ acl_t facl = acl_get_file(fn, ACL_TYPE_ACCESS);
+ if (facl) {
+ if (acl_equiv_mode(facl, NULL) == 1) {
+ *res |= RPMVERIFY_MODE;
+ }
+ acl_free(facl);
+ }
+#endif
}
if (flags & RPMVERIFY_RDEV) {
{
*res |= RPMVERIFY_RDEV;
} else if (S_ISDEV(fmode) && S_ISDEV(sb.st_mode)) {
- uint_16 st_rdev = (sb.st_rdev & 0xffff);
- uint_16 frdev = (rpmfiFRdev(fi) & 0xffff);
+ rpm_rdev_t st_rdev = (sb.st_rdev & 0xffff);
+ rpm_rdev_t frdev = (rpmfiFRdev(fi) & 0xffff);
if (st_rdev != frdev)
*res |= RPMVERIFY_RDEV;
}
}
- if (flags & RPMVERIFY_MTIME) {
- if (sb.st_mtime != rpmfiFMtime(fi))
- *res |= RPMVERIFY_MTIME;
+#if WITH_CAP
+ if (flags & RPMVERIFY_CAPS) {
+ /*
+ * Empty capability set ("=") is not exactly the same as no
+ * capabilities at all but suffices for now...
+ */
+ cap_t cap, fcap;
+ cap = cap_from_text(rpmfiFCaps(fi));
+ if (!cap) {
+ cap = cap_from_text("=");
+ }
+ fcap = cap_get_file(fn);
+ if (!fcap) {
+ fcap = cap_from_text("=");
+ }
+
+ if (cap_compare(cap, fcap) != 0)
+ *res |= RPMVERIFY_CAPS;
+
+ cap_free(fcap);
+ cap_free(cap);
+ }
+#endif
+
+ if ((flags & RPMVERIFY_MTIME) && (sb.st_mtime != rpmfiFMtime(fi))) {
+ *res |= RPMVERIFY_MTIME;
}
if (flags & RPMVERIFY_USER) {
- const char * name = uidToUname(sb.st_uid);
+ const char * name = rpmugUname(sb.st_uid);
const char * fuser = rpmfiFUser(fi);
- if (name == NULL || fuser == NULL || strcmp(name, fuser))
+ if (name == NULL || fuser == NULL || !rstreq(name, fuser))
*res |= RPMVERIFY_USER;
}
if (flags & RPMVERIFY_GROUP) {
- const char * name = gidToGname(sb.st_gid);
+ const char * name = rpmugGname(sb.st_gid);
const char * fgroup = rpmfiFGroup(fi);
- if (name == NULL || fgroup == NULL || strcmp(name, fgroup))
+ if (name == NULL || fgroup == NULL || !rstreq(name, fgroup))
*res |= RPMVERIFY_GROUP;
}
/**
* Return exit code from running verify script from header.
- * @todo malloc/free/refcount handling is fishy here.
- * @param qva parsed query/verify options
* @param ts transaction set
- * @param fi file info set
- * @param scriptFd file handle to use for stderr (or NULL)
+ * @param h header
* @return 0 on success
*/
-static int rpmVerifyScript(QVA_t qva, rpmts ts,
- rpmfi fi, FD_t scriptFd)
+static int rpmVerifyScript(rpmts ts, Header h)
{
- rpmpsm psm = rpmpsmNew(ts, NULL, fi);
int rc = 0;
- if (psm == NULL) /* XXX can't happen */
- return rc;
-
- if (scriptFd != NULL)
- rpmtsSetScriptFd(psm->ts, scriptFd);
+ if (headerIsEntry(h, RPMTAG_VERIFYSCRIPT)) {
+ /* fake up a erasure transaction element */
+ rpmte p = rpmteNew(ts, h, TR_REMOVED, NULL, NULL);
- psm->stepName = "verify";
- psm->scriptTag = RPMTAG_VERIFYSCRIPT;
- psm->progTag = RPMTAG_VERIFYSCRIPTPROG;
- rc = rpmpsmStage(psm, PSM_SCRIPT);
+ if (p != NULL) {
+ rpmteSetHeader(p, h);
- if (scriptFd != NULL)
- rpmtsSetScriptFd(psm->ts, NULL);
+ rc = (rpmpsmRun(ts, p, PKG_VERIFY) != RPMRC_OK);
- psm = rpmpsmFree(psm);
+ /* clean up our fake transaction bits */
+ rpmteFree(p);
+ } else {
+ rc = RPMRC_FAIL;
+ }
+ }
return rc;
}
+#define unknown "?"
+#define _verify(_RPMVERIFY_F, _C, _pad) \
+ ((verifyResult & _RPMVERIFY_F) ? _C : _pad)
+#define _verifylink(_RPMVERIFY_F, _C, _pad) \
+ ((verifyResult & RPMVERIFY_READLINKFAIL) ? unknown : \
+ (verifyResult & _RPMVERIFY_F) ? _C : _pad)
+#define _verifyfile(_RPMVERIFY_F, _C, _pad) \
+ ((verifyResult & RPMVERIFY_READFAIL) ? unknown : \
+ (verifyResult & _RPMVERIFY_F) ? _C : _pad)
+char * rpmVerifyString(uint32_t verifyResult, const char *pad)
+{
+ char *fmt = NULL;
+ rasprintf(&fmt, "%s%s%s%s%s%s%s%s%s",
+ _verify(RPMVERIFY_FILESIZE, "S", pad),
+ _verify(RPMVERIFY_MODE, "M", pad),
+ _verifyfile(RPMVERIFY_FILEDIGEST, "5", pad),
+ _verify(RPMVERIFY_RDEV, "D", pad),
+ _verifylink(RPMVERIFY_LINKTO, "L", pad),
+ _verify(RPMVERIFY_USER, "U", pad),
+ _verify(RPMVERIFY_GROUP, "G", pad),
+ _verify(RPMVERIFY_MTIME, "T", pad),
+ _verify(RPMVERIFY_CAPS, "P", pad));
+
+ return fmt;
+}
+#undef _verifyfile
+#undef _verifylink
+#undef _verify
+#undef aok
+#undef unknown
+
+char * rpmFFlagsString(uint32_t fflags, const char *pad)
+{
+ char *fmt = NULL;
+ rasprintf(&fmt, "%s%s%s%s%s%s%s%s",
+ (fflags & RPMFILE_DOC) ? "d" : pad,
+ (fflags & RPMFILE_CONFIG) ? "c" : pad,
+ (fflags & RPMFILE_SPECFILE) ? "s" : pad,
+ (fflags & RPMFILE_MISSINGOK) ? "m" : pad,
+ (fflags & RPMFILE_NOREPLACE) ? "n" : pad,
+ (fflags & RPMFILE_GHOST) ? "g" : pad,
+ (fflags & RPMFILE_LICENSE) ? "l" : pad,
+ (fflags & RPMFILE_README) ? "r" : pad);
+ return fmt;
+}
+
/**
* Check file info from header against what's actually installed.
- * @param qva parsed query/verify options
* @param ts transaction set
- * @param fi file info set
+ * @param h header to verify
+ * @param omitMask bits to disable verify checks
+ * @param ghosts should ghosts be verified?
* @return 0 no problems, 1 problems found
*/
-static int verifyHeader(QVA_t qva, const rpmts ts, rpmfi fi)
+static int verifyHeader(rpmts ts, Header h, rpmVerifyAttrs omitMask, int ghosts)
{
rpmVerifyAttrs verifyResult = 0;
- /* FIX: union? */
- rpmVerifyAttrs omitMask = ((qva->qva_flags & VERIFY_ATTRS) ^ VERIFY_ATTRS);
int ec = 0; /* assume no problems */
- char * t, * te;
- char buf[BUFSIZ];
- int i;
-
- te = t = buf;
- *te = '\0';
-
- fi = rpmfiLink(fi, "verifyHeader");
- fi = rpmfiInit(fi, 0);
- if (fi != NULL) /* XXX lclint */
- while ((i = rpmfiNext(fi)) >= 0) {
- rpmfileAttrs fileAttrs;
- int rc;
+ rpmfi fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_FLAGS_VERIFY);
+
+ if (fi == NULL)
+ return 1;
- fileAttrs = rpmfiFFlags(fi);
+ rpmfiInit(fi, 0);
+ while (rpmfiNext(fi) >= 0) {
+ rpmfileAttrs fileAttrs = rpmfiFFlags(fi);
+ char *buf = NULL, *attrFormat;
+ char ac;
+ int rc;
/* If not verifying %ghost, skip ghost files. */
- if (!(qva->qva_fflags & RPMFILE_GHOST)
- && (fileAttrs & RPMFILE_GHOST))
+ if ((fileAttrs & RPMFILE_GHOST) && !ghosts)
continue;
rc = rpmVerifyFile(ts, fi, &verifyResult, omitMask);
+
+ /* Filter out timestamp differences of shared files */
+ if (rc == 0 && (verifyResult & RPMVERIFY_MTIME)) {
+ rpmdbMatchIterator mi;
+ mi = rpmtsInitIterator(ts, RPMDBI_BASENAMES, rpmfiFN(fi), 0);
+ if (rpmdbGetIteratorCount(mi) > 1)
+ verifyResult &= ~RPMVERIFY_MTIME;
+ rpmdbFreeIterator(mi);
+ }
+
+ attrFormat = rpmFFlagsString(fileAttrs, "");
+ ac = rstreq(attrFormat, "") ? ' ' : attrFormat[0];
if (rc) {
if (!(fileAttrs & (RPMFILE_MISSINGOK|RPMFILE_GHOST)) || rpmIsVerbose()) {
- sprintf(te, _("missing %c %s"),
- ((fileAttrs & RPMFILE_CONFIG) ? 'c' :
- (fileAttrs & RPMFILE_DOC) ? 'd' :
- (fileAttrs & RPMFILE_GHOST) ? 'g' :
- (fileAttrs & RPMFILE_LICENSE) ? 'l' :
- (fileAttrs & RPMFILE_PUBKEY) ? 'P' :
- (fileAttrs & RPMFILE_README) ? 'r' : ' '),
- rpmfiFN(fi));
- te += strlen(te);
+ rasprintf(&buf, _("missing %c %s"), ac, rpmfiFN(fi));
if ((verifyResult & RPMVERIFY_LSTATFAIL) != 0 &&
errno != ENOENT) {
- sprintf(te, " (%s)", strerror(errno));
- te += strlen(te);
+ char *app;
+ rasprintf(&app, " (%s)", strerror(errno));
+ rstrcat(&buf, app);
+ free(app);
}
ec = rc;
}
} else if (verifyResult || rpmIsVerbose()) {
- const char * size, * MD5, * link, * mtime, * mode;
- const char * group, * user, * rdev;
- static const char *const aok = ".";
- static const char *const unknown = "?";
-
- ec = 1;
+ char *verifyFormat = rpmVerifyString(verifyResult, ".");
+ rasprintf(&buf, "%s %c %s", verifyFormat, ac, rpmfiFN(fi));
+ free(verifyFormat);
-#define _verify(_RPMVERIFY_F, _C) \
- ((verifyResult & _RPMVERIFY_F) ? _C : aok)
-#define _verifylink(_RPMVERIFY_F, _C) \
- ((verifyResult & RPMVERIFY_READLINKFAIL) ? unknown : \
- (verifyResult & _RPMVERIFY_F) ? _C : aok)
-#define _verifyfile(_RPMVERIFY_F, _C) \
- ((verifyResult & RPMVERIFY_READFAIL) ? unknown : \
- (verifyResult & _RPMVERIFY_F) ? _C : aok)
-
- MD5 = _verifyfile(RPMVERIFY_MD5, "5");
- size = _verify(RPMVERIFY_FILESIZE, "S");
- link = _verifylink(RPMVERIFY_LINKTO, "L");
- mtime = _verify(RPMVERIFY_MTIME, "T");
- rdev = _verify(RPMVERIFY_RDEV, "D");
- user = _verify(RPMVERIFY_USER, "U");
- group = _verify(RPMVERIFY_GROUP, "G");
- mode = _verify(RPMVERIFY_MODE, "M");
-
-#undef _verifyfile
-#undef _verifylink
-#undef _verify
-
- sprintf(te, "%s%s%s%s%s%s%s%s %c %s",
- size, mode, MD5, rdev, link, user, group, mtime,
- ((fileAttrs & RPMFILE_CONFIG) ? 'c' :
- (fileAttrs & RPMFILE_DOC) ? 'd' :
- (fileAttrs & RPMFILE_GHOST) ? 'g' :
- (fileAttrs & RPMFILE_LICENSE) ? 'l' :
- (fileAttrs & RPMFILE_PUBKEY) ? 'P' :
- (fileAttrs & RPMFILE_README) ? 'r' : ' '),
- rpmfiFN(fi));
- te += strlen(te);
+ if (verifyResult) ec = 1;
}
+ free(attrFormat);
- if (te > t) {
- *te++ = '\n';
- *te = '\0';
- rpmlog(RPMLOG_NOTICE, "%s", t);
- te = t = buf;
- *t = '\0';
+ if (buf) {
+ rpmlog(RPMLOG_NOTICE, "%s\n", buf);
+ buf = _free(buf);
}
}
- fi = rpmfiUnlink(fi, "verifyHeader");
+ rpmfiFree(fi);
return ec;
}
/**
* Check installed package dependencies for problems.
- * @param qva parsed query/verify options
* @param ts transaction set
* @param h header
* @return number of problems found (0 for no problems)
*/
-static int verifyDependencies(QVA_t qva, rpmts ts,
- Header h)
+static int verifyDependencies(rpmts ts, Header h)
{
rpmps ps;
- rpmpsi psi;
- int rc = 0; /* assume no problems */
- int xx;
+ rpmte te;
+ int rc;
rpmtsEmpty(ts);
(void) rpmtsAddInstallElement(ts, h, NULL, 0, NULL);
- xx = rpmtsCheck(ts);
- ps = rpmtsProblems(ts);
-
- psi = rpmpsInitIterator(ps);
- if (rpmpsNumProblems(ps) > 0) {
- char *nevra = hGetNEVRA(h, NULL);
- rpmlog(RPMLOG_NOTICE, "Unsatisfied dependencies for %s:\n", nevra);
- free(nevra);
- while (rpmpsNextIterator(psi) >= 0) {
- rpmProblem p = rpmpsGetProblem(psi);
- rpmlog(RPMLOG_NOTICE, "\t%s\n", rpmProblemString(p));
- rc++;
+ (void) rpmtsCheck(ts);
+ te = rpmtsElement(ts, 0);
+ ps = rpmteProblems(te);
+ rc = rpmpsNumProblems(ps);
+
+ if (rc > 0) {
+ rpmlog(RPMLOG_NOTICE, _("Unsatisfied dependencies for %s:\n"),
+ rpmteNEVRA(te));
+ rpmpsi psi = rpmpsInitIterator(ps);
+ rpmProblem p;
+
+ while ((p = rpmpsiNext(psi)) != NULL) {
+ char * ps = rpmProblemString(p);
+ rpmlog(RPMLOG_NOTICE, "\t%s\n", ps);
+ free(ps);
}
+ rpmpsFreeIterator(psi);
}
- psi = rpmpsFreeIterator(psi);
- ps = rpmpsFree(ps);
-
+ rpmpsFree(ps);
rpmtsEmpty(ts);
return rc;
int showVerifyPackage(QVA_t qva, rpmts ts, Header h)
{
- int scareMem = 1; /* XXX only rpmVerifyScript needs now */
- rpmfi fi;
+ rpmVerifyAttrs omitMask = ((qva->qva_flags & VERIFY_ATTRS) ^ VERIFY_ATTRS);
+ int ghosts = (qva->qva_fflags & RPMFILE_GHOST);
int ec = 0;
int rc;
- fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
- if (fi != NULL) {
-
- if (qva->qva_flags & VERIFY_DEPS) {
- int save_noise = _rpmds_unspecified_epoch_noise;
- if (rpmIsVerbose())
- _rpmds_unspecified_epoch_noise = 1;
- if ((rc = verifyDependencies(qva, ts, h)) != 0)
- ec = rc;
- _rpmds_unspecified_epoch_noise = save_noise;
- }
- if (qva->qva_flags & VERIFY_FILES) {
- if ((rc = verifyHeader(qva, ts, fi)) != 0)
- ec = rc;
- }
- if ((qva->qva_flags & VERIFY_SCRIPT)
- && headerIsEntry(h, RPMTAG_VERIFYSCRIPT))
- {
- FD_t fdo = fdDup(STDOUT_FILENO);
- if ((rc = rpmVerifyScript(qva, ts, fi, fdo)) != 0)
- ec = rc;
- if (fdo != NULL)
- rc = Fclose(fdo);
- }
-
- fi = rpmfiFree(fi);
+ if (qva->qva_flags & VERIFY_DEPS) {
+ if ((rc = verifyDependencies(ts, h)) != 0)
+ ec = rc;
+ }
+ if (qva->qva_flags & VERIFY_FILES) {
+ if ((rc = verifyHeader(ts, h, omitMask, ghosts)) != 0)
+ ec = rc;
+ }
+ if (qva->qva_flags & VERIFY_SCRIPT) {
+ if ((rc = rpmVerifyScript(ts, h)) != 0)
+ ec = rc;
}
return ec;
}
-int rpmcliVerify(rpmts ts, QVA_t qva, const char ** argv)
+int rpmcliVerify(rpmts ts, QVA_t qva, char * const * argv)
{
rpmVSFlags vsflags, ovsflags;
int ec = 0;
+ FD_t scriptFd = fdDup(STDOUT_FILENO);
+
+ /*
+ * Open the DB + indices explicitly before possible chroot,
+ * otherwises BDB is going to be unhappy...
+ */
+ rpmtsOpenDB(ts, O_RDONLY);
+ rpmdbOpenAll(rpmtsGetRdb(ts));
+ if (rpmChrootSet(rpmtsRootDir(ts)) || rpmChrootIn()) {
+ ec = 1;
+ goto exit;
+ }
if (qva->qva_showPackage == NULL)
qva->qva_showPackage = showVerifyPackage;
- /* XXX verify flags are inverted from query. */
vsflags = rpmExpandNumeric("%{?_vsflags_verify}");
- if (!(qva->qva_flags & VERIFY_DIGEST))
+ if (rpmcliQueryFlags & VERIFY_DIGEST)
vsflags |= _RPMVSF_NODIGESTS;
- if (!(qva->qva_flags & VERIFY_SIGNATURE))
+ if (rpmcliQueryFlags & VERIFY_SIGNATURE)
vsflags |= _RPMVSF_NOSIGNATURES;
- if (!(qva->qva_flags & VERIFY_HDRCHK))
+ if (rpmcliQueryFlags & VERIFY_HDRCHK)
vsflags |= RPMVSF_NOHDRCHK;
vsflags &= ~RPMVSF_NEEDPAYLOAD;
+ rpmtsSetScriptFd(ts, scriptFd);
ovsflags = rpmtsSetVSFlags(ts, vsflags);
ec = rpmcliArgIter(ts, qva, argv);
- vsflags = rpmtsSetVSFlags(ts, ovsflags);
+ rpmtsSetVSFlags(ts, ovsflags);
+ rpmtsSetScriptFd(ts, NULL);
if (qva->qva_showPackage == showVerifyPackage)
qva->qva_showPackage = NULL;
rpmtsEmpty(ts);
+ if (rpmChrootOut() || rpmChrootSet(NULL))
+ ec = 1;
+
+exit:
+ Fclose(scriptFd);
+
return ec;
}