summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/db3.c10
-rw-r--r--lib/dbindex.c22
-rw-r--r--lib/dbindex.h12
-rw-r--r--lib/install.c2
-rw-r--r--lib/query.c14
-rw-r--r--lib/rpmdb.c559
6 files changed, 292 insertions, 327 deletions
diff --git a/lib/db3.c b/lib/db3.c
index b3b48b6fd..83a67c7ea 100644
--- a/lib/db3.c
+++ b/lib/db3.c
@@ -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);