#include "db_config.h"
#include "db_int.h"
#ifdef HAVE_SYSTEM_INCLUDE_FILES
#include <tcl.h>
#endif
#include "dbinc/lock.h"
#include "dbinc/txn.h"
#include "dbinc/tcl_db.h"
static void _EnvInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
static int env_DbRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
static int env_DbRename __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
static int env_GetFlags __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
static int env_GetOpenFlag
__P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
static int env_GetLockDetect
__P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
static int env_GetTimeout __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
static int env_GetVerbose __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
int
env_Cmd(clientData, interp, objc, objv)
ClientData clientData;
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
{
static const char *envcmds[] = {
#ifdef CONFIG_TEST
"attributes",
"errfile",
"errpfx",
"event",
"id_reset",
"lock_detect",
"lock_id",
"lock_id_free",
"lock_id_set",
"lock_get",
"lock_stat",
"lock_timeout",
"lock_vec",
"log_archive",
"log_compare",
"log_cursor",
"log_file",
"log_flush",
"log_get",
"log_put",
"log_stat",
"lsn_reset",
"mpool",
"mpool_stat",
"mpool_sync",
"mpool_trickle",
"rep_config",
"rep_elect",
"rep_flush",
"rep_get_config",
"rep_lease",
"rep_limit",
"rep_process_message",
"rep_request",
"rep_start",
"rep_stat",
"rep_sync",
"rep_transport",
"repmgr",
"repmgr_stat",
"rpcid",
"set_flags",
"test",
"txn_id_set",
"txn_recover",
"txn_stat",
"txn_timeout",
"verbose",
#endif
"cdsgroup",
"close",
"dbremove",
"dbrename",
"get_cachesize",
"get_cache_max",
"get_data_dirs",
"get_encrypt_flags",
"get_errpfx",
"get_flags",
"get_home",
"get_lg_bsize",
"get_lg_dir",
"get_lg_filemode",
"get_lg_max",
"get_lg_regionmax",
"get_lk_detect",
"get_lk_max_lockers",
"get_lk_max_locks",
"get_lk_max_objects",
"get_mp_max_openfd",
"get_mp_max_write",
"get_mp_mmapsize",
"get_open_flags",
"get_rep_limit",
"get_shm_key",
"get_tas_spins",
"get_timeout",
"get_tmp_dir",
"get_tx_max",
"get_tx_timestamp",
"get_verbose",
"resize_cache",
"set_data_dir",
"txn",
"txn_checkpoint",
NULL
};
enum envcmds {
#ifdef CONFIG_TEST
ENVATTR,
ENVERRFILE,
ENVERRPFX,
ENVEVENT,
ENVIDRESET,
ENVLKDETECT,
ENVLKID,
ENVLKFREEID,
ENVLKSETID,
ENVLKGET,
ENVLKSTAT,
ENVLKTIMEOUT,
ENVLKVEC,
ENVLOGARCH,
ENVLOGCMP,
ENVLOGCURSOR,
ENVLOGFILE,
ENVLOGFLUSH,
ENVLOGGET,
ENVLOGPUT,
ENVLOGSTAT,
ENVLSNRESET,
ENVMP,
ENVMPSTAT,
ENVMPSYNC,
ENVTRICKLE,
ENVREPCONFIG,
ENVREPELECT,
ENVREPFLUSH,
ENVREPGETCONFIG,
ENVREPLEASE,
ENVREPLIMIT,
ENVREPPROCMESS,
ENVREPREQUEST,
ENVREPSTART,
ENVREPSTAT,
ENVREPSYNC,
ENVREPTRANSPORT,
ENVREPMGR,
ENVREPMGRSTAT,
ENVRPCID,
ENVSETFLAGS,
ENVTEST,
ENVTXNSETID,
ENVTXNRECOVER,
ENVTXNSTAT,
ENVTXNTIMEOUT,
ENVVERB,
#endif
ENVCDSGROUP,
ENVCLOSE,
ENVDBREMOVE,
ENVDBRENAME,
ENVGETCACHESIZE,
ENVGETCACHEMAX,
ENVGETDATADIRS,
ENVGETENCRYPTFLAGS,
ENVGETERRPFX,
ENVGETFLAGS,
ENVGETHOME,
ENVGETLGBSIZE,
ENVGETLGDIR,
ENVGETLGFILEMODE,
ENVGETLGMAX,
ENVGETLGREGIONMAX,
ENVGETLKDETECT,
ENVGETLKMAXLOCKERS,
ENVGETLKMAXLOCKS,
ENVGETLKMAXOBJECTS,
ENVGETMPMAXOPENFD,
ENVGETMPMAXWRITE,
ENVGETMPMMAPSIZE,
ENVGETOPENFLAG,
ENVGETREPLIMIT,
ENVGETSHMKEY,
ENVGETTASSPINS,
ENVGETTIMEOUT,
ENVGETTMPDIR,
ENVGETTXMAX,
ENVGETTXTIMESTAMP,
ENVGETVERBOSE,
ENVRESIZECACHE,
ENVSETDATADIR,
ENVTXN,
ENVTXNCKP
};
DBTCL_INFO *envip;
DB_ENV *dbenv;
Tcl_Obj **listobjv, *myobjv[3], *res;
db_timeout_t timeout;
size_t size;
time_t timeval;
u_int32_t bytes, gbytes, value;
long shm_key;
int cmdindex, i, intvalue, listobjc, ncache, result, ret;
const char *strval, **dirs;
char *strarg, newname[MSG_SIZE];
#ifdef CONFIG_TEST
DBTCL_INFO *logcip;
DB_LOGC *logc;
u_int32_t lockid;
long newval, otherval;
#endif
Tcl_ResetResult(interp);
dbenv = (DB_ENV *)clientData;
envip = _PtrToInfo((void *)dbenv);
result = TCL_OK;
memset(newname, 0, MSG_SIZE);
if (objc <= 1) {
Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs");
return (TCL_ERROR);
}
if (dbenv == NULL) {
Tcl_SetResult(interp, "NULL env pointer", TCL_STATIC);
return (TCL_ERROR);
}
if (envip == NULL) {
Tcl_SetResult(interp, "NULL env info pointer", TCL_STATIC);
return (TCL_ERROR);
}
if (Tcl_GetIndexFromObj(interp, objv[1], envcmds, "command",
TCL_EXACT, &cmdindex) != TCL_OK)
return (IS_HELP(objv[1]));
res = NULL;
switch ((enum envcmds)cmdindex) {
#ifdef CONFIG_TEST
case ENVEVENT:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return (TCL_ERROR);
}
result = tcl_EventNotify(interp, dbenv, objv[2], envip);
break;
case ENVIDRESET:
result = tcl_EnvIdReset(interp, objc, objv, dbenv);
break;
case ENVLSNRESET:
result = tcl_EnvLsnReset(interp, objc, objv, dbenv);
break;
case ENVLKDETECT:
result = tcl_LockDetect(interp, objc, objv, dbenv);
break;
case ENVLKSTAT:
result = tcl_LockStat(interp, objc, objv, dbenv);
break;
case ENVLKTIMEOUT:
result = tcl_LockTimeout(interp, objc, objv, dbenv);
break;
case ENVLKID:
if (objc > 2) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return (TCL_ERROR);
}
_debug_check();
ret = dbenv->lock_id(dbenv, &lockid);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"lock_id");
if (result == TCL_OK)
res = Tcl_NewWideIntObj((Tcl_WideInt)lockid);
break;
case ENVLKFREEID:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return (TCL_ERROR);
}
result = Tcl_GetLongFromObj(interp, objv[2], &newval);
if (result != TCL_OK)
return (result);
ret = dbenv->lock_id_free(dbenv, (u_int32_t)newval);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"lock id_free");
break;
case ENVLKSETID:
if (objc != 4) {
Tcl_WrongNumArgs(interp, 4, objv, "current max");
return (TCL_ERROR);
}
result = Tcl_GetLongFromObj(interp, objv[2], &newval);
if (result != TCL_OK)
return (result);
result = Tcl_GetLongFromObj(interp, objv[3], &otherval);
if (result != TCL_OK)
return (result);
ret = __lock_id_set(dbenv,
(u_int32_t)newval, (u_int32_t)otherval);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"lock id_free");
break;
case ENVLKGET:
result = tcl_LockGet(interp, objc, objv, dbenv);
break;
case ENVLKVEC:
result = tcl_LockVec(interp, objc, objv, dbenv);
break;
case ENVLOGARCH:
result = tcl_LogArchive(interp, objc, objv, dbenv);
break;
case ENVLOGCMP:
result = tcl_LogCompare(interp, objc, objv);
break;
case ENVLOGCURSOR:
snprintf(newname, sizeof(newname),
"%s.logc%d", envip->i_name, envip->i_envlogcid);
logcip = _NewInfo(interp, NULL, newname, I_LOGC);
if (logcip != NULL) {
ret = dbenv->log_cursor(dbenv, &logc, 0);
if (ret == 0) {
result = TCL_OK;
envip->i_envlogcid++;
(void)Tcl_CreateObjCommand(interp, newname,
(Tcl_ObjCmdProc *)logc_Cmd,
(ClientData)logc, NULL);
res = NewStringObj(newname, strlen(newname));
_SetInfoData(logcip, logc);
} else {
_DeleteInfo(logcip);
result = _ErrorSetup(interp, ret, "log cursor");
}
} else {
Tcl_SetResult(interp,
"Could not set up info", TCL_STATIC);
result = TCL_ERROR;
}
break;
case ENVLOGFILE:
result = tcl_LogFile(interp, objc, objv, dbenv);
break;
case ENVLOGFLUSH:
result = tcl_LogFlush(interp, objc, objv, dbenv);
break;
case ENVLOGGET:
result = tcl_LogGet(interp, objc, objv, dbenv);
break;
case ENVLOGPUT:
result = tcl_LogPut(interp, objc, objv, dbenv);
break;
case ENVLOGSTAT:
result = tcl_LogStat(interp, objc, objv, dbenv);
break;
case ENVMPSTAT:
result = tcl_MpStat(interp, objc, objv, dbenv);
break;
case ENVMPSYNC:
result = tcl_MpSync(interp, objc, objv, dbenv);
break;
case ENVTRICKLE:
result = tcl_MpTrickle(interp, objc, objv, dbenv);
break;
case ENVMP:
result = tcl_Mp(interp, objc, objv, dbenv, envip);
break;
case ENVREPCONFIG:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return (TCL_ERROR);
}
result = tcl_RepConfig(interp, dbenv, objv[2]);
break;
case ENVREPELECT:
result = tcl_RepElect(interp, objc, objv, dbenv);
break;
case ENVREPFLUSH:
result = tcl_RepFlush(interp, objc, objv, dbenv);
break;
case ENVREPGETCONFIG:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return (TCL_ERROR);
}
result = tcl_RepGetConfig(interp, dbenv, objv[2]);
break;
case ENVREPLEASE:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return (TCL_ERROR);
}
result = Tcl_ListObjGetElements(interp, objv[2],
&listobjc, &listobjv);
if (result == TCL_OK)
result = tcl_RepLease(interp,
listobjc, listobjv, dbenv);
break;
case ENVREPLIMIT:
result = tcl_RepLimit(interp, objc, objv, dbenv);
break;
case ENVREPPROCMESS:
result = tcl_RepProcessMessage(interp, objc, objv, dbenv);
break;
case ENVREPREQUEST:
result = tcl_RepRequest(interp, objc, objv, dbenv);
break;
case ENVREPSTART:
result = tcl_RepStart(interp, objc, objv, dbenv);
break;
case ENVREPSTAT:
result = tcl_RepStat(interp, objc, objv, dbenv);
break;
case ENVREPSYNC:
result = tcl_RepSync(interp, objc, objv, dbenv);
break;
case ENVREPTRANSPORT:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return (TCL_ERROR);
}
result = Tcl_ListObjGetElements(interp, objv[2],
&listobjc, &listobjv);
if (result == TCL_OK)
result = tcl_RepTransport(interp,
listobjc, listobjv, dbenv, envip);
break;
case ENVREPMGR:
result = tcl_RepMgr(interp, objc, objv, dbenv);
break;
case ENVREPMGRSTAT:
result = tcl_RepMgrStat(interp, objc, objv, dbenv);
break;
case ENVRPCID:
if (objc > 2) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return (TCL_ERROR);
}
res = Tcl_NewLongObj((long)dbenv->cl_id);
break;
case ENVTXNSETID:
if (objc != 4) {
Tcl_WrongNumArgs(interp, 4, objv, "current max");
return (TCL_ERROR);
}
result = Tcl_GetLongFromObj(interp, objv[2], &newval);
if (result != TCL_OK)
return (result);
result = Tcl_GetLongFromObj(interp, objv[3], &otherval);
if (result != TCL_OK)
return (result);
ret = __txn_id_set(dbenv,
(u_int32_t)newval, (u_int32_t)otherval);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"txn setid");
break;
case ENVTXNRECOVER:
result = tcl_TxnRecover(interp, objc, objv, dbenv, envip);
break;
case ENVTXNSTAT:
result = tcl_TxnStat(interp, objc, objv, dbenv);
break;
case ENVTXNTIMEOUT:
result = tcl_TxnTimeout(interp, objc, objv, dbenv);
break;
case ENVATTR:
result = tcl_EnvAttr(interp, objc, objv, dbenv);
break;
case ENVERRFILE:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "errfile");
return (TCL_ERROR);
}
strarg = Tcl_GetStringFromObj(objv[2], NULL);
tcl_EnvSetErrfile(interp, dbenv, envip, strarg);
result = TCL_OK;
break;
case ENVERRPFX:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "pfx");
return (TCL_ERROR);
}
strarg = Tcl_GetStringFromObj(objv[2], NULL);
result = tcl_EnvSetErrpfx(interp, dbenv, envip, strarg);
break;
case ENVSETFLAGS:
if (objc != 4) {
Tcl_WrongNumArgs(interp, 2, objv, "which on|off");
return (TCL_ERROR);
}
result = tcl_EnvSetFlags(interp, dbenv, objv[2], objv[3]);
break;
case ENVTEST:
result = tcl_EnvTest(interp, objc, objv, dbenv);
break;
case ENVVERB:
if (objc != 4) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return (TCL_ERROR);
}
result = tcl_EnvVerbose(interp, dbenv, objv[2], objv[3]);
break;
#endif
case ENVCDSGROUP:
result = tcl_CDSGroup(interp, objc, objv, dbenv, envip);
break;
case ENVCLOSE:
if (objc > 2) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return (TCL_ERROR);
}
_debug_check();
ret = dbenv->close(dbenv, 0);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env close");
_EnvInfoDelete(interp, envip);
envip = NULL;
break;
case ENVDBREMOVE:
result = env_DbRemove(interp, objc, objv, dbenv);
break;
case ENVDBRENAME:
result = env_DbRename(interp, objc, objv, dbenv);
break;
case ENVGETCACHESIZE:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_cachesize(dbenv, &gbytes, &bytes, &ncache);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_cachesize")) == TCL_OK) {
myobjv[0] = Tcl_NewLongObj((long)gbytes);
myobjv[1] = Tcl_NewLongObj((long)bytes);
myobjv[2] = Tcl_NewLongObj((long)ncache);
res = Tcl_NewListObj(3, myobjv);
}
break;
case ENVGETCACHEMAX:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_cache_max(dbenv, &gbytes, &bytes);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_cache_max")) == TCL_OK) {
myobjv[0] = Tcl_NewLongObj((long)gbytes);
myobjv[1] = Tcl_NewLongObj((long)bytes);
res = Tcl_NewListObj(2, myobjv);
}
break;
case ENVGETDATADIRS:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_data_dirs(dbenv, &dirs);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_data_dirs")) == TCL_OK) {
res = Tcl_NewListObj(0, NULL);
for (i = 0; result == TCL_OK && dirs[i] != NULL; i++)
result = Tcl_ListObjAppendElement(interp, res,
NewStringObj(dirs[i], strlen(dirs[i])));
}
break;
case ENVGETENCRYPTFLAGS:
result = tcl_EnvGetEncryptFlags(interp, objc, objv, dbenv);
break;
case ENVGETERRPFX:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
dbenv->get_errpfx(dbenv, &strval);
res = NewStringObj(strval, strlen(strval));
break;
case ENVGETFLAGS:
result = env_GetFlags(interp, objc, objv, dbenv);
break;
case ENVGETHOME:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_home(dbenv, &strval);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_home")) == TCL_OK)
res = NewStringObj(strval, strlen(strval));
break;
case ENVGETLGBSIZE:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_lg_bsize(dbenv, &value);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_lg_bsize")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
case ENVGETLGDIR:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_lg_dir(dbenv, &strval);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_lg_dir")) == TCL_OK)
res = NewStringObj(strval, strlen(strval));
break;
case ENVGETLGFILEMODE:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_lg_filemode(dbenv, &intvalue);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_lg_filemode")) == TCL_OK)
res = Tcl_NewLongObj((long)intvalue);
break;
case ENVGETLGMAX:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_lg_max(dbenv, &value);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_lg_max")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
case ENVGETLGREGIONMAX:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_lg_regionmax(dbenv, &value);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_lg_regionmax")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
case ENVGETLKDETECT:
result = env_GetLockDetect(interp, objc, objv, dbenv);
break;
case ENVGETLKMAXLOCKERS:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_lk_max_lockers(dbenv, &value);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_lk_max_lockers")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
case ENVGETLKMAXLOCKS:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_lk_max_locks(dbenv, &value);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_lk_max_locks")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
case ENVGETLKMAXOBJECTS:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_lk_max_objects(dbenv, &value);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_lk_max_objects")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
case ENVGETMPMAXOPENFD:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_mp_max_openfd(dbenv, &intvalue);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_mp_max_openfd")) == TCL_OK)
res = Tcl_NewIntObj(intvalue);
break;
case ENVGETMPMAXWRITE:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_mp_max_write(dbenv, &intvalue, &timeout);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_mp_max_write")) == TCL_OK) {
myobjv[0] = Tcl_NewIntObj(intvalue);
myobjv[1] = Tcl_NewIntObj((int)timeout);
res = Tcl_NewListObj(2, myobjv);
}
break;
case ENVGETMPMMAPSIZE:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_mp_mmapsize(dbenv, &size);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_mp_mmapsize")) == TCL_OK)
res = Tcl_NewLongObj((long)size);
break;
case ENVGETOPENFLAG:
result = env_GetOpenFlag(interp, objc, objv, dbenv);
break;
case ENVGETREPLIMIT:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->rep_get_limit(dbenv, &gbytes, &bytes);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env rep_get_limit")) == TCL_OK) {
myobjv[0] = Tcl_NewLongObj((long)gbytes);
myobjv[1] = Tcl_NewLongObj((long)bytes);
res = Tcl_NewListObj(2, myobjv);
}
break;
case ENVGETSHMKEY:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_shm_key(dbenv, &shm_key);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env shm_key")) == TCL_OK)
res = Tcl_NewLongObj(shm_key);
break;
case ENVGETTASSPINS:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->mutex_get_tas_spins(dbenv, &value);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_tas_spins")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
case ENVGETTIMEOUT:
result = env_GetTimeout(interp, objc, objv, dbenv);
break;
case ENVGETTMPDIR:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_tmp_dir(dbenv, &strval);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_tmp_dir")) == TCL_OK)
res = NewStringObj(strval, strlen(strval));
break;
case ENVGETTXMAX:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_tx_max(dbenv, &value);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_tx_max")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
case ENVGETTXTIMESTAMP:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_tx_timestamp(dbenv, &timeval);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_tx_timestamp")) == TCL_OK)
res = Tcl_NewLongObj((long)timeval);
break;
case ENVGETVERBOSE:
result = env_GetVerbose(interp, objc, objv, dbenv);
break;
case ENVRESIZECACHE:
if ((result = Tcl_ListObjGetElements(
interp, objv[2], &listobjc, &listobjv)) != TCL_OK)
break;
if (objc != 3 || listobjc != 2) {
Tcl_WrongNumArgs(interp, 2, objv,
"?-resize_cache {gbytes bytes}?");
result = TCL_ERROR;
break;
}
result = _GetUInt32(interp, listobjv[0], &gbytes);
if (result != TCL_OK)
break;
result = _GetUInt32(interp, listobjv[1], &bytes);
if (result != TCL_OK)
break;
ret = dbenv->set_cachesize(dbenv, gbytes, bytes, 0);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"resize_cache");
break;
case ENVSETDATADIR:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "pfx");
return (TCL_ERROR);
}
strarg = Tcl_GetStringFromObj(objv[2], NULL);
ret = dbenv->set_data_dir(dbenv, strarg);
return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env set data dir"));
case ENVTXN:
result = tcl_Txn(interp, objc, objv, dbenv, envip);
break;
case ENVTXNCKP:
result = tcl_TxnCheckpoint(interp, objc, objv, dbenv);
break;
}
if (result == TCL_OK && res)
Tcl_SetObjResult(interp, res);
return (result);
}
int
tcl_EnvRemove(interp, objc, objv, dbenv, envip)
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
DB_ENV *dbenv;
DBTCL_INFO *envip;
{
static const char *envremopts[] = {
#ifdef CONFIG_TEST
"-overwrite",
"-server",
#endif
"-data_dir",
"-encryptaes",
"-encryptany",
"-force",
"-home",
"-log_dir",
"-tmp_dir",
"-use_environ",
"-use_environ_root",
NULL
};
enum envremopts {
#ifdef CONFIG_TEST
ENVREM_OVERWRITE,
ENVREM_SERVER,
#endif
ENVREM_DATADIR,
ENVREM_ENCRYPT_AES,
ENVREM_ENCRYPT_ANY,
ENVREM_FORCE,
ENVREM_HOME,
ENVREM_LOGDIR,
ENVREM_TMPDIR,
ENVREM_USE_ENVIRON,
ENVREM_USE_ENVIRON_ROOT
};
DB_ENV *e;
u_int32_t cflag, enc_flag, flag, forceflag, sflag;
int i, optindex, result, ret;
char *datadir, *home, *logdir, *passwd, *server, *tmpdir;
result = TCL_OK;
cflag = flag = forceflag = sflag = 0;
home = NULL;
passwd = NULL;
datadir = logdir = tmpdir = NULL;
server = NULL;
enc_flag = 0;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 2, objv, "?args?");
return (TCL_ERROR);
}
i = 2;
while (i < objc) {
if (Tcl_GetIndexFromObj(interp, objv[i], envremopts, "option",
TCL_EXACT, &optindex) != TCL_OK) {
result = IS_HELP(objv[i]);
goto error;
}
i++;
switch ((enum envremopts)optindex) {
#ifdef CONFIG_TEST
case ENVREM_SERVER:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
"?-server name?");
result = TCL_ERROR;
break;
}
server = Tcl_GetStringFromObj(objv[i++], NULL);
cflag = DB_RPCCLIENT;
break;
#endif
case ENVREM_ENCRYPT_AES:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
"?-encryptaes passwd?");
result = TCL_ERROR;
break;
}
passwd = Tcl_GetStringFromObj(objv[i++], NULL);
enc_flag = DB_ENCRYPT_AES;
break;
case ENVREM_ENCRYPT_ANY:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
"?-encryptany passwd?");
result = TCL_ERROR;
break;
}
passwd = Tcl_GetStringFromObj(objv[i++], NULL);
enc_flag = 0;
break;
case ENVREM_FORCE:
forceflag |= DB_FORCE;
break;
case ENVREM_HOME:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
"?-home dir?");
result = TCL_ERROR;
break;
}
home = Tcl_GetStringFromObj(objv[i++], NULL);
break;
#ifdef CONFIG_TEST
case ENVREM_OVERWRITE:
sflag |= DB_OVERWRITE;
break;
#endif
case ENVREM_USE_ENVIRON:
flag |= DB_USE_ENVIRON;
break;
case ENVREM_USE_ENVIRON_ROOT:
flag |= DB_USE_ENVIRON_ROOT;
break;
case ENVREM_DATADIR:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
"-data_dir dir");
result = TCL_ERROR;
break;
}
datadir = Tcl_GetStringFromObj(objv[i++], NULL);
break;
case ENVREM_LOGDIR:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
"-log_dir dir");
result = TCL_ERROR;
break;
}
logdir = Tcl_GetStringFromObj(objv[i++], NULL);
break;
case ENVREM_TMPDIR:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
"-tmp_dir dir");
result = TCL_ERROR;
break;
}
tmpdir = Tcl_GetStringFromObj(objv[i++], NULL);
break;
}
if (result != TCL_OK)
goto error;
}
if (dbenv == NULL) {
if ((ret = db_env_create(&e, cflag)) != 0) {
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"db_env_create");
goto error;
}
if (server != NULL) {
_debug_check();
ret = e->set_rpc_server(e, NULL, server, 0, 0, 0);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_rpc_server");
if (result != TCL_OK)
goto error;
}
if (datadir != NULL) {
_debug_check();
ret = e->set_data_dir(e, datadir);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_data_dir");
if (result != TCL_OK)
goto error;
}
if (logdir != NULL) {
_debug_check();
ret = e->set_lg_dir(e, logdir);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_log_dir");
if (result != TCL_OK)
goto error;
}
if (tmpdir != NULL) {
_debug_check();
ret = e->set_tmp_dir(e, tmpdir);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_tmp_dir");
if (result != TCL_OK)
goto error;
}
if (passwd != NULL) {
ret = e->set_encrypt(e, passwd, enc_flag);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_encrypt");
}
if (sflag != 0 && (ret = e->set_flags(e, sflag, 1)) != 0) {
_debug_check();
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_flags");
if (result != TCL_OK)
goto error;
}
e->set_errpfx(e, "EnvRemove");
e->set_errcall(e, _ErrorFunc);
} else {
_EnvInfoDelete(interp, envip);
envip = NULL;
e = dbenv;
}
flag |= forceflag;
_debug_check();
ret = e->remove(e, home, flag);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env remove");
error:
return (result);
}
static void
_EnvInfoDelete(interp, envip)
Tcl_Interp *interp;
DBTCL_INFO *envip;
{
DBTCL_INFO *nextp, *p;
for (p = LIST_FIRST(&__db_infohead); p != NULL; p = nextp) {
if (p->i_parent == envip) {
switch (p->i_type) {
case I_TXN:
_TxnInfoDelete(interp, p);
break;
case I_MP:
_MpInfoDelete(interp, p);
break;
case I_DB:
case I_DBC:
case I_ENV:
case I_LOCK:
case I_LOGC:
case I_NDBM:
case I_PG:
case I_SEQ:
Tcl_SetResult(interp,
"_EnvInfoDelete: bad info type",
TCL_STATIC);
break;
}
nextp = LIST_NEXT(p, entries);
(void)Tcl_DeleteCommand(interp, p->i_name);
_DeleteInfo(p);
} else
nextp = LIST_NEXT(p, entries);
}
(void)Tcl_DeleteCommand(interp, envip->i_name);
_DeleteInfo(envip);
}
#ifdef CONFIG_TEST
int
tcl_EnvIdReset(interp, objc, objv, dbenv)
Tcl_Interp *interp;
int objc;
Tcl_Obj * CONST* objv;
DB_ENV *dbenv;
{
static const char *idwhich[] = {
"-encrypt",
NULL
};
enum idwhich {
IDENCRYPT
};
int enc, i, result, ret;
u_int32_t flags;
char *file;
result = TCL_OK;
flags = 0;
i = 2;
Tcl_SetResult(interp, "0", TCL_STATIC);
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv, "?-encrypt? filename");
return (TCL_ERROR);
} else if (objc > 3) {
if (Tcl_GetIndexFromObj(interp, objv[2], idwhich, "option",
TCL_EXACT, &enc) != TCL_OK)
return (IS_HELP(objv[2]));
switch ((enum idwhich)enc) {
case IDENCRYPT:
flags |= DB_ENCRYPT;
break;
}
i = 3;
}
file = Tcl_GetStringFromObj(objv[i], NULL);
ret = dbenv->fileid_reset(dbenv, file, flags);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "fileid reset");
return (result);
}
int
tcl_EnvLsnReset(interp, objc, objv, dbenv)
Tcl_Interp *interp;
int objc;
Tcl_Obj * CONST* objv;
DB_ENV *dbenv;
{
static const char *lsnwhich[] = {
"-encrypt",
NULL
};
enum lsnwhich {
IDENCRYPT
};
int enc, i, result, ret;
u_int32_t flags;
char *file;
result = TCL_OK;
flags = 0;
i = 2;
Tcl_SetResult(interp, "0", TCL_STATIC);
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv, "?-encrypt? filename");
return (TCL_ERROR);
} else if (objc > 3) {
if (Tcl_GetIndexFromObj(interp, objv[2], lsnwhich, "option",
TCL_EXACT, &enc) != TCL_OK)
return (IS_HELP(objv[2]));
switch ((enum lsnwhich)enc) {
case IDENCRYPT:
flags |= DB_ENCRYPT;
break;
}
i = 3;
}
file = Tcl_GetStringFromObj(objv[i], NULL);
ret = dbenv->lsn_reset(dbenv, file, flags);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "lsn reset");
return (result);
}
int
tcl_EnvVerbose(interp, dbenv, which, onoff)
Tcl_Interp *interp;
DB_ENV *dbenv;
Tcl_Obj *which;
Tcl_Obj *onoff;
{
static const char *verbwhich[] = {
"deadlock",
"fileops",
"fileops_all",
"recovery",
"register",
"rep",
"wait",
NULL
};
enum verbwhich {
ENVVERB_DEADLOCK,
ENVVERB_FILEOPS,
ENVVERB_FILEOPS_ALL,
ENVVERB_RECOVERY,
ENVVERB_REGISTER,
ENVVERB_REPLICATION,
ENVVERB_WAITSFOR
};
static const char *verbonoff[] = {
"off",
"on",
NULL
};
enum verbonoff {
ENVVERB_OFF,
ENVVERB_ON
};
int on, optindex, ret;
u_int32_t wh;
if (Tcl_GetIndexFromObj(interp, which, verbwhich, "option",
TCL_EXACT, &optindex) != TCL_OK)
return (IS_HELP(which));
switch ((enum verbwhich)optindex) {
case ENVVERB_DEADLOCK:
wh = DB_VERB_DEADLOCK;
break;
case ENVVERB_FILEOPS:
wh = DB_VERB_FILEOPS;
break;
case ENVVERB_FILEOPS_ALL:
wh = DB_VERB_FILEOPS_ALL;
break;
case ENVVERB_RECOVERY:
wh = DB_VERB_RECOVERY;
break;
case ENVVERB_REGISTER:
wh = DB_VERB_REGISTER;
break;
case ENVVERB_REPLICATION:
wh = DB_VERB_REPLICATION;
break;
case ENVVERB_WAITSFOR:
wh = DB_VERB_WAITSFOR;
break;
default:
return (TCL_ERROR);
}
if (Tcl_GetIndexFromObj(interp, onoff, verbonoff, "option",
TCL_EXACT, &optindex) != TCL_OK)
return (IS_HELP(onoff));
switch ((enum verbonoff)optindex) {
case ENVVERB_OFF:
on = 0;
break;
case ENVVERB_ON:
on = 1;
break;
default:
return (TCL_ERROR);
}
ret = dbenv->set_verbose(dbenv, wh, on);
return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env set verbose"));
}
#endif
#ifdef CONFIG_TEST
int
tcl_EnvAttr(interp, objc, objv, dbenv)
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
DB_ENV *dbenv;
{
int result;
Tcl_Obj *myobj, *retlist;
result = TCL_OK;
if (objc > 2) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return (TCL_ERROR);
}
retlist = Tcl_NewListObj(0, NULL);
myobj = NewStringObj("-home", strlen("-home"));
if ((result = Tcl_ListObjAppendElement(interp,
retlist, myobj)) != TCL_OK)
goto err;
myobj = NewStringObj(dbenv->db_home, strlen(dbenv->db_home));
if ((result = Tcl_ListObjAppendElement(interp,
retlist, myobj)) != TCL_OK)
goto err;
if (CDB_LOCKING(dbenv)) {
myobj = NewStringObj("-cdb", strlen("-cdb"));
if ((result = Tcl_ListObjAppendElement(interp,
retlist, myobj)) != TCL_OK)
goto err;
}
if (CRYPTO_ON(dbenv)) {
myobj = NewStringObj("-crypto", strlen("-crypto"));
if ((result = Tcl_ListObjAppendElement(interp,
retlist, myobj)) != TCL_OK)
goto err;
}
if (LOCKING_ON(dbenv)) {
myobj = NewStringObj("-lock", strlen("-lock"));
if ((result = Tcl_ListObjAppendElement(interp,
retlist, myobj)) != TCL_OK)
goto err;
}
if (LOGGING_ON(dbenv)) {
myobj = NewStringObj("-log", strlen("-log"));
if ((result = Tcl_ListObjAppendElement(interp,
retlist, myobj)) != TCL_OK)
goto err;
}
if (MPOOL_ON(dbenv)) {
myobj = NewStringObj("-mpool", strlen("-mpool"));
if ((result = Tcl_ListObjAppendElement(interp,
retlist, myobj)) != TCL_OK)
goto err;
}
if (RPC_ON(dbenv)) {
myobj = NewStringObj("-rpc", strlen("-rpc"));
if ((result = Tcl_ListObjAppendElement(interp,
retlist, myobj)) != TCL_OK)
goto err;
}
if (REP_ON(dbenv)) {
myobj = NewStringObj("-rep", strlen("-rep"));
if ((result = Tcl_ListObjAppendElement(interp,
retlist, myobj)) != TCL_OK)
goto err;
}
if (TXN_ON(dbenv)) {
myobj = NewStringObj("-txn", strlen("-txn"));
if ((result = Tcl_ListObjAppendElement(interp,
retlist, myobj)) != TCL_OK)
goto err;
}
Tcl_SetObjResult(interp, retlist);
err:
return (result);
}
int
tcl_EventNotify(interp, dbenv, eobj, ip)
Tcl_Interp *interp;
DB_ENV *dbenv;
Tcl_Obj *eobj;
DBTCL_INFO *ip;
{
int ret;
if (ip->i_event != NULL)
Tcl_DecrRefCount(ip->i_event);
ip->i_event = eobj;
Tcl_IncrRefCount(ip->i_event);
_debug_check();
ret = dbenv->set_event_notify(dbenv, _EventFunc);
return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env event"));
}
int
tcl_EnvSetFlags(interp, dbenv, which, onoff)
Tcl_Interp *interp;
DB_ENV *dbenv;
Tcl_Obj *which;
Tcl_Obj *onoff;
{
static const char *sfwhich[] = {
"-auto_commit",
"-direct_db",
"-direct_log",
"-dsync_log",
"-log_inmemory",
"-log_remove",
"-multiversion",
"-nolock",
"-nommap",
"-nopanic",
"-nosync",
"-overwrite",
"-panic",
"-wrnosync",
NULL
};
enum sfwhich {
ENVSF_AUTOCOMMIT,
ENVSF_DIRECTDB,
ENVSF_DIRECTLOG,
ENVSF_DSYNCLOG,
ENVSF_LOG_INMEMORY,
ENVSF_LOG_REMOVE,
ENVSF_MULTIVERSION,
ENVSF_NOLOCK,
ENVSF_NOMMAP,
ENVSF_NOPANIC,
ENVSF_NOSYNC,
ENVSF_OVERWRITE,
ENVSF_PANIC,
ENVSF_WRNOSYNC
};
static const char *sfonoff[] = {
"off",
"on",
NULL
};
enum sfonoff {
ENVSF_OFF,
ENVSF_ON
};
int on, optindex, ret;
u_int32_t wh;
if (Tcl_GetIndexFromObj(interp, which, sfwhich, "option",
TCL_EXACT, &optindex) != TCL_OK)
return (IS_HELP(which));
switch ((enum sfwhich)optindex) {
case ENVSF_AUTOCOMMIT:
wh = DB_AUTO_COMMIT;
break;
case ENVSF_DIRECTDB:
wh = DB_DIRECT_DB;
break;
case ENVSF_DIRECTLOG:
wh = DB_DIRECT_LOG;
break;
case ENVSF_DSYNCLOG:
wh = DB_DSYNC_LOG;
break;
case ENVSF_LOG_INMEMORY:
wh = DB_LOG_INMEMORY;
break;
case ENVSF_LOG_REMOVE:
wh = DB_LOG_AUTOREMOVE;
break;
case ENVSF_MULTIVERSION:
wh = DB_MULTIVERSION;
break;
case ENVSF_NOLOCK:
wh = DB_NOLOCKING;
break;
case ENVSF_NOMMAP:
wh = DB_NOMMAP;
break;
case ENVSF_NOSYNC:
wh = DB_TXN_NOSYNC;
break;
case ENVSF_NOPANIC:
wh = DB_NOPANIC;
break;
case ENVSF_PANIC:
wh = DB_PANIC_ENVIRONMENT;
break;
case ENVSF_OVERWRITE:
wh = DB_OVERWRITE;
break;
case ENVSF_WRNOSYNC:
wh = DB_TXN_WRITE_NOSYNC;
break;
default:
return (TCL_ERROR);
}
if (Tcl_GetIndexFromObj(interp, onoff, sfonoff, "option",
TCL_EXACT, &optindex) != TCL_OK)
return (IS_HELP(onoff));
switch ((enum sfonoff)optindex) {
case ENVSF_OFF:
on = 0;
break;
case ENVSF_ON:
on = 1;
break;
default:
return (TCL_ERROR);
}
ret = dbenv->set_flags(dbenv, wh, on);
return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env set flags"));
}
int
tcl_EnvTest(interp, objc, objv, dbenv)
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
DB_ENV *dbenv;
{
static const char *envtestcmd[] = {
"abort",
"check",
"copy",
"force",
NULL
};
enum envtestcmd {
ENVTEST_ABORT,
ENVTEST_CHECK,
ENVTEST_COPY,
ENVTEST_FORCE
};
static const char *envtestat[] = {
"electinit",
"electvote1",
"none",
"predestroy",
"preopen",
"postdestroy",
"postlog",
"postlogmeta",
"postopen",
"postsync",
"recycle",
"subdb_lock",
NULL
};
enum envtestat {
ENVTEST_ELECTINIT,
ENVTEST_ELECTVOTE1,
ENVTEST_NONE,
ENVTEST_PREDESTROY,
ENVTEST_PREOPEN,
ENVTEST_POSTDESTROY,
ENVTEST_POSTLOG,
ENVTEST_POSTLOGMETA,
ENVTEST_POSTOPEN,
ENVTEST_POSTSYNC,
ENVTEST_RECYCLE,
ENVTEST_SUBDB_LOCKS
};
static const char *envtestforce[] = {
"noarchive_timeout",
NULL
};
enum envtestforce {
ENVTEST_NOARCHIVE_TIMEOUT
};
int *loc, optindex, result, testval;
result = TCL_OK;
loc = NULL;
if (objc != 4) {
Tcl_WrongNumArgs(interp,
2, objv, "abort|check|copy|force <args>");
return (TCL_ERROR);
}
if (Tcl_GetIndexFromObj(interp, objv[2], envtestcmd, "command",
TCL_EXACT, &optindex) != TCL_OK) {
result = IS_HELP(objv[2]);
return (result);
}
switch ((enum envtestcmd)optindex) {
case ENVTEST_ABORT:
loc = &dbenv->test_abort;
break;
case ENVTEST_CHECK:
loc = &dbenv->test_check;
if (Tcl_GetIntFromObj(interp, objv[3], &testval) != TCL_OK) {
result = IS_HELP(objv[3]);
return (result);
}
goto done;
case ENVTEST_COPY:
loc = &dbenv->test_copy;
break;
case ENVTEST_FORCE:
if (Tcl_GetIndexFromObj(interp, objv[3], envtestforce, "arg",
TCL_EXACT, &optindex) != TCL_OK) {
result = IS_HELP(objv[3]);
return (result);
}
DB_ASSERT(dbenv,
(enum envtestforce)optindex == ENVTEST_NOARCHIVE_TIMEOUT);
return (tcl_RepNoarchiveTimeout(interp, dbenv));
default:
Tcl_SetResult(interp, "Illegal store location", TCL_STATIC);
return (TCL_ERROR);
}
if (Tcl_GetIndexFromObj(interp, objv[3], envtestat, "location",
TCL_EXACT, &optindex) != TCL_OK) {
result = IS_HELP(objv[3]);
return (result);
}
switch ((enum envtestat)optindex) {
case ENVTEST_ELECTINIT:
DB_ASSERT(dbenv, loc == &dbenv->test_abort);
testval = DB_TEST_ELECTINIT;
break;
case ENVTEST_ELECTVOTE1:
DB_ASSERT(dbenv, loc == &dbenv->test_abort);
testval = DB_TEST_ELECTVOTE1;
break;
case ENVTEST_NONE:
testval = 0;
break;
case ENVTEST_PREOPEN:
testval = DB_TEST_PREOPEN;
break;
case ENVTEST_PREDESTROY:
testval = DB_TEST_PREDESTROY;
break;
case ENVTEST_POSTLOG:
testval = DB_TEST_POSTLOG;
break;
case ENVTEST_POSTLOGMETA:
testval = DB_TEST_POSTLOGMETA;
break;
case ENVTEST_POSTOPEN:
testval = DB_TEST_POSTOPEN;
break;
case ENVTEST_POSTDESTROY:
testval = DB_TEST_POSTDESTROY;
break;
case ENVTEST_POSTSYNC:
testval = DB_TEST_POSTSYNC;
break;
case ENVTEST_RECYCLE:
DB_ASSERT(dbenv, loc == &dbenv->test_copy);
testval = DB_TEST_RECYCLE;
break;
case ENVTEST_SUBDB_LOCKS:
DB_ASSERT(dbenv, loc == &dbenv->test_abort);
testval = DB_TEST_SUBDB_LOCKS;
break;
default:
Tcl_SetResult(interp, "Illegal test location", TCL_STATIC);
return (TCL_ERROR);
}
done:
*loc = testval;
Tcl_SetResult(interp, "0", TCL_STATIC);
return (result);
}
#endif
static int
env_DbRemove(interp, objc, objv, dbenv)
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
DB_ENV *dbenv;
{
static const char *envdbrem[] = {
"-auto_commit",
"-txn",
"--",
NULL
};
enum envdbrem {
TCL_EDBREM_COMMIT,
TCL_EDBREM_TXN,
TCL_EDBREM_ENDARG
};
DB_TXN *txn;
u_int32_t flag;
int endarg, i, optindex, result, ret, subdblen;
u_char *subdbtmp;
char *arg, *db, *subdb, msg[MSG_SIZE];
txn = NULL;
result = TCL_OK;
subdbtmp = NULL;
db = subdb = NULL;
endarg = 0;
flag = 0;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 2, objv, "?args? filename ?database?");
return (TCL_ERROR);
}
i = 2;
while (i < objc) {
if (Tcl_GetIndexFromObj(interp, objv[i], envdbrem,
"option", TCL_EXACT, &optindex) != TCL_OK) {
arg = Tcl_GetStringFromObj(objv[i], NULL);
if (arg[0] == '-') {
result = IS_HELP(objv[i]);
goto error;
} else
Tcl_ResetResult(interp);
break;
}
i++;
switch ((enum envdbrem)optindex) {
case TCL_EDBREM_COMMIT:
flag |= DB_AUTO_COMMIT;
break;
case TCL_EDBREM_TXN:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
result = TCL_ERROR;
break;
}
arg = Tcl_GetStringFromObj(objv[i++], NULL);
txn = NAME_TO_TXN(arg);
if (txn == NULL) {
snprintf(msg, MSG_SIZE,
"env dbremove: Invalid txn %s\n", arg);
Tcl_SetResult(interp, msg, TCL_VOLATILE);
return (TCL_ERROR);
}
break;
case TCL_EDBREM_ENDARG:
endarg = 1;
break;
}
if (result != TCL_OK)
goto error;
if (endarg)
break;
}
if (result != TCL_OK)
goto error;
if ((i != (objc - 1)) || (i != (objc - 2))) {
db = Tcl_GetStringFromObj(objv[i++], NULL);
if (strcmp(db, "") == 0)
db = NULL;
if (i != objc) {
subdbtmp =
Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
if ((ret = __os_malloc(
dbenv, (size_t)subdblen + 1, &subdb)) != 0) {
Tcl_SetResult(interp,
db_strerror(ret), TCL_STATIC);
return (0);
}
memcpy(subdb, subdbtmp, (size_t)subdblen);
subdb[subdblen] = '\0';
}
} else {
Tcl_WrongNumArgs(interp, 2, objv, "?args? filename ?database?");
result = TCL_ERROR;
goto error;
}
ret = dbenv->dbremove(dbenv, txn, db, subdb, flag);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env dbremove");
error:
if (subdb)
__os_free(dbenv, subdb);
return (result);
}
static int
env_DbRename(interp, objc, objv, dbenv)
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
DB_ENV *dbenv;
{
static const char *envdbmv[] = {
"-auto_commit",
"-txn",
"--",
NULL
};
enum envdbmv {
TCL_EDBMV_COMMIT,
TCL_EDBMV_TXN,
TCL_EDBMV_ENDARG
};
DB_TXN *txn;
u_int32_t flag;
int endarg, i, newlen, optindex, result, ret, subdblen;
u_char *subdbtmp;
char *arg, *db, *newname, *subdb, msg[MSG_SIZE];
txn = NULL;
result = TCL_OK;
subdbtmp = NULL;
db = newname = subdb = NULL;
endarg = 0;
flag = 0;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 3, objv,
"?args? filename ?database? ?newname?");
return (TCL_ERROR);
}
i = 2;
while (i < objc) {
if (Tcl_GetIndexFromObj(interp, objv[i], envdbmv,
"option", TCL_EXACT, &optindex) != TCL_OK) {
arg = Tcl_GetStringFromObj(objv[i], NULL);
if (arg[0] == '-') {
result = IS_HELP(objv[i]);
goto error;
} else
Tcl_ResetResult(interp);
break;
}
i++;
switch ((enum envdbmv)optindex) {
case TCL_EDBMV_COMMIT:
flag |= DB_AUTO_COMMIT;
break;
case TCL_EDBMV_TXN:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
result = TCL_ERROR;
break;
}
arg = Tcl_GetStringFromObj(objv[i++], NULL);
txn = NAME_TO_TXN(arg);
if (txn == NULL) {
snprintf(msg, MSG_SIZE,
"env dbrename: Invalid txn %s\n", arg);
Tcl_SetResult(interp, msg, TCL_VOLATILE);
return (TCL_ERROR);
}
break;
case TCL_EDBMV_ENDARG:
endarg = 1;
break;
}
if (result != TCL_OK)
goto error;
if (endarg)
break;
}
if (result != TCL_OK)
goto error;
if ((i != (objc - 2)) || (i != (objc - 3))) {
db = Tcl_GetStringFromObj(objv[i++], NULL);
if (strcmp(db, "") == 0)
db = NULL;
if (i == objc - 2) {
subdbtmp =
Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
if ((ret = __os_malloc(
dbenv, (size_t)subdblen + 1, &subdb)) != 0) {
Tcl_SetResult(interp,
db_strerror(ret), TCL_STATIC);
return (0);
}
memcpy(subdb, subdbtmp, (size_t)subdblen);
subdb[subdblen] = '\0';
}
subdbtmp = Tcl_GetByteArrayFromObj(objv[i++], &newlen);
if ((ret = __os_malloc(
dbenv, (size_t)newlen + 1, &newname)) != 0) {
Tcl_SetResult(interp,
db_strerror(ret), TCL_STATIC);
return (0);
}
memcpy(newname, subdbtmp, (size_t)newlen);
newname[newlen] = '\0';
} else {
Tcl_WrongNumArgs(interp, 3, objv,
"?args? filename ?database? ?newname?");
result = TCL_ERROR;
goto error;
}
ret = dbenv->dbrename(dbenv, txn, db, subdb, newname, flag);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env dbrename");
error:
if (subdb)
__os_free(dbenv, subdb);
if (newname)
__os_free(dbenv, newname);
return (result);
}
static int
env_GetFlags(interp, objc, objv, dbenv)
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
DB_ENV *dbenv;
{
int i, ret, result;
u_int32_t flags;
char buf[512];
Tcl_Obj *res;
static const struct {
u_int32_t flag;
char *arg;
} open_flags[] = {
{ DB_AUTO_COMMIT, "-auto_commit" },
{ DB_CDB_ALLDB, "-cdb_alldb" },
{ DB_DIRECT_DB, "-direct_db" },
{ DB_DIRECT_LOG, "-direct_log" },
{ DB_DSYNC_LOG, "-dsync_log" },
{ DB_LOG_AUTOREMOVE, "-log_remove" },
{ DB_LOG_INMEMORY, "-log_inmemory" },
{ DB_MULTIVERSION, "-multiversion" },
{ DB_NOLOCKING, "-nolock" },
{ DB_NOMMAP, "-nommap" },
{ DB_NOPANIC, "-nopanic" },
{ DB_OVERWRITE, "-overwrite" },
{ DB_PANIC_ENVIRONMENT, "-panic" },
{ DB_REGION_INIT, "-region_init" },
{ DB_TXN_NOSYNC, "-nosync" },
{ DB_TXN_WRITE_NOSYNC, "-wrnosync" },
{ DB_YIELDCPU, "-yield" },
{ 0, NULL }
};
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_flags(dbenv, &flags);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_flags")) == TCL_OK) {
buf[0] = '\0';
for (i = 0; open_flags[i].flag != 0; i++)
if (LF_ISSET(open_flags[i].flag)) {
if (strlen(buf) > 0)
(void)strncat(buf, " ", sizeof(buf));
(void)strncat(
buf, open_flags[i].arg, sizeof(buf));
}
res = NewStringObj(buf, strlen(buf));
Tcl_SetObjResult(interp, res);
}
return (result);
}
static int
env_GetOpenFlag(interp, objc, objv, dbenv)
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
DB_ENV *dbenv;
{
int i, ret, result;
u_int32_t flags;
char buf[512];
Tcl_Obj *res;
static const struct {
u_int32_t flag;
char *arg;
} open_flags[] = {
{ DB_CREATE, "-create" },
{ DB_INIT_CDB, "-cdb" },
{ DB_INIT_LOCK, "-lock" },
{ DB_INIT_LOG, "-log" },
{ DB_INIT_MPOOL, "-mpool" },
{ DB_INIT_TXN, "-txn" },
{ DB_LOCKDOWN, "-lockdown" },
{ DB_PRIVATE, "-private" },
{ DB_RECOVER, "-recover" },
{ DB_RECOVER_FATAL, "-recover_fatal" },
{ DB_REGISTER, "-register" },
{ DB_SYSTEM_MEM, "-system_mem" },
{ DB_THREAD, "-thread" },
{ DB_USE_ENVIRON, "-use_environ" },
{ DB_USE_ENVIRON_ROOT, "-use_environ_root" },
{ 0, NULL }
};
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_open_flags(dbenv, &flags);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_open_flags")) == TCL_OK) {
buf[0] = '\0';
for (i = 0; open_flags[i].flag != 0; i++)
if (LF_ISSET(open_flags[i].flag)) {
if (strlen(buf) > 0)
(void)strncat(buf, " ", sizeof(buf));
(void)strncat(
buf, open_flags[i].arg, sizeof(buf));
}
res = NewStringObj(buf, strlen(buf));
Tcl_SetObjResult(interp, res);
}
return (result);
}
int
tcl_EnvGetEncryptFlags(interp, objc, objv, dbenv)
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
DB_ENV *dbenv;
{
int i, ret, result;
u_int32_t flags;
char buf[512];
Tcl_Obj *res;
static const struct {
u_int32_t flag;
char *arg;
} encrypt_flags[] = {
{ DB_ENCRYPT_AES, "-encryptaes" },
{ 0, NULL }
};
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_encrypt_flags(dbenv, &flags);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_encrypt_flags")) == TCL_OK) {
buf[0] = '\0';
for (i = 0; encrypt_flags[i].flag != 0; i++)
if (LF_ISSET(encrypt_flags[i].flag)) {
if (strlen(buf) > 0)
(void)strncat(buf, " ", sizeof(buf));
(void)strncat(
buf, encrypt_flags[i].arg, sizeof(buf));
}
res = NewStringObj(buf, strlen(buf));
Tcl_SetObjResult(interp, res);
}
return (result);
}
static int
env_GetLockDetect(interp, objc, objv, dbenv)
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
DB_ENV *dbenv;
{
int i, ret, result;
u_int32_t lk_detect;
const char *answer;
Tcl_Obj *res;
static const struct {
u_int32_t flag;
char *name;
} lk_detect_returns[] = {
{ DB_LOCK_DEFAULT, "default" },
{ DB_LOCK_EXPIRE, "expire" },
{ DB_LOCK_MAXLOCKS, "maxlocks" },
{ DB_LOCK_MAXWRITE, "maxwrite" },
{ DB_LOCK_MINLOCKS, "minlocks" },
{ DB_LOCK_MINWRITE, "minwrite" },
{ DB_LOCK_OLDEST, "oldest" },
{ DB_LOCK_RANDOM, "random" },
{ DB_LOCK_YOUNGEST, "youngest" },
{ 0, NULL }
};
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
ret = dbenv->get_lk_detect(dbenv, &lk_detect);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_lk_detect")) == TCL_OK) {
answer = "unknown";
for (i = 0; lk_detect_returns[i].flag != 0; i++)
if (lk_detect == lk_detect_returns[i].flag)
answer = lk_detect_returns[i].name;
res = NewStringObj(answer, strlen(answer));
Tcl_SetObjResult(interp, res);
}
return (result);
}
static int
env_GetTimeout(interp, objc, objv, dbenv)
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
DB_ENV *dbenv;
{
static const struct {
u_int32_t flag;
char *arg;
} timeout_flags[] = {
{ DB_SET_TXN_TIMEOUT, "txn" },
{ DB_SET_LOCK_TIMEOUT, "lock" },
{ 0, NULL }
};
Tcl_Obj *res;
db_timeout_t timeout;
u_int32_t which;
int i, ret, result;
const char *arg;
COMPQUIET(timeout, 0);
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
arg = Tcl_GetStringFromObj(objv[2], NULL);
which = 0;
for (i = 0; timeout_flags[i].flag != 0; i++)
if (strcmp(arg, timeout_flags[i].arg) == 0)
which = timeout_flags[i].flag;
if (which == 0) {
ret = EINVAL;
goto err;
}
ret = dbenv->get_timeout(dbenv, &timeout, which);
err: if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_timeout")) == TCL_OK) {
res = Tcl_NewLongObj((long)timeout);
Tcl_SetObjResult(interp, res);
}
return (result);
}
static int
env_GetVerbose(interp, objc, objv, dbenv)
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
DB_ENV *dbenv;
{
static const struct {
u_int32_t flag;
char *arg;
} verbose_flags[] = {
{ DB_VERB_DEADLOCK, "deadlock" },
{ DB_VERB_FILEOPS, "fileops" },
{ DB_VERB_FILEOPS_ALL, "fileops_all" },
{ DB_VERB_RECOVERY, "recovery" },
{ DB_VERB_REGISTER, "register" },
{ DB_VERB_REPLICATION, "rep" },
{ DB_VERB_WAITSFOR, "wait" },
{ 0, NULL }
};
Tcl_Obj *res;
u_int32_t which;
int i, onoff, ret, result;
const char *arg, *answer;
COMPQUIET(onoff, 0);
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
arg = Tcl_GetStringFromObj(objv[2], NULL);
which = 0;
for (i = 0; verbose_flags[i].flag != 0; i++)
if (strcmp(arg, verbose_flags[i].arg) == 0)
which = verbose_flags[i].flag;
if (which == 0) {
ret = EINVAL;
goto err;
}
ret = dbenv->get_verbose(dbenv, which, &onoff);
err: if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_verbose")) == 0) {
answer = onoff ? "on" : "off";
res = NewStringObj(answer, strlen(answer));
Tcl_SetObjResult(interp, res);
}
return (result);
}
void
tcl_EnvSetErrfile(interp, dbenv, ip, errf)
Tcl_Interp *interp;
DB_ENV *dbenv;
DBTCL_INFO *ip;
char *errf;
{
COMPQUIET(interp, NULL);
if (ip->i_err != NULL && ip->i_err != stdout &&
ip->i_err != stderr)
(void)fclose(ip->i_err);
if (strcmp(errf, "/dev/stdout") == 0)
ip->i_err = stdout;
else if (strcmp(errf, "/dev/stderr") == 0)
ip->i_err = stderr;
else
ip->i_err = fopen(errf, "a");
if (ip->i_err != NULL)
dbenv->set_errfile(dbenv, ip->i_err);
}
int
tcl_EnvSetErrpfx(interp, dbenv, ip, pfx)
Tcl_Interp *interp;
DB_ENV *dbenv;
DBTCL_INFO *ip;
char *pfx;
{
int result, ret;
result = TCL_OK;
Tcl_SetResult(interp, "0", TCL_STATIC);
if (ip->i_errpfx != NULL)
__os_free(dbenv, ip->i_errpfx);
if ((ret = __os_strdup(dbenv, pfx, &ip->i_errpfx)) != 0) {
result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "__os_strdup");
ip->i_errpfx = NULL;
}
if (ip->i_errpfx != NULL)
dbenv->set_errpfx(dbenv, ip->i_errpfx);
return (result);
}