Return-Path: Delivered-To: apmail-apr-dev-archive@apr.apache.org Received: (qmail 37003 invoked by uid 500); 20 Aug 2001 17:28:07 -0000 Mailing-List: contact dev-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Delivered-To: mailing list dev@apr.apache.org Received: (qmail 36979 invoked from network); 20 Aug 2001 17:28:07 -0000 Message-ID: <3B8148C8.6020707@cnet.com> Date: Mon, 20 Aug 2001 10:28:40 -0700 From: Ian Holsman User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:0.9.3+) Gecko/20010817 X-Accept-Language: en-us MIME-Version: 1.0 To: Justin Erenkrantz CC: dev@apr.apache.org Subject: Re: [proposal] DBM - allow multiple DBM's of differnt types at the same time. References: <3B813B77.6030204@cnet.com> <20010820095412.J1397@ebuilt.com> Content-Type: multipart/mixed; boundary="------------080705000900050100060605" X-Spam-Rating: h31.sny.collab.net 1.6.2 0/1000/N This is a multi-part message in MIME format. --------------080705000900050100060605 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit sorry bout that. MSVC does it's own thing with spacing ;( (ok.. I've run the code through indent so that should help.) Justin Erenkrantz wrote: >On Mon, Aug 20, 2001 at 09:31:51AM -0700, Ian Holsman wrote: > >>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); >>} >> > >Watch the style. This should be: > >return dbm->fetch(dbm, key, pvalue); > >No spaces before the ( and spaces in between parameter names. > >I think you misnamed the Berkeley DB file/structure. You called it >berkley. =-) I can never spell it right either - I had to go to >their website (which of course requires spelling berkeley right - a >catch-22 - thanks goodness for Google...). > >>static void apr_dbm_close_db(apr_dbm_t *dbm) >>{ >> //APR_DBM_CLOSE(dbm.file); >> > >// is invalid in C. Use /* */. > >>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; >> > >Seems like there are tabs and spaces in this fragment. We should only >have 4 space indention (no tab chars). > >HTH. Please repost once the style is cleaned-up and then I'll look at >it again. My brain doesn't parse code that isn't in the correct >style. Sorry. > >It generally looks good, but I'll take a deeper look once the style >issues are addressed. -- justin > --------------080705000900050100060605 Content-Type: text/plain; name="testdbm.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="testdbm.c" /* ==================================================================== * 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 apache@apache.org. * * 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 * . * * This file came from the SDBM package (written by oz@nexus.yorku.ca). * 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 #endif #if APR_HAVE_UNISTD_H #include #endif #include /* for atexit(), malloc() */ #include #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); } --------------080705000900050100060605 Content-Type: text/plain; name="apr_dbm_sdbm.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="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 apache@apache.org. * * 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 * . */ #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 *
 *           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
 * 
* @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 */ --------------080705000900050100060605 Content-Type: text/plain; name="apr_dbm_db.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="apr_dbm_db.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 apache@apache.org. * * 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 * . */ #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 *
 *           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
 * 
* @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 */ --------------080705000900050100060605 Content-Type: text/plain; name="apr_dbm.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="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 apache@apache.org. * * 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 * . */ #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 *
 *           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
 * 
* @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 */ --------------080705000900050100060605 Content-Type: text/plain; name="apr_dbm_berkeleydb.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="apr_dbm_berkeleydb.c" /* ==================================================================== * 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 apache@apache.org. * * 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 * . */ #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 #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_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); 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; #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; 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) { } 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 */ --------------080705000900050100060605 Content-Type: text/plain; name="apr_dbm_sdbm.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="apr_dbm_sdbm.c" /* ==================================================================== * 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 apache@apache.org. * * 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 * . */ #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" #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); *(pvalue) = *(apr_datum_t *) & rd; /* 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; ckey = (apr_sdbm_datum_t *) & key; cvalue = (apr_sdbm_datum_t *) & 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; 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; 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); *pkey = *(apr_datum_t *) & rd; /* 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; /* 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 */ --------------080705000900050100060605 Content-Type: text/plain; name="apr_dbm.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="apr_dbm.c" /* ==================================================================== * 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 apache@apache.org. * * 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 * . */ #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 } --------------080705000900050100060605 Content-Type: text/plain; name="dbm_private.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dbm_private.h" #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. */ /* 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; /** 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 */ --------------080705000900050100060605--