зеркало из https://github.com/mozilla/gecko-dev.git
1785 строки
44 KiB
C
1785 строки
44 KiB
C
/*-
|
|
* See the file LICENSE for redistribution information.
|
|
*
|
|
* Copyright (c) 1996, 1997, 1998
|
|
* Sleepycat Software. All rights reserved.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#ifndef lint
|
|
static const char sccsid[] = "@(#)utils.c 10.46 (Sleepycat) 5/31/98";
|
|
#endif /* not lint */
|
|
|
|
/*
|
|
* This file is divided up into 4 sets of functions:
|
|
* 1. The dbopen command and its support functions.
|
|
* 2. The dbwidget and dbcursor commands.
|
|
* 3. The db support functions (e.g. get, put, del)
|
|
* 4. The cursor support functions (e.g. get put, del)
|
|
*/
|
|
|
|
#ifndef NO_SYSTEM_INCLUDES
|
|
#include <sys/types.h>
|
|
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <tcl.h>
|
|
|
|
#include "db_int.h"
|
|
#include "db_page.h"
|
|
#include "hash.h"
|
|
#include "dbtest.h"
|
|
#include "test_ext.h"
|
|
|
|
/* Internal functions */
|
|
int db_del_cmd __P((Tcl_Interp *interp, int argc, char *argv[], DB *dbp));
|
|
int db_get_cmd __P((Tcl_Interp *interp, int argc, char *argv[], DB *dbp));
|
|
int db_getbin_cmd __P((Tcl_Interp *interp, int argc, char *argv[], DB *dbp));
|
|
int db_put_cmd __P((Tcl_Interp *interp, int argc, char *argv[], DB *dbp));
|
|
int db_putbin_cmd __P((Tcl_Interp *interp, int argc, char *argv[], DB *dbp));
|
|
int dbc_del_cmd __P((Tcl_Interp *interp, int argc, char *argv[], DBC *dbc));
|
|
int dbc_get_cmd __P((Tcl_Interp *interp, int argc, char *argv[], DBC *dbc));
|
|
int dbc_getbin_cmd __P((Tcl_Interp *interp, int argc, char *argv[], DBC *dbc));
|
|
int dbc_put_cmd __P((Tcl_Interp *interp, int argc, char *argv[], DBC *dbc));
|
|
int dbt_from_file __P((Tcl_Interp *interp, char *file, DBT *dbt));
|
|
int dbt_to_file __P((Tcl_Interp *interp, char *file, DBT *dbt));
|
|
u_int8_t *list_to_numarray __P((Tcl_Interp *, char *));
|
|
void set_get_result __P((Tcl_Interp *interp, DBT *dbt));
|
|
|
|
/*
|
|
* dbopen_cmd --
|
|
* Implements dbopen for dbtest. Dbopen creates a widget that
|
|
* implements all the commands found off the DB structure.
|
|
*/
|
|
|
|
#define DBOPEN_USAGE "dbopen file flags mode type [options]\n\toptions:\n\t"
|
|
|
|
int
|
|
dbopen_cmd(notused, interp, argc, argv)
|
|
ClientData notused;
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
static int db_number = 0;
|
|
static struct {
|
|
const char *str;
|
|
DBTYPE type;
|
|
} list[] = {
|
|
{"DB_UNKNOWN", DB_UNKNOWN},
|
|
{"db_unknown", DB_UNKNOWN},
|
|
{"UNKNOWN", DB_UNKNOWN},
|
|
{"unknown", DB_UNKNOWN},
|
|
{"DB_BTREE", DB_BTREE},
|
|
{"db_btree", DB_BTREE},
|
|
{"BTREE", DB_BTREE},
|
|
{"btree", DB_BTREE},
|
|
{"DB_HASH", DB_HASH},
|
|
{"db_hash", DB_HASH},
|
|
{"HASH", DB_HASH},
|
|
{"hash", DB_HASH},
|
|
{"DB_RECNO", DB_RECNO},
|
|
{"db_recno", DB_RECNO},
|
|
{"RECNO", DB_RECNO},
|
|
{"recno", DB_RECNO},
|
|
{ 0 }
|
|
}, *lp;
|
|
DB *dbp;
|
|
DBTYPE type;
|
|
DB_ENV *env;
|
|
DB_INFO *openinfo;
|
|
u_int32_t flags;
|
|
int mode, ret, tclint;
|
|
char dbname[50], *name;
|
|
|
|
notused = NULL;
|
|
|
|
/* Check number of arguments. */
|
|
USAGE_GE(argc, 5, DBOPEN_USAGE, DO_INFO);
|
|
|
|
/* Check flags and mode. */
|
|
if (Tcl_GetInt(interp, argv[2], &tclint) != TCL_OK)
|
|
goto usage;
|
|
flags = (u_int32_t)tclint;
|
|
if (Tcl_GetInt(interp, argv[3], &mode) != TCL_OK) {
|
|
usage: Tcl_AppendResult(interp,
|
|
"\nUsage: ", DBOPEN_USAGE, DB_INFO_FLAGS, NULL);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
name = strcmp(argv[1], "NULL") == 0 ? NULL : argv[1];
|
|
|
|
process_am_options(interp, argc - 5, &argv[5], &openinfo);
|
|
process_env_options(interp, argc - 5, &argv[5], &env);
|
|
|
|
/* Figure out type. */
|
|
COMPQUIET(type, DB_HASH);
|
|
for (lp = list; lp->str != NULL; ++lp)
|
|
if (strcmp(argv[4], lp->str) == 0) {
|
|
type = lp->type;
|
|
break;
|
|
}
|
|
if (lp->str == NULL) {
|
|
Tcl_SetResult(interp, "Invalid type", TCL_STATIC);
|
|
return (TCL_ERROR);
|
|
}
|
|
|
|
if (openinfo == NULL && type != DB_UNKNOWN) {
|
|
Tcl_AppendResult(interp, "Usage: ", DBOPEN_USAGE,
|
|
DB_INFO_FLAGS, NULL);
|
|
return (TCL_ERROR);
|
|
}
|
|
|
|
debug_check();
|
|
|
|
/* Call dbopen. */
|
|
ret = db_open(name, type, flags, mode, env, openinfo, &dbp);
|
|
if (openinfo && openinfo->re_source)
|
|
free(openinfo->re_source);
|
|
if (openinfo)
|
|
free(openinfo);
|
|
if (ret != 0) {
|
|
Tcl_SetResult(interp, "dbopen: ", TCL_STATIC);
|
|
errno = ret;
|
|
Tcl_AppendResult(interp, Tcl_PosixError(interp), NULL);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
/* Create widget command. */
|
|
/* Create new command name. */
|
|
sprintf(&dbname[0], "db%d", db_number);
|
|
db_number++;
|
|
|
|
Tcl_CreateCommand(interp, dbname, dbwidget_cmd, (ClientData)dbp, NULL);
|
|
Tcl_SetResult(interp, dbname, TCL_VOLATILE);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
/*
|
|
* process_am_options --
|
|
* Read the options in the command line and create a DB_INFO structure
|
|
* to pass to db_open.
|
|
*/
|
|
int
|
|
process_am_options(interp, argc, argv, openinfo)
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
DB_INFO **openinfo;
|
|
{
|
|
DB_INFO *oi;
|
|
int err, tclint;
|
|
char *option;
|
|
|
|
COMPQUIET(option, NULL);
|
|
|
|
err = TCL_OK;
|
|
oi = (DB_INFO *)calloc(sizeof(DB_INFO), 1);
|
|
|
|
while (argc > 1) {
|
|
if (**argv != '-') { /* Make sure it's an option */
|
|
argc--;
|
|
argv++;
|
|
continue;
|
|
}
|
|
/* Set option to first character after "-" */
|
|
option = argv[0];
|
|
option++;
|
|
|
|
if (strcmp(option, "flags") == 0) {
|
|
/* Contains flags for all access methods */
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
oi->flags = (u_int32_t)tclint;
|
|
} else if (strcmp(option, "psize") == 0) {
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
oi->db_pagesize = (size_t)tclint;
|
|
} else if (strcmp(option, "order") == 0) {
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
oi->db_lorder = (int)tclint;
|
|
} else if (strcmp(option, "cachesize") == 0) {
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
oi->db_cachesize = (size_t)tclint;
|
|
} else if (strcmp(option, "minkey") == 0) {
|
|
/* Btree flags */
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
oi->bt_minkey = (u_int32_t)tclint;
|
|
} else if (strcmp(option, "compare") == 0) {
|
|
/* Not sure how to handle this. */
|
|
err = TCL_ERROR;
|
|
} else if (strcmp(option, "prefix") == 0) {
|
|
/* Not sure how to handle this. */
|
|
err = TCL_ERROR;
|
|
} else if (strcmp(option, "ffactor") == 0) {
|
|
/* Hash flags */
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
oi->h_ffactor = (u_int32_t)tclint;
|
|
} else if (strcmp(option, "nelem") == 0) {
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
oi->h_nelem = (u_int32_t)tclint;
|
|
} else if (strcmp(option, "hash") == 0) {
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
switch (tclint) {
|
|
case 2: oi->h_hash = __ham_func2; break;
|
|
case 3: oi->h_hash = __ham_func3; break;
|
|
case 4: oi->h_hash = __ham_func4; break;
|
|
case 5: oi->h_hash = __ham_func5; break;
|
|
}
|
|
if (oi->h_hash == NULL) {
|
|
err = TCL_ERROR;
|
|
break;
|
|
}
|
|
} else if (strcmp(option, "recdelim") == 0) {
|
|
/* Recno flags */
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
oi->re_delim = (int)tclint;
|
|
} else if (strcmp(option, "recpad") == 0) {
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
oi->re_pad = (int)tclint;
|
|
} else if (strcmp(option, "reclen") == 0) {
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
oi->re_len = (u_int32_t)tclint;
|
|
} else if (strcmp(option, "recsrc") == 0)
|
|
oi->re_source = (char *)strdup(argv[1]);
|
|
|
|
argc -= 2;
|
|
argv += 2;
|
|
}
|
|
if (err != TCL_OK) {
|
|
Tcl_AppendResult(interp,
|
|
"\nInvalid ", option, " value: ", argv[1], "\n", NULL);
|
|
free(oi);
|
|
oi = NULL;
|
|
}
|
|
*openinfo = oi;
|
|
return (oi ? 0 : 1);
|
|
}
|
|
|
|
/*
|
|
* process_env_options --
|
|
* Read the options in the command line and create a DB_ENV structure
|
|
* to pass to db_open.
|
|
*/
|
|
int
|
|
process_env_options(interp, argc, argv, envinfo)
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
DB_ENV **envinfo;
|
|
{
|
|
DB_ENV *env;
|
|
Tcl_CmdInfo info;
|
|
u_int32_t flags;
|
|
int err, nconf, tclint;
|
|
char *option, *db_home, **config;
|
|
|
|
COMPQUIET(option, NULL);
|
|
err = TCL_OK;
|
|
flags = 0;
|
|
db_home = Tcl_GetVar(interp, "testdir", 0);
|
|
config = NULL;
|
|
|
|
env = (DB_ENV *)calloc(sizeof(DB_ENV), 1);
|
|
while (argc > 1) {
|
|
if (**argv != '-') { /* Make sure it's an option */
|
|
argc--;
|
|
argv++;
|
|
continue;
|
|
}
|
|
/* Set option to first character after "-" */
|
|
option = argv[0];
|
|
option++;
|
|
|
|
if (strcmp(option, "dbenv") == 0) {
|
|
/* environment already set up. */
|
|
if (Tcl_GetCommandInfo(interp, argv[1], &info) == 0) {
|
|
Tcl_SetResult(interp,
|
|
"Invalid environment: ", TCL_STATIC);
|
|
Tcl_AppendResult(interp, argv[1], 0);
|
|
return (TCL_ERROR);
|
|
}
|
|
free(env);
|
|
*envinfo = (DB_ENV *)info.clientData;
|
|
return (TCL_OK);
|
|
} else if (strcmp(option, "dbflags") == 0) {
|
|
/* db_appinit parameters */
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
flags = (u_int32_t)tclint;
|
|
/*
|
|
* Don't specify DB_THREAD if the architecture can't
|
|
* do spinlocks.
|
|
*/
|
|
#ifndef HAVE_SPINLOCKS
|
|
LF_CLR(DB_THREAD);
|
|
#endif
|
|
} else if (strcmp(option, "dbhome") == 0) {
|
|
db_home = argv[1];
|
|
} else if (strcmp(option, "dbconfig") == 0) {
|
|
err = Tcl_SplitList(interp, argv[1], &nconf, &config);
|
|
if (err)
|
|
break;
|
|
} else if (strcmp(option, "maxlocks") == 0) {
|
|
/* Lock flags */
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
env->lk_max = (u_int32_t)tclint;
|
|
} else if (strcmp(option, "nmodes") == 0) {
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
env->lk_modes = (u_int32_t)tclint;
|
|
} else if (strcmp(option, "detect") == 0) {
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
env->lk_detect = (u_int32_t)tclint;
|
|
} else if (strcmp(option, "conflicts") == 0) {
|
|
env->lk_conflicts = list_to_numarray(interp, argv[1]);
|
|
if (env->lk_conflicts == NULL)
|
|
break;
|
|
} else if (strcmp(option, "maxsize") == 0) {
|
|
/* Log flags */
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
env->lg_max = (u_int32_t)tclint;
|
|
} else if (strcmp(option, "cachesize") == 0) {
|
|
/* Mpool flags */
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
env->mp_size = (size_t)tclint;
|
|
} else if (strcmp(option, "maxtxns") == 0) {
|
|
/* Txn flags */
|
|
if ((err =
|
|
Tcl_GetInt(interp, argv[1], &tclint)) != TCL_OK)
|
|
break;
|
|
env->tx_max = (u_int32_t)tclint;
|
|
} else if (strcmp(option, "rinit") == 0) {
|
|
/* Region init */
|
|
if ((err = db_value_set(1, DB_REGION_INIT)) != 0) {
|
|
if (err == EINVAL) {
|
|
Tcl_SetResult(interp,
|
|
"EINVAL", TCL_STATIC);
|
|
return (TCL_ERROR);
|
|
}
|
|
Tcl_SetResult(interp,
|
|
"env/rinit:", TCL_STATIC);
|
|
errno = err;
|
|
Tcl_AppendResult(interp,
|
|
Tcl_PosixError(interp), 0);
|
|
return (TCL_ERROR);
|
|
}
|
|
} else if (strcmp(option, "shmem") == 0) {
|
|
/* Shared memory specification */
|
|
if (strcmp(argv[1], "anon") == 0) {
|
|
if ((err =
|
|
db_value_set(1, DB_REGION_ANON)) != 0) {
|
|
if (err == EINVAL) {
|
|
Tcl_SetResult(interp,
|
|
"EINVAL", TCL_STATIC);
|
|
return (TCL_ERROR);
|
|
}
|
|
Tcl_SetResult(interp,
|
|
"env/shmem:", TCL_STATIC);
|
|
errno = err;
|
|
Tcl_AppendResult(interp,
|
|
Tcl_PosixError(interp), 0);
|
|
return (TCL_ERROR);
|
|
}
|
|
} else if (strcmp(argv[1], "named") == 0) {
|
|
if ((err =
|
|
db_value_set(1, DB_REGION_NAME)) != 0) {
|
|
if (err == EINVAL) {
|
|
Tcl_SetResult(interp,
|
|
"EINVAL", TCL_STATIC);
|
|
return (TCL_ERROR);
|
|
}
|
|
Tcl_SetResult(interp,
|
|
"env/shmem:", TCL_STATIC);
|
|
errno = err;
|
|
Tcl_AppendResult(interp,
|
|
Tcl_PosixError(interp), 0);
|
|
return (TCL_ERROR);
|
|
}
|
|
} else {
|
|
Tcl_SetResult(interp,
|
|
"Invalid shmem option", TCL_STATIC);
|
|
Tcl_AppendResult(interp, argv[1], NULL);
|
|
return (TCL_OK);
|
|
}
|
|
}
|
|
|
|
argc -= 2;
|
|
argv += 2;
|
|
}
|
|
if (err != TCL_OK) {
|
|
Tcl_AppendResult(interp, "\nInvalid ", option, " value: ",
|
|
argv[1], "\n", NULL);
|
|
if (env->lk_conflicts)
|
|
free(env->lk_conflicts);
|
|
free(env);
|
|
env = NULL;
|
|
}
|
|
|
|
/*
|
|
* Set up error stuff.
|
|
*/
|
|
|
|
if (env) {
|
|
env->db_errfile = stderr;
|
|
env->db_errpfx = "dbtest";
|
|
env->db_errcall = NULL;
|
|
env->db_verbose = 0;
|
|
|
|
if ((errno = db_appinit(db_home, config, env, flags)) != 0) {
|
|
if (config)
|
|
free(config);
|
|
if (env->lk_conflicts)
|
|
free(env->lk_conflicts);
|
|
free(env);
|
|
env = NULL;
|
|
}
|
|
}
|
|
|
|
*envinfo = env;
|
|
return (env ? 0 : 1);
|
|
}
|
|
|
|
/*
|
|
* dbwidget --
|
|
* Since dbopen creates a widget, we need a command that then
|
|
* handles all the widget commands. This is that command. If we
|
|
* ever add new "methods" we add new widget commands here.
|
|
*/
|
|
#define DBWIDGET_USAGE "dbN option ?arg arg ...?"
|
|
#define DBCLOSE_USAGE "dbN close"
|
|
#define DBCURS_USAGE "dbN cursor txn"
|
|
#define DBFD_USAGE "dbN fd"
|
|
#define DBSYNC_USAGE "dbN sync flags"
|
|
#define DBLOCKER_USAGE "dbN locker"
|
|
|
|
int
|
|
dbwidget_cmd(cd_dbp, interp, argc, argv)
|
|
ClientData cd_dbp;
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
static int curs_id = 0;
|
|
DB *dbp;
|
|
DBC *cursor;
|
|
DB_ENV *env;
|
|
DB_TXN *txnid;
|
|
Tcl_CmdInfo info;
|
|
u_int32_t flags;
|
|
int fd, ret, tclint;
|
|
char cursname[128];
|
|
|
|
dbp = (DB *)cd_dbp;
|
|
|
|
USAGE_GE(argc, 2, DBWIDGET_USAGE, 0);
|
|
|
|
Tcl_SetResult(interp, "0", TCL_STATIC);
|
|
|
|
if (strcmp(argv[1], "close") == 0) {
|
|
USAGE(argc, 2, DBCLOSE_USAGE, 0);
|
|
env = dbp->dbenv;
|
|
debug_check();
|
|
#ifdef STATISTICS
|
|
if (dbp->stat != NULL)
|
|
(void)dbp->stat(dbp, stdout);
|
|
#endif
|
|
ret = dbp->close(dbp, 0);
|
|
if (env && !F_ISSET(env, DB_ENV_STANDALONE)) {
|
|
(void)db_appexit(env);
|
|
if (env->lk_conflicts)
|
|
free(env->lk_conflicts);
|
|
free(env);
|
|
}
|
|
(void)Tcl_DeleteCommand(interp, argv[0]);
|
|
if (ret < 0)
|
|
Tcl_SetResult(interp, "1", TCL_STATIC);
|
|
else if (ret > 0) {
|
|
Tcl_SetResult(interp, "db_close:", TCL_STATIC);
|
|
errno = ret;
|
|
Tcl_AppendResult(interp, Tcl_PosixError(interp), 0);
|
|
} else
|
|
Tcl_SetResult(interp, "0", TCL_STATIC);
|
|
return (TCL_OK);
|
|
} else if (strcmp(argv[1], "cursor") == 0) {
|
|
USAGE(argc, 3, DBCURS_USAGE, 0);
|
|
sprintf(&cursname[0], "%s.cursor%d", argv[0], curs_id);
|
|
curs_id++;
|
|
if (argv[2][0] == '0' && argv[2][1] == '\0')
|
|
txnid = NULL;
|
|
else {
|
|
if (Tcl_GetCommandInfo(interp, argv[2], &info) == 0) {
|
|
Tcl_SetResult(interp,
|
|
"db_del: Invalid argument ", TCL_STATIC);
|
|
Tcl_AppendResult(interp, argv[2],
|
|
" not a transaction.", 0);
|
|
return (TCL_ERROR);
|
|
}
|
|
txnid = (DB_TXN *)(info.clientData);
|
|
}
|
|
debug_check();
|
|
if ((ret = dbp->cursor(dbp, txnid, &cursor)) == 0) {
|
|
Tcl_CreateCommand(interp, cursname, dbcursor_cmd,
|
|
(ClientData)cursor, NULL);
|
|
Tcl_SetResult(interp, cursname, TCL_VOLATILE);
|
|
} else {
|
|
Tcl_SetResult(interp, "db_cursor:", TCL_STATIC);
|
|
errno = ret;
|
|
Tcl_AppendResult(interp, Tcl_PosixError(interp), 0);
|
|
}
|
|
return (TCL_OK);
|
|
} else if (strcmp(argv[1], "del") == 0) {
|
|
return (db_del_cmd(interp, argc, argv, dbp));
|
|
} else if (strcmp(argv[1], "fd") == 0) {
|
|
USAGE(argc, 2, DBFD_USAGE, 0);
|
|
Tcl_ResetResult(interp);
|
|
debug_check();
|
|
(void)dbp->fd(dbp, &fd);
|
|
sprintf(interp->result, "%d", fd);
|
|
return (TCL_OK);
|
|
} else if (strcmp(argv[1], "get") == 0) {
|
|
return (db_get_cmd(interp, argc, argv, dbp));
|
|
} else if (strcmp(argv[1], "getn") == 0) {
|
|
return (db_get_cmd(interp, argc, argv, dbp));
|
|
} else if (strcmp(argv[1], "getbin") == 0) {
|
|
return (db_getbin_cmd(interp, argc, argv, dbp));
|
|
} else if (strcmp(argv[1], "getbinkey") == 0) {
|
|
return (db_getbin_cmd(interp, argc, argv, dbp));
|
|
} else if (strcmp(argv[1], "locker") == 0) {
|
|
USAGE(argc, 2, DBLOCKER_USAGE, 0);
|
|
sprintf(cursname, "%lu", (u_long)dbp->locker);
|
|
Tcl_SetResult(interp, cursname, TCL_VOLATILE);
|
|
return (TCL_OK);
|
|
} else if (strcmp(argv[1], "put") == 0) {
|
|
return (db_put_cmd(interp, argc, argv, dbp));
|
|
} else if (strcmp(argv[1], "putn") == 0) {
|
|
return (db_put_cmd(interp, argc, argv, dbp));
|
|
} else if (strcmp(argv[1], "putbin") == 0) {
|
|
return (db_putbin_cmd(interp, argc, argv, dbp));
|
|
} else if (strcmp(argv[1], "putbinkey") == 0) {
|
|
return (db_putbin_cmd(interp, argc, argv, dbp));
|
|
} else if (strcmp(argv[1], "put0") == 0) {
|
|
return (db_put_cmd(interp, argc, argv, dbp));
|
|
} else if (strcmp(argv[1], "sync") == 0) {
|
|
USAGE(argc, 3, DBSYNC_USAGE, 0);
|
|
if (Tcl_GetInt(interp, argv[2], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
flags = (u_int32_t)tclint;
|
|
debug_check();
|
|
if ((ret = dbp->sync(dbp, flags)) < 0)
|
|
Tcl_SetResult(interp, "1", TCL_STATIC);
|
|
else if (ret > 0) {
|
|
Tcl_SetResult(interp, "db_sync:", TCL_STATIC);
|
|
errno = ret;
|
|
Tcl_AppendResult(interp, Tcl_PosixError(interp), 0);
|
|
} else
|
|
Tcl_SetResult(interp, "0", TCL_STATIC);
|
|
return (TCL_OK);
|
|
} else {
|
|
Tcl_SetResult(interp, DBWIDGET_USAGE, TCL_STATIC);
|
|
return (TCL_ERROR);
|
|
}
|
|
}
|
|
|
|
#define DBCURSOR_USAGE "dbN.cursorM ?arg arg ...?"
|
|
#define DBCCLOSE_USAGE "dbN.cursorM close"
|
|
int
|
|
dbcursor_cmd(cd_dbc, interp, argc, argv)
|
|
ClientData cd_dbc;
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
DBC *dbc;
|
|
|
|
dbc = (DBC *)cd_dbc;
|
|
Tcl_SetResult(interp, "0", TCL_STATIC);
|
|
|
|
if (strcmp(argv[1], "close") == 0) {
|
|
USAGE(argc, 2, DBCCLOSE_USAGE, 0);
|
|
debug_check();
|
|
(void)dbc->c_close(dbc);
|
|
return (Tcl_DeleteCommand(interp, argv[0]));
|
|
} else if (strcmp(argv[1], "del") == 0) {
|
|
return (dbc_del_cmd(interp, argc, argv, dbc));
|
|
} else if (strcmp(argv[1], "get") == 0) {
|
|
return (dbc_get_cmd(interp, argc, argv, dbc));
|
|
} else if (strcmp(argv[1], "getn") == 0) {
|
|
return (dbc_get_cmd(interp, argc, argv, dbc));
|
|
} else if (strcmp(argv[1], "getbin") == 0) {
|
|
return (dbc_getbin_cmd(interp, argc, argv, dbc));
|
|
} else if (strcmp(argv[1], "getbinkey") == 0) {
|
|
return (dbc_getbin_cmd(interp, argc, argv, dbc));
|
|
} else if (strcmp(argv[1], "put") == 0) {
|
|
return (dbc_put_cmd(interp, argc, argv, dbc));
|
|
} else if (strcmp(argv[1], "putn") == 0) {
|
|
return (dbc_put_cmd(interp, argc, argv, dbc));
|
|
} else {
|
|
Tcl_SetResult(interp, DBCURSOR_USAGE, TCL_STATIC);
|
|
return (TCL_ERROR);
|
|
}
|
|
/* NOTREACHED */
|
|
}
|
|
|
|
/* Widget support commands. */
|
|
|
|
#define DBDEL_USAGE "dbN del txn key flags"
|
|
int
|
|
db_del_cmd(interp, argc, argv, dbp)
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
DB *dbp;
|
|
{
|
|
DBT key;
|
|
DB_TXN *txnid;
|
|
Tcl_CmdInfo info;
|
|
db_recno_t rkey;
|
|
u_int32_t flags;
|
|
int ret, tclint;
|
|
|
|
USAGE(argc, 5, DBDEL_USAGE, 0);
|
|
|
|
if (Tcl_GetInt(interp, argv[4], &tclint) != TCL_OK) {
|
|
Tcl_AppendResult(interp, "\n", DBDEL_USAGE, NULL);
|
|
return (TCL_ERROR);
|
|
}
|
|
flags = (u_int32_t)tclint;
|
|
|
|
memset(&key, 0, sizeof(key));
|
|
if (dbp->type == DB_RECNO) {
|
|
if (Tcl_GetInt(interp, argv[3], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
rkey = (db_recno_t)tclint;
|
|
key.data = &rkey;
|
|
key.size = sizeof(db_recno_t);
|
|
} else {
|
|
key.data = argv[3];
|
|
key.size = strlen(argv[3]) + 1; /* Add NULL on end. */
|
|
}
|
|
|
|
if (argv[2][0] == '0' && argv[2][1] == '\0')
|
|
txnid = NULL;
|
|
else {
|
|
if (Tcl_GetCommandInfo(interp, argv[2], &info) == 0) {
|
|
Tcl_SetResult(interp,
|
|
"db_del: Invalid argument ", TCL_STATIC);
|
|
Tcl_AppendResult(interp, argv[2],
|
|
" not a transaction.", 0);
|
|
return (TCL_ERROR);
|
|
}
|
|
txnid = (DB_TXN *)(info.clientData);
|
|
}
|
|
|
|
debug_check();
|
|
|
|
if ((ret = dbp->del(dbp, txnid, &key, flags)) == 0)
|
|
return (TCL_OK);
|
|
else if (ret == DB_NOTFOUND) {
|
|
Tcl_ResetResult(interp);
|
|
Tcl_AppendResult(interp, "Key ", argv[3], " not found.", NULL);
|
|
return (TCL_OK);
|
|
} else {
|
|
Tcl_SetResult(interp, "-1", TCL_STATIC);
|
|
return (TCL_OK);
|
|
}
|
|
}
|
|
|
|
#define DBGET_USAGE "dbN get txn key flags [beg len]"
|
|
int
|
|
db_get_cmd(interp, argc, argv, dbp)
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
DB *dbp;
|
|
{
|
|
DBT data, key;
|
|
DB_TXN *txnid;
|
|
Tcl_CmdInfo info;
|
|
db_recno_t ikey;
|
|
u_int32_t flags;
|
|
int ret, tclint;
|
|
|
|
USAGE_GE(argc, 5, DBGET_USAGE, 0);
|
|
|
|
if (Tcl_GetInt(interp, argv[4], &tclint) != TCL_OK) {
|
|
Tcl_AppendResult(interp, "\n", DBGET_USAGE, NULL);
|
|
return (TCL_ERROR);
|
|
}
|
|
flags = (u_int32_t)tclint;
|
|
|
|
memset(&key, 0, sizeof(key));
|
|
if (dbp->type == DB_RECNO || strcmp(argv[1], "getn") == 0) {
|
|
if (Tcl_GetInt(interp, argv[3], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
ikey = (db_recno_t)tclint;
|
|
key.data = &ikey;
|
|
key.size = sizeof(db_recno_t);
|
|
} else {
|
|
key.data = argv[3];
|
|
key.size = strlen(argv[3]) + 1; /* Add Null on end */
|
|
}
|
|
|
|
memset(&data, 0, sizeof(data));
|
|
if (flags == DB_DBT_PARTIAL) {
|
|
USAGE(argc, 7, DBGET_USAGE, 0);
|
|
if (Tcl_GetInt(interp, argv[5], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
data.doff = (size_t)tclint;
|
|
if (Tcl_GetInt(interp, argv[6], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
data.dlen = (size_t)tclint;
|
|
data.flags = DB_DBT_PARTIAL;
|
|
flags = 0;
|
|
}
|
|
|
|
if (argv[2][0] == '0' && argv[2][1] == '\0')
|
|
txnid = NULL;
|
|
else {
|
|
if (Tcl_GetCommandInfo(interp, argv[2], &info) == 0) {
|
|
Tcl_SetResult(interp,
|
|
"db_get: Invalid argument ", TCL_STATIC);
|
|
Tcl_AppendResult(interp, argv[2],
|
|
" not a transaction.", 0);
|
|
return (TCL_ERROR);
|
|
}
|
|
txnid = (DB_TXN *)(info.clientData);
|
|
}
|
|
|
|
debug_check();
|
|
|
|
if (F_ISSET(dbp, DB_AM_THREAD))
|
|
F_SET(&data, DB_DBT_MALLOC);
|
|
if ((ret = dbp->get(dbp, txnid, &key, &data, flags)) == 0) {
|
|
Tcl_ResetResult(interp);
|
|
set_get_result(interp, &data);
|
|
if (F_ISSET(&data, DB_DBT_MALLOC))
|
|
free(data.data);
|
|
return (TCL_OK);
|
|
} else if (ret == DB_NOTFOUND) {
|
|
Tcl_ResetResult(interp);
|
|
Tcl_AppendResult(interp, "Key ", argv[3], " not found.", NULL);
|
|
return (TCL_OK);
|
|
} else {
|
|
Tcl_SetResult(interp, "-1", TCL_STATIC);
|
|
return (TCL_OK);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Used for getting and verifying the data associated with a binary
|
|
* data field in the database. These are big and tend to crash tcl.
|
|
* We do the handling of the big stuff in C. The path is the file
|
|
* into which to write the large key/data element.
|
|
*/
|
|
#define DBGETBIN_USAGE "dbN getbin path txn key flags"
|
|
int
|
|
db_getbin_cmd(interp, argc, argv, dbp)
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
DB *dbp;
|
|
{
|
|
DBT data, key;
|
|
DB_TXN *txnid;
|
|
Tcl_CmdInfo info;
|
|
db_recno_t rkey;
|
|
u_int32_t flags;
|
|
int ret, tclint;
|
|
|
|
USAGE(argc, 6, DBGETBIN_USAGE, 0);
|
|
|
|
if (Tcl_GetInt(interp, argv[5], &tclint) != TCL_OK) {
|
|
Tcl_AppendResult(interp, "\n", DBGET_USAGE, NULL);
|
|
return (TCL_ERROR);
|
|
}
|
|
flags = (u_int32_t)tclint;
|
|
|
|
memset(&key, 0, sizeof(key));
|
|
if (strcmp(argv[1], "getbinkey") == 0) {
|
|
if (dbt_from_file(interp, argv[4], &key) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
} else if (dbp->type == DB_RECNO) {
|
|
if (Tcl_GetInt(interp, argv[4], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
rkey = (db_recno_t)tclint;
|
|
key.data = &rkey;
|
|
key.size = sizeof(db_recno_t);
|
|
} else {
|
|
key.data = argv[4];
|
|
key.size = strlen(argv[4]) + 1; /* Add Null on end */
|
|
}
|
|
|
|
memset(&data, 0, sizeof(data));
|
|
if (strcmp(argv[1], "getbinkey") != 0)
|
|
F_SET(&data, DB_DBT_MALLOC);
|
|
|
|
if (argv[3][0] == '0' && argv[3][1] == '\0')
|
|
txnid = NULL;
|
|
else {
|
|
if (Tcl_GetCommandInfo(interp, argv[3], &info) == 0) {
|
|
Tcl_SetResult(interp,
|
|
"db_getbin: Invalid argument ", TCL_STATIC);
|
|
Tcl_AppendResult(interp, argv[3],
|
|
" not a transaction.", 0);
|
|
return (TCL_ERROR);
|
|
}
|
|
txnid = (DB_TXN *)(info.clientData);
|
|
}
|
|
|
|
debug_check();
|
|
|
|
if ((ret = dbp->get(dbp, txnid, &key, &data, flags)) == DB_NOTFOUND) {
|
|
Tcl_ResetResult(interp);
|
|
Tcl_AppendResult(interp, "Key ", argv[3], " not found.", NULL);
|
|
return (TCL_OK);
|
|
} else if (ret != 0) {
|
|
Tcl_SetResult(interp, "-1", TCL_STATIC);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
/* Got item; write it to file. */
|
|
if (strcmp(argv[1], "getbinkey") == 0) {
|
|
free(key.data);
|
|
Tcl_SetResult(interp, data.data, TCL_VOLATILE);
|
|
} else {
|
|
if (dbt_to_file(interp, argv[2], &data) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
Tcl_SetResult(interp, argv[2], TCL_VOLATILE);
|
|
}
|
|
|
|
return (TCL_OK);
|
|
}
|
|
|
|
#define DBPUT_USAGE "dbN put txn key data flags"
|
|
#define DBPPUT_USAGE "dbN put txn key data flags doff dlen"
|
|
int
|
|
db_put_cmd(interp, argc, argv, dbp)
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
DB *dbp;
|
|
{
|
|
DBT data, key;
|
|
DB_TXN *txnid;
|
|
Tcl_CmdInfo info;
|
|
db_recno_t ikey;
|
|
u_int32_t flags;
|
|
int ret, tclint;
|
|
char numbuf[16];
|
|
|
|
USAGE_GE(argc, 6, DBPUT_USAGE, 0);
|
|
|
|
if (Tcl_GetInt(interp, argv[5], &tclint) != TCL_OK) {
|
|
Tcl_AppendResult(interp, "\n", DBPUT_USAGE, NULL);
|
|
return (TCL_ERROR);
|
|
}
|
|
flags = (u_int32_t)tclint;
|
|
|
|
memset(&key, 0, sizeof(key));
|
|
if (strcmp(argv[1], "putn") == 0 || dbp->type == DB_RECNO) {
|
|
if (Tcl_GetInt(interp, argv[3], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
ikey = (db_recno_t)tclint;
|
|
key.data = &ikey;
|
|
key.size = sizeof(db_recno_t);
|
|
} else {
|
|
key.data = argv[3];
|
|
key.size = strlen(argv[3]) + 1; /* Add Null on end */
|
|
}
|
|
|
|
memset(&data, 0, sizeof(data));
|
|
data.data = argv[4];
|
|
data.size = strlen(argv[4]) + (strcmp(argv[1], "put0") == 0 ? 0 : 1);
|
|
|
|
/*
|
|
* If the partial flag is set, then arguments 6 and 7 are the
|
|
* offset and length respectively.
|
|
*/
|
|
if (flags == DB_DBT_PARTIAL) {
|
|
USAGE_GE(argc, 8, DBPPUT_USAGE, 0);
|
|
if (Tcl_GetInt(interp, argv[6], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
data.doff = (size_t)tclint;
|
|
if (Tcl_GetInt(interp, argv[7], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
data.dlen = (size_t)tclint;
|
|
data.flags = DB_DBT_PARTIAL;
|
|
data.size--; /* Remove the NULL */
|
|
flags = 0;
|
|
}
|
|
|
|
if (argv[2][0] == '0' && argv[2][1] == '\0')
|
|
txnid = NULL;
|
|
else {
|
|
if (Tcl_GetCommandInfo(interp, argv[2], &info) == 0) {
|
|
Tcl_SetResult(interp,
|
|
"db_put: Invalid argument ", TCL_STATIC);
|
|
Tcl_AppendResult(interp, argv[2],
|
|
" not a transaction.", 0);
|
|
return (TCL_ERROR);
|
|
}
|
|
txnid = (DB_TXN *)(info.clientData);
|
|
}
|
|
debug_check();
|
|
|
|
if ((ret = dbp->put(dbp, txnid, &key, &data, flags)) == 0) {
|
|
if (LF_ISSET(DB_APPEND)) {
|
|
if (key.size != sizeof(db_recno_t)) {
|
|
Tcl_SetResult(interp,
|
|
"Error: key not integer", TCL_STATIC);
|
|
return (TCL_ERROR);
|
|
}
|
|
memcpy(&ikey, key.data, sizeof(db_recno_t));
|
|
sprintf(numbuf, "%ld", (long)ikey);
|
|
Tcl_SetResult(interp, numbuf, TCL_VOLATILE);
|
|
} else {
|
|
Tcl_SetResult(interp, "0", TCL_STATIC);
|
|
}
|
|
} else if (ret < 0) {
|
|
Tcl_ResetResult(interp);
|
|
Tcl_AppendResult(interp, "Error on put of key ",
|
|
argv[3], " either not found or bad flag values.", NULL);
|
|
} else {
|
|
Tcl_SetResult(interp, "-1", TCL_STATIC);
|
|
}
|
|
return (TCL_OK);
|
|
}
|
|
|
|
/*
|
|
* Used for putting very large data items into a db file. Instead of
|
|
* passing the data in a DB, we'll pass a file name and read the data
|
|
* from the file and put it in the db. This can be checked using the
|
|
* getbin command.
|
|
*/
|
|
#define DBPUTBIN_USAGE "dbN put txn key data flags"
|
|
int
|
|
db_putbin_cmd(interp, argc, argv, dbp)
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
DB *dbp;
|
|
{
|
|
DBT data, key;
|
|
DB_TXN *txnid;
|
|
Tcl_CmdInfo info;
|
|
db_recno_t rkey;
|
|
u_int32_t flags;
|
|
int ret, tclint;
|
|
void *p;
|
|
|
|
USAGE(argc, 6, DBPUTBIN_USAGE, 0);
|
|
|
|
if (Tcl_GetInt(interp, argv[5], &tclint) != TCL_OK) {
|
|
Tcl_AppendResult(interp, "\n", DBPUT_USAGE, NULL);
|
|
return (TCL_ERROR);
|
|
}
|
|
flags = (u_int32_t)tclint;
|
|
|
|
memset(&key, 0, sizeof(key));
|
|
memset(&data, 0, sizeof(data));
|
|
if (strcmp(argv[1], "putbinkey") == 0) {
|
|
/* Get data from file. */
|
|
if (dbt_from_file(interp, argv[3], &key) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
data.data = argv[4];
|
|
data.size = strlen(argv[4]) + 1; /* Add Null on end */
|
|
p = key.data;
|
|
} else {
|
|
if (dbt_from_file(interp, argv[4], &data) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
p = data.data;
|
|
|
|
if (dbp->type == DB_RECNO) {
|
|
if (Tcl_GetInt(interp, argv[3], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
rkey = (db_recno_t)tclint;
|
|
key.data = &rkey;
|
|
key.size = sizeof(db_recno_t);
|
|
} else {
|
|
key.data = argv[3];
|
|
key.size = strlen(argv[3]) + 1; /* Add Null on end */
|
|
}
|
|
}
|
|
|
|
if (argv[2][0] == '0' && argv[2][1] == '\0')
|
|
txnid = NULL;
|
|
else {
|
|
if (Tcl_GetCommandInfo(interp, argv[2], &info) == 0) {
|
|
Tcl_SetResult(interp,
|
|
"db_putbin: Invalid argument ", TCL_STATIC);
|
|
Tcl_AppendResult(interp, argv[2],
|
|
" not a transaction.", 0);
|
|
return (TCL_ERROR);
|
|
}
|
|
txnid = (DB_TXN *)(info.clientData);
|
|
}
|
|
debug_check();
|
|
|
|
ret = dbp->put(dbp, txnid, &key, &data, flags);
|
|
free(p);
|
|
|
|
if (ret == 0)
|
|
return (TCL_OK);
|
|
else if (ret < 0) {
|
|
Tcl_ResetResult(interp);
|
|
Tcl_AppendResult(interp, "Key ", argv[3], " not found.", NULL);
|
|
return (TCL_OK);
|
|
} else {
|
|
Tcl_SetResult(interp, "-1", TCL_STATIC);
|
|
return (TCL_OK);
|
|
}
|
|
}
|
|
|
|
/* Cursor support commands. */
|
|
|
|
#define DBCDEL_USAGE "cursorN del flags"
|
|
int
|
|
dbc_del_cmd(interp, argc, argv, dbc)
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
DBC *dbc;
|
|
{
|
|
u_int32_t flags;
|
|
int ret, tclint;
|
|
|
|
USAGE(argc, 3, DBCDEL_USAGE, 0);
|
|
|
|
if (Tcl_GetInt(interp, argv[2], &tclint) != TCL_OK) {
|
|
Tcl_AppendResult(interp, "\n", DBCDEL_USAGE, NULL);
|
|
return (TCL_ERROR);
|
|
}
|
|
flags = (u_int32_t)tclint;
|
|
|
|
debug_check();
|
|
|
|
if ((ret = dbc->c_del(dbc, flags)) == 0)
|
|
return (TCL_OK);
|
|
else if (ret < 0) {
|
|
Tcl_SetResult(interp, "Uninitialized Cursor", TCL_STATIC);
|
|
return (TCL_OK);
|
|
} else {
|
|
Tcl_SetResult(interp, "-1", TCL_STATIC);
|
|
return (TCL_OK);
|
|
}
|
|
}
|
|
|
|
#define DBCGET_USAGE "cursorN get key flags [beg len]"
|
|
int
|
|
dbc_get_cmd(interp, argc, argv, dbc)
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
DBC *dbc;
|
|
{
|
|
DBT data, key;
|
|
db_recno_t rkey;
|
|
u_int32_t flags;
|
|
int ret, tclint;
|
|
char numbuf[16];
|
|
|
|
USAGE_GE(argc, 4, DBCGET_USAGE, 0);
|
|
|
|
if (Tcl_GetInt(interp, argv[3], &tclint) != TCL_OK) {
|
|
Tcl_AppendResult(interp, "\n", DBCGET_USAGE, NULL);
|
|
return (TCL_ERROR);
|
|
}
|
|
flags = (u_int32_t)tclint;
|
|
|
|
memset(&key, 0, sizeof(key));
|
|
if (dbc->dbp->type == DB_RECNO || strcmp(argv[1], "getn") == 0) {
|
|
if (Tcl_GetInt(interp, argv[2], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
rkey = (db_recno_t)tclint;
|
|
key.data = &rkey;
|
|
key.size = sizeof(db_recno_t);
|
|
} else {
|
|
key.data = argv[2];
|
|
key.size = strlen(argv[2]) + 1; /* Add Null on end */
|
|
}
|
|
|
|
memset(&data, 0, sizeof(data));
|
|
if (LF_ISSET(DB_DBT_PARTIAL)) {
|
|
USAGE(argc, 6, DBCGET_USAGE, 0);
|
|
if (Tcl_GetInt(interp, argv[4], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
data.doff = (size_t)tclint;
|
|
if (Tcl_GetInt(interp, argv[5], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
data.dlen = (size_t)tclint;
|
|
data.flags = DB_DBT_PARTIAL;
|
|
LF_CLR(DB_DBT_PARTIAL);
|
|
}
|
|
|
|
debug_check();
|
|
|
|
if (F_ISSET(dbc->dbp, DB_AM_THREAD)) {
|
|
F_SET(&data, DB_DBT_MALLOC);
|
|
switch(flags) {
|
|
case DB_FIRST:
|
|
case DB_LAST:
|
|
case DB_NEXT:
|
|
case DB_PREV:
|
|
case DB_CURRENT:
|
|
case DB_SET_RANGE:
|
|
case DB_SET_RECNO:
|
|
case DB_GET_RECNO:
|
|
F_SET(&key, DB_DBT_MALLOC);
|
|
break;
|
|
/* case DB_SET: Do nothing */
|
|
}
|
|
}
|
|
if ((ret = dbc->c_get(dbc, &key, &data, flags)) == 0) {
|
|
if (dbc->dbp->type == DB_RECNO) {
|
|
if (key.size != sizeof(db_recno_t)) {
|
|
Tcl_SetResult(interp,
|
|
"Error: key not integer", TCL_STATIC);
|
|
if (F_ISSET(&data, DB_DBT_MALLOC))
|
|
free(&data.data);
|
|
if (F_ISSET(&key, DB_DBT_MALLOC))
|
|
free(&key.data);
|
|
return (TCL_ERROR);
|
|
}
|
|
memcpy(&rkey, key.data, sizeof(db_recno_t));
|
|
sprintf(numbuf, "%ld", (long)rkey);
|
|
Tcl_SetResult(interp, numbuf, TCL_VOLATILE);
|
|
} else
|
|
Tcl_SetResult(interp, key.data, TCL_VOLATILE);
|
|
|
|
Tcl_AppendResult(interp, " {", NULL);
|
|
set_get_result(interp, &data);
|
|
Tcl_AppendResult(interp, "} ", NULL);
|
|
if (F_ISSET(&data, DB_DBT_MALLOC))
|
|
free(&data.data);
|
|
if (F_ISSET(&key, DB_DBT_MALLOC))
|
|
free(&key.data);
|
|
return (TCL_OK);
|
|
} else if (ret < 0) { /* End/Beginning of file. */
|
|
Tcl_ResetResult(interp);
|
|
return (TCL_OK);
|
|
} else {
|
|
Tcl_SetResult(interp, "-1", TCL_STATIC);
|
|
return (TCL_OK);
|
|
}
|
|
}
|
|
|
|
#define DBCGETBIN_USAGE "cursorN getbin file key flags"
|
|
int
|
|
dbc_getbin_cmd(interp, argc, argv, dbc)
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
DBC *dbc;
|
|
{
|
|
DBT data, key, *dbt;
|
|
db_recno_t rkey;
|
|
u_int32_t flags;
|
|
int ret, tclint;
|
|
char nbuf[32];
|
|
|
|
USAGE(argc, 5, DBCGET_USAGE, 0);
|
|
|
|
if (Tcl_GetInt(interp, argv[4], &tclint) != TCL_OK) {
|
|
Tcl_AppendResult(interp, "\n", DBCGET_USAGE, NULL);
|
|
return (TCL_ERROR);
|
|
}
|
|
flags = (u_int32_t)tclint;
|
|
|
|
memset(&key, 0, sizeof(key));
|
|
if (flags == DB_SET || flags == DB_KEYFIRST || flags == DB_KEYLAST)
|
|
if (strcmp(argv[1], "getbinkey") == 0) {
|
|
if (dbt_from_file(interp, argv[3], &key) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
} else if (dbc->dbp->type == DB_RECNO) {
|
|
if (Tcl_GetInt(interp, argv[3], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
rkey = (db_recno_t)tclint;
|
|
key.data = &rkey;
|
|
key.size = sizeof(db_recno_t);
|
|
} else {
|
|
key.data = argv[3];
|
|
key.size = strlen(argv[3]) + 1; /* Add Null on end */
|
|
}
|
|
|
|
memset(&data, 0, sizeof(data));
|
|
if (strcmp(argv[1], "getbinkey") != 0 && dbc->dbp->type != DB_RECNO)
|
|
F_SET(&data, DB_DBT_MALLOC);
|
|
|
|
debug_check();
|
|
|
|
ret = dbc->c_get(dbc, &key, &data, flags);
|
|
if (ret < 0) { /* End/Beginning of file. */
|
|
Tcl_ResetResult(interp);
|
|
return (TCL_OK);
|
|
} else if (ret != 0) {
|
|
Tcl_SetResult(interp, "-1", TCL_STATIC);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
/* Got key; write it or its data to a file. */
|
|
if (strcmp(argv[1], "getbinkey") == 0) {
|
|
dbt = &key;
|
|
Tcl_SetResult(interp, data.data, TCL_VOLATILE);
|
|
} else if (dbc->dbp->type == DB_RECNO) {
|
|
dbt = &data;
|
|
memcpy(&rkey, key.data, sizeof(db_recno_t));
|
|
sprintf(nbuf, "%ld", (long)rkey);
|
|
Tcl_SetResult(interp, nbuf, TCL_VOLATILE);
|
|
} else {
|
|
dbt = &data;
|
|
Tcl_SetResult(interp, key.data, TCL_VOLATILE);
|
|
}
|
|
|
|
if (dbt_to_file(interp, argv[2], dbt) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
|
|
Tcl_AppendElement(interp, argv[2]);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
#define DBCPUT_USAGE "cursorN put key data flags"
|
|
int
|
|
dbc_put_cmd(interp, argc, argv, dbc)
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
DBC *dbc;
|
|
{
|
|
DBT data, key;
|
|
db_recno_t ikey;
|
|
u_int32_t flags;
|
|
int ret, tclint;
|
|
|
|
USAGE(argc, 5, DBCPUT_USAGE, 0);
|
|
|
|
if (Tcl_GetInt(interp, argv[4], &tclint) != TCL_OK) {
|
|
Tcl_AppendResult(interp, "\n", DBCPUT_USAGE, NULL);
|
|
return (TCL_ERROR);
|
|
}
|
|
flags = (u_int32_t)tclint;
|
|
|
|
/*
|
|
* If this is a DB_CURRENT, we should never look at the key, so
|
|
* send it a NULL.
|
|
*/
|
|
memset(&key, 0, sizeof(key));
|
|
if (flags != DB_CURRENT)
|
|
if (strcmp(argv[1], "putn") == 0 ||
|
|
dbc->dbp->type == DB_RECNO) {
|
|
if (Tcl_GetInt(interp, argv[2], &tclint) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
ikey = (db_recno_t)tclint;
|
|
key.data = &ikey;
|
|
key.size = sizeof(db_recno_t);
|
|
} else {
|
|
key.data = argv[2];
|
|
key.size = strlen(argv[2]) + 1; /* Add Null on end */
|
|
}
|
|
|
|
memset(&data, 0, sizeof(data));
|
|
data.data = argv[3];
|
|
data.size = strlen(argv[3]) + 1;
|
|
|
|
debug_check();
|
|
|
|
if ((ret = dbc->c_put(dbc, &key, &data, flags)) == 0)
|
|
return (TCL_OK);
|
|
else if (ret < 0) {
|
|
Tcl_ResetResult(interp);
|
|
Tcl_AppendResult(interp, "Key ", argv[2], " not found.", NULL);
|
|
return (TCL_OK);
|
|
} else {
|
|
Tcl_SetResult(interp, "-1", TCL_STATIC);
|
|
return (TCL_OK);
|
|
}
|
|
}
|
|
|
|
u_int8_t *
|
|
list_to_numarray(interp, str)
|
|
Tcl_Interp *interp;
|
|
char *str;
|
|
{
|
|
int argc, i, tmp;
|
|
u_int8_t *nums, *np;
|
|
char **argv, **ap;
|
|
|
|
if (Tcl_SplitList(interp, str, &argc, &argv) != TCL_OK)
|
|
return (NULL);
|
|
if ((nums = (u_int8_t *)calloc(argc, sizeof(u_int8_t))) == NULL) {
|
|
Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_STATIC);
|
|
return (NULL);
|
|
}
|
|
|
|
for (np = nums, ap = argv, i = 0; i < argc; i++, ap++, np++) {
|
|
if (Tcl_GetInt(interp, *ap, &tmp) != TCL_OK) {
|
|
free (nums);
|
|
return (NULL);
|
|
}
|
|
*np = (u_int8_t)tmp; /* XXX: Possible overflow. */
|
|
}
|
|
#ifndef _WIN32
|
|
/*
|
|
* XXX
|
|
* This currently traps on Windows/NT, probably due to a mismatch of
|
|
* malloc/free implementations between the TCL library and this module.
|
|
* Sidestep the issue for now.
|
|
*/
|
|
free(argv);
|
|
#endif
|
|
return (nums);
|
|
}
|
|
|
|
#define STAMP_USAGE "timestamp [-r]"
|
|
int
|
|
stamp_cmd(notused, interp, argc, argv)
|
|
ClientData notused;
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
static time_t start;
|
|
struct tm *tp;
|
|
time_t elapsed, now;
|
|
static char buf[25];
|
|
|
|
notused = NULL;
|
|
|
|
USAGE_GE(argc, 1, STAMP_USAGE, 0);
|
|
(void)time(&now);
|
|
if (now == (time_t)-1)
|
|
goto err;
|
|
if (argc > 1 && strcmp(argv[1], "-r") == 0) {
|
|
sprintf(buf, "%lu", (u_long)now);
|
|
Tcl_SetResult(interp, buf, TCL_STATIC);
|
|
return (TCL_OK);
|
|
}
|
|
if ((tp = localtime(&now)) == NULL)
|
|
goto err;
|
|
|
|
if (start == 0)
|
|
start = now;
|
|
elapsed = now - start;
|
|
(void)sprintf(buf, "%02d:%02d:%02d (%02d:%02d:%02d)",
|
|
tp->tm_hour, tp->tm_min, tp->tm_sec, (int)(elapsed / 3600),
|
|
(int)((elapsed % 3600) / 60), (int)(((elapsed % 3600) % 60)));
|
|
start = now;
|
|
|
|
Tcl_SetResult(interp, buf, TCL_STATIC);
|
|
return (TCL_OK);
|
|
|
|
err: Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_STATIC);
|
|
return (TCL_ERROR);
|
|
}
|
|
|
|
int debug_stop; /* Stop on each iteration. */
|
|
|
|
void
|
|
debug_check()
|
|
{
|
|
if (debug_on == 0)
|
|
return;
|
|
|
|
if (debug_print != 0) {
|
|
printf("\r%6d:", debug_on);
|
|
fflush(stdout);
|
|
}
|
|
|
|
if (debug_on++ == debug_test || debug_stop)
|
|
__db_loadme();
|
|
}
|
|
|
|
int
|
|
dbt_from_file(interp, file, dbt)
|
|
Tcl_Interp *interp;
|
|
char *file;
|
|
DBT *dbt;
|
|
{
|
|
size_t len, size;
|
|
ssize_t nr;
|
|
u_int32_t mbytes, bytes;
|
|
int fd;
|
|
|
|
/* Get data from file. */
|
|
fd = -1;
|
|
len = strlen(file) + 1;
|
|
if ((errno = __db_open(file, DB_RDONLY, DB_RDONLY, 0, &fd)) != 0)
|
|
goto err;
|
|
if ((errno = __db_ioinfo(file, fd, &mbytes, &bytes, NULL)) != 0)
|
|
goto err;
|
|
size = mbytes * MEGABYTE + bytes;
|
|
if ((dbt->data = (void *)malloc(size + len)) == NULL)
|
|
goto err;
|
|
if ((errno =
|
|
__db_read(fd, ((u_int8_t *)dbt->data) + len, size, &nr)) != 0)
|
|
goto err;
|
|
if (nr != (ssize_t)size) {
|
|
errno = EIO;
|
|
goto err;
|
|
}
|
|
if ((errno =__db_close(fd)) != 0) {
|
|
err: if (fd != -1)
|
|
close(fd);
|
|
Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_STATIC);
|
|
return (TCL_ERROR);
|
|
}
|
|
strcpy((char *)(dbt->data), file);
|
|
dbt->size = size + (u_int32_t)len;
|
|
dbt->flags = 0;
|
|
return (TCL_OK);
|
|
}
|
|
|
|
/*
|
|
* file is the file we are creating. ofile is the original file
|
|
* name so we know how many characters to drop off the end.
|
|
*/
|
|
int
|
|
dbt_to_file(interp, file, dbt)
|
|
Tcl_Interp *interp;
|
|
char *file;
|
|
DBT *dbt;
|
|
{
|
|
size_t len;
|
|
ssize_t nw;
|
|
int fd;
|
|
char *p;
|
|
|
|
/* Got key; write it to file. */
|
|
for (len = 1, p = (char *)(dbt->data); *p != '\0'; len++, p++)
|
|
;
|
|
p++;
|
|
|
|
fd = -1;
|
|
if ((errno = __db_open(file, DB_CREATE | DB_TRUNCATE,
|
|
DB_CREATE | DB_TRUNCATE, 0644, &fd)) != 0 ||
|
|
(errno = __db_write(fd, p, dbt->size - len, &nw) != 0) ||
|
|
nw != (ssize_t)(dbt->size - len) ||
|
|
(errno = __db_close(fd)) != 0) {
|
|
if (errno == 0)
|
|
errno = EIO;
|
|
if (fd == -1)
|
|
(void)__db_close(fd);
|
|
Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_STATIC);
|
|
return (TCL_ERROR);
|
|
}
|
|
if (F_ISSET(dbt, DB_DBT_MALLOC))
|
|
free(dbt->data);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
void
|
|
set_get_result(interp, dbt)
|
|
Tcl_Interp *interp;
|
|
DBT *dbt;
|
|
{
|
|
size_t i;
|
|
u_int8_t *p;
|
|
char numbuf[32], sprbuf[128], *outbuf;
|
|
|
|
for (i = 0, p = dbt->data; i < dbt->size && *p == '\0'; i++, p++)
|
|
;
|
|
/*
|
|
* If this is a partial get, we need to make sure that the last
|
|
* character is a NUL so that tcl can handle it.
|
|
*/
|
|
if (F_ISSET(dbt, DB_DBT_PARTIAL)) {
|
|
if (dbt->size == 0)
|
|
((char *)dbt->data)[0] = '\0';
|
|
else
|
|
((char *)dbt->data)[dbt->size - 1] = '\0';
|
|
}
|
|
|
|
if (i == 0) {
|
|
if (((u_int8_t *)dbt->data)[dbt->size - 1] != '\0') {
|
|
outbuf = (char *)malloc(dbt->size + 1);
|
|
memcpy(outbuf, dbt->data, dbt->size);
|
|
outbuf[dbt->size] = '\0';
|
|
} else
|
|
outbuf = dbt->data;
|
|
Tcl_AppendResult(interp, outbuf, NULL);
|
|
if (outbuf != dbt->data)
|
|
free(outbuf);
|
|
} else {
|
|
sprintf(&numbuf[0], "%lu", (u_long)i);
|
|
sprintf(&sprbuf[0], " %%.%ds", dbt->size - i);
|
|
outbuf = (char *)malloc(dbt->size - i + 5);
|
|
sprintf(outbuf, sprbuf, p);
|
|
Tcl_AppendResult(interp, numbuf, outbuf, NULL);
|
|
free(outbuf);
|
|
}
|
|
}
|
|
|
|
#define SRAND_USAGE "srand seed"
|
|
int
|
|
srand_cmd(notused, interp, argc, argv)
|
|
ClientData notused;
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
int ival;
|
|
|
|
notused = NULL;
|
|
USAGE(argc, 2, SRAND_USAGE, 0);
|
|
if (Tcl_GetInt(interp, argv[1], &ival) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
|
|
srand((u_int)ival);
|
|
Tcl_SetResult(interp, "0", TCL_STATIC);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
#define RAND_USAGE "rand"
|
|
int
|
|
rand_cmd(notused, interp, argc, argv)
|
|
ClientData notused;
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
char retbuf[50];
|
|
|
|
notused = NULL;
|
|
argv = NULL;
|
|
USAGE(argc, 1, RAND_USAGE, 0);
|
|
|
|
sprintf(retbuf, "%ld", (long)rand());
|
|
Tcl_SetResult(interp, retbuf, TCL_VOLATILE);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
#define RANDOMINT_USAGE "random_int lo hi"
|
|
int
|
|
randomint_cmd(notused, interp, argc, argv)
|
|
ClientData notused;
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
long t;
|
|
int lo, hi, ret;
|
|
char retbuf[50];
|
|
|
|
notused = NULL;
|
|
USAGE(argc, 3, RANDOMINT_USAGE, 0);
|
|
if (Tcl_GetInt(interp, argv[1], &lo) != TCL_OK ||
|
|
Tcl_GetInt(interp, argv[2], &hi) != TCL_OK)
|
|
return (TCL_ERROR);
|
|
|
|
#ifndef RAND_MAX
|
|
#define RAND_MAX 0x7fffffff
|
|
#endif
|
|
t = rand();
|
|
if (t > RAND_MAX)
|
|
printf("Max random is higher than %ld\n", (long)RAND_MAX);
|
|
ret = (int)(((double)t / ((double)(RAND_MAX) + 1)) * (hi - lo + 1));
|
|
ret += lo;
|
|
sprintf(retbuf, "%d", ret);
|
|
Tcl_SetResult(interp, retbuf, TCL_VOLATILE);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
#define VERSION_USAGE "db_version"
|
|
int
|
|
dbversion_cmd(notused, interp, argc, notused2)
|
|
ClientData notused;
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *notused2[];
|
|
{
|
|
char *str;
|
|
|
|
notused = NULL;
|
|
notused2 = NULL;
|
|
USAGE(argc, 1, VERSION_USAGE, 0);
|
|
str = db_version(NULL, NULL, NULL);
|
|
if (str == NULL) {
|
|
Tcl_SetResult(interp, "db_version: ", TCL_STATIC);
|
|
Tcl_AppendResult(interp, Tcl_PosixError(interp), 0);
|
|
return (TCL_ERROR);
|
|
}
|
|
Tcl_SetResult(interp, str, TCL_DYNAMIC);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
/*
|
|
* Create an environment that we can pass around between different
|
|
* calls.
|
|
*/
|
|
#define DBENV_USAGE "dbenv "
|
|
int
|
|
dbenv_cmd(notused, interp, argc, argv)
|
|
ClientData notused;
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
static int env_number = 0;
|
|
DB_ENV *env;
|
|
char envname[50];
|
|
|
|
debug_check();
|
|
notused = NULL;
|
|
|
|
/* Check number of arguments. */
|
|
USAGE_GE(argc, 1, DBENV_USAGE, DO_ENV);
|
|
|
|
process_env_options(interp, argc - 1, &argv[1], &env);
|
|
if (env == NULL) {
|
|
Tcl_SetResult(interp, "NULL", TCL_STATIC);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
F_SET(env, DB_ENV_STANDALONE);
|
|
|
|
/* Create new command name. */
|
|
sprintf(&envname[0], "env%d", env_number);
|
|
env_number++;
|
|
|
|
Tcl_CreateCommand(interp, envname, envwidget_cmd, (ClientData)env,
|
|
envwidget_delcmd);
|
|
Tcl_SetResult(interp, envname, TCL_VOLATILE);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
void
|
|
envwidget_delcmd(cd)
|
|
ClientData cd;
|
|
{
|
|
DB_ENV *env;
|
|
|
|
debug_check();
|
|
env = (DB_ENV *)cd;
|
|
|
|
(void)db_appexit(env);
|
|
if (env->lk_conflicts)
|
|
free(env->lk_conflicts);
|
|
free(env);
|
|
}
|
|
|
|
#define ENVWIDGET_USAGE "envN"
|
|
#define ENVWIDGET_SIMPLEDUP "envN simpledup"
|
|
int
|
|
envwidget_cmd(cd, interp, argc, argv)
|
|
ClientData cd;
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
static int nenv_number = 0;
|
|
DB_ENV *env, *newenv;
|
|
char **p, nenvname[50];
|
|
|
|
argv = argv;
|
|
env = (DB_ENV *)cd;
|
|
|
|
if (argc == 1) {
|
|
USAGE(argc, 1, ENVWIDGET_USAGE, 0);
|
|
|
|
Tcl_ResetResult(interp);
|
|
if (env->db_home != NULL)
|
|
Tcl_AppendResult(interp, " Home: ", env->db_home, 0);
|
|
if ((p = env->db_data_dir) != NULL)
|
|
for (; *p != NULL; ++p)
|
|
Tcl_AppendResult(interp, " Data: ", *p, 0);
|
|
if (env->db_log_dir != NULL)
|
|
Tcl_AppendResult(interp, " Log: ", env->db_log_dir, 0);
|
|
if (env->db_tmp_dir != NULL)
|
|
Tcl_AppendResult(interp, " Tmp: ", env->db_tmp_dir, 0);
|
|
} else if (strcmp(argv[1], "simpledup") == 0) {
|
|
USAGE(argc, 2, ENVWIDGET_SIMPLEDUP, 0);
|
|
/*
|
|
* Copy the env and then NULL out the log, lock and
|
|
* transaction info pointers so that we only share an
|
|
* mpool.
|
|
*/
|
|
newenv = (DB_ENV *)malloc(sizeof(*newenv));
|
|
*newenv = *env;
|
|
newenv->lg_info = NULL;
|
|
newenv->lk_info = NULL;
|
|
newenv->tx_info = NULL;
|
|
|
|
/* Create new command name. */
|
|
sprintf(&nenvname[0], "nenv%d", nenv_number);
|
|
nenv_number++;
|
|
|
|
Tcl_CreateCommand(interp, nenvname, envwidget_cmd,
|
|
(ClientData)newenv, NULL);
|
|
Tcl_SetResult(interp, nenvname, TCL_VOLATILE);
|
|
} else {
|
|
Tcl_SetResult(interp, "Invalid command", TCL_STATIC);
|
|
return (TCL_ERROR);
|
|
}
|
|
|
|
return (TCL_OK);
|
|
}
|
|
|
|
#define ARGS_USAGE "args"
|
|
int
|
|
args_cmd(cd, interp, argc, argv)
|
|
ClientData cd;
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
cd = cd;
|
|
argv = argv;
|
|
|
|
USAGE(argc, 1, ARGS_USAGE, 0);
|
|
printf("Legal environment options are: %s\n", DB_ENV_FLAGS);
|
|
printf("Legal access method options are: %s\n", DB_INFO_FLAGS);
|
|
Tcl_ResetResult(interp);
|
|
return (TCL_OK);
|
|
}
|
|
|
|
#define DEBUG_CHECK_USAGE "debug_check"
|
|
int
|
|
debugcheck_cmd(notused1, interp, argc, notused2)
|
|
ClientData notused1;
|
|
Tcl_Interp *interp;
|
|
int argc;
|
|
char *notused2[];
|
|
{
|
|
USAGE(argc, 1, DEBUG_CHECK_USAGE, 0);
|
|
notused1 = notused1;
|
|
notused2 = notused2;
|
|
debug_check();
|
|
Tcl_ResetResult(interp);
|
|
return (TCL_OK);
|
|
}
|