- fix: db1 end-of-file not detected in legacy compatible way.
authorjbj <devnull@localhost>
Fri, 15 Jun 2001 04:56:33 +0000 (04:56 +0000)
committerjbj <devnull@localhost>
Fri, 15 Jun 2001 04:56:33 +0000 (04:56 +0000)
- fix: remove (harmless) chown error message from %post.
- add --target/--host to %configure, add example cross-build/config.site
  scripts to /usr/lib/rpm <arjanv@redhat.com> (#44581).
- rpmdb iterator selectors permit default/strcmp/regex/glob matching.
- rpmdb iterator selectors permit negative matches.

CVS patchset: 4861
CVS date: 2001/06/15 04:56:33

15 files changed:
CHANGES
Makefile.am
lib/header.c
lib/psm.c
lib/query.c
lib/rpmlib.h
lib/transaction.c
macros.in
rpm.spec.in
rpmdb/db1.c
rpmdb/falloc.c
rpmdb/rpmdb.c
rpmio/digest.c
rpmpopt.in
scripts/Makefile.am

diff --git a/CHANGES b/CHANGES
index ff722fb..8167408 100644 (file)
--- a/CHANGES
+++ b/CHANGES
        - permit rpm -qa to take RE args applied to name tag.
        - permit dbiFindMatches() to use version/release patterns.
        - eliminate all uses of rpmdbSetIterator{Version,Release}.
+       - fix: db1 end-of-file not detected in legacy compatible way.
+       - fix: remove (harmless) chown error message from %post.
+       - add --target/--host to %configure, add example cross-build/config.site
+               scripts to /usr/lib/rpm <arjanv@redhat.com> (#44581).
+       - rpmdb iterator selectors permit default/strcmp/regex/glob matching.
+       - rpmdb iterator selectors permit negative matches.
 
 4.0 -> 4.0.[12]
        - add doxygen and lclint annotations most everywhere.
index 0140ef8..8533bfb 100644 (file)
@@ -45,7 +45,7 @@ pkglibdir =           @RPMCONFIGDIR@
 pkglib_PROGRAMS =      rpmb rpmd rpmi rpmk rpmq
 pkglib_DATA =          rpmrc rpmpopt-$(VERSION) macros
 pkglib_SCRIPTS =       find-provides find-requires mkinstalldirs \
-                       config.guess config.sub
+                       config.guess config.sub config.site
 
 rpmpopt-$(VERSION): rpmpopt
        cp rpmpopt $@
index ef98e20..5a1c5ee 100644 (file)
@@ -1585,9 +1585,7 @@ static void copyData(int_32 type, /*@out@*/ void * dstPtr, const void * srcPtr,
        break;
 
     default:
-       /*@-mayaliasunique@*/
-       memcpy(dstPtr, srcPtr, dataLength);
-       /*@=mayaliasunique@*/
+       memmove(dstPtr, srcPtr, dataLength);
        break;
     }
 }
@@ -1717,9 +1715,7 @@ int headerAddI18NString(Header h, int_32 tag, const char * string, const char *
            table->info.offset = 0;
        } else
            table->data = xrealloc(table->data, table->length + length);
-       /*@-mayaliasunique@*/
-       memcpy(((char *)table->data) + table->length, lang, length);
-       /*@=mayaliasunique@*/
+       memmove(((char *)table->data) + table->length, lang, length);
        table->length += length;
        table->info.count++;
     }
@@ -1744,9 +1740,7 @@ int headerAddI18NString(Header h, int_32 tag, const char * string, const char *
            entry->data = xrealloc(entry->data, entry->length + length);
 
        memset(((char *)entry->data) + entry->length, '\0', ghosts);
-       /*@-mayaliasunique@*/
-       strcpy(((char *)entry->data) + entry->length + ghosts, string);
-       /*@=mayaliasunique@*/
+       memmove(((char *)entry->data) + entry->length + ghosts, string, strlen(string));
 
        entry->length += length;
        entry->info.count = langNum + 1;
index 9998c72..57a2ef7 100644 (file)
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -1332,13 +1332,11 @@ int psmStage(PSM_t psm, pkgStage stage)
 
 assert(psm->mi == NULL);
            psm->mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, fi->name, 0);
-#ifdef DYING
-           (void) rpmdbSetIteratorVersion(psm->mi, fi->version);
-           (void) rpmdbSetIteratorRelease(psm->mi, fi->release);
-#else
-           (void) rpmdbSetIteratorRE(psm->mi, RPMTAG_VERSION, fi->version);
-           (void) rpmdbSetIteratorRE(psm->mi, RPMTAG_RELEASE, fi->release);
-#endif
+           (void) rpmdbSetIteratorRE(psm->mi, RPMTAG_VERSION,
+                       RPMMIRE_DEFAULT, fi->version);
+           (void) rpmdbSetIteratorRE(psm->mi, RPMTAG_RELEASE,
+                       RPMMIRE_DEFAULT, fi->release);
+
            while ((psm->oh = rpmdbNextIterator(psm->mi))) {
                fi->record = rpmdbGetIteratorOffset(psm->mi);
                if (ts->transFlags & RPMTRANS_FLAG_MULTILIB)
index b9bbb2b..c25d37a 100644 (file)
@@ -633,7 +633,7 @@ restart:
            retcode = 1;
        } else {
            for (av = (const char **) arg; av && *av; av++) {
-               if (!rpmdbSetIteratorRE(mi, RPMTAG_NAME, *av))
+               if (!rpmdbSetIteratorRE(mi, RPMTAG_NAME, RPMMIRE_DEFAULT, *av))
                    continue;
                mi = rpmdbFreeIterator(mi);
                retcode = 1;
index 557a566..2bb66da 100644 (file)
@@ -762,20 +762,33 @@ int rpmdbPruneIterator(/*@null@*/ rpmdbMatchIterator mi,
                /*@null@*/ int * hdrNums, int nHdrNums, int sorted)
        /*@modifies mi, hdrNums @*/;
 
+/**
+ * Tag value pattern match mode.
+ */
+typedef enum rpmMireMode_e {
+    RPMMIRE_DEFAULT    = 0,    /*!< regex with \., .* and ^...$ */
+    RPMMIRE_STRCMP     = 1,    /*!< strcmp on strings */
+    RPMMIRE_REGEX      = 2,    /*!< regex patterns */
+    RPMMIRE_GLOB       = 3     /*!< glob patterns */
+} rpmMireMode;
+
 /** \ingroup rpmdb
- * Add regular expression to iterator selector.
+ * Add pattern to iterator selector.
  * @param mi           rpm database iterator
  * @param tag          rpm tag
- * @param pattern      regex pattern to match
+ * @param mode         type of pattern match
+ * @param pattern      pattern to match
  * @return             0 on success
  */
 int rpmdbSetIteratorRE(/*@null@*/ rpmdbMatchIterator mi, rpmTag tag,
-               /*@null@*/ const char * pattern)
+               rpmMireMode mode, /*@null@*/ const char * pattern)
        /*@modifies mi @*/;
 
 /** \ingroup rpmdb
  * Modify iterator to filter out headers that do not match version.
- * @deprecated Use rpmdbSetIteratorRE(mi, RPMTAG_VERSION, version) instead.
+ * @deprecated Use
+ *     rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_DEFAULT, version)
+ * instead.
  * @todo Eliminate from API.
  * @param mi           rpm database iterator
  * @param version      version to match (can be a regex pattern)
@@ -788,7 +801,9 @@ int rpmdbSetIteratorVersion(/*@null@*/ rpmdbMatchIterator mi,
 
 /** \ingroup rpmdb
  * Modify iterator to filter out headers that do not match release.
- * @deprecated Use rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, release) instead.
+ * @deprecated Use
+ *     rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_DEFAULT, release)
+ * instead.
  * @todo Eliminate from API.
  * @param mi           rpm database iterator
  * @param release      release to match (can be a regex pattern)
index da80a78..4b5d307 100644 (file)
@@ -1650,13 +1650,11 @@ int rpmRunTransactions( rpmTransactionSet ts,
        if (!(ts->ignoreSet & RPMPROB_FILTER_REPLACEPKG) && !alp->multiLib) {
            rpmdbMatchIterator mi;
            mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, alp->name, 0);
-#ifdef DYING
-           (void) rpmdbSetIteratorVersion(mi, alp->version);
-           (void) rpmdbSetIteratorRelease(mi, alp->release);
-#else
-           (void) rpmdbSetIteratorRE(mi, RPMTAG_VERSION, alp->version);
-           (void) rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, alp->release);
-#endif
+           (void) rpmdbSetIteratorRE(mi, RPMTAG_VERSION,
+                       RPMMIRE_DEFAULT, alp->version);
+           (void) rpmdbSetIteratorRE(mi, RPMTAG_RELEASE,
+                       RPMMIRE_DEFAULT, alp->release);
+
            while (rpmdbNextIterator(mi) != NULL) {
                psAppend(ts->probs, RPMPROB_PKG_INSTALLED, alp,
                        NULL, NULL, NULL, 0);
index 1b2e601..9c87781 100644 (file)
--- a/macros.in
+++ b/macros.in
@@ -1,7 +1,7 @@
 #/*! \page config_macros Default configuration: /usr/lib/rpm/macros
 # \verbatim
 #
-# $Id: macros.in,v 1.79 2001/06/06 19:57:12 jbj Exp $
+# $Id: macros.in,v 1.80 2001/06/15 04:56:33 jbj Exp $
 #
 # This is a global RPM configuration file. All changes made here will
 # be lost when the rpm package is upgraded. Any per-system configuration
 #
 #%_langpatt
 
+#      (experimental)
+#      The type of pattern match used on rpmdb iterator selectors:
+#      "default"       simple glob-like regex, periods will be escaped,
+#                      splats will have period prepended, full "^...$" match
+#                      required. Also, file path tags will use glob(7).
+#      "strcmp"        compare strings
+#      "regex"         regex(7) patterns using regcomp(3)/regexec(3)
+#      "glob"          glob(7) patterns using fnmatch(3)
+#
+%_query_selector_match default
+
 #      A colon separated list of paths where files should *not* be installed.
 #      Usually, these are network file system mount points.
 #
@@ -690,7 +701,8 @@ CFLAGS="${CFLAGS:-%optflags}" ; export CFLAGS ; \
 CXXFLAGS="${CXXFLAGS:-%optflags}" ; export CXXFLAGS ; \
 FFLAGS="${FFLAGS:-%optflags}" ; export FFLAGS ; \
 %{?__libtoolize:[ -f configure.in ] && %{__libtoolize} --copy --force} ; \
-./configure %{_target_platform} \\\
+./configure \\\
+       --target=%{_target_platform} \\\
        --prefix=%{_prefix} \\\
        --exec-prefix=%{_exec_prefix} \\\
        --bindir=%{_bindir} \\\
@@ -703,7 +715,9 @@ FFLAGS="${FFLAGS:-%optflags}" ; export FFLAGS ; \
        --localstatedir=%{_localstatedir} \\\
        --sharedstatedir=%{_sharedstatedir} \\\
        --mandir=%{_mandir} \\\
+       --host=%{_host} \\\
        --infodir=%{_infodir}
+
 #------------------------------------------------------------------------------
 # The make install analogue of %configure:
 %makeinstall \
index 44f88f9..5d1b2f8 100644 (file)
@@ -187,16 +187,16 @@ exit 0
 %ifos linux
 /sbin/ldconfig
 if [ -f /var/lib/rpm/packages.rpm ]; then
-    : # do nothing
+    /bin/chown @RPMUSER@.@RPMGROUP@ /var/lib/rpm/*.rpm
 elif [ -f /var/lib/rpm/Packages ]; then
     # undo db1 configuration
     rm -f /etc/rpm/macros.db1
+    /bin/chown @RPMUSER@.@RPMGROUP@ /var/lib/rpm/[A-Z]*
 else
     # initialize db3 database
     rm -f /etc/rpm/macros.db1
     /bin/rpm --initdb
 fi
-/bin/chown @RPMUSER@.@RPMGROUP@ /var/lib/rpm/[A-Z]* /var/lib/rpm/*.rpm
 %endif
 exit 0
 
index eb451e6..a653b3a 100644 (file)
@@ -296,6 +296,10 @@ static int db1cget(dbiIndex dbi, /*@unused@*/ DBC * dbcursor,
            key.data = &dbi->dbi_lastoffset;
            /*@=immediatetrans@*/
            key.size = sizeof(dbi->dbi_lastoffset);
+
+           /* Catch end-of-chain conditions. */
+           if (dbi->dbi_lastoffset == 0)
+               goto bail;
        }
 
        memcpy(&offset, key.data, sizeof(offset));
@@ -339,6 +343,7 @@ static int db1cget(dbiIndex dbi, /*@unused@*/ DBC * dbcursor,
        rc = EINVAL;
 #endif
 
+bail:
     if (rc == 0) {
        if (keyp)       *keyp = key.data;
        if (keylen)     *keylen = key.size;
index 91713c3..777c776 100644 (file)
@@ -382,31 +382,34 @@ void fadFree(FD_t fd, unsigned int offset)
     }
 }
 
-static int insane = 0;
-
-static int fadSanity(FD_t fd, int offset, struct faHeader * fh)
+static int fadSanity(FD_t fd, int offset, const struct faHeader * fh, int printit)
+       /*@modifies fileSystem @*/
 {
     int rc = 0;
 
-    if (fh->size <= 0 || fh->size > 0x00200000 || (fh->size & 0x3f) != 0)
+    /* Check size range and alignment. */
+    if (!(fh->size > 0 || fh->size <= 0x00200000 && (fh->size & 0x3f) == 0))
        rc |= 0x1;
 
+    /* Check forward link range, alignment and offset. */
     if (fh->freeNext &&
        !(      fh->freeNext > sizeof(struct faFileHeader) &&
                fh->freeNext < fadGetFileSize(fd) &&
                (fh->freeNext & 0x3f) == sizeof(struct faFileHeader)) )
        rc |= 0x2;
 
+    /* Check backward link range, alignment and offset. */
     if (fh->freePrev &&
        !(      fh->freePrev > sizeof(struct faFileHeader) &&
                fh->freePrev < fadGetFileSize(fd) &&
                (fh->freePrev & 0x3f) == sizeof(struct faFileHeader)) )
        rc |= 0x4;
 
+    /* Check that only the isFree bit is (possibly) set. */
     if (fh->isFree & ~1)
        rc |= 0x8;
 
-    if (!insane && rc) {
+    if (printit && rc) {
        rpmMessage(RPMMESS_DEBUG,
     "offset %d(0x%08x) rc %d: size 0x%08x next %d(0x%08x) prev %d(0x%08x) isFree 0x%08x\n",
                offset, (unsigned) offset, rc,
@@ -427,7 +430,6 @@ int fadNextOffset(FD_t fd, unsigned int lastOffset)
 {
     struct faHeader header;
     int offset;
-    int rc;
 
     offset = (lastOffset)
        ? (lastOffset - sizeof(header))
@@ -447,46 +449,35 @@ int fadNextOffset(FD_t fd, unsigned int lastOffset)
      * XXX Try to reconnect at next record found. This isn't perfect
      * XXX but handles many common db1 corruption problems.
      */
-    rc = fadSanity(fd, offset, &header);
-    if (rc) {
+    if (fadSanity(fd, offset, &header, 0)) {
        struct faHeader myheader;
-       int o = offset + sizeof(header); 
+       int o = offset;
 
        memset(&myheader, 0, sizeof(myheader));
-       insane = 1;
-       for (   o = offset + 0x40;
-               o < fadGetFileSize(fd);
-               o += 0x40)
-       {
-           rc = Pread(fd, &myheader, sizeof(myheader), o);
-           if (rc != sizeof(header))
+       do {
+           o += 0x40;  /* XXX allocation chunks are padded to 64b */
+           if (o >= fadGetFileSize(fd))
                return 0;
-           rc = fadSanity(fd, o, &myheader);
-           if (rc == 0)
-               break;
-       }
-       insane = 0;
-       if (o >= fadGetFileSize(fd))
-           return 0;
+           if (Pread(fd, &myheader, sizeof(myheader), o) != sizeof(header))
+               return 0;
+       } while (fadSanity(fd, o, &myheader, 0));
        return (o + sizeof(header));
     }
 
     do {
        offset += header.size;
+       if (offset >= fadGetFileSize(fd))
+           return 0;
 
        if (Pread(fd, &header, sizeof(header), offset) != sizeof(header))
            return 0;
 
-       if (header.isFree == 0) break;
-    } while (offset < fadGetFileSize(fd) && header.isFree == 1);
-
-    if (offset < fadGetFileSize(fd)) {
-       /* Sanity check this to make sure we're not going in loops */
-       offset += sizeof(header);
+    } while (header.isFree == 1);
 
-       if (offset <= lastOffset) return -1;
+    /* Sanity check this to make sure we're not going in loops */
+    offset += sizeof(header);
+    if (offset <= lastOffset)
+       return 0;       /* XXX used to return -1 */
 
-       return offset;
-    } else
-       return 0;
+    return offset;
 }
index a5c067a..a825954 100644 (file)
@@ -11,6 +11,7 @@ static int _debug = 0;
 #include <signal.h>
 #include <sys/signal.h>
 
+#include <fnmatch.h>
 #include <regex.h>
 
 #include <rpmcli.h>
@@ -1197,8 +1198,8 @@ int rpmdbCountPackages(rpmdb db, const char * name)
  * @param dbi          index database handle (always RPMTAG_NAME)
  * @param dbcursor     index database cursor
  * @param name         package name
- * @param version      package version (can be a regex pattern)
- * @param release      package release (can be a regex pattern)
+ * @param version      package version (can be a pattern)
+ * @param release      package release (can be a pattern)
  * @retval matches     set of header instances that match
  * @return             0 on match, 1 on no match, 2 on error
  */
@@ -1227,7 +1228,7 @@ static int dbiFindMatches(dbiIndex dbi, DBC * dbcursor,
 
     gotMatches = 0;
 
-    /* make sure the version and releases match */
+    /* Make sure the version and release match. */
     for (i = 0; i < dbiIndexSetCount(*matches); i++) {
        unsigned int recoff = dbiIndexRecordOffset(*matches, i);
        Header h;
@@ -1240,11 +1241,15 @@ static int dbiFindMatches(dbiIndex dbi, DBC * dbcursor,
                        RPMDBI_PACKAGES, &recoff, sizeof(recoff));
 
            /* Set iterator selectors for version/release if available. */
-           if (version && rpmdbSetIteratorRE(mi, RPMTAG_VERSION, version)) {
+           if (version &&
+               rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_DEFAULT, version))
+           {
                rc = 2;
                goto exit;
            }
-           if (release && rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, release)) {
+           if (release &&
+               rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_DEFAULT, release))
+           {
                rc = 2;
                goto exit;
            }
@@ -1280,9 +1285,8 @@ exit:
 
 /**
  * Lookup by name, name-version, and finally by name-version-release.
- * Both version and release can be regex patterns.
+ * Both version and release can be patterns.
  * @todo Name must be an exact match, as name is a db key.
- * @todo N-V-R split needs to be made RE aware, i.e. '[0-9]' is split badly.
  * @param dbi          index database handle (always RPMTAG_NAME)
  * @param dbcursor     index database cursor
  * @param arg          name[-version[-release]] string
@@ -1293,8 +1297,11 @@ static int dbiFindByLabel(dbiIndex dbi, DBC * dbcursor,
                /*@null@*/ const char * arg, /*@out@*/ dbiIndexSet * matches)
        /*@modifies dbi, *dbcursor, *matches, fileSystem @*/
 {
-    char * localarg, * chptr;
-    char * release;
+    const char * release;
+    char * localarg;
+    char * s;
+    char c;
+    int brackets;
     int rc;
  
     if (arg == NULL || strlen(arg) == 0) return 1;
@@ -1309,15 +1316,25 @@ static int dbiFindByLabel(dbiIndex dbi, DBC * dbcursor,
 
     /* maybe a name and a release */
     localarg = alloca(strlen(arg) + 1);
-    strcpy(localarg, arg);
+    s = stpcpy(localarg, arg);
+
+    c = '\0';
+    brackets = 0;
+    for (s -= 1; s > localarg; s--) {
+       switch (*s) {
+       case '[':       brackets = 1;                   break;
+       case ']':       if (c != '[') brackets = 0;     break;
+       }
+       c = *s;
+       if (!brackets && *s == '-')
+           break;
+    }
 
-    chptr = (localarg + strlen(localarg)) - 1;
-    while (chptr > localarg && *chptr != '-') chptr--;
     /*@-nullstate@*/   /* FIX: *matches may be NULL. */
-    if (chptr == localarg) return 1;
+    if (s == localarg) return 1;
 
-    *chptr = '\0';
-    rc = dbiFindMatches(dbi, dbcursor, localarg, chptr + 1, NULL, matches);
+    *s = '\0';
+    rc = dbiFindMatches(dbi, dbcursor, localarg, s + 1, NULL, matches);
     if (rc != 1) return rc;
 
     /*@-unqualifiedtrans@*/
@@ -1326,12 +1343,24 @@ static int dbiFindByLabel(dbiIndex dbi, DBC * dbcursor,
     
     /* how about name-version-release? */
 
-    release = chptr + 1;
-    while (chptr > localarg && *chptr != '-') chptr--;
-    if (chptr == localarg) return 1;
+    release = s + 1;
+
+    c = '\0';
+    brackets = 0;
+    for (; s > localarg; s--) {
+       switch (*s) {
+       case '[':       brackets = 1;                   break;
+       case ']':       if (c != '[') brackets = 0;     break;
+       }
+       c = *s;
+       if (!brackets && *s == '-')
+           break;
+    }
+
+    if (s == localarg) return 1;
 
-    *chptr = '\0';
-    return dbiFindMatches(dbi, dbcursor, localarg, chptr + 1, release, matches);
+    *s = '\0';
+    return dbiFindMatches(dbi, dbcursor, localarg, s + 1, release, matches);
     /*@=nullstate@*/
 }
 
@@ -1372,10 +1401,13 @@ static int dbiUpdateRecord(dbiIndex dbi, DBC * dbcursor, int offset, Header h)
 
 typedef struct miRE_s {
     rpmTag             tag;            /*!< header tag */
-/*@only@*/ const char *        pattern;        /*!< regular expression */
-    int                        cflags;         /*!< compile flags */
-/*@only@*/ regex_t *   preg;           /*!< compiled pattern buffer */
-    int                        eflags;         /*!< match flags */
+    rpmMireMode                mode;           /*!< pattern match mode */
+/*@only@*/ const char *        pattern;        /*!< pattern string */
+    int                        notmatch;       /*!< like "grep -v" */
+/*@only@*/ regex_t *   preg;           /*!< regex compiled pattern buffer */
+    int                        cflags;         /*!< regcomp(3) flags */
+    int                        eflags;         /*!< regexec(3) flags */
+    int                        fnflags;        /*!< fnmatch(3) flags */
 } * miRE;
 
 struct _rpmdbMatchIterator {
@@ -1480,14 +1512,34 @@ int rpmdbGetIteratorCount(rpmdbMatchIterator mi) {
 static int miregexec(miRE mire, const char * val)
        /*@*/
 {
-    int rc = regexec(mire->preg, val, 0, NULL, mire->eflags);
+    int rc = 0;
 
-    if (rc && rc != REG_NOMATCH) {
-       char msg[256];
-       (void) regerror(rc, mire->preg, msg, sizeof(msg)-1);
-       msg[sizeof(msg)-1] = '\0';
-       rpmError(RPMERR_REGEXEC, "%s: regexec failed: %s\n", mire->pattern, msg);
+    switch (mire->mode) {
+    case RPMMIRE_STRCMP:
+       rc = strcmp(mire->pattern, val);
+       break;
+    case RPMMIRE_DEFAULT:
+    case RPMMIRE_REGEX:
+       rc = regexec(mire->preg, val, 0, NULL, mire->eflags);
+       if (rc && rc != REG_NOMATCH) {
+           char msg[256];
+           (void) regerror(rc, mire->preg, msg, sizeof(msg)-1);
+           msg[sizeof(msg)-1] = '\0';
+           rpmError(RPMERR_REGEXEC, "%s: regexec failed: %s\n",
+                       mire->pattern, msg);
+           rc = -1;
+       }
+       break;
+    case RPMMIRE_GLOB:
+       rc = fnmatch(mire->pattern, val, mire->fnflags);
+       if (rc && rc != FNM_NOMATCH)
+           rc = -1;
+       break;
+    default:
+       rc = -1;
+       break;
     }
+
     return rc;
 }
 
@@ -1504,37 +1556,144 @@ static int mireCmp(const void * a, const void * b)
     return (mireA->tag - mireB->tag);
 }
 
-int rpmdbSetIteratorRE(rpmdbMatchIterator mi, rpmTag tag, const char * pattern)
+/**
+ * Copy pattern, escaping for appropriate mode.
+ * @param tag          rpm tag
+ * @retval modep       type of pattern match
+ * @param pattern      pattern to duplicate
+ * @return             duplicated pattern
+ */
+static /*@only*/ char * mireDup(rpmTag tag, rpmMireMode *modep,
+                       const char * pattern)
+       /*@*/
 {
+    const char * s;
+    char * pat;
+    char * t;
+    int brackets;
+    size_t nb;
+    int c;
+
+    switch (*modep) {
+    default:
+    case RPMMIRE_DEFAULT:
+       if (tag == RPMTAG_DIRNAMES || tag == RPMTAG_BASENAMES) {
+           *modep = RPMMIRE_GLOB;
+           pat = xstrdup(pattern);
+           break;
+       }
+
+       nb = strlen(pattern) + sizeof("^$");
+
+       /* periods are escaped, splats become '.*' */
+       c = '\0';
+       brackets = 0;
+       for (s = pattern; *s != '\0'; s++) {
+           switch (*s) {
+           case '.':
+           case '*':   if (!brackets) nb++;            break;
+           case '\\':  s++;                            break;
+           case '[':   brackets = 1;                   break;
+           case ']':   if (c != '[') brackets = 0;     break;
+           }
+           c = *s;
+       }
+
+       pat = t = xmalloc(nb);
+
+       if (pattern[0] != '^') *t++ = '^';
+
+       /* periods are escaped, splats become '.*' */
+       c = '\0';
+       brackets = 0;
+       for (s = pattern; *s != '\0'; s++, t++) {
+           switch (*s) {
+           case '.':   if (!brackets) *t++ = '\\';     break;
+           case '*':   if (!brackets) *t++ = '.';      break;
+           case '\\':  *t++ = *s++;                    break;
+           case '[':   brackets = 1;                   break;
+           case ']':   if (c != '[') brackets = 0;     break;
+           }
+           c = *t = *s;
+       }
+
+       if (pattern[nb-1] != '$') *t++ = '$';
+       *t = '\0';
+       *modep = RPMMIRE_REGEX;
+       break;
+    case RPMMIRE_STRCMP:
+    case RPMMIRE_REGEX:
+    case RPMMIRE_GLOB:
+       pat = xstrdup(pattern);
+       break;
+    }
+
+    return pat;
+}
+
+int rpmdbSetIteratorRE(rpmdbMatchIterator mi, rpmTag tag,
+               rpmMireMode mode, const char * pattern)
+{
+    static rpmMireMode defmode = (rpmMireMode)-1;
+    miRE mire = NULL;
     const char * allpat = NULL;
+    int notmatch = 0;
     regex_t * preg = NULL;
-    miRE mire = NULL;
-    int cflags = (REG_EXTENDED | REG_NOSUB);
+    int cflags = 0;
     int eflags = 0;
+    int fnflags = 0;
     int rc = 0;
 
+    if (defmode == (rpmMireMode)-1) {
+       const char *t = rpmExpand("%{?_query_selector_match}", NULL);
+       if (*t == '\0' || !strcmp(t, "default"))
+           defmode = RPMMIRE_DEFAULT;
+       else if (!strcmp(t, "strcmp"))
+           defmode = RPMMIRE_STRCMP;
+       else if (!strcmp(t, "regex"))
+           defmode = RPMMIRE_REGEX;
+       else if (!strcmp(t, "glob"))
+           defmode = RPMMIRE_GLOB;
+       else
+           defmode = RPMMIRE_DEFAULT;
+       t = _free(t);
+     }
+
     if (mi == NULL || pattern == NULL)
        return rc;
 
-    {  int nb = strlen(pattern);
-       char * t = xmalloc(nb + sizeof("^.$"));
-       allpat = t;
-       if (pattern[0] != '^') *t++ = '^';
+    /* Leading '!' inverts pattern match sense, like "grep -v". */
+    if (*pattern == '!') {
+       notmatch = 1;
+       pattern++;
+    }
 
-       /* XXX let's fix a common error with RE's */
-       if (pattern[0] == '*') *t++ = '.';
+    allpat = mireDup(tag, &mode, pattern);
 
-       t = stpcpy(t, pattern);
-       if (pattern[nb-1] != '$') *t++ = '$';
-       *t = '\0';
-    }
-    preg = xcalloc(1, sizeof(*preg));
-    rc = regcomp(preg, allpat, cflags);
-    if (rc) {
-       char msg[256];
-       (void) regerror(rc, preg, msg, sizeof(msg)-1);
-       msg[sizeof(msg)-1] = '\0';
-       rpmError(RPMERR_REGCOMP, "%s: regcomp failed: %s\n", allpat, msg);
+    if (mode == RPMMIRE_DEFAULT)
+       mode = defmode;
+
+    switch (mode) {
+    case RPMMIRE_DEFAULT:
+    case RPMMIRE_STRCMP:
+       break;
+    case RPMMIRE_REGEX:
+       preg = xcalloc(1, sizeof(*preg));
+       cflags = (REG_EXTENDED | REG_NOSUB);
+       rc = regcomp(preg, allpat, cflags);
+       if (rc) {
+           char msg[256];
+           (void) regerror(rc, preg, msg, sizeof(msg)-1);
+           msg[sizeof(msg)-1] = '\0';
+           rpmError(RPMERR_REGCOMP, "%s: regcomp failed: %s\n", allpat, msg);
+           goto exit;
+       }
+       break;
+    case RPMMIRE_GLOB:
+       fnflags = FNM_PATHNAME | FNM_PERIOD;
+       break;
+    default:
+       rc = -1;
        goto exit;
     }
 
@@ -1543,20 +1702,26 @@ int rpmdbSetIteratorRE(rpmdbMatchIterator mi, rpmTag tag, const char * pattern)
     mi->mi_nre++;
     
     mire->tag = tag;
+    mire->mode = mode;
     mire->pattern = allpat;
-    mire->cflags = cflags;
+    mire->notmatch = notmatch;
     mire->preg = preg;
+    mire->cflags = cflags;
     mire->eflags = eflags;
+    mire->fnflags = fnflags;
 
     (void) qsort(mi->mi_re, mi->mi_nre, sizeof(*mi->mi_re), mireCmp);
 
 exit:
     if (rc) {
-       /*@-kepttrans@*/        /* FIX: mire has kept values */
+       /*@=kepttrans@*/        /* FIX: mire has kept values */
        allpat = _free(allpat);
-       regfree(preg);
-       preg = _free(preg);
+       if (preg) {
+           regfree(preg);
+           preg = _free(preg);
+       }
        /*@=kepttrans@*/
+       mire = _free(mire);
     }
     return rc;
 }
@@ -1587,6 +1752,7 @@ static int mireSkip (const rpmdbMatchIterator mi)
     int ntags = 0;
     int nmatches = 0;
     int i, j;
+    int rc;
 
     if (mi->mi_h == NULL)      /* XXX can't happen */
        return 0;
@@ -1608,30 +1774,35 @@ static int mireSkip (const rpmdbMatchIterator mi)
            case RPM_CHAR_TYPE:
            case RPM_INT8_TYPE:
                sprintf(numbuf, "%d", (int) *u.i8p);
-               if (!miregexec(mire, numbuf))
+               rc = miregexec(mire, numbuf);
+               if ((!rc && !mire->notmatch) || (rc && mire->notmatch))
                    anymatch++;
                break;
            case RPM_INT16_TYPE:
                sprintf(numbuf, "%d", (int) *u.i16p);
-               if (!miregexec(mire, numbuf))
+               rc = miregexec(mire, numbuf);
+               if ((!rc && !mire->notmatch) || (rc && mire->notmatch))
                    anymatch++;
                break;
            case RPM_INT32_TYPE:
                sprintf(numbuf, "%d", (int) *u.i32p);
-               if (!miregexec(mire, numbuf))
+               rc = miregexec(mire, numbuf);
+               if ((!rc && !mire->notmatch) || (rc && mire->notmatch))
                    anymatch++;
                break;
            case RPM_STRING_TYPE:
-               if (!miregexec(mire, u.str))
+               rc = miregexec(mire, u.str);
+               if ((!rc && !mire->notmatch) || (rc && mire->notmatch))
                    anymatch++;
                break;
            case RPM_I18NSTRING_TYPE:
            case RPM_STRING_ARRAY_TYPE:
                for (j = 0; j < c; j++) {
-                   if (miregexec(mire, u.argv[j]))
-                       continue;
-                   anymatch++;
-                   /*@innerbreak@*/ break;
+                   rc = miregexec(mire, u.argv[j]);
+                   if ((!rc && !mire->notmatch) || (rc && mire->notmatch)) {
+                       anymatch++;
+                       /*@innerbreak@*/ break;
+                   }
                }
                break;
            case RPM_NULL_TYPE:
@@ -1659,11 +1830,11 @@ static int mireSkip (const rpmdbMatchIterator mi)
 }
 
 int rpmdbSetIteratorRelease(rpmdbMatchIterator mi, const char * release) {
-    return rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, release);
+    return rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_DEFAULT, release);
 }
 
 int rpmdbSetIteratorVersion(rpmdbMatchIterator mi, const char * version) {
-    return rpmdbSetIteratorRE(mi, RPMTAG_VERSION, version);
+    return rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_DEFAULT, version);
 }
 
 int rpmdbSetIteratorRewrite(rpmdbMatchIterator mi, int rewrite) {
@@ -2911,13 +3082,10 @@ int rpmdbRebuild(const char * rootdir)
                /*@-shadow@*/
                {   rpmdbMatchIterator mi;
                    mi = rpmdbInitIterator(newdb, RPMTAG_NAME, name, 0);
-#ifdef DYING
-                   (void) rpmdbSetIteratorVersion(mi, version);
-                   (void) rpmdbSetIteratorRelease(mi, release);
-#else
-                   (void) rpmdbSetIteratorRE(mi, RPMTAG_VERSION, version);
-                   (void) rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, release);
-#endif
+                   (void) rpmdbSetIteratorRE(mi, RPMTAG_VERSION,
+                               RPMMIRE_DEFAULT, version);
+                   (void) rpmdbSetIteratorRE(mi, RPMTAG_RELEASE,
+                               RPMMIRE_DEFAULT, release);
                    while (rpmdbNextIterator(mi)) {
                        skip = 1;
                        /*@innerbreak@*/ break;
index 60bb9ae..a0c4d29 100644 (file)
@@ -465,9 +465,7 @@ rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
 
     /* Process data in ctx->datalen chunks */
     for (; len >= ctx->datalen; buf += ctx->datalen, len -= ctx->datalen) {
-       /*@-mayaliasunique@*/
-       memcpy(ctx->in, buf, ctx->datalen);
-       /*@=mayaliasunique@*/
+       memmove(ctx->in, buf, ctx->datalen);
        if (ctx->doByteReverse)
            byteReverse(ctx->in, ctx->datalen);
        /*@-moduncon@*/
@@ -476,9 +474,7 @@ rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
     }
 
     /* Handle any remaining bytes of data. */
-    /*@-mayaliasunique@*/
-    memcpy(ctx->in, buf, len);
-    /*@=mayaliasunique@*/
+    memmove(ctx->in, buf, len);
 }
 
 void
index 0c622ee..54be52b 100644 (file)
@@ -114,27 +114,27 @@ rpm       alias --timecheck       --define '_timecheck !#:+'
 # Popt glue to preserve legacy CLI behavior.
 #
 # XXX popt exec parsing doesn't honor POPT_ARGFLAG_ONEDASH
-#rpm   exec --bp               rpmb -bp
-#rpm   exec --bc               rpmb -bc
-#rpm   exec --bi               rpmb -bi
-#rpm   exec --bl               rpmb -bl
-#rpm   exec --ba               rpmb -ba
-#rpm   exec --bb               rpmb -bb
-#rpm   exec --bs               rpmb -bs
-#rpm   exec --tp               rpmb -tp
-#rpm   exec --tc               rpmb -tc
-#rpm   exec --ti               rpmb -ti
-#rpm   exec --tl               rpmb -tl
-#rpm   exec --ta               rpmb -ta
-#rpm   exec --tb               rpmb -tb
-#rpm   exec --ts               rpmb -ts
-#rpm   exec --rebuild          rpmb --rebuild
-#rpm   exec --recompile        rpmb --recompile
-#rpm   exec --clean            rpmb --clean
-#rpm   exec --rmsource         rpmb --rmsource
-#rpm   exec --rmspec           rpmb --rmspec
-#rpm   exec --target           rpmb --target
-#rpm   exec --short-circuit    rpmb --short-circuit
+rpm    exec --bp               rpmb -bp
+rpm    exec --bc               rpmb -bc
+rpm    exec --bi               rpmb -bi
+rpm    exec --bl               rpmb -bl
+rpm    exec --ba               rpmb -ba
+rpm    exec --bb               rpmb -bb
+rpm    exec --bs               rpmb -bs
+rpm    exec --tp               rpmb -tp
+rpm    exec --tc               rpmb -tc
+rpm    exec --ti               rpmb -ti
+rpm    exec --tl               rpmb -tl
+rpm    exec --ta               rpmb -ta
+rpm    exec --tb               rpmb -tb
+rpm    exec --ts               rpmb -ts
+rpm    exec --rebuild          rpmb --rebuild
+rpm    exec --recompile        rpmb --recompile
+rpm    exec --clean            rpmb --clean
+rpm    exec --rmsource         rpmb --rmsource
+rpm    exec --rmspec           rpmb --rmspec
+rpm    exec --target           rpmb --target
+rpm    exec --short-circuit    rpmb --short-circuit
 
 rpm    exec --initdb           rpmd --initdb
 rpm    exec --rebuilddb        rpmd --rebuilddb
@@ -157,17 +157,17 @@ rpm       exec -V                 rpmv -V
 rpm    exec -y                 rpmv -y
 rpm    exec --verify           rpmv --verify
 
-#rpm   alias --with            --define "_with_!#:+       --with-!#:+"
-#rpm   alias --without         --define "_without_!#:+    --without-!#:+"
+rpm    alias --with            --define "_with_!#:+       --with-!#:+"
+rpm    alias --without         --define "_without_!#:+    --without-!#:+"
 #==============================================================================
-#rpmb  alias --dbpath          --define '_dbpath !#:+'
-#rpmb  alias --ftpport         --define '_ftpport !#:+'
-#rpmb  alias --ftpproxy        --define '_ftpproxy !#:+'
-#rpmb  alias --httpport        --define '_httpport !#:+'
-#rpmb  alias --httpproxy       --define '_httpproxy !#:+'
-#rpmb  alias --timecheck       --define '_timecheck !#:+'
-#rpmb  alias --with            --define "_with_!#:+       --with-!#:+"
-#rpmb  alias --without         --define "_without_!#:+    --without-!#:+"
+rpmb   alias --dbpath          --define '_dbpath !#:+'
+rpmb   alias --ftpport         --define '_ftpport !#:+'
+rpmb   alias --ftpproxy        --define '_ftpproxy !#:+'
+rpmb   alias --httpport        --define '_httpport !#:+'
+rpmb   alias --httpproxy       --define '_httpproxy !#:+'
+rpmb   alias --timecheck       --define '_timecheck !#:+'
+rpmb   alias --with            --define "_with_!#:+       --with-!#:+"
+rpmb   alias --without         --define "_without_!#:+    --without-!#:+"
 #==============================================================================
 rpmbuild       alias --dbpath          --define '_dbpath !#:+'
 rpmbuild       alias --ftpport         --define '_ftpport !#:+'
index 0c3d264..003f675 100644 (file)
@@ -5,8 +5,8 @@ AUTOMAKE_OPTIONS = 1.4 foreign
 EXTRA_DIST = \
        brp-compress brp-redhat brp-strip brp-strip-comment-note \
        brp-strip-shared \
-       brp-sparc64-linux check-prereqs convertrpmrc.sh find-lang.sh \
-       find-prov.pl find-req.pl cpanflute find-provides.perl \
+       brp-sparc64-linux check-prereqs convertrpmrc.sh cross-build \
+       find-lang.sh find-prov.pl find-req.pl cpanflute find-provides.perl \
        find-requires.perl get_magic.pl getpo.sh http.req \
        magic.prov magic.req perl.prov perl.req rpmdiff rpmdiff.cgi \
        rpm.daily rpm.log rpm.xinetd \