1102644Snectar/* 2233294Sstas * Copyright (c) 2002 Kungliga Tekniska H��gskolan 3102644Snectar * (Royal Institute of Technology, Stockholm, Sweden). 4102644Snectar * All rights reserved. 5233294Sstas * 6102644Snectar * Redistribution and use in source and binary forms, with or without 7102644Snectar * modification, are permitted provided that the following conditions 8102644Snectar * are met: 9233294Sstas * 10102644Snectar * 1. Redistributions of source code must retain the above copyright 11102644Snectar * notice, this list of conditions and the following disclaimer. 12233294Sstas * 13102644Snectar * 2. Redistributions in binary form must reproduce the above copyright 14102644Snectar * notice, this list of conditions and the following disclaimer in the 15102644Snectar * documentation and/or other materials provided with the distribution. 16233294Sstas * 17102644Snectar * 3. Neither the name of the Institute nor the names of its contributors 18102644Snectar * may be used to endorse or promote products derived from this software 19102644Snectar * without specific prior written permission. 20233294Sstas * 21102644Snectar * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22102644Snectar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23102644Snectar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24102644Snectar * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25102644Snectar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26102644Snectar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27102644Snectar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28102644Snectar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29102644Snectar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30102644Snectar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31102644Snectar * SUCH DAMAGE. 32102644Snectar */ 33102644Snectar 34102644Snectar#include <config.h> 35102644Snectar 36102644Snectar#include "ndbm_wrap.h" 37233294Sstas#if defined(HAVE_DBHEADER) 38233294Sstas#include <db.h> 39233294Sstas#elif defined(HAVE_DB5_DB_H) 40233294Sstas#include <db5/db.h> 41233294Sstas#elif defined(HAVE_DB4_DB_H) 42102644Snectar#include <db4/db.h> 43102644Snectar#elif defined(HAVE_DB3_DB_H) 44102644Snectar#include <db3/db.h> 45102644Snectar#else 46102644Snectar#include <db.h> 47102644Snectar#endif 48102644Snectar 49102644Snectar#include <stdio.h> 50102644Snectar#include <stdlib.h> 51102644Snectar#include <string.h> 52102644Snectar#include <fcntl.h> 53102644Snectar 54178825Sdfr/* XXX undefine open so this works on Solaris with large file support */ 55178825Sdfr#undef open 56102644Snectar 57102644Snectar#define DBT2DATUM(DBT, DATUM) do { (DATUM)->dptr = (DBT)->data; (DATUM)->dsize = (DBT)->size; } while(0) 58102644Snectar#define DATUM2DBT(DATUM, DBT) do { (DBT)->data = (DATUM)->dptr; (DBT)->size = (DATUM)->dsize; } while(0) 59102644Snectar#define RETURN(X) return ((X) == 0) ? 0 : -1 60102644Snectar 61102644Snectar#ifdef HAVE_DB3 62102644Snectarstatic DBC *cursor; 63102644Snectar#endif 64102644Snectar 65102644Snectar#define D(X) ((DB*)(X)) 66102644Snectar 67233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 68102644Snectardbm_close (DBM *db) 69102644Snectar{ 70102644Snectar#ifdef HAVE_DB3 71102644Snectar D(db)->close(D(db), 0); 72102644Snectar cursor = NULL; 73102644Snectar#else 74102644Snectar D(db)->close(D(db)); 75102644Snectar#endif 76102644Snectar} 77102644Snectar 78233294SstasROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 79102644Snectardbm_delete (DBM *db, datum dkey) 80102644Snectar{ 81102644Snectar DBT key; 82102644Snectar DATUM2DBT(&dkey, &key); 83102644Snectar#ifdef HAVE_DB3 84102644Snectar RETURN(D(db)->del(D(db), NULL, &key, 0)); 85102644Snectar#else 86102644Snectar RETURN(D(db)->del(D(db), &key, 0)); 87102644Snectar#endif 88102644Snectar} 89102644Snectar 90102644Snectardatum 91102644Snectardbm_fetch (DBM *db, datum dkey) 92102644Snectar{ 93102644Snectar datum dvalue; 94102644Snectar DBT key, value; 95102644Snectar DATUM2DBT(&dkey, &key); 96233294Sstas if(D(db)->get(D(db), 97102644Snectar#ifdef HAVE_DB3 98233294Sstas NULL, 99102644Snectar#endif 100178825Sdfr &key, &value, 0) != 0) { 101102644Snectar dvalue.dptr = NULL; 102178825Sdfr dvalue.dsize = 0; 103178825Sdfr } 104102644Snectar else 105102644Snectar DBT2DATUM(&value, &dvalue); 106102644Snectar 107102644Snectar return dvalue; 108102644Snectar} 109102644Snectar 110102644Snectarstatic datum 111102644Snectardbm_get (DB *db, int flags) 112102644Snectar{ 113102644Snectar DBT key, value; 114102644Snectar datum datum; 115102644Snectar#ifdef HAVE_DB3 116233294Sstas if(cursor == NULL) 117102644Snectar db->cursor(db, NULL, &cursor, 0); 118178825Sdfr if(cursor->c_get(cursor, &key, &value, flags) != 0) { 119102644Snectar datum.dptr = NULL; 120178825Sdfr datum.dsize = 0; 121233294Sstas } else 122102644Snectar DBT2DATUM(&value, &datum); 123102644Snectar#else 124102644Snectar db->seq(db, &key, &value, flags); 125233294Sstas DBT2DATUM(&value, &datum); 126102644Snectar#endif 127102644Snectar return datum; 128102644Snectar} 129102644Snectar 130102644Snectar#ifndef DB_FIRST 131102644Snectar#define DB_FIRST R_FIRST 132102644Snectar#define DB_NEXT R_NEXT 133102644Snectar#define DB_NOOVERWRITE R_NOOVERWRITE 134102644Snectar#define DB_KEYEXIST 1 135102644Snectar#endif 136102644Snectar 137233294SstasROKEN_LIB_FUNCTION datum ROKEN_LIB_CALL 138102644Snectardbm_firstkey (DBM *db) 139102644Snectar{ 140102644Snectar return dbm_get(D(db), DB_FIRST); 141102644Snectar} 142102644Snectar 143233294SstasROKEN_LIB_FUNCTION datum ROKEN_LIB_CALL 144102644Snectardbm_nextkey (DBM *db) 145102644Snectar{ 146102644Snectar return dbm_get(D(db), DB_NEXT); 147102644Snectar} 148102644Snectar 149233294SstasROKEN_LIB_FUNCTION DBM* ROKEN_LIB_CALL 150102644Snectardbm_open (const char *file, int flags, mode_t mode) 151102644Snectar{ 152233294Sstas#ifdef HAVE_DB3 153233294Sstas int myflags = 0; 154233294Sstas#endif 155102644Snectar DB *db; 156102644Snectar char *fn = malloc(strlen(file) + 4); 157102644Snectar if(fn == NULL) 158102644Snectar return NULL; 159102644Snectar strcpy(fn, file); 160102644Snectar strcat(fn, ".db"); 161102644Snectar#ifdef HAVE_DB3 162102644Snectar if (flags & O_CREAT) 163102644Snectar myflags |= DB_CREATE; 164102644Snectar 165102644Snectar if (flags & O_EXCL) 166102644Snectar myflags |= DB_EXCL; 167102644Snectar 168102644Snectar if (flags & O_RDONLY) 169102644Snectar myflags |= DB_RDONLY; 170102644Snectar 171102644Snectar if (flags & O_TRUNC) 172102644Snectar myflags |= DB_TRUNCATE; 173102644Snectar if(db_create(&db, NULL, 0) != 0) { 174102644Snectar free(fn); 175102644Snectar return NULL; 176102644Snectar } 177127808Snectar 178127808Snectar#if (DB_VERSION_MAJOR > 3) && (DB_VERSION_MINOR > 0) 179127808Snectar if(db->open(db, NULL, fn, NULL, DB_BTREE, myflags, mode) != 0) { 180127808Snectar#else 181102644Snectar if(db->open(db, fn, NULL, DB_BTREE, myflags, mode) != 0) { 182127808Snectar#endif 183102644Snectar free(fn); 184102644Snectar db->close(db, 0); 185102644Snectar return NULL; 186102644Snectar } 187102644Snectar#else 188102644Snectar db = dbopen(fn, flags, mode, DB_BTREE, NULL); 189102644Snectar#endif 190102644Snectar free(fn); 191102644Snectar return (DBM*)db; 192102644Snectar} 193102644Snectar 194233294SstasROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 195102644Snectardbm_store (DBM *db, datum dkey, datum dvalue, int flags) 196102644Snectar{ 197102644Snectar int ret; 198102644Snectar DBT key, value; 199102644Snectar int myflags = 0; 200102644Snectar if((flags & DBM_REPLACE) == 0) 201102644Snectar myflags |= DB_NOOVERWRITE; 202102644Snectar DATUM2DBT(&dkey, &key); 203233294Sstas DATUM2DBT(&dvalue, &value); 204233294Sstas ret = D(db)->put(D(db), 205102644Snectar#ifdef HAVE_DB3 206233294Sstas NULL, 207102644Snectar#endif 208102644Snectar&key, &value, myflags); 209102644Snectar if(ret == DB_KEYEXIST) 210102644Snectar return 1; 211102644Snectar RETURN(ret); 212102644Snectar} 213102644Snectar 214233294SstasROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 215102644Snectardbm_error (DBM *db) 216102644Snectar{ 217102644Snectar return 0; 218102644Snectar} 219102644Snectar 220233294SstasROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 221102644Snectardbm_clearerr (DBM *db) 222102644Snectar{ 223102644Snectar return 0; 224102644Snectar} 225102644Snectar 226