--- 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;
 	    }
