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
/* ====================================================================
* 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);
}
/* ====================================================================
* 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/>.
*/
#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/>.
*/
#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_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 */
/* ====================================================================
* 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"
#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 */
/* ====================================================================
* 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
}
#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 */