RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: j...@rpm5.org Module: rpm Date: 29-Aug-2009 20:51:15 Branch: HEAD Handle: 2009082918511400 Modified files: rpm/lib verify.c Log: - permit HMAC's to be substituted for digests in *.rpm. Summary: Revision Changes Path 2.197 +307 -282 rpm/lib/verify.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/lib/verify.c ============================================================================ $ cvs diff -u -r2.196 -r2.197 verify.c --- rpm/lib/verify.c 27 Mar 2009 21:17:42 -0000 2.196 +++ rpm/lib/verify.c 29 Aug 2009 18:51:14 -0000 2.197 @@ -13,6 +13,7 @@ #include <rpmtypes.h> #include <rpmtag.h> +#define _RPMFI_INTERNAL #include <rpmfi.h> #define _RPMSQ_INTERNAL @@ -34,202 +35,309 @@ /*...@unchecked@*/ extern int _rpmds_unspecified_epoch_noise; +typedef struct rpmvf_s * rpmvf; +struct rpmvf_s { + struct rpmioItem_s _item; /*!< usage mutex and pool identifier. */ + const char * fn; + const char * flink; + struct stat sb; + rpmfileAttrs fflags; + rpmfileState fstate; + rpmVerifyAttrs vflags; + int dalgo; + size_t dlen; + const unsigned char * digest; + const char * fuser; + const char * fgroup; +#if defined(__LCLINT__) +/*...@refs@*/ + int nrefs; /*!< (unused) keep splint happy */ +#endif +}; + +static rpmvf rpmvfFree(rpmvf vf) +{ + if (vf) { +#ifdef NOTYET + yarnPossess(vf->_item.use); + if (yarnPeekLock(vf->_item.use) <= 1L) { + yarnLock use = vf->_item.use; + vf->fn = _free(vf->fn); + vf = _free(vf); + yarnTwist(use, TO, 0); + use = yarnFreeLock(use); + } else + yarnTwist(vf->_item.use, BY, -1); +#else + vf->fn = _free(vf->fn); + vf = _free(vf); +#endif + } + return NULL; +} + +static rpmvf rpmvfNew(rpmts ts, rpmfi fi, int i, rpmVerifyAttrs omitMask) +{ + rpmvf vf = xcalloc(1, sizeof(*vf)); + +#ifdef NOTYET + vf->_item.use = yarnNewLock(1); + vf->_item.pool = NULL; +#endif + + vf->fn = rpmGetPath(rpmtsRootDir(ts), fi->dnl[fi->dil[i]], fi->bnl[i], NULL); + vf->flink = fi->flinks[i]; + vf->fuser = fi->fuser[i]; + vf->fgroup = fi->fgroup[i]; + + { struct stat *st = &vf->sb; + st->st_dev = + st->st_rdev = fi->frdevs[i]; + st->st_ino = fi->finodes[i]; + st->st_mode = fi->fmodes[i]; +#ifdef NOTNEEDED + st->st_nlink = rpmfiFNlink(fi) + (int)S_ISDIR(st->st_mode); +#endif + if (unameToUid(vf->fuser, &st->st_uid) == -1) + st->st_uid = 0; /* XXX */ + if (gnameToGid(vf->fgroup, &st->st_gid) == -1) + st->st_gid = 0; /* XXX */ + st->st_size = fi->fsizes[i]; + st->st_blksize = 4 * 1024; /* XXX */ + st->st_blocks = (st->st_size + (st->st_blksize - 1)) / st->st_blksize; + st->st_atime = + st->st_ctime = + st->st_mtime = fi->fmtimes[i]; + } + + vf->fflags = fi->fflags[i]; + vf->fstate = fi->fstates[i]; + vf->vflags = fi->vflags[i]; + vf->dalgo = fi->fdigestalgos + ? fi->fdigestalgos[i] + : fi->digestalgo; + vf->dlen = fi->digestlen; + vf->digest = fi->digests + (fi->digestlen * i); + + /* Don't verify any features in omitMask. */ + vf->vflags &= ~(omitMask | RPMVERIFY_FAILURES); + + /* Content checks of %ghost files are meaningless. */ + if (vf->fflags & RPMFILE_GHOST) + vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME | + RPMVERIFY_LINKTO | RPMVERIFY_HMAC); + + return vf; +} + /** \ingroup rpmcli * Verify file attributes (including file digest). - * @todo gnorpm and python bindings prevent this from being static. - * @param ts transaction set - * @param fi file info (with linked header and current file index) - * @retval *res bit(s) returned to indicate failure - * @param omitMask bit(s) to disable verify checks + * @param vf file data to verify + * #param spew should verify results be printed? * @return 0 on success (or not installed), 1 on error */ -static int rpmVerifyFile(const rpmts ts, const rpmfi fi, - /*...@out@*/ rpmVerifyAttrs * res, rpmVerifyAttrs omitMask) +static int rpmvfVerify(rpmvf vf, int spew) /*...@globals h_errno, fileSystem, internalState @*/ - /*...@modifies fi, *res, fileSystem, internalState @*/ + /*...@modifies vf, te, fileSystem, internalState @*/ /*...@requires maxSet(res) >= 0 @*/ { - unsigned short fmode = rpmfiFMode(fi); - rpmfileAttrs fileAttrs = rpmfiFFlags(fi); - rpmVerifyAttrs flags = rpmfiVFlags(fi); - const char * fn = rpmfiFN(fi); - const char * rootDir = rpmtsRootDir(ts); + rpmVerifyAttrs res = RPMVERIFY_NONE; 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; + int ec = 0; - /* - * Check to see if the file was installed - if not pretend all is OK. - */ - switch (rpmfiFState(fi)) { + /* Check to see if the file was installed - if not pretend all is OK. */ + switch (vf->fstate) { + default: case RPMFILE_STATE_NETSHARED: case RPMFILE_STATE_REPLACED: case RPMFILE_STATE_NOTINSTALLED: case RPMFILE_STATE_WRONGCOLOR: - return 0; + goto exit; /*...@notreached@*/ break; case RPMFILE_STATE_NORMAL: break; } - if (fn == NULL || Lstat(fn, &sb) != 0) { - *res |= RPMVERIFY_LSTATFAIL; - return 1; +assert(vf->fn != NULL); + if (vf->fn == NULL || Lstat(vf->fn, &sb) != 0) { + res |= RPMVERIFY_LSTATFAIL; + ec = 1; + goto exit; } - /* - * Not all attributes of non-regular files can be verified. - */ + /* Not all attributes of non-regular files can be verified. */ if (S_ISDIR(sb.st_mode)) - flags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME | - RPMVERIFY_LINKTO); + vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME | + RPMVERIFY_LINKTO | RPMVERIFY_HMAC); else if (S_ISLNK(sb.st_mode)) { - flags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME | - RPMVERIFY_MODE); + vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME | + RPMVERIFY_MODE | RPMVERIFY_HMAC); #if CHOWN_FOLLOWS_SYMLINK - flags &= ~(RPMVERIFY_USER | RPMVERIFY_GROUP); + vf->vflags &= ~(RPMVERIFY_USER | RPMVERIFY_GROUP); #endif } else if (S_ISFIFO(sb.st_mode)) - flags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME | - RPMVERIFY_LINKTO); + vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME | + RPMVERIFY_LINKTO | RPMVERIFY_HMAC); else if (S_ISCHR(sb.st_mode)) - flags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME | - RPMVERIFY_LINKTO); + vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME | + RPMVERIFY_LINKTO | RPMVERIFY_HMAC); else if (S_ISBLK(sb.st_mode)) - flags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME | - RPMVERIFY_LINKTO); + vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME | + RPMVERIFY_LINKTO | RPMVERIFY_HMAC); else - flags &= ~(RPMVERIFY_LINKTO); - - /* - * Content checks of %ghost files are meaningless. - */ - if (fileAttrs & RPMFILE_GHOST) - flags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME | - RPMVERIFY_LINKTO); - - /* - * Don't verify any features in omitMask. - */ - flags &= ~(omitMask | RPMVERIFY_FAILURES); - - - if (flags & RPMVERIFY_FDIGEST) { - int dalgo = 0; - size_t dlen = 0; - const unsigned char * digest = rpmfiDigest(fi, &dalgo, &dlen); + vf->vflags &= ~(RPMVERIFY_LINKTO); - if (digest == NULL) - *res |= RPMVERIFY_FDIGEST; + if (vf->vflags & (RPMVERIFY_FDIGEST | RPMVERIFY_HMAC)) { + if (vf->digest == NULL || vf->dlen == 0) + res |= RPMVERIFY_FDIGEST; else { /* XXX If --nofdigest, then prelinked library sizes fail to verify. */ - unsigned char * fdigest = memset(alloca(dlen), 0, dlen); - size_t fsize; - rc = dodigest(dalgo, fn, fdigest, 0, &fsize); + unsigned char * fdigest = memset(alloca(vf->dlen), 0, vf->dlen); + size_t fsize = 0; +#define _mask (RPMVERIFY_FDIGEST|RPMVERIFY_HMAC) + unsigned dflags = (vf->vflags & _mask) == RPMVERIFY_HMAC + ? 0x2 : 0x0; +#undef _mask + int rc = dodigest(vf->dalgo, vf->fn, fdigest, dflags, &fsize); sb.st_size = fsize; if (rc) - *res |= (RPMVERIFY_READFAIL|RPMVERIFY_FDIGEST); + res |= (RPMVERIFY_READFAIL|RPMVERIFY_FDIGEST); else - if (memcmp(fdigest, digest, dlen)) - *res |= RPMVERIFY_FDIGEST; + if (memcmp(fdigest, vf->digest, vf->dlen)) + res |= RPMVERIFY_FDIGEST; } } - if (flags & RPMVERIFY_LINKTO) { + if (vf->vflags & RPMVERIFY_LINKTO) { char linkto[1024+1]; int size = 0; - if ((size = Readlink(fn, linkto, sizeof(linkto)-1)) == -1) - *res |= (RPMVERIFY_READLINKFAIL|RPMVERIFY_LINKTO); + if ((size = Readlink(vf->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)) - *res |= RPMVERIFY_LINKTO; + if (vf->flink == NULL || strcmp(linkto, vf->flink)) + res |= RPMVERIFY_LINKTO; } } - if (flags & RPMVERIFY_FILESIZE) { - if (sb.st_size != rpmfiFSize(fi)) - *res |= RPMVERIFY_FILESIZE; - } - - if (flags & RPMVERIFY_MODE) { - unsigned short metamode = fmode; - unsigned short filemode; - - /* - * Platforms (like AIX) where sizeof(unsigned short) != sizeof(mode_t) - * need the (unsigned short) cast here. - */ - filemode = (unsigned short)sb.st_mode; - - /* - * Comparing the type of %ghost files is meaningless, but perms are OK. - */ - if (fileAttrs & RPMFILE_GHOST) { + if (vf->vflags & RPMVERIFY_FILESIZE) { + if (sb.st_size != vf->sb.st_size) + res |= RPMVERIFY_FILESIZE; + } + + if (vf->vflags & RPMVERIFY_MODE) { + /* XXX AIX has sizeof(mode_t) > sizeof(unsigned short) */ + unsigned short metamode = (unsigned short)vf->sb.st_mode; + unsigned short filemode = (unsigned short)sb.st_mode; + + /* Comparing type of %ghost files is meaningless, but perms are OK. */ + if (vf->fflags & RPMFILE_GHOST) { metamode &= ~0xf000; filemode &= ~0xf000; } - if (metamode != filemode) - *res |= RPMVERIFY_MODE; + res |= RPMVERIFY_MODE; } - if (flags & RPMVERIFY_RDEV) { - if (S_ISCHR(fmode) != S_ISCHR(sb.st_mode) - || S_ISBLK(fmode) != S_ISBLK(sb.st_mode)) - { - *res |= RPMVERIFY_RDEV; - } else if (S_ISDEV(fmode) && S_ISDEV(sb.st_mode)) { + if (vf->vflags & RPMVERIFY_RDEV) { + if (S_ISCHR(vf->sb.st_mode) != S_ISCHR(sb.st_mode) + || S_ISBLK(vf->sb.st_mode) != S_ISBLK(sb.st_mode)) + res |= RPMVERIFY_RDEV; + else if (S_ISDEV(vf->sb.st_mode) && S_ISDEV(sb.st_mode)) { rpmuint16_t st_rdev = (rpmuint16_t)(sb.st_rdev & 0xffff); - rpmuint16_t frdev = (rpmuint16_t)(rpmfiFRdev(fi) & 0xffff); + rpmuint16_t frdev = (rpmuint16_t)(vf->sb.st_rdev & 0xffff); if (st_rdev != frdev) - *res |= RPMVERIFY_RDEV; + res |= RPMVERIFY_RDEV; } } - if (flags & RPMVERIFY_MTIME) { - if ((rpmuint32_t)sb.st_mtime != rpmfiFMtime(fi)) - *res |= RPMVERIFY_MTIME; + if (vf->vflags & RPMVERIFY_MTIME) { + if (sb.st_mtime != vf->sb.st_mtime) + res |= RPMVERIFY_MTIME; } - if (flags & RPMVERIFY_USER) { - const char * name = uidToUname(sb.st_uid); - const char * fuser = rpmfiFUser(fi); - if (name == NULL || fuser == NULL || strcmp(name, fuser)) - *res |= RPMVERIFY_USER; + if (vf->vflags & RPMVERIFY_USER) { + const char * fuser = uidToUname(sb.st_uid); + if (fuser == NULL || vf->fuser == NULL || strcmp(fuser, vf->fuser)) + res |= RPMVERIFY_USER; } - if (flags & RPMVERIFY_GROUP) { - const char * name = gidToGname(sb.st_gid); - const char * fgroup = rpmfiFGroup(fi); - if (name == NULL || fgroup == NULL || strcmp(name, fgroup)) - *res |= RPMVERIFY_GROUP; + if (vf->vflags & RPMVERIFY_GROUP) { + const char * fgroup = gidToGname(sb.st_gid); + if (fgroup == NULL || vf->fgroup == NULL || strcmp(fgroup, vf->fgroup)) + res |= RPMVERIFY_GROUP; + } + +exit: + + if (spew) { /* XXX no output w verify(...) probe. */ + char buf[BUFSIZ]; + char * t = buf; + char * te = t; + *te = '\0'; + if (ec) { + if (!(vf->fflags & (RPMFILE_MISSINGOK|RPMFILE_GHOST)) + || rpmIsVerbose()) + { + sprintf(te, _("missing %c %s"), + ((vf->fflags & RPMFILE_CONFIG) ? 'c' : + (vf->fflags & RPMFILE_DOC) ? 'd' : + (vf->fflags & RPMFILE_GHOST) ? 'g' : + (vf->fflags & RPMFILE_LICENSE) ? 'l' : + (vf->fflags & RPMFILE_PUBKEY) ? 'P' : + (vf->fflags & RPMFILE_README) ? 'r' : ' '), + vf->fn); + if ((res & RPMVERIFY_LSTATFAIL) != 0 && errno != ENOENT) { + te += strlen(te); + sprintf(te, " (%s)", strerror(errno)); + } + } + } else if (res || rpmIsVerbose()) { + /*...@observer@*/ static const char aok[] = "."; + /*...@observer@*/ static const char unknown[] = "?"; + +#define _verify(_RPMVERIFY_F, _C) \ + ((res & _RPMVERIFY_F) ? _C : aok) +#define _verifylink(_RPMVERIFY_F, _C) \ + ((res & RPMVERIFY_READLINKFAIL) ? unknown : \ + (res & _RPMVERIFY_F) ? _C : aok) +#define _verifyfile(_RPMVERIFY_F, _C) \ + ((res & RPMVERIFY_READFAIL) ? unknown : \ + (res & _RPMVERIFY_F) ? _C : aok) + + const char * digest = _verifyfile(RPMVERIFY_FDIGEST, "5"); + const char * size = _verify(RPMVERIFY_FILESIZE, "S"); + const char * link = _verifylink(RPMVERIFY_LINKTO, "L"); + const char * mtime = _verify(RPMVERIFY_MTIME, "T"); + const char * rdev = _verify(RPMVERIFY_RDEV, "D"); + const char * user = _verify(RPMVERIFY_USER, "U"); + const char * group = _verify(RPMVERIFY_GROUP, "G"); + const char * 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, digest, rdev, link, user, group, mtime, + ((vf->fflags & RPMFILE_CONFIG) ? 'c' : + (vf->fflags & RPMFILE_DOC) ? 'd' : + (vf->fflags & RPMFILE_GHOST) ? 'g' : + (vf->fflags & RPMFILE_LICENSE) ? 'l' : + (vf->fflags & RPMFILE_PUBKEY) ? 'P' : + (vf->fflags & RPMFILE_README) ? 'r' : ' '), + vf->fn); + + } + + if (t && *t) + rpmlog(RPMLOG_NOTICE, "%s\n", t); + } - return 0; + return (res != 0); } /** @@ -275,131 +383,6 @@ } /** - * 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 - * @return 0 no problems, 1 problems found - */ -static int verifyHeader(QVA_t qva, const rpmts ts, rpmfi fi) - /*...@globals h_errno, fileSystem, internalState @*/ - /*...@modifies fi, fileSystem, internalState @*/ -{ - rpmVerifyAttrs verifyResult = 0; - /*...@-type@*/ /* FIX: union? */ - rpmVerifyAttrs omitMask = ((qva->qva_flags & VERIFY_ATTRS) ^ VERIFY_ATTRS); - /*...@=type@*/ - int ec = 0; /* assume no problems */ - char * t, * te; - char buf[BUFSIZ]; - int i; - - te = t = buf; - *te = '\0'; - -/*...@-castexpose@*/ - fi = rpmfiLink(fi, "verifyHeader"); -/*...@=castexpose@*/ - fi = rpmfiInit(fi, 0); - if (fi != NULL) /* XXX lclint */ - while ((i = rpmfiNext(fi)) >= 0) { - rpmfileAttrs fflags; - int rc; - - fflags = rpmfiFFlags(fi); - - /* If not querying %config, skip config files. */ - if ((qva->qva_fflags & RPMFILE_CONFIG) && (fflags & RPMFILE_CONFIG)) - continue; - - /* If not querying %doc, skip doc files. */ - if ((qva->qva_fflags & RPMFILE_DOC) && (fflags & RPMFILE_DOC)) - continue; - - /* If not verifying %ghost, skip ghost files. */ - /* XXX the broken!!! logic disables %ghost queries always. */ - if (!(qva->qva_fflags & RPMFILE_GHOST) && (fflags & RPMFILE_GHOST)) - continue; - - rc = rpmVerifyFile(ts, fi, &verifyResult, omitMask); - if (rc) { - if (qva->qva_mode != 'v') /* XXX no output w verify(...) probe. */ - if (!(fflags & (RPMFILE_MISSINGOK|RPMFILE_GHOST)) || rpmIsVerbose()) { - sprintf(te, _("missing %c %s"), - ((fflags & RPMFILE_CONFIG) ? 'c' : - (fflags & RPMFILE_DOC) ? 'd' : - (fflags & RPMFILE_GHOST) ? 'g' : - (fflags & RPMFILE_LICENSE) ? 'l' : - (fflags & RPMFILE_PUBKEY) ? 'P' : - (fflags & RPMFILE_README) ? 'r' : ' '), - rpmfiFN(fi)); - te += strlen(te); - if ((verifyResult & RPMVERIFY_LSTATFAIL) != 0 && errno != ENOENT) { - sprintf(te, " (%s)", strerror(errno)); - te += strlen(te); - } - ec = rc; - } - } else if (verifyResult || rpmIsVerbose()) { - const char * size, * digest, * link, * mtime, * mode; - const char * group, * user, * rdev; - /*...@observer@*/ static const char *const aok = "."; - /*...@observer@*/ static const char *const unknown = "?"; - - if (!ec) - ec = (verifyResult != 0); - - if (qva->qva_mode != 'v') { /* XXX no output w verify(...) probe. */ -#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) - - digest = _verifyfile(RPMVERIFY_FDIGEST, "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, digest, rdev, link, user, group, mtime, - ((fflags & RPMFILE_CONFIG) ? 'c' : - (fflags & RPMFILE_DOC) ? 'd' : - (fflags & RPMFILE_GHOST) ? 'g' : - (fflags & RPMFILE_LICENSE) ? 'l' : - (fflags & RPMFILE_PUBKEY) ? 'P' : - (fflags & RPMFILE_README) ? 'r' : ' '), - rpmfiFN(fi)); - te += strlen(te); - } - } - - if (qva->qva_mode != 'v') /* XXX no output w verify(...) probe. */ - if (te > t) { - *te++ = '\n'; - *te = '\0'; - rpmlog(RPMLOG_NOTICE, "%s", t); - te = t = buf; - *t = '\0'; - } - } - fi = rpmfiUnlink(fi, "verifyHeader"); - - return ec; -} - -/** * Check installed package dependencies for problems. * @param qva parsed query/verify options * @param ts transaction set @@ -493,43 +476,85 @@ int showVerifyPackage(QVA_t qva, rpmts ts, Header h) { - int scareMem = 0; - rpmfi fi = NULL; + rpmVerifyAttrs omitMask = ((qva->qva_flags & VERIFY_ATTRS) ^ VERIFY_ATTRS); + int spew = (qva->qva_mode != 'v'); /* XXX no output w verify(...) probe. */ + static int scareMem = 0; + rpmfi fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem); + rpmvf vf; int ec = 0; int rc; + int i; - fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem); - if (fi != NULL) { - if (qva->qva_flags & VERIFY_DEPS) { - int save_noise = _rpmds_unspecified_epoch_noise; -/*...@-mods@*/ - if (rpmIsVerbose()) - _rpmds_unspecified_epoch_noise = 1; - if ((rc = verifyDependencies(qva, ts, h)) != 0) - ec = rc; - _rpmds_unspecified_epoch_noise = save_noise; -/*...@=mods@*/ - } - 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) || - headerIsEntry(h, RPMTAG_SANITYCHECK))) + if (fi != NULL) +#if defined(_OPENMP) + #pragma omp parallel +#endif + { + if (qva->qva_flags & VERIFY_FILES) +#if defined(_OPENMP) + #pragma omp for reduction(+:ec) private(vf,rc,i) nowait +#endif + for (i = 0; i < rpmfiFC(fi); i++) { + int fflags = fi->fflags[i]; + + /* If not querying %config, skip config files. */ + if ((qva->qva_fflags & RPMFILE_CONFIG) && (fflags & RPMFILE_CONFIG)) + continue; + + /* If not querying %doc, skip doc files. */ + if ((qva->qva_fflags & RPMFILE_DOC) && (fflags & RPMFILE_DOC)) + continue; + + /* If not verifying %ghost, skip ghost files. */ + /* XXX the broken!!! logic disables %ghost queries always. */ + if (!(qva->qva_fflags & RPMFILE_GHOST) && (fflags & RPMFILE_GHOST)) + continue; + + /* Gather per-file data into a carrier. */ + vf = rpmvfNew(ts, fi, i, omitMask); + + /* Verify per-file metadata. */ + rc = rpmvfVerify(vf, spew); + if (rc) + ec += rc; + + (void) rpmvfFree(vf); + } + if (qva->qva_flags & VERIFY_SCRIPT) +#if defined(_OPENMP) + #pragma omp master +#endif + { + if (headerIsEntry(h, RPMTAG_VERIFYSCRIPT) || + headerIsEntry(h, RPMTAG_SANITYCHECK)) { FD_t fdo = fdDup(STDOUT_FILENO); rc = rpmfiSetHeader(fi, h); if ((rc = rpmVerifyScript(qva, ts, fi, fdo)) != 0) - ec = rc; + ec += rc; if (fdo != NULL) rc = Fclose(fdo); rc = rpmfiSetHeader(fi, NULL); } - - fi = rpmfiFree(fi); } + if (qva->qva_flags & VERIFY_DEPS) +#if defined(_OPENMP) + #pragma omp master +#endif + { + int save_noise = _rpmds_unspecified_epoch_noise; +/*...@-mods@*/ + if (rpmIsVerbose()) + _rpmds_unspecified_epoch_noise = 1; + if ((rc = verifyDependencies(qva, ts, h)) != 0) + ec += rc; + _rpmds_unspecified_epoch_noise = save_noise; +/*...@=mods@*/ + } + } + + fi = rpmfiFree(fi); return ec; } @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org