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