00001
00006
00007 static int _debug = 1;
00008
00009 #include "system.h"
00010
00011 #if defined(HAVE_FTOK) && defined(HAVE_SYS_IPC_H)
00012 #include <sys/ipc.h>
00013 #endif
00014
00015 #include <rpmio.h>
00016 #include <rpmlog.h>
00017 #include <rpmmacro.h>
00018 #include <rpmurl.h>
00019
00020 #define _RPMTAG_INTERNAL
00021 #include <rpmtag.h>
00022 #define _RPMDB_INTERNAL
00023 #include <rpmdb.h>
00024
00025 #include "debug.h"
00026
00027 #if !defined(DB_CLIENT)
00028 #define DB_CLIENT DB_RPCCLIENT
00029 #endif
00030
00031
00032
00033
00034
00038
00039 struct dbiHStats_s {
00040 unsigned int hash_magic;
00041 unsigned int hash_version;
00042 unsigned int hash_nkeys;
00043 unsigned int hash_ndata;
00044 unsigned int hash_pagesize;
00045 unsigned int hash_nelem;
00046 unsigned int hash_ffactor;
00047 unsigned int hash_buckets;
00048 unsigned int hash_free;
00049 unsigned int hash_bfree;
00050 unsigned int hash_bigpages;
00051 unsigned int hash_big_bfree;
00052 unsigned int hash_overflows;
00053 unsigned int hash_ovfl_free;
00054 unsigned int hash_dup;
00055 unsigned int hash_dup_free;
00056 };
00057
00061 struct dbiBStats_s {
00062 unsigned int bt_magic;
00063 unsigned int bt_version;
00064 unsigned int bt_nkeys;
00065 unsigned int bt_ndata;
00066 unsigned int bt_pagesize;
00067 unsigned int bt_minkey;
00068 unsigned int bt_re_len;
00069 unsigned int bt_re_pad;
00070 unsigned int bt_levels;
00071 unsigned int bt_int_pg;
00072 unsigned int bt_leaf_pg;
00073 unsigned int bt_dup_pg;
00074 unsigned int bt_over_pg;
00075 unsigned int bt_free;
00076 unsigned int bt_int_pgfree;
00077 unsigned int bt_leaf_pgfree;
00078 unsigned int bt_dup_pgfree;
00079 unsigned int bt_over_pgfree;
00080 };
00081
00082
00083 #ifdef NOTNOW
00084 static const char * bfstring(unsigned int x, const char * xbf)
00085 {
00086 const char * s = xbf;
00087 static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
00088 static char buf[BUFSIZ];
00089 char * t, * te;
00090 unsigned radix;
00091 unsigned c, i, k;
00092
00093 radix = (s != NULL ? *s++ : 16);
00094
00095 if (radix <= 1 || radix >= 32)
00096 radix = 16;
00097
00098 t = buf;
00099 switch (radix) {
00100 case 8: *t++ = '0'; break;
00101 case 16: *t++ = '0'; *t++ = 'x'; break;
00102 }
00103
00104 i = 0;
00105 k = x;
00106 do { i++; k /= radix; } while (k);
00107
00108 te = t + i;
00109
00110 k = x;
00111 do { --i; t[i] = digits[k % radix]; k /= radix; } while (k);
00112
00113 t = te;
00114 i = '<';
00115 if (s != NULL)
00116 while ((c = *s++) != '\0') {
00117 if (c > ' ') continue;
00118
00119 k = (1 << (c - 1));
00120 if (!(x & k)) continue;
00121
00122 if (t == te) *t++ = '=';
00123
00124 *t++ = i;
00125 i = ',';
00126 while (*s > ' ')
00127 *t++ = *s++;
00128 }
00129 if (t > te) *t++ = '>';
00130 *t = '\0';
00131 return buf;
00132 }
00133
00134
00135 static const char * dbtFlags =
00136 "\20\1APPMALLOC\2ISSET\3MALLOC\4PARTIAL\5REALLOC\6USERMEM\7DUPOK";
00137
00138 static const char * dbenvOpenFlags =
00139 "\20\1CREATE\2DURABLE_UNKNOWN\3FORCE\4MULTIVERSION\5NOMMAP\6RDONLY\7RECOVER\10THREAD\11TRUNCATE\12TXN_NOSYNC\13TXN_NOT_DURABLEi\14TXN_WRITE_NOSYNC\15USE_ENVIRON\16USE_ENVIRON_ROOT\17CDB\20LOCK\21LOG\22MPOOL\23REP\24TXN\25LOCKDOWN\26PRIVATE\27RECOVER_FATAL\30REGISTER\31SYSTEM_MEM";
00140
00141 static const char * dbOpenFlags =
00142 "\20\1CREATE\2DURABLE_UNKNOWN\3FORCE\4MULTIVERSION\5NOMMAP\6RDONLY\7RECOVER\10THREAD\11TRUNCATE\12TXN_NOSYNC\13TXN_NOT_DURABLEi\14TXN_WRITE_NOSYNC\15USE_ENVIRON\16USE_ENVIRON_ROOT\17EXCL\20FCNTL_LOCKING\21NO_AUTO_COMMIT\22RDWRMASTER\23WRITEOPEN";
00143
00144 static const char * dbenvSetFlags =
00145 "\20\1CREATE\2DURABLE_UNKNOWN\3FORCE\4MULTIVERSION\5NOMMAP\6RDONLY\7RECOVER\10THREAD\11TRUNCATE\12TXN_NOSYNC\13TXN_NOT_DURABLEi\14TXN_WRITE_NOSYNC\15USE_ENVIRON\16USE_ENVIRON_ROOT\17CDB_ALLDB\20DIRECT_DB\21DIRECT_LOG\22DSYNC_DB\23DSYNC_LOG\24LOG_AUTOREMOVE\25LOG_INMEMORY\26NOLOCKING\27NOPANIC\30OVERWRITE\31PANIC_ENV\36REGION_INIT\37TIME_NOTGRANTED\40YIELDCPU";
00146
00147 static const char * dbSetFlags =
00148 "\20\1CREATE\2DURABLE_UNKNOWN\3FORCE\4MULTIVERSION\5NOMMAP\6RDONLY\7RECOVER\10THREAD\11TRUNCATE\12TXN_NOSYNC\13TXN_NOT_DURABLEi\14TXN_WRITE_NOSYNC\15USE_ENVIRON\16USE_ENVIRON_ROOT\17CHKSUM\20DUP\21DUPSORT\22ENCRYPT\23INORDER\24RECNUM\25RENUMBER\26REVSPLITOFF\27SNAPSHOT";
00149
00150 static const char * dbiModeFlags =
00151 "\20\1WRONLY\2RDWR\7CREAT\10EXCL\11NOCTTY\12TRUNC\13APPEND\14NONBLOCK\15SYNC\16ASYNC\17DIRECT\20LARGEFILE\21DIRECTORY\22NOFOLLOW";
00152 #endif
00153
00154
00155
00156 static int cvtdberr( dbiIndex dbi, const char * msg, int error, int printit)
00157
00158
00159 {
00160 int rc = error;
00161
00162 if (printit && rc) {
00163
00164 if (msg)
00165 rpmlog(RPMLOG_ERR, _("db%d error(%d) from %s: %s\n"),
00166 DB_VERSION_MAJOR, rc, msg, db_strerror(error));
00167 else
00168 rpmlog(RPMLOG_ERR, _("db%d error(%d): %s\n"),
00169 DB_VERSION_MAJOR, rc, db_strerror(error));
00170
00171 }
00172
00173 return rc;
00174 }
00175
00176
00183
00184 static const char * mapTagName(rpmdb rpmdb, dbiIndex dbi)
00185
00186 {
00187 tagStore_t dbiTags = rpmdb->db_tags;
00188 int dbix = 0;
00189
00190 if (dbiTags != NULL)
00191 while (dbix < rpmdb->db_ndbi) {
00192 if (dbi->dbi_rpmtag == dbiTags->tag)
00193 return dbiTags->str;
00194 dbiTags++;
00195 dbix++;
00196 }
00197
00198 return tagName(dbi->dbi_rpmtag);
00199 }
00200
00201 static int db_fini(dbiIndex dbi, const char * dbhome,
00202 const char * dbfile,
00203 const char * dbsubfile)
00204
00205
00206 {
00207 rpmdb rpmdb = dbi->dbi_rpmdb;
00208 DB_ENV * dbenv = rpmdb->db_dbenv;
00209 int rc;
00210
00211 if (dbenv == NULL)
00212 return 0;
00213
00214 rc = dbenv->close(dbenv, 0);
00215 rc = cvtdberr(dbi, "dbenv->close", rc, _debug);
00216
00217 if (dbfile)
00218 rpmlog(RPMLOG_DEBUG, D_("closed db environment %s/%s\n"),
00219 dbhome, dbfile);
00220
00221 if (rpmdb->db_remove_env) {
00222 int xx;
00223
00224
00225 xx = db_env_create(&dbenv, 0);
00226
00227 if (!xx && dbenv != NULL) {
00228 xx = cvtdberr(dbi, "db_env_create", xx, _debug);
00229 #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR != 0) || (DB_VERSION_MAJOR == 4)
00230 xx = dbenv->remove(dbenv, dbhome, DB_FORCE);
00231 #else
00232 xx = dbenv->remove(dbenv, dbhome, NULL, 0);
00233 #endif
00234 xx = cvtdberr(dbi, "dbenv->remove", xx, _debug);
00235
00236 if (dbfile)
00237 rpmlog(RPMLOG_DEBUG, D_("removed db environment %s/%s\n"),
00238 dbhome, dbfile);
00239 }
00240
00241 }
00242 return rc;
00243 }
00244
00245 static int db3_fsync_disable( int fd)
00246
00247 {
00248 return 0;
00249 }
00250
00251 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 5)
00252
00260 static int db3is_alive( DB_ENV *dbenv, pid_t pid, db_threadid_t tid,
00261 uint32_t flags)
00262
00263 {
00264 int is_alive = 1;
00265
00266 switch (flags) {
00267 case DB_MUTEX_PROCESS_ONLY:
00268 case 0:
00269 default:
00270 is_alive = (!(kill(pid, 0) < 0 && errno == ESRCH));
00271 break;
00272 }
00273 return is_alive;
00274 }
00275 #endif
00276
00277
00278 static int db_init(dbiIndex dbi, const char * dbhome,
00279 const char * dbfile,
00280 const char * dbsubfile,
00281 DB_ENV ** dbenvp)
00282
00283
00284
00285 {
00286 static int oneshot = 0;
00287 rpmdb rpmdb = dbi->dbi_rpmdb;
00288 DB_ENV *dbenv = NULL;
00289 int eflags;
00290 int rc;
00291 int xx;
00292
00293 if (!oneshot) {
00294 #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR != 0) || (DB_VERSION_MAJOR == 4)
00295 xx = db_env_set_func_open((int (*)(const char *, int, ...))Open);
00296 xx = cvtdberr(dbi, "db_env_set_func_open", xx, _debug);
00297 #endif
00298 oneshot++;
00299 }
00300
00301 if (dbenvp == NULL)
00302 return 1;
00303
00304
00305
00306 if (rpmdb->db_errfile == NULL)
00307 rpmdb->db_errfile = stderr;
00308
00309
00310 eflags = (dbi->dbi_oeflags | dbi->dbi_eflags);
00311
00312
00313 if (eflags & DB_JOINENV) eflags &= DB_JOINENV;
00314
00315 if (dbfile)
00316 rpmlog(RPMLOG_DEBUG, D_("opening db environment %s/%s %s\n"),
00317 dbhome, dbfile, prDbiOpenFlags(eflags, 1));
00318
00319
00320 if (dbi->dbi_host == NULL)
00321 dbi->dbi_ecflags &= ~DB_CLIENT;
00322
00323
00324 if ((dbi->dbi_eflags & DB_SYSTEM_MEM) && dbi->dbi_shmkey == 0) {
00325 #if defined(HAVE_FTOK)
00326 dbi->dbi_shmkey = ftok(dbhome, 0);
00327 #else
00328 dbi->dbi_shmkey = 0x44631380;
00329 #endif
00330 }
00331
00332 rc = db_env_create(&dbenv, dbi->dbi_ecflags);
00333 rc = cvtdberr(dbi, "db_env_create", rc, _debug);
00334 if (dbenv == NULL || rc)
00335 goto errxit;
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 dbenv->set_errcall(dbenv, (void *)rpmdb->db_errcall);
00346
00347 dbenv->set_errfile(dbenv, rpmdb->db_errfile);
00348 dbenv->set_errpfx(dbenv, rpmdb->db_errpfx);
00349
00350
00351
00352
00353
00354
00355
00356 if ((dbi->dbi_ecflags & DB_CLIENT) && dbi->dbi_host) {
00357 const char * home;
00358 int retry = 0;
00359
00360 if ((home = strrchr(dbhome, '/')) != NULL)
00361 dbhome = ++home;
00362
00363 while (retry++ < 5) {
00364
00365 #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 3) || (DB_VERSION_MAJOR == 4)
00366 xx = dbenv->set_rpc_server(dbenv, NULL, dbi->dbi_host,
00367 dbi->dbi_cl_timeout, dbi->dbi_sv_timeout, 0);
00368 xx = cvtdberr(dbi, "dbenv->set_server", xx, _debug);
00369 #else
00370 xx = dbenv->set_server(dbenv, dbi->dbi_host,
00371 dbi->dbi_cl_timeout, dbi->dbi_sv_timeout, 0);
00372 xx = cvtdberr(dbi, "dbenv->set_server", xx, _debug);
00373 #endif
00374 if (!xx)
00375 break;
00376 (void) sleep(15);
00377 }
00378 } else {
00379 #if !(DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3)
00380 xx = dbenv->set_verbose(dbenv, DB_VERB_CHKPOINT,
00381 (dbi->dbi_verbose & DB_VERB_CHKPOINT));
00382 #endif
00383 xx = dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK,
00384 (dbi->dbi_verbose & DB_VERB_DEADLOCK));
00385 xx = dbenv->set_verbose(dbenv, DB_VERB_RECOVERY,
00386 (dbi->dbi_verbose & DB_VERB_RECOVERY));
00387 #if defined(DB_VERB_REGISTER)
00388 xx = dbenv->set_verbose(dbenv, DB_VERB_REGISTER,
00389 (dbi->dbi_verbose & DB_VERB_REGISTER));
00390 #endif
00391 #if defined(DB_VERB_REPLICATION)
00392 xx = dbenv->set_verbose(dbenv, DB_VERB_REPLICATION,
00393 (dbi->dbi_verbose & DB_VERB_REPLICATION));
00394 #endif
00395 xx = dbenv->set_verbose(dbenv, DB_VERB_WAITSFOR,
00396 (dbi->dbi_verbose & DB_VERB_WAITSFOR));
00397 #if defined(DB_VERB_FILEOPS)
00398 xx = dbenv->set_verbose(dbenv, DB_VERB_FILEOPS,
00399 (dbi->dbi_verbose & DB_VERB_FILEOPS));
00400 #endif
00401 #if defined(DB_VERB_FILEOPS_ALL)
00402 xx = dbenv->set_verbose(dbenv, DB_VERB_FILEOPS_ALL,
00403 (dbi->dbi_verbose & DB_VERB_FILEOPS_ALL));
00404 #endif
00405
00406 if (dbi->dbi_mmapsize) {
00407 xx = dbenv->set_mp_mmapsize(dbenv, dbi->dbi_mmapsize);
00408 xx = cvtdberr(dbi, "dbenv->set_mp_mmapsize", xx, _debug);
00409 }
00410 if (dbi->dbi_tmpdir) {
00411 const char * root;
00412 const char * tmpdir;
00413
00414 root = (dbi->dbi_root ? dbi->dbi_root : rpmdb->db_root);
00415 if ((root[0] == '/' && root[1] == '\0') || rpmdb->db_chrootDone)
00416 root = NULL;
00417
00418 tmpdir = rpmGenPath(root, dbi->dbi_tmpdir, NULL);
00419
00420 xx = dbenv->set_tmp_dir(dbenv, tmpdir);
00421 xx = cvtdberr(dbi, "dbenv->set_tmp_dir", xx, _debug);
00422 tmpdir = _free(tmpdir);
00423 }
00424 }
00425
00426
00427
00428 if (dbi->dbi_lk_detect) {
00429 xx = dbenv->set_lk_detect(dbenv, dbi->dbi_lk_detect);
00430 xx = cvtdberr(dbi, "dbenv->set_lk_detect", xx, _debug);
00431 }
00432 #if !(DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
00433 if (dbi->dbi_lk_max_lockers) {
00434 xx = dbenv->set_lk_max_lockers(dbenv, dbi->dbi_lk_max_lockers);
00435 xx = cvtdberr(dbi, "dbenv->set_lk_max_lockers", xx, _debug);
00436 }
00437 if (dbi->dbi_lk_max_locks) {
00438 xx = dbenv->set_lk_max_locks(dbenv, dbi->dbi_lk_max_locks);
00439 xx = cvtdberr(dbi, "dbenv->set_lk_max_locks", xx, _debug);
00440 }
00441 if (dbi->dbi_lk_max_objects) {
00442 xx = dbenv->set_lk_max_objects(dbenv, dbi->dbi_lk_max_objects);
00443 xx = cvtdberr(dbi, "dbenv->set_lk_max_objects", xx, _debug);
00444 }
00445
00446 if (dbi->dbi_lg_bsize) {
00447 xx = dbenv->set_lg_bsize(dbenv, dbi->dbi_lg_bsize);
00448 xx = cvtdberr(dbi, "dbenv->set_lg_bsize", xx, _debug);
00449 }
00450 if (dbi->dbi_lg_dir) {
00451 xx = dbenv->set_lg_dir(dbenv, dbi->dbi_lg_dir);
00452 xx = cvtdberr(dbi, "dbenv->set_lg_dir", xx, _debug);
00453 }
00454 if (dbi->dbi_lg_filemode) {
00455 xx = dbenv->set_lg_filemode(dbenv, dbi->dbi_lg_filemode);
00456 xx = cvtdberr(dbi, "dbenv->set_lg_filemode", xx, _debug);
00457 }
00458 if (dbi->dbi_lg_max) {
00459 xx = dbenv->set_lg_max(dbenv, dbi->dbi_lg_max);
00460 xx = cvtdberr(dbi, "dbenv->set_lg_max", xx, _debug);
00461 }
00462 if (dbi->dbi_lg_regionmax) {
00463 xx = dbenv->set_lg_regionmax(dbenv, dbi->dbi_lg_regionmax);
00464 xx = cvtdberr(dbi, "dbenv->set_lg_regionmax", xx, _debug);
00465 }
00466 #endif
00467
00468
00469 if (dbi->dbi_cachesize) {
00470 xx = dbenv->set_cachesize(dbenv, 0, dbi->dbi_cachesize, 0);
00471 xx = cvtdberr(dbi, "dbenv->set_cachesize", xx, _debug);
00472 }
00473
00474
00475 if (dbi->dbi_mutex_align) {
00476 xx = dbenv->mutex_set_align(dbenv, dbi->dbi_mutex_align);
00477 xx = cvtdberr(dbi, "dbenv->mutex_set_align", xx, _debug);
00478 }
00479 if (dbi->dbi_mutex_increment) {
00480 xx = dbenv->mutex_set_increment(dbenv, dbi->dbi_mutex_increment);
00481 xx = cvtdberr(dbi, "dbenv->mutex_set_increment", xx, _debug);
00482 }
00483 if (dbi->dbi_mutex_max) {
00484 xx = dbenv->mutex_set_max(dbenv, dbi->dbi_mutex_max);
00485 xx = cvtdberr(dbi, "dbenv->mutex_set_max", xx, _debug);
00486 }
00487 if (dbi->dbi_mutex_tas_spins) {
00488 xx = dbenv->mutex_set_tas_spins(dbenv, dbi->dbi_mutex_tas_spins);
00489 xx = cvtdberr(dbi, "dbenv->mutex_set_tas_spins", xx, _debug);
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 if (dbi->dbi_tx_max) {
00504 xx = dbenv->set_tx_max(dbenv, dbi->dbi_tx_max);
00505 xx = cvtdberr(dbi, "dbenv->set_tx_max", xx, _debug);
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515 if (dbi->dbi_no_fsync) {
00516 #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR != 0) || (DB_VERSION_MAJOR == 4)
00517 xx = db_env_set_func_fsync(db3_fsync_disable);
00518 #else
00519 xx = dbenv->set_func_fsync(dbenv, db3_fsync_disable);
00520 #endif
00521 xx = cvtdberr(dbi, "db_env_set_func_fsync", xx, _debug);
00522 }
00523
00524 if (dbi->dbi_shmkey) {
00525 xx = dbenv->set_shm_key(dbenv, dbi->dbi_shmkey);
00526 xx = cvtdberr(dbi, "dbenv->set_shm_key", xx, _debug);
00527 }
00528
00529 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 5)
00530
00531
00532 dbenv->set_msgfile(dbenv, rpmdb->db_errfile);
00533
00534
00535 if (dbi->dbi_thread_count >= 8) {
00536 xx = dbenv->set_thread_count(dbenv, dbi->dbi_thread_count);
00537 xx = cvtdberr(dbi, "dbenv->set_thread_count", xx, _debug);
00538 }
00539 #endif
00540
00541 #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR != 0) || (DB_VERSION_MAJOR == 4)
00542 rc = (dbenv->open)(dbenv, dbhome, eflags, dbi->dbi_perms);
00543 #else
00544 rc = (dbenv->open)(dbenv, dbhome, NULL, eflags, dbi->dbi_perms);
00545 #endif
00546 xx = _debug;
00547 #if defined(DB_VERSION_MISMATCH)
00548 if (rc == DB_VERSION_MISMATCH) xx = 0;
00549 #endif
00550 if (rc == EINVAL) xx = 0;
00551 rc = cvtdberr(dbi, "dbenv->open", rc, xx);
00552 if (rc)
00553 goto errxit;
00554
00555 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 5)
00556 if (!rpmdb->db_verifying && dbi->dbi_thread_count >= 8) {
00557
00558 xx = dbenv->set_isalive(dbenv, db3is_alive);
00559 xx = cvtdberr(dbi, "dbenv->set_isalive", xx, _debug);
00560
00561 xx = dbenv->failchk(dbenv, 0);
00562 xx = cvtdberr(dbi, "dbenv->failchk", xx, _debug);
00563 if (xx == DB_RUNRECOVERY) {
00564 rc = xx;
00565 goto errxit;
00566 }
00567 }
00568 #endif
00569
00570 *dbenvp = dbenv;
00571
00572 return 0;
00573
00574 errxit:
00575 if (dbenv) {
00576 xx = dbenv->close(dbenv, 0);
00577 xx = cvtdberr(dbi, "dbenv->close", xx, _debug);
00578 }
00579 return rc;
00580 }
00581
00582
00583 static int db3sync(dbiIndex dbi, unsigned int flags)
00584
00585
00586 {
00587 DB * db = dbi->dbi_db;
00588 int rc = 0;
00589 int _printit;
00590
00591 if (db != NULL)
00592 rc = db->sync(db, flags);
00593 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
00594 _printit = _debug;
00595 #else
00596
00597 _printit = (rc == DB_INCOMPLETE ? 0 : _debug);
00598 #endif
00599 rc = cvtdberr(dbi, "db->sync", rc, _printit);
00600 return rc;
00601 }
00602
00603 static int db3cdup(dbiIndex dbi, DBC * dbcursor, DBC ** dbcp,
00604 unsigned int flags)
00605
00606
00607 {
00608 int rc;
00609
00610 if (dbcp) *dbcp = NULL;
00611 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 6)
00612 rc = dbcursor->dup(dbcursor, dbcp, flags);
00613 rc = cvtdberr(dbi, "dbcursor->dup", rc, _debug);
00614 #else
00615 rc = dbcursor->c_dup(dbcursor, dbcp, flags);
00616 rc = cvtdberr(dbi, "dbcursor->c_dup", rc, _debug);
00617 #endif
00618
00619 return rc;
00620
00621 }
00622
00623
00624 static int db3cclose(dbiIndex dbi, DBC * dbcursor,
00625 unsigned int flags)
00626
00627
00628 {
00629 int rc = -2;
00630
00631
00632 if (dbcursor != NULL) {
00633 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 6)
00634 rc = dbcursor->close(dbcursor);
00635 rc = cvtdberr(dbi, "dbcursor->close", rc, _debug);
00636 #else
00637 rc = dbcursor->c_close(dbcursor);
00638 rc = cvtdberr(dbi, "dbcursor->c_close", rc, _debug);
00639 #endif
00640 }
00641 return rc;
00642 }
00643
00644
00645 static int db3copen(dbiIndex dbi, DB_TXN * txnid,
00646 DBC ** dbcp, unsigned int dbiflags)
00647
00648
00649 {
00650 DB * db = dbi->dbi_db;
00651 DBC * dbcursor = NULL;
00652 int flags;
00653 int rc;
00654
00655
00656 assert(db != NULL);
00657 if ((dbiflags & DB_WRITECURSOR) &&
00658 (dbi->dbi_eflags & DB_INIT_CDB) && !(dbi->dbi_oflags & DB_RDONLY))
00659 {
00660 flags = DB_WRITECURSOR;
00661 } else
00662 flags = 0;
00663
00664 rc = db->cursor(db, txnid, &dbcursor, flags);
00665 rc = cvtdberr(dbi, "db->cursor", rc, _debug);
00666
00667 if (dbcp)
00668 *dbcp = dbcursor;
00669 else
00670 (void) db3cclose(dbi, dbcursor, 0);
00671
00672 return rc;
00673 }
00674
00675 static int db3cput(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data,
00676 unsigned int flags)
00677
00678
00679 {
00680 DB * db = dbi->dbi_db;
00681 int rc;
00682
00683 assert(db != NULL);
00684 if (dbcursor == NULL) {
00685 rc = db->put(db, dbi->dbi_txnid, key, data, 0);
00686 rc = cvtdberr(dbi, "db->put", rc, _debug);
00687 } else {
00688 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 6)
00689 rc = dbcursor->put(dbcursor, key, data, DB_KEYLAST);
00690 rc = cvtdberr(dbi, "dbcursor->put", rc, _debug);
00691 #else
00692 rc = dbcursor->c_put(dbcursor, key, data, DB_KEYLAST);
00693 rc = cvtdberr(dbi, "dbcursor->c_put", rc, _debug);
00694 #endif
00695 }
00696
00697 return rc;
00698 }
00699
00700
00701 static int db3cdel(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data,
00702 unsigned int flags)
00703
00704
00705 {
00706 DB * db = dbi->dbi_db;
00707 int rc;
00708
00709 assert(db != NULL);
00710 if (dbcursor == NULL) {
00711 rc = db->del(db, dbi->dbi_txnid, key, flags);
00712 rc = cvtdberr(dbi, "db->del", rc, _debug);
00713 } else {
00714 int _printit;
00715
00716
00717 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 6)
00718 rc = dbcursor->get(dbcursor, key, data, DB_SET);
00719
00720 _printit = (rc == DB_NOTFOUND ? 0 : _debug);
00721 rc = cvtdberr(dbi, "dbcursor->get", rc, _printit);
00722 #else
00723 rc = dbcursor->c_get(dbcursor, key, data, DB_SET);
00724
00725 _printit = (rc == DB_NOTFOUND ? 0 : _debug);
00726 rc = cvtdberr(dbi, "dbcursor->c_get", rc, _printit);
00727 #endif
00728
00729 if (rc == 0) {
00730 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 6)
00731 rc = dbcursor->del(dbcursor, flags);
00732 rc = cvtdberr(dbi, "dbcursor->del", rc, _debug);
00733 #else
00734 rc = dbcursor->c_del(dbcursor, flags);
00735 rc = cvtdberr(dbi, "dbcursor->c_del", rc, _debug);
00736 #endif
00737 }
00738 }
00739
00740 return rc;
00741 }
00742
00743
00744
00745 static int db3cget(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data,
00746 unsigned int flags)
00747
00748
00749 {
00750 DB * db = dbi->dbi_db;
00751 int _printit;
00752 int rc;
00753
00754 assert(db != NULL);
00755 if (dbcursor == NULL) {
00756
00757 rc = db->get(db, dbi->dbi_txnid, key, data, 0);
00758
00759 _printit = (rc == DB_NOTFOUND ? 0 : _debug);
00760 rc = cvtdberr(dbi, "db->get", rc, _printit);
00761 } else {
00762 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 6)
00763
00764 rc = dbcursor->get(dbcursor, key, data, flags);
00765
00766 _printit = (rc == DB_NOTFOUND ? 0 : _debug);
00767 rc = cvtdberr(dbi, "dbcursor->get", rc, _printit);
00768 #else
00769
00770 rc = dbcursor->c_get(dbcursor, key, data, flags);
00771
00772 _printit = (rc == DB_NOTFOUND ? 0 : _debug);
00773 rc = cvtdberr(dbi, "dbcursor->c_get", rc, _printit);
00774 #endif
00775 }
00776
00777 return rc;
00778 }
00779
00780
00781
00782 static int db3cpget(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * pkey,
00783 DBT * data, unsigned int flags)
00784
00785
00786 {
00787 DB * db = dbi->dbi_db;
00788 int _printit;
00789 int rc;
00790
00791 assert(db != NULL);
00792 assert(dbcursor != NULL);
00793
00794 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 6)
00795
00796 rc = dbcursor->pget(dbcursor, key, pkey, data, flags);
00797
00798 _printit = (rc == DB_NOTFOUND ? 0 : _debug);
00799 rc = cvtdberr(dbi, "dbcursor->pget", rc, _printit);
00800 #else
00801
00802 rc = dbcursor->c_pget(dbcursor, key, pkey, data, flags);
00803
00804 _printit = (rc == DB_NOTFOUND ? 0 : _debug);
00805 rc = cvtdberr(dbi, "dbcursor->c_pget", rc, _printit);
00806 #endif
00807
00808 return rc;
00809 }
00810
00811
00812 static int db3ccount(dbiIndex dbi, DBC * dbcursor,
00813 unsigned int * countp,
00814 unsigned int flags)
00815
00816
00817 {
00818 db_recno_t count = 0;
00819 int rc = 0;
00820
00821 flags = 0;
00822 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 6)
00823 rc = dbcursor->count(dbcursor, &count, flags);
00824 rc = cvtdberr(dbi, "dbcursor->count", rc, _debug);
00825 #else
00826 rc = dbcursor->c_count(dbcursor, &count, flags);
00827 rc = cvtdberr(dbi, "dbcursor->c_count", rc, _debug);
00828 #endif
00829 if (rc) return rc;
00830 if (countp) *countp = count;
00831
00832 return rc;
00833 }
00834
00835 static int db3byteswapped(dbiIndex dbi)
00836 {
00837 DB * db = dbi->dbi_db;
00838 int rc = 0;
00839
00840 if (db != NULL) {
00841 #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 3 && DB_VERSION_PATCH == 11) \
00842 || (DB_VERSION_MAJOR == 4)
00843 int isswapped = 0;
00844 rc = db->get_byteswapped(db, &isswapped);
00845 if (rc == 0)
00846 rc = isswapped;
00847 #else
00848 rc = db->get_byteswapped(db);
00849 #endif
00850 }
00851
00852 return rc;
00853 }
00854
00855 static int db3stat(dbiIndex dbi, unsigned int flags)
00856
00857
00858 {
00859 DB * db = dbi->dbi_db;
00860 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3)
00861 DB_TXN * txnid = NULL;
00862 #endif
00863 int rc = 0;
00864
00865 assert(db != NULL);
00866 #if defined(DB_FAST_STAT)
00867 if (flags)
00868 flags = DB_FAST_STAT;
00869 else
00870 #endif
00871 flags = 0;
00872 dbi->dbi_stats = _free(dbi->dbi_stats);
00873
00874 #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 3) || (DB_VERSION_MAJOR == 4)
00875 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3)
00876 rc = db->stat(db, txnid, &dbi->dbi_stats, flags);
00877 #else
00878 rc = db->stat(db, &dbi->dbi_stats, flags);
00879 #endif
00880 #else
00881 rc = db->stat(db, &dbi->dbi_stats, NULL, flags);
00882 #endif
00883 rc = cvtdberr(dbi, "db->stat", rc, _debug);
00884 return rc;
00885 }
00886
00887
00888 static int db3associate(dbiIndex dbi, dbiIndex dbisecondary,
00889 int (*callback)(DB *, const DBT *, const DBT *, DBT *),
00890 unsigned int flags)
00891
00892
00893 {
00894 DB * db = dbi->dbi_db;
00895 DB * secondary = dbisecondary->dbi_db;
00896 int rc;
00897
00898
00899 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
00900 DB_TXN * txnid = NULL;
00901
00902 assert(db != NULL);
00903 rc = db->associate(db, txnid, secondary, callback, flags);
00904 #else
00905 assert(db != NULL);
00906 rc = db->associate(db, secondary, callback, flags);
00907 #endif
00908
00909 rc = cvtdberr(dbi, "db->associate", rc, _debug);
00910 return rc;
00911 }
00912
00913
00914
00915 static int db3join(dbiIndex dbi, DBC ** curslist, DBC ** dbcp,
00916 unsigned int flags)
00917
00918
00919 {
00920 DB * db = dbi->dbi_db;
00921 int rc;
00922
00923 assert(db != NULL);
00924
00925 rc = db->join(db, curslist, dbcp, flags);
00926
00927 rc = cvtdberr(dbi, "db->join", rc, _debug);
00928 return rc;
00929 }
00930
00931
00932
00933 static int db3close( dbiIndex dbi, unsigned int flags)
00934
00935
00936
00937 {
00938 rpmdb rpmdb = dbi->dbi_rpmdb;
00939 const char * urlfn = NULL;
00940 const char * root;
00941 const char * home;
00942 const char * dbhome;
00943 const char * dbfile;
00944 const char * dbsubfile;
00945 DB * db = dbi->dbi_db;
00946 const char * dbiBN = mapTagName(rpmdb, dbi);
00947 int _printit;
00948 int rc = 0, xx;
00949
00950 flags = 0;
00951
00952
00953
00954
00955 root = (dbi->dbi_root ? dbi->dbi_root : rpmdb->db_root);
00956 if ((root[0] == '/' && root[1] == '\0') || rpmdb->db_chrootDone)
00957 root = NULL;
00958 home = (dbi->dbi_home ? dbi->dbi_home : rpmdb->db_home);
00959
00960
00961
00962
00963
00964
00965 urlfn = rpmGenPath(root, home, NULL);
00966
00967 (void) urlPath(urlfn, &dbhome);
00968 if (dbi->dbi_temporary) {
00969 dbfile = NULL;
00970 dbsubfile = NULL;
00971 } else {
00972 #ifdef HACK
00973 dbfile = (dbi->dbi_file ? dbi->dbi_file : db3basename);
00974 dbsubfile = (dbi->dbi_subfile ? dbi->dbi_subfile : dbiBN);
00975 #else
00976 dbfile = (dbi->dbi_file ? dbi->dbi_file : dbiBN);
00977 dbsubfile = NULL;
00978 #endif
00979 }
00980
00981 if (db) {
00982 rc = db->close(db, 0);
00983
00984 _printit = (rc == ENOENT ? 0 : _debug);
00985 rc = cvtdberr(dbi, "db->close", rc, _printit);
00986 db = dbi->dbi_db = NULL;
00987
00988 rpmlog(RPMLOG_DEBUG, D_("closed db index %s/%s\n"),
00989 dbhome, (dbfile ? dbfile : dbiBN));
00990
00991 }
00992
00993 if (rpmdb->db_dbenv != NULL && dbi->dbi_use_dbenv) {
00994 if (rpmdb->db_opens == 1) {
00995
00996 xx = db_fini(dbi, (dbhome ? dbhome : ""), dbfile, dbsubfile);
00997
00998 rpmdb->db_dbenv = NULL;
00999 }
01000 rpmdb->db_opens--;
01001 }
01002
01003 if (dbi->dbi_verify_on_close && !dbi->dbi_temporary) {
01004 DB_ENV * dbenv = NULL;
01005 int eflags;
01006
01007
01008 rc = db_env_create(&dbenv, 0);
01009
01010 rc = cvtdberr(dbi, "db_env_create", rc, _debug);
01011 if (rc || dbenv == NULL) goto exit;
01012
01013
01014
01015 dbenv->set_errcall(dbenv, (void *)rpmdb->db_errcall);
01016
01017 dbenv->set_errfile(dbenv, rpmdb->db_errfile);
01018 dbenv->set_errpfx(dbenv, rpmdb->db_errpfx);
01019
01020
01021 #if !(DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3)
01022 xx = dbenv->set_verbose(dbenv, DB_VERB_CHKPOINT,
01023 (dbi->dbi_verbose & DB_VERB_CHKPOINT));
01024 #endif
01025 xx = dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK,
01026 (dbi->dbi_verbose & DB_VERB_DEADLOCK));
01027 xx = dbenv->set_verbose(dbenv, DB_VERB_RECOVERY,
01028 (dbi->dbi_verbose & DB_VERB_RECOVERY));
01029 xx = dbenv->set_verbose(dbenv, DB_VERB_WAITSFOR,
01030 (dbi->dbi_verbose & DB_VERB_WAITSFOR));
01031
01032 if (dbi->dbi_tmpdir) {
01033
01034 const char * tmpdir = rpmGenPath(root, dbi->dbi_tmpdir, NULL);
01035
01036 rc = dbenv->set_tmp_dir(dbenv, tmpdir);
01037 rc = cvtdberr(dbi, "dbenv->set_tmp_dir", rc, _debug);
01038 tmpdir = _free(tmpdir);
01039 if (rc) goto exit;
01040 }
01041
01042 eflags = DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON;
01043 rc = (dbenv->open)(dbenv, dbhome, eflags, 0);
01044 rc = cvtdberr(dbi, "dbenv->open", rc, _debug);
01045 if (rc) goto exit;
01046
01047
01048 rc = db_create(&db, dbenv, 0);
01049
01050 rc = cvtdberr(dbi, "db_create", rc, _debug);
01051
01052 if (db != NULL) {
01053
01054 const char * dbf = rpmGetPath(dbhome, "/", dbfile, NULL);
01055
01056
01057 rc = db->verify(db, dbf, NULL, NULL, flags);
01058 rc = cvtdberr(dbi, "db->verify", rc, _debug);
01059
01060 rpmlog(RPMLOG_DEBUG, D_("verified db index %s/%s\n"),
01061 (dbhome ? dbhome : ""),
01062 (dbfile ? dbfile : dbiBN));
01063
01064
01065
01066
01067
01068 db = NULL;
01069 dbf = _free(dbf);
01070 }
01071 xx = dbenv->close(dbenv, 0);
01072 xx = cvtdberr(dbi, "dbenv->close", xx, _debug);
01073 if (rc == 0 && xx) rc = xx;
01074 }
01075
01076 exit:
01077 dbi->dbi_db = NULL;
01078
01079 urlfn = _free(urlfn);
01080
01081 dbi = db3Free(dbi);
01082
01083 return rc;
01084 }
01085
01086
01087 static int db3open(rpmdb rpmdb, rpmTag rpmtag, dbiIndex * dbip)
01088
01089
01090
01091 {
01092
01093 extern struct _dbiVec db3vec;
01094
01095 const char * urlfn = NULL;
01096 const char * root;
01097 const char * home;
01098 const char * dbhome;
01099 const char * dbfile;
01100 const char * dbsubfile;
01101 const char * dbiBN;
01102 dbiIndex dbi = NULL;
01103 int rc = 0;
01104 int xx;
01105
01106 DB * db = NULL;
01107 DB_ENV * dbenv = NULL;
01108 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
01109 DB_TXN * txnid = NULL;
01110 #endif
01111 DBTYPE dbi_type = DB_UNKNOWN;
01112 uint32_t oflags;
01113 int _printit;
01114
01115 if (dbip)
01116 *dbip = NULL;
01117
01118
01119
01120
01121
01122 if ((dbi = db3New(rpmdb, rpmtag)) == NULL)
01123
01124 return 1;
01125
01126
01127 dbi->dbi_api = DB_VERSION_MAJOR;
01128 dbiBN = mapTagName(rpmdb, dbi);
01129
01130
01131
01132
01133 root = (dbi->dbi_root ? dbi->dbi_root : rpmdb->db_root);
01134 if ((root[0] == '/' && root[1] == '\0') || rpmdb->db_chrootDone)
01135 root = NULL;
01136 home = (dbi->dbi_home ? dbi->dbi_home : rpmdb->db_home);
01137
01138
01139
01140
01141
01142
01143 urlfn = rpmGenPath(root, home, NULL);
01144
01145 (void) urlPath(urlfn, &dbhome);
01146 if (dbi->dbi_temporary) {
01147 dbfile = NULL;
01148 dbsubfile = NULL;
01149 } else {
01150 #ifdef HACK
01151 dbfile = (dbi->dbi_file ? dbi->dbi_file : db3basename);
01152 dbsubfile = (dbi->dbi_subfile ? dbi->dbi_subfile : dbiBN);
01153 #else
01154 dbfile = (dbi->dbi_file ? dbi->dbi_file : dbiBN);
01155 dbsubfile = NULL;
01156 #endif
01157 }
01158
01159 oflags = (dbi->dbi_oeflags | dbi->dbi_oflags);
01160 oflags &= ~DB_TRUNCATE;
01161
01162 #if 0
01163 if ( dbi->dbi_mode & O_EXCL) oflags |= DB_EXCL;
01164 #endif
01165
01166
01167
01168
01169 if (dbi->dbi_temporary) {
01170 oflags |= DB_CREATE;
01171 dbi->dbi_oeflags |= DB_CREATE;
01172 oflags &= ~DB_RDONLY;
01173 dbi->dbi_oflags &= ~DB_RDONLY;
01174 } else {
01175 if (!(dbi->dbi_mode & (O_RDWR|O_WRONLY))) oflags |= DB_RDONLY;
01176 if (dbi->dbi_mode & O_CREAT) {
01177 oflags |= DB_CREATE;
01178 dbi->dbi_oeflags |= DB_CREATE;
01179 }
01180 #ifdef DANGEROUS
01181 if ( dbi->dbi_mode & O_TRUNC) oflags |= DB_TRUNCATE;
01182 #endif
01183 }
01184
01185
01186
01187
01188 (void) rpmioMkpath(dbhome, 0755, getuid(), getgid());
01189
01190
01191
01192
01193 if (dbi->dbi_use_dbenv) {
01194
01195 if (access(dbhome, W_OK) == -1) {
01196
01197
01198 oflags &= ~DB_CREATE;
01199
01200
01201 if (dbi->dbi_eflags & DB_PRIVATE) {
01202 dbi->dbi_eflags &= ~DB_JOINENV;
01203 } else {
01204 dbi->dbi_eflags |= DB_JOINENV;
01205 dbi->dbi_oeflags &= ~DB_CREATE;
01206 dbi->dbi_oeflags &= ~DB_THREAD;
01207
01208 dbi->dbi_use_dbenv = 0;
01209 }
01210
01211
01212 if (dbi->dbi_temporary) {
01213 oflags |= DB_CREATE;
01214 dbi->dbi_oeflags |= DB_CREATE;
01215 oflags &= ~DB_RDONLY;
01216 dbi->dbi_oflags &= ~DB_RDONLY;
01217 } else {
01218 oflags |= DB_RDONLY;
01219
01220 dbi->dbi_oflags |= DB_RDONLY;
01221 }
01222
01223 } else {
01224
01225 const char * dbf = rpmGetPath(dbhome, "/__db.001", NULL);
01226
01227
01228 #if defined(RPM_VENDOR_OPENPKG)
01229
01230
01231 struct stat sb;
01232 long size = -1;
01233 if (stat(dbf, &sb) == 0)
01234 size = (long)sb.st_size;
01235 if (access(dbf, F_OK) == -1 || size == 0) {
01236 #else
01237 if (access(dbf, F_OK) == -1) {
01238 #endif
01239
01240 dbi->dbi_oeflags |= DB_CREATE;
01241 dbi->dbi_eflags &= ~DB_JOINENV;
01242 } else {
01243
01244 if (dbi->dbi_eflags & DB_PRIVATE) {
01245 dbi->dbi_eflags &= ~DB_JOINENV;
01246 } else {
01247 dbi->dbi_eflags |= DB_JOINENV;
01248 dbi->dbi_oeflags &= ~DB_CREATE;
01249 dbi->dbi_oeflags &= ~DB_THREAD;
01250 }
01251 }
01252 dbf = _free(dbf);
01253 }
01254 }
01255
01256
01257
01258
01259 if ((oflags & DB_CREATE) && (oflags & DB_RDONLY)) {
01260
01261 const char * dbfn = (dbfile ? dbfile : dbiBN);
01262
01263 const char * dbf = rpmGetPath(dbhome, "/", dbfn, NULL);
01264
01265
01266 if (access(dbf, F_OK) == -1) {
01267
01268 oflags &= ~DB_RDONLY;
01269 } else {
01270
01271 oflags &= ~DB_CREATE;
01272 }
01273
01274
01275 if (!(oflags & DB_RDONLY) && access(dbf, W_OK) == 0) {
01276 dbi->dbi_oflags &= ~DB_RDONLY;
01277 } else {
01278 dbi->dbi_oflags |= DB_RDONLY;
01279 }
01280 dbf = _free(dbf);
01281 }
01282
01283
01284
01285
01286 if (oflags & DB_CREATE)
01287 dbi_type = dbi->dbi_type;
01288
01289
01290
01291
01292 if (oflags & DB_RDONLY)
01293 dbi->dbi_verify_on_close = 0;
01294
01295 if (dbi->dbi_use_dbenv) {
01296
01297 if (rpmdb->db_dbenv == NULL) {
01298 rc = db_init(dbi, dbhome, dbfile, dbsubfile, &dbenv);
01299 switch (rc) {
01300 default:
01301 break;
01302
01303 case DB_RUNRECOVERY:
01304 rpmlog(RPMLOG_ERR, _("Runnning db->verify ...\n"));
01305 rpmdb = rpmdbLink(rpmdb, "DB_RUNRECOVERY");
01306 rpmdb->db_remove_env = 1;
01307 rpmdb->db_verifying = 1;
01308 xx = rpmdbVerifyAllDBI(rpmdb);
01309 xx = cvtdberr(dbi, "db->verify", xx, _debug);
01310 rpmdb->db_remove_env = 0;
01311 rpmdb->db_verifying = 0;
01312
01313 dbi->dbi_oeflags |= DB_CREATE;
01314 dbi->dbi_eflags &= ~DB_JOINENV;
01315 rc = db_init(dbi, dbhome, dbfile, dbsubfile, &dbenv);
01316
01317 rc = cvtdberr(dbi, "dbenv->open", rc, _debug);
01318 if (rc)
01319 break;
01320
01321 assert(dbenv);
01322 rpmdb->db_dbenv = dbenv;
01323 rpmdb->db_opens = 1;
01324 break;
01325
01326 #if defined(DB_VERSION_MISMATCH)
01327 case DB_VERSION_MISMATCH:
01328 #endif
01329 case EINVAL:
01330 if (getuid() != 0)
01331 break;
01332 { char * filename = alloca(BUFSIZ);
01333 struct stat st;
01334 int i;
01335
01336 for (i = 0; i < 16; i++) {
01337 sprintf(filename, "%s/__db.%03d", dbhome, i);
01338 (void)rpmCleanPath(filename);
01339 if (Stat(filename, &st)
01340 && (errno == ENOENT || errno == EINVAL))
01341 continue;
01342 xx = Unlink(filename);
01343 }
01344 }
01345 dbi->dbi_oeflags |= DB_CREATE;
01346 dbi->dbi_eflags &= ~DB_JOINENV;
01347 rc = db_init(dbi, dbhome, dbfile, dbsubfile, &dbenv);
01348
01349 rc = cvtdberr(dbi, "dbenv->open", rc, _debug);
01350 if (rc)
01351 break;
01352
01353 case 0:
01354 assert(dbenv);
01355 rpmdb->db_dbenv = dbenv;
01356 rpmdb->db_opens = 1;
01357 break;
01358 }
01359 } else {
01360 assert(rpmdb && rpmdb->db_dbenv);
01361 dbenv = rpmdb->db_dbenv;
01362 #define PLD_CHROOT
01363 #ifdef PLD_CHROOT
01364 if (rpmdb->db_chrootDone)
01365 xx = dbenv->set_data_dir(dbenv, dbhome);
01366 #endif
01367 rpmdb->db_opens++;
01368 }
01369
01370 }
01371
01372 rpmlog(RPMLOG_DEBUG, D_("opening db index %s/%s %s mode=0x%x\n"),
01373 dbhome, (dbfile ? dbfile : dbiBN),
01374 prDbiOpenFlags(oflags, 0), dbi->dbi_mode);
01375
01376 if (rc == 0) {
01377 static int _lockdbfd = 0;
01378
01379
01380 rc = db_create(&db, dbenv, dbi->dbi_cflags);
01381
01382 rc = cvtdberr(dbi, "db_create", rc, _debug);
01383 if (rc == 0 && db != NULL) {
01384
01385
01386 #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 3) || (DB_VERSION_MAJOR == 4)
01387 if (rc == 0 &&
01388 rpmdb->db_malloc && rpmdb->db_realloc && rpmdb->db_free)
01389 {
01390 rc = db->set_alloc(db,
01391 rpmdb->db_malloc, rpmdb->db_realloc, rpmdb->db_free);
01392 rc = cvtdberr(dbi, "db->set_alloc", rc, _debug);
01393 }
01394 #else
01395 if (rc == 0 && rpmdb->db_malloc) {
01396 rc = db->set_malloc(db, rpmdb->db_malloc);
01397 rc = cvtdberr(dbi, "db->set_malloc", rc, _debug);
01398 }
01399 #endif
01400
01401
01402 if (rc == 0 && !dbi->dbi_use_dbenv && dbi->dbi_cachesize) {
01403 rc = db->set_cachesize(db, 0, dbi->dbi_cachesize, 0);
01404 rc = cvtdberr(dbi, "db->set_cachesize", rc, _debug);
01405 }
01406
01407
01408
01409
01410
01411
01412 if (rc == 0 && dbi->dbi_lorder) {
01413 rc = db->set_lorder(db, dbi->dbi_lorder);
01414 rc = cvtdberr(dbi, "db->set_lorder", rc, _debug);
01415 }
01416 if (rc == 0 && dbi->dbi_pagesize) {
01417 rc = db->set_pagesize(db, dbi->dbi_pagesize);
01418 rc = cvtdberr(dbi, "db->set_pagesize", rc, _debug);
01419 }
01420
01421 if (rc == 0 && oflags & DB_CREATE) {
01422 switch(dbi->dbi_type) {
01423 default:
01424 case DB_HASH:
01425 if (dbi->dbi_h_ffactor) {
01426 rc = db->set_h_ffactor(db, dbi->dbi_h_ffactor);
01427 rc = cvtdberr(dbi, "db->set_h_ffactor", rc, _debug);
01428 if (rc) break;
01429 }
01430 if (dbi->dbi_h_nelem) {
01431 rc = db->set_h_nelem(db, dbi->dbi_h_nelem);
01432 rc = cvtdberr(dbi, "db->set_h_nelem", rc, _debug);
01433 if (rc) break;
01434 }
01435 if (dbi->dbi_h_flags) {
01436 rc = db->set_flags(db, dbi->dbi_h_flags);
01437 rc = cvtdberr(dbi, "db->set_h_flags", rc, _debug);
01438 if (rc) break;
01439 }
01440
01441 #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR > 2) || (DB_VERSION_MAJOR == 4)
01442 if (dbi->dbi_h_hash_fcn) {
01443 rc = db->set_h_hash(db, dbi->dbi_h_hash_fcn);
01444 rc = cvtdberr(dbi, "db->set_h_hash", rc, _debug);
01445 if (rc) break;
01446 }
01447 if (dbi->dbi_h_dup_compare_fcn) {
01448 rc = db->set_dup_compare(db, dbi->dbi_h_dup_compare_fcn);
01449 rc = cvtdberr(dbi, "db->set_dup_compare", rc, _debug);
01450 if (rc) break;
01451 }
01452 #endif
01453 break;
01454 case DB_BTREE:
01455
01456 if (dbi->dbi_bt_flags) {
01457 rc = db->set_flags(db, dbi->dbi_bt_flags);
01458 rc = cvtdberr(dbi, "db->set_bt_flags", rc, _debug);
01459 if (rc) break;
01460 }
01461 if (dbi->dbi_bt_minkey) {
01462 rc = db->set_bt_minkey(db, dbi->dbi_bt_minkey);
01463 rc = cvtdberr(dbi, "db->set_bt_minkey", rc, _debug);
01464 if (rc) break;
01465 }
01466
01467 #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR > 2) || (DB_VERSION_MAJOR == 4)
01468 if (dbi->dbi_bt_compare_fcn) {
01469 rc = db->set_bt_compare(db, dbi->dbi_bt_compare_fcn);
01470 rc = cvtdberr(dbi, "db->set_bt_compare", rc, _debug);
01471 if (rc) break;
01472 }
01473 if (dbi->dbi_bt_dup_compare_fcn) {
01474 rc = db->set_dup_compare(db, dbi->dbi_bt_dup_compare_fcn);
01475 rc = cvtdberr(dbi, "db->set_dup_compare", rc, _debug);
01476 if (rc) break;
01477 }
01478 if (dbi->dbi_bt_prefix_fcn) {
01479 rc = db->set_bt_prefix(db, dbi->dbi_bt_prefix_fcn);
01480 rc = cvtdberr(dbi, "db->set_bt_prefix", rc, _debug);
01481 if (rc) break;
01482 }
01483 #endif
01484 break;
01485 case DB_RECNO:
01486 if (dbi->dbi_re_delim) {
01487
01488 rc = db->set_re_delim(db, dbi->dbi_re_delim);
01489 rc = cvtdberr(dbi, "db->set_re_selim", rc, _debug);
01490 if (rc) break;
01491 }
01492 if (dbi->dbi_re_len) {
01493 rc = db->set_re_len(db, dbi->dbi_re_len);
01494 rc = cvtdberr(dbi, "db->set_re_len", rc, _debug);
01495 if (rc) break;
01496 }
01497 if (dbi->dbi_re_pad) {
01498 rc = db->set_re_pad(db, dbi->dbi_re_pad);
01499 rc = cvtdberr(dbi, "db->set_re_pad", rc, _debug);
01500 if (rc) break;
01501 }
01502 if (dbi->dbi_re_source) {
01503 rc = db->set_re_source(db, dbi->dbi_re_source);
01504 rc = cvtdberr(dbi, "db->set_re_source", rc, _debug);
01505 if (rc) break;
01506 }
01507 break;
01508 case DB_QUEUE:
01509 if (dbi->dbi_q_extentsize) {
01510 rc = db->set_q_extentsize(db, dbi->dbi_q_extentsize);
01511 rc = cvtdberr(dbi, "db->set_q_extentsize", rc, _debug);
01512 if (rc) break;
01513 }
01514 break;
01515 }
01516 }
01517
01518 if (rc == 0) {
01519 const char * dbfullpath;
01520 const char * dbpath;
01521 char * t;
01522 int nb;
01523
01524 nb = strlen(dbhome);
01525 if (dbfile) nb += 1 + strlen(dbfile);
01526 dbfullpath = t = alloca(nb + 1);
01527
01528 t = stpcpy(t, dbhome);
01529 if (dbfile)
01530 t = stpcpy( stpcpy( t, "/"), dbfile);
01531 #ifdef HACK
01532 dbpath = (!dbi->dbi_use_dbenv && !dbi->dbi_temporary)
01533 ? dbfullpath : dbfile;
01534 #else
01535 #ifdef PLD_CHROOT
01536
01537 dbpath = (!dbi->dbi_use_dbenv)
01538 ? dbfullpath : dbfile;
01539 #else
01540 dbpath = (!dbi->dbi_temporary)
01541 ? dbfullpath : dbfile;
01542 #endif
01543 #endif
01544
01545 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
01546 rc = (db->open)(db, txnid, dbpath, dbsubfile,
01547 dbi_type, oflags, dbi->dbi_perms);
01548 #else
01549 rc = (db->open)(db, dbpath, dbsubfile,
01550 dbi_type, oflags, dbi->dbi_perms);
01551 #endif
01552
01553 if (rc == 0 && dbi_type == DB_UNKNOWN) {
01554 #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 3 && DB_VERSION_PATCH == 11) \
01555 || (DB_VERSION_MAJOR == 4)
01556 xx = db->get_type(db, &dbi_type);
01557 if (xx == 0)
01558 dbi->dbi_type = dbi_type;
01559 #else
01560 dbi->dbi_type = db->get_type(db);
01561 #endif
01562 }
01563 }
01564
01565
01566 _printit = (rc > 0 ? 0 : _debug);
01567 xx = cvtdberr(dbi, "db->open", rc, _printit);
01568
01569 dbi->dbi_txnid = NULL;
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589 if (rc == 0 && dbi->dbi_lockdbfd &&
01590 !((dbi->dbi_ecflags & DB_CLIENT) && dbi->dbi_host) &&
01591 (!dbi->dbi_use_dbenv || _lockdbfd++ == 0))
01592 {
01593 int fdno = -1;
01594
01595 if (!(db->fd(db, &fdno) == 0 && fdno >= 0)) {
01596 rc = 1;
01597 } else {
01598 struct flock l;
01599 memset(&l, 0, sizeof(l));
01600 l.l_whence = 0;
01601 l.l_start = 0;
01602 l.l_len = 0;
01603 l.l_type = (dbi->dbi_mode & (O_RDWR|O_WRONLY))
01604 ? F_WRLCK : F_RDLCK;
01605 l.l_pid = 0;
01606
01607 rc = fcntl(fdno, F_SETLK, (void *) &l);
01608 if (rc) {
01609
01610 rc = ((dbi->dbi_use_dbenv &&
01611 (dbi->dbi_eflags & DB_INIT_CDB) &&
01612 !(dbi->dbi_eflags & DB_PRIVATE))
01613 ? 0 : 1);
01614 rpmlog( (rc ? RPMLOG_ERR : RPMLOG_WARNING),
01615 _("cannot get %s lock on %s/%s\n"),
01616 ((dbi->dbi_mode & (O_RDWR|O_WRONLY))
01617 ? _("exclusive") : _("shared")),
01618 dbhome, (dbfile ? dbfile : ""));
01619 } else if (dbfile) {
01620 rpmlog(RPMLOG_DEBUG,
01621 D_("locked db index %s/%s\n"),
01622 dbhome, dbfile);
01623 }
01624 }
01625 }
01626 }
01627 }
01628
01629 dbi->dbi_db = db;
01630
01631 if (rc == 0 && dbi->dbi_db != NULL && dbip != NULL) {
01632 dbi->dbi_vec = &db3vec;
01633 *dbip = dbi;
01634 } else {
01635 dbi->dbi_verify_on_close = 0;
01636 (void) db3close(dbi, 0);
01637 }
01638
01639 urlfn = _free(urlfn);
01640
01641
01642 return rc;
01643
01644 }
01645
01648
01649
01650 struct _dbiVec db3vec = {
01651 DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH,
01652 db3open, db3close, db3sync, db3associate, db3join,
01653 db3copen, db3cclose, db3cdup, db3cdel, db3cget, db3cpget, db3cput, db3ccount,
01654 db3byteswapped, db3stat
01655 };
01656
01657