From: jbj Date: Fri, 15 Jun 2001 04:56:33 +0000 (+0000) Subject: - fix: db1 end-of-file not detected in legacy compatible way. X-Git-Tag: tznext/4.11.0.1.tizen20130304~7750 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f0d2abd2bcb74ab18645355ba45189abe77f38bf;p=tools%2Flibrpm-tizen.git - 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 (#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 --- diff --git a/CHANGES b/CHANGES index ff722fb..8167408 100644 --- a/CHANGES +++ b/CHANGES @@ -102,6 +102,12 @@ - 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 (#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. diff --git a/Makefile.am b/Makefile.am index 0140ef8..8533bfb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 $@ diff --git a/lib/header.c b/lib/header.c index ef98e20..5a1c5ee 100644 --- a/lib/header.c +++ b/lib/header.c @@ -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; diff --git a/lib/psm.c b/lib/psm.c index 9998c72..57a2ef7 100644 --- 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) diff --git a/lib/query.c b/lib/query.c index b9bbb2b..c25d37a 100644 --- a/lib/query.c +++ b/lib/query.c @@ -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; diff --git a/lib/rpmlib.h b/lib/rpmlib.h index 557a566..2bb66da 100644 --- a/lib/rpmlib.h +++ b/lib/rpmlib.h @@ -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) diff --git a/lib/transaction.c b/lib/transaction.c index da80a78..4b5d307 100644 --- a/lib/transaction.c +++ b/lib/transaction.c @@ -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); diff --git a/macros.in b/macros.in index 1b2e601..9c87781 100644 --- 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 @@ -227,6 +227,17 @@ # #%_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 \ diff --git a/rpm.spec.in b/rpm.spec.in index 44f88f9..5d1b2f8 100644 --- a/rpm.spec.in +++ b/rpm.spec.in @@ -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 diff --git a/rpmdb/db1.c b/rpmdb/db1.c index eb451e6..a653b3a 100644 --- a/rpmdb/db1.c +++ b/rpmdb/db1.c @@ -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; diff --git a/rpmdb/falloc.c b/rpmdb/falloc.c index 91713c3..777c776 100644 --- a/rpmdb/falloc.c +++ b/rpmdb/falloc.c @@ -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; } diff --git a/rpmdb/rpmdb.c b/rpmdb/rpmdb.c index a5c067a..a825954 100644 --- a/rpmdb/rpmdb.c +++ b/rpmdb/rpmdb.c @@ -11,6 +11,7 @@ static int _debug = 0; #include #include +#include #include #include @@ -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; diff --git a/rpmio/digest.c b/rpmio/digest.c index 60bb9ae..a0c4d29 100644 --- a/rpmio/digest.c +++ b/rpmio/digest.c @@ -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 diff --git a/rpmpopt.in b/rpmpopt.in index 0c622ee..54be52b 100644 --- a/rpmpopt.in +++ b/rpmpopt.in @@ -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 !#:+' diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 0c3d264..003f675 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -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 \