diff options
-rw-r--r-- | lib/db3.c | 10 | ||||
-rw-r--r-- | lib/dbindex.c | 22 | ||||
-rw-r--r-- | lib/dbindex.h | 12 | ||||
-rw-r--r-- | lib/install.c | 2 | ||||
-rw-r--r-- | lib/query.c | 14 | ||||
-rw-r--r-- | lib/rpmdb.c | 559 |
6 files changed, 292 insertions, 327 deletions
@@ -489,7 +489,11 @@ static int db3SearchIndex(dbiIndex dbi, const char * str, dbiIndexSet * set) } else #endif rc = db->get(db, NULL, &key, &data, 0); +#if 0 _printit = (rc == DB_NOTFOUND ? 0 : _debug); +#else + _printit = _debug; +#endif rc = cvtdberr(dbi, "db->get", rc, _printit); #else rc = db->get(db, &key, &data, 0); @@ -580,11 +584,11 @@ static int db3open(dbiIndex dbi) int rc = 0; #if defined(__USE_DB2) || defined(__USE_DB3) - char * dbhome = NULL; - char * dbfile = NULL; DB * db = NULL; - DB_ENV * dbenv = NULL; + char * dbhome; + char * dbfile; u_int32_t dbflags; + DB_ENV * dbenv = NULL; int __do_dbcursor_rmw = 0; dbhome = alloca(strlen(dbi->dbi_file) + 1); diff --git a/lib/dbindex.c b/lib/dbindex.c index 6e4e286b8..20f959f8c 100644 --- a/lib/dbindex.c +++ b/lib/dbindex.c @@ -63,8 +63,12 @@ void dbiIndexRecordOffsetSave(dbiIndexSet set, int recno, unsigned int recoff) { set->recs[recno].recOffset = recoff; } -static dbiIndex newDBI(void) { +static dbiIndex newDBI(const dbiIndex dbiTemplate) { dbiIndex dbi = xcalloc(1, sizeof(*dbi)); + + *dbi = *dbiTemplate; /* structure assignment */ + if (dbiTemplate->dbi_basename) + dbi->dbi_basename = xstrdup(dbiTemplate->dbi_basename); return dbi; } @@ -73,6 +77,7 @@ static void freeDBI( /*@only@*/ /*@null@*/ dbiIndex dbi) { if (dbi->dbi_dbenv) free(dbi->dbi_dbenv); if (dbi->dbi_dbinfo) free(dbi->dbi_dbinfo); if (dbi->dbi_file) xfree(dbi->dbi_file); + if (dbi->dbi_basename) xfree(dbi->dbi_basename); xfree(dbi); } } @@ -83,7 +88,8 @@ static struct _dbiVec *mydbvecs[] = { DB0vec, DB1vec, DB2vec, DB3vec, NULL }; -dbiIndex dbiOpenIndex(const char * urlfn, int flags, int perms, DBI_TYPE type) { +dbiIndex dbiOpenIndex(const char * urlfn, int flags, const dbiIndex dbiTemplate) +{ dbiIndex dbi; const char * filename; int rc = 0; @@ -94,12 +100,9 @@ dbiIndex dbiOpenIndex(const char * urlfn, int flags, int perms, DBI_TYPE type) { return NULL; } - dbi = newDBI(); + dbi = newDBI(dbiTemplate); dbi->dbi_file = xstrdup(filename); dbi->dbi_flags = flags; - dbi->dbi_perms = perms; - dbi->dbi_type = type; - dbi->dbi_openinfo = NULL; dbi->dbi_major = _useDbiMajor; switch (dbi->dbi_major) { @@ -213,8 +216,7 @@ int dbiUpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set) { return rc; } -int dbiAppendIndexRecord(dbiIndexSet set, - unsigned int recOffset, unsigned int fileNumber) +int dbiAppendIndexRecord(dbiIndexSet set, dbiIndexRecord rec) { set->count++; @@ -223,8 +225,8 @@ int dbiAppendIndexRecord(dbiIndexSet set, } else { set->recs = xrealloc(set->recs, set->count * sizeof(*(set->recs))); } - set->recs[set->count - 1].recOffset = recOffset; - set->recs[set->count - 1].fileNumber = fileNumber; + set->recs[set->count - 1].recOffset = rec->recOffset; + set->recs[set->count - 1].fileNumber = rec->fileNumber; return 0; } diff --git a/lib/dbindex.h b/lib/dbindex.h index 8066ba36c..67d3fa785 100644 --- a/lib/dbindex.h +++ b/lib/dbindex.h @@ -90,10 +90,13 @@ struct _dbiVec { */ struct _dbiIndex { const char * dbi_basename; /*<! last component of name */ + int dbi_rpmtag; /*<! rpm tag used for index */ + DBI_TYPE dbi_type; /*<! type of access */ int dbi_flags; /*<! flags to use on open */ int dbi_perms; /*<! file permission to use on open */ int dbi_major; /*<! Berkeley db version major */ + const char * dbi_file; /*<! name of index database */ void * dbi_db; /*<! Berkeley db[123] handle */ void * dbi_dbenv; @@ -112,12 +115,11 @@ extern "C" { * Return handle for an index database. * @param filename file name of database * @param flags type of open - * @param perm permissions on database file - * @param type one of { DBI_BTREE, DBI_HASH, DBI_RECNO } + * @param dbiTemplate template to initialize new dbiIndex * @return index database handle */ -/*@only@*/ dbiIndex dbiOpenIndex(const char * filename, int flags, int perms, - DBI_TYPE type); +/*@only@*/ dbiIndex dbiOpenIndex(const char * filename, int flags, + const dbiIndex dbiTemplate); /** * Close index database. @@ -155,7 +157,7 @@ int dbiUpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set); * @param rec item to append to set * @return 0 success (always) */ -int dbiAppendIndexRecord( /*@out@*/ dbiIndexSet set, unsigned int recOffset, unsigned int fileNumber); +int dbiAppendIndexRecord( /*@out@*/ dbiIndexSet set, dbiIndexRecord rec); /** * Create empty set of index database items. diff --git a/lib/install.c b/lib/install.c index 572ad7033..892b6f90c 100644 --- a/lib/install.c +++ b/lib/install.c @@ -916,7 +916,7 @@ int installBinaryPackage(const char * rootdir, rpmdb db, FD_t fd, Header h, rpmMessage(RPMMESS_DEBUG, _("running postinstall scripts (if any)\n")); if (runInstScript(rootdir, h, RPMTAG_POSTIN, RPMTAG_POSTINPROG, scriptArg, - flags & RPMTRANS_FLAG_NOSCRIPTS, scriptFd)) { + (flags & RPMTRANS_FLAG_NOSCRIPTS), scriptFd)) { rc = 2; goto exit; } diff --git a/lib/query.c b/lib/query.c index ef0b7dd90..69da3fbd6 100644 --- a/lib/query.c +++ b/lib/query.c @@ -634,7 +634,17 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg, break; case RPMQV_DBOFFSET: - recNumber = strtoul(arg, &end, 10); + { int mybase = 10; + const char * myarg = arg; + if (*myarg == '0') { + myarg++; + mybase = 8; + if (*myarg == 'x') { + myarg++; + mybase = 16; + } + } + recNumber = strtoul(myarg, &end, mybase); if ((*end) || (end == arg) || (recNumber == ULONG_MAX)) { fprintf(stderr, _("invalid package number: %s\n"), arg); return 1; @@ -648,7 +658,7 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg, retcode = showPackage(qva, db, h); headerFree(h); } - break; + } break; case RPMQV_PACKAGE: rc = rpmdbFindByLabel(db, arg, &matches); diff --git a/lib/rpmdb.c b/lib/rpmdb.c index 5cf1ab321..d8b8829da 100644 --- a/lib/rpmdb.c +++ b/lib/rpmdb.c @@ -24,31 +24,40 @@ extern int _noDirTokens; #define _DBI_MAJOR -1 struct _dbiIndex rpmdbi[] = { - { "packages.rpm", DBI_RECNO, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, + { "packages.rpm", 0, + DBI_RECNO, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, #define RPMDBI_PACKAGES 0 - { "nameindex.rpm", DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, + { "nameindex.rpm", RPMTAG_NAME, + DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, #define RPMDBI_NAME 1 - { "fileindex.rpm", DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, + { "fileindex.rpm", RPMTAG_BASENAMES, + DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, #define RPMDBI_FILE 2 - { "groupindex.rpm", DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, + { "groupindex.rpm", RPMTAG_GROUP, + DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, #define RPMDBI_GROUP 3 - { "requiredby.rpm", DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, + { "requiredby.rpm", RPMTAG_REQUIRENAME, + DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, #define RPMDBI_REQUIREDBY 4 - { "providesindex.rpm", DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, + { "providesindex.rpm", RPMTAG_PROVIDENAME, + DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, #define RPMDBI_PROVIDES 5 - { "conflictsindex.rpm", DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, + { "conflictsindex.rpm", RPMTAG_CONFLICTNAME, + DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, #define RPMDBI_CONFLICTS 6 - { "triggerindex.rpm", DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, + { "triggerindex.rpm", RPMTAG_TRIGGERNAME, + DBI_HASH, _DBI_FLAGS, _DBI_PERMS, _DBI_MAJOR, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, #define RPMDBI_TRIGGER 7 { NULL } +#define RPMDBI_MIN 1 /* XXX no package headers yet */ #define RPMDBI_MAX 8 }; @@ -65,23 +74,15 @@ struct _dbiIndex rpmdbi[] = { struct rpmdb_s { FD_t pkgs; -#ifdef DYING - dbiIndex nameIndex; - dbiIndex fileIndex; - dbiIndex groupIndex; - dbiIndex providesIndex; - dbiIndex requiredbyIndex; - dbiIndex conflictsIndex; - dbiIndex triggerIndex; -#else dbiIndex _dbi[RPMDBI_MAX]; -#define nameIndex _dbi[1] -#define fileIndex _dbi[2] -#define groupIndex _dbi[3] -#define providesIndex _dbi[4] -#define requiredbyIndex _dbi[5] -#define conflictsIndex _dbi[6] -#define triggerIndex _dbi[7] +#ifdef DYING +#define nameIndex _dbi[RPMDBI_NAME] +#define fileIndex _dbi[RPMDBI_FILE] +#define groupIndex _dbi[RPMDBI_GROUP] +#define requiredbyIndex _dbi[RPMDBI_REQUIREDBY] +#define providesIndex _dbi[RPMDBI_PROVIDES] +#define conflictsIndex _dbi[RPMDBI_CONFLICTS] +#define triggerIndex _dbi[RPMDBI_TRIGGER] #endif }; @@ -100,20 +101,16 @@ static void unblockSignals(void) sigprocmask(SIG_SETMASK, &signalMask, NULL); } -static int openDbFile(const char * prefix, const char * dbpath, int dbix, - int justCheck, int mode, dbiIndex * dbip) +static int openDbFile(const char * prefix, const char * dbpath, + const dbiIndex dbi, int justCheck, int mode, dbiIndex * dbip) { - dbiIndex dbi; char * filename, * fn; int len; - if (dbix < 0 || dbix >= RPMDBI_MAX) - return 1; - if (dbip == NULL) + if (dbi == NULL || dbip == NULL) return 1; *dbip = NULL; - dbi = rpmdbi + dbix; len = (prefix ? strlen(prefix) : 0) + strlen(dbpath) + strlen(dbi->dbi_basename) + 1; fn = filename = alloca(len); @@ -133,7 +130,7 @@ static int openDbFile(const char * prefix, const char * dbpath, int dbix, fn = stpcpy(fn, dbi->dbi_basename); if (!justCheck || !rpmfileexists(filename)) { - if ((*dbip = dbiOpenIndex(filename, mode, dbi->dbi_perms, dbi->dbi_type)) == NULL) + if ((*dbip = dbiOpenIndex(filename, mode, dbi)) == NULL) return 1; } @@ -143,16 +140,6 @@ static int openDbFile(const char * prefix, const char * dbpath, int dbix, static /*@only@*/ rpmdb newRpmdb(void) { rpmdb db = xcalloc(sizeof(*db), 1); -#ifdef DYING - db->pkgs = NULL; - db->nameIndex = NULL; - db->fileIndex = NULL; - db->groupIndex = NULL; - db->providesIndex = NULL; - db->requiredbyIndex = NULL; - db->conflictsIndex = NULL; - db->triggerIndex = NULL; -#endif return db; } @@ -240,59 +227,14 @@ int openDatabase(const char * prefix, const char * dbpath, rpmdb *rpmdbp, int mo } } -#ifdef DYING - rc = openDbFile(prefix, dbpath, RPMDBI_NAME, justcheck, mode, - &db->nameIndex); - - if (minimal) { - *rpmdbp = xmalloc(sizeof(struct rpmdb_s)); - if (rpmdbp) - *rpmdbp = db; /* structure assignment */ - else - rpmdbClose(db); - return 0; - } - - if (!rc) - rc = openDbFile(prefix, dbpath, RPMDBI_FILE, justcheck, mode, - &db->fileIndex); - - /* We used to store the fileindexes as complete paths, rather then - plain basenames. Let's see which version we are... */ - /* - * XXX FIXME: db->fileindex can be NULL under pathological (e.g. mixed - * XXX db1/db2 linkage) conditions. - */ - if (!justcheck && !dbiGetFirstKey(db->fileIndex, &akey)) { - if (strchr(akey, '/')) { - rpmError(RPMERR_OLDDB, _("old format database is present; " - "use --rebuilddb to generate a new format database")); - rc |= 1; - } - xfree(akey); - } - - if (!rc) - rc = openDbFile(prefix, dbpath, RPMDBI_GROUP, justcheck, mode, - &db->groupIndex); - if (!rc) - rc = openDbFile(prefix, dbpath, RPMDBI_REQUIREDBY, justcheck, mode, - &db->requiredbyIndex); - if (!rc) - rc = openDbFile(prefix, dbpath, RPMDBI_PROVIDES, justcheck, mode, - &db->providesIndex); - if (!rc) - rc = openDbFile(prefix, dbpath, RPMDBI_CONFLICTS, justcheck, mode, - &db->conflictsIndex); - if (!rc) - rc = openDbFile(prefix, dbpath, RPMDBI_TRIGGER, justcheck, mode, - &db->triggerIndex); -#else { int dbix; rc = 0; - for (dbix = 1; rc == 0 && dbix < RPMDBI_MAX; dbix++) { - rc = openDbFile(prefix, dbpath, dbix, justcheck, mode, + for (dbix = RPMDBI_MIN; rc == 0 && dbix < RPMDBI_MAX; dbix++) { + dbiIndex dbiTemplate; + + dbiTemplate = rpmdbi + dbix; + rc = openDbFile(prefix, dbpath, dbiTemplate, justcheck, mode, &db->_dbi[dbix]); if (rc) continue; @@ -316,7 +258,7 @@ int openDatabase(const char * prefix, const char * dbpath, rpmdb *rpmdbp, int mo * XXX FIXME: db->fileindex can be NULL under pathological (e.g. mixed * XXX db1/db2 linkage) conditions. */ - if (!justcheck && !dbiGetFirstKey(db->fileIndex, &akey)) { + if (!justcheck && !dbiGetFirstKey(db->_dbi[RPMDBI_FILE], &akey)) { if (strchr(akey, '/')) { rpmError(RPMERR_OLDDB, _("old format database is present; " "use --rebuilddb to generate a new format database")); @@ -329,7 +271,6 @@ int openDatabase(const char * prefix, const char * dbpath, rpmdb *rpmdbp, int mo } } } -#endif /* DYING */ if (rc || justcheck || rpmdbp == NULL) rpmdbClose(db); @@ -374,26 +315,15 @@ int rpmdbInit (const char * prefix, int perms) void rpmdbClose (rpmdb db) { -#ifdef DYING - if (db->pkgs != NULL) Fclose(db->pkgs); - if (db->fileIndex) dbiCloseIndex(db->fileIndex); - if (db->groupIndex) dbiCloseIndex(db->groupIndex); - if (db->nameIndex) dbiCloseIndex(db->nameIndex); - if (db->providesIndex) dbiCloseIndex(db->providesIndex); - if (db->requiredbyIndex) dbiCloseIndex(db->requiredbyIndex); - if (db->conflictsIndex) dbiCloseIndex(db->conflictsIndex); - if (db->triggerIndex) dbiCloseIndex(db->triggerIndex); -#else int dbix; if (db->pkgs != NULL) Fclose(db->pkgs); - for (dbix = 1; dbix < RPMDBI_MAX; dbix++) { + for (dbix = RPMDBI_MIN; dbix < RPMDBI_MAX; dbix++) { if (db->_dbi[dbix] == NULL) continue; dbiCloseIndex(db->_dbi[dbix]); db->_dbi[dbix] = NULL; } -#endif free(db); } @@ -471,10 +401,12 @@ int rpmdbFindByFile(rpmdb db, const char * filespec, dbiIndexSet * matches) { const char * dirName; const char * baseName; - fingerPrint fp1, fp2; - dbiIndexSet allMatches = NULL; - int i, rc; fingerPrintCache fpc; + fingerPrint fp1; + dbiIndexSet allMatches = NULL; + dbiIndexRecord rec = NULL; + int i; + int rc; *matches = NULL; if ((baseName = strrchr(filespec, '/')) != NULL) { @@ -494,7 +426,7 @@ int rpmdbFindByFile(rpmdb db, const char * filespec, dbiIndexSet * matches) fpc = fpCacheCreate(20); fp1 = fpLookup(fpc, dirName, baseName, 1); - rc = dbiSearchIndex(db->fileIndex, baseName, &allMatches); + rc = dbiSearchIndex(db->_dbi[RPMDBI_FILE], baseName, &allMatches); if (rc) { dbiFreeIndexSet(allMatches); allMatches = NULL; @@ -503,6 +435,7 @@ int rpmdbFindByFile(rpmdb db, const char * filespec, dbiIndexSet * matches) } *matches = dbiCreateIndexSet(); + rec = dbiReturnIndexRecordInstance(0, 0); i = 0; while (i < dbiIndexSetCount(allMatches)) { const char ** baseNames, ** dirNames; @@ -524,11 +457,15 @@ int rpmdbFindByFile(rpmdb db, const char * filespec, dbiIndexSet * matches) (void **) &dirNames, NULL); do { + fingerPrint fp2; int num = dbiIndexRecordFileNumber(allMatches, i); fp2 = fpLookup(fpc, dirNames[dirIndexes[num]], baseNames[num], 1); - if (FP_EQUAL(fp1, fp2)) - dbiAppendIndexRecord(*matches, dbiIndexRecordOffset(allMatches, i), dbiIndexRecordFileNumber(allMatches, i)); + if (FP_EQUAL(fp1, fp2)) { + rec->recOffset = dbiIndexRecordOffset(allMatches, i); + rec->fileNumber = dbiIndexRecordFileNumber(allMatches, i); + dbiAppendIndexRecord(*matches, rec); + } prevoff = recoff; i++; @@ -541,6 +478,10 @@ int rpmdbFindByFile(rpmdb db, const char * filespec, dbiIndexSet * matches) headerFree(h); } + if (rec) { + dbiFreeIndexRecordInstance(rec); + rec = NULL; + } if (allMatches) { dbiFreeIndexSet(allMatches); allMatches = NULL; @@ -558,27 +499,27 @@ int rpmdbFindByFile(rpmdb db, const char * filespec, dbiIndexSet * matches) } int rpmdbFindByProvides(rpmdb db, const char * filespec, dbiIndexSet * matches) { - return dbiSearchIndex(db->providesIndex, filespec, matches); + return dbiSearchIndex(db->_dbi[RPMDBI_PROVIDES], filespec, matches); } int rpmdbFindByRequiredBy(rpmdb db, const char * filespec, dbiIndexSet * matches) { - return dbiSearchIndex(db->requiredbyIndex, filespec, matches); + return dbiSearchIndex(db->_dbi[RPMDBI_REQUIREDBY], filespec, matches); } int rpmdbFindByConflicts(rpmdb db, const char * filespec, dbiIndexSet * matches) { - return dbiSearchIndex(db->conflictsIndex, filespec, matches); + return dbiSearchIndex(db->_dbi[RPMDBI_CONFLICTS], filespec, matches); } int rpmdbFindByTriggeredBy(rpmdb db, const char * filespec, dbiIndexSet * matches) { - return dbiSearchIndex(db->triggerIndex, filespec, matches); + return dbiSearchIndex(db->_dbi[RPMDBI_TRIGGER], filespec, matches); } int rpmdbFindByGroup(rpmdb db, const char * group, dbiIndexSet * matches) { - return dbiSearchIndex(db->groupIndex, group, matches); + return dbiSearchIndex(db->_dbi[RPMDBI_GROUP], group, matches); } int rpmdbFindPackage(rpmdb db, const char * name, dbiIndexSet * matches) { - return dbiSearchIndex(db->nameIndex, name, matches); + return dbiSearchIndex(db->_dbi[RPMDBI_NAME], name, matches); } static void removeIndexEntry(dbiIndex dbi, const char * key, dbiIndexRecord rec, @@ -590,9 +531,10 @@ static void removeIndexEntry(dbiIndex dbi, const char * key, dbiIndexRecord rec, rc = dbiSearchIndex(dbi, key, &matches); switch (rc) { case 0: - if (dbiRemoveIndexRecord(matches, rec) && !tolerant) { - rpmError(RPMERR_DBCORRUPT, _("package %s not listed in %s"), - key, idxName); + if (dbiRemoveIndexRecord(matches, rec)) { + if (!tolerant) + rpmError(RPMERR_DBCORRUPT, _("package not found with key \"%s\" in %s"), + key, idxName); } else { dbiUpdateIndex(dbi, key, matches); /* errors from above will be reported from dbindex.c */ @@ -600,7 +542,7 @@ static void removeIndexEntry(dbiIndex dbi, const char * key, dbiIndexRecord rec, break; case 1: if (!tolerant) - rpmError(RPMERR_DBCORRUPT, _("package %s not found in %s"), + rpmError(RPMERR_DBCORRUPT, _("key \"%s\" not found in %s"), key, idxName); break; case 2: @@ -615,125 +557,103 @@ static void removeIndexEntry(dbiIndex dbi, const char * key, dbiIndexRecord rec, int rpmdbRemove(rpmdb db, unsigned int offset, int tolerant) { Header h; - char * name, * group; - int type; - unsigned int count; - dbiIndexRecord rec; - char ** baseNames, ** providesList, ** requiredbyList; - char ** conflictList, ** triggerList; - int i; - h = rpmdbGetRecord(db, offset); if (h == NULL) { - rpmError(RPMERR_DBCORRUPT, _("cannot read header at %d for uninstall"), + rpmError(RPMERR_DBCORRUPT, _("rpmdbRemove: cannot read header at 0x%x"), offset); return 1; } - rec = dbiReturnIndexRecordInstance(offset, 0); - blockSignals(); - if (!headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &count)) { - rpmError(RPMERR_DBCORRUPT, _("package has no name")); - } else { - rpmMessage(RPMMESS_DEBUG, _("removing name index\n")); - removeIndexEntry(db->nameIndex, name, rec, tolerant, "name index"); - } - - if (!headerGetEntry(h, RPMTAG_GROUP, &type, (void **) &group, &count)) { - rpmMessage(RPMMESS_DEBUG, _("package has no group\n")); - } else { - rpmMessage(RPMMESS_DEBUG, _("removing group index\n")); - removeIndexEntry(db->groupIndex, group, rec, tolerant, "group index"); - } + { int dbix; + dbiIndexRecord rec = dbiReturnIndexRecordInstance(offset, 0); + + for (dbix = RPMDBI_MIN; dbix < RPMDBI_MAX; dbix++) { + dbiIndex dbi; + const char **rpmvals = NULL; + int rpmtype = 0; + int rpmcnt = 0; + + dbi = db->_dbi[dbix]; + if (!headerGetEntry(h, dbi->dbi_rpmtag, &rpmtype, + (void **) &rpmvals, &rpmcnt)) { + rpmMessage(RPMMESS_DEBUG, _("removing 0 %s entries.\n"), + tagName(dbi->dbi_rpmtag)); + continue; + } - if (headerGetEntry(h, RPMTAG_PROVIDENAME, &type, (void **) &providesList, - &count)) { - for (i = 0; i < count; i++) { - rpmMessage(RPMMESS_DEBUG, _("removing provides index for %s\n"), - providesList[i]); - removeIndexEntry(db->providesIndex, providesList[i], rec, tolerant, - "providesfile index"); - } - free(providesList); - } + if (rpmtype == RPM_STRING_TYPE) { + rpmMessage(RPMMESS_DEBUG, _("removing \"%s\" from %s index.\n"), + (const char *)rpmvals, tagName(dbi->dbi_rpmtag)); + + removeIndexEntry(dbi, (const char *)rpmvals, + rec, tolerant, dbi->dbi_basename); + } else { + int i, mytolerant; + + rpmMessage(RPMMESS_DEBUG, _("removing %d entries in %s index:\n"), + rpmcnt, tagName(dbi->dbi_rpmtag)); + + for (i = 0; i < rpmcnt; i++) { + rpmMessage(RPMMESS_DEBUG, _("\t%6d %s\n"), + i, rpmvals[i]); + + mytolerant = tolerant; + rec->fileNumber = 0; + + switch (dbi->dbi_rpmtag) { + case RPMTAG_BASENAMES: + rec->fileNumber = i; + break; + /* + * There could be dups in the sorted list. Rather then + * sort the list, be tolerant of missing entries as they + * should just indicate duplicated entries. + */ + case RPMTAG_REQUIRENAME: + case RPMTAG_TRIGGERNAME: + mytolerant = 1; + break; + } - if (headerGetEntry(h, RPMTAG_REQUIRENAME, &type, (void **) &requiredbyList, - &count)) { - /* There could be dups in requiredByLIst, and the list is sorted. - Rather then sort the list, be tolerant of missing entries - as they should just indicate duplicated requirements. */ - - for (i = 0; i < count; i++) { - rpmMessage(RPMMESS_DEBUG, _("removing requiredby index for %s\n"), - requiredbyList[i]); - removeIndexEntry(db->requiredbyIndex, requiredbyList[i], rec, - 1, "requiredby index"); - } - free(requiredbyList); - } + removeIndexEntry(dbi, rpmvals[i], + rec, mytolerant, dbi->dbi_basename); + } + } - if (headerGetEntry(h, RPMTAG_TRIGGERNAME, &type, (void **) &triggerList, - &count)) { - /* triggerList often contains duplicates */ - for (i = 0; i < count; i++) { - rpmMessage(RPMMESS_DEBUG, _("removing trigger index for %s\n"), - triggerList[i]); - removeIndexEntry(db->triggerIndex, triggerList[i], rec, - 1, "trigger index"); - } - free(triggerList); - } + dbiSyncIndex(dbi); - if (headerGetEntry(h, RPMTAG_CONFLICTNAME, &type, (void **) &conflictList, - &count)) { - for (i = 0; i < count; i++) { - rpmMessage(RPMMESS_DEBUG, _("removing conflict index for %s\n"), - conflictList[i]); - removeIndexEntry(db->conflictsIndex, conflictList[i], rec, - tolerant, "conflict index"); - } - free(conflictList); - } - - if (headerGetEntry(h, RPMTAG_BASENAMES, &type, (void **) &baseNames, - &count)) { - for (i = 0; i < count; i++) { - rpmMessage(RPMMESS_DEBUG, _("removing file index for %s\n"), - baseNames[i]); - /* structure assignment */ - rec = dbiReturnIndexRecordInstance(offset, i); - removeIndexEntry(db->fileIndex, baseNames[i], rec, tolerant, - "file index"); + switch (rpmtype) { + case RPM_STRING_ARRAY_TYPE: + case RPM_I18NSTRING_TYPE: + xfree(rpmvals); + rpmvals = NULL; + break; + } + rpmtype = 0; + rpmcnt = 0; } - free(baseNames); - } else { - rpmMessage(RPMMESS_DEBUG, _("package has no files\n")); + dbiFreeIndexRecordInstance(rec); } fadFree(db->pkgs, offset); - dbiSyncIndex(db->nameIndex); - dbiSyncIndex(db->groupIndex); - dbiSyncIndex(db->fileIndex); - unblockSignals(); - dbiFreeIndexRecordInstance(rec); headerFree(h); return 0; } -static int addIndexEntry(dbiIndex dbi, const char *index, unsigned int offset, - unsigned int fileNumber) +static int addIndexEntry(dbiIndex dbi, const char *index, dbiIndexRecord rec) { dbiIndexSet set = NULL; int rc; rc = dbiSearchIndex(dbi, index, &set); + switch (rc) { case -1: /* error */ if (set) { @@ -749,7 +669,7 @@ static int addIndexEntry(dbiIndex dbi, const char *index, unsigned int offset, break; } - dbiAppendIndexRecord(set, offset, fileNumber); + dbiAppendIndexRecord(set, rec); if (dbiUpdateIndex(dbi, index, set)) exit(EXIT_FAILURE); /* XXX W2DO? return 1; */ @@ -761,121 +681,140 @@ static int addIndexEntry(dbiIndex dbi, const char *index, unsigned int offset, return 0; } -int rpmdbAdd(rpmdb db, Header dbentry) +int rpmdbAdd(rpmdb db, Header h) { - unsigned int dboffset; - unsigned int i, j; const char ** baseNames; - const char ** providesList; - const char ** requiredbyList; - const char ** conflictList; - const char ** triggerList; - const char * name; - const char * group; - int count = 0, providesCount = 0, requiredbyCount = 0, conflictCount = 0; - int triggerCount = 0; + int count = 0; int type; - int newSize; + unsigned int offset; int rc = 0; - headerGetEntry(dbentry, RPMTAG_NAME, &type, (void **) &name, &count); - headerGetEntry(dbentry, RPMTAG_GROUP, &type, (void **) &group, &count); - - if (!group) group = "Unknown"; - - count = 0; + /* + * If old style filenames is requested, the basenames need to be + * retrieved early, and the header needs to be converted before + * being written to the package header database. + */ - headerGetEntry(dbentry, RPMTAG_BASENAMES, &type, (void **) + headerGetEntry(h, RPMTAG_BASENAMES, &type, (void **) &baseNames, &count); - if (_noDirTokens) { - const char ** newBaseNames; - char * data; - int len; - len = count * sizeof(*baseNames); - for (i = 0; i < count; i++) - len += strlen(baseNames[i]) + 1; - newBaseNames = xmalloc(len); - data = (char *) newBaseNames + count; - for (i = 0; i < count; i++) { - newBaseNames[i] = data; - data = stpcpy(data, baseNames[i]); - *data++ = '\0'; - } - expandFilelist(dbentry); - } - - headerGetEntry(dbentry, RPMTAG_PROVIDENAME, &type, (void **) &providesList, - &providesCount); - headerGetEntry(dbentry, RPMTAG_REQUIRENAME, &type, - (void **) &requiredbyList, &requiredbyCount); - headerGetEntry(dbentry, RPMTAG_CONFLICTNAME, &type, - (void **) &conflictList, &conflictCount); - headerGetEntry(dbentry, RPMTAG_TRIGGERNAME, &type, - (void **) &triggerList, &triggerCount); + if (_noDirTokens) + expandFilelist(h); blockSignals(); - newSize = headerSizeof(dbentry, HEADER_MAGIC_NO); - dboffset = fadAlloc(db->pkgs, newSize); - if (!dboffset) { - rc = 1; - } else { - (void)Fseek(db->pkgs, dboffset, SEEK_SET); - fdSetContentLength(db->pkgs, newSize); - rc = headerWrite(db->pkgs, dbentry, HEADER_MAGIC_NO); - fdSetContentLength(db->pkgs, -1); - } + { int newSize; + newSize = headerSizeof(h, HEADER_MAGIC_NO); + offset = fadAlloc(db->pkgs, newSize); + if (offset == 0) { + rc = 1; + } else { + (void)Fseek(db->pkgs, offset, SEEK_SET); + fdSetContentLength(db->pkgs, newSize); + rc = headerWrite(db->pkgs, h, HEADER_MAGIC_NO); + fdSetContentLength(db->pkgs, -1); + } - if (rc) { - rpmError(RPMERR_DBCORRUPT, _("cannot allocate space for database")); - goto exit; + if (rc) { + rpmError(RPMERR_DBCORRUPT, _("cannot allocate space for database")); + goto exit; + } } - /* Now update the appropriate indexes */ - if (addIndexEntry(db->nameIndex, name, dboffset, 0)) - rc = 1; - if (addIndexEntry(db->groupIndex, group, dboffset, 0)) - rc = 1; + /* Now update the indexes */ - for (i = 0; i < triggerCount; i++) { - /* don't add duplicates */ - for (j = 0; j < i; j++) - if (!strcmp(triggerList[i], triggerList[j])) break; - if (j == i) - rc += addIndexEntry(db->triggerIndex, triggerList[i], dboffset, 0); - } + { int dbix; + dbiIndexRecord rec = dbiReturnIndexRecordInstance(offset, 0); + + for (dbix = RPMDBI_MIN; dbix < RPMDBI_MAX; dbix++) { + dbiIndex dbi; + const char **rpmvals = NULL; + int rpmtype = 0; + int rpmcnt = 0; + + dbi = db->_dbi[dbix]; + + /* XXX preserve legacy behavior */ + switch (dbi->dbi_rpmtag) { + case RPMTAG_BASENAMES: + rpmtype = type; + rpmvals = baseNames; + rpmcnt = count; + break; + default: + headerGetEntry(h, dbi->dbi_rpmtag, &rpmtype, + (void **) &rpmvals, &rpmcnt); + break; + } - for (i = 0; i < conflictCount; i++) - rc += addIndexEntry(db->conflictsIndex, conflictList[i], dboffset, 0); + if (rpmcnt <= 0) { + if (dbi->dbi_rpmtag != RPMTAG_GROUP) { + rpmMessage(RPMMESS_DEBUG, _("adding 0 %s entries.\n"), + tagName(dbi->dbi_rpmtag)); + continue; + } - for (i = 0; i < requiredbyCount; i++) - rc += addIndexEntry(db->requiredbyIndex, requiredbyList[i], - dboffset, 0); + /* XXX preserve legacy behavior */ + rpmtype = RPM_STRING_TYPE; + rpmvals = (const char **) "Unknown"; + rpmcnt = 1; + } - for (i = 0; i < providesCount; i++) - rc += addIndexEntry(db->providesIndex, providesList[i], dboffset, 0); + if (rpmtype == RPM_STRING_TYPE) { + rpmMessage(RPMMESS_DEBUG, _("adding \"%s\" to %s index.\n"), + (const char *)rpmvals, tagName(dbi->dbi_rpmtag)); + + rc += addIndexEntry(dbi, (const char *)rpmvals, rec); + } else { + int i, j; + + rpmMessage(RPMMESS_DEBUG, _("adding %d entries to %s index:\n"), + rpmcnt, tagName(dbi->dbi_rpmtag)); + + for (i = 0; i < rpmcnt; i++) { + rpmMessage(RPMMESS_DEBUG, _("\t%6d %s\n"), + i, rpmvals[i]); + + rec->fileNumber = 0; + + switch (dbi->dbi_rpmtag) { + case RPMTAG_BASENAMES: + rec->fileNumber = i; + break; + case RPMTAG_TRIGGERNAME: /* don't add duplicates */ + if (i == 0) + break; + for (j = 0; j < i; j++) { + if (!strcmp(rpmvals[i], rpmvals[j])) + break; + } + if (j < i) + continue; + break; + } - for (i = 0; i < count; i++) { - rc += addIndexEntry(db->fileIndex, baseNames[i], dboffset, i); - } + rc += addIndexEntry(dbi, rpmvals[i], rec); + } + } + + dbiSyncIndex(dbi); - dbiSyncIndex(db->nameIndex); - dbiSyncIndex(db->groupIndex); - dbiSyncIndex(db->fileIndex); - dbiSyncIndex(db->providesIndex); - dbiSyncIndex(db->requiredbyIndex); - dbiSyncIndex(db->triggerIndex); + switch (dbi->dbi_rpmtype) { + case RPM_STRING_ARRAY_TYPE: + case RPM_I18NSTRING_TYPE: + xfree(rpmvals); + rpmvals = NULL; + break; + } + rpmtype = 0; + rpmcnt = 0; + } + dbiFreeIndexRecordInstance(rec); + } exit: unblockSignals(); - if (requiredbyCount) free(requiredbyList); - if (providesCount) free(providesList); - if (conflictCount) free(conflictList); - if (triggerCount) free(triggerList); - if (count) free(baseNames); - return rc; } @@ -1019,6 +958,7 @@ int rpmdbFindFpList(rpmdb db, fingerPrint * fpList, dbiIndexSet * matchList, const char ** fullBaseNames; int_32 * dirIndexes, * fullDirIndexes; fingerPrintCache fpc; + dbiIndexRecord rec = NULL; /* this may be worth batching by baseName, but probably not as baseNames are quite unique as it is */ @@ -1028,7 +968,7 @@ int rpmdbFindFpList(rpmdb db, fingerPrint * fpList, dbiIndexSet * matchList, /* Gather all matches from the database */ for (i = 0; i < numItems; i++) { dbiIndexSet matches = NULL; - switch (dbiSearchIndex(db->fileIndex, fpList[i].baseName, &matches)) { + switch (dbiSearchIndex(db->_dbi[RPMDBI_FILE], fpList[i].baseName, &matches)) { default: break; case 2: @@ -1071,6 +1011,8 @@ int rpmdbFindFpList(rpmdb db, fingerPrint * fpList, dbiIndexSet * matchList, fpc = fpCacheCreate(numIntMatches); + rec = dbiReturnIndexRecordInstance(0, 0); + /* For each set of files matched in a package ... */ for (start = 0; start < numIntMatches; start = end) { struct intMatch * im; @@ -1116,10 +1058,14 @@ int rpmdbFindFpList(rpmdb db, fingerPrint * fpList, dbiIndexSet * matchList, free(dirIndexes); /* Add db (recnum,filenum) to list for fingerprint matches. */ + for (i = 0; i < num; i++) { j = im[i].fpNum; - if (FP_EQUAL_DIFFERENT_CACHE(fps[i], fpList[j])) - dbiAppendIndexRecord(matchList[j], im[i].recOffset, im[i].fileNumber); + if (FP_EQUAL_DIFFERENT_CACHE(fps[i], fpList[j])) { + rec->recOffset = im[i].recOffset; + rec->fileNumber = im[i].fileNumber; + dbiAppendIndexRecord(matchList[j], rec); + } } headerFree(h); @@ -1127,6 +1073,7 @@ int rpmdbFindFpList(rpmdb db, fingerPrint * fpList, dbiIndexSet * matchList, free(fps); } + dbiFreeIndexRecordInstance(rec); fpCacheFree(fpc); free(intMatches); |