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