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

Reply via email to