00001
00005 static int _debug = 1;
00006
00007 #ifdef __LCLINT__
00008 typedef unsigned int u_int32_t;
00009 typedef unsigned short u_int16_t;
00010 typedef unsigned char u_int8_t;
00011 typedef int int32_t;
00012 #endif
00013
00014 #include "system.h"
00015
00016 #include <db3/db.h>
00017
00018 #include <rpmlib.h>
00019 #include <rpmmacro.h>
00020 #include <rpmurl.h>
00021
00022 #include "rpmdb.h"
00023 #include "debug.h"
00024
00025
00026
00027
00028
00029 #if DB_VERSION_MAJOR == 3
00030 #define __USE_DB3 1
00031
00032 #if defined(__USE_DB2) || defined(__USE_DB3)
00033 #if defined(__USE_DB2)
00034 static const char * db_strerror(int error)
00035 {
00036 if (error == 0)
00037 return ("Successful return: 0");
00038 if (error > 0)
00039 return (strerror(error));
00040
00041 switch (error) {
00042 case DB_INCOMPLETE:
00043 return ("DB_INCOMPLETE: Cache flush was unable to complete");
00044 case DB_KEYEMPTY:
00045 return ("DB_KEYEMPTY: Non-existent key/data pair");
00046 case DB_KEYEXIST:
00047 return ("DB_KEYEXIST: Key/data pair already exists");
00048 case DB_LOCK_DEADLOCK:
00049 return ("DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock");
00050 case DB_LOCK_NOTGRANTED:
00051 return ("DB_LOCK_NOTGRANTED: Lock not granted");
00052 case DB_NOTFOUND:
00053 return ("DB_NOTFOUND: No matching key/data pair found");
00054 #if defined(__USE_DB3)
00055 case DB_OLD_VERSION:
00056 return ("DB_OLDVERSION: Database requires a version upgrade");
00057 case DB_RUNRECOVERY:
00058 return ("DB_RUNRECOVERY: Fatal error, run database recovery");
00059 #else
00060 case DB_LOCK_NOTHELD:
00061 return ("DB_LOCK_NOTHELD:");
00062 case DB_REGISTERED:
00063 return ("DB_REGISTERED:");
00064 #endif
00065 default:
00066 {
00067
00068
00069
00070
00071
00072
00073 static char ebuf[40];
00074
00075 (void)snprintf(ebuf, sizeof(ebuf), "Unknown error: %d", error);
00076 return(ebuf);
00077 }
00078 }
00079
00080 }
00081
00082 static int db_env_create(DB_ENV **dbenvp, int foo)
00083 {
00084 DB_ENV *dbenv;
00085
00086 if (dbenvp == NULL)
00087 return 1;
00088 dbenv = xcalloc(1, sizeof(*dbenv));
00089
00090 *dbenvp = dbenv;
00091 return 0;
00092 }
00093 #endif
00094
00095 static int cvtdberr(dbiIndex dbi, const char * msg, int error, int printit) {
00096 int rc = 0;
00097
00098 rc = error;
00099
00100 if (printit && rc) {
00101 if (msg)
00102 rpmError(RPMERR_DBERR, _("db%d error(%d) from %s: %s\n"),
00103 dbi->dbi_api, rc, msg, db_strerror(error));
00104 else
00105 rpmError(RPMERR_DBERR, _("db%d error(%d): %s\n"),
00106 dbi->dbi_api, rc, db_strerror(error));
00107 }
00108
00109 return rc;
00110 }
00111
00112 static int db_fini(dbiIndex dbi, const char * dbhome, const char * dbfile,
00113 const char * dbsubfile)
00114 {
00115 rpmdb rpmdb = dbi->dbi_rpmdb;
00116 DB_ENV * dbenv = dbi->dbi_dbenv;
00117
00118 #if defined(__USE_DB3)
00119 int rc;
00120
00121 if (dbenv == NULL) {
00122 dbi->dbi_dbenv = NULL;
00123 return 0;
00124 }
00125
00126 rc = dbenv->close(dbenv, 0);
00127 rc = cvtdberr(dbi, "dbenv->close", rc, _debug);
00128
00129 if (dbfile)
00130 rpmMessage(RPMMESS_DEBUG, _("closed db environment %s/%s\n"),
00131 dbhome, dbfile);
00132
00133 if (rpmdb->db_remove_env || dbi->dbi_tear_down) {
00134 int xx;
00135
00136 xx = db_env_create(&dbenv, 0);
00137 xx = cvtdberr(dbi, "db_env_create", rc, _debug);
00138 #if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1
00139 xx = dbenv->remove(dbenv, dbhome, 0);
00140 #else
00141 xx = dbenv->remove(dbenv, dbhome, NULL, 0);
00142 #endif
00143 xx = cvtdberr(dbi, "dbenv->remove", rc, _debug);
00144
00145 if (dbfile)
00146 rpmMessage(RPMMESS_DEBUG, _("removed db environment %s/%s\n"),
00147 dbhome, dbfile);
00148
00149 }
00150
00151 #else
00152 rc = db_appexit(dbenv);
00153 rc = cvtdberr(dbi, "db_appexit", rc, _debug);
00154 free(dbenv);
00155 #endif
00156 dbi->dbi_dbenv = NULL;
00157 return rc;
00158 }
00159
00160 static int db3_fsync_disable( int fd) {
00161 return 0;
00162 }
00163
00164 static int db_init(dbiIndex dbi, const char *dbhome, const char *dbfile,
00165 const char * dbsubfile, DB_ENV **dbenvp)
00166 {
00167 rpmdb rpmdb = dbi->dbi_rpmdb;
00168 DB_ENV *dbenv = NULL;
00169 int eflags;
00170 int rc;
00171
00172 if (dbenvp == NULL)
00173 return 1;
00174
00175
00176 if (rpmdb->db_errfile == NULL)
00177 rpmdb->db_errfile = stderr;
00178
00179 eflags = (dbi->dbi_oeflags | dbi->dbi_eflags);
00180 if ( dbi->dbi_mode & O_CREAT) eflags |= DB_CREATE;
00181
00182 if (dbfile)
00183 rpmMessage(RPMMESS_DEBUG, _("opening db environment %s/%s %s\n"),
00184 dbhome, dbfile, prDbiOpenFlags(eflags, 1));
00185
00186 rc = db_env_create(&dbenv, dbi->dbi_cflags);
00187 rc = cvtdberr(dbi, "db_env_create", rc, _debug);
00188 if (rc)
00189 goto errxit;
00190
00191 #if defined(__USE_DB3)
00192 { int xx;
00193 dbenv->set_errcall(dbenv, rpmdb->db_errcall);
00194 dbenv->set_errfile(dbenv, rpmdb->db_errfile);
00195 dbenv->set_errpfx(dbenv, rpmdb->db_errpfx);
00196
00197 dbenv->set_verbose(dbenv, DB_VERB_CHKPOINT,
00198 (dbi->dbi_verbose & DB_VERB_CHKPOINT));
00199 dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK,
00200 (dbi->dbi_verbose & DB_VERB_DEADLOCK));
00201 dbenv->set_verbose(dbenv, DB_VERB_RECOVERY,
00202 (dbi->dbi_verbose & DB_VERB_RECOVERY));
00203 dbenv->set_verbose(dbenv, DB_VERB_WAITSFOR,
00204 (dbi->dbi_verbose & DB_VERB_WAITSFOR));
00205
00206
00207
00208
00209 xx = dbenv->set_mp_mmapsize(dbenv, dbi->dbi_mp_mmapsize);
00210 xx = cvtdberr(dbi, "dbenv->set_mp_mmapsize", xx, _debug);
00211 xx = dbenv->set_cachesize(dbenv, 0, dbi->dbi_mp_size, 0);
00212 xx = cvtdberr(dbi, "dbenv->set_cachesize", xx, _debug);
00213
00214
00215 if (dbi->dbi_no_fsync) {
00216 #if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1
00217 xx = db_env_set_func_fsync(db3_fsync_disable);
00218 #else
00219 xx = dbenv->set_func_fsync(dbenv, db3_fsync_disable);
00220 #endif
00221 xx = cvtdberr(dbi, "db_env_set_func_fsync", xx, _debug);
00222 }
00223 }
00224 #else
00225 dbenv->db_errcall = rpmdb->db_errcall;
00226 dbenv->db_errfile = rpmdb->db_errfile;
00227 dbenv->db_errpfx = rpmdb->db_errpfx;
00228 dbenv->db_verbose = dbi->dbi_verbose;
00229 dbenv->mp_mmapsize = dbi->dbi_mp_mmapsize;
00230 dbenv->mp_size = dbi->dbi_mp_size;
00231 #endif
00232
00233 #if defined(__USE_DB3)
00234 #if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1
00235 rc = dbenv->open(dbenv, dbhome, eflags, dbi->dbi_perms);
00236 #else
00237 rc = dbenv->open(dbenv, dbhome, NULL, eflags, dbi->dbi_perms);
00238 #endif
00239 rc = cvtdberr(dbi, "dbenv->open", rc, _debug);
00240 if (rc)
00241 goto errxit;
00242 #else
00243 rc = db_appinit(dbhome, NULL, dbenv, eflags);
00244 rc = cvtdberr(dbi, "db_appinit", rc, _debug);
00245 if (rc)
00246 goto errxit;
00247 #endif
00248
00249 *dbenvp = dbenv;
00250
00251 return 0;
00252
00253 errxit:
00254
00255 #if defined(__USE_DB3)
00256 if (dbenv) {
00257 int xx;
00258 xx = dbenv->close(dbenv, 0);
00259 xx = cvtdberr(dbi, "dbenv->close", xx, _debug);
00260 }
00261 #else
00262 if (dbenv) free(dbenv);
00263 #endif
00264 return rc;
00265 }
00266
00267 #endif
00268
00269 static int db3sync(dbiIndex dbi, unsigned int flags)
00270 {
00271 DB * db = dbi->dbi_db;
00272 int rc;
00273
00274 #if defined(__USE_DB2) || defined(__USE_DB3)
00275 int _printit;
00276
00277 rc = db->sync(db, flags);
00278
00279 _printit = (rc == DB_INCOMPLETE ? 0 : _debug);
00280 rc = cvtdberr(dbi, "db->sync", rc, _printit);
00281 #else
00282 rc = db->sync(db, flags);
00283 #endif
00284
00285 return rc;
00286 }
00287
00288 static int db3c_del(dbiIndex dbi, DBC * dbcursor, u_int32_t flags)
00289 {
00290 int rc;
00291
00292 rc = dbcursor->c_del(dbcursor, flags);
00293 rc = cvtdberr(dbi, "dbcursor->c_del", rc, _debug);
00294 return rc;
00295 }
00296
00297 static int db3c_dup(dbiIndex dbi, DBC * dbcursor, DBC ** dbcp,
00298 u_int32_t flags)
00299 {
00300 int rc;
00301
00302 rc = dbcursor->c_dup(dbcursor, dbcp, flags);
00303 rc = cvtdberr(dbi, "dbcursor->c_dup", rc, _debug);
00304 return rc;
00305 }
00306
00307 static int db3c_get(dbiIndex dbi, DBC * dbcursor,
00308 DBT * key, DBT * data, u_int32_t flags)
00309 {
00310 int _printit;
00311 int rc;
00312 int rmw;
00313
00314 #ifdef NOTYET
00315 if ((dbi->dbi_eflags & DB_INIT_CDB) && !(dbi->dbi_oflags & DB_RDONLY))
00316 rmw = DB_RMW;
00317 else
00318 #endif
00319 rmw = 0;
00320
00321 rc = dbcursor->c_get(dbcursor, key, data, rmw | flags);
00322
00323
00324 _printit = (rc == DB_NOTFOUND ? 0 : _debug);
00325 rc = cvtdberr(dbi, "dbcursor->c_get", rc, _printit);
00326 return rc;
00327 }
00328
00329 static int db3c_put(dbiIndex dbi, DBC * dbcursor,
00330 DBT * key, DBT * data, u_int32_t flags)
00331 {
00332 int rc;
00333
00334 rc = dbcursor->c_put(dbcursor, key, data, flags);
00335
00336 rc = cvtdberr(dbi, "dbcursor->c_put", rc, _debug);
00337 return rc;
00338 }
00339
00340 static inline int db3c_close(dbiIndex dbi, DBC * dbcursor)
00341 {
00342 int rc;
00343
00344 rc = dbcursor->c_close(dbcursor);
00345 rc = cvtdberr(dbi, "dbcursor->c_close", rc, _debug);
00346 return rc;
00347 }
00348
00349 static inline int db3c_open(dbiIndex dbi, DBC ** dbcp)
00350 {
00351 DB * db = dbi->dbi_db;
00352 DB_TXN * txnid = NULL;
00353 int flags;
00354 int rc;
00355
00356 #if defined(__USE_DB3)
00357 if ((dbi->dbi_eflags & DB_INIT_CDB) && !(dbi->dbi_oflags & DB_RDONLY))
00358 flags = DB_WRITECURSOR;
00359 else
00360 flags = 0;
00361 rc = db->cursor(db, txnid, dbcp, flags);
00362 #else
00363 rc = db->cursor(db, txnid, dbcp);
00364 #endif
00365 rc = cvtdberr(dbi, "db3c_open", rc, _debug);
00366
00367 return rc;
00368 }
00369
00370 static int db3cclose(dbiIndex dbi, DBC * dbcursor,
00371 unsigned int flags)
00372 {
00373 int rc = 0;
00374
00375
00376 if (flags == 1)
00377 return db3c_close(dbi, dbcursor);
00378
00379 if (!dbi->dbi_use_cursors)
00380 return 0;
00381
00382 if (dbcursor == NULL)
00383 dbcursor = dbi->dbi_rmw;
00384 if (dbcursor) {
00385 if (dbcursor == dbi->dbi_rmw)
00386 dbi->dbi_rmw = NULL;
00387 rc = db3c_close(dbi, dbcursor);
00388 }
00389 return rc;
00390 }
00391
00392 static int db3copen(dbiIndex dbi, DBC ** dbcp, unsigned int flags)
00393 {
00394 DBC * dbcursor;
00395 int rc = 0;
00396
00397
00398 if (flags == 1)
00399 return db3c_open(dbi, dbcp);
00400
00401 if (!dbi->dbi_use_cursors) {
00402 if (dbcp) *dbcp = NULL;
00403 return 0;
00404 }
00405
00406 if ((dbcursor = dbi->dbi_rmw) == NULL) {
00407 if ((rc = db3c_open(dbi, &dbcursor)) == 0)
00408 dbi->dbi_rmw = dbcursor;
00409 }
00410
00411 if (dbcp)
00412 *dbcp = dbi->dbi_rmw;
00413
00414 return rc;
00415 }
00416
00417 static int db3cput(dbiIndex dbi, DBC * dbcursor,
00418 const void * keyp, size_t keylen,
00419 const void * datap, size_t datalen,
00420 unsigned int flags)
00421 {
00422 DB * db = dbi->dbi_db;
00423 DB_TXN * txnid = NULL;
00424 DBT key, data;
00425 int rc;
00426
00427 memset(&key, 0, sizeof(key));
00428 memset(&data, 0, sizeof(data));
00429 key.data = (void *)keyp;
00430 key.size = keylen;
00431 data.data = (void *)datap;
00432 data.size = datalen;
00433
00434 if (dbcursor == NULL) {
00435 rc = db->put(db, txnid, &key, &data, 0);
00436 rc = cvtdberr(dbi, "db->put", rc, _debug);
00437 } else {
00438
00439 rc = db3c_put(dbi, dbcursor, &key, &data, DB_KEYLAST);
00440
00441 }
00442
00443 return rc;
00444 }
00445
00446 static int db3cdel(dbiIndex dbi, DBC * dbcursor,
00447 const void * keyp, size_t keylen,
00448 unsigned int flags)
00449 {
00450 DB * db = dbi->dbi_db;
00451 DB_TXN * txnid = NULL;
00452 DBT key, data;
00453 int rc;
00454
00455 memset(&key, 0, sizeof(key));
00456 memset(&data, 0, sizeof(data));
00457
00458 key.data = (void *)keyp;
00459 key.size = keylen;
00460
00461 if (dbcursor == NULL) {
00462 rc = db->del(db, txnid, &key, 0);
00463 rc = cvtdberr(dbi, "db->del", rc, _debug);
00464 } else {
00465
00466 rc = db3c_get(dbi, dbcursor, &key, &data, DB_SET);
00467
00468 if (rc == 0) {
00469
00470 rc = db3c_del(dbi, dbcursor, 0);
00471 }
00472
00473 }
00474
00475 return rc;
00476 }
00477
00478 static int db3cget(dbiIndex dbi, DBC * dbcursor,
00479 void ** keyp, size_t * keylen,
00480 void ** datap, size_t * datalen,
00481 unsigned int flags)
00482 {
00483 DB * db = dbi->dbi_db;
00484 DB_TXN * txnid = NULL;
00485 DBT key, data;
00486 int rc;
00487
00488 memset(&key, 0, sizeof(key));
00489 memset(&data, 0, sizeof(data));
00490 if (keyp) key.data = *keyp;
00491 if (keylen) key.size = *keylen;
00492 if (datap) data.data = *datap;
00493 if (datalen) data.size = *datalen;
00494
00495 if (dbcursor == NULL) {
00496 int _printit;
00497 rc = db->get(db, txnid, &key, &data, 0);
00498
00499 _printit = (rc == DB_NOTFOUND ? 0 : _debug);
00500 rc = cvtdberr(dbi, "db->get", rc, _printit);
00501 } else {
00502
00503
00504 rc = db3c_get(dbi, dbcursor, &key, &data,
00505 key.data == NULL ? DB_NEXT : DB_SET);
00506
00507 }
00508
00509 if (rc == 0) {
00510 if (keyp) *keyp = key.data;
00511 if (keylen) *keylen = key.size;
00512 if (datap) *datap = data.data;
00513 if (datalen) *datalen = data.size;
00514 }
00515
00516 return rc;
00517 }
00518
00519 static int db3byteswapped(dbiIndex dbi)
00520 {
00521 DB * db = dbi->dbi_db;
00522 int rc = 0;
00523
00524 #if defined(__USE_DB3)
00525 rc = db->get_byteswapped(db);
00526 #endif
00527
00528 return rc;
00529 }
00530
00531 static int db3close( dbiIndex dbi, unsigned int flags)
00532 {
00533 rpmdb rpmdb = dbi->dbi_rpmdb;
00534 const char * urlfn = NULL;
00535 const char * dbhome;
00536 const char * dbfile;
00537 const char * dbsubfile;
00538 DB * db = dbi->dbi_db;
00539 int rc = 0, xx;
00540
00541 urlfn = rpmGenPath(
00542 (dbi->dbi_root ? dbi->dbi_root : rpmdb->db_root),
00543 (dbi->dbi_home ? dbi->dbi_home : rpmdb->db_home),
00544 NULL);
00545 (void) urlPath(urlfn, &dbhome);
00546 if (dbi->dbi_temporary) {
00547 dbfile = NULL;
00548 dbsubfile = NULL;
00549 } else {
00550 #ifdef HACK
00551 dbfile = (dbi->dbi_file ? dbi->dbi_file : db3basename);
00552 dbsubfile = (dbi->dbi_subfile ? dbi->dbi_subfile : tagName(dbi->dbi_rpmtag));
00553 #else
00554 dbfile = (dbi->dbi_file ? dbi->dbi_file : tagName(dbi->dbi_rpmtag));
00555 dbsubfile = NULL;
00556 #endif
00557 }
00558
00559 #if defined(__USE_DB2) || defined(__USE_DB3)
00560
00561 if (dbi->dbi_rmw)
00562 db3cclose(dbi, NULL, 0);
00563
00564 if (db) {
00565 rc = db->close(db, 0);
00566 rc = cvtdberr(dbi, "db->close", rc, _debug);
00567 db = dbi->dbi_db = NULL;
00568
00569 rpmMessage(RPMMESS_DEBUG, _("closed db index %s/%s\n"),
00570 dbhome, (dbfile ? dbfile : tagName(dbi->dbi_rpmtag)));
00571
00572 }
00573
00574 if (dbi->dbi_dbinfo) {
00575 free(dbi->dbi_dbinfo);
00576 dbi->dbi_dbinfo = NULL;
00577 }
00578
00579 if (dbi->dbi_use_dbenv)
00580 xx = db_fini(dbi, dbhome, dbfile, dbsubfile);
00581
00582 #else
00583
00584 rc = db->close(db);
00585
00586 #endif
00587 dbi->dbi_db = NULL;
00588
00589 if (urlfn)
00590 free((void *)urlfn);
00591
00592 db3Free(dbi);
00593
00594 return rc;
00595 }
00596
00597 static int db3open( rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
00598 {
00599 const char * urlfn = NULL;
00600 const char * dbhome;
00601 const char * dbfile;
00602 const char * dbsubfile;
00603 extern struct _dbiVec db3vec;
00604 dbiIndex dbi = NULL;
00605 int rc = 0;
00606 int xx;
00607
00608 #if defined(__USE_DB2) || defined(__USE_DB3)
00609 DB * db = NULL;
00610 DB_ENV * dbenv = NULL;
00611 DB_TXN * txnid = NULL;
00612 u_int32_t oflags;
00613 int _printit;
00614
00615 if (dbip)
00616 *dbip = NULL;
00617 if ((dbi = db3New(rpmdb, rpmtag)) == NULL)
00618 return 1;
00619 dbi->dbi_api = DB_VERSION_MAJOR;
00620
00621 urlfn = rpmGenPath(
00622 (dbi->dbi_root ? dbi->dbi_root : rpmdb->db_root),
00623 (dbi->dbi_home ? dbi->dbi_home : rpmdb->db_home),
00624 NULL);
00625 (void) urlPath(urlfn, &dbhome);
00626 if (dbi->dbi_temporary) {
00627 dbfile = NULL;
00628 dbsubfile = NULL;
00629 } else {
00630 #ifdef HACK
00631 dbfile = (dbi->dbi_file ? dbi->dbi_file : db3basename);
00632 dbsubfile = (dbi->dbi_subfile ? dbi->dbi_subfile : tagName(dbi->dbi_rpmtag));
00633 #else
00634 dbfile = (dbi->dbi_file ? dbi->dbi_file : tagName(dbi->dbi_rpmtag));
00635 dbsubfile = NULL;
00636 #endif
00637 }
00638
00639 oflags = (dbi->dbi_oeflags | dbi->dbi_oflags);
00640 oflags &= ~DB_TRUNCATE;
00641
00642 #if 0
00643 if ( dbi->dbi_mode & O_EXCL) oflags |= DB_EXCL;
00644 #endif
00645 if (dbi->dbi_temporary) {
00646 oflags &= ~DB_RDONLY;
00647 oflags |= DB_CREATE;
00648 } else {
00649 if(!(dbi->dbi_mode & O_RDWR)) oflags |= DB_RDONLY;
00650 if ( dbi->dbi_mode & O_CREAT) oflags |= DB_CREATE;
00651 if ( dbi->dbi_mode & O_TRUNC) oflags |= DB_TRUNCATE;
00652 }
00653
00654 dbi->dbi_dbinfo = NULL;
00655
00656 if (dbi->dbi_use_dbenv)
00657 rc = db_init(dbi, dbhome, dbfile, dbsubfile, &dbenv);
00658
00659 rpmMessage(RPMMESS_DEBUG, _("opening db index %s/%s %s mode=0x%x\n"),
00660 dbhome, (dbfile ? dbfile : tagName(dbi->dbi_rpmtag)),
00661 prDbiOpenFlags(oflags, 0), dbi->dbi_mode);
00662
00663 if (rc == 0) {
00664 #if defined(__USE_DB3)
00665 rc = db_create(&db, dbenv, dbi->dbi_cflags);
00666 rc = cvtdberr(dbi, "db_create", rc, _debug);
00667 if (rc == 0) {
00668 if (dbi->dbi_lorder) {
00669 rc = db->set_lorder(db, dbi->dbi_lorder);
00670 rc = cvtdberr(dbi, "db->set_lorder", rc, _debug);
00671 }
00672 if (dbi->dbi_cachesize) {
00673 rc = db->set_cachesize(db, 0, dbi->dbi_cachesize, 0);
00674 rc = cvtdberr(dbi, "db->set_cachesize", rc, _debug);
00675 }
00676 if (dbi->dbi_pagesize) {
00677 rc = db->set_pagesize(db, dbi->dbi_pagesize);
00678 rc = cvtdberr(dbi, "db->set_pagesize", rc, _debug);
00679 }
00680 if (rpmdb->db_malloc) {
00681 rc = db->set_malloc(db, rpmdb->db_malloc);
00682 rc = cvtdberr(dbi, "db->set_malloc", rc, _debug);
00683 }
00684 if (oflags & DB_CREATE) {
00685 switch(dbi->dbi_type) {
00686 default:
00687 case DB_HASH:
00688 if (dbi->dbi_h_ffactor) {
00689 rc = db->set_h_ffactor(db, dbi->dbi_h_ffactor);
00690 rc = cvtdberr(dbi, "db->set_h_ffactor", rc, _debug);
00691 }
00692 if (dbi->dbi_h_hash_fcn) {
00693 rc = db->set_h_hash(db, dbi->dbi_h_hash_fcn);
00694 rc = cvtdberr(dbi, "db->set_h_hash", rc, _debug);
00695 }
00696 if (dbi->dbi_h_nelem) {
00697 rc = db->set_h_nelem(db, dbi->dbi_h_nelem);
00698 rc = cvtdberr(dbi, "db->set_h_nelem", rc, _debug);
00699 }
00700 if (dbi->dbi_h_flags) {
00701 rc = db->set_flags(db, dbi->dbi_h_flags);
00702 rc = cvtdberr(dbi, "db->set_h_flags", rc, _debug);
00703 }
00704 if (dbi->dbi_h_dup_compare_fcn) {
00705 rc = db->set_dup_compare(db, dbi->dbi_h_dup_compare_fcn);
00706 rc = cvtdberr(dbi, "db->set_dup_compare", rc, _debug);
00707 }
00708 break;
00709 case DB_BTREE:
00710 case DB_RECNO:
00711 case DB_QUEUE:
00712 break;
00713 }
00714 }
00715 dbi->dbi_dbinfo = NULL;
00716
00717 { const char * dbfullpath;
00718 const char * dbpath;
00719 char * t;
00720 int nb;
00721
00722 nb = strlen(dbhome);
00723 if (dbfile) nb += 1 + strlen(dbfile);
00724 dbfullpath = t = alloca(nb + 1);
00725
00726 t = stpcpy(t, dbhome);
00727 if (dbfile)
00728 t = stpcpy( stpcpy( t, "/"), dbfile);
00729 dbpath = (!dbi->dbi_use_dbenv && !dbi->dbi_temporary)
00730 ? dbfullpath : dbfile;
00731
00732 rc = db->open(db, dbpath, dbsubfile,
00733 dbi->dbi_type, oflags, dbi->dbi_perms);
00734 }
00735
00736
00737 _printit = (rc > 0 ? 0 : _debug);
00738 xx = cvtdberr(dbi, "db->open", rc, _printit);
00739
00740 if (rc == 0 && dbi->dbi_get_rmw_cursor) {
00741 DBC * dbcursor = NULL;
00742 xx = db->cursor(db, txnid, &dbcursor,
00743 ((oflags & DB_RDONLY) ? 0 : DB_WRITECURSOR));
00744 xx = cvtdberr(dbi, "db->cursor", xx, _debug);
00745 dbi->dbi_rmw = dbcursor;
00746 } else
00747 dbi->dbi_rmw = NULL;
00748
00749 if (rc == 0 && dbi->dbi_lockdbfd) {
00750 int fdno = -1;
00751
00752 if (!(db->fd(db, &fdno) == 0 && fdno >= 0)) {
00753 rc = 1;
00754 } else {
00755 struct flock l;
00756 l.l_whence = 0;
00757 l.l_start = 0;
00758 l.l_len = 0;
00759 l.l_type = (dbi->dbi_mode & O_RDWR) ? F_WRLCK : F_RDLCK;
00760 l.l_pid = 0;
00761
00762 if (fcntl(fdno, F_SETLK, (void *) &l)) {
00763 rpmError(RPMERR_FLOCK,
00764 _("cannot get %s lock on %s/%s\n"),
00765 ((dbi->dbi_mode & O_RDWR)
00766 ? _("exclusive") : _("shared")),
00767 dbhome, dbfile);
00768 rc = 1;
00769 } else if (dbfile) {
00770 rpmMessage(RPMMESS_DEBUG,
00771 _("locked db index %s/%s\n"),
00772 dbhome, dbfile);
00773 }
00774 }
00775 }
00776 }
00777 #else
00778 { DB_INFO * dbinfo = xcalloc(1, sizeof(*dbinfo));
00779 dbinfo->db_cachesize = dbi->dbi_cachesize;
00780 dbinfo->db_lorder = dbi->dbi_lorder;
00781 dbinfo->db_pagesize = dbi->dbi_pagesize;
00782 dbinfo->db_malloc = rpmdb->db_malloc;
00783 if (oflags & DB_CREATE) {
00784 switch(dbi->dbi_type) {
00785 default:
00786 case DB_HASH:
00787 dbinfo->h_ffactor = dbi->dbi_h_ffactor;
00788 dbinfo->h_hash = dbi->dbi_h_hash_fcn;
00789 dbinfo->h_nelem = dbi->dbi_h_nelem;
00790 dbinfo->flags = dbi->dbi_h_flags;
00791 break;
00792 }
00793 }
00794 dbi->dbi_dbinfo = dbinfo;
00795 rc = db_open(dbfile, dbi->dbi_type, oflags,
00796 dbi->dbi_perms, dbenv, dbinfo, &db);
00797
00798 _printit = (rc > 0 ? 0 : _debug);
00799 xx = cvtdberr(dbi, "db->open", rc, _printit);
00800 }
00801 #endif
00802 }
00803
00804 dbi->dbi_db = db;
00805 dbi->dbi_dbenv = dbenv;
00806
00807 #else
00808 void * dbopeninfo = NULL;
00809
00810 if (dbip)
00811 *dbip = NULL;
00812 if ((dbi = db3New(rpmdb, rpmtag)) == NULL)
00813 return 1;
00814
00815 dbi->dbi_db = dbopen(dbfile, dbi->dbi_mode, dbi->dbi_perms,
00816 dbi->dbi_type, dbopeninfo);
00817
00818 if (dbi->dbi_db == NULL) rc = errno;
00819 #endif
00820
00821 if (rc == 0 && dbi->dbi_db != NULL && dbip != NULL) {
00822 dbi->dbi_vec = &db3vec;
00823 *dbip = dbi;
00824 } else
00825 db3close(dbi, 0);
00826
00827 if (urlfn)
00828 free((void *)urlfn);
00829
00830 return rc;
00831 }
00832
00835 struct _dbiVec db3vec = {
00836 DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH,
00837 db3open, db3close, db3sync, db3copen, db3cclose, db3cdel, db3cget, db3cput,
00838 db3byteswapped
00839 };
00840
00841 #endif