I'm posting the source, as the patches would be too hard to read
I've split up the single apr_dbm.c into 2 parts. a logical interface, (apr_dbm.c) and a implementation. (apr_dbm_[SDBM/DB].c)
by doing this It allows: * other DB types to be added easily externally by other people * allows a 'default' db type for developers who just want a 'db' * allows developers to specify which DB they want * allows people to have multiple DB-types running at the same type.
If I could get some +1 votes I'll commit the changes (and get a GDBM version working)
..Ian
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */
#include "apr.h" #include "apr_errno.h" #include "apr_pools.h" #include "apr_strings.h" #define APR_WANT_MEMFUNC #define APR_WANT_STRFUNC #include "apr_want.h" #include "apu_select_dbm.h" #include "apr_dbm.h" /* this is so we can select a 'default' open/getnames */ #if APU_USE_SDBM #include "apr_dbm_sdbm.h" #elif APU_USE_DB #include "apr_dbm_db.h" #elif APU_USE_GDBM #include "gdbm.h" #include "gdbmerrno.h" #endif #include "dbm_private.h" /* Most DBM libraries take a POSIX mode for creating files. Don't trust * the mode_t type, some platforms may not support it, int is safe. */ APU_DECLARE(int) apr_posix_perms2mode(apr_fileperms_t perm) { int mode = 0; mode |= 0700 & (perm >> 2); /* User is off-by-2 bits */ mode |= 0070 & (perm >> 1); /* Group is off-by-1 bit */ mode |= 0007 & (perm); /* World maps 1 for 1 */ return mode; } APU_DECLARE(apr_status_t) apr_dbm_open(apr_dbm_t **pdb, const char *pathname, apr_int32_t mode, apr_fileperms_t perm, apr_pool_t *pool) { #if APU_USE_SDBM return apr_dbm_open_sdbm(pdb,pathname,mode,perm,pool); #elif APU_USE_DB return apr_dbm_open_db(pdb,pathname,mode,perm,pool); #else return APR_ENOTAVAIL; #endif } APU_DECLARE(void) apr_dbm_close(apr_dbm_t *dbm) { dbm->close (dbm); } APU_DECLARE(apr_status_t) apr_dbm_fetch(apr_dbm_t *dbm, apr_datum_t key, apr_datum_t *pvalue) { return dbm->fetch (dbm,key,pvalue); } APU_DECLARE(apr_status_t) apr_dbm_store(apr_dbm_t *dbm, apr_datum_t key, apr_datum_t value) { return dbm->store (dbm,key,value); } APU_DECLARE(apr_status_t) apr_dbm_delete(apr_dbm_t *dbm, apr_datum_t key) { return dbm->del (dbm,key); } APU_DECLARE(int) apr_dbm_exists(apr_dbm_t *dbm, apr_datum_t key) { return dbm->exists (dbm,key); } APU_DECLARE(apr_status_t) apr_dbm_firstkey(apr_dbm_t *dbm, apr_datum_t *pkey) { return dbm->firstkey (dbm,pkey); } APU_DECLARE(apr_status_t) apr_dbm_nextkey(apr_dbm_t *dbm, apr_datum_t *pkey) { return dbm->nextkey(dbm,pkey); } APU_DECLARE(void) apr_dbm_freedatum(apr_dbm_t *dbm, apr_datum_t data) { dbm->freedatum (dbm,data); } APU_DECLARE(char *) apr_dbm_geterror(apr_dbm_t *dbm, int *errcode, char *errbuf, apr_size_t errbufsize) { return dbm->geterror(dbm,errcode,errbuf,errbufsize); } APU_DECLARE(void) apr_dbm_get_usednames( apr_pool_t *p, const char *pathname, const char **used1, const char **used2) { #if APU_USE_SDBM apr_dbm_get_usednames_sdbm(p,pathname,used1,used2); #elif APU_USE_DB apr_dbm_get_usednames_db(p,pathname,used1,used2); #else /* default op. no assumptions made */ fprintf(stderr,"This Database does not implement apr_dbm_get_usednames"); *used1=NULL; *used2=NULL; #endif }
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ #include "apr.h" #include "apr_errno.h" #include "apr_pools.h" #include "apr_strings.h" #define APR_WANT_MEMFUNC #define APR_WANT_STRFUNC #include "apr_want.h" #include "apu_select_dbm.h" #include "apr_dbm.h" #include "dbm_private.h" #if APU_USE_DB #include "apr_dbm_db.h" /* * We pick up all varieties of Berkeley DB through db.h (included through * apu_select_dbm.h). This code has been compiled/tested against DB1, * DB_185, DB2, and DB3. */ #if defined(DB_VERSION_MAJOR) && (DB_VERSION_MAJOR == 3) #define DB_VER 3 #elif defined(DB_VERSION_MAJOR) && (DB_VERSION_MAJOR == 2) #define DB_VER 2 #else #define DB_VER 1 #endif typedef struct { DB *bdb; #if DB_VER != 1 DBC *curs; #endif } apr_berkley_db_t; #if DB_VER == 1 #include <sys/fcntl.h> #define APR_DBM_DBMODE_RO O_RDONLY #define APR_DBM_DBMODE_RW O_RDWR #define APR_DBM_DBMODE_RWCREATE (O_CREAT | O_RDWR) #else #define APR_DBM_DBMODE_RO DB_RDONLY #define APR_DBM_DBMODE_RW 0 #define APR_DBM_DBMODE_RWCREATE DB_CREATE #endif /* map a DB error to an apr_status_t */ static apr_status_t db2s(int dberr) { if (dberr != 0) { /* ### need to fix this */ return APR_OS_START_USEERR+dberr; } return APR_SUCCESS; } /* handle the FIRSTKEY functionality */ static apr_status_t do_firstkey(apr_berkley_db_t *f, DBT *pkey) { int dberr; DBT data; memset(&data,0,sizeof(DBT)); #if DB_VER == 1 dberr = (*f->bdb->seq)(f->bdb, pkey, &data, R_FIRST); #else if ((dberr = (*f->bdb->cursor)(f->bdb, NULL, &f->curs #if DB_VER == 3 , 0 #endif )) == 0) { dberr = (*f->curs->c_get)(f->curs, pkey, &data, DB_FIRST); if (dberr == DB_NOTFOUND) { memset(pkey, 0, sizeof(*pkey)); (*f->curs->c_close)(f->curs); f->curs = NULL; return APR_SUCCESS; } } #endif return db2s(dberr); } /* handle the NEXTKEY functionality This function also returns the 'data' as well as the key. */ static apr_status_t do_nextkey(apr_berkley_db_t *f, DBT *pkey, DBT *pdata) { int dberr; memset(pdata,0,sizeof(DBT)); #if DB_VER == 1 dberr = (*f->bdb->seq)(f->bdb, pkey, pdata, R_NEXT); #else if (f->curs == NULL) return APR_EINVAL; dberr = (*f->curs->c_get)(f->curs, pkey, pdata, DB_NEXT); if (dberr == DB_NOTFOUND) { memset(pkey, 0, sizeof(*pkey)); memset(pdata, 0, sizeof(*pdata)); (*f->curs->c_close)(f->curs); f->curs = NULL; return APR_SUCCESS; } #endif return db2s(dberr); } static apr_status_t apr_dbm_set_error_db(apr_dbm_t *dbm, apr_status_t dbm_said) { apr_status_t rv = APR_SUCCESS; /* ### ignore whatever the DBM said (dbm_said); ask it explicitly */ if (dbm_said == APR_SUCCESS) { dbm->errcode = 0; dbm->errmsg = NULL; } else { /* ### need to fix. dberr was tossed in db2s(). */ /* ### use db_strerror() */ dbm->errcode = dbm_said; dbm->errmsg = db_strerror( dbm_said - APR_OS_START_USEERR); rv = dbm_said; } return rv; } static void apr_dbm_close_db(apr_dbm_t *dbm) { //APR_DBM_CLOSE(dbm.file); apr_berkley_db_t *real_ptr = dbm->file; DB*db; if (real_ptr) { db = real_ptr->bdb; #if DB_VER == 1 db->close(db); #else db->close(db,0); #endif dbm->file=NULL; } } /* make sure we clean up and close things */ static apr_status_t db_cleanup(void* p) { apr_dbm_t **db=p; if (*db) { apr_dbm_close_db(*db); *db=NULL; } return APR_SUCCESS; } static apr_status_t apr_dbm_fetch_db(apr_dbm_t *dbm, apr_datum_t key, apr_datum_t *pvalue) { apr_status_t rv; apr_berkley_db_t *real_ptr = dbm->file; DB*db=real_ptr->bdb; DBT ckey; DBT rd; int dberr; memset(&ckey,0,sizeof(DBT)); memset(&rd,0,sizeof(DBT)); ckey.data = key.dptr; ckey.size = key.dsize; #if DB_VER == 1 dberr=db->get(db, &ckey,&rd,0); #else dberr=db->get(db, NULL,&ckey,&rd,0); #endif rv = db2s(dberr); //rv = APR_DBM_FETCH(dbm->file, ckey, rd); pvalue->dptr = rd.data; pvalue->dsize =rd.size; /* store the error info into DBM, and return a status code. Also, note that *pvalue should have been cleared on error. */ return apr_dbm_set_error_db(dbm, rv); } static apr_status_t apr_dbm_store_db(apr_dbm_t *dbm, apr_datum_t key, apr_datum_t value) { apr_status_t rv; int dberr; apr_berkley_db_t *real_ptr = dbm->file; DB*db=real_ptr->bdb; DBT ckey; DBT cvalue; memset(&ckey,0,sizeof(DBT)); ckey.data = key.dptr; ckey.size=key.dsize; memset(&cvalue,0,sizeof(DBT)); cvalue.data = value.dptr; cvalue.size=value.dsize; // rv = APR_DBM_STORE(dbm->file, ckey, cvalue); #if DB_VER == 1 dberr = db->put(db,&ckey,&cvalue,0); #else dberr = db->put(db,NULL,&ckey,&cvalue,0); #endif rv = db2s(dberr); /* store any error info into DBM, and return a status code. */ return apr_dbm_set_error_db(dbm, rv); } static apr_status_t apr_dbm_delete_db(apr_dbm_t *dbm, apr_datum_t key) { apr_status_t rv; DBT ckey; apr_berkley_db_t *real_ptr = dbm->file; DB*db=real_ptr->bdb; int dberr; memset(&ckey,0,sizeof(DBT)); ckey.data = key.dptr; ckey.size=key.dsize; #if DB_VER ==1 dberr = db->del(db,&ckey,0); #else dberr = db->del(db,NULL,&ckey,0); #endif rv = db2s(dberr); /* store any error info into DBM, and return a status code. */ return apr_dbm_set_error_db(dbm, rv); } static int apr_dbm_exists_db(apr_dbm_t *dbm, apr_datum_t key) { int exists; DBT ckey; DBT data; apr_berkley_db_t *real_ptr = dbm->file; DB*db=real_ptr->bdb; int dberr; // CONVERT_DATUM(ckey, &key); memset(&ckey,0,sizeof(DBT)); ckey.data = key.dptr; ckey.size=key.dsize; memset(&data,0,sizeof(DBT)); data.data = key.dptr; data.size=key.dsize; #if DB_VER ==1 dberr = db->get(db, &ckey, &data,0); #else dberr = db->get(db, NULL,&ckey, &data, 0); #endif /* DB returns DB_NOTFOUND if it doesn't exist. but we want to say that *any* error means it doesn't exist. */ exists = dberr == 0; return exists; } static apr_status_t apr_dbm_firstkey_db(apr_dbm_t *dbm, apr_datum_t *pkey) { apr_status_t rv; DBT rd; apr_berkley_db_t *real_ptr = dbm->file; memset(&rd,0,sizeof(DBT)); rv = do_firstkey(real_ptr,&rd); pkey->dptr = rd.data; pkey->dsize = rd.size; /* store any error info into DBM, and return a status code. */ return apr_dbm_set_error_db(dbm, rv); } static apr_status_t apr_dbm_nextkey_db(apr_dbm_t *dbm, apr_datum_t *pkey) { apr_status_t rv; DBT ckey; DBT rd; apr_berkley_db_t *real_ptr = dbm->file; memset(&rd,0,sizeof(DBT)); memset(&ckey,0,sizeof(DBT)); ckey.data = pkey->dptr; ckey.size=pkey->dsize; rv = do_nextkey(real_ptr,&ckey,&rd); pkey->dptr = ckey.data; pkey->dsize =ckey.size; /* store any error info into DBM, and return a status code. */ return apr_dbm_set_error_db(dbm, APR_SUCCESS); } static void apr_dbm_freedatum_noop(apr_dbm_t *dbm, apr_datum_t data) { //APR_DBM_FREEDPTR(data.dptr); } static apr_status_t apr_dbm_datum_cleanup_noop(void*x) { return APR_SUCCESS; } static char * apr_dbm_geterror_db(apr_dbm_t *dbm, int *errcode, char *errbuf, apr_size_t errbufsize) { if (errcode != NULL) *errcode = dbm->errcode; /* assert: errbufsize > 0 */ if (dbm->errmsg == NULL) *errbuf = '\0'; else (void) apr_cpystrn(errbuf, dbm->errmsg, errbufsize); return errbuf; } APU_DECLARE(void) apr_dbm_get_usednames_db( apr_pool_t *p, const char *pathname, const char **used1, const char **used2) { *used1 = apr_pstrdup(p, pathname); *used2 = NULL; } APU_DECLARE(apr_status_t) apr_dbm_open_db(apr_dbm_t **pdb, const char *pathname, apr_int32_t mode, apr_fileperms_t perm, apr_pool_t *pool) { apr_berkley_db_t *file=apr_palloc(pool,sizeof(apr_berkley_db_t)); int dbmode; int dberr; *pdb = NULL; switch (mode) { case APR_DBM_READONLY: dbmode = APR_DBM_DBMODE_RO; break; case APR_DBM_READWRITE: dbmode = APR_DBM_DBMODE_RW; break; case APR_DBM_RWCREATE: dbmode = APR_DBM_DBMODE_RWCREATE; break; default: return APR_EINVAL; } /* * Allocate the structure before attempting to open * the DB. * (so we can call a error routine if we fail to open) */ *pdb = apr_pcalloc(pool, sizeof(**pdb)); (*pdb)->pool = pool; (*pdb)->file = file; (*pdb)->close = apr_dbm_close_db; (*pdb)->set_error = apr_dbm_set_error_db; (*pdb)->fetch = apr_dbm_fetch_db; (*pdb)->store = apr_dbm_store_db; (*pdb)->del = apr_dbm_delete_db; (*pdb)->exists = apr_dbm_exists_db; (*pdb)->firstkey =apr_dbm_firstkey_db; (*pdb)->nextkey =apr_dbm_nextkey_db; (*pdb)->geterror =apr_dbm_geterror_db; (*pdb)->freedatum =apr_dbm_freedatum_noop; (*pdb)->datum_cleanup=apr_dbm_datum_cleanup_noop; #if DB_VER == 3 if ((dberr = db_create(&file->bdb, NULL, 0)) == 0) { if ((dberr = (*file->bdb->open)(file->bdb, pathname, NULL, DB_HASH, dbmode, apr_posix_perms2mode(perm))) != 0) { /* close the DB handler */ (void) (*file->bdb->close)(file->bdb, 0); } } file->curs = NULL; #elif DB_VER == 2 dberr = db_open(pathname, DB_HASH, dbmode, apr_posix_perms2mode(perm), NULL, NULL, &file->bdb); file->curs = NULL; #else file->bdb = dbopen(pathname, dbmode, apr_posix_perms2mode(perm), DB_HASH, NULL); if (file->bdb == NULL) return APR_OS_START_USEERR; /* ### need a better error */ dberr = 0; #endif if (dberr != 0) return apr_dbm_set_error_db(*pdb, db2s(dberr)); apr_pool_cleanup_register(pool, pdb, db_cleanup, apr_pool_cleanup_null); return APR_SUCCESS; } #endif /* APU_USE_DB */
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ #include "apr.h" #include "apr_errno.h" #include "apr_pools.h" #include "apr_strings.h" #define APR_WANT_MEMFUNC #define APR_WANT_STRFUNC #include "apr_want.h" #include "apu_select_dbm.h" #include "apr_dbm.h" #include "apu.h" #include "dbm_private.h" #if APU_USE_SDBM #include "apr_sdbm.h" //typedef apr_sdbm_t *real_file_t; //typedef apr_sdbm_datum_t *cvt_datum_t; //#define CONVERT_DATUM(cvt, pinput) ((cvt) = (apr_sdbm_datum_t *)(pinput)) //typedef apr_sdbm_datum_t result_datum_t; //#define RETURN_DATUM(poutput, rd) (*(poutput) = *(apr_datum_t *)&(rd)) //#define APR_DBM_CLOSE(f) apr_sdbm_close(f) //#define APR_DBM_FETCH(f, k, v) apr_sdbm_fetch(f, &(v), *(k)) //#define APR_DBM_STORE(f, k, v) apr_sdbm_store(f, *(k), *(v), APR_SDBM_REPLACE) //#define APR_DBM_DELETE(f, k) apr_sdbm_delete(f, *(k)) //#define APR_DBM_FIRSTKEY(f, k) apr_sdbm_firstkey(f, &(k)) //#define APR_DBM_NEXTKEY(f, k, nk) apr_sdbm_nextkey(f, &(nk)) //#define APR_DBM_FREEDPTR(dptr) NOOP_FUNCTION #define APR_DBM_DBMODE_RO APR_READ #define APR_DBM_DBMODE_RW (APR_READ | APR_WRITE) #define APR_DBM_DBMODE_RWCREATE (APR_READ | APR_WRITE | APR_CREATE) static void apr_dbm_close_sdbm(apr_dbm_t *dbm) { apr_sdbm_close((apr_sdbm_t*)dbm->file); } static apr_status_t apr_dbm_set_error_sdbm(apr_dbm_t *dbm, apr_status_t dbm_said) { apr_status_t rv = APR_SUCCESS; /* ### ignore whatever the DBM said (dbm_said); ask it explicitly */ if ((dbm->errcode = dbm_said) == APR_SUCCESS) { dbm->errmsg = NULL; } else { dbm->errmsg = "I/O error occurred."; rv = APR_EGENERAL; /* ### need something better */ } return rv; } static apr_status_t apr_dbm_fetch_sdbm(apr_dbm_t *dbm, apr_datum_t key, apr_datum_t *pvalue) { apr_status_t rv; apr_sdbm_datum_t *ckey; apr_sdbm_datum_t rd; ckey = (apr_sdbm_datum_t *)&key; rd.dptr=NULL; rd.dsize =-1; rv = apr_sdbm_fetch(dbm->file, &rd, *ckey); // rv = apr_sdbm_fetch(dbm->file , &ckey, *rd); *(pvalue) = *(apr_datum_t *)&rd; // REGISTER_CLEANUP(dbm, pvalue); /* store the error info into DBM, and return a status code. Also, note that *pvalue should have been cleared on error. */ return apr_dbm_set_error_sdbm(dbm, rv); } static apr_status_t apr_dbm_store_sdbm(apr_dbm_t *dbm, apr_datum_t key, apr_datum_t value) { apr_status_t rv; apr_sdbm_datum_t *ckey; apr_sdbm_datum_t *cvalue; // CONVERT_DATUM(ckey, &key); ckey = (apr_sdbm_datum_t*)&key; cvalue = (apr_sdbm_datum_t*)&value; // CONVERT_DATUM(cvalue, &value); rv = apr_sdbm_store(dbm->file, *ckey, *cvalue,APR_SDBM_REPLACE); /* store any error info into DBM, and return a status code. */ return apr_dbm_set_error_sdbm(dbm, rv); } static apr_status_t apr_dbm_delete_sdbm(apr_dbm_t *dbm, apr_datum_t key) { apr_status_t rv; apr_sdbm_datum_t *ckey; // CONVERT_DATUM(ckey, &key); ckey = (apr_sdbm_datum_t*)&key; rv = apr_sdbm_delete(dbm->file, *ckey); /* store any error info into DBM, and return a status code. */ return apr_dbm_set_error_sdbm(dbm, rv); } static int apr_dbm_exists_sdbm(apr_dbm_t *dbm, apr_datum_t key) { int exists; apr_sdbm_datum_t *ckey; apr_sdbm_datum_t value; // CONVERT_DATUM(ckey, &key); ckey = (apr_sdbm_datum_t*)&key; if (apr_sdbm_fetch(dbm->file, &value, *ckey) != APR_SUCCESS) { exists = 0; } else { exists = value.dptr != NULL; } return exists; } static apr_status_t apr_dbm_firstkey_sdbm(apr_dbm_t *dbm, apr_datum_t *pkey) { apr_status_t rv; apr_sdbm_datum_t rd; rv = apr_sdbm_firstkey(dbm->file, &rd); // RETURN_DATUM(pkey, rd); *pkey=*(apr_datum_t *)&rd; // REGISTER_CLEANUP(dbm, pkey); /* store any error info into DBM, and return a status code. */ return apr_dbm_set_error_sdbm(dbm, rv); } static apr_status_t apr_dbm_nextkey_sdbm(apr_dbm_t *dbm, apr_datum_t *pkey) { apr_status_t rv; apr_sdbm_datum_t *ckey; apr_sdbm_datum_t rd; ckey = (apr_sdbm_datum_t*)pkey; rv = apr_sdbm_nextkey(dbm->file, &rd); *pkey=*(apr_datum_t *)&rd; // REGISTER_CLEANUP(dbm, pkey); /* store any error info into DBM, and return a status code. */ return apr_dbm_set_error_sdbm(dbm, APR_SUCCESS); } APU_DECLARE(void) apr_dbm_get_usednames_sdbm( apr_pool_t *p, const char *pathname, const char **used1, const char **used2) { char *work; *used1 = apr_pstrcat(p, pathname, APR_SDBM_DIRFEXT, NULL); *used2 = work = apr_pstrdup(p, *used1); /* we know the extension is 4 characters */ memcpy(&work[strlen(work) - 4], APR_SDBM_PAGFEXT, 4); } static void apr_dbm_freedatum_noop(apr_dbm_t *dbm, apr_datum_t data) { } static apr_status_t apr_dbm_datum_cleanup_noop(void*x) { return APR_SUCCESS; } static char * apr_dbm_geterror_sdbm(apr_dbm_t *dbm, int *errcode, char *errbuf, apr_size_t errbufsize) { if (errcode != NULL) *errcode = dbm->errcode; /* assert: errbufsize > 0 */ if (dbm->errmsg == NULL) *errbuf = '\0'; else (void) apr_cpystrn(errbuf, dbm->errmsg, errbufsize); return errbuf; } APU_DECLARE(apr_status_t) apr_dbm_open_sdbm(apr_dbm_t **pdb, const char *pathname, apr_int32_t mode, apr_fileperms_t perm, apr_pool_t *pool) { apr_sdbm_t *file; apr_status_t rv; int dbmode; *pdb = NULL; switch (mode) { case APR_DBM_READONLY: dbmode = APR_DBM_DBMODE_RO; break; case APR_DBM_READWRITE: dbmode = APR_DBM_DBMODE_RW; break; case APR_DBM_RWCREATE: dbmode = APR_DBM_DBMODE_RWCREATE; break; default: return APR_EINVAL; } rv = apr_sdbm_open(&file, pathname, dbmode, perm, pool); if (rv != APR_SUCCESS) return rv; *pdb = apr_pcalloc(pool, sizeof(**pdb)); (*pdb)->pool = pool; (*pdb)->file = file; (*pdb)->close = apr_dbm_close_sdbm; (*pdb)->set_error = apr_dbm_set_error_sdbm; (*pdb)->fetch = apr_dbm_fetch_sdbm; (*pdb)->store = apr_dbm_store_sdbm; (*pdb)->del = apr_dbm_delete_sdbm; (*pdb)->exists = apr_dbm_exists_sdbm; (*pdb)->firstkey =apr_dbm_firstkey_sdbm; (*pdb)->nextkey =apr_dbm_nextkey_sdbm; (*pdb)->geterror =apr_dbm_geterror_sdbm; (*pdb)->freedatum =apr_dbm_freedatum_noop; (*pdb)->datum_cleanup=apr_dbm_datum_cleanup_noop; /* we have an open database... return it */ return APR_SUCCESS; } #endif /* APU_USE_SDBM */
#ifndef _DBM_PRIVATE_H #define _DBM_PRIVATE_H 1 /* this is used in a few places to define a noop "function". it is needed to stop "no effect" warnings from GCC. */ #define NOOP_FUNCTION if (0) ; else /* Most DBM libraries take a POSIX mode for creating files. Don't trust * the mode_t type, some platforms may not support it, int is safe. */ APU_DECLARE(int) apr_posix_perms2mode(apr_fileperms_t perm); struct apr_dbm_t { apr_pool_t *pool; /** XXX: pointer to DB Implementation Specific data */ void* file; int errcode; const char *errmsg; apr_status_t (*set_error) (apr_dbm_t*dbm, apr_status_t dbm_said); void (*close) (apr_dbm_t*dbm); apr_status_t (*fetch) (apr_dbm_t *dbm, apr_datum_t key,apr_datum_t *pvalue); apr_status_t (*store) (apr_dbm_t *dbm, apr_datum_t key, apr_datum_t value); apr_status_t (*del) (apr_dbm_t *dbm, apr_datum_t key); int (*exists) (apr_dbm_t *dbm, apr_datum_t key); apr_status_t (*firstkey) (apr_dbm_t *dbm, apr_datum_t *pkey); apr_status_t (*nextkey) (apr_dbm_t *dbm, apr_datum_t *pkey); char* (*geterror) (apr_dbm_t *dbm, int *errcode, char *errbuf, apr_size_t errbufsize); /** if a DBM needs to call something free data */ apr_status_t (*datum_cleanup) (void*); void (*freedatum) (apr_dbm_t *dbm, apr_datum_t data); }; #endif /* _DBM_PRIVATE_H */
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ #ifndef APR_DBM_H #define APR_DBM_H #include "apu.h" #include "apr.h" #include "apr_errno.h" #include "apr_pools.h" #include "apr_file_info.h" #ifdef __cplusplus extern "C" { #endif /** * @package APR-UTIL DBM library */ /** * Structure for referencing a dbm * @defvar apr_dbm_t */ typedef struct apr_dbm_t apr_dbm_t; /** * Structure for referencing the datum record within a dbm * @defvar apr_datum_t */ typedef struct { char *dptr; apr_size_t dsize; } apr_datum_t; /* modes to open the DB */ #define APR_DBM_READONLY 1 /* open for read-only access */ #define APR_DBM_READWRITE 2 /* open for read-write access */ #define APR_DBM_RWCREATE 3 /* open for r/w, create if needed */ /** * Open a dbm file by file name * @param dbm The newly opened database * @param name The dbm file name to open * @param mode The flag value * <PRE> * APR_DBM_READONLY open for read-only access * APR_DBM_READWRITE open for read-write access * APR_DBM_RWCREATE open for r/w, create if needed * </PRE> * @param perm Permissions to apply to if created * @param cntxt The pool to use when creating the dbm * @deffunc apr_status_t apr_dbm_open(apr_dbm_t **dbm, const char *name, int mode * @tip The dbm name may not be a true file name, as many dbm packages * append suffixes for seperate data and index files. */ APU_DECLARE(apr_status_t) apr_dbm_open(apr_dbm_t **dbm, const char *name, apr_int32_t mode, apr_fileperms_t perm, apr_pool_t *cntxt); /** * Close a dbm file previously opened by apr_dbm_open * @param dbm The database to close * @deffunc void apr_dbm_close(apr_dbm_t *dbm) */ APU_DECLARE(void) apr_dbm_close(apr_dbm_t *dbm); /** * Fetch a dbm record value by key * @param dbm The database * @param key The key datum to find this record * @param value The value datum retrieved for this record * @deffunc apr_status_t apr_dbm_fetch(apr_dbm_t *dbm, apr_datum_t key */ APU_DECLARE(apr_status_t) apr_dbm_fetch(apr_dbm_t *dbm, apr_datum_t key, apr_datum_t *pvalue); /** * Store a dbm record value by key * @param dbm The database * @param key The key datum to store this record by * @param value The value datum to store in this record * @deffunc apr_status_t apr_dbm_store(apr_dbm_t *dbm, apr_datum_t key, apr_datum_t value) */ APU_DECLARE(apr_status_t) apr_dbm_store(apr_dbm_t *dbm, apr_datum_t key, apr_datum_t value); /** * Delete a dbm record value by key * @param dbm The database * @param key The key datum of the record to delete * @deffunc apr_status_t apr_dbm_delete(apr_dbm_t *dbm, apr_datum_t key) * @tip It is not an error to delete a non-existent record. */ APU_DECLARE(apr_status_t) apr_dbm_delete(apr_dbm_t *dbm, apr_datum_t key); /** * Search for a key within the dbm * @param dbm The database * @param key The datum describing a key to test * @deffunc int apr_dbm_exists(apr_dbm_t *dbm, apr_datum_t key) */ APU_DECLARE(int) apr_dbm_exists(apr_dbm_t *dbm, apr_datum_t key); /** * Retrieve the first record key from a dbm * @param dbm The database * @param key The key datum of the first record * @deffunc apr_status_t apr_dbm_firstkey(apr_dbm_t *dbm, apr_datum_t *pkey) */ APU_DECLARE(apr_status_t) apr_dbm_firstkey(apr_dbm_t *dbm, apr_datum_t *pkey); /** * Retrieve the next record key from a dbm * @param dbm The database * @param key The key datum of the next record * @deffunc apr_status_t apr_dbm_nextkey(apr_dbm_t *dbm, apr_datum_t *pkey) */ APU_DECLARE(apr_status_t) apr_dbm_nextkey(apr_dbm_t *dbm, apr_datum_t *pkey); /** * Proactively toss any memory associated with the apr_datum_t. * @param dbm The database * @param data The datum to free. * @deffunc void apr_dbm_freedatum(apr_dbm_t *dbm, apr_datum_t data) */ APU_DECLARE(void) apr_dbm_freedatum(apr_dbm_t *dbm, apr_datum_t data); /** * Report more information when an apr_dbm function fails. * @param dbm The database * @param errcode A DBM-specific value for the error (for logging). If this * isn't needed, it may be NULL. * @param errbuf Location to store the error text * @param errbufsize The size of the provided buffer * @return The errbuf parameter, for convenience. * @deffunc const char * apr_dbm_geterror(apr_dbm_t *dbm, int *errcode, char *errbuf, apr_size_t errbufsize) */ APU_DECLARE(char *) apr_dbm_geterror(apr_dbm_t *dbm, int *errcode, char *errbuf, apr_size_t errbufsize); /** * If the specified file/path were passed to apr_dbm_open(), return the * actual file/path names which would be (created and) used. At most, two * files may be used; used2 may be NULL if only one file is used. * @param pool The pool for allocating used1 and used2. * @param pathname The path name to generate used-names from. * @param used1 The first pathname used by the apr_dbm implementation. * @param used2 The second pathname used by apr_dbm. If only one file is * used by the specific implementation, this will be set to NULL. */ APU_DECLARE(void) apr_dbm_get_usednames(apr_pool_t *pool, const char *pathname, const char **used1, const char **used2); #ifdef __cplusplus } #endif #endif /* !APR_DBM_H */
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ #ifndef APR_DBM_SDBM_H #define APR_DBM_SDBM_H 1 #include "apr.h" #include "apr_dbm.h" #ifdef __cplusplus extern "C" { #endif /** * Open a SDBM file by file name * @param dbm The newly opened database * @param name The dbm file name to open * @param mode The flag value * <PRE> * APR_DBM_READONLY open for read-only access * APR_DBM_READWRITE open for read-write access * APR_DBM_RWCREATE open for r/w, create if needed * </PRE> * @param perm Permissions to apply to if created * @param cntxt The pool to use when creating the dbm * @deffunc apr_status_t apr_dbm_open(apr_dbm_t **dbm, const char *name, int mode * @tip The dbm name may not be a true file name, as many dbm packages * append suffixes for seperate data and index files. */ APU_DECLARE(apr_status_t) apr_dbm_open_sdbm(apr_dbm_t **dbm, const char *name, apr_int32_t mode, apr_fileperms_t perm, apr_pool_t *cntxt); /** * If the specified file/path were passed to apr_dbm_open_sdbm(), return the * actual file/path names which would be (created and) used. At most, two * files may be used; used2 may be NULL if only one file is used. * @param pool The pool for allocating used1 and used2. * @param pathname The path name to generate used-names from. * @param used1 The first pathname used by the apr_dbm implementation. * @param used2 The second pathname used by apr_dbm. If only one file is * used by the specific implementation, this will be set to NULL. */ APU_DECLARE(void) apr_dbm_get_usednames_sdbm( apr_pool_t *p, const char *pathname, const char **used1, const char **used2); #ifdef __cplusplus } #endif #endif /* APR_DBM_SDBM_H */
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ #ifndef APR_DBM_SDBM_H #define APR_DBM_SDBM_H 1 #include "apr.h" #include "apr_dbm.h" #ifdef __cplusplus extern "C" { #endif /** * Open a Berkley DB file by file name * @param dbm The newly opened database * @param name The dbm file name to open * @param mode The flag value * <PRE> * APR_DBM_READONLY open for read-only access * APR_DBM_READWRITE open for read-write access * APR_DBM_RWCREATE open for r/w, create if needed * </PRE> * @param perm Permissions to apply to if created * @param cntxt The pool to use when creating the dbm * @deffunc apr_status_t apr_dbm_open(apr_dbm_t **dbm, const char *name, int mode * @tip The dbm name may not be a true file name, as many dbm packages * append suffixes for seperate data and index files. */ APU_DECLARE(apr_status_t) apr_dbm_open_db(apr_dbm_t **dbm, const char *name, apr_int32_t mode, apr_fileperms_t perm, apr_pool_t *cntxt); /** * If the specified file/path were passed to apr_dbm_open_db(), return the * actual file/path names which would be (created and) used. At most, two * files may be used; used2 may be NULL if only one file is used. * @param pool The pool for allocating used1 and used2. * @param pathname The path name to generate used-names from. * @param used1 The first pathname used by the apr_dbm implementation. * @param used2 The second pathname used by apr_dbm. If only one file is * used by the specific implementation, this will be set to NULL. */ APU_DECLARE(void) apr_dbm_get_usednames_db( apr_pool_t *p, const char *pathname, const char **used1, const char **used2); #ifdef __cplusplus } #endif #endif /* APR_DBM_SDBM_H */
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * * This file came from the SDBM package (written by [EMAIL PROTECTED]). * That package was under public domain. This file has been ported to * APR, updated to ANSI C and other, newer idioms, and added to the Apache * codebase under the above copyright and license. */ #include "apr.h" #include "apr_general.h" #include "apr_pools.h" #include "apr_errno.h" #include "apr_getopt.h" #include "apr_time.h" #if APR_HAVE_STDIO_H #include <stdio.h> #endif #if APR_HAVE_UNISTD_H #include <unistd.h> #endif #include <stdlib.h> /* for atexit(), malloc() */ #include <string.h> #include "apr_dbm.h" #include "apr_dbm_sdbm.h" static const char *progname; static int rflag; static const char *usage = "%s [-R] cat | look |... dbmname"; #define DERROR 0 #define DLOOK 1 #define DDELETE 3 #define DCAT 4 #define DBUILD 5 #define DPRESS 6 #define DCREAT 7 #define DNAME 8 #define LINEMAX 8192 typedef struct { const char *sname; int scode; int flags; } cmd; static const cmd cmds[] = { { "fetch", DLOOK, APR_DBM_READONLY, }, { "get", DLOOK, APR_DBM_READONLY, }, { "look", DLOOK, APR_DBM_READONLY, }, { "add", DBUILD, APR_DBM_READWRITE, }, { "insert", DBUILD, APR_DBM_READWRITE, }, { "store", DBUILD, APR_DBM_READWRITE, }, { "build", DBUILD, APR_DBM_RWCREATE, }, /** this one creates the DB */ { "delete", DDELETE, APR_DBM_READWRITE, }, { "remove", DDELETE, APR_DBM_READWRITE, }, { "dump", DCAT, APR_DBM_READONLY, }, { "list", DCAT, APR_DBM_READONLY, }, { "cat", DCAT, APR_DBM_READONLY, }, { "creat", DCREAT, APR_DBM_RWCREATE , }, { "new", DCREAT, APR_DBM_RWCREATE , }, { "names", DNAME, APR_DBM_READONLY, }, #if 0 { "squash", DPRESS, APR_DBM_READWRITE, }, { "compact", DPRESS, APR_DBM_READWRITE, }, { "compress", DPRESS, APR_DBM_READWRITE, }, #endif }; #define CTABSIZ (sizeof (cmds)/sizeof (cmd)) static void doit(const cmd *act, const char *file, apr_pool_t *pool); static void badk(const char *word); static const cmd *parse(const char *str); static void prdatum(FILE *stream, apr_datum_t d); static void oops(apr_dbm_t *dbm,apr_status_t rv, const char *s1, const char *s2); int main(int argc, const char * const * argv) { apr_pool_t *pool; const cmd *act; apr_getopt_t *os; char optch; const char *optarg; (void) apr_initialize(); apr_pool_create(&pool, NULL); atexit(apr_terminate); (void) apr_getopt_init(&os, pool, argc, argv); progname = argv[0]; while (apr_getopt(os, "R", &optch, &optarg) == APR_SUCCESS) switch (optch) { case 'R': /* raw processing */ rflag++; break; default: oops(NULL,APR_EGENERAL,"(unknown option) usage: %s", usage); break; } if (os->ind + 2 > argc) oops(NULL,APR_EGENERAL,"usage: %s", usage); if ((act = parse(argv[os->ind])) == NULL) badk(argv[os->ind]); os->ind++; doit(act, argv[os->ind], pool); apr_pool_destroy(pool); return 0; } static void doit(const cmd *act, const char *file, apr_pool_t *pool) { apr_status_t rv; apr_datum_t key; apr_datum_t val; apr_dbm_t *db; char *op; int n; char *line; char*use1; char*use2; #ifdef TIME long start; extern long time(); #endif rv =apr_dbm_open(&db, file, act->flags, APR_OS_DEFAULT, pool); if (rv != APR_SUCCESS) oops(db,rv,"cannot open: %s", file); line = (char *) apr_palloc(pool,LINEMAX); if ( line == NULL) { oops(NULL,APR_EGENERAL,"%s: cannot get memory", "line alloc"); } switch (act->scode) { case DLOOK: while (fgets(line, LINEMAX, stdin) != NULL) { n = strlen(line) - 1; line[n] = 0; if (n==0) break; key.dptr = line; key.dsize = n; rv = apr_dbm_fetch(db, key, &val); if (rv == APR_SUCCESS) { prdatum(stdout, val); putchar('\n'); continue; } prdatum(stderr, key); fprintf(stderr, ": not found.\n"); } break; case DDELETE: while (fgets(line, LINEMAX, stdin) != NULL) { n = strlen(line) - 1; line[n] = 0; if (n==0) break; key.dptr = line; key.dsize = n; if (apr_dbm_delete(db, key) != APR_SUCCESS) { prdatum(stderr, key); fprintf(stderr, ": not found.\n"); } } break; case DCAT: rv =apr_dbm_firstkey(db, &key); if ( rv != APR_SUCCESS) oops(db,rv,"could not fetch first key: %s", file); while ( key.dptr != NULL ) { prdatum(stdout, key); putchar('\t'); rv = apr_dbm_fetch(db, key, &val); if (rv != APR_SUCCESS) oops(db,rv,"apr_dbm_fetch","failure"); prdatum(stdout, val); putchar('\n'); rv = apr_dbm_nextkey( db,&key); if (rv != APR_SUCCESS) oops(db,rv,"NextKey","failure"); } break; case DBUILD: #ifdef TIME start = time(0); #endif while (fgets(line, LINEMAX, stdin) != NULL) { n = strlen(line) - 1; line[n] = 0; if (n==0) break; key.dptr = line; if ((op = strchr(line, '\t')) != 0) { key.dsize = op - line; *op++ = 0; val.dptr = op; val.dsize = line + n - op; } else { oops(NULL,APR_EGENERAL,"bad input: %s", line); } rv = apr_dbm_store(db, key, val); if ( rv != APR_SUCCESS) { prdatum(stderr, key); fprintf(stderr, ": "); oops(db,rv,"store: %s", "failed"); } } #ifdef TIME printf("done: %d seconds.\n", time(0) - start); #endif break; case DPRESS: break; case DCREAT: break; case DNAME: apr_dbm_get_usednames(pool,file,&use1,&use2); fprintf( stderr,"%s %s %s",file,use1,use2); break; } apr_dbm_close(db); } static void badk(const char *word) { int i; if (progname) fprintf(stderr, "%s: ", progname); fprintf(stderr, "bad keywd %s. use one of\n", word); for (i = 0; i < (int)CTABSIZ; i++) fprintf(stderr, "%-8s%c", cmds[i].sname, ((i + 1) % 6 == 0) ? '\n' : ' '); fprintf(stderr, "\n"); exit(1); /*NOTREACHED*/ } static const cmd *parse(const char *str) { int i = CTABSIZ; const cmd *p; for (p = cmds; i--; p++) if (strcmp(p->sname, str) == 0) return p; return NULL; } static void prdatum(FILE *stream, apr_datum_t d) { int c; const char *p = d.dptr; int n = d.dsize; while (n--) { c = *p++ & 0377; if (c & 0200) { fprintf(stream, "M-"); c &= 0177; } if (c == 0177 || c < ' ') fprintf(stream, "^%c", (c == 0177) ? '?' : c + '@'); else putc(c, stream); } } static void oops(apr_dbm_t *dbm, apr_status_t rv, const char *s1, const char *s2) { char errbuf[200]; if (progname) fprintf(stderr, "%s: ", progname); fprintf(stderr, s1, s2); if (errno > 0 && errno < sys_nerr) fprintf(stderr, " (%s)", sys_errlist[errno]); fprintf(stderr, "\n"); if (rv != APR_SUCCESS) { apr_strerror(rv,errbuf,sizeof(errbuf)); fprintf(stderr,"APR Error %d - %s\n",rv,errbuf); if (dbm) { apr_dbm_geterror(dbm,&rv,errbuf,sizeof(errbuf)); fprintf(stderr,"APR_DB Error %d - %s\n",rv, errbuf); } } exit(1); }