Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

tcl_env.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1999-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: tcl_env.c,v 12.15 2005/11/02 20:21:37 bostic Exp $
00008  */
00009 
00010 #include "db_config.h"
00011 
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 
00015 #include <stdlib.h>
00016 #include <string.h>
00017 #include <tcl.h>
00018 #endif
00019 
00020 #include "db_int.h"
00021 #include "dbinc/db_shash.h"
00022 #include "dbinc/lock.h"
00023 #include "dbinc/txn.h"
00024 #include "dbinc/tcl_db.h"
00025 
00026 /*
00027  * Prototypes for procedures defined later in this file:
00028  */
00029 static void _EnvInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
00030 static int  env_DbRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
00031 static int  env_DbRename __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
00032 static int  env_GetFlags __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
00033 static int  env_GetOpenFlag
00034                 __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
00035 static int  env_GetLockDetect
00036                 __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
00037 static int  env_GetTimeout __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
00038 static int  env_GetVerbose __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
00039 
00040 /*
00041  * PUBLIC: int env_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
00042  *
00043  * env_Cmd --
00044  *      Implements the "env" command.
00045  */
00046 int
00047 env_Cmd(clientData, interp, objc, objv)
00048         ClientData clientData;          /* Env handle */
00049         Tcl_Interp *interp;             /* Interpreter */
00050         int objc;                       /* How many arguments? */
00051         Tcl_Obj *CONST objv[];          /* The argument objects */
00052 {
00053         static const char *envcmds[] = {
00054 #ifdef CONFIG_TEST
00055                 "attributes",
00056                 "errfile",
00057                 "errpfx",
00058                 "id_reset",
00059                 "lock_detect",
00060                 "lock_id",
00061                 "lock_id_free",
00062                 "lock_id_set",
00063                 "lock_get",
00064                 "lock_stat",
00065                 "lock_timeout",
00066                 "lock_vec",
00067                 "log_archive",
00068                 "log_compare",
00069                 "log_cursor",
00070                 "log_file",
00071                 "log_flush",
00072                 "log_get",
00073                 "log_put",
00074                 "log_stat",
00075                 "lsn_reset",
00076                 "mpool",
00077                 "mpool_stat",
00078                 "mpool_sync",
00079                 "mpool_trickle",
00080                 "rep_config",
00081                 "rep_elect",
00082                 "rep_flush",
00083                 "rep_get_config",
00084                 "rep_limit",
00085                 "rep_process_message",
00086                 "rep_request",
00087                 "rep_start",
00088                 "rep_stat",
00089                 "rep_sync",
00090                 "rep_transport",
00091                 "rpcid",
00092                 "set_flags",
00093                 "test",
00094                 "txn_id_set",
00095                 "txn_recover",
00096                 "txn_stat",
00097                 "txn_timeout",
00098                 "verbose",
00099 #endif
00100                 "close",
00101                 "dbremove",
00102                 "dbrename",
00103                 "get_cachesize",
00104                 "get_data_dirs",
00105                 "get_encrypt_flags",
00106                 "get_errpfx",
00107                 "get_flags",
00108                 "get_home",
00109                 "get_lg_bsize",
00110                 "get_lg_dir",
00111                 "get_lg_filemode",
00112                 "get_lg_max",
00113                 "get_lg_regionmax",
00114                 "get_lk_detect",
00115                 "get_lk_max_lockers",
00116                 "get_lk_max_locks",
00117                 "get_lk_max_objects",
00118                 "get_mp_max_openfd",
00119                 "get_mp_max_write",
00120                 "get_mp_mmapsize",
00121                 "get_open_flags",
00122                 "get_rep_limit",
00123                 "get_shm_key",
00124                 "get_tas_spins",
00125                 "get_timeout",
00126                 "get_tmp_dir",
00127                 "get_tx_max",
00128                 "get_tx_timestamp",
00129                 "get_verbose",
00130                 "txn",
00131                 "txn_checkpoint",
00132                 NULL
00133         };
00134         enum envcmds {
00135 #ifdef CONFIG_TEST
00136                 ENVATTR,
00137                 ENVERRFILE,
00138                 ENVERRPFX,
00139                 ENVIDRESET,
00140                 ENVLKDETECT,
00141                 ENVLKID,
00142                 ENVLKFREEID,
00143                 ENVLKSETID,
00144                 ENVLKGET,
00145                 ENVLKSTAT,
00146                 ENVLKTIMEOUT,
00147                 ENVLKVEC,
00148                 ENVLOGARCH,
00149                 ENVLOGCMP,
00150                 ENVLOGCURSOR,
00151                 ENVLOGFILE,
00152                 ENVLOGFLUSH,
00153                 ENVLOGGET,
00154                 ENVLOGPUT,
00155                 ENVLOGSTAT,
00156                 ENVLSNRESET,
00157                 ENVMP,
00158                 ENVMPSTAT,
00159                 ENVMPSYNC,
00160                 ENVTRICKLE,
00161                 ENVREPCONFIG,
00162                 ENVREPELECT,
00163                 ENVREPFLUSH,
00164                 ENVREPGETCONFIG,
00165                 ENVREPLIMIT,
00166                 ENVREPPROCMESS,
00167                 ENVREPREQUEST,
00168                 ENVREPSTART,
00169                 ENVREPSTAT,
00170                 ENVREPSYNC,
00171                 ENVREPTRANSPORT,
00172                 ENVRPCID,
00173                 ENVSETFLAGS,
00174                 ENVTEST,
00175                 ENVTXNSETID,
00176                 ENVTXNRECOVER,
00177                 ENVTXNSTAT,
00178                 ENVTXNTIMEOUT,
00179                 ENVVERB,
00180 #endif
00181                 ENVCLOSE,
00182                 ENVDBREMOVE,
00183                 ENVDBRENAME,
00184                 ENVGETCACHESIZE,
00185                 ENVGETDATADIRS,
00186                 ENVGETENCRYPTFLAGS,
00187                 ENVGETERRPFX,
00188                 ENVGETFLAGS,
00189                 ENVGETHOME,
00190                 ENVGETLGBSIZE,
00191                 ENVGETLGDIR,
00192                 ENVGETLGFILEMODE,
00193                 ENVGETLGMAX,
00194                 ENVGETLGREGIONMAX,
00195                 ENVGETLKDETECT,
00196                 ENVGETLKMAXLOCKERS,
00197                 ENVGETLKMAXLOCKS,
00198                 ENVGETLKMAXOBJECTS,
00199                 ENVGETMPMAXOPENFD,
00200                 ENVGETMPMAXWRITE,
00201                 ENVGETMPMMAPSIZE,
00202                 ENVGETOPENFLAG,
00203                 ENVGETREPLIMIT,
00204                 ENVGETSHMKEY,
00205                 ENVGETTASSPINS,
00206                 ENVGETTIMEOUT,
00207                 ENVGETTMPDIR,
00208                 ENVGETTXMAX,
00209                 ENVGETTXTIMESTAMP,
00210                 ENVGETVERBOSE,
00211                 ENVTXN,
00212                 ENVTXNCKP
00213         };
00214         DBTCL_INFO *envip;
00215         DB_ENV *dbenv;
00216         Tcl_Obj *myobjv[3], *res;
00217         char newname[MSG_SIZE];
00218         int cmdindex, i, intvalue1, intvalue2, ncache, result, ret;
00219         u_int32_t bytes, gbytes, value;
00220         size_t size;
00221         long shm_key;
00222         time_t timeval;
00223         const char *strval, **dirs;
00224 #ifdef CONFIG_TEST
00225         DBTCL_INFO *logcip;
00226         DB_LOGC *logc;
00227         Tcl_Obj **repobjv;
00228         u_int32_t lockid;
00229         long newval, otherval;
00230         int repobjc;
00231         char *strarg;
00232 #endif
00233 
00234         Tcl_ResetResult(interp);
00235         dbenv = (DB_ENV *)clientData;
00236         envip = _PtrToInfo((void *)dbenv);
00237         result = TCL_OK;
00238         memset(newname, 0, MSG_SIZE);
00239 
00240         if (objc <= 1) {
00241                 Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs");
00242                 return (TCL_ERROR);
00243         }
00244         if (dbenv == NULL) {
00245                 Tcl_SetResult(interp, "NULL env pointer", TCL_STATIC);
00246                 return (TCL_ERROR);
00247         }
00248         if (envip == NULL) {
00249                 Tcl_SetResult(interp, "NULL env info pointer", TCL_STATIC);
00250                 return (TCL_ERROR);
00251         }
00252 
00253         /*
00254          * Get the command name index from the object based on the berkdbcmds
00255          * defined above.
00256          */
00257         if (Tcl_GetIndexFromObj(interp, objv[1], envcmds, "command",
00258             TCL_EXACT, &cmdindex) != TCL_OK)
00259                 return (IS_HELP(objv[1]));
00260         res = NULL;
00261         switch ((enum envcmds)cmdindex) {
00262 #ifdef CONFIG_TEST
00263         case ENVIDRESET:
00264                 result = tcl_EnvIdReset(interp, objc, objv, dbenv);
00265                 break;
00266         case ENVLSNRESET:
00267                 result = tcl_EnvLsnReset(interp, objc, objv, dbenv);
00268                 break;
00269         case ENVLKDETECT:
00270                 result = tcl_LockDetect(interp, objc, objv, dbenv);
00271                 break;
00272         case ENVLKSTAT:
00273                 result = tcl_LockStat(interp, objc, objv, dbenv);
00274                 break;
00275         case ENVLKTIMEOUT:
00276                 result = tcl_LockTimeout(interp, objc, objv, dbenv);
00277                 break;
00278         case ENVLKID:
00279                 /*
00280                  * No args for this.  Error if there are some.
00281                  */
00282                 if (objc > 2) {
00283                         Tcl_WrongNumArgs(interp, 2, objv, NULL);
00284                         return (TCL_ERROR);
00285                 }
00286                 _debug_check();
00287                 ret = dbenv->lock_id(dbenv, &lockid);
00288                 result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00289                     "lock_id");
00290                 if (result == TCL_OK)
00291                         res = Tcl_NewWideIntObj((Tcl_WideInt)lockid);
00292                 break;
00293         case ENVLKFREEID:
00294                 if (objc != 3) {
00295                         Tcl_WrongNumArgs(interp, 3, objv, NULL);
00296                         return (TCL_ERROR);
00297                 }
00298                 result = Tcl_GetLongFromObj(interp, objv[2], &newval);
00299                 if (result != TCL_OK)
00300                         return (result);
00301                 ret = dbenv->lock_id_free(dbenv, (u_int32_t)newval);
00302                 result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00303                     "lock id_free");
00304                 break;
00305         case ENVLKSETID:
00306                 if (objc != 4) {
00307                         Tcl_WrongNumArgs(interp, 4, objv, "current max");
00308                         return (TCL_ERROR);
00309                 }
00310                 result = Tcl_GetLongFromObj(interp, objv[2], &newval);
00311                 if (result != TCL_OK)
00312                         return (result);
00313                 result = Tcl_GetLongFromObj(interp, objv[3], &otherval);
00314                 if (result != TCL_OK)
00315                         return (result);
00316                 ret = __lock_id_set(dbenv,
00317                     (u_int32_t)newval, (u_int32_t)otherval);
00318                 result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00319                     "lock id_free");
00320                 break;
00321         case ENVLKGET:
00322                 result = tcl_LockGet(interp, objc, objv, dbenv);
00323                 break;
00324         case ENVLKVEC:
00325                 result = tcl_LockVec(interp, objc, objv, dbenv);
00326                 break;
00327         case ENVLOGARCH:
00328                 result = tcl_LogArchive(interp, objc, objv, dbenv);
00329                 break;
00330         case ENVLOGCMP:
00331                 result = tcl_LogCompare(interp, objc, objv);
00332                 break;
00333         case ENVLOGCURSOR:
00334                 snprintf(newname, sizeof(newname),
00335                     "%s.logc%d", envip->i_name, envip->i_envlogcid);
00336                 logcip = _NewInfo(interp, NULL, newname, I_LOGC);
00337                 if (logcip != NULL) {
00338                         ret = dbenv->log_cursor(dbenv, &logc, 0);
00339                         if (ret == 0) {
00340                                 result = TCL_OK;
00341                                 envip->i_envlogcid++;
00342                                 /*
00343                                  * We do NOT want to set i_parent to
00344                                  * envip here because log cursors are
00345                                  * not "tied" to the env.  That is, they
00346                                  * are NOT closed if the env is closed.
00347                                  */
00348                                 (void)Tcl_CreateObjCommand(interp, newname,
00349                                     (Tcl_ObjCmdProc *)logc_Cmd,
00350                                     (ClientData)logc, NULL);
00351                                 res = NewStringObj(newname, strlen(newname));
00352                                 _SetInfoData(logcip, logc);
00353                         } else {
00354                                 _DeleteInfo(logcip);
00355                                 result = _ErrorSetup(interp, ret, "log cursor");
00356                         }
00357                 } else {
00358                         Tcl_SetResult(interp,
00359                             "Could not set up info", TCL_STATIC);
00360                         result = TCL_ERROR;
00361                 }
00362                 break;
00363         case ENVLOGFILE:
00364                 result = tcl_LogFile(interp, objc, objv, dbenv);
00365                 break;
00366         case ENVLOGFLUSH:
00367                 result = tcl_LogFlush(interp, objc, objv, dbenv);
00368                 break;
00369         case ENVLOGGET:
00370                 result = tcl_LogGet(interp, objc, objv, dbenv);
00371                 break;
00372         case ENVLOGPUT:
00373                 result = tcl_LogPut(interp, objc, objv, dbenv);
00374                 break;
00375         case ENVLOGSTAT:
00376                 result = tcl_LogStat(interp, objc, objv, dbenv);
00377                 break;
00378         case ENVMPSTAT:
00379                 result = tcl_MpStat(interp, objc, objv, dbenv);
00380                 break;
00381         case ENVMPSYNC:
00382                 result = tcl_MpSync(interp, objc, objv, dbenv);
00383                 break;
00384         case ENVTRICKLE:
00385                 result = tcl_MpTrickle(interp, objc, objv, dbenv);
00386                 break;
00387         case ENVMP:
00388                 result = tcl_Mp(interp, objc, objv, dbenv, envip);
00389                 break;
00390         case ENVREPCONFIG:
00391                 /*
00392                  * Two args for this.  Error if different.
00393                  */
00394                 if (objc != 3) {
00395                         Tcl_WrongNumArgs(interp, 2, objv, NULL);
00396                         return (TCL_ERROR);
00397                 }
00398                 result = tcl_RepConfig(interp, dbenv, objv[2]);
00399                 break;
00400         case ENVREPELECT:
00401                 result = tcl_RepElect(interp, objc, objv, dbenv);
00402                 break;
00403         case ENVREPFLUSH:
00404                 result = tcl_RepFlush(interp, objc, objv, dbenv);
00405                 break;
00406         case ENVREPGETCONFIG:
00407                 /*
00408                  * Two args for this.  Error if different.
00409                  */
00410                 if (objc != 3) {
00411                         Tcl_WrongNumArgs(interp, 2, objv, NULL);
00412                         return (TCL_ERROR);
00413                 }
00414                 result = tcl_RepGetConfig(interp, dbenv, objv[2]);
00415                 break;
00416         case ENVREPLIMIT:
00417                 result = tcl_RepLimit(interp, objc, objv, dbenv);
00418                 break;
00419         case ENVREPPROCMESS:
00420                 result = tcl_RepProcessMessage(interp, objc, objv, dbenv);
00421                 break;
00422         case ENVREPREQUEST:
00423                 result = tcl_RepRequest(interp, objc, objv, dbenv);
00424                 break;
00425         case ENVREPSTART:
00426                 result = tcl_RepStart(interp, objc, objv, dbenv);
00427                 break;
00428         case ENVREPSTAT:
00429                 result = tcl_RepStat(interp, objc, objv, dbenv);
00430                 break;
00431         case ENVREPSYNC:
00432                 result = tcl_RepSync(interp, objc, objv, dbenv);
00433                 break;
00434         case ENVREPTRANSPORT:
00435                 if (objc != 3) {
00436                         Tcl_WrongNumArgs(interp, 2, objv, NULL);
00437                         return (TCL_ERROR);
00438                 }
00439                 result = Tcl_ListObjGetElements(interp, objv[2],
00440                     &repobjc, &repobjv);
00441                 if (result == TCL_OK)
00442                         result = tcl_RepTransport(interp,
00443                             repobjc, repobjv, dbenv, envip);
00444                 break;
00445         case ENVRPCID:
00446                 /*
00447                  * No args for this.  Error if there are some.
00448                  */
00449                 if (objc > 2) {
00450                         Tcl_WrongNumArgs(interp, 2, objv, NULL);
00451                         return (TCL_ERROR);
00452                 }
00453                 /*
00454                  * !!! Retrieve the client ID from the dbp handle directly.
00455                  * This is for testing purposes only.  It is dbp-private data.
00456                  */
00457                 res = Tcl_NewLongObj((long)dbenv->cl_id);
00458                 break;
00459         case ENVTXNSETID:
00460                 if (objc != 4) {
00461                         Tcl_WrongNumArgs(interp, 4, objv, "current max");
00462                         return (TCL_ERROR);
00463                 }
00464                 result = Tcl_GetLongFromObj(interp, objv[2], &newval);
00465                 if (result != TCL_OK)
00466                         return (result);
00467                 result = Tcl_GetLongFromObj(interp, objv[3], &otherval);
00468                 if (result != TCL_OK)
00469                         return (result);
00470                 ret = __txn_id_set(dbenv,
00471                     (u_int32_t)newval, (u_int32_t)otherval);
00472                 result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00473                     "txn setid");
00474                 break;
00475         case ENVTXNRECOVER:
00476                 result = tcl_TxnRecover(interp, objc, objv, dbenv, envip);
00477                 break;
00478         case ENVTXNSTAT:
00479                 result = tcl_TxnStat(interp, objc, objv, dbenv);
00480                 break;
00481         case ENVTXNTIMEOUT:
00482                 result = tcl_TxnTimeout(interp, objc, objv, dbenv);
00483                 break;
00484         case ENVATTR:
00485                 result = tcl_EnvAttr(interp, objc, objv, dbenv);
00486                 break;
00487         case ENVERRFILE:
00488                 /*
00489                  * One args for this.  Error if different.
00490                  */
00491                 if (objc != 3) {
00492                         Tcl_WrongNumArgs(interp, 2, objv, "errfile");
00493                         return (TCL_ERROR);
00494                 }
00495                 strarg = Tcl_GetStringFromObj(objv[2], NULL);
00496                 tcl_EnvSetErrfile(interp, dbenv, envip, strarg);
00497                 result = TCL_OK;
00498                 break;
00499         case ENVERRPFX:
00500                 /*
00501                  * One args for this.  Error if different.
00502                  */
00503                 if (objc != 3) {
00504                         Tcl_WrongNumArgs(interp, 2, objv, "pfx");
00505                         return (TCL_ERROR);
00506                 }
00507                 strarg = Tcl_GetStringFromObj(objv[2], NULL);
00508                 result = tcl_EnvSetErrpfx(interp, dbenv, envip, strarg);
00509                 break;
00510         case ENVSETFLAGS:
00511                 /*
00512                  * Two args for this.  Error if different.
00513                  */
00514                 if (objc != 4) {
00515                         Tcl_WrongNumArgs(interp, 2, objv, "which on|off");
00516                         return (TCL_ERROR);
00517                 }
00518                 result = tcl_EnvSetFlags(interp, dbenv, objv[2], objv[3]);
00519                 break;
00520         case ENVTEST:
00521                 result = tcl_EnvTest(interp, objc, objv, dbenv);
00522                 break;
00523         case ENVVERB:
00524                 /*
00525                  * Two args for this.  Error if different.
00526                  */
00527                 if (objc != 4) {
00528                         Tcl_WrongNumArgs(interp, 2, objv, NULL);
00529                         return (TCL_ERROR);
00530                 }
00531                 result = tcl_EnvVerbose(interp, dbenv, objv[2], objv[3]);
00532                 break;
00533 #endif
00534         case ENVCLOSE:
00535                 /*
00536                  * No args for this.  Error if there are some.
00537                  */
00538                 if (objc > 2) {
00539                         Tcl_WrongNumArgs(interp, 2, objv, NULL);
00540                         return (TCL_ERROR);
00541                 }
00542                 /*
00543                  * Any transactions will be aborted, and an mpools
00544                  * closed automatically.  We must delete any txn
00545                  * and mp widgets we have here too for this env.
00546                  * NOTE: envip is freed when we come back from
00547                  * this function.  Set it to NULL to make sure no
00548                  * one tries to use it later.
00549                  */
00550                 _debug_check();
00551                 ret = dbenv->close(dbenv, 0);
00552                 result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00553                     "env close");
00554                 _EnvInfoDelete(interp, envip);
00555                 envip = NULL;
00556                 break;
00557         case ENVDBREMOVE:
00558                 result = env_DbRemove(interp, objc, objv, dbenv);
00559                 break;
00560         case ENVDBRENAME:
00561                 result = env_DbRename(interp, objc, objv, dbenv);
00562                 break;
00563         case ENVGETCACHESIZE:
00564                 if (objc != 2) {
00565                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00566                         return (TCL_ERROR);
00567                 }
00568                 ret = dbenv->get_cachesize(dbenv, &gbytes, &bytes, &ncache);
00569                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00570                     "env get_cachesize")) == TCL_OK) {
00571                         myobjv[0] = Tcl_NewLongObj((long)gbytes);
00572                         myobjv[1] = Tcl_NewLongObj((long)bytes);
00573                         myobjv[2] = Tcl_NewLongObj((long)ncache);
00574                         res = Tcl_NewListObj(3, myobjv);
00575                 }
00576                 break;
00577         case ENVGETDATADIRS:
00578                 if (objc != 2) {
00579                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00580                         return (TCL_ERROR);
00581                 }
00582                 ret = dbenv->get_data_dirs(dbenv, &dirs);
00583                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00584                     "env get_data_dirs")) == TCL_OK) {
00585                         res = Tcl_NewListObj(0, NULL);
00586                         for (i = 0; result == TCL_OK && dirs[i] != NULL; i++)
00587                                 result = Tcl_ListObjAppendElement(interp, res,
00588                                     NewStringObj(dirs[i], strlen(dirs[i])));
00589                 }
00590                 break;
00591         case ENVGETENCRYPTFLAGS:
00592                 result = tcl_EnvGetEncryptFlags(interp, objc, objv, dbenv);
00593                 break;
00594         case ENVGETERRPFX:
00595                 if (objc != 2) {
00596                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00597                         return (TCL_ERROR);
00598                 }
00599                 dbenv->get_errpfx(dbenv, &strval);
00600                 res = NewStringObj(strval, strlen(strval));
00601                 break;
00602         case ENVGETFLAGS:
00603                 result = env_GetFlags(interp, objc, objv, dbenv);
00604                 break;
00605         case ENVGETHOME:
00606                 if (objc != 2) {
00607                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00608                         return (TCL_ERROR);
00609                 }
00610                 ret = dbenv->get_home(dbenv, &strval);
00611                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00612                     "env get_home")) == TCL_OK)
00613                         res = NewStringObj(strval, strlen(strval));
00614                 break;
00615         case ENVGETLGBSIZE:
00616                 if (objc != 2) {
00617                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00618                         return (TCL_ERROR);
00619                 }
00620                 ret = dbenv->get_lg_bsize(dbenv, &value);
00621                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00622                     "env get_lg_bsize")) == TCL_OK)
00623                         res = Tcl_NewLongObj((long)value);
00624                 break;
00625         case ENVGETLGDIR:
00626                 if (objc != 2) {
00627                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00628                         return (TCL_ERROR);
00629                 }
00630                 ret = dbenv->get_lg_dir(dbenv, &strval);
00631                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00632                     "env get_lg_dir")) == TCL_OK)
00633                         res = NewStringObj(strval, strlen(strval));
00634                 break;
00635         case ENVGETLGFILEMODE:
00636                 if (objc != 2) {
00637                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00638                         return (TCL_ERROR);
00639                 }
00640                 ret = dbenv->get_lg_filemode(dbenv, &intvalue1);
00641                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00642                     "env get_lg_filemode")) == TCL_OK)
00643                         res = Tcl_NewLongObj((long)intvalue1);
00644                 break;
00645         case ENVGETLGMAX:
00646                 if (objc != 2) {
00647                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00648                         return (TCL_ERROR);
00649                 }
00650                 ret = dbenv->get_lg_max(dbenv, &value);
00651                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00652                     "env get_lg_max")) == TCL_OK)
00653                         res = Tcl_NewLongObj((long)value);
00654                 break;
00655         case ENVGETLGREGIONMAX:
00656                 if (objc != 2) {
00657                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00658                         return (TCL_ERROR);
00659                 }
00660                 ret = dbenv->get_lg_regionmax(dbenv, &value);
00661                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00662                     "env get_lg_regionmax")) == TCL_OK)
00663                         res = Tcl_NewLongObj((long)value);
00664                 break;
00665         case ENVGETLKDETECT:
00666                 result = env_GetLockDetect(interp, objc, objv, dbenv);
00667                 break;
00668         case ENVGETLKMAXLOCKERS:
00669                 if (objc != 2) {
00670                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00671                         return (TCL_ERROR);
00672                 }
00673                 ret = dbenv->get_lk_max_lockers(dbenv, &value);
00674                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00675                     "env get_lk_max_lockers")) == TCL_OK)
00676                         res = Tcl_NewLongObj((long)value);
00677                 break;
00678         case ENVGETLKMAXLOCKS:
00679                 if (objc != 2) {
00680                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00681                         return (TCL_ERROR);
00682                 }
00683                 ret = dbenv->get_lk_max_locks(dbenv, &value);
00684                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00685                     "env get_lk_max_locks")) == TCL_OK)
00686                         res = Tcl_NewLongObj((long)value);
00687                 break;
00688         case ENVGETLKMAXOBJECTS:
00689                 if (objc != 2) {
00690                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00691                         return (TCL_ERROR);
00692                 }
00693                 ret = dbenv->get_lk_max_objects(dbenv, &value);
00694                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00695                     "env get_lk_max_objects")) == TCL_OK)
00696                         res = Tcl_NewLongObj((long)value);
00697                 break;
00698         case ENVGETMPMAXOPENFD:
00699                 if (objc != 2) {
00700                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00701                         return (TCL_ERROR);
00702                 }
00703                 ret = dbenv->get_mp_max_openfd(dbenv, &intvalue1);
00704                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00705                     "env get_mp_max_openfd")) == TCL_OK)
00706                         res = Tcl_NewIntObj(intvalue1);
00707                 break;
00708         case ENVGETMPMAXWRITE:
00709                 if (objc != 2) {
00710                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00711                         return (TCL_ERROR);
00712                 }
00713                 ret = dbenv->get_mp_max_write(dbenv, &intvalue1, &intvalue2);
00714                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00715                     "env get_mp_max_write")) == TCL_OK) {
00716                         myobjv[0] = Tcl_NewIntObj(intvalue1);
00717                         myobjv[1] = Tcl_NewIntObj(intvalue2);
00718                         res = Tcl_NewListObj(2, myobjv);
00719                 }
00720                 break;
00721         case ENVGETMPMMAPSIZE:
00722                 if (objc != 2) {
00723                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00724                         return (TCL_ERROR);
00725                 }
00726                 ret = dbenv->get_mp_mmapsize(dbenv, &size);
00727                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00728                     "env get_mp_mmapsize")) == TCL_OK)
00729                         res = Tcl_NewLongObj((long)size);
00730                 break;
00731         case ENVGETOPENFLAG:
00732                 result = env_GetOpenFlag(interp, objc, objv, dbenv);
00733                 break;
00734         case ENVGETREPLIMIT:
00735                 if (objc != 2) {
00736                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00737                         return (TCL_ERROR);
00738                 }
00739                 ret = dbenv->get_rep_limit(dbenv, &gbytes, &bytes);
00740                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00741                     "env get_rep_limit")) == TCL_OK) {
00742                         myobjv[0] = Tcl_NewLongObj((long)gbytes);
00743                         myobjv[1] = Tcl_NewLongObj((long)bytes);
00744                         res = Tcl_NewListObj(2, myobjv);
00745                 }
00746                 break;
00747         case ENVGETSHMKEY:
00748                 if (objc != 2) {
00749                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00750                         return (TCL_ERROR);
00751                 }
00752                 ret = dbenv->get_shm_key(dbenv, &shm_key);
00753                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00754                     "env shm_key")) == TCL_OK)
00755                         res = Tcl_NewLongObj(shm_key);
00756                 break;
00757         case ENVGETTASSPINS:
00758                 if (objc != 2) {
00759                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00760                         return (TCL_ERROR);
00761                 }
00762                 ret = dbenv->mutex_get_tas_spins(dbenv, &value);
00763                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00764                     "env get_tas_spins")) == TCL_OK)
00765                         res = Tcl_NewLongObj((long)value);
00766                 break;
00767         case ENVGETTIMEOUT:
00768                 result = env_GetTimeout(interp, objc, objv, dbenv);
00769                 break;
00770         case ENVGETTMPDIR:
00771                 if (objc != 2) {
00772                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00773                         return (TCL_ERROR);
00774                 }
00775                 ret = dbenv->get_tmp_dir(dbenv, &strval);
00776                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00777                     "env get_tmp_dir")) == TCL_OK)
00778                         res = NewStringObj(strval, strlen(strval));
00779                 break;
00780         case ENVGETTXMAX:
00781                 if (objc != 2) {
00782                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00783                         return (TCL_ERROR);
00784                 }
00785                 ret = dbenv->get_tx_max(dbenv, &value);
00786                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00787                     "env get_tx_max")) == TCL_OK)
00788                         res = Tcl_NewLongObj((long)value);
00789                 break;
00790         case ENVGETTXTIMESTAMP:
00791                 if (objc != 2) {
00792                         Tcl_WrongNumArgs(interp, 1, objv, NULL);
00793                         return (TCL_ERROR);
00794                 }
00795                 ret = dbenv->get_tx_timestamp(dbenv, &timeval);
00796                 if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00797                     "env get_tx_timestamp")) == TCL_OK)
00798                         res = Tcl_NewLongObj((long)timeval);
00799                 break;
00800         case ENVGETVERBOSE:
00801                 result = env_GetVerbose(interp, objc, objv, dbenv);
00802                 break;
00803         case ENVTXN:
00804                 result = tcl_Txn(interp, objc, objv, dbenv, envip);
00805                 break;
00806         case ENVTXNCKP:
00807                 result = tcl_TxnCheckpoint(interp, objc, objv, dbenv);
00808                 break;
00809         }
00810         /*
00811          * Only set result if we have a res.  Otherwise, lower
00812          * functions have already done so.
00813          */
00814         if (result == TCL_OK && res)
00815                 Tcl_SetObjResult(interp, res);
00816         return (result);
00817 }
00818 
00819 /*
00820  * PUBLIC: int tcl_EnvRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
00821  * PUBLIC:      DB_ENV *, DBTCL_INFO *));
00822  *
00823  * tcl_EnvRemove --
00824  */
00825 int
00826 tcl_EnvRemove(interp, objc, objv, dbenv, envip)
00827         Tcl_Interp *interp;             /* Interpreter */
00828         int objc;                       /* How many arguments? */
00829         Tcl_Obj *CONST objv[];          /* The argument objects */
00830         DB_ENV *dbenv;                  /* Env pointer */
00831         DBTCL_INFO *envip;              /* Info pointer */
00832 {
00833         static const char *envremopts[] = {
00834 #ifdef CONFIG_TEST
00835                 "-overwrite",
00836                 "-server",
00837 #endif
00838                 "-data_dir",
00839                 "-encryptaes",
00840                 "-encryptany",
00841                 "-force",
00842                 "-home",
00843                 "-log_dir",
00844                 "-tmp_dir",
00845                 "-use_environ",
00846                 "-use_environ_root",
00847                 NULL
00848         };
00849         enum envremopts {
00850 #ifdef CONFIG_TEST
00851                 ENVREM_OVERWRITE,
00852                 ENVREM_SERVER,
00853 #endif
00854                 ENVREM_DATADIR,
00855                 ENVREM_ENCRYPT_AES,
00856                 ENVREM_ENCRYPT_ANY,
00857                 ENVREM_FORCE,
00858                 ENVREM_HOME,
00859                 ENVREM_LOGDIR,
00860                 ENVREM_TMPDIR,
00861                 ENVREM_USE_ENVIRON,
00862                 ENVREM_USE_ENVIRON_ROOT
00863         };
00864         DB_ENV *e;
00865         u_int32_t cflag, enc_flag, flag, forceflag, sflag;
00866         int i, optindex, result, ret;
00867         char *datadir, *home, *logdir, *passwd, *server, *tmpdir;
00868 
00869         result = TCL_OK;
00870         cflag = flag = forceflag = sflag = 0;
00871         home = NULL;
00872         passwd = NULL;
00873         datadir = logdir = tmpdir = NULL;
00874         server = NULL;
00875         enc_flag = 0;
00876 
00877         if (objc < 2) {
00878                 Tcl_WrongNumArgs(interp, 2, objv, "?args?");
00879                 return (TCL_ERROR);
00880         }
00881 
00882         i = 2;
00883         while (i < objc) {
00884                 if (Tcl_GetIndexFromObj(interp, objv[i], envremopts, "option",
00885                     TCL_EXACT, &optindex) != TCL_OK) {
00886                         result = IS_HELP(objv[i]);
00887                         goto error;
00888                 }
00889                 i++;
00890                 switch ((enum envremopts)optindex) {
00891 #ifdef CONFIG_TEST
00892                 case ENVREM_SERVER:
00893                         /* Make sure we have an arg to check against! */
00894                         if (i >= objc) {
00895                                 Tcl_WrongNumArgs(interp, 2, objv,
00896                                     "?-server name?");
00897                                 result = TCL_ERROR;
00898                                 break;
00899                         }
00900                         server = Tcl_GetStringFromObj(objv[i++], NULL);
00901                         cflag = DB_RPCCLIENT;
00902                         break;
00903 #endif
00904                 case ENVREM_ENCRYPT_AES:
00905                         /* Make sure we have an arg to check against! */
00906                         if (i >= objc) {
00907                                 Tcl_WrongNumArgs(interp, 2, objv,
00908                                     "?-encryptaes passwd?");
00909                                 result = TCL_ERROR;
00910                                 break;
00911                         }
00912                         passwd = Tcl_GetStringFromObj(objv[i++], NULL);
00913                         enc_flag = DB_ENCRYPT_AES;
00914                         break;
00915                 case ENVREM_ENCRYPT_ANY:
00916                         /* Make sure we have an arg to check against! */
00917                         if (i >= objc) {
00918                                 Tcl_WrongNumArgs(interp, 2, objv,
00919                                     "?-encryptany passwd?");
00920                                 result = TCL_ERROR;
00921                                 break;
00922                         }
00923                         passwd = Tcl_GetStringFromObj(objv[i++], NULL);
00924                         enc_flag = 0;
00925                         break;
00926                 case ENVREM_FORCE:
00927                         forceflag |= DB_FORCE;
00928                         break;
00929                 case ENVREM_HOME:
00930                         /* Make sure we have an arg to check against! */
00931                         if (i >= objc) {
00932                                 Tcl_WrongNumArgs(interp, 2, objv,
00933                                     "?-home dir?");
00934                                 result = TCL_ERROR;
00935                                 break;
00936                         }
00937                         home = Tcl_GetStringFromObj(objv[i++], NULL);
00938                         break;
00939 #ifdef CONFIG_TEST
00940                 case ENVREM_OVERWRITE:
00941                         sflag |= DB_OVERWRITE;
00942                         break;
00943 #endif
00944                 case ENVREM_USE_ENVIRON:
00945                         flag |= DB_USE_ENVIRON;
00946                         break;
00947                 case ENVREM_USE_ENVIRON_ROOT:
00948                         flag |= DB_USE_ENVIRON_ROOT;
00949                         break;
00950                 case ENVREM_DATADIR:
00951                         if (i >= objc) {
00952                                 Tcl_WrongNumArgs(interp, 2, objv,
00953                                     "-data_dir dir");
00954                                 result = TCL_ERROR;
00955                                 break;
00956                         }
00957                         datadir = Tcl_GetStringFromObj(objv[i++], NULL);
00958                         break;
00959                 case ENVREM_LOGDIR:
00960                         if (i >= objc) {
00961                                 Tcl_WrongNumArgs(interp, 2, objv,
00962                                     "-log_dir dir");
00963                                 result = TCL_ERROR;
00964                                 break;
00965                         }
00966                         logdir = Tcl_GetStringFromObj(objv[i++], NULL);
00967                         break;
00968                 case ENVREM_TMPDIR:
00969                         if (i >= objc) {
00970                                 Tcl_WrongNumArgs(interp, 2, objv,
00971                                     "-tmp_dir dir");
00972                                 result = TCL_ERROR;
00973                                 break;
00974                         }
00975                         tmpdir = Tcl_GetStringFromObj(objv[i++], NULL);
00976                         break;
00977                 }
00978                 /*
00979                  * If, at any time, parsing the args we get an error,
00980                  * bail out and return.
00981                  */
00982                 if (result != TCL_OK)
00983                         goto error;
00984         }
00985 
00986         /*
00987          * If dbenv is NULL, we don't have an open env and we need to open
00988          * one of the user.  Don't bother with the info stuff.
00989          */
00990         if (dbenv == NULL) {
00991                 if ((ret = db_env_create(&e, cflag)) != 0) {
00992                         result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
00993                             "db_env_create");
00994                         goto error;
00995                 }
00996                 if (server != NULL) {
00997                         _debug_check();
00998                         ret = e->set_rpc_server(e, NULL, server, 0, 0, 0);
00999                         result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
01000                             "set_rpc_server");
01001                         if (result != TCL_OK)
01002                                 goto error;
01003                 }
01004                 if (datadir != NULL) {
01005                         _debug_check();
01006                         ret = e->set_data_dir(e, datadir);
01007                         result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
01008                             "set_data_dir");
01009                         if (result != TCL_OK)
01010                                 goto error;
01011                 }
01012                 if (logdir != NULL) {
01013                         _debug_check();
01014                         ret = e->set_lg_dir(e, logdir);
01015                         result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
01016                             "set_log_dir");
01017                         if (result != TCL_OK)
01018                                 goto error;
01019                 }
01020                 if (tmpdir != NULL) {
01021                         _debug_check();
01022                         ret = e->set_tmp_dir(e, tmpdir);
01023                         result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
01024                             "set_tmp_dir");
01025                         if (result != TCL_OK)
01026                                 goto error;
01027                 }
01028                 if (passwd != NULL) {
01029                         ret = e->set_encrypt(e, passwd, enc_flag);
01030                         result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
01031                             "set_encrypt");
01032                 }
01033                 if (sflag != 0 && (ret = e->set_flags(e, sflag, 1)) != 0) {
01034                         _debug_check();
01035                         result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
01036                             "set_flags");
01037                         if (result != TCL_OK)
01038                                 goto error;
01039                 }
01040         } else {
01041                 /*
01042                  * We have to clean up any info associated with this env,
01043                  * regardless of the result of the remove so do it first.
01044                  * NOTE: envip is freed when we come back from this function.
01045                  */
01046                 _EnvInfoDelete(interp, envip);
01047                 envip = NULL;
01048                 e = dbenv;
01049         }
01050 
01051         flag |= forceflag;
01052         /*
01053          * When we get here we have parsed all the args.  Now remove
01054          * the environment.
01055          */
01056         _debug_check();
01057         ret = e->remove(e, home, flag);
01058         result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
01059             "env remove");
01060 error:
01061         return (result);
01062 }
01063 
01064 static void
01065 _EnvInfoDelete(interp, envip)
01066         Tcl_Interp *interp;             /* Tcl Interpreter */
01067         DBTCL_INFO *envip;              /* Info for env */
01068 {
01069         DBTCL_INFO *nextp, *p;
01070 
01071         /*
01072          * Before we can delete the environment info, we must close
01073          * any open subsystems in this env.  We will:
01074          * 1.  Abort any transactions (which aborts any nested txns).
01075          * 2.  Close any mpools (which will put any pages itself).
01076          * 3.  Put any locks and close log cursors.
01077          * 4.  Close the error file.
01078          */
01079         for (p = LIST_FIRST(&__db_infohead); p != NULL; p = nextp) {
01080                 /*
01081                  * Check if this info structure "belongs" to this
01082                  * env.  If so, remove its commands and info structure.
01083                  * We do not close/abort/whatever here, because we
01084                  * don't want to replicate DB behavior.
01085                  *
01086                  * NOTE:  Only those types that can nest need to be
01087                  * itemized in the switch below.  That is txns and mps.
01088                  * Other types like log cursors and locks will just
01089                  * get cleaned up here.
01090                  */
01091                 if (p->i_parent == envip) {
01092                         switch (p->i_type) {
01093                         case I_TXN:
01094                                 _TxnInfoDelete(interp, p);
01095                                 break;
01096                         case I_MP:
01097                                 _MpInfoDelete(interp, p);
01098                                 break;
01099                         case I_DB:
01100                         case I_DBC:
01101                         case I_ENV:
01102                         case I_LOCK:
01103                         case I_LOGC:
01104                         case I_NDBM:
01105                         case I_PG:
01106                         case I_SEQ:
01107                                 Tcl_SetResult(interp,
01108                                     "_EnvInfoDelete: bad info type",
01109                                     TCL_STATIC);
01110                                 break;
01111                         }
01112                         nextp = LIST_NEXT(p, entries);
01113                         (void)Tcl_DeleteCommand(interp, p->i_name);
01114                         _DeleteInfo(p);
01115                 } else
01116                         nextp = LIST_NEXT(p, entries);
01117         }
01118         (void)Tcl_DeleteCommand(interp, envip->i_name);
01119         _DeleteInfo(envip);
01120 }
01121 
01122 #ifdef CONFIG_TEST
01123 /*
01124  * PUBLIC: int tcl_EnvIdReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
01125  * PUBLIC:    DB_ENV *));
01126  *
01127  * tcl_EnvIdReset --
01128  *      Implements the ENV->fileid_reset command.
01129  */
01130 int
01131 tcl_EnvIdReset(interp, objc, objv, dbenv)
01132         Tcl_Interp *interp;             /* Interpreter */
01133         int objc;                       /* arg count */
01134         Tcl_Obj * CONST* objv;          /* args */
01135         DB_ENV *dbenv;                  /* Database pointer */
01136 {
01137         static const char *idwhich[] = {
01138                 "-encrypt",
01139                 NULL
01140         };
01141         enum idwhich {
01142                 IDENCRYPT
01143         };
01144         int enc, i, result, ret;
01145         u_int32_t flags;
01146         char *file;
01147 
01148         result = TCL_OK;
01149         flags = 0;
01150         i = 2;
01151         Tcl_SetResult(interp, "0", TCL_STATIC);
01152         if (objc < 3) {
01153                 Tcl_WrongNumArgs(interp, 2, objv, "?-encrypt? filename");
01154                 return (TCL_ERROR);
01155         } else if (objc > 3) {
01156                 /*
01157                  * If there is an arg, make sure it is the right one.
01158                  */
01159                 if (Tcl_GetIndexFromObj(interp, objv[2], idwhich, "option",
01160                     TCL_EXACT, &enc) != TCL_OK)
01161                         return (IS_HELP(objv[2]));
01162                 switch ((enum idwhich)enc) {
01163                 case IDENCRYPT:
01164                         flags |= DB_ENCRYPT;
01165                         break;
01166                 }
01167                 i = 3;
01168         }
01169         file = Tcl_GetStringFromObj(objv[i], NULL);
01170         ret = dbenv->fileid_reset(dbenv, file, flags);
01171         result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "fileid reset");
01172         return (result);
01173 }
01174 
01175 /*
01176  * PUBLIC: int tcl_EnvLsnReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
01177  * PUBLIC:    DB_ENV *));
01178  *
01179  * tcl_EnvLsnReset --
01180  *      Implements the ENV->lsn_reset command.
01181  */
01182 int
01183 tcl_EnvLsnReset(interp, objc, objv, dbenv)
01184         Tcl_Interp *interp;             /* Interpreter */
01185         int objc;                       /* arg count */
01186         Tcl_Obj * CONST* objv;          /* args */
01187         DB_ENV *dbenv;                  /* Database pointer */
01188 {
01189         static const char *lsnwhich[] = {
01190                 "-encrypt",
01191                 NULL
01192         };
01193         enum lsnwhich {
01194                 IDENCRYPT
01195         };
01196         int enc, i, result, ret;
01197         u_int32_t flags;
01198         char *file;
01199 
01200         result = TCL_OK;
01201         flags = 0;
01202         i = 2;
01203         Tcl_SetResult(interp, "0", TCL_STATIC);
01204         if (objc < 3) {
01205                 Tcl_WrongNumArgs(interp, 2, objv, "?-encrypt? filename");
01206                 return (TCL_ERROR);
01207         } else if (objc > 3) {
01208                 /*
01209                  * If there is an arg, make sure it is the right one.
01210                  */
01211                 if (Tcl_GetIndexFromObj(interp, objv[2], lsnwhich, "option",
01212                     TCL_EXACT, &enc) != TCL_OK)
01213                         return (IS_HELP(objv[2]));
01214 
01215                 switch ((enum lsnwhich)enc) {
01216                 case IDENCRYPT:
01217                         flags |= DB_ENCRYPT;
01218                         break;
01219                 }
01220                 i = 3;
01221         }
01222         file = Tcl_GetStringFromObj(objv[i], NULL);
01223         ret = dbenv->lsn_reset(dbenv, file, flags);
01224         result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "lsn reset");
01225         return (result);
01226 }
01227 
01228 /*
01229  * PUBLIC: int tcl_EnvVerbose __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *,
01230  * PUBLIC:    Tcl_Obj *));
01231  *
01232  * tcl_EnvVerbose --
01233  */
01234 int
01235 tcl_EnvVerbose(interp, dbenv, which, onoff)
01236         Tcl_Interp *interp;             /* Interpreter */
01237         DB_ENV *dbenv;                  /* Env pointer */
01238         Tcl_Obj *which;                 /* Which subsystem */
01239         Tcl_Obj *onoff;                 /* On or off */
01240 {
01241         static const char *verbwhich[] = {
01242                 "deadlock",
01243                 "recovery",
01244                 "register",
01245                 "rep",
01246                 "wait",
01247                 NULL
01248         };
01249         enum verbwhich {
01250                 ENVVERB_DEADLOCK,
01251                 ENVVERB_RECOVERY,
01252                 ENVVERB_REGISTER,
01253                 ENVVERB_REPLICATION,
01254                 ENVVERB_WAITSFOR
01255         };
01256         static const char *verbonoff[] = {
01257                 "off",
01258                 "on",
01259                 NULL
01260         };
01261         enum verbonoff {
01262                 ENVVERB_OFF,
01263                 ENVVERB_ON
01264         };
01265         int on, optindex, ret;
01266         u_int32_t wh;
01267 
01268         if (Tcl_GetIndexFromObj(interp, which, verbwhich, "option",
01269             TCL_EXACT, &optindex) != TCL_OK)
01270                 return (IS_HELP(which));
01271 
01272         switch ((enum verbwhich)optindex) {
01273         case ENVVERB_DEADLOCK:
01274                 wh = DB_VERB_DEADLOCK;
01275                 break;
01276         case ENVVERB_RECOVERY:
01277                 wh = DB_VERB_RECOVERY;
01278                 break;
01279         case ENVVERB_REGISTER:
01280                 wh = DB_VERB_REGISTER;
01281                 break;
01282         case ENVVERB_REPLICATION:
01283                 wh = DB_VERB_REPLICATION;
01284                 break;
01285         case ENVVERB_WAITSFOR:
01286                 wh = DB_VERB_WAITSFOR;
01287                 break;
01288         default:
01289                 return (TCL_ERROR);
01290         }
01291         if (Tcl_GetIndexFromObj(interp, onoff, verbonoff, "option",
01292             TCL_EXACT, &optindex) != TCL_OK)
01293                 return (IS_HELP(onoff));
01294         switch ((enum verbonoff)optindex) {
01295         case ENVVERB_OFF:
01296                 on = 0;
01297                 break;
01298         case ENVVERB_ON:
01299                 on = 1;
01300                 break;
01301         default:
01302                 return (TCL_ERROR);
01303         }
01304         ret = dbenv->set_verbose(dbenv, wh, on);
01305         return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
01306             "env set verbose"));
01307 }
01308 #endif
01309 
01310 #ifdef CONFIG_TEST
01311 /*
01312  * PUBLIC: int tcl_EnvAttr __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
01313  *
01314  * tcl_EnvAttr --
01315  *      Return a list of the env's attributes
01316  */
01317 int
01318 tcl_EnvAttr(interp, objc, objv, dbenv)
01319         Tcl_Interp *interp;             /* Interpreter */
01320         int objc;                       /* How many arguments? */
01321         Tcl_Obj *CONST objv[];          /* The argument objects */
01322         DB_ENV *dbenv;                  /* Env pointer */
01323 {
01324         int result;
01325         Tcl_Obj *myobj, *retlist;
01326 
01327         result = TCL_OK;
01328 
01329         if (objc > 2) {
01330                 Tcl_WrongNumArgs(interp, 2, objv, NULL);
01331                 return (TCL_ERROR);
01332         }
01333         retlist = Tcl_NewListObj(0, NULL);
01334         /*
01335          * XXX
01336          * We peek at the dbenv to determine what subsystems
01337          * we have available in this env.
01338          */
01339         myobj = NewStringObj("-home", strlen("-home"));
01340         if ((result = Tcl_ListObjAppendElement(interp,
01341             retlist, myobj)) != TCL_OK)
01342                 goto err;
01343         myobj = NewStringObj(dbenv->db_home, strlen(dbenv->db_home));
01344         if ((result = Tcl_ListObjAppendElement(interp,
01345             retlist, myobj)) != TCL_OK)
01346                 goto err;
01347         if (CDB_LOCKING(dbenv)) {
01348                 myobj = NewStringObj("-cdb", strlen("-cdb"));
01349                 if ((result = Tcl_ListObjAppendElement(interp,
01350                     retlist, myobj)) != TCL_OK)
01351                         goto err;
01352         }
01353         if (CRYPTO_ON(dbenv)) {
01354                 myobj = NewStringObj("-crypto", strlen("-crypto"));
01355                 if ((result = Tcl_ListObjAppendElement(interp,
01356                     retlist, myobj)) != TCL_OK)
01357                         goto err;
01358         }
01359         if (LOCKING_ON(dbenv)) {
01360                 myobj = NewStringObj("-lock", strlen("-lock"));
01361                 if ((result = Tcl_ListObjAppendElement(interp,
01362                     retlist, myobj)) != TCL_OK)
01363                         goto err;
01364         }
01365         if (LOGGING_ON(dbenv)) {
01366                 myobj = NewStringObj("-log", strlen("-log"));
01367                 if ((result = Tcl_ListObjAppendElement(interp,
01368                     retlist, myobj)) != TCL_OK)
01369                         goto err;
01370         }
01371         if (MPOOL_ON(dbenv)) {
01372                 myobj = NewStringObj("-mpool", strlen("-mpool"));
01373                 if ((result = Tcl_ListObjAppendElement(interp,
01374                     retlist, myobj)) != TCL_OK)
01375                         goto err;
01376         }
01377         if (RPC_ON(dbenv)) {
01378                 myobj = NewStringObj("-rpc", strlen("-rpc"));
01379                 if ((result = Tcl_ListObjAppendElement(interp,
01380                     retlist, myobj)) != TCL_OK)
01381                         goto err;
01382         }
01383         if (REP_ON(dbenv)) {
01384                 myobj = NewStringObj("-rep", strlen("-rep"));
01385                 if ((result = Tcl_ListObjAppendElement(interp,
01386                     retlist, myobj)) != TCL_OK)
01387                         goto err;
01388         }
01389         if (TXN_ON(dbenv)) {
01390                 myobj = NewStringObj("-txn", strlen("-txn"));
01391                 if ((result = Tcl_ListObjAppendElement(interp,
01392                     retlist, myobj)) != TCL_OK)
01393                         goto err;
01394         }
01395         Tcl_SetObjResult(interp, retlist);
01396 err:
01397         return (result);
01398 }
01399 
01400 /*
01401  * PUBLIC: int tcl_EnvSetFlags __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *,
01402  * PUBLIC:    Tcl_Obj *));
01403  *
01404  * tcl_EnvSetFlags --
01405  *      Set flags in an env.
01406  */
01407 int
01408 tcl_EnvSetFlags(interp, dbenv, which, onoff)
01409         Tcl_Interp *interp;             /* Interpreter */
01410         DB_ENV *dbenv;                  /* Env pointer */
01411         Tcl_Obj *which;                 /* Which subsystem */
01412         Tcl_Obj *onoff;                 /* On or off */
01413 {
01414         static const char *sfwhich[] = {
01415                 "-auto_commit",
01416                 "-direct_db",
01417                 "-direct_log",
01418                 "-dsync_log",
01419                 "-log_inmemory",
01420                 "-log_remove",
01421                 "-nolock",
01422                 "-nommap",
01423                 "-nopanic",
01424                 "-nosync",
01425                 "-overwrite",
01426                 "-panic",
01427                 "-wrnosync",
01428                 NULL
01429         };
01430         enum sfwhich {
01431                 ENVSF_AUTOCOMMIT,
01432                 ENVSF_DIRECTDB,
01433                 ENVSF_DIRECTLOG,
01434                 ENVSF_DSYNCLOG,
01435                 ENVSF_LOG_INMEMORY,
01436                 ENVSF_LOG_REMOVE,
01437                 ENVSF_NOLOCK,
01438                 ENVSF_NOMMAP,
01439                 ENVSF_NOPANIC,
01440                 ENVSF_NOSYNC,
01441                 ENVSF_OVERWRITE,
01442                 ENVSF_PANIC,
01443                 ENVSF_WRNOSYNC
01444         };
01445         static const char *sfonoff[] = {
01446                 "off",
01447                 "on",
01448                 NULL
01449         };
01450         enum sfonoff {
01451                 ENVSF_OFF,
01452                 ENVSF_ON
01453         };
01454         int on, optindex, ret;
01455         u_int32_t wh;
01456 
01457         if (Tcl_GetIndexFromObj(interp, which, sfwhich, "option",
01458             TCL_EXACT, &optindex) != TCL_OK)
01459                 return (IS_HELP(which));
01460 
01461         switch ((enum sfwhich)optindex) {
01462         case ENVSF_AUTOCOMMIT:
01463                 wh = DB_AUTO_COMMIT;
01464                 break;
01465         case ENVSF_DIRECTDB:
01466                 wh = DB_DIRECT_DB;
01467                 break;
01468         case ENVSF_DIRECTLOG:
01469                 wh = DB_DIRECT_LOG;
01470                 break;
01471         case ENVSF_DSYNCLOG:
01472                 wh = DB_DSYNC_LOG;
01473                 break;
01474         case ENVSF_LOG_INMEMORY:
01475                 wh = DB_LOG_INMEMORY;
01476                 break;
01477         case ENVSF_LOG_REMOVE:
01478                 wh = DB_LOG_AUTOREMOVE;
01479                 break;
01480         case ENVSF_NOLOCK:
01481                 wh = DB_NOLOCKING;
01482                 break;
01483         case ENVSF_NOMMAP:
01484                 wh = DB_NOMMAP;
01485                 break;
01486         case ENVSF_NOSYNC:
01487                 wh = DB_TXN_NOSYNC;
01488                 break;
01489         case ENVSF_NOPANIC:
01490                 wh = DB_NOPANIC;
01491                 break;
01492         case ENVSF_PANIC:
01493                 wh = DB_PANIC_ENVIRONMENT;
01494                 break;
01495         case ENVSF_OVERWRITE:
01496                 wh = DB_OVERWRITE;
01497                 break;
01498         case ENVSF_WRNOSYNC:
01499                 wh = DB_TXN_WRITE_NOSYNC;
01500                 break;
01501         default:
01502                 return (TCL_ERROR);
01503         }
01504         if (Tcl_GetIndexFromObj(interp, onoff, sfonoff, "option",
01505             TCL_EXACT, &optindex) != TCL_OK)
01506                 return (IS_HELP(onoff));
01507         switch ((enum sfonoff)optindex) {
01508         case ENVSF_OFF:
01509                 on = 0;
01510                 break;
01511         case ENVSF_ON:
01512                 on = 1;
01513                 break;
01514         default:
01515                 return (TCL_ERROR);
01516         }
01517         ret = dbenv->set_flags(dbenv, wh, on);
01518         return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
01519             "env set verbose"));
01520 }
01521 
01522 /*
01523  * PUBLIC: int tcl_EnvTest __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
01524  *
01525  * tcl_EnvTest --
01526  */
01527 int
01528 tcl_EnvTest(interp, objc, objv, dbenv)
01529         Tcl_Interp *interp;             /* Interpreter */
01530         int objc;                       /* How many arguments? */
01531         Tcl_Obj *CONST objv[];          /* The argument objects */
01532         DB_ENV *dbenv;                  /* Env pointer */
01533 {
01534         static const char *envtestcmd[] = {
01535                 "abort",
01536                 "check",
01537                 "copy",
01538                 NULL
01539         };
01540         enum envtestcmd {
01541                 ENVTEST_ABORT,
01542                 ENVTEST_CHECK,
01543                 ENVTEST_COPY
01544         };
01545         static const char *envtestat[] = {
01546                 "electinit",
01547                 "electvote1",
01548                 "none",
01549                 "predestroy",
01550                 "preopen",
01551                 "postdestroy",
01552                 "postlog",
01553                 "postlogmeta",
01554                 "postopen",
01555                 "postsync",
01556                 "subdb_lock",
01557                 NULL
01558         };
01559         enum envtestat {
01560                 ENVTEST_ELECTINIT,
01561                 ENVTEST_ELECTVOTE1,
01562                 ENVTEST_NONE,
01563                 ENVTEST_PREDESTROY,
01564                 ENVTEST_PREOPEN,
01565                 ENVTEST_POSTDESTROY,
01566                 ENVTEST_POSTLOG,
01567                 ENVTEST_POSTLOGMETA,
01568                 ENVTEST_POSTOPEN,
01569                 ENVTEST_POSTSYNC,
01570                 ENVTEST_SUBDB_LOCKS
01571         };
01572         int *loc, optindex, result, testval;
01573 
01574         result = TCL_OK;
01575         loc = NULL;
01576 
01577         if (objc != 4) {
01578                 Tcl_WrongNumArgs(interp, 2, objv, "abort|copy location");
01579                 return (TCL_ERROR);
01580         }
01581 
01582         /*
01583          * This must be the "check", "copy" or "abort" portion of the command.
01584          */
01585         if (Tcl_GetIndexFromObj(interp, objv[2], envtestcmd, "command",
01586             TCL_EXACT, &optindex) != TCL_OK) {
01587                 result = IS_HELP(objv[2]);
01588                 return (result);
01589         }
01590         switch ((enum envtestcmd)optindex) {
01591         case ENVTEST_ABORT:
01592                 loc = &dbenv->test_abort;
01593                 break;
01594         case ENVTEST_CHECK:
01595                 loc = &dbenv->test_check;
01596                 if (Tcl_GetIntFromObj(interp, objv[3], &testval) != TCL_OK) {
01597                         result = IS_HELP(objv[3]);
01598                         return (result);
01599                 }
01600                 goto done;
01601         case ENVTEST_COPY:
01602                 loc = &dbenv->test_copy;
01603                 break;
01604         default:
01605                 Tcl_SetResult(interp, "Illegal store location", TCL_STATIC);
01606                 return (TCL_ERROR);
01607         }
01608 
01609         /*
01610          * This must be the location portion of the command.
01611          */
01612         if (Tcl_GetIndexFromObj(interp, objv[3], envtestat, "location",
01613             TCL_EXACT, &optindex) != TCL_OK) {
01614                 result = IS_HELP(objv[3]);
01615                 return (result);
01616         }
01617         switch ((enum envtestat)optindex) {
01618         case ENVTEST_ELECTINIT:
01619                 DB_ASSERT(loc == &dbenv->test_abort);
01620                 testval = DB_TEST_ELECTINIT;
01621                 break;
01622         case ENVTEST_ELECTVOTE1:
01623                 DB_ASSERT(loc == &dbenv->test_abort);
01624                 testval = DB_TEST_ELECTVOTE1;
01625                 break;
01626         case ENVTEST_NONE:
01627                 testval = 0;
01628                 break;
01629         case ENVTEST_PREOPEN:
01630                 testval = DB_TEST_PREOPEN;
01631                 break;
01632         case ENVTEST_PREDESTROY:
01633                 testval = DB_TEST_PREDESTROY;
01634                 break;
01635         case ENVTEST_POSTLOG:
01636                 testval = DB_TEST_POSTLOG;
01637                 break;
01638         case ENVTEST_POSTLOGMETA:
01639                 testval = DB_TEST_POSTLOGMETA;
01640                 break;
01641         case ENVTEST_POSTOPEN:
01642                 testval = DB_TEST_POSTOPEN;
01643                 break;
01644         case ENVTEST_POSTDESTROY:
01645                 testval = DB_TEST_POSTDESTROY;
01646                 break;
01647         case ENVTEST_POSTSYNC:
01648                 testval = DB_TEST_POSTSYNC;
01649                 break;
01650         case ENVTEST_SUBDB_LOCKS:
01651                 DB_ASSERT(loc == &dbenv->test_abort);
01652                 testval = DB_TEST_SUBDB_LOCKS;
01653                 break;
01654         default:
01655                 Tcl_SetResult(interp, "Illegal test location", TCL_STATIC);
01656                 return (TCL_ERROR);
01657         }
01658 done:
01659         *loc = testval;
01660         Tcl_SetResult(interp, "0", TCL_STATIC);
01661         return (result);
01662 }
01663 #endif
01664 
01665 /*
01666  * env_DbRemove --
01667  *      Implements the ENV->dbremove command.
01668  */
01669 static int
01670 env_DbRemove(interp, objc, objv, dbenv)
01671         Tcl_Interp *interp;             /* Interpreter */
01672         int objc;                       /* How many arguments? */
01673         Tcl_Obj *CONST objv[];          /* The argument objects */
01674         DB_ENV *dbenv;
01675 {
01676         static const char *envdbrem[] = {
01677                 "-auto_commit",
01678                 "-txn",
01679                 "--",
01680                 NULL
01681         };
01682         enum envdbrem {
01683                 TCL_EDBREM_COMMIT,
01684                 TCL_EDBREM_TXN,
01685                 TCL_EDBREM_ENDARG
01686         };
01687         DB_TXN *txn;
01688         u_int32_t flag;
01689         int endarg, i, optindex, result, ret, subdblen;
01690         u_char *subdbtmp;
01691         char *arg, *db, *subdb, msg[MSG_SIZE];
01692 
01693         txn = NULL;
01694         result = TCL_OK;
01695         subdbtmp = NULL;
01696         db = subdb = NULL;
01697         endarg = 0;
01698         flag = 0;
01699 
01700         if (objc < 2) {
01701                 Tcl_WrongNumArgs(interp, 2, objv, "?args? filename ?database?");
01702                 return (TCL_ERROR);
01703         }
01704 
01705         /*
01706          * We must first parse for the environment flag, since that
01707          * is needed for db_create.  Then create the db handle.
01708          */
01709         i = 2;
01710         while (i < objc) {
01711                 if (Tcl_GetIndexFromObj(interp, objv[i], envdbrem,
01712                     "option", TCL_EXACT, &optindex) != TCL_OK) {
01713                         arg = Tcl_GetStringFromObj(objv[i], NULL);
01714                         if (arg[0] == '-') {
01715                                 result = IS_HELP(objv[i]);
01716                                 goto error;
01717                         } else
01718                                 Tcl_ResetResult(interp);
01719                         break;
01720                 }
01721                 i++;
01722                 switch ((enum envdbrem)optindex) {
01723                 case TCL_EDBREM_COMMIT:
01724                         flag |= DB_AUTO_COMMIT;
01725                         break;
01726                 case TCL_EDBREM_TXN:
01727                         if (i >= objc) {
01728                                 Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
01729                                 result = TCL_ERROR;
01730                                 break;
01731                         }
01732                         arg = Tcl_GetStringFromObj(objv[i++], NULL);
01733                         txn = NAME_TO_TXN(arg);
01734                         if (txn == NULL) {
01735                                 snprintf(msg, MSG_SIZE,
01736                                     "env dbremove: Invalid txn %s\n", arg);
01737                                 Tcl_SetResult(interp, msg, TCL_VOLATILE);
01738                                 return (TCL_ERROR);
01739                         }
01740                         break;
01741                 case TCL_EDBREM_ENDARG:
01742                         endarg = 1;
01743                         break;
01744                 }
01745                 /*
01746                  * If, at any time, parsing the args we get an error,
01747                  * bail out and return.
01748                  */
01749                 if (result != TCL_OK)
01750                         goto error;
01751                 if (endarg)
01752                         break;
01753         }
01754         if (result != TCL_OK)
01755                 goto error;
01756         /*
01757          * Any args we have left, (better be 1 or 2 left) are
01758          * file names. If there is 1, a db name, if 2 a db and subdb name.
01759          */
01760         if ((i != (objc - 1)) || (i != (objc - 2))) {
01761                 /*
01762                  * Dbs must be NULL terminated file names, but subdbs can
01763                  * be anything.  Use Strings for the db name and byte
01764                  * arrays for the subdb.
01765                  */
01766                 db = Tcl_GetStringFromObj(objv[i++], NULL);
01767                 if (strcmp(db, "") == 0)
01768                         db = NULL;
01769                 if (i != objc) {
01770                         subdbtmp =
01771                             Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
01772                         if ((ret = __os_malloc(
01773                             dbenv, (size_t)subdblen + 1, &subdb)) != 0) {
01774                                 Tcl_SetResult(interp,
01775                                     db_strerror(ret), TCL_STATIC);
01776                                 return (0);
01777                         }
01778                         memcpy(subdb, subdbtmp, (size_t)subdblen);
01779                         subdb[subdblen] = '\0';
01780                 }
01781         } else {
01782                 Tcl_WrongNumArgs(interp, 2, objv, "?args? filename ?database?");
01783                 result = TCL_ERROR;
01784                 goto error;
01785         }
01786         ret = dbenv->dbremove(dbenv, txn, db, subdb, flag);
01787         result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
01788             "env dbremove");
01789 error:
01790         if (subdb)
01791                 __os_free(dbenv, subdb);
01792         return (result);
01793 }
01794 
01795 /*
01796  * env_DbRename --
01797  *      Implements the ENV->dbrename command.
01798  */
01799 static int
01800 env_DbRename(interp, objc, objv, dbenv)
01801         Tcl_Interp *interp;             /* Interpreter */
01802         int objc;                       /* How many arguments? */
01803         Tcl_Obj *CONST objv[];          /* The argument objects */
01804         DB_ENV *dbenv;
01805 {
01806         static const char *envdbmv[] = {
01807                 "-auto_commit",
01808                 "-txn",
01809                 "--",
01810                 NULL
01811         };
01812         enum envdbmv {
01813                 TCL_EDBMV_COMMIT,
01814                 TCL_EDBMV_TXN,
01815                 TCL_EDBMV_ENDARG
01816         };
01817         DB_TXN *txn;
01818         u_int32_t flag;
01819         int endarg, i, newlen, optindex, result, ret, subdblen;
01820         u_char *subdbtmp;
01821         char *arg, *db, *newname, *subdb, msg[MSG_SIZE];
01822 
01823         txn = NULL;
01824         result = TCL_OK;
01825         subdbtmp = NULL;
01826         db = newname = subdb = NULL;
01827         endarg = 0;
01828         flag = 0;
01829 
01830         if (objc < 2) {
01831                 Tcl_WrongNumArgs(interp, 3, objv,
01832                     "?args? filename ?database? ?newname?");
01833                 return (TCL_ERROR);
01834         }
01835 
01836         /*
01837          * We must first parse for the environment flag, since that
01838          * is needed for db_create.  Then create the db handle.
01839          */
01840         i = 2;
01841         while (i < objc) {
01842                 if (Tcl_GetIndexFromObj(interp, objv[i], envdbmv,
01843                     "option", TCL_EXACT, &optindex) != TCL_OK) {
01844                         arg = Tcl_GetStringFromObj(objv[i], NULL);
01845                         if (arg[0] == '-') {
01846                                 result = IS_HELP(objv[i]);
01847                                 goto error;
01848                         } else
01849                                 Tcl_ResetResult(interp);
01850                         break;
01851                 }
01852                 i++;
01853                 switch ((enum envdbmv)optindex) {
01854                 case TCL_EDBMV_COMMIT:
01855                         flag |= DB_AUTO_COMMIT;
01856                         break;
01857                 case TCL_EDBMV_TXN:
01858                         if (i >= objc) {
01859                                 Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
01860                                 result = TCL_ERROR;
01861                                 break;
01862                         }
01863                         arg = Tcl_GetStringFromObj(objv[i++], NULL);
01864                         txn = NAME_TO_TXN(arg);
01865                         if (txn == NULL) {
01866                                 snprintf(msg, MSG_SIZE,
01867                                     "env dbrename: Invalid txn %s\n", arg);
01868                                 Tcl_SetResult(interp, msg, TCL_VOLATILE);
01869                                 return (TCL_ERROR);
01870                         }
01871                         break;
01872                 case TCL_EDBMV_ENDARG:
01873                         endarg = 1;
01874                         break;
01875                 }
01876                 /*
01877                  * If, at any time, parsing the args we get an error,
01878                  * bail out and return.
01879                  */
01880                 if (result != TCL_OK)
01881                         goto error;
01882                 if (endarg)
01883                         break;
01884         }
01885         if (result != TCL_OK)
01886                 goto error;
01887         /*
01888          * Any args we have left, (better be 2 or 3 left) are
01889          * file names. If there is 2, a db name, if 3 a db and subdb name.
01890          */
01891         if ((i != (objc - 2)) || (i != (objc - 3))) {
01892                 /*
01893                  * Dbs must be NULL terminated file names, but subdbs can
01894                  * be anything.  Use Strings for the db name and byte
01895                  * arrays for the subdb.
01896                  */
01897                 db = Tcl_GetStringFromObj(objv[i++], NULL);
01898                 if (strcmp(db, "") == 0)
01899                         db = NULL;
01900                 if (i == objc - 2) {
01901                         subdbtmp =
01902                             Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
01903                         if ((ret = __os_malloc(
01904                             dbenv, (size_t)subdblen + 1, &subdb)) != 0) {
01905                                 Tcl_SetResult(interp,
01906                                     db_strerror(ret), TCL_STATIC);
01907                                 return (0);
01908                         }
01909                         memcpy(subdb, subdbtmp, (size_t)subdblen);
01910                         subdb[subdblen] = '\0';
01911                 }
01912                 subdbtmp = Tcl_GetByteArrayFromObj(objv[i++], &newlen);
01913                 if ((ret = __os_malloc(
01914                     dbenv, (size_t)newlen + 1, &newname)) != 0) {
01915                         Tcl_SetResult(interp,
01916                             db_strerror(ret), TCL_STATIC);
01917                         return (0);
01918                 }
01919                 memcpy(newname, subdbtmp, (size_t)newlen);
01920                 newname[newlen] = '\0';
01921         } else {
01922                 Tcl_WrongNumArgs(interp, 3, objv,
01923                     "?args? filename ?database? ?newname?");
01924                 result = TCL_ERROR;
01925                 goto error;
01926         }
01927         ret = dbenv->dbrename(dbenv, txn, db, subdb, newname, flag);
01928         result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
01929             "env dbrename");
01930 error:
01931         if (subdb)
01932                 __os_free(dbenv, subdb);
01933         if (newname)
01934                 __os_free(dbenv, newname);
01935         return (result);
01936 }
01937 
01938 /*
01939  * env_GetFlags --
01940  *      Implements the ENV->get_flags command.
01941  */
01942 static int
01943 env_GetFlags(interp, objc, objv, dbenv)
01944         Tcl_Interp *interp;             /* Interpreter */
01945         int objc;                       /* How many arguments? */
01946         Tcl_Obj *CONST objv[];          /* The argument objects */
01947         DB_ENV *dbenv;
01948 {
01949         int i, ret, result;
01950         u_int32_t flags;
01951         char buf[512];
01952         Tcl_Obj *res;
01953 
01954         static const struct {
01955                 u_int32_t flag;
01956                 char *arg;
01957         } open_flags[] = {
01958                 { DB_AUTO_COMMIT, "-auto_commit" },
01959                 { DB_CDB_ALLDB, "-cdb_alldb" },
01960                 { DB_DIRECT_DB, "-direct_db" },
01961                 { DB_DIRECT_LOG, "-direct_log" },
01962                 { DB_DSYNC_LOG, "-dsync_log" },
01963                 { DB_LOG_AUTOREMOVE, "-log_remove" },
01964                 { DB_LOG_INMEMORY, "-log_inmemory" },
01965                 { DB_NOLOCKING, "-nolock" },
01966                 { DB_NOMMAP, "-nommap" },
01967                 { DB_NOPANIC, "-nopanic" },
01968                 { DB_OVERWRITE, "-overwrite" },
01969                 { DB_PANIC_ENVIRONMENT, "-panic" },
01970                 { DB_REGION_INIT, "-region_init" },
01971                 { DB_TXN_NOSYNC, "-nosync" },
01972                 { DB_TXN_WRITE_NOSYNC, "-wrnosync" },
01973                 { DB_YIELDCPU, "-yield" },
01974                 { 0, NULL }
01975         };
01976 
01977         if (objc != 2) {
01978                 Tcl_WrongNumArgs(interp, 1, objv, NULL);
01979                 return (TCL_ERROR);
01980         }
01981 
01982         ret = dbenv->get_flags(dbenv, &flags);
01983         if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
01984             "env get_flags")) == TCL_OK) {
01985                 buf[0] = '\0';
01986 
01987                 for (i = 0; open_flags[i].flag != 0; i++)
01988                         if (LF_ISSET(open_flags[i].flag)) {
01989                                 if (strlen(buf) > 0)
01990                                         (void)strncat(buf, " ", sizeof(buf));
01991                                 (void)strncat(
01992                                     buf, open_flags[i].arg, sizeof(buf));
01993                         }
01994 
01995                 res = NewStringObj(buf, strlen(buf));
01996                 Tcl_SetObjResult(interp, res);
01997         }
01998 
01999         return (result);
02000 }
02001 
02002 /*
02003  * env_GetOpenFlag --
02004  *      Implements the ENV->get_open_flags command.
02005  */
02006 static int
02007 env_GetOpenFlag(interp, objc, objv, dbenv)
02008         Tcl_Interp *interp;             /* Interpreter */
02009         int objc;                       /* How many arguments? */
02010         Tcl_Obj *CONST objv[];          /* The argument objects */
02011         DB_ENV *dbenv;
02012 {
02013         int i, ret, result;
02014         u_int32_t flags;
02015         char buf[512];
02016         Tcl_Obj *res;
02017 
02018         static const struct {
02019                 u_int32_t flag;
02020                 char *arg;
02021         } open_flags[] = {
02022                 { DB_CREATE, "-create" },
02023                 { DB_INIT_CDB, "-cdb" },
02024                 { DB_INIT_LOCK, "-lock" },
02025                 { DB_INIT_LOG, "-log" },
02026                 { DB_INIT_MPOOL, "-mpool" },
02027                 { DB_INIT_TXN, "-txn" },
02028                 { DB_LOCKDOWN, "-lockdown" },
02029                 { DB_PRIVATE, "-private" },
02030                 { DB_RECOVER, "-recover" },
02031                 { DB_RECOVER_FATAL, "-recover_fatal" },
02032                 { DB_REGISTER, "-register" },
02033                 { DB_SYSTEM_MEM, "-system_mem" },
02034                 { DB_THREAD, "-thread" },
02035                 { DB_USE_ENVIRON, "-use_environ" },
02036                 { DB_USE_ENVIRON_ROOT, "-use_environ_root" },
02037                 { 0, NULL }
02038         };
02039 
02040         if (objc != 2) {
02041                 Tcl_WrongNumArgs(interp, 1, objv, NULL);
02042                 return (TCL_ERROR);
02043         }
02044 
02045         ret = dbenv->get_open_flags(dbenv, &flags);
02046         if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
02047             "env get_open_flags")) == TCL_OK) {
02048                 buf[0] = '\0';
02049 
02050                 for (i = 0; open_flags[i].flag != 0; i++)
02051                         if (LF_ISSET(open_flags[i].flag)) {
02052                                 if (strlen(buf) > 0)
02053                                         (void)strncat(buf, " ", sizeof(buf));
02054                                 (void)strncat(
02055                                     buf, open_flags[i].arg, sizeof(buf));
02056                         }
02057 
02058                 res = NewStringObj(buf, strlen(buf));
02059                 Tcl_SetObjResult(interp, res);
02060         }
02061 
02062         return (result);
02063 }
02064 
02065 /*
02066  * PUBLIC: int tcl_EnvGetEncryptFlags __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
02067  * PUBLIC:      DB_ENV *));
02068  *
02069  * tcl_EnvGetEncryptFlags --
02070  *      Implements the ENV->get_encrypt_flags command.
02071  */
02072 int
02073 tcl_EnvGetEncryptFlags(interp, objc, objv, dbenv)
02074         Tcl_Interp *interp;             /* Interpreter */
02075         int objc;                       /* How many arguments? */
02076         Tcl_Obj *CONST objv[];          /* The argument objects */
02077         DB_ENV *dbenv;                  /* Database pointer */
02078 {
02079         int i, ret, result;
02080         u_int32_t flags;
02081         char buf[512];
02082         Tcl_Obj *res;
02083 
02084         static const struct {
02085                 u_int32_t flag;
02086                 char *arg;
02087         } encrypt_flags[] = {
02088                 { DB_ENCRYPT_AES, "-encryptaes" },
02089                 { 0, NULL }
02090         };
02091 
02092         if (objc != 2) {
02093                 Tcl_WrongNumArgs(interp, 1, objv, NULL);
02094                 return (TCL_ERROR);
02095         }
02096 
02097         ret = dbenv->get_encrypt_flags(dbenv, &flags);
02098         if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
02099             "env get_encrypt_flags")) == TCL_OK) {
02100                 buf[0] = '\0';
02101 
02102                 for (i = 0; encrypt_flags[i].flag != 0; i++)
02103                         if (LF_ISSET(encrypt_flags[i].flag)) {
02104                                 if (strlen(buf) > 0)
02105                                         (void)strncat(buf, " ", sizeof(buf));
02106                                 (void)strncat(
02107                                     buf, encrypt_flags[i].arg, sizeof(buf));
02108                         }
02109 
02110                 res = NewStringObj(buf, strlen(buf));
02111                 Tcl_SetObjResult(interp, res);
02112         }
02113 
02114         return (result);
02115 }
02116 
02117 /*
02118  * env_GetLockDetect --
02119  *      Implements the ENV->get_lk_detect command.
02120  */
02121 static int
02122 env_GetLockDetect(interp, objc, objv, dbenv)
02123         Tcl_Interp *interp;             /* Interpreter */
02124         int objc;                       /* How many arguments? */
02125         Tcl_Obj *CONST objv[];          /* The argument objects */
02126         DB_ENV *dbenv;
02127 {
02128         int i, ret, result;
02129         u_int32_t lk_detect;
02130         const char *answer;
02131         Tcl_Obj *res;
02132         static const struct {
02133                 u_int32_t flag;
02134                 char *name;
02135         } lk_detect_returns[] = {
02136                 { DB_LOCK_DEFAULT, "default" },
02137                 { DB_LOCK_EXPIRE, "expire" },
02138                 { DB_LOCK_MAXLOCKS, "maxlocks" },
02139                 { DB_LOCK_MAXWRITE, "maxwrite" },
02140                 { DB_LOCK_MINLOCKS, "minlocks" },
02141                 { DB_LOCK_MINWRITE, "minwrite" },
02142                 { DB_LOCK_OLDEST, "oldest" },
02143                 { DB_LOCK_RANDOM, "random" },
02144                 { DB_LOCK_YOUNGEST, "youngest" },
02145                 { 0, NULL }
02146         };
02147 
02148         if (objc != 2) {
02149                 Tcl_WrongNumArgs(interp, 1, objv, NULL);
02150                 return (TCL_ERROR);
02151         }
02152         ret = dbenv->get_lk_detect(dbenv, &lk_detect);
02153         if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
02154             "env get_lk_detect")) == TCL_OK) {
02155                 answer = "unknown";
02156                 for (i = 0; lk_detect_returns[i].flag != 0; i++)
02157                         if (lk_detect == lk_detect_returns[i].flag)
02158                                 answer = lk_detect_returns[i].name;
02159 
02160                 res = NewStringObj(answer, strlen(answer));
02161                 Tcl_SetObjResult(interp, res);
02162         }
02163 
02164         return (result);
02165 }
02166 
02167 /*
02168  * env_GetTimeout --
02169  *      Implements the ENV->get_timeout command.
02170  */
02171 static int
02172 env_GetTimeout(interp, objc, objv, dbenv)
02173         Tcl_Interp *interp;             /* Interpreter */
02174         int objc;                       /* How many arguments? */
02175         Tcl_Obj *CONST objv[];          /* The argument objects */
02176         DB_ENV *dbenv;
02177 {
02178         static const struct {
02179                 u_int32_t flag;
02180                 char *arg;
02181         } timeout_flags[] = {
02182                 { DB_SET_TXN_TIMEOUT, "txn" },
02183                 { DB_SET_LOCK_TIMEOUT, "lock" },
02184                 { 0, NULL }
02185         };
02186         Tcl_Obj *res;
02187         db_timeout_t timeout;
02188         u_int32_t which;
02189         int i, ret, result;
02190         const char *arg;
02191 
02192         COMPQUIET(timeout, 0);
02193 
02194         if (objc != 3) {
02195                 Tcl_WrongNumArgs(interp, 1, objv, NULL);
02196                 return (TCL_ERROR);
02197         }
02198 
02199         arg = Tcl_GetStringFromObj(objv[2], NULL);
02200         which = 0;
02201         for (i = 0; timeout_flags[i].flag != 0; i++)
02202                 if (strcmp(arg, timeout_flags[i].arg) == 0)
02203                         which = timeout_flags[i].flag;
02204         if (which == 0) {
02205                 ret = EINVAL;
02206                 goto err;
02207         }
02208 
02209         ret = dbenv->get_timeout(dbenv, &timeout, which);
02210 err:    if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
02211             "env get_timeout")) == TCL_OK) {
02212                 res = Tcl_NewLongObj((long)timeout);
02213                 Tcl_SetObjResult(interp, res);
02214         }
02215 
02216         return (result);
02217 }
02218 
02219 /*
02220  * env_GetVerbose --
02221  *      Implements the ENV->get_open_flags command.
02222  */
02223 static int
02224 env_GetVerbose(interp, objc, objv, dbenv)
02225         Tcl_Interp *interp;             /* Interpreter */
02226         int objc;                       /* How many arguments? */
02227         Tcl_Obj *CONST objv[];          /* The argument objects */
02228         DB_ENV *dbenv;
02229 {
02230         static const struct {
02231                 u_int32_t flag;
02232                 char *arg;
02233         } verbose_flags[] = {
02234                 { DB_VERB_DEADLOCK, "deadlock" },
02235                 { DB_VERB_RECOVERY, "recovery" },
02236                 { DB_VERB_REGISTER, "register" },
02237                 { DB_VERB_REPLICATION, "rep" },
02238                 { DB_VERB_WAITSFOR, "wait" },
02239                 { 0, NULL }
02240         };
02241         Tcl_Obj *res;
02242         u_int32_t which;
02243         int i, onoff, ret, result;
02244         const char *arg, *answer;
02245 
02246         COMPQUIET(onoff, 0);
02247 
02248         if (objc != 3) {
02249                 Tcl_WrongNumArgs(interp, 1, objv, NULL);
02250                 return (TCL_ERROR);
02251         }
02252 
02253         arg = Tcl_GetStringFromObj(objv[2], NULL);
02254         which = 0;
02255         for (i = 0; verbose_flags[i].flag != 0; i++)
02256                 if (strcmp(arg, verbose_flags[i].arg) == 0)
02257                         which = verbose_flags[i].flag;
02258         if (which == 0) {
02259                 ret = EINVAL;
02260                 goto err;
02261         }
02262 
02263         ret = dbenv->get_verbose(dbenv, which, &onoff);
02264 err:    if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
02265             "env get_verbose")) == 0) {
02266                 answer = onoff ? "on" : "off";
02267                 res = NewStringObj(answer, strlen(answer));
02268                 Tcl_SetObjResult(interp, res);
02269         }
02270 
02271         return (result);
02272 }
02273 
02274 /*
02275  * PUBLIC: void tcl_EnvSetErrfile __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *,
02276  * PUBLIC:    char *));
02277  *
02278  * tcl_EnvSetErrfile --
02279  *      Implements the ENV->set_errfile command.
02280  */
02281 void
02282 tcl_EnvSetErrfile(interp, dbenv, ip, errf)
02283         Tcl_Interp *interp;             /* Interpreter */
02284         DB_ENV *dbenv;                  /* Database pointer */
02285         DBTCL_INFO *ip;                 /* Our internal info */
02286         char *errf;
02287 {
02288         COMPQUIET(interp, NULL);
02289         /*
02290          * If the user already set one, free it.
02291          */
02292         if (ip->i_err != NULL && ip->i_err != stdout &&
02293             ip->i_err != stderr)
02294                 (void)fclose(ip->i_err);
02295         if (strcmp(errf, "/dev/stdout") == 0)
02296                 ip->i_err = stdout;
02297         else if (strcmp(errf, "/dev/stderr") == 0)
02298                 ip->i_err = stderr;
02299         else
02300                 ip->i_err = fopen(errf, "a");
02301         if (ip->i_err != NULL)
02302                 dbenv->set_errfile(dbenv, ip->i_err);
02303 }
02304 
02305 /*
02306  * PUBLIC: int tcl_EnvSetErrpfx __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *,
02307  * PUBLIC:    char *));
02308  *
02309  * tcl_EnvSetErrpfx --
02310  *      Implements the ENV->set_errpfx command.
02311  */
02312 int
02313 tcl_EnvSetErrpfx(interp, dbenv, ip, pfx)
02314         Tcl_Interp *interp;             /* Interpreter */
02315         DB_ENV *dbenv;                  /* Database pointer */
02316         DBTCL_INFO *ip;                 /* Our internal info */
02317         char *pfx;
02318 {
02319         int result, ret;
02320 
02321         /*
02322          * Assume success.  The only thing that can fail is
02323          * the __os_strdup.
02324          */
02325         result = TCL_OK;
02326         Tcl_SetResult(interp, "0", TCL_STATIC);
02327         /*
02328          * If the user already set one, free it.
02329          */
02330         if (ip->i_errpfx != NULL)
02331                 __os_free(dbenv, ip->i_errpfx);
02332         if ((ret = __os_strdup(dbenv, pfx, &ip->i_errpfx)) != 0) {
02333                 result = _ReturnSetup(interp, ret,
02334                     DB_RETOK_STD(ret), "__os_strdup");
02335                 ip->i_errpfx = NULL;
02336         }
02337         if (ip->i_errpfx != NULL)
02338                 dbenv->set_errpfx(dbenv, ip->i_errpfx);
02339         return (result);
02340 }

Generated on Sun Dec 25 12:14:52 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2