--- rpm-4.4.2/rpmdb/db3.c.mismatch 2008-09-29 12:25:56.000000000 -0400 +++ rpm-4.4.2/rpmdb/db3.c 2008-09-29 12:30:02.000000000 -0400 @@ -281,6 +281,7 @@ static int db_init(dbiIndex dbi, const c DB_ENV *dbenv = NULL; int eflags; int rc; + int xx; if (dbenvp == NULL) return 1; @@ -434,7 +435,12 @@ static int db_init(dbiIndex dbi, const c #else rc = dbenv->open(dbenv, dbhome, NULL, eflags, dbi->dbi_perms); #endif - rc = cvtdberr(dbi, "dbenv->open", rc, _debug); + xx = _debug; +#if defined(DB_VERSION_MISMATCH) + if (rc == DB_VERSION_MISMATCH) xx = 0; +#endif + if (rc == EINVAL) xx = 0; + rc = cvtdberr(dbi, "dbenv->open", rc, xx); if (rc) goto errxit; @@ -446,7 +452,6 @@ static int db_init(dbiIndex dbi, const c errxit: if (dbenv) { - int xx; xx = dbenv->close(dbenv, 0); xx = cvtdberr(dbi, "dbenv->close", xx, _debug); } @@ -1122,7 +1127,37 @@ static int db3open(rpmdb rpmdb, rpmTag r /*@-mods@*/ if (rpmdb->db_dbenv == NULL) { rc = db_init(dbi, dbhome, dbfile, dbsubfile, &dbenv); - if (rc == 0) { + switch (rc) { + default: + break; +#if defined(DB_VERSION_MISMATCH) /* Nuke __db* files and retry open once. */ + case DB_VERSION_MISMATCH: +#endif + case EINVAL: + if (getuid() != 0) + break; + { char * filename = alloca(BUFSIZ); + struct stat st; + int i; + + for (i = 0; i < 16; i++) { + sprintf(filename, "%s/__db.%03d", dbhome, i); + (void)rpmCleanPath(filename); + if (Stat(filename, &st) + && (errno == ENOENT || errno == EINVAL)) + continue; + xx = Unlink(filename); + } + } + dbi->dbi_oeflags |= DB_CREATE; + dbi->dbi_eflags &= ~DB_JOINENV; + rc = db_init(dbi, dbhome, dbfile, dbsubfile, &dbenv); + /* XXX db_init EINVAL was masked. */ + rc = cvtdberr(dbi, "dbenv->open", rc, _debug); + if (rc) + break; + /*@fallthrough@*/ + case 0: rpmdb->db_dbenv = dbenv; rpmdb->db_opens = 1; }