forked from Mirrors/freeswitch
3b35430557
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3734 d0543943-73ff-0310-b7d9-9358b9ac24b2
426 lines
11 KiB
C
426 lines
11 KiB
C
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
|
|
* applicable.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
/* 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.
|
|
*/
|
|
|
|
/*
|
|
* testdbm: Simple APR dbm tester.
|
|
* Automatic test case: ./testdbm auto foo
|
|
* - Attempts to store and fetch values from the DBM.
|
|
*
|
|
* Run the program for more help.
|
|
*/
|
|
|
|
#include "apr.h"
|
|
#include "apr_general.h"
|
|
#include "apr_pools.h"
|
|
#include "apr_errno.h"
|
|
#include "apr_getopt.h"
|
|
#include "apr_time.h"
|
|
#define APR_WANT_STRFUNC
|
|
#include "apr_want.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"
|
|
|
|
static const char *progname;
|
|
static int rflag;
|
|
|
|
#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 DTRUNC 9
|
|
#define DAUTO 10
|
|
|
|
#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 },
|
|
{ "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 },
|
|
{ "build", DBUILD, APR_DBM_RWCREATE }, /** this one creates the DB */
|
|
{ "creat", DCREAT, APR_DBM_RWCREATE },
|
|
{ "trunc", DTRUNC, APR_DBM_RWTRUNC },
|
|
{ "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
|
|
{ "auto", DAUTO, APR_DBM_RWCREATE },
|
|
};
|
|
|
|
#define CMD_SIZE (sizeof(cmds)/sizeof(cmd))
|
|
|
|
static void doit(const cmd *act, const char*type, const char *file, apr_pool_t *pool);
|
|
static const cmd *parse_command(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);
|
|
static void show_usage(void);
|
|
|
|
int main(int argc, const char * const * argv)
|
|
{
|
|
apr_pool_t *pool;
|
|
const cmd *act;
|
|
apr_getopt_t *os;
|
|
char optch;
|
|
const char *optarg;
|
|
const char*dbtype;
|
|
|
|
(void) apr_initialize();
|
|
apr_pool_create(&pool, NULL);
|
|
atexit(apr_terminate);
|
|
|
|
(void) apr_getopt_init(&os, pool, argc, argv);
|
|
|
|
progname = argv[0];
|
|
dbtype = "default";
|
|
|
|
while (apr_getopt(os, "Rt:", &optch, &optarg) == APR_SUCCESS) {
|
|
switch (optch) {
|
|
case 'R': /* raw processing */
|
|
rflag++;
|
|
break;
|
|
case 't':
|
|
dbtype = optarg;
|
|
break;
|
|
default:
|
|
show_usage();
|
|
fputs("unknown option.",stderr);
|
|
exit(-1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (argc <= os->ind) {
|
|
show_usage();
|
|
fputs("Note: If you have no clue what this program is, start with:\n", stderr);
|
|
fputs(" ./testdbm auto foo\n", stderr);
|
|
fputs(" where foo is the DBM prefix.\n", stderr);
|
|
exit(-2);
|
|
}
|
|
|
|
if ((act = parse_command(argv[os->ind])) == NULL) {
|
|
show_usage();
|
|
fprintf(stderr, "unrecognized command: %s\n", argv[os->ind]);
|
|
exit(-3);
|
|
}
|
|
|
|
if (++os->ind >= argc) {
|
|
show_usage();
|
|
fputs("please supply a DB file to use (may be created)\n", stderr);
|
|
exit(-4);
|
|
}
|
|
|
|
doit(act, dbtype, argv[os->ind], pool);
|
|
|
|
apr_pool_destroy(pool);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void doit(const cmd *act, const char*type, 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;
|
|
const char *use1;
|
|
const char *use2;
|
|
#ifdef TIME
|
|
long start;
|
|
extern long time();
|
|
#endif
|
|
|
|
rv = apr_dbm_open_ex(&db, type, file, act->flags, APR_OS_DEFAULT, pool);
|
|
if (rv != APR_SUCCESS)
|
|
oops(db, rv, "cannot open: %s", file);
|
|
|
|
line = (char *) apr_palloc(pool,LINEMAX);
|
|
|
|
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 DTRUNC:
|
|
break;
|
|
case DNAME:
|
|
apr_dbm_get_usednames(pool, file, &use1, &use2);
|
|
fprintf(stderr, "%s %s\n", use1, use2);
|
|
break;
|
|
case DAUTO:
|
|
{
|
|
int i;
|
|
char *valdata = "0123456789";
|
|
fprintf(stderr, "Generating data: ");
|
|
for (i = 0; i < 10; i++) {
|
|
int j;
|
|
char c, keydata[10];
|
|
for (j = 0, c = 'A' + (i % 16); j < 10; j++, c++) {
|
|
keydata[j] = c;
|
|
}
|
|
key.dptr = keydata;
|
|
key.dsize = 10;
|
|
val.dptr = valdata;
|
|
val.dsize = 10;
|
|
rv = apr_dbm_store(db, key, val);
|
|
if (rv != APR_SUCCESS) {
|
|
prdatum(stderr, key);
|
|
fprintf(stderr, ": ");
|
|
oops(db, rv, "store: %s", "failed");
|
|
}
|
|
}
|
|
fputs("OK\n", stderr);
|
|
fputs("Testing existence/retrieval: ", stderr);
|
|
for (i = 0; i < 10; i++) {
|
|
int j;
|
|
char c, keydata[10];
|
|
for (j = 0, c = 'A' + (i % 16); j < 10; j++, c++) {
|
|
keydata[j] = c;
|
|
}
|
|
key.dptr = keydata;
|
|
key.dsize = 10;
|
|
if (!apr_dbm_exists(db, key)) {
|
|
prdatum(stderr, key);
|
|
oops(db, 0, "exists: %s", "failed");
|
|
}
|
|
rv = apr_dbm_fetch(db, key, &val);
|
|
if (rv != APR_SUCCESS || val.dsize != 10 ||
|
|
(strncmp(val.dptr, valdata, 10) != 0) ) {
|
|
prdatum(stderr, key);
|
|
fprintf(stderr, ": ");
|
|
oops(db, rv, "fetch: %s", "failed");
|
|
}
|
|
}
|
|
fputs("OK\n", stderr);
|
|
}
|
|
break;
|
|
}
|
|
|
|
apr_dbm_close(db);
|
|
}
|
|
|
|
static const cmd *parse_command(const char *str)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < CMD_SIZE; i++)
|
|
if (strcasecmp(cmds[i].sname, str) == 0)
|
|
return &cmds[i];
|
|
|
|
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);
|
|
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);
|
|
}
|
|
|
|
static void show_usage(void)
|
|
{
|
|
int i;
|
|
|
|
if (!progname) {
|
|
progname = "testdbm";
|
|
}
|
|
|
|
fprintf(stderr, "%s [-t DBM-type] [-R] [commands] dbm-file-path\n",
|
|
progname);
|
|
|
|
fputs("Available DBM-types:", stderr);
|
|
#if APU_HAVE_GDBM
|
|
fputs(" GDBM", stderr);
|
|
#endif
|
|
#if APU_HAVE_NDBM
|
|
fputs(" NDBM", stderr);
|
|
#endif
|
|
#if APU_HAVE_SDBM
|
|
fputs(" SDBM", stderr);
|
|
#endif
|
|
#if APU_HAVE_DB
|
|
fputs(" DB", stderr);
|
|
#endif
|
|
fputs(" default\n", stderr);
|
|
|
|
fputs("Available commands:\n", stderr);
|
|
for (i = 0; i < CMD_SIZE; i++) {
|
|
fprintf(stderr, "%-8s%c", cmds[i].sname,
|
|
((i + 1) % 6 == 0) ? '\n' : ' ');
|
|
}
|
|
fputs("\n", stderr);
|
|
}
|