summaryrefslogtreecommitdiff
path: root/tcl
diff options
context:
space:
mode:
authorZhang Qiang <qiang.z.zhang@intel.com>2012-05-29 11:25:24 +0800
committerZhang Qiang <qiang.z.zhang@intel.com>2012-05-29 11:25:24 +0800
commite776056ea09ba0b6d9505ced6913c9190a12d632 (patch)
tree092838f2a86042abc586aa5576e36ae6cb47e256 /tcl
parent2e082c838d2ca750f5daac6dcdabecc22dfd4e46 (diff)
downloaddb4-e776056ea09ba0b6d9505ced6913c9190a12d632.tar.gz
db4-e776056ea09ba0b6d9505ced6913c9190a12d632.tar.bz2
db4-e776056ea09ba0b6d9505ced6913c9190a12d632.zip
updated with Tizen:Base source codes
Diffstat (limited to 'tcl')
-rw-r--r--tcl/docs/db.html267
-rw-r--r--tcl/docs/env.html344
-rw-r--r--tcl/docs/historic.html168
-rw-r--r--tcl/docs/index.html50
-rw-r--r--tcl/docs/library.html26
-rw-r--r--tcl/docs/lock.html206
-rw-r--r--tcl/docs/log.html123
-rw-r--r--tcl/docs/mpool.html189
-rw-r--r--tcl/docs/rep.html50
-rw-r--r--tcl/docs/sequence.html93
-rw-r--r--tcl/docs/test.html103
-rw-r--r--tcl/docs/txn.html69
-rw-r--r--tcl/tcl_compat.c738
-rw-r--r--tcl/tcl_db.c3465
-rw-r--r--tcl/tcl_db_pkg.c4398
-rw-r--r--tcl/tcl_dbcursor.c1056
-rw-r--r--tcl/tcl_env.c2670
-rw-r--r--tcl/tcl_internal.c817
-rw-r--r--tcl/tcl_lock.c775
-rw-r--r--tcl/tcl_log.c770
-rw-r--r--tcl/tcl_mp.c939
-rw-r--r--tcl/tcl_mutex.c315
-rw-r--r--tcl/tcl_rep.c1426
-rw-r--r--tcl/tcl_seq.c511
-rw-r--r--tcl/tcl_txn.c778
-rw-r--r--tcl/tcl_util.c121
26 files changed, 0 insertions, 20467 deletions
diff --git a/tcl/docs/db.html b/tcl/docs/db.html
deleted file mode 100644
index 02429af..0000000
--- a/tcl/docs/db.html
+++ /dev/null
@@ -1,267 +0,0 @@
-<!--Copyright 1999-2009 Oracle. All rights reserved.-->
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.08 [en] (X11; I; FreeBSD 3.3-RELEASE i386) [Netscape]">
-</HEAD>
-<BODY>
-
-<H2>
-<A NAME="Database Commands"></A>Database Commands</H2>
-The database commands provide a fairly straightforward mapping to the
-DB method functions.
-
-<P>
-<B>> berkdb open</B>
-<dl>
-
-<dt><B>[-btcompare <I>proc</I>]</B><dd>
-Sets the Btree comparison function to the Tcl procedure named
-<I>proc</I> using the
-<A HREF="../../docs/api_c/db_set_bt_compare.html">DB->set_bt_compare</A>
-method.
-
-<dt><B>[-btree|-hash|-recno|-queue|-unknown]</B><dd>
-</td><td>
-Select the database type:<br>
-DB_BTREE, DB_HASH, DB_RECNO, DB_QUEUE or DB_UNKNOWN.
-
-
-<dt><B>[-cachesize {<I>gbytes bytes ncaches</I>}]</B><dd>
-Sets the size of the database cache to the size specified by
-<I>gbytes</I> and <I>bytes</I>, broken up into <I>ncaches</I> number of
-caches using the
-<A HREF="../../docs/api_c/db_set_cachesize.html">DB->set_cachesize</A>
-method.
-
-<dt><B>[-create]</B><dd>
-Selects the DB_CREATE flag to create underlying files.
-
-<dt><B>[-delim <I>delim</I>]</B><dd>
-Sets the delimiting byte for variable length records to <I>delim</I>
-using the
-<A HREF="../../docs/api_c/db_set_re_delim.html">DB->set_re_delim</A>
-method.
-
-<dt><B>[-compress]</B><dd>
-Enables default compression using the
-<A HREF="../../docs/api_c/db_set_bt_compress.html">DB->set_bt_compress</A>
-method.
-
-<dt><B>[-dup]</B><dd>
-Selects the DB_DUP flag to permit duplicates in the database.
-
-<dt><B>[-dupcompare <I>proc</I>]</B><dd>
-Sets the duplicate data comparison function to the Tcl procedure named
-<I>proc</I> using the
-<A HREF="../../docs/api_c/db_set_dup_compare.html">DB->set_dup_compare</A>
-method.
-
-<dt><B>[-dupsort]</B><dd>
-Selects the DB_DUPSORT flag to support sorted duplicates.
-
-<dt><B>[-env <I>env</I>]</B><dd>
-The database environment.
-
-<dt><B>[-errfile <I>filename</I>]</B><dd>
-Specifies the error file to use for this environment to <I>filename</I>
-by calling
-<A HREF="../../docs/api_c/db_set_errfile.html">DB->set_errfile</A>.
-If the file already exists then we will append to the end of the file.
-
-<dt><B>[-excl]</B><dd>
-Selects the DB_EXCL flag to exclusively create underlying files.
-
-<dt><B>[-extent <I>size</I>]</B><dd>
-Sets the size of a Queue database extent to the given <I>size</I> using
-the
-<A HREF="../../docs/api_c/db_set_q_extentsize.html">DB->set_q_extentsize</A>
-method.
-
-<dt><B>[-ffactor <I>density</I>]</B><dd>
-Sets the hash table key density to the given <I>density</I> using the
-<A HREF="../../docs/api_c/db_set_h_ffactor.html">DB->set_h_ffactor</A>
-method.
-
-<dt><B>[-hashproc <I>proc</I>]</B><dd>
-Sets a user-defined hash function to the Tcl procedure named <I>proc</I>
-using the
-<A HREF="../../docs/api_c/db_set_h_hash.html">DB->set_h_hash</A> method.
-
-<dt><B>[-len <I>len</I>]</B><dd>
-Sets the length of fixed-length records to <I>len</I> using the
-<A HREF="../../docs/api_c/db_set_re_len.html">DB->set_re_len</A>
-method.
-
-<dt><B>[-lorder <I>order</I>]</B><dd>
-Sets the byte order for integers stored in the database meta-data to
-the given <I>order</I> using the
-<A HREF="../../docs/api_c/db_set_lorder.html">DB->set_lorder</A>
-method.
-
-<dt><B>[-minkey <I>minkey</I>]</B><dd>
-Sets the minimum number of keys per Btree page to <I>minkey</I> using
-the
-<A HREF="../../docs/api_c/db_set_bt_minkey.html">DB->set_bt_minkey</A>
-method.
-
-<dt><B>[-mode <I>mode</I>]</B><dd>
-Specifies the mode for created files.
-
-<dt><B>[-nelem <I>size</I>]</B><dd>
-Sets the hash table size estimate to the given <I>size</I> using the
-<A HREF="../../docs/api_c/db_set_h_nelem.html">DB->set_h_nelem</A>
-method.
-
-<dt><B>[-nommap]</B><dd>
-Selects the DB_NOMMAP flag to forbid mmaping of files.
-
-<dt><B>[-pad <I>pad</I>]</B><dd>
-Sets the pad character used for fixed length records to <I>pad</I> using
-the
-<A HREF="../../docs/db_set_re_pad.html">DB->set_re_pad</A> method.
-
-<dt><B>[-pagesize <I>pagesize</I>]</B><dd>
-Sets the size of the database page to <I>pagesize</I> using the
-<A HREF="../../docs/api_c/db_set_pagesize.html">DB->set_pagesize</A>
-method.
-
-<dt><B>[-rdonly]</B><dd>
-Selects the DB_RDONLY flag for opening in read-only mode.
-
-<dt><B>[-recnum]</B><dd>
-Selects the DB_RECNUM flag to support record numbers in Btrees.
-
-<dt><B>[-renumber]</B><dd>
-Selects the DB_RENUMBER flag to support mutable record numbers.
-
-<dt><B>[-revsplitoff]</B><dd>
-Selects the DB_REVSPLITOFF flag to suppress reverse splitting of pages
-on deletion.
-
-<dt><B>[-snapshot]</B><dd>
-Selects the DB_SNAPSHOT flag to support database snapshots.
-
-<dt><B>[-source <I>file</I>]</B><dd>
-Sets the backing source file name to <I>file</I> using the
-<A HREF="../../docs/api_c/db_set_re_source.html">DB->set_re_source</A>
-method.
-
-<dt><B>[-truncate]</B><dd>
-Selects the DB_TRUNCATE flag to truncate the database.
-
-<dt><B>[--]</B><dd>
-Terminate the list of options and use remaining arguments as the file
-or subdb names (thus allowing the use of filenames beginning with a dash
-'-').
-
-<dt><B>[<I>filename </I>[<I>subdbname</I>]]</B><dd>
-The names of the database and sub-database.
-</dl>
-
-<HR WIDTH="100%">
-<B>> berkdb upgrade [-dupsort] [-env <I>env</I>] [--] [<I>filename</I>]</B>
-<P>This command will invoke the <A HREF="../../docs/api_c/db_upgrade.html">DB->upgrade</A>
-function.&nbsp; If the command is given the <B>-env</B> option, then we
-will accordingly upgrade the database filename within the context of that
-environment. The <B>-dupsort</B> option selects the DB_DUPSORT flag for
-upgrading. The use of --<B> </B>terminates the list of options, thus allowing
-filenames beginning with a dash.
-<P>
-
-<HR WIDTH="100%">
-<B>> berkdb verify [-env <I>env</I>] [--] [<I>filename</I>]</B>
-<P>This command will invoke the <A HREF="../../docs/api_c/db_verify.html">DB->verify</A>
-function.&nbsp; If the command is given the <B>-env</B> option, then we
-will accordingly verify the database filename within the context of that
-environment.&nbsp; The use of --<B> </B>terminates the list of options,
-thus allowing filenames beginning with a dash.
-<P>
-
-<HR WIDTH="100%"><B>> <I>db</I> del</B>
-<P>There are no undocumented options.
-
-<HR WIDTH="100%">
-<B>> <I>db</I> join [-nosort] <I>db0.c0 db1.c0</I> ...</B>
-<P>This command will invoke the <A HREF="../../docs/api_c/db_join.html">db_join</A>
-function.&nbsp; After it successfully joins a database, we bind it to a
-new Tcl command of the form <B><I>dbN.cX, </I></B>where X is an integer
-starting at 0 (e.g. <B>db2.c0, db3.c0, </B>etc).&nbsp; We use the <I>Tcl_CreateObjCommand()&nbsp;</I>
-to create the top level database function.&nbsp; It is through this cursor
-handle that the user can access the joined data items.
-<P>The options are:
-<UL>
-<LI>
-<B>-nosort -</B> This flag causes DB not to sort the cursors based on the
-number of data items they reference.&nbsp; It results in the DB_JOIN_NOSORT
-flag being set.</LI>
-</UL>
-
-<P>
-This command will invoke the
-<A HREF="../../docs/api_c/db_create.html">db_create</A> function. If
-the command is given the <B>-env</B> option, then we will accordingly
-creating the database within the context of that environment. After it
-successfully gets a handle to a database, we bind it to a new Tcl
-command of the form <B><I>dbX, </I></B>where X is an integer starting
-at 0 (e.g. <B>db0, db1, </B>etc).
-
-<p>
-We use the <I>Tcl_CreateObjCommand()</I> to create the top level
-database function. It is through this handle that the user can access
-all of the commands described in the <A HREF="#Database Commands">
-Database Commands</A> section. Internally, the database handle
-is sent as the <I>ClientData</I> portion of the new command set so that
-all future database calls access the appropriate handle.
-
-<P>
-After parsing all of the optional arguments affecting the setup of the
-database and making the appropriate calls to DB to manipulate those
-values, we open the database for the user. It translates to the
-<A HREF="../../docs/api_c/db_open.html">DB->open</A> method call after
-parsing all of the various optional arguments. We automatically set the
-DB_THREAD flag. The arguments are:
-
-<HR WIDTH="100%">
-<B>> <I>db</I> get_join [-nosort] {db key} {db key} ...</B>
-<P>This command performs a join operation on the keys specified and returns
-a list of the joined {key data} pairs.
-<P>The options are:
-<UL>
-<LI>
-<B>-nosort</B> This flag causes DB not to sort the cursors based on the
-number of data items they reference.&nbsp; It results in the DB_JOIN_NOSORT
-flag being set.</LI>
-</UL>
-
-<HR WIDTH="100%">
-<B>> <I>db</I> keyrange [-txn <I>id</I>] key</B>
-<P>This command returns the range for the given <B>key</B>.&nbsp; It returns
-a list of 3 double elements of the form {<B><I>less equal greater</I></B>}
-where <B><I>less</I></B> is the percentage of keys less than the given
-key, <B><I>equal</I></B> is the percentage equal to the given key and <B><I>greater</I></B>
-is the percentage greater than the given key.&nbsp; If the -txn option
-is specified it performs this operation under transaction protection.
-
-<HR WIDTH="100%"><B>> <I>db</I> put</B>
-<P>The <B>undocumented</B> options are:
-<dl>
-<dt><B>-nodupdata</B><dd>
-This flag causes DB not to insert the key/data pair if it already
-exists, that is, both the key and data items are already in the
-database. The -nodupdata flag may only be specified if the underlying
-database has been configured to support sorted duplicates.
-</dl>
-
-<HR WIDTH="100%"><B>> <I>dbc</I> put</B>
-<P>The <B>undocumented</B> options are:
-<dl>
-<dt><B>-nodupdata</B><dd>
-This flag causes DB not to insert the key/data pair if it already
-exists, that is, both the key and data items are already in the
-database. The -nodupdata flag may only be specified if the underlying
-database has been configured to support sorted duplicates.
-</dl>
-
-</BODY>
-</HTML>
diff --git a/tcl/docs/env.html b/tcl/docs/env.html
deleted file mode 100644
index eba6fb1..0000000
--- a/tcl/docs/env.html
+++ /dev/null
@@ -1,344 +0,0 @@
-<!--Copyright 1999-2009 Oracle. All rights reserved.-->
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <meta name="GENERATOR" content="Mozilla/4.75 [en] (X11; U; Linux 2.2.16-22 i686) [Netscape]">
-</head>
-<body>
-
-<h2>
-Environment Commands</h2>
-Environments provide a structure for creating a consistent environment
-for processes using one or more of the features of Berkeley DB.&nbsp; Unlike
-some of the database commands, the environment commands are very low level.
-<br>
-<hr WIDTH="100%">
-<p>The user may create and open a new DB environment&nbsp; by invoking:
-<p><b>> berkdb env</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-cdb] [-cdb_alldb] [-lock] [-log] [-txn [nosync]]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-create] [-home<i> directory</i>] [-mode <i>mode</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-data_dir <i>directory</i>] [-log_dir <i>directory</i>]
-[-tmp_dir <i>directory</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-nommap] [-private] [-recover] [-recover_fatal]
-[-system_mem] [-errfile <i>filename</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-use_environ] [-use_environ_root] [-verbose
-{<i>which </i>on|off}]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-region_init]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-cachesize {<i>gbytes bytes ncaches</i>}]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-mmapsize<i> size</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-log_max <i>max</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-log_buffer <i>size</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-lock_conflict {<i>nmodes </i>{<i>matrix</i>}}]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-lock_detect default|oldest|random|youngest]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-lock_max <i>max</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-lock_max_locks <i>max</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-lock_max_lockers <i>max</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-lock_max_objects <i>max</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-lock_timeout <i>timeout</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-overwrite]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-txn_max <i>max</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-txn_timeout <i>timeout</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-client_timeout <i>seconds</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-server_timeout <i>seconds</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-server <i>hostname</i>]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-rep_master] [-rep_client]</b>
-<br><b>&nbsp;&nbsp;&nbsp; [-rep_transport <i>{ machineid sendproc }</i>]</b>
-<br>&nbsp;
-<p>This command opens up an environment.&nbsp;&nbsp; We automatically set
-the DB_THREAD and the DB_INIT_MPOOL flags.&nbsp; The arguments are:
-<ul>
-<li>
-<b>-cdb</b> selects the DB_INIT_CDB flag for Concurrent Data Store</li>
-
-<li>
-<b>-cdb_alldb</b> selects the DB_CDB_ALLDB flag for Concurrent Data Store</li>
-
-<li>
-<b>-lock</b> selects the DB_INIT_LOCK flag for the locking subsystem</li>
-
-<li>
-<b>-log</b> selects the DB_INIT_LOG flag for the logging subsystem</li>
-
-<li>
-<b>-txn</b> selects the DB_INIT_TXN, DB_INIT_LOCK and DB_INIT_LOG flags
-for the transaction subsystem.&nbsp; If <b>nosync</b> is specified, then
-it will also select DB_TXN_NOSYNC to indicate no flushes of log on commits</li>
-
-<li>
-<b>-create </b>selects the DB_CREATE flag to create underlying files</li>
-
-<li>
-<b>-home <i>directory </i></b>selects the home directory of the environment</li>
-
-<li>
-<b>-data_dir <i>directory </i></b>selects the data file directory of the
-environment by calling <a href="../../docs/api_c/env_set_data_dir.html">DBENV->set_data_dir</a>.</li>
-
-<li>
-<b>-log_dir <i>directory </i></b>selects the log file directory of the
-environment&nbsp; by calling <a href="../../docs/api_c/env_set_lg_dir.html">DBENV->set_lg_dir</a>.</li>
-
-<li>
-<b>-tmp_dir <i>directory </i></b>selects the temporary file directory of
-the environment&nbsp; by calling <a href="../../docs/api_c/env_set_tmp_dir.so">DBENV->set_tmp_dir</a>.</li>
-
-<li>
-<b>-mode <i>mode </i></b>sets the permissions of created files to <b><i>mode</i></b></li>
-
-<li>
-<b>-nommap</b> selects the DB_NOMMAP flag to disallow using mmap'ed files</li>
-
-<li>
-<b>-private</b> selects the DB_PRIVATE flag for a private environment</li>
-
-<li>
-<b>-recover</b> selects the DB_RECOVER flag for recovery</li>
-
-<li>
-<b>-recover_fatal</b> selects the DB_RECOVER_FATAL flag for catastrophic
-recovery</li>
-
-<li>
-<b>-system_mem</b> selects the DB_SYSTEM_MEM flag to use system memory</li>
-
-<li>
-<b>-errfile </b>specifies the error file to use for this environment to
-<b><i>filename</i></b>
-by calling <a href="../../docs/api_c/env_set_errfile.html">DBENV->set_errfile</a><b><i>.
-</i></b>If
-the file already exists then we will append to the end of the file</li>
-
-<li>
-<b>-use_environ</b> selects the DB_USE_ENVIRON flag to affect file naming</li>
-
-<li>
-<b>-use_environ_root</b> selects the DB_USE_ENVIRON_ROOT flag to have the
-root environment affect file naming</li>
-
-<li>
-<b>-verbose</b> produces verbose error output for the given which subsystem,
-using the <a href="../../docs/api_c/dbenv_set_verbose.html">DBENV->set_verbose</a>
-method.&nbsp;&nbsp; See the description of <a href="#> <env> verbose which on|off">verbose</a>
-below for valid <b><i>which </i></b>values</li>
-
-<li>
-<b>-region_init </b>specifies that the user wants to page fault the region
-in on startup using the <a href="../../docs/api_c/env_set_region_init.html">DBENV->set_region_init</a>
-method call</li>
-
-<li>
-<b>-cachesize </b>sets the size of the database cache to the size&nbsp;
-specified by <b><i>gbytes </i></b>and <b><i>bytes, </i></b>broken up into
-<b><i>ncaches</i></b>
-number of caches using the <a href="../../docs/api_c/env_set_cachesize.html">DBENV->set_cachesize</a>
-method</li>
-
-<li>
-<b>-mmapsize </b>sets the size of the database page to <b><i>size </i></b>using
-the <a href="../../docs/api_c/env_set_mp_mmapsize.html">DBENV->set_mp_mmapsize</a>
-method</li>
-
-<li>
-<b>-log_max </b>sets the maximum size of the log file to <b><i>max</i></b>
-using the <a href="../../docs/api_c/env_set_lg_max.html">DBENV->set_lg_max</a>
-call</li>
-
-<li>
-<b>-log_regionmax </b>sets the size of the log region to <b><i>max</i></b>
-using the <a href="../../docs/api_c/env_set_lg_regionmax.html">DBENV->set_lg_regionmax</a>
-call</li>
-
-<li>
-<b>-log_buffer </b>sets the size of the log file in bytes to <b><i>size</i></b>
-using the <a href="../../docs/api_c/env_set_lg_bsize.html">DBENV->set_lg_bsize</a>
-call</li>
-
-<li>
-<b>-lock_conflict </b>sets the number of lock modes to <b><i>nmodes</i></b>
-and sets the locking policy for those modes to the <b><i>conflict_matrix</i></b>
-given using the <a href="../../docs/api_c/env_set_lk_conflict.html">DBENV->set_lk_conflict</a>
-method call</li>
-
-<li>
-<b>-lock_detect </b>sets the deadlock detection policy to the given policy
-using the <a href="../../docs/env_set_lk_detect.html">DBENV->set_lk_detect</a>
-method call.&nbsp; The policy choices are:</li>
-
-<ul>
-<li>
-<b>default</b> selects the DB_LOCK_DEFAULT policy for default detection</li>
-
-<li>
-<b>oldest </b>selects DB_LOCK_OLDEST to abort the oldest locker on a deadlock</li>
-
-<li>
-<b>random</b> selects DB_LOCK_RANDOM to abort a random locker on a deadlock</li>
-
-<li>
-<b>youngest</b> selects DB_LOCK_YOUNGEST to abort the youngest locker on
-a deadlock</li>
-</ul>
-
-<li>
-<b>-lock_max_locks </b>sets the maximum number of locks to <b><i>max </i></b>using
-the <a href="../../docs/api_c/env_set_lk_max_locks.html">DBENV->set_lk_max_locks</a>
-method call</li>
-
-<li>
-<b>-lock_max_lockers </b>sets the maximum number of locking entities to
-<b><i>max
-</i></b>using the <a href="../../docs/api_c/env_set_lk_max_lockers.html">DBENV->set_lk_max_lockers</a>
-method call</li>
-
-<li>
-<b>-lock_max_objects </b>sets the maximum number of simultaneously locked
-objects to <b><i>max </i></b>using the <a href="../../docs/api_c/env_set_lk_max_objects.html">DBENV->set_lk_max_objects</a>
-method call</li>
-
-<li>
-<b>-lock_timeout </b>sets the timeout for locks in the environment</li>
-
-<li>
-<b>-overwrite </b>sets DB_OVERWRITE flag</li>
-
-<li>
-<b>-txn_max </b>sets the maximum size of the transaction table to <b><i>max</i></b>
-using the <a href="../../docs/api_c/env_set_txn_max.html">DBENV->set_txn_max</a>
-method call</li>
-
-<li>
-<b>-txn_timeout </b>sets the timeout for transactions in the environment</li>
-
-<li>
-<b>-client_timeout</b> sets the timeout value for the client waiting for
-a reply from the server for RPC operations to <b><i>seconds</i></b>.</li>
-
-<li>
-<b>-server_timeout</b> sets the timeout value for the server to determine
-an idle client is gone to <b><i>seconds</i></b>.</li>
-
-<li>
-<b>-server </b>specifies the <b><i>hostname</i></b> of the server
-to connect to in the <a href="../../docs/api_c/env_set_server.html">DBENV->set_server</a>
-call.</li>
-
-<li>
-<b>-rep_client </b>sets the newly created environment to be a
-replication client, using the <a href="../../docs/api_c/rep_client.html">
-DBENV->rep_client</a> call.</li>
-
-<li>
-<b>-rep_master </b>sets the newly created environment to be a
-replication master, using the <a href="../../docs/api_c/rep_master.html">
-DBENV->rep_master</a> call.</li>
-
-<li>
-<b>-rep_transport </b>specifies the replication transport function,
-using the
-<a href="../../docs/api_c/rep_transport.html">DBENV->rep_set_transport</a>
-call. This site's machine ID is set to <b><i>machineid</i></b> and
-the send function, a Tcl proc, is set to <b><i>sendproc</i></b>.</li>
-
-</ul>
-
-This command will invoke the <a href="../../docs/api_c/env_create.html">db_env_create</a>
-function.&nbsp; After it successfully gets a handle to an environment,
-we bind it to a new Tcl command of the form <b><i>envX</i></b>, where X
-is an integer starting at&nbsp; 0 (e.g. <b>env0, env1, </b>etc).&nbsp;
-We use the <i>Tcl_CreateObjCommand()</i> to create the top level environment
-command function.&nbsp; It is through this handle that the user can access
-all the commands described in the <a href="#Environment Commands">Environment
-Commands</a> section.&nbsp; Internally, the handle we get back from DB
-will be stored as the <i>ClientData</i> portion of the new command set
-so that all future environment calls will have that handle readily available.&nbsp;
-Then we call the <a href="../../docs/api_c/env_open.html">DBENV->open</a>
-method call and possibly some number of setup calls as described above.
-<p>
-<hr WIDTH="100%">
-<br><a NAME="> <env> verbose which on|off"></a><b>> &lt;env> verbose <i>which</i>
-on|off</b>
-<p>This command controls the use of debugging output for the environment.&nbsp;
-This command directly translates to a call to the <a href="../../docs/api_c/dbenv_set_verbose.html">DBENV->set_verbose</a>
-method call.&nbsp; It returns either a 0 (for success), a DB error message
-or it throws a Tcl error with a system message.&nbsp; The user specifies
-<b><i>which</i></b>
-subsystem to control, and indicates whether debug messages should be turned
-<b>on</b>
-or <b>off</b> for that subsystem.&nbsp; The value of <b><i>which</i></b>
-must be one of the following:
-<ul>
-<li>
-<b>deadlock </b>- Chooses the deadlocking code by using the DB_VERB_DEADLOCK
-value</li>
-
-<li>
-<b>recovery </b>- Chooses the recovery code by using the DB_VERB_RECOVERY
-value</li>
-
-<li>
-<b>wait </b>- Chooses the waitsfor code by using the DB_VERB_WAITSFOR value</li>
-</ul>
-
-<hr WIDTH="100%">
-<p><a NAME="> <env> close"></a><b>> &lt;env> close</b>
-<p>This command closes an environment and deletes the handle.&nbsp; This
-command directly translates to a call to the <a href="../../docs/api_c/env_close.html">DBENV->close</a>
-method call.&nbsp; It returns either a 0 (for success), a DB error message
-or it throws a Tcl error with a system message.
-<p>Additionally, since the handle is no longer valid, we will call <i>Tcl_DeleteCommand()
-</i>so
-that further uses of the handle will be dealt with properly by Tcl itself.
-<p>Also, the close command will automatically abort any <a href="txn.html">transactions</a>
-and close any <a href="mpool.html">mpool</a> memory files.&nbsp; As such
-we must maintain a list of open transaction and mpool handles so that we
-can call <i>Tcl_DeleteCommand</i> on those as well.
-<p>
-<hr WIDTH="100%">
-
-<b>> berkdb envremove<br>
-[-data_dir <i>directory</i>]<br>
-[-force]<br>
-[-home <i>directory</i>]<br>
-[-log_dir <i>directory</i>]<br>
-[-overwrite]<br>
-[-tmp_dir <i>directory</i>]<br>
-[-use_environ]<br>
-[-use_environ_root]</b>
-
-<p>This command removes the environment if it is not in use and deletes
-the handle.&nbsp; This command directly translates to a call to the <a href="../../docs/api_c/env_remove.html">DBENV->remove</a>
-method call.&nbsp; It returns either a 0 (for success), a DB error message
-or it throws a Tcl error with a system message.&nbsp; The arguments are:
-<ul>
-<li>
-<b>-force</b> selects the DB_FORCE flag to remove even if other processes
-have the environment open</li>
-
-<li>
-<b>-home <i>directory</i> </b>specifies the home directory of the environment</li>
-
-<li>
-<b>-data_dir <i>directory </i></b>selects the data file directory of the
-environment by calling <a href="../../docs/api_c/env_set_data_dir.html">DBENV->set_data_dir</a>.</li>
-
-<li>
-<b>-log_dir <i>directory </i></b>selects the log file directory of the
-environment&nbsp; by calling <a href="../../docs/api_c/env_set_lg_dir.html">DBENV->set_lg_dir</a>.</li>
-
-<li>
-<b>-overwrite </b>sets DB_OVERWRITE flag</li>
-
-<li>
-<b>-tmp_dir <i>directory </i></b>selects the temporary file directory of
-the environment&nbsp; by calling <a href="../../docs/api_c/env_set_tmp_dir.so">DBENV->set_tmp_dir</a>.</li>
-
-<li>
-<b>-use_environ </b>selects the DB_USE_ENVIRON flag to affect file naming</li>
-
-<li>
-<b>-use_environ_root</b> selects the DB_USE_ENVIRON_ROOT flag to affect
-file naming</li>
-</ul>
-
-</body>
-</html>
diff --git a/tcl/docs/historic.html b/tcl/docs/historic.html
deleted file mode 100644
index 97e33e6..0000000
--- a/tcl/docs/historic.html
+++ /dev/null
@@ -1,168 +0,0 @@
-<!--Copyright 1999-2009 Oracle. All rights reserved.-->
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.08 [en] (X11; I; FreeBSD 2.2.8-19990120-SNAP i386) [Netscape]">
-</HEAD>
-<BODY>
-
-<H2>
-<A NAME="Compatibility Commands"></A>Compatibility Commands</H2>
-The compatibility commands for old Dbm and Ndbm are described in the <A HREF="../../docs/api_c/dbm.html">dbm</A>
-manpage.
-<P><B>> berkdb dbminit <I>filename</I></B>
-<P>This command will invoke the dbminit function.&nbsp;&nbsp; <B><I>Filename</I></B>
-is used as the name of the database.
-<P>
-<HR WIDTH="100%"><B>> berkdb dbmclose</B>
-<P>This command will invoke the dbmclose function.
-<P>
-<HR WIDTH="100%"><B>> berkdb fetch <I>key</I></B>
-<P>This command will invoke the fetch function.&nbsp;&nbsp; It will return
-the data associated with the given <B><I>key </I></B>or a Tcl error.
-<P>
-<HR WIDTH="100%"><B>> berkdb store <I>key data</I></B>
-<P>This command will invoke the store function.&nbsp;&nbsp; It will store
-the <B><I>key/data</I></B> pair.&nbsp; It will return a 0 on success or
-throw a Tcl error.
-<P>
-<HR WIDTH="100%"><B>> berkdb delete <I>key</I></B>
-<P>This command will invoke the deletet function.&nbsp;&nbsp; It will delete
-the <B><I>key</I></B> from the database.&nbsp; It will return a 0 on success
-or throw a Tcl error.
-<P>
-<HR WIDTH="100%"><B>> berkdb firstkey</B>
-<P>This command will invoke the firstkey function.&nbsp;&nbsp; It will
-return the first key in the database or a Tcl error.
-<P>
-<HR WIDTH="100%"><B>> berkdb nextkey <I>key</I></B>
-<P>This command will invoke the nextkey function.&nbsp;&nbsp; It will return
-the next key after the given <B><I>key</I></B> or a Tcl error.
-<P>
-<HR WIDTH="100%"><B>> berkdb hcreate <I>nelem</I></B>
-<P>This command will invoke the hcreate function with <B><I>nelem</I></B>
-elements.&nbsp; It will return a 0 on success or a Tcl error.
-<P>
-<HR WIDTH="100%"><B>> berkdb hsearch <I>key data action</I></B>
-<P>This command will invoke the hsearch function with <B><I>key</I></B>
-and <B><I>data</I></B>.&nbsp; The <B><I>action</I></B> must be either <B>find</B>
-or <B>enter</B>.&nbsp; If it is <B>find</B>, it will return the resultant
-data.&nbsp; If it is <B>enter</B>, it will return a 0 on success or a Tcl
-error.
-<P>
-<HR WIDTH="100%"><B>> berkdb hdestroy</B>
-<P>This command will invoke the hdestroy function.&nbsp; It will return
-a 0.
-<HR WIDTH="100%"><B>> berkdb ndbm_open [-create] [-rdonly] [-truncate]
-[-mode
-<I>mode</I>] [--] <I>filename</I></B>
-<P>This command will invoke the dbm_open function.&nbsp;&nbsp;&nbsp; After
-it successfully gets a handle to a database, we bind it to a new Tcl command
-of the form <B><I>ndbmX, </I></B>where X is an integer starting at 0 (e.g.
-<B>ndbm0,
-ndbm1, </B>etc).&nbsp; We use the <I>Tcl_CreateObjCommand()&nbsp;</I> to
-create the top level database function.&nbsp; It is through this handle
-that the user can access all of the commands described below.&nbsp; Internally,
-the database handle is sent as the <I>ClientData</I> portion of the new
-command set so that all future database calls access the appropriate handle.
-<P>The arguments are:
-<UL>
-<LI>
-<B>-- </B>- Terminate the list of options and use remaining arguments as
-the file or subdb names (thus allowing the use of filenames beginning with
-a dash '-')</LI>
-
-<LI>
-<B>-create</B> selects the O_CREAT flag&nbsp; to create underlying files</LI>
-
-<LI>
-<B>-rdonly</B> selects the O_RDONLY flag for opening in read-only mode</LI>
-
-<LI>
-<B>-truncate</B> selects the O_TRUNC flag to truncate the database</LI>
-
-<LI>
-<B>-mode<I> mode</I></B> specifies the mode for created files</LI>
-
-<LI>
-<B><I>filename</I></B> indicates the name of the database</LI>
-</UL>
-
-<P><BR>
-<HR WIDTH="100%">
-<BR><B>> &lt;ndbm> close</B>
-<P>This command closes the database and renders the handle invalid.&nbsp;&nbsp;
-This command directly translates to the dbm_close function call.&nbsp;
-It returns either a 0 (for success),&nbsp; or it throws a Tcl error with
-a system message.
-<P>Additionally, since the handle is no longer valid, we will call <I>Tcl_DeleteCommand()
-</I>so
-that further uses of the handle will be dealt with properly by Tcl itself.&nbsp;
-<HR WIDTH="100%">
-<BR><B>> &lt;ndbm> clearerr</B>
-<P>This command clears errors&nbsp; the database.&nbsp;&nbsp; This command
-directly translates to the dbm_clearerr function call.&nbsp; It returns
-either a 0 (for success),&nbsp; or it throws a Tcl error with a system
-message.
-<P>
-<HR WIDTH="100%">
-<BR><B>> &lt;ndbm> delete <I>key</I></B>
-<P>This command deletes the <B><I>key</I></B> from thedatabase.&nbsp;&nbsp;
-This command directly translates to the dbm_delete function call.&nbsp;
-It returns either a 0 (for success),&nbsp; or it throws a Tcl error with
-a system message.
-<P>
-<HR WIDTH="100%">
-<BR><B>> &lt;ndbm> dirfno</B>
-<P>This command directly translates to the dbm_dirfno function call.&nbsp;
-It returns either resultts,&nbsp; or it throws a Tcl error with a system
-message.
-<P>
-<HR WIDTH="100%">
-<BR><B>> &lt;ndbm> error</B>
-<P>This command returns the last error.&nbsp;&nbsp; This command directly
-translates to the dbm_error function call.&nbsp; It returns an error string..
-<P>
-<HR WIDTH="100%">
-<BR><B>> &lt;ndbm> fetch <I>key</I></B>
-<P>This command gets the given <B><I>key</I></B> from the database.&nbsp;&nbsp;
-This command directly translates to the dbm_fetch function call.&nbsp;
-It returns either the data,&nbsp; or it throws a Tcl error with a system
-message.
-<P>
-<HR WIDTH="100%">
-<BR><B>> &lt;ndbm> firstkey</B>
-<P>This command returns the first key in the database.&nbsp;&nbsp; This
-command directly translates to the dbm_firstkey function call.&nbsp; It
-returns either the key,&nbsp; or it throws a Tcl error with a system message.
-<P>
-<HR WIDTH="100%">
-<BR><B>> &lt;ndbm> nextkey</B>
-<P>This command returns the next key in the database.&nbsp;&nbsp; This
-command directly translates to the dbm_nextkey function call.&nbsp; It
-returns either the key,&nbsp; or it throws a Tcl error with a system message.
-<P>
-<HR WIDTH="100%">
-<BR><B>> &lt;ndbm> pagfno</B>
-<P>This command directly translates to the dbm_pagfno function call.&nbsp;
-It returns either resultts,&nbsp; or it throws a Tcl error with a system
-message.
-<BR>
-<HR WIDTH="100%">
-<BR><B>> &lt;ndbm> rdonly</B>
-<P>This command changes the database to readonly.&nbsp;&nbsp; This command
-directly translates to the dbm_rdonly function call.&nbsp; It returns either
-a 0 (for success),&nbsp; or it throws a Tcl error with a system message.
-<P>
-<HR WIDTH="100%">
-<BR><B>> &lt;ndbm> store <I>key data </I>insert|replace</B>
-<P>This command puts the given <B><I>key</I></B> and <B><I>data</I></B>
-pair into the database.&nbsp;&nbsp; This command directly translates to
-the dbm_store function call.&nbsp; It will either <B>insert</B> or <B>replace</B>
-the data based on the action given in the third argument.&nbsp; It returns
-either a 0 (for success),&nbsp; or it throws a Tcl error with a system
-message.
-<BR>
-<HR WIDTH="100%">
-</BODY>
-</HTML>
diff --git a/tcl/docs/index.html b/tcl/docs/index.html
deleted file mode 100644
index ae35bd6..0000000
--- a/tcl/docs/index.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!--Copyright 1999-2009 Oracle. All rights reserved.-->
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.08 [en] (X11; I; FreeBSD 2.2.8-19990120-SNAP i386) [Netscape]">
-</HEAD>
-<BODY>
-
-<CENTER>
-<H1>
-Complete Tcl Interface for Berkeley DB</H1></CENTER>
-
-<UL type=disc>
-<LI>
-<A HREF="../../docs/api_tcl/tcl_index.html">General use Berkeley DB commands</A></LI>
-</UL>
-
-<UL type=disc>
-<LI>
-<A HREF="./env.html">Environment commands</A></LI>
-
-<LI>
-<A HREF="./lock.html">Locking commands</A></LI>
-
-<LI>
-<A HREF="./log.html">Logging commands</A></LI>
-
-<LI>
-<A HREF="./mpool.html">Memory Pool commands</A></LI>
-
-<LI>
-<A HREF="./rep.html">Replication commands</A></LI>
-
-<LI>
-<A HREF="./txn.html">Transaction commands</A></LI>
-</UL>
-
-<UL>
-<LI>
-<A HREF="./db.html">Access Method commands</A></LI>
-
-<LI>
-<A HREF="./test.html">Debugging and Testing</A></LI>
-
-<LI>
-<A HREF="./historic.html">Compatibility commands</A></LI>
-
-<LI>
-<A HREF="./library.html">Convenience commands</A></LI>
-</UL>
diff --git a/tcl/docs/library.html b/tcl/docs/library.html
deleted file mode 100644
index a56898e..0000000
--- a/tcl/docs/library.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--Copyright 1999-2009 Oracle. All rights reserved.-->
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.08 [en] (X11; I; FreeBSD 2.2.8-19990120-SNAP i386) [Netscape]">
-</HEAD>
-<BODY>
-<HR WIDTH="100%">
-<H2>
-<A NAME="Convenience Commands"></A>Convenience Commands</H2>
-The convenience commands are provided for ease of use with the DB test
-suite.
-<P><B>> berkdb rand</B>
-<P>This command will invoke the rand function and return the random number.
-<P>
-<HR WIDTH="100%"><B>> berkdb random_int <I>low high</I></B>
-<P>This command will invoke the rand function and return a number between
-<B><I>low</I></B>
-and <B><I>high</I></B>.
-<P>
-<HR WIDTH="100%">
-<P><B>> berkdb srand <I>seed</I></B>
-<P>This command will invoke the srand function with the given <B><I>seed</I></B>
-and return 0.
-<P>
-<HR WIDTH="100%">
diff --git a/tcl/docs/lock.html b/tcl/docs/lock.html
deleted file mode 100644
index abd15c2..0000000
--- a/tcl/docs/lock.html
+++ /dev/null
@@ -1,206 +0,0 @@
-<!--Copyright 1999-2009 Oracle. All rights reserved.-->
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <meta name="GENERATOR" content="Mozilla/4.75 [en] (X11; U; Linux 2.2.16-22 i686) [Netscape]">
-</head>
-<body>
-
-<h2>
-<a NAME="Locking Commands"></a>Locking Commands</h2>
-Most locking commands work with the environment handle.&nbsp; However,
-when a user gets a lock we create a new lock handle that they then use
-with in a similar manner to all the other handles to release the lock.&nbsp;
-We present the general locking functions first, and then those that manipulate
-locks.
-<p><b>> &lt;env> lock_detect [default|oldest|youngest|random]</b>
-<p>This command runs the deadlock detector.&nbsp; It directly translates
-to the <a href="../../docs/api_c/lock_detect.html">lock_detect</a> DB call.&nbsp;
-It returns either a 0 (for success), a DB error message or it throws a
-Tcl error with a system message.&nbsp; The first argument sets the policy
-for deadlock as follows:
-<ul>
-<li>
-<b>default</b> selects the DB_LOCK_DEFAULT policy for default detection
-(default if not specified)</li>
-
-<li>
-<b>oldest </b>selects DB_LOCK_OLDEST to abort the oldest locker on a deadlock</li>
-
-<li>
-<b>random</b> selects DB_LOCK_RANDOM to abort a random locker on a deadlock</li>
-
-<li>
-<b>youngest</b> selects DB_LOCK_YOUNGEST to abort the youngest locker on
-a deadlock</li>
-</ul>
-
-<hr WIDTH="100%">
-<br><b>> &lt;env> lock_stat</b>
-<p>This command returns a list of name/value pairs where the names correspond
-to the C-structure field names of DB_LOCK_STAT and the values are the data
-returned.&nbsp; This command is a direct translation of the <a href="../../docs/api_c/lock_stat.html">lock_stat</a>
-DB call.
-<hr WIDTH="100%">
-<br><a NAME="> <env> lock_id"></a><b>> &lt;env> lock_id</b>
-<p>This command returns a unique locker ID value.&nbsp; It directly translates
-to the <a href="../../docs/api_c/lock_id.html">lock_id</a> DB call.
-<br>
-<hr WIDTH="100%">
-<br><a NAME="> <env> lock_id"></a><b>> &lt;env> lock_id_free&nbsp; </b><i>locker</i>
-<p>This command frees the locker allockated by the lock_id call. It directly
-translates to the&nbsp; <a href="../../docs/api_c/lock_id.html">lock_id_free
-</a>DB
-call.
-<hr WIDTH="100%">
-<br><a NAME="> <env> lock_id"></a><b>> &lt;env> lock_id_set&nbsp; </b><i>current
-max</i>
-<p>This&nbsp; is a diagnostic command to set the locker id that will get
-allocated next and the maximum id that
-<br>will trigger the id reclaim algorithm.
-<hr WIDTH="100%">
-<br><a NAME="> <env> lock_get"></a><b>> &lt;env> lock_get [-nowait]<i>lockmode
-locker obj</i></b>
-<p>This command gets a lock. It will invoke the <a href="../../docs/api_c/lock_get.html">lock_get</a>
-function.&nbsp; After it successfully gets a handle to a lock, we bind
-it to a new Tcl command of the form <b><i>$env.lockX</i></b>, where X is
-an integer starting at&nbsp; 0 (e.g. <b>$env.lock0, $env.lock1, </b>etc).&nbsp;
-We use the <i>Tcl_CreateObjCommand()</i> to create the top level locking
-command function.&nbsp; It is through this handle that the user can release
-the lock.&nbsp; Internally, the handle we get back from DB will be stored
-as the <i>ClientData</i> portion of the new command set so that future
-locking calls will have that handle readily available.
-<p>The arguments are:
-<ul>
-<li>
-<b><i>locker</i></b> specifies the locker ID returned from the <a href="#> <env> lock_id">lock_id</a>
-command</li>
-
-<li>
-<b><i>obj</i></b> specifies an object to lock</li>
-
-<li>
-the <b><i>lock mode</i></b> is specified as one of the following:</li>
-
-<ul>
-<li>
-<b>ng </b>specifies DB_LOCK_NG for not granted (always 0)</li>
-
-<li>
-<b>read</b> specifies DB_LOCK_READ for a read (shared) lock</li>
-
-<li>
-<b>write</b> specifies DB_LOCK_WRITE for an exclusive write lock</li>
-
-<li>
-<b>iwrite </b>specifies DB_LOCK_IWRITE for intent for exclusive write lock</li>
-
-<li>
-<b>iread </b>specifies DB_LOCK_IREAD for intent for shared read lock</li>
-
-<li>
-<b>iwr </b>specifies DB_LOCK_IWR for intent for eread and write lock</li>
-</ul>
-
-<li>
-<b>-nowait</b> selects the DB_LOCK_NOWAIT to indicate that we do not want
-to wait on the lock</li>
-</ul>
-
-<hr WIDTH="100%">
-<br><b>> &lt;lock> put</b>
-<p>This command releases the lock referenced by the command.&nbsp; It is
-a direct translation of the <a href="../../docs/api_c/lock_put.html">lock_put</a>
-function.&nbsp; It returns either a 0 (for success), a DB error message
-or it throws a Tcl error with a system message.&nbsp; Additionally, since
-the handle is no longer valid, we will call
-<i>Tcl_DeleteCommand()
-</i>so
-that further uses of the handle will be dealt with properly by Tcl itself.
-<br>
-<hr WIDTH="100%">
-<br><a NAME="> <env> lock_vec"></a><b>> &lt;env> lock_vec [-nowait] <i>locker
-</i>{get|put|put_all|put_obj
-[<i>obj</i>] [<i>lockmode</i>] [<i>lock</i>]} ...</b>
-<p>This command performs a series of lock calls.&nbsp; It is a direct translation
-of the <a href="../../docs/api_c/lock_vec.html">lock_vec</a> function.&nbsp;
-This command will return a list of the return values from each operation
-specified in the argument list.&nbsp; For the 'put' operations the entry
-in the return value list is either a 0 (for success) or an error.&nbsp;
-For the 'get' operation, the entry is the lock widget handle, <b>$env.lockN</b>
-(as described above in <a href="#> <env> lock_get">&lt;env> lock_get</a>)
-or an error.&nbsp; If an error occurs, the return list will contain the
-return values for all the successful operations up the erroneous one and
-the error code for that operation.&nbsp; Subsequent operations will be
-ignored.
-<p>As for the other operations, if we are doing a 'get' we will create
-the commands and if we are doing a 'put' we will have to delete the commands.&nbsp;
-Additionally, we will have to do this after the call to the DB lock_vec
-and iterate over the results, creating and/or deleting Tcl commands.&nbsp;
-It is possible that we may return a lock widget from a get operation that
-is considered invalid, if, for instance, there was a <b>put_all</b> operation
-performed later in the vector of operations.&nbsp; The arguments are:
-<ul>
-<li>
-<b><i>locker</i></b> specifies the locker ID returned from the <a href="#> <env> lock_id">lock_id</a>
-command</li>
-
-<li>
-<b>-nowait</b> selects the DB_LOCK_NOWAIT to indicate that we do not want
-to wait on the lock</li>
-
-<li>
-the lock vectors are tuple consisting of {an operation, lock object, lock
-mode, lock handle} where what is required is based on the operation desired:</li>
-
-<ul>
-<li>
-<b>get</b> specifes DB_LOCK_GET to get a lock.&nbsp; Requires a tuple <b>{get
-<i>objmode</i>}
-</b>where
-<b><i>mode</i></b>
-is:</li>
-
-<ul>
-<li>
-<b>ng </b>specifies DB_LOCK_NG for not granted (always 0)</li>
-
-<li>
-<b>read</b> specifies DB_LOCK_READ for a read (shared) lock</li>
-
-<li>
-<b>write</b> specifies DB_LOCK_WRITE for an exclusive write lock</li>
-
-<li>
-<b>iwrite </b>specifies DB_LOCK_IWRITE for intent for exclusive write lock</li>
-
-<li>
-<b>iread </b>specifies DB_LOCK_IREAD for intent for shared read lock</li>
-
-<li>
-<b>iwr </b>specifies DB_LOCK_IWR for intent for eread and write lock</li>
-</ul>
-
-<li>
-<b>put</b> specifies DB_LOCK_PUT to release a <b><i>lock</i></b>.&nbsp;
-Requires a tuple <b>{put <i>lock}</i></b></li>
-
-<li>
-<b>put_all </b>specifies DB_LOCK_PUT_ALL to release all locks held by <b><i>locker</i></b>.&nbsp;
-Requires a tuple <b>{put_all}</b></li>
-
-<li>
-<b>put_obj</b> specifies DB_LOCK_PUT_OBJ to release all locks held by <b><i>locker</i></b>
-associated with the given <b><i>obj</i></b>.&nbsp; Requires a tuple <b>{put_obj
-<i>obj}</i></b></li>
-</ul>
-</ul>
-
-<hr WIDTH="100%">
-<br><a NAME="> <env> lock_vec"></a><b>> &lt;env> lock_timeout <i>timeout</i></b>
-<p>This command sets the lock timeout for all future locks in this environment.&nbsp;
-The timeout is in micorseconds.
-<br>&nbsp;
-<br>&nbsp;
-</body>
-</html>
diff --git a/tcl/docs/log.html b/tcl/docs/log.html
deleted file mode 100644
index 02cd399..0000000
--- a/tcl/docs/log.html
+++ /dev/null
@@ -1,123 +0,0 @@
-<!--Copyright 1999-2009 Oracle. All rights reserved.-->
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.08 [en] (X11; I; FreeBSD 3.3-RELEASE i386) [Netscape]">
-</HEAD>
-<BODY>
-
-<H2>
-<A NAME="Logging Commands"></A>Logging Commands</H2>
-Logging commands work from the environment handle to control the use of
-the log files.&nbsp; Log files are opened when the environment is opened
-and closed when the environment is closed.&nbsp; In all of the commands
-in the logging subsystem that take or return a log sequence number, it
-is of the form:
-<BR><B>{<I>fileid offset</I>}</B>
-<BR>where the <B><I>fileid</I></B> is an identifier of the log file, as
-returned from the <A HREF="#> <env> log_get">log_get</A> call.
-<P><B>> &lt;env> log_archive [-arch_abs] [-arch_data] [-arch_log]</B>
-<P>This command returns&nbsp; a list of log files that are no longer in
-use.&nbsp; It is a direct call to the <A HREF="../../docs/api_c/log_archive.html">log_archive</A>
-function. The arguments are:
-<UL>
-<LI>
-<B>-arch_abs </B>selects DB_ARCH_ABS to return all pathnames as absolute
-pathnames</LI>
-
-<LI>
-<B>-arch_data </B>selects DB_ARCH_DATA to return a list of database files</LI>
-
-<LI>
-<B>-arch_log </B>selects DB_ARCH_LOG to return a list of log files</LI>
-</UL>
-
-<HR WIDTH="100%">
-<BR><B>> &lt;env> log_compare <I>lsn1 lsn2</I></B>
-<P>This command compares two log sequence numbers, given as <B><I>lsn1</I></B>
-and <B><I>lsn2</I></B>.&nbsp; It is a direct call to the <A HREF="../../docs/api_c/log_compare.html">log_compare</A>
-function.&nbsp; It will return a -1, 0, 1 to indicate if <B><I>lsn1</I></B>
-is less than, equal to or greater than <B><I>lsn2</I></B> respectively.
-<BR>
-<HR WIDTH="100%">
-<BR><B>> &lt;env> log_file <I>lsn</I></B>
-<P>This command returns&nbsp; the file name associated with the given <B><I>lsn</I></B>.&nbsp;
-It is a direct call to the <A HREF="../../docs/api_c/log_file.html">log_file</A>
-function.
-<BR>
-<HR WIDTH="100%">
-<BR><B>> &lt;env> log_flush [<I>lsn</I>]</B>
-<P>This command&nbsp; flushes the log up to the specified <B><I>lsn</I></B>
-or flushes all records if none is given&nbsp; It is a direct call to the
-<A HREF="../../docs/api_c/log_flush.html">log_flush</A>
-function.&nbsp; It returns either a 0 (for success), a DB error message
-or it throws a Tcl error with a system message.
-<BR>
-<HR WIDTH="100%">
-<BR><A NAME="<env> log_get"></A><B>> &lt;env> log_get<I> </I>[-checkpoint]
-[-current] [-first] [-last] [-next] [-prev] [-set <I>lsn</I>]</B>
-<P>This command retrieves a record from the log according to the <B><I>lsn</I></B>
-given and returns it and the data.&nbsp; It is a direct call to the <A HREF="../../docs/api_c/log_get.html">log_get</A>
-function.&nbsp; It is a way of implementing a manner of log iteration similar
-to <A HREF="../../docs/api_tcl/db_cursor.html">cursors</A>.&nbsp;&nbsp;
-The information we return is similar to database information.&nbsp; We
-return a list where the first item is the LSN (which is a list itself)
-and the second item is the data.&nbsp; So it looks like, fully expanded,
-<B>{{<I>fileid</I>
-<I>offset</I>}
-<I>data</I>}.</B>&nbsp;
-In the case where DB_NOTFOUND is returned, we return an empty list <B>{}</B>.&nbsp;
-All other errors return a Tcl error.&nbsp; The arguments are:
-<UL>
-<LI>
-<B>-checkpoint </B>selects the DB_CHECKPOINT flag to return the LSN/data
-pair of the last record written through <A HREF="#> <env> log_put">log_put</A>
-with DB_CHECKPOINT specified</LI>
-
-<LI>
-<B>-current</B> selects the DB_CURRENT flag to return the current record</LI>
-
-<LI>
-<B>-first</B> selects the DB_FIRST flag to return the first record in the
-log.</LI>
-
-<LI>
-<B>-last </B>selects the DB_LAST flag to return the last record in the
-log.</LI>
-
-<LI>
-<B>-next</B> selects the DB_NEXT flag to return the next record in the
-log.</LI>
-
-<LI>
-<B>-prev </B>selects the DB_PREV flag to return the&nbsp; previous record
-in the log.</LI>
-
-<LI>
-<B>-set</B> selects the DB_SET flag to return the record specified by the
-given <B><I>lsn</I></B></LI>
-</UL>
-
-<HR WIDTH="100%">
-<BR><A NAME="> <env> log_put"></A><B>> &lt;env> log_put<I> </I>[-checkpoint]
-[-flush] <I>record</I></B>
-<P>This command stores a <B><I>record</I></B> into the log and returns
-the LSN of the log record.&nbsp; It is a direct call to the <A HREF="../../docs/api_c/log_put.html">log_put</A>
-function.&nbsp; It returns either an LSN or it throws a Tcl error with
-a system message.&nbsp;<B> </B>The arguments are:
-<UL>
-<LI>
-<B>-checkpoint </B>selects the DB_CHECKPOINT flag</LI>
-
-<LI>
-<B>-flush </B>selects the DB_FLUSH flag to flush the log to disk.</LI>
-</UL>
-
-<HR WIDTH="100%">
-<BR><B>> &lt;env> log_stat</B>
-<P>This command returns&nbsp; the statistics associated with the logging
-subsystem.&nbsp; It is a direct call to the <A HREF="../../docs/api_c/log_stat.html">log_stat</A>
-function.&nbsp; It returns a list of name/value pairs of the DB_LOG_STAT
-structure.
-</BODY>
-</HTML>
diff --git a/tcl/docs/mpool.html b/tcl/docs/mpool.html
deleted file mode 100644
index 25967e3..0000000
--- a/tcl/docs/mpool.html
+++ /dev/null
@@ -1,189 +0,0 @@
-<!--Copyright 1999-2009 Oracle. All rights reserved.-->
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.08 [en] (X11; I; FreeBSD 2.2.8-19990120-SNAP i386) [Netscape]">
-</HEAD>
-<BODY>
-
-<H2>
-<A NAME="Memory Pool Commands"></A>Memory Pool Commands</H2>
-Memory pools are used in a manner similar to the other subsystems.&nbsp;
-We create a handle to the pool and&nbsp; then use it for a variety of operations.&nbsp;
-Some of the memory pool commands use the environment instead. Those are
-presented first.
-<P><B>> &lt;env> mpool_stat</B>
-<P>This command returns&nbsp; the statistics associated with the memory
-pool subsystem.&nbsp; It is a direct call to the <A HREF="../../docs/api_c/memp_stat.html">memp_stat</A>
-function.&nbsp; It returns a list of name/value pairs of the DB_MPOOL_STAT
-structure.
-<BR>
-<HR WIDTH="100%">
-<BR><B>> &lt;env> mpool_sync <I>lsn</I></B>
-<P>This command flushes the memory pool for all pages with a log sequence
-number less than <B><I>lsn</I></B>.&nbsp; It is a direct call to the <A HREF="../../docs/api_c/memp_sync.html">memp_sync&nbsp;</A>
-function.&nbsp; It returns either a 0 (for success), a DB error message
-or it throws a Tcl error with a system message.
-<BR>
-<HR WIDTH="100%">
-<BR><B>> &lt;env> mpool_trickle <I>percent</I></B>
-<P>This command tells DB to ensure that at least <B><I>percent</I></B>
-percent of the pages are clean by writing out enough to dirty pages to
-achieve that percentage.&nbsp; It is a direct call to the <A HREF="../../docs/api_c/memp_trickle.html">memp_trickle</A>
-function.&nbsp; The command will return the number of pages actually written.&nbsp;
-It returns either the number of pages on success, or it throws a Tcl error
-with a system message.
-<BR>
-<HR WIDTH="100%">
-<P><B>> &lt;env> mpool [-create] [-nommap] [-rdonly] [-mode <I>mode</I>]
--pagesize <I>size</I> [<I>file</I>]</B>
-<P>This command creates a new memory pool.&nbsp; It invokes the <A HREF="../../docs/api_c/memp_fopen.html">memp_fopen</A>
-function.&nbsp; After it successfully gets a handle to a memory pool, we
-bind it to a new Tcl command of the form <B><I>$env.mpX</I></B>, where
-X is an integer starting at&nbsp; 0 (e.g. <B>$env.mp0, $env.mp1, </B>etc).&nbsp;
-We use the <I>Tcl_CreateObjCommand()</I> to create the top level memory
-pool functions.&nbsp; It is through this handle that the user can manipulate
-the pool.&nbsp; Internally, the handle we get back from DB will be stored
-as the <I>ClientData</I> portion of the new command set so that future
-memory pool calls will have that handle readily available.&nbsp; Additionally,
-we need to maintain this handle in relation to the environment so that
-if the user calls <A HREF="../../docs/api_tcl/env_close.html">&lt;env> close</A> without closing
-the memory pool we can properly clean up.&nbsp; The arguments are:
-<UL>
-<LI>
-<B><I>file</I></B> is the name of the file to open</LI>
-
-<LI>
-<B>-create </B>selects the DB_CREATE flag to create underlying file</LI>
-
-<LI>
-<B>-mode <I>mode </I></B>sets the permissions of created file to <B><I>mode</I></B></LI>
-
-<LI>
-<B>-nommap</B> selects the DB_NOMMAP flag to disallow using mmap'ed files</LI>
-
-<LI>
-<B>-pagesize</B> sets the underlying file page size to <B><I>size</I></B></LI>
-
-<LI>
-<B>-rdonly </B>selects the DB_RDONLY flag for read only access</LI>
-</UL>
-
-<HR WIDTH="100%">
-<BR><B>> &lt;mp> close</B>
-<P>This command closes the memory pool.&nbsp; It is a direct call to the
-<A HREF="../../docs/api_c/memp_fclose.html">memp_close</A>
-function.&nbsp; It returns either a 0 (for success), a DB error message
-or it throws a Tcl error with a system message.
-<P>Additionally, since the handle is no longer valid, we will call
-<I>Tcl_DeleteCommand()
-</I>so
-that further uses of the handle will be dealt with properly by Tcl itself.&nbsp;
-We must also remove the reference to this handle from the environment.&nbsp;
-We will go through the list of pinned pages that were acquired by the <A HREF="#> <mp> get">get</A>
-command and
-<A HREF="#> <pg> put">put</A> them back.
-<HR WIDTH="100%">
-<BR><B>> &lt;mp> fsync</B>
-<P>This command flushes all of the file's dirty pages to disk.&nbsp; It
-is a direct call to the <A HREF="../../docs/api_c/memp_fsync.html">memp_fsync</A>
-function.&nbsp; It returns either a 0 (for success), a DB error message
-or it throws a Tcl error with a system message.
-<HR WIDTH="100%">
-<BR><A NAME="> <mp> get"></A><B>> &lt;mp> get [-create] [-last] [-new]
-[<I>pgno</I>]</B>
-<P>This command gets the&nbsp; <B><I>pgno </I></B>page from the memory
-pool.&nbsp; It invokes the <A HREF="../../docs/api_c/memp_fget.html">memp_fget</A>
-function and possibly the <A HREF="../../docs/api_c/memp_fset.html">memp_fset</A>
-function if any options are chosen to set the page characteristics.&nbsp;
-After it successfully gets a handle to a page,&nbsp; we bind it to and
-return a new Tcl command of the form <B><I>$env.mpN.pX</I></B>, where X
-is an integer starting at&nbsp; 0 (e.g. <B>$env.mp0.p0, $env.mp1.p0, </B>etc).&nbsp;
-We use the <I>Tcl_CreateObjCommand()</I> to create the top level page functions.&nbsp;
-It is through this handle that the user can manipulate the page.&nbsp;
-Internally, the handle we get back from DB will be stored as the <I>ClientData</I>
-portion of the new command set.&nbsp; We need to store this handle in&nbsp;
-relation to the memory pool handle so that if the memory pool is closed,
-we will <A HREF="#> <pg> put">put</A> back the pages (setting the discard
-flag) and delete that set of commands.
-<P>The arguments are:
-<UL>
-<LI>
-<B>-create </B>selects the DB_MPOOL_CREATE flag&nbsp; to create the page
-if it does not exist.</LI>
-
-<LI>
-<B>-last</B> selects the DB_MPOOL_LAST flag to return the last page in
-the file</LI>
-
-<LI>
-<B>-new</B> selects the DB_MPOOL_NEW flag to create a new page</LI>
-</UL>
-
-<HR WIDTH="100%">
-<BR><B>> &lt;pg> pgnum</B>
-<P>This command returns the page number associated with this memory pool
-page.&nbsp; Primarily it will be used after an <A HREF="#> <mp> get">&lt;mp>
-get</A> call.
-<BR>
-<HR WIDTH="100%"><B>> &lt;pg> pgsize</B>
-<P>This command returns the page size associated with this memory pool
-page.&nbsp; Primarily it will be used after an <A HREF="#> <mp> get">&lt;mp>
-get</A> call.
-<BR>
-<HR WIDTH="100%"><B>> &lt;pg> set [-clean] [-dirty] [-discard]</B>
-<P>This command sets the characteristics of the page.&nbsp; It is a direct
-call to the <A HREF="../../docs/api_c/memp_fset.html">memp_fset</A> function.&nbsp;
-It returns either a 0 (for success), a DB error message or it throws a
-Tcl error with a system message.&nbsp; The arguments are:
-<UL>
-<LI>
-<B>-clean</B> selects the DB_MPOOL_CLEAN flag to indicate this is a clean
-page</LI>
-
-<LI>
-<B>-dirty</B> selects the DB_MPOOL_DIRTY flag to indicate this page should
-be flushed before eviction</LI>
-
-<LI>
-<B>-discard</B> selects the DB_MPOOL_DISCARD flag to indicate this page
-is unimportant</LI>
-</UL>
-
-<HR WIDTH="100%">
-<BR><A NAME="> <pg> put"></A><B>> &lt;pg> put [-clean] [-dirty] [-discard]</B>
-<P>This command will put back the page to the memory pool.&nbsp; It is
-a direct call to the <A HREF="../../docs/api_c/memp_fput.html">memp_fput</A>
-function.&nbsp; It returns either a 0 (for success), a DB error message
-or it throws a Tcl error with a system message. Additionally, since the
-handle is no longer valid, we will call
-<I>Tcl_DeleteCommand()
-</I>so that
-further uses of the handle will be dealt with properly by Tcl itself.&nbsp;
-We must also remove the reference to this handle from the memory pool.
-<P>The arguments are:
-<UL>
-<LI>
-<B>-clean</B> selects the DB_MPOOL_CLEAN flag to indicate this is a clean
-page</LI>
-
-<LI>
-<B>-dirty</B> selects the DB_MPOOL_DIRTY flag to indicate this page should
-be flushed before eviction</LI>
-
-<LI>
-<B>-discard</B> selects the DB_MPOOL_DISCARD flag to indicate this page
-is unimportant</LI>
-</UL>
-
-<HR WIDTH="100%">
-<BR><B>> &lt;pg> init <I>val|string</I></B>
-<P>This command initializes the page to the <B><I>val</I></B> given or
-places the <B><I>string</I></B> given at the beginning of the page.&nbsp;
-It returns a 0 for success or it throws a Tcl error with an error message.
-<P>
-<HR WIDTH="100%">
-<BR><B>> &lt;pg> is_setto <I>val|string</I></B>
-<P>This command verifies the page contains the <B><I>val</I></B> given
-or checks that the <B>string</B> given is at the beginning of the page.&nbsp;
-It returns a 1 if the page is correctly set to the value and a 0 otherwise.
diff --git a/tcl/docs/rep.html b/tcl/docs/rep.html
deleted file mode 100644
index 3c1e49c..0000000
--- a/tcl/docs/rep.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!--Copyright 1999-2009 Oracle. All rights reserved.-->
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <title>Replication commands</title>
-</head>
-<body>
-
-<h2>
-<a NAME="Replication Commands"></a>Replication Commands</h2>
-Replication commands are invoked from the environment handle, after
-it has been opened with the appropriate flags defined
-<a href="./env.html">here</a>.<br>
-<hr WIDTH="100%">
-<p><b>> &lt;env> rep_process_message <i>machid</i> <i>control</i>
-<i>rec</i></b>
-<p>This command processes a single incoming replication message.&nbsp; It
-is a direct translation of the <a
-href="../../docs/api_c/rep_process_message.html">rep_process_message</a>
-function.&nbsp;
-It returns either a 0 (for success), a DB error message or it throws a
-Tcl error with a system message.&nbsp; The arguments are:
-<ul>
-<li>
-<b>machid </b>is the machine ID of the machine that <i>sent</i> this
-message.</li>
-
-<li>
-<b>control</b> is a binary string containing the exact contents of the
-<b><i>control</i></b> argument to the <b><i>sendproc</i></b> function
-that was passed this message on another site.</li>
-
-<li>
-<b>rec</b> is a binary string containing the exact contents of the
-<b><i>rec</i></b> argument to the <b><i>sendproc</i></b> function
-that was passed this message on another site.</li>
-</ul>
-
-<hr WIDTH="100%">
-<br><b>> &lt;env> rep_elect <i>nsites</i> <i>pri</i> <i>wait</i>
-<i>sleep</i></b>
-<p>This command causes a replication election.&nbsp; It is a direct translation
-of the <a href="../../docs/api_c/rep_elect.html">rep_elect</a> function.&nbsp;
-Its arguments, all integers, correspond exactly to that C function's
-parameters.
-It will return a list containing two integers, which contain,
-respectively, the integer values returned in the C function's
-<i><b>midp</b></i> and <i><b>selfp</b></i> parameters.
-</body>
-</html>
diff --git a/tcl/docs/sequence.html b/tcl/docs/sequence.html
deleted file mode 100644
index 4aceab8..0000000
--- a/tcl/docs/sequence.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<!--Copyright 1999-2009 Oracle. All rights reserved.-->
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
- <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
- <title>Sequence Commands</title>
-</head>
-<body>
-<h2><a name="Database Commands"></a>Sequence Commands</h2>
-<b>&gt; berkdb sequence [-auto_commit] [-txn txnid] [-create] </b><br>
-<div style="margin-left: 40px;">&nbsp;Implements <a
- href="file:///home/ubell/db.new/docs/seq/seq_open.html">DBENV-&gt;sequence</a>
-function. The above options have the usual meanings.<br>
-</div>
-<span style="font-weight: bold;">[-cachesize]</span><br>
-<div style="margin-left: 40px;">Set the size of the cache in this
-handle.<br>
-</div>
-<span style="font-weight: bold;">[-inc]<br>
-</span>
-<div style="margin-left: 40px;">Sequence increments..<br>
-</div>
-<span style="font-weight: bold;">[-dec]<br>
-</span>
-<div style="margin-left: 40px;">Sequence decrements.<br>
-</div>
-<span style="font-weight: bold;">[-init integer]<br>
-</span>
-<div style="margin-left: 40px;">Set the initial value for sequence.<br>
-</div>
-<span style="font-weight: bold;">[-max integer]</span><br>
-<div style="margin-left: 40px;">Set the maximum value for the sequence.<br>
-</div>
-<span style="font-weight: bold;">[-max integer]<br>
-</span>
-<div style="margin-left: 40px;">Set the minimum value for the sequence.<br>
-</div>
-<span style="font-weight: bold;">[-wrap]</span><br>
-<div style="margin-left: 40px;">Wrap around at max or min.<br>
-</div>
-<span style="font-weight: bold;"><span style="font-style: italic;">db</span>
-key<br>
-</span>
-<div style="margin-left: 40px;">Database handle and key of sequence.<br>
-</div>
-<hr width="100%"><span style="font-style: italic;"><span
- style="font-weight: bold;">&gt; seq </span></span><span
- style="font-weight: bold;">get [-txn <span style="font-style: italic;">txn</span>]
-[-auto_commit] [-nosync] delta<br>
-</span>
-<div style="margin-left: 40px;">Get the nexted sequence value and
-increment the sequence by <span style="font-weight: bold;">delta</span>.<br>
-</div>
-<hr width="100%"><span style="font-weight: bold;">&gt; <span
- style="font-style: italic;">seq </span>close</span><br>
-<div style="margin-left: 40px;">Close the sequence<br>
-</div>
-<br>
-<hr width="100%"><span style="font-weight: bold;">&gt; <span
- style="font-style: italic;">seq</span> remove [-auto_commit] [-nosync]
-[-txn] <br>
-</span>
-<div style="margin-left: 40px;">Remove the sequence.<br>
-</div>
-<hr width="100%"><span style="font-weight: bold;">&gt; <span
- style="font-style: italic;">seq </span>get_cachesize<br>
-</span>
-<div style="margin-left: 40px;">Return the size of the cache.<br>
-</div>
-<hr width="100%"><span style="font-weight: bold;">&gt; <span
- style="font-style: italic;">seq </span>get_db<br>
-</span>
-<div style="margin-left: 40px;">Return the underlying db handle.<br>
-</div>
-<hr width="100%"><span style="font-weight: bold;">&gt; <span
- style="font-style: italic;">seq </span>get_flags</span><br>
-<div style="margin-left: 40px;">Return the flags set on create.<br>
-</div>
-<hr width="100%"><span style="font-weight: bold;">&gt; <span
- style="font-style: italic;">seq</span> get_range<br>
-</span>
-<div style="margin-left: 40px;">Return the min and max set at create.<br>
-</div>
-<hr width="100%"><span style="font-weight: bold;">&gt; <span
- style="font-style: italic;">seq </span>stat<br>
-</span>
-<div style="margin-left: 40px;">Implements the <a
- href="../../docs/seq/seq_stat.html">SEQUENCE-&gt;stat</a> function.<br>
-</div>
-<hr width="100%">
-</body>
-</html>
diff --git a/tcl/docs/test.html b/tcl/docs/test.html
deleted file mode 100644
index 225f6a2..0000000
--- a/tcl/docs/test.html
+++ /dev/null
@@ -1,103 +0,0 @@
-<!--Copyright 1999-2009 Oracle. All rights reserved.-->
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.08 [en] (X11; I; FreeBSD 2.2.8-19990120-SNAP i386) [Netscape]">
-</HEAD>
-<BODY>
-
-<H2>
-<A NAME="Debugging"></A>Debugging and Testing</H2>
-We have imported the debugging system from the old test suite into the
-new interface to aid in debugging problems.&nbsp; There are several variables
-that are available both in gdb as globals to the C code, and variables
-in Tcl that the user can set.&nbsp; These variables are linked together
-so that changes in one venue are reflected in the other.&nbsp; The names
-of the variables have been modified a bit to reduce the likelihood
-<BR>of namespace trampling.&nbsp; We have added a double underscore to
-all the names.
-<P>The variables are all initialized to zero (0) thus resulting in debugging
-being turned off.&nbsp; The purpose of the debugging, fundamentally, is
-to allow the user to set a breakpoint prior to making a DB call.&nbsp;
-This breakpoint is set in the <I>__db_loadme() </I>function.&nbsp; The
-user may selectively turn on various debugging areas each controlled by
-a separate variable (note they all have two (2) underscores prepended to
-the name):
-<UL>
-<LI>
-<B>__debug_on</B> - Turns on the debugging system.&nbsp; This must be on
-for any debugging to occur</LI>
-
-<LI>
-<B>__debug_print - </B>Turns on printing a debug count statement on each
-call</LI>
-
-<LI>
-<B>__debug_test -</B> Hits the breakpoint in <I>__db_loadme</I> on the
-specific iteration</LI>
-
-<LI>
-<B>__debug_stop </B>- Hits the breakpoint in <I>__db_loadme</I> on every
-(or the next) iteration</LI>
-</UL>
-<B>Note to developers:</B>&nbsp; Anyone extending this interface must place
-a call to <B>_debug_check()</B> (no arguments) before every call into the
-DB library.
-<P>There is also a command available that will force a call to the _debug_check
-function.
-<P><B>> berkdb debug_check</B>
-<P>
-<HR WIDTH="100%">
-<BR>For testing purposes we have added several hooks into the DB library
-and a small interface into the environment and/or database commands to
-manipulate the hooks.&nbsp; This command interface and the hooks and everything
-that goes with it is only enabled when the test option is configured into
-DB.
-<P><B>> &lt;env> test copy <I>location</I></B>
-<BR><B>> &lt;db> test copy <I>location</I></B>
-<BR><B>> &lt;env> test abort <I>location</I></B>
-<BR><B>> &lt;db> test abort <I>location</I></B>
-<P>In order to test recovery we need to be able to abort the creation or
-deletion process at various points.&nbsp; Also we want to invoke a copy
-function to copy the database file(s)&nbsp; at various points as well so
-that we can obtain before/after snapshots of the databases.&nbsp; The interface
-provides the test command to specify a <B><I>location</I></B> where we
-wish to invoke a <B>copy</B> or an <B>abort</B>.&nbsp; The command is available
-from either the environment or the database for convenience.&nbsp; The
-<B><I>location</I></B>
-can be one of the following:
-<UL>
-<LI>
-<B>none -</B> Clears the location</LI>
-
-<LI>
-<B>preopen -</B> Sets the location prior to the __os_open call in the creation
-process</LI>
-
-<LI>
-<B>postopen</B> - Sets the location to immediately following the __os_open
-call in creation</LI>
-
-<LI>
-<B>postlogmeta</B> - Sets the location to immediately following the __db_log_page
-call to log the meta data in creation.&nbsp; Only valid for Btree.</LI>
-
-<LI>
-<B>postlog</B> - Sets the location to immediately following the last (or
-only) __db_log_page call in creation.</LI>
-
-<LI>
-<B>postsync</B> - Sets the location to immediately following the sync of
-the log page in creation.</LI>
-
-<LI>
-<B>prerename</B> - Sets the location prior to the __os_rename call in the
-deletion process.</LI>
-
-<LI>
-<B>postrename</B> - Sets the location to immediately following the __os_rename
-call in deletion</LI>
-</UL>
-
-</BODY>
-</HTML>
diff --git a/tcl/docs/txn.html b/tcl/docs/txn.html
deleted file mode 100644
index 3f234a2..0000000
--- a/tcl/docs/txn.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<!--Copyright 1999-2009 Oracle. All rights reserved.-->
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <meta name="GENERATOR" content="Mozilla/4.75 [en] (X11; U; Linux 2.2.16-22 i686) [Netscape]">
-</head>
-<body>
-
-<h2>
-<a NAME="Transaction Commands"></a>Transaction Commands</h2>
-Transactions are used in a manner similar to the other subsystems.&nbsp;
-We create a handle to the transaction and&nbsp; then use it for a variety
-of operations.&nbsp; Some of the transaction commands use the environment
-instead.&nbsp; Those are presented first.&nbsp; The transaction command
-handle returned is the handle used by the various commands that can be
-transaction protected, such as <a href="../../docs/api_tcl/db_cursor.html">cursors</a>.
-<br>
-<hr WIDTH="100%">
-<p><b>> &lt;env> txn_checkpoint [-kbyte <i>kb</i>] [-min <i>min</i>]</b>
-<p>This command causes a checkpoint of the transaction region.&nbsp; It
-is a direct translation of the <a href="../../docs/api_c/txn_checkpoint.html">txn_checkpoint
-</a>function.&nbsp;
-It returns either a 0 (for success), a DB error message or it throws a
-Tcl error with a system message.&nbsp; The arguments are:
-<ul>
-<li>
-<b>-force</b>causes the checkpoint to occur regardless of inactivity
-
-<li>
-<b>-kbyte</b>causes the checkpoint to occur only if <b><i>kb</i></b> kilobytes
-of log data has been written since the last checkpoint
-
-<li>
-<b>-min</b> causes the checkpoint to occur only if <b><i>min</i></b> minutes
-have passed since the last checkpoint
-</ul>
-
-<hr WIDTH="100%">
-<br><b>> &lt;env> txn_stat</b>
-<p>This command returns transaction statistics.&nbsp; It is a direct translation
-of the <a href="../../docs/api_c/txn_stat.html">txn_stat</a> function.&nbsp;
-It will return a list of name/value pairs that correspond to the DB_TXN_STAT
-structure.
-<hr WIDTH="100%">
-<br><b>> &lt;env> txn_id_set&nbsp;</b><i> current max</i>
-<p>This is a diagnosic command that sets the next transaction id to be
-allocated and the maximum transaction
-<br>id, which is the point at which the relcaimation algorthm is triggered.
-<hr WIDTH="100%">
-<br><b>>&nbsp; &lt;txn> id</b>
-<p>This command returns the transaction id.&nbsp; It is a direct call to
-the <a href="../../docs/api_c/txn_id.html">txn_id</a> function.&nbsp; The
-typical use of this identifier is as the <b><i>locker</i></b> value for
-the <a href="lock.html">lock_get</a> and <a href="lock.html">lock_vec</a>
-calls.
-<hr WIDTH="100%">
-<br><b>> &lt;txn> prepare</b>
-<p>This command initiates a two-phase commit.&nbsp; It is a direct call
-to the <a href="../../docs/api_c/txn_prepare.html">txn_prepare</a> function.&nbsp;
-It returns either a 0 (for success), a DB error message or it throws a
-Tcl error with a system message.
-<hr WIDTH="100%"><a NAME="> <env> lock_vec"></a><b>> &lt;env> txn_timeout
-<i>timeout</i></b>
-<p>This command sets thetransaction timeout for transactions started in
-the future in this environment.&nbsp; The timeout is in micorseconds.
-<br>&nbsp;
-<br>&nbsp;
-</body>
-</html>
diff --git a/tcl/tcl_compat.c b/tcl/tcl_compat.c
deleted file mode 100644
index 6b3664d..0000000
--- a/tcl/tcl_compat.c
+++ /dev/null
@@ -1,738 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-#ifdef CONFIG_TEST
-
-#define DB_DBM_HSEARCH 1
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/tcl_db.h"
-
-/*
- * bdb_HCommand --
- * Implements h* functions.
- *
- * PUBLIC: int bdb_HCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
- */
-int
-bdb_HCommand(interp, objc, objv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *hcmds[] = {
- "hcreate",
- "hdestroy",
- "hsearch",
- NULL
- };
- enum hcmds {
- HHCREATE,
- HHDESTROY,
- HHSEARCH
- };
- static const char *srchacts[] = {
- "enter",
- "find",
- NULL
- };
- enum srchacts {
- ACT_ENTER,
- ACT_FIND
- };
- ENTRY item, *hres;
- ACTION action;
- int actindex, cmdindex, nelem, result, ret;
- Tcl_Obj *res;
-
- result = TCL_OK;
- /*
- * Get the command name index from the object based on the cmds
- * defined above. This SHOULD NOT fail because we already checked
- * in the 'berkdb' command.
- */
- if (Tcl_GetIndexFromObj(interp,
- objv[1], hcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
-
- res = NULL;
- switch ((enum hcmds)cmdindex) {
- case HHCREATE:
- /*
- * Must be 1 arg, nelem. Error if not.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "nelem");
- return (TCL_ERROR);
- }
- result = Tcl_GetIntFromObj(interp, objv[2], &nelem);
- if (result == TCL_OK) {
- _debug_check();
- ret = hcreate((size_t)nelem) == 0 ? 1: 0;
- (void)_ReturnSetup(
- interp, ret, DB_RETOK_STD(ret), "hcreate");
- }
- break;
- case HHSEARCH:
- /*
- * 3 args for this. Error if different.
- */
- if (objc != 5) {
- Tcl_WrongNumArgs(interp, 2, objv, "key data action");
- return (TCL_ERROR);
- }
- item.key = Tcl_GetStringFromObj(objv[2], NULL);
- item.data = Tcl_GetStringFromObj(objv[3], NULL);
- if (Tcl_GetIndexFromObj(interp, objv[4], srchacts,
- "action", TCL_EXACT, &actindex) != TCL_OK)
- return (IS_HELP(objv[4]));
- switch ((enum srchacts)actindex) {
- case ACT_ENTER:
- action = ENTER;
- break;
- default:
- case ACT_FIND:
- action = FIND;
- break;
- }
- _debug_check();
- hres = hsearch(item, action);
- if (hres == NULL)
- Tcl_SetResult(interp, "-1", TCL_STATIC);
- else if (action == FIND)
- Tcl_SetResult(interp, (char *)hres->data, TCL_STATIC);
- else
- /* action is ENTER */
- Tcl_SetResult(interp, "0", TCL_STATIC);
-
- break;
- case HHDESTROY:
- /*
- * No args for this. Error if there are some.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- hdestroy();
- res = Tcl_NewIntObj(0);
- break;
- }
- /*
- * Only set result if we have a res. Otherwise, lower
- * functions have already done so.
- */
- if (result == TCL_OK && res)
- Tcl_SetObjResult(interp, res);
- return (result);
-}
-
-/*
- *
- * bdb_NdbmOpen --
- * Opens an ndbm database.
- *
- * PUBLIC: #if DB_DBM_HSEARCH != 0
- * PUBLIC: int bdb_NdbmOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBM **));
- * PUBLIC: #endif
- */
-int
-bdb_NdbmOpen(interp, objc, objv, dbpp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DBM **dbpp; /* Dbm pointer */
-{
- static const char *ndbopen[] = {
- "-create",
- "-mode",
- "-rdonly",
- "-truncate",
- "--",
- NULL
- };
- enum ndbopen {
- NDB_CREATE,
- NDB_MODE,
- NDB_RDONLY,
- NDB_TRUNC,
- NDB_ENDARG
- };
-
- int endarg, i, mode, open_flags, optindex, read_only, result, ret;
- char *arg, *db;
-
- result = TCL_OK;
- endarg = mode = open_flags = read_only = 0;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args?");
- return (TCL_ERROR);
- }
-
- /*
- * Get the option name index from the object based on the args
- * defined above.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], ndbopen, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto error;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum ndbopen)optindex) {
- case NDB_CREATE:
- open_flags |= O_CREAT;
- break;
- case NDB_RDONLY:
- read_only = 1;
- break;
- case NDB_TRUNC:
- open_flags |= O_TRUNC;
- break;
- case NDB_MODE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-mode mode?");
- result = TCL_ERROR;
- break;
- }
- /*
- * Don't need to check result here because
- * if TCL_ERROR, the error message is already
- * set up, and we'll bail out below. If ok,
- * the mode is set and we go on.
- */
- result = Tcl_GetIntFromObj(interp, objv[i++], &mode);
- break;
- case NDB_ENDARG:
- endarg = 1;
- break;
- }
-
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- if (endarg)
- break;
- }
- if (result != TCL_OK)
- goto error;
-
- /*
- * Any args we have left, (better be 0, or 1 left) is a
- * file name. If we have 0, then an in-memory db. If
- * there is 1, a db name.
- */
- db = NULL;
- if (i != objc && i != objc - 1) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args? ?file?");
- result = TCL_ERROR;
- goto error;
- }
- if (i != objc)
- db = Tcl_GetStringFromObj(objv[objc - 1], NULL);
-
- /*
- * When we get here, we have already parsed all of our args
- * and made all our calls to set up the database. Everything
- * is okay so far, no errors, if we get here.
- *
- * Now open the database.
- */
- if (read_only)
- open_flags |= O_RDONLY;
- else
- open_flags |= O_RDWR;
- _debug_check();
- if ((*dbpp = dbm_open(db, open_flags, mode)) == NULL) {
- ret = Tcl_GetErrno();
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db open");
- goto error;
- }
- return (TCL_OK);
-
-error:
- *dbpp = NULL;
- return (result);
-}
-
-/*
- * bdb_DbmCommand --
- * Implements "dbm" commands.
- *
- * PUBLIC: #if DB_DBM_HSEARCH != 0
- * PUBLIC: int bdb_DbmCommand
- * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST*, int, DBM *));
- * PUBLIC: #endif
- */
-int
-bdb_DbmCommand(interp, objc, objv, flag, dbm)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- int flag; /* Which db interface */
- DBM *dbm; /* DBM pointer */
-{
- static const char *dbmcmds[] = {
- "dbmclose",
- "dbminit",
- "delete",
- "fetch",
- "firstkey",
- "nextkey",
- "store",
- NULL
- };
- enum dbmcmds {
- DBMCLOSE,
- DBMINIT,
- DBMDELETE,
- DBMFETCH,
- DBMFIRST,
- DBMNEXT,
- DBMSTORE
- };
- static const char *stflag[] = {
- "insert", "replace",
- NULL
- };
- enum stflag {
- STINSERT, STREPLACE
- };
- datum key, data;
- void *dtmp, *ktmp;
- u_int32_t size;
- int cmdindex, freedata, freekey, stindex, result, ret;
- char *name, *t;
-
- result = TCL_OK;
- freekey = freedata = 0;
- dtmp = ktmp = NULL;
-
- /*
- * Get the command name index from the object based on the cmds
- * defined above. This SHOULD NOT fail because we already checked
- * in the 'berkdb' command.
- */
- if (Tcl_GetIndexFromObj(interp,
- objv[1], dbmcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
-
- switch ((enum dbmcmds)cmdindex) {
- case DBMCLOSE:
- /*
- * No arg for this. Error if different.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- if (flag == DBTCL_DBM)
- ret = dbmclose();
- else {
- Tcl_SetResult(interp,
- "Bad interface flag for command", TCL_STATIC);
- return (TCL_ERROR);
- }
- (void)_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "dbmclose");
- break;
- case DBMINIT:
- /*
- * Must be 1 arg - file.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "file");
- return (TCL_ERROR);
- }
- name = Tcl_GetStringFromObj(objv[2], NULL);
- if (flag == DBTCL_DBM)
- ret = dbminit(name);
- else {
- Tcl_SetResult(interp, "Bad interface flag for command",
- TCL_STATIC);
- return (TCL_ERROR);
- }
- (void)_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "dbminit");
- break;
- case DBMFETCH:
- /*
- * 1 arg for this. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "key");
- return (TCL_ERROR);
- }
- if ((ret = _CopyObjBytes(
- interp, objv[2], &ktmp, &size, &freekey)) != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "dbm fetch");
- goto out;
- }
- key.dsize = (int)size;
- key.dptr = (char *)ktmp;
- _debug_check();
- if (flag == DBTCL_DBM)
- data = fetch(key);
- else if (flag == DBTCL_NDBM)
- data = dbm_fetch(dbm, key);
- else {
- Tcl_SetResult(interp,
- "Bad interface flag for command", TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- }
- if (data.dptr == NULL ||
- (ret = __os_malloc(NULL, (size_t)data.dsize + 1, &t)) != 0)
- Tcl_SetResult(interp, "-1", TCL_STATIC);
- else {
- memcpy(t, data.dptr, (size_t)data.dsize);
- t[data.dsize] = '\0';
- Tcl_SetResult(interp, t, TCL_VOLATILE);
- __os_free(NULL, t);
- }
- break;
- case DBMSTORE:
- /*
- * 2 args for this. Error if different.
- */
- if (objc != 4 && flag == DBTCL_DBM) {
- Tcl_WrongNumArgs(interp, 2, objv, "key data");
- return (TCL_ERROR);
- }
- if (objc != 5 && flag == DBTCL_NDBM) {
- Tcl_WrongNumArgs(interp, 2, objv, "key data action");
- return (TCL_ERROR);
- }
- if ((ret = _CopyObjBytes(
- interp, objv[2], &ktmp, &size, &freekey)) != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "dbm fetch");
- goto out;
- }
- key.dsize = (int)size;
- key.dptr = (char *)ktmp;
- if ((ret = _CopyObjBytes(
- interp, objv[3], &dtmp, &size, &freedata)) != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "dbm fetch");
- goto out;
- }
- data.dsize = (int)size;
- data.dptr = (char *)dtmp;
- _debug_check();
- if (flag == DBTCL_DBM)
- ret = store(key, data);
- else if (flag == DBTCL_NDBM) {
- if (Tcl_GetIndexFromObj(interp, objv[4], stflag,
- "flag", TCL_EXACT, &stindex) != TCL_OK)
- return (IS_HELP(objv[4]));
- switch ((enum stflag)stindex) {
- case STINSERT:
- flag = DBM_INSERT;
- break;
- case STREPLACE:
- flag = DBM_REPLACE;
- break;
- }
- ret = dbm_store(dbm, key, data, flag);
- } else {
- Tcl_SetResult(interp,
- "Bad interface flag for command", TCL_STATIC);
- return (TCL_ERROR);
- }
- (void)_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "store");
- break;
- case DBMDELETE:
- /*
- * 1 arg for this. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "key");
- return (TCL_ERROR);
- }
- if ((ret = _CopyObjBytes(
- interp, objv[2], &ktmp, &size, &freekey)) != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "dbm fetch");
- goto out;
- }
- key.dsize = (int)size;
- key.dptr = (char *)ktmp;
- _debug_check();
- if (flag == DBTCL_DBM)
- ret = delete(key);
- else if (flag == DBTCL_NDBM)
- ret = dbm_delete(dbm, key);
- else {
- Tcl_SetResult(interp,
- "Bad interface flag for command", TCL_STATIC);
- return (TCL_ERROR);
- }
- (void)_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "delete");
- break;
- case DBMFIRST:
- /*
- * No arg for this. Error if different.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- if (flag == DBTCL_DBM)
- key = firstkey();
- else if (flag == DBTCL_NDBM)
- key = dbm_firstkey(dbm);
- else {
- Tcl_SetResult(interp,
- "Bad interface flag for command", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (key.dptr == NULL ||
- (ret = __os_malloc(NULL, (size_t)key.dsize + 1, &t)) != 0)
- Tcl_SetResult(interp, "-1", TCL_STATIC);
- else {
- memcpy(t, key.dptr, (size_t)key.dsize);
- t[key.dsize] = '\0';
- Tcl_SetResult(interp, t, TCL_VOLATILE);
- __os_free(NULL, t);
- }
- break;
- case DBMNEXT:
- /*
- * 0 or 1 arg for this. Error if different.
- */
- _debug_check();
- if (flag == DBTCL_DBM) {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- if ((ret = _CopyObjBytes(
- interp, objv[2], &ktmp, &size, &freekey)) != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "dbm fetch");
- goto out;
- }
- key.dsize = (int)size;
- key.dptr = (char *)ktmp;
- data = nextkey(key);
- } else if (flag == DBTCL_NDBM) {
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- data = dbm_nextkey(dbm);
- } else {
- Tcl_SetResult(interp,
- "Bad interface flag for command", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (data.dptr == NULL ||
- (ret = __os_malloc(NULL, (size_t)data.dsize + 1, &t)) != 0)
- Tcl_SetResult(interp, "-1", TCL_STATIC);
- else {
- memcpy(t, data.dptr, (size_t)data.dsize);
- t[data.dsize] = '\0';
- Tcl_SetResult(interp, t, TCL_VOLATILE);
- __os_free(NULL, t);
- }
- break;
- }
-
-out: if (dtmp != NULL && freedata)
- __os_free(NULL, dtmp);
- if (ktmp != NULL && freekey)
- __os_free(NULL, ktmp);
- return (result);
-}
-
-/*
- * ndbm_Cmd --
- * Implements the "ndbm" widget.
- *
- * PUBLIC: int ndbm_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
- */
-int
-ndbm_Cmd(clientData, interp, objc, objv)
- ClientData clientData; /* DB handle */
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *ndbcmds[] = {
- "clearerr",
- "close",
- "delete",
- "dirfno",
- "error",
- "fetch",
- "firstkey",
- "nextkey",
- "pagfno",
- "rdonly",
- "store",
- NULL
- };
- enum ndbcmds {
- NDBCLRERR,
- NDBCLOSE,
- NDBDELETE,
- NDBDIRFNO,
- NDBERR,
- NDBFETCH,
- NDBFIRST,
- NDBNEXT,
- NDBPAGFNO,
- NDBRDONLY,
- NDBSTORE
- };
- DBM *dbp;
- DBTCL_INFO *dbip;
- Tcl_Obj *res;
- int cmdindex, result, ret;
-
- Tcl_ResetResult(interp);
- dbp = (DBM *)clientData;
- dbip = _PtrToInfo((void *)dbp);
- result = TCL_OK;
- if (objc <= 1) {
- Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs");
- return (TCL_ERROR);
- }
- if (dbp == NULL) {
- Tcl_SetResult(interp, "NULL db pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (dbip == NULL) {
- Tcl_SetResult(interp, "NULL db info pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the dbcmds
- * defined above.
- */
- if (Tcl_GetIndexFromObj(interp,
- objv[1], ndbcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
-
- res = NULL;
- switch ((enum ndbcmds)cmdindex) {
- case NDBCLOSE:
- _debug_check();
- dbm_close(dbp);
- (void)Tcl_DeleteCommand(interp, dbip->i_name);
- _DeleteInfo(dbip);
- res = Tcl_NewIntObj(0);
- break;
- case NDBDELETE:
- case NDBFETCH:
- case NDBFIRST:
- case NDBNEXT:
- case NDBSTORE:
- result = bdb_DbmCommand(interp, objc, objv, DBTCL_NDBM, dbp);
- break;
- case NDBCLRERR:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbm_clearerr(dbp);
- if (ret)
- (void)_ReturnSetup(
- interp, ret, DB_RETOK_STD(ret), "clearerr");
- else
- res = Tcl_NewIntObj(ret);
- break;
- case NDBDIRFNO:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbm_dirfno(dbp);
- res = Tcl_NewIntObj(ret);
- break;
- case NDBPAGFNO:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbm_pagfno(dbp);
- res = Tcl_NewIntObj(ret);
- break;
- case NDBERR:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbm_error(dbp);
- Tcl_SetErrno(ret);
- Tcl_SetResult(interp,
- (char *)Tcl_PosixError(interp), TCL_STATIC);
- break;
- case NDBRDONLY:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbm_rdonly(dbp);
- if (ret)
- (void)_ReturnSetup(
- interp, ret, DB_RETOK_STD(ret), "rdonly");
- else
- res = Tcl_NewIntObj(ret);
- break;
- }
-
- /*
- * Only set result if we have a res. Otherwise, lower functions have
- * already done so.
- */
- if (result == TCL_OK && res)
- Tcl_SetObjResult(interp, res);
- return (result);
-}
-#endif /* CONFIG_TEST */
diff --git a/tcl/tcl_db.c b/tcl/tcl_db.c
deleted file mode 100644
index 4b68cd9..0000000
--- a/tcl/tcl_db.c
+++ /dev/null
@@ -1,3465 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/db_page.h"
-#include "dbinc/db_am.h"
-#include "dbinc/tcl_db.h"
-
-/*
- * Prototypes for procedures defined later in this file:
- */
-static int tcl_DbAssociate __P((Tcl_Interp *,
- int, Tcl_Obj * CONST*, DB *));
-static int tcl_DbClose __P((Tcl_Interp *,
- int, Tcl_Obj * CONST*, DB *, DBTCL_INFO *));
-static int tcl_DbDelete __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
-static int tcl_DbGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *, int));
-#ifdef CONFIG_TEST
-static int tcl_DbKeyRange __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
-#endif
-static int tcl_DbPut __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
-static int tcl_DbStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
-static int tcl_DbTruncate __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
-#ifdef CONFIG_TEST
-static int tcl_DbCompact __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
-static int tcl_DbCompactStat __P((Tcl_Interp *,
- int, Tcl_Obj * CONST*, DB *));
-#endif
-static int tcl_DbCursor __P((Tcl_Interp *,
- int, Tcl_Obj * CONST*, DB *, DBC **));
-static int tcl_DbJoin __P((Tcl_Interp *,
- int, Tcl_Obj * CONST*, DB *, DBC **));
-static int tcl_DbGetFlags __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
-static int tcl_DbGetOpenFlags __P((Tcl_Interp *,
- int, Tcl_Obj * CONST*, DB *));
-static int tcl_DbGetjoin __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
-static int tcl_DbCount __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
-static int tcl_second_call __P((DB *, const DBT *, const DBT *, DBT *));
-
-/*
- * _DbInfoDelete --
- *
- * PUBLIC: void _DbInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
- */
-void
-_DbInfoDelete(interp, dbip)
- Tcl_Interp *interp;
- DBTCL_INFO *dbip;
-{
- DBTCL_INFO *nextp, *p;
- /*
- * First we have to close any open cursors. Then we close
- * our db.
- */
- for (p = LIST_FIRST(&__db_infohead); p != NULL; p = nextp) {
- nextp = LIST_NEXT(p, entries);
- /*
- * Check if this is a cursor info structure and if
- * it is, if it belongs to this DB. If so, remove
- * its commands and info structure.
- */
- if (p->i_parent == dbip && p->i_type == I_DBC) {
- (void)Tcl_DeleteCommand(interp, p->i_name);
- _DeleteInfo(p);
- }
- }
- (void)Tcl_DeleteCommand(interp, dbip->i_name);
- _DeleteInfo(dbip);
-}
-
-/*
- *
- * PUBLIC: int db_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
- *
- * db_Cmd --
- * Implements the "db" widget.
- */
-int
-db_Cmd(clientData, interp, objc, objv)
- ClientData clientData; /* DB handle */
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *dbcmds[] = {
-#ifdef CONFIG_TEST
- "keyrange",
- "pget",
- "rpcid",
- "test",
- "compact",
- "compact_stat",
-#endif
- "associate",
- "close",
- "count",
- "cursor",
- "del",
- "get",
- "get_bt_minkey",
- "get_cachesize",
- "get_dbname",
- "get_encrypt_flags",
- "get_env",
- "get_errpfx",
- "get_flags",
- "get_h_ffactor",
- "get_h_nelem",
- "get_join",
- "get_lorder",
- "get_open_flags",
- "get_pagesize",
- "get_q_extentsize",
- "get_re_delim",
- "get_re_len",
- "get_re_pad",
- "get_re_source",
- "get_type",
- "is_byteswapped",
- "join",
- "put",
- "stat",
- "sync",
- "truncate",
- NULL
- };
- enum dbcmds {
-#ifdef CONFIG_TEST
- DBKEYRANGE,
- DBPGET,
- DBRPCID,
- DBTEST,
- DBCOMPACT,
- DBCOMPACT_STAT,
-#endif
- DBASSOCIATE,
- DBCLOSE,
- DBCOUNT,
- DBCURSOR,
- DBDELETE,
- DBGET,
- DBGETBTMINKEY,
- DBGETCACHESIZE,
- DBGETDBNAME,
- DBGETENCRYPTFLAGS,
- DBGETENV,
- DBGETERRPFX,
- DBGETFLAGS,
- DBGETHFFACTOR,
- DBGETHNELEM,
- DBGETJOIN,
- DBGETLORDER,
- DBGETOPENFLAGS,
- DBGETPAGESIZE,
- DBGETQEXTENTSIZE,
- DBGETREDELIM,
- DBGETRELEN,
- DBGETREPAD,
- DBGETRESOURCE,
- DBGETTYPE,
- DBSWAPPED,
- DBJOIN,
- DBPUT,
- DBSTAT,
- DBSYNC,
- DBTRUNCATE
- };
- DB *dbp;
- DB_ENV *dbenv;
- DBC *dbc;
- DBTCL_INFO *dbip, *ip;
- DBTYPE type;
- Tcl_Obj *res, *myobjv[3];
- int cmdindex, intval, ncache, result, ret;
- char newname[MSG_SIZE];
- u_int32_t bytes, gbytes, value;
- const char *strval, *filename, *dbname, *envid;
-
- Tcl_ResetResult(interp);
- dbp = (DB *)clientData;
- dbip = _PtrToInfo((void *)dbp);
- memset(newname, 0, MSG_SIZE);
- result = TCL_OK;
- if (objc <= 1) {
- Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs");
- return (TCL_ERROR);
- }
- if (dbp == NULL) {
- Tcl_SetResult(interp, "NULL db pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (dbip == NULL) {
- Tcl_SetResult(interp, "NULL db info pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the dbcmds
- * defined above.
- */
- if (Tcl_GetIndexFromObj(interp,
- objv[1], dbcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
-
- res = NULL;
- switch ((enum dbcmds)cmdindex) {
-#ifdef CONFIG_TEST
- case DBKEYRANGE:
- result = tcl_DbKeyRange(interp, objc, objv, dbp);
- break;
- case DBPGET:
- result = tcl_DbGet(interp, objc, objv, dbp, 1);
- break;
- case DBRPCID:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- /*
- * !!! Retrieve the client ID from the dbp handle directly.
- * This is for testing purposes only. It is dbp-private data.
- */
- res = Tcl_NewLongObj((long)dbp->cl_id);
- break;
- case DBTEST:
- result = tcl_EnvTest(interp, objc, objv, dbp->dbenv);
- break;
-
- case DBCOMPACT:
- result = tcl_DbCompact(interp, objc, objv, dbp);
- break;
-
- case DBCOMPACT_STAT:
- result = tcl_DbCompactStat(interp, objc, objv, dbp);
- break;
-
-#endif
- case DBASSOCIATE:
- result = tcl_DbAssociate(interp, objc, objv, dbp);
- break;
- case DBCLOSE:
- result = tcl_DbClose(interp, objc, objv, dbp, dbip);
- break;
- case DBDELETE:
- result = tcl_DbDelete(interp, objc, objv, dbp);
- break;
- case DBGET:
- result = tcl_DbGet(interp, objc, objv, dbp, 0);
- break;
- case DBPUT:
- result = tcl_DbPut(interp, objc, objv, dbp);
- break;
- case DBCOUNT:
- result = tcl_DbCount(interp, objc, objv, dbp);
- break;
- case DBSWAPPED:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbp->get_byteswapped(dbp, &intval);
- res = Tcl_NewIntObj(intval);
- break;
- case DBGETTYPE:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbp->get_type(dbp, &type);
- if (type == DB_BTREE)
- res = NewStringObj("btree", strlen("btree"));
- else if (type == DB_HASH)
- res = NewStringObj("hash", strlen("hash"));
- else if (type == DB_RECNO)
- res = NewStringObj("recno", strlen("recno"));
- else if (type == DB_QUEUE)
- res = NewStringObj("queue", strlen("queue"));
- else {
- Tcl_SetResult(interp,
- "db gettype: Returned unknown type\n", TCL_STATIC);
- result = TCL_ERROR;
- }
- break;
- case DBSTAT:
- result = tcl_DbStat(interp, objc, objv, dbp);
- break;
- case DBSYNC:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbp->sync(dbp, 0);
- res = Tcl_NewIntObj(ret);
- if (ret != 0) {
- Tcl_SetObjResult(interp, res);
- result = TCL_ERROR;
- }
- break;
- case DBCURSOR:
- snprintf(newname, sizeof(newname),
- "%s.c%d", dbip->i_name, dbip->i_dbdbcid);
- ip = _NewInfo(interp, NULL, newname, I_DBC);
- if (ip != NULL) {
- result = tcl_DbCursor(interp, objc, objv, dbp, &dbc);
- if (result == TCL_OK) {
- dbip->i_dbdbcid++;
- ip->i_parent = dbip;
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)dbc_Cmd,
- (ClientData)dbc, NULL);
- res = NewStringObj(newname, strlen(newname));
- _SetInfoData(ip, dbc);
- } else
- _DeleteInfo(ip);
- } else {
- Tcl_SetResult(interp,
- "Could not set up info", TCL_STATIC);
- result = TCL_ERROR;
- }
- break;
- case DBJOIN:
- snprintf(newname, sizeof(newname),
- "%s.c%d", dbip->i_name, dbip->i_dbdbcid);
- ip = _NewInfo(interp, NULL, newname, I_DBC);
- if (ip != NULL) {
- result = tcl_DbJoin(interp, objc, objv, dbp, &dbc);
- if (result == TCL_OK) {
- dbip->i_dbdbcid++;
- ip->i_parent = dbip;
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)dbc_Cmd,
- (ClientData)dbc, NULL);
- res = NewStringObj(newname, strlen(newname));
- _SetInfoData(ip, dbc);
- } else
- _DeleteInfo(ip);
- } else {
- Tcl_SetResult(interp,
- "Could not set up info", TCL_STATIC);
- result = TCL_ERROR;
- }
- break;
- case DBGETBTMINKEY:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbp->get_bt_minkey(dbp, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_bt_minkey")) == TCL_OK)
- res = Tcl_NewIntObj((int)value);
- break;
- case DBGETCACHESIZE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbp->get_cachesize(dbp, &gbytes, &bytes, &ncache);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_cachesize")) == TCL_OK) {
- myobjv[0] = Tcl_NewIntObj((int)gbytes);
- myobjv[1] = Tcl_NewIntObj((int)bytes);
- myobjv[2] = Tcl_NewIntObj((int)ncache);
- res = Tcl_NewListObj(3, myobjv);
- }
- break;
- case DBGETDBNAME:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbp->get_dbname(dbp, &filename, &dbname);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_dbname")) == TCL_OK) {
- myobjv[0] = NewStringObj(filename, strlen(filename));
- myobjv[1] = NewStringObj(dbname, strlen(dbname));
- res = Tcl_NewListObj(2, myobjv);
- }
- break;
- case DBGETENCRYPTFLAGS:
- result = tcl_EnvGetEncryptFlags(interp, objc, objv, dbp->dbenv);
- break;
- case DBGETENV:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- dbenv = dbp->get_env(dbp);
- if (dbenv != NULL && (ip = _PtrToInfo(dbenv)) != NULL) {
- envid = ip->i_name;
- res = NewStringObj(envid, strlen(envid));
- } else
- Tcl_ResetResult(interp);
- break;
- case DBGETERRPFX:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- dbp->get_errpfx(dbp, &strval);
- res = NewStringObj(strval, strlen(strval));
- break;
- case DBGETFLAGS:
- result = tcl_DbGetFlags(interp, objc, objv, dbp);
- break;
- case DBGETHFFACTOR:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbp->get_h_ffactor(dbp, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_h_ffactor")) == TCL_OK)
- res = Tcl_NewIntObj((int)value);
- break;
- case DBGETHNELEM:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbp->get_h_nelem(dbp, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_h_nelem")) == TCL_OK)
- res = Tcl_NewIntObj((int)value);
- break;
- case DBGETJOIN:
- result = tcl_DbGetjoin(interp, objc, objv, dbp);
- break;
- case DBGETLORDER:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbp->get_lorder(dbp, &intval);
- res = Tcl_NewIntObj(intval);
- break;
- case DBGETOPENFLAGS:
- result = tcl_DbGetOpenFlags(interp, objc, objv, dbp);
- break;
- case DBGETPAGESIZE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbp->get_pagesize(dbp, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_pagesize")) == TCL_OK)
- res = Tcl_NewIntObj((int)value);
- break;
- case DBGETQEXTENTSIZE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbp->get_q_extentsize(dbp, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_q_extentsize")) == TCL_OK)
- res = Tcl_NewIntObj((int)value);
- break;
- case DBGETREDELIM:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbp->get_re_delim(dbp, &intval);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_re_delim")) == TCL_OK)
- res = Tcl_NewIntObj(intval);
- break;
- case DBGETRELEN:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbp->get_re_len(dbp, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_re_len")) == TCL_OK)
- res = Tcl_NewIntObj((int)value);
- break;
- case DBGETREPAD:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbp->get_re_pad(dbp, &intval);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_re_pad")) == TCL_OK)
- res = Tcl_NewIntObj((int)intval);
- break;
- case DBGETRESOURCE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbp->get_re_source(dbp, &strval);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_re_source")) == TCL_OK)
- res = NewStringObj(strval, strlen(strval));
- break;
- case DBTRUNCATE:
- result = tcl_DbTruncate(interp, objc, objv, dbp);
- break;
- }
- /*
- * Only set result if we have a res. Otherwise, lower
- * functions have already done so.
- */
- if (result == TCL_OK && res)
- Tcl_SetObjResult(interp, res);
- return (result);
-}
-
-/*
- * tcl_db_stat --
- */
-static int
-tcl_DbStat(interp, objc, objv, dbp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
-{
- static const char *dbstatopts[] = {
-#ifdef CONFIG_TEST
- "-read_committed",
- "-read_uncommitted",
-#endif
- "-faststat",
- "-txn",
- NULL
- };
- enum dbstatopts {
-#ifdef CONFIG_TEST
- DBCUR_READ_COMMITTED,
- DBCUR_READ_UNCOMMITTED,
-#endif
- DBCUR_FASTSTAT,
- DBCUR_TXN
- };
- DBTYPE type;
- DB_BTREE_STAT *bsp;
- DB_HASH_STAT *hsp;
- DB_QUEUE_STAT *qsp;
- DB_TXN *txn;
- Tcl_Obj *res, *flaglist, *myobjv[2];
- u_int32_t flag;
- int i, optindex, result, ret;
- char *arg, msg[MSG_SIZE];
- void *sp;
-
- result = TCL_OK;
- flag = 0;
- txn = NULL;
- sp = NULL;
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbstatopts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[i]);
- goto error;
- }
- i++;
- switch ((enum dbstatopts)optindex) {
-#ifdef CONFIG_TEST
- case DBCUR_READ_COMMITTED:
- flag |= DB_READ_COMMITTED;
- break;
- case DBCUR_READ_UNCOMMITTED:
- flag |= DB_READ_UNCOMMITTED;
- break;
-#endif
- case DBCUR_FASTSTAT:
- flag |= DB_FAST_STAT;
- break;
- case DBCUR_TXN:
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Stat: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- }
- if (result != TCL_OK)
- break;
- }
- if (result != TCL_OK)
- goto error;
-
- _debug_check();
- ret = dbp->stat(dbp, txn, &sp, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db stat");
- if (result == TCL_ERROR)
- return (result);
-
- (void)dbp->get_type(dbp, &type);
- /*
- * Have our stats, now construct the name value
- * list pairs and free up the memory.
- */
- res = Tcl_NewObj();
-
- /*
- * MAKE_STAT_LIST assumes 'res' and 'error' label.
- */
- if (type == DB_HASH) {
- hsp = (DB_HASH_STAT *)sp;
- MAKE_STAT_LIST("Magic", hsp->hash_magic);
- MAKE_STAT_LIST("Version", hsp->hash_version);
- MAKE_STAT_LIST("Page size", hsp->hash_pagesize);
- MAKE_STAT_LIST("Page count", hsp->hash_pagecnt);
- MAKE_STAT_LIST("Number of keys", hsp->hash_nkeys);
- MAKE_STAT_LIST("Number of records", hsp->hash_ndata);
- MAKE_STAT_LIST("Fill factor", hsp->hash_ffactor);
- MAKE_STAT_LIST("Buckets", hsp->hash_buckets);
- if (flag != DB_FAST_STAT) {
- MAKE_STAT_LIST("Free pages", hsp->hash_free);
- MAKE_WSTAT_LIST("Bytes free", hsp->hash_bfree);
- MAKE_STAT_LIST("Number of big pages",
- hsp->hash_bigpages);
- MAKE_STAT_LIST("Big pages bytes free",
- hsp->hash_big_bfree);
- MAKE_STAT_LIST("Overflow pages", hsp->hash_overflows);
- MAKE_STAT_LIST("Overflow bytes free",
- hsp->hash_ovfl_free);
- MAKE_STAT_LIST("Duplicate pages", hsp->hash_dup);
- MAKE_STAT_LIST("Duplicate pages bytes free",
- hsp->hash_dup_free);
- }
- } else if (type == DB_QUEUE) {
- qsp = (DB_QUEUE_STAT *)sp;
- MAKE_STAT_LIST("Magic", qsp->qs_magic);
- MAKE_STAT_LIST("Version", qsp->qs_version);
- MAKE_STAT_LIST("Page size", qsp->qs_pagesize);
- MAKE_STAT_LIST("Extent size", qsp->qs_extentsize);
- MAKE_STAT_LIST("Number of keys", qsp->qs_nkeys);
- MAKE_STAT_LIST("Number of records", qsp->qs_ndata);
- MAKE_STAT_LIST("Record length", qsp->qs_re_len);
- MAKE_STAT_LIST("Record pad", qsp->qs_re_pad);
- MAKE_STAT_LIST("First record number", qsp->qs_first_recno);
- MAKE_STAT_LIST("Last record number", qsp->qs_cur_recno);
- if (flag != DB_FAST_STAT) {
- MAKE_STAT_LIST("Number of pages", qsp->qs_pages);
- MAKE_WSTAT_LIST("Bytes free", qsp->qs_pgfree);
- }
- } else { /* BTREE and RECNO are same stats */
- bsp = (DB_BTREE_STAT *)sp;
- MAKE_STAT_LIST("Magic", bsp->bt_magic);
- MAKE_STAT_LIST("Version", bsp->bt_version);
- MAKE_STAT_LIST("Number of keys", bsp->bt_nkeys);
- MAKE_STAT_LIST("Number of records", bsp->bt_ndata);
- MAKE_STAT_LIST("Minimum keys per page", bsp->bt_minkey);
- MAKE_STAT_LIST("Fixed record length", bsp->bt_re_len);
- MAKE_STAT_LIST("Record pad", bsp->bt_re_pad);
- MAKE_STAT_LIST("Page size", bsp->bt_pagesize);
- MAKE_STAT_LIST("Page count", bsp->bt_pagecnt);
- if (flag != DB_FAST_STAT) {
- MAKE_STAT_LIST("Levels", bsp->bt_levels);
- MAKE_STAT_LIST("Internal pages", bsp->bt_int_pg);
- MAKE_STAT_LIST("Leaf pages", bsp->bt_leaf_pg);
- MAKE_STAT_LIST("Duplicate pages", bsp->bt_dup_pg);
- MAKE_STAT_LIST("Overflow pages", bsp->bt_over_pg);
- MAKE_STAT_LIST("Empty pages", bsp->bt_empty_pg);
- MAKE_STAT_LIST("Pages on freelist", bsp->bt_free);
- MAKE_STAT_LIST("Internal pages bytes free",
- bsp->bt_int_pgfree);
- MAKE_STAT_LIST("Leaf pages bytes free",
- bsp->bt_leaf_pgfree);
- MAKE_STAT_LIST("Duplicate pages bytes free",
- bsp->bt_dup_pgfree);
- MAKE_STAT_LIST("Bytes free in overflow pages",
- bsp->bt_over_pgfree);
- }
- }
-
- /*
- * Construct a {name {flag1 flag2 ... flagN}} list for the
- * dbp flags. These aren't access-method dependent, but they
- * include all the interesting flags, and the integer value
- * isn't useful from Tcl--return the strings instead.
- */
- myobjv[0] = NewStringObj("Flags", strlen("Flags"));
- myobjv[1] = _GetFlagsList(interp, dbp->flags, __db_get_flags_fn());
- flaglist = Tcl_NewListObj(2, myobjv);
- if (flaglist == NULL) {
- result = TCL_ERROR;
- goto error;
- }
- if ((result =
- Tcl_ListObjAppendElement(interp, res, flaglist)) != TCL_OK)
- goto error;
-
- Tcl_SetObjResult(interp, res);
-error:
- if (sp != NULL)
- __os_ufree(dbp->env, sp);
- return (result);
-}
-
-/*
- * tcl_db_close --
- */
-static int
-tcl_DbClose(interp, objc, objv, dbp, dbip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
- DBTCL_INFO *dbip; /* Info pointer */
-{
- static const char *dbclose[] = {
- "-nosync", "--", NULL
- };
- enum dbclose {
- TCL_DBCLOSE_NOSYNC,
- TCL_DBCLOSE_ENDARG
- };
- u_int32_t flag;
- int endarg, i, optindex, result, ret;
- char *arg;
-
- result = TCL_OK;
- endarg = 0;
- flag = 0;
- if (objc > 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-nosync?");
- return (TCL_ERROR);
- }
-
- for (i = 2; i < objc; ++i) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbclose,
- "option", TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-')
- return (IS_HELP(objv[i]));
- else
- Tcl_ResetResult(interp);
- break;
- }
- switch ((enum dbclose)optindex) {
- case TCL_DBCLOSE_NOSYNC:
- flag = DB_NOSYNC;
- break;
- case TCL_DBCLOSE_ENDARG:
- endarg = 1;
- break;
- }
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- return (result);
- if (endarg)
- break;
- }
- if (dbip->i_cdata != NULL)
- __os_free(dbp->env, dbip->i_cdata);
- _DbInfoDelete(interp, dbip);
- _debug_check();
-
- /* Paranoia. */
- dbp->api_internal = NULL;
-
- ret = (dbp)->close(dbp, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db close");
- return (result);
-}
-
-/*
- * tcl_db_put --
- */
-static int
-tcl_DbPut(interp, objc, objv, dbp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
-{
- static const char *dbputopts[] = {
-#ifdef CONFIG_TEST
- "-nodupdata",
-#endif
- "-append",
- "-multiple",
- "-multiple_key",
- "-nooverwrite",
- "-overwritedup",
- "-partial",
- "-txn",
- NULL
- };
- enum dbputopts {
-#ifdef CONFIG_TEST
- DBGET_NODUPDATA,
-#endif
- DBPUT_APPEND,
- DBPUT_MULTIPLE,
- DBPUT_MULTIPLE_KEY,
- DBPUT_NOOVER,
- DBPUT_OVER,
- DBPUT_PART,
- DBPUT_TXN
- };
- static const char *dbputapp[] = {
- "-append",
- "-multiple_key",
- NULL
- };
- enum dbputapp { DBPUT_APPEND0, DBPUT_MULTIPLE_KEY0 };
- DBT key, data;
- DBTYPE type;
- DB_TXN *txn;
- Tcl_Obj **delemv, **elemv, *res;
- void *dtmp, *ktmp, *ptr;
- db_recno_t recno;
- u_int32_t flag, multiflag;
- int delemc, elemc, end, freekey, freedata;
- int dlen, klen, i, optindex, result, ret;
- char *arg, msg[MSG_SIZE];
-
- txn = NULL;
- result = TCL_OK;
- flag = multiflag = 0;
- if (objc <= 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-args? key data");
- return (TCL_ERROR);
- }
-
- dtmp = ktmp = NULL;
- freekey = freedata = 0;
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- COMPQUIET(recno, 0);
-
- /*
- * If it is a QUEUE or RECNO database, the key is a record number
- * and must be setup up to contain a db_recno_t. Otherwise the
- * key is a "string".
- */
- (void)dbp->get_type(dbp, &type);
-
- /*
- * We need to determine where the end of required args are. If we are
- * using a QUEUE/RECNO db and -append, or -multiple_key is specified,
- * then there is just one req arg (data). Otherwise there are two
- * (key data).
- *
- * We preparse the list to determine this since we need to know
- * to properly check # of args for other options below.
- */
- end = objc - 2;
- i = 2;
- while (i < objc - 1) {
- if (Tcl_GetIndexFromObj(interp, objv[i++], dbputapp,
- "option", TCL_EXACT, &optindex) != TCL_OK)
- continue;
- switch ((enum dbputapp)optindex) {
- case DBPUT_APPEND0:
- case DBPUT_MULTIPLE_KEY0:
- end = objc - 1;
- break;
- }
- }
- Tcl_ResetResult(interp);
-
- /*
- * Get the command name index from the object based on the options
- * defined above.
- */
- i = 2;
- while (i < end) {
- if (Tcl_GetIndexFromObj(interp, objv[i],
- dbputopts, "option", TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(objv[i]));
- i++;
- switch ((enum dbputopts)optindex) {
-#ifdef CONFIG_TEST
- case DBGET_NODUPDATA:
- FLAG_CHECK(flag);
- flag = DB_NODUPDATA;
- break;
-#endif
- case DBPUT_TXN:
- if (i > (end - 1)) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Put: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- case DBPUT_APPEND:
- FLAG_CHECK(flag);
- flag = DB_APPEND;
- break;
- case DBPUT_MULTIPLE:
- FLAG_CHECK(multiflag);
- multiflag = DB_MULTIPLE;
- break;
- case DBPUT_MULTIPLE_KEY:
- FLAG_CHECK(multiflag);
- multiflag = DB_MULTIPLE_KEY;
- break;
- case DBPUT_NOOVER:
- FLAG_CHECK(flag);
- flag = DB_NOOVERWRITE;
- break;
- case DBPUT_OVER:
- FLAG_CHECK(flag);
- flag = DB_OVERWRITE_DUP;
- break;
- case DBPUT_PART:
- if (i > (end - 1)) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-partial {offset length}?");
- result = TCL_ERROR;
- break;
- }
- /*
- * Get sublist as {offset length}
- */
- result = Tcl_ListObjGetElements(interp, objv[i++],
- &elemc, &elemv);
- if (elemc != 2) {
- Tcl_SetResult(interp,
- "List must be {offset length}", TCL_STATIC);
- result = TCL_ERROR;
- break;
- }
- data.flags = DB_DBT_PARTIAL;
- result = _GetUInt32(interp, elemv[0], &data.doff);
- if (result != TCL_OK)
- break;
- result = _GetUInt32(interp, elemv[1], &data.dlen);
- /*
- * NOTE: We don't check result here because all we'd
- * do is break anyway, and we are doing that. If you
- * add code here, you WILL need to add the check
- * for result. (See the check for save.doff, a few
- * lines above and copy that.)
- */
- break;
- }
- if (result != TCL_OK)
- break;
- }
-
- if (result == TCL_ERROR)
- return (result);
-
- if (multiflag == DB_MULTIPLE) {
- /*
- * To work out how big a buffer is needed, we first need to
- * find out the total length of the data and the number of data
- * items (elemc).
- */
- ktmp = Tcl_GetByteArrayFromObj(objv[objc - 2], &klen);
- result = Tcl_ListObjGetElements(interp, objv[objc - 2],
- &elemc, &elemv);
- if (result != TCL_OK)
- return (result);
-
- dtmp = Tcl_GetByteArrayFromObj(objv[objc - 1], &dlen);
- result = Tcl_ListObjGetElements(interp, objv[objc - 1],
- &delemc, &delemv);
- if (result != TCL_OK)
- return (result);
-
- if (elemc < delemc)
- delemc = elemc;
- else
- elemc = delemc;
-
- memset(&key, 0, sizeof(key));
- key.ulen = DB_ALIGN((u_int32_t)klen +
- (u_int32_t)elemc * sizeof(u_int32_t) * 2, 1024UL);
- key.flags = DB_DBT_USERMEM | DB_DBT_BULK;
- if ((ret = __os_malloc(dbp->env, key.ulen, &key.data)) != 0)
- return (ret);
- freekey = 1;
-
- memset(&data, 0, sizeof(data));
- data.ulen = DB_ALIGN((u_int32_t)dlen +
- (u_int32_t)delemc * sizeof(u_int32_t) * 2, 1024UL);
- data.flags = DB_DBT_USERMEM | DB_DBT_BULK;
- if ((ret = __os_malloc(dbp->env, data.ulen, &data.data)) != 0)
- return (ret);
- freedata = 1;
-
- if (type == DB_QUEUE || type == DB_RECNO) {
- DB_MULTIPLE_RECNO_WRITE_INIT(ptr, &key);
- for (i = 0; i < elemc; i++) {
- result = _GetUInt32(interp, elemv[i], &recno);
- DB_MULTIPLE_RECNO_WRITE_NEXT(ptr, &key, recno,
- dtmp, 0);
- DB_ASSERT(dbp->env, ptr != NULL);
- }
- } else {
- DB_MULTIPLE_WRITE_INIT(ptr, &key);
- for (i = 0; i < elemc; i++) {
- ktmp = Tcl_GetByteArrayFromObj(elemv[i], &klen);
- DB_MULTIPLE_WRITE_NEXT(ptr,
- &key, ktmp, (u_int32_t)klen);
- DB_ASSERT(dbp->env, ptr != NULL);
- }
- }
- DB_MULTIPLE_WRITE_INIT(ptr, &data);
- for (i = 0; i < elemc; i++) {
- dtmp = Tcl_GetByteArrayFromObj(delemv[i], &dlen);
- DB_MULTIPLE_WRITE_NEXT(ptr,
- &data, dtmp, (u_int32_t)dlen);
- DB_ASSERT(dbp->env, ptr != NULL);
- }
- } else if (multiflag == DB_MULTIPLE_KEY) {
- /*
- * To work out how big a buffer is needed, we first need to
- * find out the total length of the data (len) and the number
- * of data items (elemc).
- */
- ktmp = Tcl_GetByteArrayFromObj(objv[objc - 1], &klen);
- result = Tcl_ListObjGetElements(interp, objv[objc - 1],
- &elemc, &elemv);
- if (result != TCL_OK)
- return (result);
-
- memset(&key, 0, sizeof(key));
- key.ulen = DB_ALIGN((u_int32_t)klen +
- (u_int32_t)elemc * sizeof(u_int32_t) * 2, 1024UL);
- key.flags = DB_DBT_USERMEM | DB_DBT_BULK;
- if ((ret = __os_malloc(dbp->env, key.ulen, &key.data)) != 0)
- return (ret);
- freekey = 1;
-
- if (type == DB_QUEUE || type == DB_RECNO) {
- DB_MULTIPLE_RECNO_WRITE_INIT(ptr, &key);
- for (i = 0; i + 1 < elemc; i += 2) {
- result = _GetUInt32(interp, elemv[i], &recno);
- dtmp = Tcl_GetByteArrayFromObj(elemv[i + 1],
- &dlen);
- DB_MULTIPLE_RECNO_WRITE_NEXT(ptr, &key,
- recno, dtmp, (u_int32_t)dlen);
- DB_ASSERT(dbp->env, ptr != NULL);
- }
- } else {
- DB_MULTIPLE_WRITE_INIT(ptr, &key);
- for (i = 0; i + 1 < elemc; i += 2) {
- ktmp = Tcl_GetByteArrayFromObj(elemv[i], &klen);
- dtmp = Tcl_GetByteArrayFromObj(elemv[i + 1],
- &dlen);
- DB_MULTIPLE_KEY_WRITE_NEXT(ptr,
- &key, ktmp, (u_int32_t)klen,
- dtmp, (u_int32_t)dlen);
- DB_ASSERT(dbp->env, ptr != NULL);
- }
- }
- } else if (type == DB_QUEUE || type == DB_RECNO) {
- /*
- * If we are a recno db and we are NOT using append, then the
- * 2nd last arg is the key.
- */
- key.data = &recno;
- key.ulen = key.size = sizeof(db_recno_t);
- key.flags = DB_DBT_USERMEM;
- if (flag == DB_APPEND)
- recno = 0;
- else {
- result = _GetUInt32(interp, objv[objc-2], &recno);
- if (result != TCL_OK)
- return (result);
- }
- } else {
- ret = _CopyObjBytes(interp, objv[objc-2], &ktmp,
- &key.size, &freekey);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBPUT(ret), "db put");
- return (result);
- }
- key.data = ktmp;
- }
-
- if (multiflag == 0) {
- ret = _CopyObjBytes(interp,
- objv[objc-1], &dtmp, &data.size, &freedata);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBPUT(ret), "db put");
- goto out;
- }
- data.data = dtmp;
- }
- _debug_check();
- ret = dbp->put(dbp, txn, &key, &data, flag | multiflag);
- result = _ReturnSetup(interp, ret, DB_RETOK_DBPUT(ret), "db put");
-
- /* We may have a returned record number. */
- if (ret == 0 &&
- (type == DB_QUEUE || type == DB_RECNO) && flag == DB_APPEND) {
- res = Tcl_NewWideIntObj((Tcl_WideInt)recno);
- Tcl_SetObjResult(interp, res);
- }
-
-out: if (freedata && data.data != NULL)
- __os_free(dbp->env, data.data);
- if (freekey && key.data != NULL)
- __os_free(dbp->env, key.data);
- return (result);
-}
-
-/*
- * tcl_db_get --
- */
-static int
-tcl_DbGet(interp, objc, objv, dbp, ispget)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
- int ispget; /* 1 for pget, 0 for get */
-{
- static const char *dbgetopts[] = {
-#ifdef CONFIG_TEST
- "-data_buf_size",
- "-multi",
- "-nolease",
- "-read_committed",
- "-read_uncommitted",
-#endif
- "-consume",
- "-consume_wait",
- "-get_both",
- "-glob",
- "-partial",
- "-recno",
- "-rmw",
- "-txn",
- "--",
- NULL
- };
- enum dbgetopts {
-#ifdef CONFIG_TEST
- DBGET_DATA_BUF_SIZE,
- DBGET_MULTI,
- DBGET_NOLEASE,
- DBGET_READ_COMMITTED,
- DBGET_READ_UNCOMMITTED,
-#endif
- DBGET_CONSUME,
- DBGET_CONSUME_WAIT,
- DBGET_BOTH,
- DBGET_GLOB,
- DBGET_PART,
- DBGET_RECNO,
- DBGET_RMW,
- DBGET_TXN,
- DBGET_ENDARG
- };
- DBC *dbc;
- DBT key, pkey, data, save;
- DBTYPE ptype, type;
- DB_TXN *txn;
- Tcl_Obj **elemv, *retlist;
- db_recno_t precno, recno;
- u_int32_t flag, cflag, isdup, mflag, rmw;
- int elemc, end, endarg, freekey, freedata, i;
- int optindex, result, ret, useglob, useprecno, userecno;
- char *arg, *pattern, *prefix, msg[MSG_SIZE];
- void *dtmp, *ktmp;
-#ifdef CONFIG_TEST
- int bufsize, data_buf_size;
-#endif
-
- result = TCL_OK;
- freekey = freedata = 0;
- cflag = endarg = flag = mflag = rmw = 0;
- useglob = userecno = 0;
- txn = NULL;
- pattern = prefix = NULL;
- dtmp = ktmp = NULL;
-#ifdef CONFIG_TEST
- COMPQUIET(bufsize, 0);
- data_buf_size = 0;
-#endif
-
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-args? key");
- return (TCL_ERROR);
- }
-
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- memset(&save, 0, sizeof(save));
-
- /* For the primary key in a pget call. */
- memset(&pkey, 0, sizeof(pkey));
-
- /*
- * Get the command name index from the object based on the options
- * defined above.
- */
- i = 2;
- (void)dbp->get_type(dbp, &type);
- end = objc;
- while (i < end) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbgetopts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto out;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum dbgetopts)optindex) {
-#ifdef CONFIG_TEST
- case DBGET_DATA_BUF_SIZE:
- result =
- Tcl_GetIntFromObj(interp, objv[i], &data_buf_size);
- if (result != TCL_OK)
- goto out;
- i++;
- break;
- case DBGET_MULTI:
- mflag |= DB_MULTIPLE;
- result =
- Tcl_GetIntFromObj(interp, objv[i], &bufsize);
- if (result != TCL_OK)
- goto out;
- i++;
- break;
- case DBGET_NOLEASE:
- rmw |= DB_IGNORE_LEASE;
- break;
- case DBGET_READ_COMMITTED:
- rmw |= DB_READ_COMMITTED;
- break;
- case DBGET_READ_UNCOMMITTED:
- rmw |= DB_READ_UNCOMMITTED;
- break;
-#endif
- case DBGET_BOTH:
- /*
- * Change 'end' and make sure we aren't already past
- * the new end.
- */
- if (i > objc - 2) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-get_both key data?");
- result = TCL_ERROR;
- break;
- }
- end = objc - 2;
- FLAG_CHECK(flag);
- flag = DB_GET_BOTH;
- break;
- case DBGET_TXN:
- if (i >= end) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Get: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- case DBGET_GLOB:
- useglob = 1;
- end = objc - 1;
- break;
- case DBGET_CONSUME:
- FLAG_CHECK(flag);
- flag = DB_CONSUME;
- break;
- case DBGET_CONSUME_WAIT:
- FLAG_CHECK(flag);
- flag = DB_CONSUME_WAIT;
- break;
- case DBGET_RECNO:
- end = objc - 1;
- userecno = 1;
- if (type != DB_RECNO && type != DB_QUEUE) {
- FLAG_CHECK(flag);
- flag = DB_SET_RECNO;
- key.flags |= DB_DBT_MALLOC;
- }
- break;
- case DBGET_RMW:
- rmw |= DB_RMW;
- break;
- case DBGET_PART:
- end = objc - 1;
- if (i == end) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-partial {offset length}?");
- result = TCL_ERROR;
- break;
- }
- /*
- * Get sublist as {offset length}
- */
- result = Tcl_ListObjGetElements(interp, objv[i++],
- &elemc, &elemv);
- if (elemc != 2) {
- Tcl_SetResult(interp,
- "List must be {offset length}", TCL_STATIC);
- result = TCL_ERROR;
- break;
- }
- save.flags = DB_DBT_PARTIAL;
- result = _GetUInt32(interp, elemv[0], &save.doff);
- if (result != TCL_OK)
- break;
- result = _GetUInt32(interp, elemv[1], &save.dlen);
- /*
- * NOTE: We don't check result here because all we'd
- * do is break anyway, and we are doing that. If you
- * add code here, you WILL need to add the check
- * for result. (See the check for save.doff, a few
- * lines above and copy that.)
- */
- break;
- case DBGET_ENDARG:
- endarg = 1;
- break;
- }
- if (result != TCL_OK)
- break;
- if (endarg)
- break;
- }
- if (result != TCL_OK)
- goto out;
-
- if (type == DB_RECNO || type == DB_QUEUE)
- userecno = 1;
-
- /*
- * Check args we have left versus the flags we were given.
- * We might have 0, 1 or 2 left. If we have 0, it must
- * be DB_CONSUME*, if 2, then DB_GET_BOTH, all others should
- * be 1.
- */
- if (((flag == DB_CONSUME || flag == DB_CONSUME_WAIT) && i != objc) ||
- (flag == DB_GET_BOTH && i != objc - 2)) {
- Tcl_SetResult(interp,
- "Wrong number of key/data given based on flags specified\n",
- TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- } else if (flag == 0 && i != objc - 1) {
- Tcl_SetResult(interp,
- "Wrong number of key/data given\n", TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- }
-
- /*
- * Find out whether the primary key should also be a recno.
- */
- if (ispget && dbp->s_primary != NULL) {
- (void)dbp->s_primary->get_type(dbp->s_primary, &ptype);
- useprecno = ptype == DB_RECNO || ptype == DB_QUEUE;
- } else
- useprecno = 0;
-
- /*
- * Check for illegal combos of options.
- */
- if (useglob && (userecno || flag == DB_SET_RECNO ||
- type == DB_RECNO || type == DB_QUEUE)) {
- Tcl_SetResult(interp,
- "Cannot use -glob and record numbers.\n",
- TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- }
-#ifdef CONFIG_TEST
- if (data_buf_size != 0 && flag == DB_GET_BOTH) {
- Tcl_SetResult(interp,
- "Only one of -data_buf_size or -get_both can be specified.\n",
- TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- }
- if (data_buf_size != 0 && mflag != 0) {
- Tcl_SetResult(interp,
- "Only one of -data_buf_size or -multi can be specified.\n",
- TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- }
-#endif
- if (useglob && flag == DB_GET_BOTH) {
- Tcl_SetResult(interp,
- "Only one of -glob or -get_both can be specified.\n",
- TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- }
-
- if (useglob)
- pattern = Tcl_GetStringFromObj(objv[objc - 1], NULL);
-
- /*
- * This is the list we return
- */
- retlist = Tcl_NewListObj(0, NULL);
- save.flags |= DB_DBT_MALLOC;
-
- /*
- * isdup is used to know if we support duplicates. If not, we
- * can just do a db->get call and avoid using cursors.
- */
- if ((ret = dbp->get_flags(dbp, &isdup)) != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db get");
- goto out;
- }
- isdup &= DB_DUP;
-
- /*
- * If the database doesn't support duplicates or we're performing
- * ops that don't require returning multiple items, use DB->get
- * instead of a cursor operation.
- */
- if (pattern == NULL && (isdup == 0 || mflag != 0 ||
-#ifdef CONFIG_TEST
- data_buf_size != 0 ||
-#endif
- flag == DB_SET_RECNO || flag == DB_GET_BOTH ||
- flag == DB_CONSUME || flag == DB_CONSUME_WAIT)) {
-#ifdef CONFIG_TEST
- if (data_buf_size == 0) {
- F_CLR(&save, DB_DBT_USERMEM);
- F_SET(&save, DB_DBT_MALLOC);
- } else {
- (void)__os_malloc(
- NULL, (size_t)data_buf_size, &save.data);
- save.ulen = (u_int32_t)data_buf_size;
- F_CLR(&save, DB_DBT_MALLOC);
- F_SET(&save, DB_DBT_USERMEM);
- }
-#endif
- if (flag == DB_GET_BOTH) {
- if (userecno) {
- result = _GetUInt32(interp,
- objv[(objc - 2)], &recno);
- if (result == TCL_OK) {
- key.data = &recno;
- key.size = sizeof(db_recno_t);
- } else
- goto out;
- } else {
- /*
- * Some get calls (SET_*) can change the
- * key pointers. So, we need to store
- * the allocated key space in a tmp.
- */
- ret = _CopyObjBytes(interp, objv[objc-2],
- &key.data, &key.size, &freekey);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBGET(ret), "db get");
- goto out;
- }
- }
- ktmp = key.data;
- /*
- * Already checked args above. Fill in key and save.
- * Save is used in the dbp->get call below to fill in
- * data.
- *
- * If the "data" here is really a primary key--that
- * is, if we're in a pget--and that primary key
- * is a recno, treat it appropriately as an int.
- */
- if (useprecno) {
- result = _GetUInt32(interp,
- objv[objc - 1], &precno);
- if (result == TCL_OK) {
- save.data = &precno;
- save.size = sizeof(db_recno_t);
- } else
- goto out;
- } else {
- ret = _CopyObjBytes(interp, objv[objc-1],
- &dtmp, &save.size, &freedata);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBGET(ret), "db get");
- goto out;
- }
- save.data = dtmp;
- }
- } else if (flag != DB_CONSUME && flag != DB_CONSUME_WAIT) {
- if (userecno) {
- result = _GetUInt32(
- interp, objv[(objc - 1)], &recno);
- if (result == TCL_OK) {
- key.data = &recno;
- key.size = sizeof(db_recno_t);
- } else
- goto out;
- } else {
- /*
- * Some get calls (SET_*) can change the
- * key pointers. So, we need to store
- * the allocated key space in a tmp.
- */
- ret = _CopyObjBytes(interp, objv[objc-1],
- &key.data, &key.size, &freekey);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBGET(ret), "db get");
- goto out;
- }
- }
- ktmp = key.data;
-#ifdef CONFIG_TEST
- if (mflag & DB_MULTIPLE) {
- if ((ret = __os_malloc(dbp->env,
- (size_t)bufsize, &save.data)) != 0) {
- Tcl_SetResult(interp,
- db_strerror(ret), TCL_STATIC);
- goto out;
- }
- save.ulen = (u_int32_t)bufsize;
- F_CLR(&save, DB_DBT_MALLOC);
- F_SET(&save, DB_DBT_USERMEM);
- }
-#endif
- }
-
- data = save;
-
- if (ispget) {
- if (flag == DB_GET_BOTH) {
- pkey.data = save.data;
- pkey.size = save.size;
- data.data = NULL;
- data.size = 0;
- }
- F_SET(&pkey, DB_DBT_MALLOC);
- _debug_check();
- ret = dbp->pget(dbp,
- txn, &key, &pkey, &data, flag | rmw);
- } else {
- _debug_check();
- ret = dbp->get(dbp,
- txn, &key, &data, flag | rmw | mflag);
- }
- result = _ReturnSetup(interp, ret, DB_RETOK_DBGET(ret),
- "db get");
- if (ret == 0) {
- /*
- * Success. Return a list of the form {name value}
- * If it was a recno in key.data, we need to convert
- * into a string/object representation of that recno.
- */
- if (mflag & DB_MULTIPLE)
- result = _SetMultiList(interp,
- retlist, &key, &data, type, flag);
- else if (type == DB_RECNO || type == DB_QUEUE)
- if (ispget)
- result = _Set3DBTList(interp,
- retlist, &key, 1, &pkey,
- useprecno, &data);
- else
- result = _SetListRecnoElem(interp,
- retlist, *(db_recno_t *)key.data,
- data.data, data.size);
- else {
- if (ispget)
- result = _Set3DBTList(interp,
- retlist, &key, 0, &pkey,
- useprecno, &data);
- else
- result = _SetListElem(interp, retlist,
- key.data, key.size,
- data.data, data.size);
- }
- }
- /*
- * Free space from DBT.
- *
- * If we set DB_DBT_MALLOC, we need to free the space if and
- * only if we succeeded and if DB allocated anything (the
- * pointer has changed from what we passed in). If
- * DB_DBT_MALLOC is not set, this is a bulk get buffer, and
- * needs to be freed no matter what.
- */
- if (F_ISSET(&key, DB_DBT_MALLOC) && ret == 0 &&
- key.data != ktmp)
- __os_ufree(dbp->env, key.data);
- if (F_ISSET(&data, DB_DBT_MALLOC) && ret == 0 &&
- data.data != dtmp)
- __os_ufree(dbp->env, data.data);
- else if (!F_ISSET(&data, DB_DBT_MALLOC))
- __os_free(dbp->env, data.data);
- if (ispget && ret == 0 && pkey.data != save.data)
- __os_ufree(dbp->env, pkey.data);
- if (result == TCL_OK)
- Tcl_SetObjResult(interp, retlist);
- goto out;
- }
-
- if (userecno) {
- result = _GetUInt32(interp, objv[(objc - 1)], &recno);
- if (result == TCL_OK) {
- key.data = &recno;
- key.size = sizeof(db_recno_t);
- } else
- goto out;
- } else {
- /*
- * Some get calls (SET_*) can change the
- * key pointers. So, we need to store
- * the allocated key space in a tmp.
- */
- ret = _CopyObjBytes(interp, objv[objc-1], &key.data,
- &key.size, &freekey);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBGET(ret), "db get");
- return (result);
- }
- }
- ktmp = key.data;
- ret = dbp->cursor(dbp, txn, &dbc, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db cursor");
- if (result == TCL_ERROR)
- goto out;
-
- /*
- * At this point, we have a cursor, if we have a pattern,
- * we go to the nearest one and step forward until we don't
- * have any more that match the pattern prefix. If we have
- * an exact key, we go to that key position, and step through
- * all the duplicates. In either case we build up a list of
- * the form {{key data} {key data}...} along the way.
- */
- memset(&data, 0, sizeof(data));
- /*
- * Restore any "partial" info we have saved.
- */
- data = save;
- if (pattern) {
- /*
- * Note, prefix is returned in new space. Must free it.
- */
- ret = _GetGlobPrefix(pattern, &prefix);
- if (ret) {
- result = TCL_ERROR;
- Tcl_SetResult(interp,
- "Unable to allocate pattern space", TCL_STATIC);
- goto out1;
- }
- key.data = prefix;
- key.size = (u_int32_t)strlen(prefix);
- /*
- * If they give us an empty pattern string
- * (i.e. -glob *), go through entire DB.
- */
- if (strlen(prefix) == 0)
- cflag = DB_FIRST;
- else
- cflag = DB_SET_RANGE;
- } else
- cflag = DB_SET;
- if (ispget) {
- _debug_check();
- F_SET(&pkey, DB_DBT_MALLOC);
- ret = dbc->pget(dbc, &key, &pkey, &data, cflag | rmw);
- } else {
- _debug_check();
- ret = dbc->get(dbc, &key, &data, cflag | rmw);
- }
- result = _ReturnSetup(interp, ret, DB_RETOK_DBCGET(ret),
- "db get (cursor)");
- if (result == TCL_ERROR)
- goto out1;
- if (pattern) {
- if (ret == 0 && prefix != NULL &&
- memcmp(key.data, prefix, strlen(prefix)) != 0) {
- /*
- * Free space from DB_DBT_MALLOC
- */
- __os_ufree(dbp->env, data.data);
- goto out1;
- }
- cflag = DB_NEXT;
- } else
- cflag = DB_NEXT_DUP;
-
- while (ret == 0 && result == TCL_OK) {
- /*
- * Build up our {name value} sublist
- */
- if (ispget)
- result = _Set3DBTList(interp, retlist, &key, 0,
- &pkey, useprecno, &data);
- else
- result = _SetListElem(interp, retlist,
- key.data, key.size, data.data, data.size);
- /*
- * Free space from DB_DBT_MALLOC
- */
- if (ispget)
- __os_ufree(dbp->env, pkey.data);
- __os_ufree(dbp->env, data.data);
- if (result != TCL_OK)
- break;
- /*
- * Append {name value} to return list
- */
- memset(&key, 0, sizeof(key));
- memset(&pkey, 0, sizeof(pkey));
- memset(&data, 0, sizeof(data));
- /*
- * Restore any "partial" info we have saved.
- */
- data = save;
- if (ispget) {
- F_SET(&pkey, DB_DBT_MALLOC);
- ret = dbc->pget(dbc, &key, &pkey, &data, cflag | rmw);
- } else
- ret = dbc->get(dbc, &key, &data, cflag | rmw);
- if (ret == 0 && prefix != NULL &&
- memcmp(key.data, prefix, strlen(prefix)) != 0) {
- /*
- * Free space from DB_DBT_MALLOC
- */
- __os_ufree(dbp->env, data.data);
- break;
- }
- }
-out1:
- (void)dbc->close(dbc);
- if (result == TCL_OK)
- Tcl_SetObjResult(interp, retlist);
-out:
- /*
- * _GetGlobPrefix(), the function which allocates prefix, works
- * by copying and condensing another string. Thus prefix may
- * have multiple nuls at the end, so we free using __os_free().
- */
- if (prefix != NULL)
- __os_free(dbp->env, prefix);
- if (dtmp != NULL && freedata)
- __os_free(dbp->env, dtmp);
- if (ktmp != NULL && freekey)
- __os_free(dbp->env, ktmp);
- return (result);
-}
-
-/*
- * tcl_db_delete --
- */
-static int
-tcl_DbDelete(interp, objc, objv, dbp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
-{
- static const char *dbdelopts[] = {
- "-consume",
- "-glob",
- "-multiple",
- "-multiple_key",
- "-txn",
- NULL
- };
- enum dbdelopts {
- DBDEL_CONSUME,
- DBDEL_GLOB,
- DBDEL_MULTIPLE,
- DBDEL_MULTIPLE_KEY,
- DBDEL_TXN
- };
- DBC *dbc;
- DBT key, data;
- DBTYPE type;
- DB_TXN *txn;
- Tcl_Obj **elemv;
- void *dtmp, *ktmp, *ptr;
- db_recno_t recno;
- int dlen, elemc, freekey, i, j, klen, optindex, result, ret;
- u_int32_t dflag, flag, multiflag;
- char *arg, *pattern, *prefix, msg[MSG_SIZE];
-
- result = TCL_OK;
- freekey = 0;
- dflag = 0;
- multiflag = 0;
- pattern = prefix = NULL;
- txn = NULL;
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-args? key");
- return (TCL_ERROR);
- }
-
- dtmp = ktmp = NULL;
- memset(&key, 0, sizeof(key));
- /*
- * The first arg must be -glob, -txn or a list of keys.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbdelopts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- /*
- * If we don't have a -glob or -txn, then the remaining
- * args must be exact keys. Reset the result so we
- * don't get an errant error message if there is another
- * error.
- */
- if (IS_HELP(objv[i]) == TCL_OK)
- return (TCL_OK);
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum dbdelopts)optindex) {
- case DBDEL_TXN:
- if (i == objc) {
- /*
- * Someone could conceivably have a key of
- * the same name. So just break and use it.
- */
- i--;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Delete: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- case DBDEL_GLOB:
- /*
- * Get the pattern. Get the prefix and use cursors to
- * get all the data items.
- */
- if (i == objc) {
- /*
- * Someone could conceivably have a key of
- * the same name. So just break and use it.
- */
- i--;
- break;
- }
- pattern = Tcl_GetStringFromObj(objv[i++], NULL);
- break;
- case DBDEL_CONSUME:
- FLAG_CHECK(dflag);
- dflag = DB_CONSUME;
- break;
- case DBDEL_MULTIPLE:
- FLAG_CHECK(multiflag);
- multiflag |= DB_MULTIPLE;
- break;
- case DBDEL_MULTIPLE_KEY:
- FLAG_CHECK(multiflag);
- multiflag |= DB_MULTIPLE_KEY;
- break;
- }
- if (result != TCL_OK)
- break;
- }
-
- if (result != TCL_OK)
- goto out;
- /*
- * XXX
- * For consistency with get, we have decided for the moment, to
- * allow -glob, or one key, not many. The code was originally
- * written to take many keys and we'll leave it that way, because
- * tcl_DbGet may one day accept many disjoint keys to get, rather
- * than one, and at that time we'd make delete be consistent. In
- * any case, the code is already here and there is no need to remove,
- * just check that we only have one arg left.
- *
- * If we have a pattern AND more keys to process, there is an error.
- * Either we have some number of exact keys, or we have a pattern.
- */
- if (pattern == NULL) {
- if (i != (objc - 1)) {
- Tcl_WrongNumArgs(
- interp, 2, objv, "?args? -glob pattern | key");
- result = TCL_ERROR;
- goto out;
- }
- } else {
- if (i != objc) {
- Tcl_WrongNumArgs(
- interp, 2, objv, "?args? -glob pattern | key");
- result = TCL_ERROR;
- goto out;
- }
- }
-
- /*
- * If we have remaining args, they are all exact keys. Call
- * DB->del on each of those keys.
- *
- * If it is a RECNO database, the key is a record number and must be
- * setup up to contain a db_recno_t. Otherwise the key is a "string".
- */
- (void)dbp->get_type(dbp, &type);
- ret = 0;
- while (i < objc && ret == 0) {
- memset(&key, 0, sizeof(key));
- if (multiflag == DB_MULTIPLE) {
- /*
- * To work out how big a buffer is needed, we first
- * need to find out the total length of the data and
- * the number of data items (elemc).
- */
- ktmp = Tcl_GetByteArrayFromObj(objv[i], &klen);
- result = Tcl_ListObjGetElements(interp, objv[i++],
- &elemc, &elemv);
- if (result != TCL_OK)
- return (result);
-
- memset(&key, 0, sizeof(key));
- key.ulen = DB_ALIGN((u_int32_t)klen + (u_int32_t)elemc
- * sizeof(u_int32_t) * 2, 1024UL);
- key.flags = DB_DBT_USERMEM | DB_DBT_BULK;
- if ((ret =
- __os_malloc(dbp->env, key.ulen, &key.data)) != 0)
- return (ret);
- freekey = 1;
-
- if (type == DB_RECNO || type == DB_QUEUE) {
- DB_MULTIPLE_RECNO_WRITE_INIT(ptr, &key);
- for (j = 0; j < elemc; j++) {
- result =
- _GetUInt32(interp,
- elemv[j], &recno);
- if (result != TCL_OK)
- return (result);
- DB_MULTIPLE_RECNO_WRITE_NEXT(ptr,
- &key, recno, dtmp, 0);
- DB_ASSERT(dbp->env, ptr != NULL);
- }
- } else {
- DB_MULTIPLE_WRITE_INIT(ptr, &key);
- for (j = 0; j < elemc; j++) {
- ktmp = Tcl_GetByteArrayFromObj(elemv[j],
- &klen);
- DB_MULTIPLE_WRITE_NEXT(ptr,
- &key, ktmp, (u_int32_t)klen);
- DB_ASSERT(dbp->env, ptr != NULL);
- }
- }
- } else if (multiflag == DB_MULTIPLE_KEY) {
- /*
- * To work out how big a buffer is needed, we first
- * need to find out the total length of the data (len)
- * and the number of data items (elemc).
- */
- ktmp = Tcl_GetByteArrayFromObj(objv[i], &klen);
- result = Tcl_ListObjGetElements(interp, objv[i++],
- &elemc, &elemv);
- if (result != TCL_OK)
- return (result);
-
- memset(&key, 0, sizeof(key));
- key.ulen = DB_ALIGN((u_int32_t)klen +
- (u_int32_t)elemc * sizeof(u_int32_t) * 2, 1024UL);
- key.flags = DB_DBT_USERMEM | DB_DBT_BULK;
- if ((ret =
- __os_malloc(dbp->env, key.ulen, &key.data)) != 0)
- return (ret);
- freekey = 1;
-
- if (type == DB_RECNO || type == DB_QUEUE) {
- DB_MULTIPLE_RECNO_WRITE_INIT(ptr, &key);
- for (j = 0; j + 1 < elemc; j += 2) {
- result =
- _GetUInt32(interp,
- elemv[j], &recno);
- if (result != TCL_OK)
- return (result);
- dtmp = Tcl_GetByteArrayFromObj(
- elemv[j + 1], &dlen);
- DB_MULTIPLE_RECNO_WRITE_NEXT(ptr,
- &key, recno, dtmp, (u_int32_t)dlen);
- DB_ASSERT(dbp->env, ptr != NULL);
- }
- } else {
- DB_MULTIPLE_WRITE_INIT(ptr, &key);
- for (j = 0; j + 1 < elemc; j += 2) {
- ktmp = Tcl_GetByteArrayFromObj(
- elemv[j], &klen);
- dtmp = Tcl_GetByteArrayFromObj(
- elemv[j + 1], &dlen);
- DB_MULTIPLE_KEY_WRITE_NEXT(ptr,
- &key, ktmp, (u_int32_t)klen,
- dtmp, (u_int32_t)dlen);
- DB_ASSERT(dbp->env, ptr != NULL);
- }
- }
- } else if (type == DB_RECNO || type == DB_QUEUE) {
- result = _GetUInt32(interp, objv[i++], &recno);
- if (result == TCL_OK) {
- key.data = &recno;
- key.size = sizeof(db_recno_t);
- } else
- return (result);
- } else {
- ret = _CopyObjBytes(interp, objv[i++], &ktmp,
- &key.size, &freekey);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBDEL(ret), "db del");
- return (result);
- }
- key.data = ktmp;
- }
- _debug_check();
- ret = dbp->del(dbp, txn, &key, dflag | multiflag);
- /*
- * If we have any error, set up return result and stop
- * processing keys.
- */
- if (freekey && key.data != NULL)
- __os_free(dbp->env, key.data);
- if (ret != 0)
- break;
- }
- result = _ReturnSetup(interp, ret, DB_RETOK_DBDEL(ret), "db del");
-
- /*
- * At this point we've either finished or, if we have a pattern,
- * we go to the nearest one and step forward until we don't
- * have any more that match the pattern prefix.
- */
- if (pattern) {
- ret = dbp->cursor(dbp, txn, &dbc, 0);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db cursor");
- goto out;
- }
- /*
- * Note, prefix is returned in new space. Must free it.
- */
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- ret = _GetGlobPrefix(pattern, &prefix);
- if (ret) {
- result = TCL_ERROR;
- Tcl_SetResult(interp,
- "Unable to allocate pattern space", TCL_STATIC);
- goto out;
- }
- key.data = prefix;
- key.size = (u_int32_t)strlen(prefix);
- if (strlen(prefix) == 0)
- flag = DB_FIRST;
- else
- flag = DB_SET_RANGE;
- ret = dbc->get(dbc, &key, &data, flag);
- while (ret == 0 &&
- memcmp(key.data, prefix, strlen(prefix)) == 0) {
- /*
- * Each time through here the cursor is pointing
- * at the current valid item. Delete it and
- * move ahead.
- */
- _debug_check();
- ret = dbc->del(dbc, dflag);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBCDEL(ret), "db c_del");
- break;
- }
- /*
- * Deleted the current, now move to the next item
- * in the list, check if it matches the prefix pattern.
- */
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- ret = dbc->get(dbc, &key, &data, DB_NEXT);
- }
- if (ret == DB_NOTFOUND)
- ret = 0;
- /*
- * _GetGlobPrefix(), the function which allocates prefix, works
- * by copying and condensing another string. Thus prefix may
- * have multiple nuls at the end, so we free using __os_free().
- */
- __os_free(dbp->env, prefix);
- (void)dbc->close(dbc);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db del");
- }
-out:
- return (result);
-}
-
-/*
- * tcl_db_cursor --
- */
-static int
-tcl_DbCursor(interp, objc, objv, dbp, dbcp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
- DBC **dbcp; /* Return cursor pointer */
-{
- static const char *dbcuropts[] = {
-#ifdef CONFIG_TEST
- "-read_committed",
- "-read_uncommitted",
- "-update",
-#endif
- "-bulk",
- "-txn",
- NULL
- };
- enum dbcuropts {
-#ifdef CONFIG_TEST
- DBCUR_READ_COMMITTED,
- DBCUR_READ_UNCOMMITTED,
- DBCUR_UPDATE,
-#endif
- DBCUR_BULK,
- DBCUR_TXN
- };
- DB_TXN *txn;
- u_int32_t flag;
- int i, optindex, result, ret;
- char *arg, msg[MSG_SIZE];
-
- result = TCL_OK;
- flag = 0;
- txn = NULL;
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbcuropts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[i]);
- goto out;
- }
- i++;
- switch ((enum dbcuropts)optindex) {
-#ifdef CONFIG_TEST
- case DBCUR_READ_COMMITTED:
- flag |= DB_READ_COMMITTED;
- break;
- case DBCUR_READ_UNCOMMITTED:
- flag |= DB_READ_UNCOMMITTED;
- break;
- case DBCUR_UPDATE:
- flag |= DB_WRITECURSOR;
- break;
-#endif
- case DBCUR_BULK:
- flag |= DB_CURSOR_BULK;
- break;
- case DBCUR_TXN:
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Cursor: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- }
- if (result != TCL_OK)
- break;
- }
- if (result != TCL_OK)
- goto out;
-
- _debug_check();
- ret = dbp->cursor(dbp, txn, dbcp, flag);
- if (ret != 0)
- result = _ErrorSetup(interp, ret, "db cursor");
-out:
- return (result);
-}
-
-/*
- * tcl_DbAssociate --
- * Call DB->associate().
- */
-static int
-tcl_DbAssociate(interp, objc, objv, dbp)
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
- DB *dbp;
-{
- static const char *dbaopts[] = {
- "-create",
- "-immutable_key",
- "-txn",
- NULL
- };
- enum dbaopts {
- DBA_CREATE,
- DBA_IMMUTABLE_KEY,
- DBA_TXN
- };
- DB *sdbp;
- DB_TXN *txn;
- DBTCL_INFO *sdbip;
- int i, optindex, result, ret;
- char *arg, msg[MSG_SIZE];
- u_int32_t flag;
-#ifdef CONFIG_TEST
- /*
- * When calling DB->associate over RPC, the Tcl API uses
- * special flags that the RPC server interprets to set the
- * callback correctly.
- */
- const char *cbname;
- struct {
- const char *name;
- u_int32_t flag;
- } *cb, callbacks[] = {
- { "", 0 }, /* A NULL callback in Tcl. */
- { "_s_reversedata", DB_RPC2ND_REVERSEDATA },
- { "_s_noop", DB_RPC2ND_NOOP },
- { "_s_concatkeydata", DB_RPC2ND_CONCATKEYDATA },
- { "_s_concatdatakey", DB_RPC2ND_CONCATDATAKEY },
- { "_s_reverseconcat", DB_RPC2ND_REVERSECONCAT },
- { "_s_truncdata", DB_RPC2ND_TRUNCDATA },
- { "_s_reversedata", DB_RPC2ND_REVERSEDATA },
- { "_s_constant", DB_RPC2ND_CONSTANT },
- { "sj_getzip", DB_RPC2ND_GETZIP },
- { "sj_getname", DB_RPC2ND_GETNAME },
- { NULL, 0 }
- };
-#endif
-
- txn = NULL;
- result = TCL_OK;
- flag = 0;
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "[callback] secondary");
- return (TCL_ERROR);
- }
-
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbaopts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[i]);
- if (result == TCL_OK)
- return (result);
- result = TCL_OK;
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum dbaopts)optindex) {
- case DBA_CREATE:
- flag |= DB_CREATE;
- break;
- case DBA_IMMUTABLE_KEY:
- flag |= DB_IMMUTABLE_KEY;
- break;
- case DBA_TXN:
- if (i > (objc - 1)) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Associate: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- }
- }
- if (result != TCL_OK)
- return (result);
-
- /*
- * Better be 1 or 2 args left. The last arg must be the sdb
- * handle. If 2 args then objc-2 is the callback proc, else
- * we have a NULL callback.
- */
- /* Get the secondary DB handle. */
- arg = Tcl_GetStringFromObj(objv[objc - 1], NULL);
- sdbp = NAME_TO_DB(arg);
- if (sdbp == NULL) {
- snprintf(msg, MSG_SIZE,
- "Associate: Invalid database handle: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- return (TCL_ERROR);
- }
-
- /*
- * The callback is simply a Tcl object containing the name
- * of the callback proc, which is the second-to-last argument.
- *
- * Note that the callback needs to go in the *secondary* DB handle's
- * info struct; we may have multiple secondaries with different
- * callbacks.
- */
- sdbip = (DBTCL_INFO *)sdbp->api_internal;
-
-#ifdef CONFIG_TEST
- if (i != objc - 1 && RPC_ON(dbp->dbenv)) {
- /*
- * The flag values allowed to DB->associate may have changed to
- * overlap with the range we've chosen. If this happens, we
- * need to reset all of the RPC_2ND_* flags to a new range.
- */
- if ((flag & DB_RPC2ND_MASK) != 0) {
- snprintf(msg, MSG_SIZE,
- "RPC secondary flags overlap -- recalculate!\n");
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- return (TCL_ERROR);
- }
-
- cbname = Tcl_GetStringFromObj(objv[objc - 2], NULL);
- for (cb = callbacks; cb->name != NULL; cb++)
- if (strcmp(cb->name, cbname) == 0) {
- flag |= cb->flag;
- break;
- }
-
- if (cb->name == NULL) {
- snprintf(msg, MSG_SIZE,
- "Associate: unknown callback: %s\n", cbname);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- return (TCL_ERROR);
- }
-
- ret = dbp->associate(dbp, txn, sdbp, NULL, flag);
-
- /*
- * The primary reference isn't set when calling through
- * the RPC server, but the Tcl API peeks at it in other
- * places (see tcl_DbGet).
- */
- if (ret == 0)
- sdbp->s_primary = dbp;
- } else if (i != objc - 1) {
-#else
- if (i != objc - 1) {
-#endif
- /*
- * We have 2 args, get the callback.
- */
- sdbip->i_second_call = objv[objc - 2];
- Tcl_IncrRefCount(sdbip->i_second_call);
-
- /* Now call associate. */
- _debug_check();
- ret = dbp->associate(dbp, txn, sdbp, tcl_second_call, flag);
- } else {
- /*
- * We have a NULL callback.
- */
- sdbip->i_second_call = NULL;
- ret = dbp->associate(dbp, txn, sdbp, NULL, flag);
- }
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "associate");
-
- return (result);
-}
-
-/*
- * tcl_second_call --
- * Callback function for secondary indices. Get the callback
- * out of ip->i_second_call and call it.
- */
-static int
-tcl_second_call(dbp, pkey, data, skey)
- DB *dbp;
- const DBT *pkey, *data;
- DBT *skey;
-{
- DBT *tskey;
- DBTCL_INFO *ip;
- Tcl_Interp *interp;
- Tcl_Obj *pobj, *dobj, *objv[3], *robj, **skeylist;
- size_t len;
- int ilen, result, ret;
- u_int32_t i, nskeys;
- void *retbuf, *databuf;
-
- ip = (DBTCL_INFO *)dbp->api_internal;
- interp = ip->i_interp;
- objv[0] = ip->i_second_call;
-
- /*
- * Create two ByteArray objects, with the contents of the pkey
- * and data DBTs that are our inputs.
- */
- pobj = Tcl_NewByteArrayObj(pkey->data, (int)pkey->size);
- Tcl_IncrRefCount(pobj);
- dobj = Tcl_NewByteArrayObj(data->data, (int)data->size);
- Tcl_IncrRefCount(dobj);
-
- objv[1] = pobj;
- objv[2] = dobj;
-
- result = Tcl_EvalObjv(interp, 3, objv, 0);
-
- Tcl_DecrRefCount(pobj);
- Tcl_DecrRefCount(dobj);
-
- if (result != TCL_OK) {
- __db_errx(dbp->env,
- "Tcl callback function failed with code %d", result);
- return (EINVAL);
- }
-
- robj = Tcl_GetObjResult(interp);
- if (robj->typePtr == NULL || strcmp(robj->typePtr->name, "list") != 0) {
- nskeys = 1;
- skeylist = &robj;
- tskey = skey;
- } else {
- if ((result = Tcl_ListObjGetElements(interp,
- robj, &ilen, &skeylist)) != TCL_OK) {
- __db_errx(dbp->env,
- "Could not get list elements from Tcl callback");
- return (EINVAL);
- }
- nskeys = (u_int32_t)ilen;
-
- /*
- * It would be nice to check for nskeys == 0 and return
- * DB_DONOTINDEX, but Tcl does not distinguish between an empty
- * string and an empty list, so that would disallow empty
- * secondary keys.
- */
- if (nskeys == 0) {
- nskeys = 1;
- skeylist = &robj;
- }
- if (nskeys == 1)
- tskey = skey;
- else {
- memset(skey, 0, sizeof(DBT));
- if ((ret = __os_umalloc(dbp->env,
- nskeys * sizeof(DBT), &skey->data)) != 0)
- return (ret);
- skey->size = nskeys;
- F_SET(skey, DB_DBT_MULTIPLE | DB_DBT_APPMALLOC);
- tskey = (DBT *)skey->data;
- }
- }
-
- for (i = 0; i < nskeys; i++, tskey++) {
- retbuf = Tcl_GetByteArrayFromObj(skeylist[i], &ilen);
- len = (size_t)ilen;
-
- /*
- * retbuf is owned by Tcl; copy it into malloc'ed memory.
- * We need to use __os_umalloc rather than ufree because this
- * will be freed by DB using __os_ufree--the DB_DBT_APPMALLOC
- * flag tells DB to free application-allocated memory.
- */
- if ((ret = __os_umalloc(dbp->env, len, &databuf)) != 0)
- return (ret);
- memcpy(databuf, retbuf, len);
-
- memset(tskey, 0, sizeof(DBT));
- tskey->data = databuf;
- tskey->size = (u_int32_t)len;
- F_SET(tskey, DB_DBT_APPMALLOC);
- }
-
- return (0);
-}
-
-/*
- * tcl_db_join --
- */
-static int
-tcl_DbJoin(interp, objc, objv, dbp, dbcp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
- DBC **dbcp; /* Cursor pointer */
-{
- static const char *dbjopts[] = {
- "-nosort",
- NULL
- };
- enum dbjopts {
- DBJ_NOSORT
- };
- DBC **listp;
- size_t size;
- u_int32_t flag;
- int adj, i, j, optindex, result, ret;
- char *arg, msg[MSG_SIZE];
-
- result = TCL_OK;
- flag = 0;
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "curs1 curs2 ...");
- return (TCL_ERROR);
- }
-
- for (adj = i = 2; i < objc; i++) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbjopts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[i]);
- if (result == TCL_OK)
- return (result);
- result = TCL_OK;
- Tcl_ResetResult(interp);
- break;
- }
- switch ((enum dbjopts)optindex) {
- case DBJ_NOSORT:
- flag |= DB_JOIN_NOSORT;
- adj++;
- break;
- }
- }
- if (result != TCL_OK)
- return (result);
- /*
- * Allocate one more for NULL ptr at end of list.
- */
- size = sizeof(DBC *) * (size_t)((objc - adj) + 1);
- ret = __os_malloc(dbp->env, size, &listp);
- if (ret != 0) {
- Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC);
- return (TCL_ERROR);
- }
-
- memset(listp, 0, size);
- for (j = 0, i = adj; i < objc; i++, j++) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- listp[j] = NAME_TO_DBC(arg);
- if (listp[j] == NULL) {
- snprintf(msg, MSG_SIZE,
- "Join: Invalid cursor: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- goto out;
- }
- }
- listp[j] = NULL;
- _debug_check();
- ret = dbp->join(dbp, listp, dbcp, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db join");
-
-out:
- __os_free(dbp->env, listp);
- return (result);
-}
-
-/*
- * tcl_db_getjoin --
- */
-static int
-tcl_DbGetjoin(interp, objc, objv, dbp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
-{
- static const char *dbgetjopts[] = {
-#ifdef CONFIG_TEST
- "-nosort",
-#endif
- "-txn",
- NULL
- };
- enum dbgetjopts {
-#ifdef CONFIG_TEST
- DBGETJ_NOSORT,
-#endif
- DBGETJ_TXN
- };
- DB_TXN *txn;
- DB *elemdbp;
- DBC **listp;
- DBC *dbc;
- DBT key, data;
- Tcl_Obj **elemv, *retlist;
- void *ktmp;
- size_t size;
- u_int32_t flag;
- int adj, elemc, freekey, i, j, optindex, result, ret;
- char *arg, msg[MSG_SIZE];
-
- result = TCL_OK;
- flag = 0;
- ktmp = NULL;
- freekey = 0;
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "{db1 key1} {db2 key2} ...");
- return (TCL_ERROR);
- }
-
- txn = NULL;
- i = 2;
- adj = i;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbgetjopts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[i]);
- if (result == TCL_OK)
- return (result);
- result = TCL_OK;
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum dbgetjopts)optindex) {
-#ifdef CONFIG_TEST
- case DBGETJ_NOSORT:
- flag |= DB_JOIN_NOSORT;
- adj++;
- break;
-#endif
- case DBGETJ_TXN:
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- adj += 2;
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "GetJoin: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- }
- }
- if (result != TCL_OK)
- return (result);
- size = sizeof(DBC *) * (size_t)((objc - adj) + 1);
- ret = __os_malloc(NULL, size, &listp);
- if (ret != 0) {
- Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC);
- return (TCL_ERROR);
- }
-
- memset(listp, 0, size);
- for (j = 0, i = adj; i < objc; i++, j++) {
- /*
- * Get each sublist as {db key}
- */
- result = Tcl_ListObjGetElements(interp, objv[i],
- &elemc, &elemv);
- if (elemc != 2) {
- Tcl_SetResult(interp, "Lists must be {db key}",
- TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- }
- /*
- * Get a pointer to that open db. Then, open a cursor in
- * that db, and go to the "key" place.
- */
- elemdbp = NAME_TO_DB(Tcl_GetStringFromObj(elemv[0], NULL));
- if (elemdbp == NULL) {
- snprintf(msg, MSG_SIZE, "Get_join: Invalid db: %s\n",
- Tcl_GetStringFromObj(elemv[0], NULL));
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- goto out;
- }
- ret = elemdbp->cursor(elemdbp, txn, &listp[j], 0);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db cursor")) == TCL_ERROR)
- goto out;
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- ret = _CopyObjBytes(interp, elemv[elemc-1], &ktmp,
- &key.size, &freekey);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "db join");
- goto out;
- }
- key.data = ktmp;
- ret = (listp[j])->get(listp[j], &key, &data, DB_SET);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_DBCGET(ret),
- "db cget")) == TCL_ERROR)
- goto out;
- }
- listp[j] = NULL;
- _debug_check();
- ret = dbp->join(dbp, listp, &dbc, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db join");
- if (result == TCL_ERROR)
- goto out;
-
- retlist = Tcl_NewListObj(0, NULL);
- while (ret == 0 && result == TCL_OK) {
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- key.flags |= DB_DBT_MALLOC;
- data.flags |= DB_DBT_MALLOC;
- ret = dbc->get(dbc, &key, &data, 0);
- /*
- * Build up our {name value} sublist
- */
- if (ret == 0) {
- result = _SetListElem(interp, retlist,
- key.data, key.size,
- data.data, data.size);
- __os_ufree(dbp->env, key.data);
- __os_ufree(dbp->env, data.data);
- }
- }
- (void)dbc->close(dbc);
- if (result == TCL_OK)
- Tcl_SetObjResult(interp, retlist);
-out:
- if (ktmp != NULL && freekey)
- __os_free(dbp->env, ktmp);
- while (j) {
- if (listp[j])
- (void)(listp[j])->close(listp[j]);
- j--;
- }
- __os_free(dbp->env, listp);
- return (result);
-}
-
-/*
- * tcl_DbGetFlags --
- */
-static int
-tcl_DbGetFlags(interp, objc, objv, dbp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
-{
- int i, ret, result;
- u_int32_t flags;
- char buf[512];
- Tcl_Obj *res;
-
- static const struct {
- u_int32_t flag;
- char *arg;
- } db_flags[] = {
- { DB_CHKSUM, "-chksum" },
- { DB_DUP, "-dup" },
- { DB_DUPSORT, "-dupsort" },
- { DB_ENCRYPT, "-encrypt" },
- { DB_INORDER, "-inorder" },
- { DB_TXN_NOT_DURABLE, "-notdurable" },
- { DB_RECNUM, "-recnum" },
- { DB_RENUMBER, "-renumber" },
- { DB_REVSPLITOFF, "-revsplitoff" },
- { DB_SNAPSHOT, "-snapshot" },
- { 0, NULL }
- };
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
-
- ret = dbp->get_flags(dbp, &flags);
- if ((result = _ReturnSetup(
- interp, ret, DB_RETOK_STD(ret), "db get_flags")) == TCL_OK) {
- buf[0] = '\0';
-
- for (i = 0; db_flags[i].flag != 0; i++)
- if (LF_ISSET(db_flags[i].flag)) {
- if (strlen(buf) > 0)
- (void)strncat(buf, " ", sizeof(buf));
- (void)strncat(
- buf, db_flags[i].arg, sizeof(buf));
- }
-
- res = NewStringObj(buf, strlen(buf));
- Tcl_SetObjResult(interp, res);
- }
-
- return (result);
-}
-
-/*
- * tcl_DbGetOpenFlags --
- */
-static int
-tcl_DbGetOpenFlags(interp, objc, objv, dbp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
-{
- int i, ret, result;
- u_int32_t flags;
- char buf[512];
- Tcl_Obj *res;
-
- static const struct {
- u_int32_t flag;
- char *arg;
- } open_flags[] = {
- { DB_AUTO_COMMIT, "-auto_commit" },
- { DB_CREATE, "-create" },
- { DB_EXCL, "-excl" },
- { DB_MULTIVERSION, "-multiversion" },
- { DB_NOMMAP, "-nommap" },
- { DB_RDONLY, "-rdonly" },
- { DB_READ_UNCOMMITTED, "-read_uncommitted" },
- { DB_THREAD, "-thread" },
- { DB_TRUNCATE, "-truncate" },
- { 0, NULL }
- };
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
-
- ret = dbp->get_open_flags(dbp, &flags);
- if ((result = _ReturnSetup(
- interp, ret, DB_RETOK_STD(ret), "db get_open_flags")) == TCL_OK) {
- buf[0] = '\0';
-
- for (i = 0; open_flags[i].flag != 0; i++)
- if (LF_ISSET(open_flags[i].flag)) {
- if (strlen(buf) > 0)
- (void)strncat(buf, " ", sizeof(buf));
- (void)strncat(
- buf, open_flags[i].arg, sizeof(buf));
- }
-
- res = NewStringObj(buf, strlen(buf));
- Tcl_SetObjResult(interp, res);
- }
-
- return (result);
-}
-
-/*
- * tcl_DbCount --
- */
-static int
-tcl_DbCount(interp, objc, objv, dbp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
-{
- DBC *dbc;
- DBT key, data;
- Tcl_Obj *res;
- void *ktmp;
- db_recno_t count, recno;
- int freekey, result, ret;
-
- res = NULL;
- count = 0;
- freekey = ret = 0;
- ktmp = NULL;
- result = TCL_OK;
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "key");
- return (TCL_ERROR);
- }
-
- /*
- * Get the count for our key.
- * We do this by getting a cursor for this DB. Moving the cursor
- * to the set location, and getting a count on that cursor.
- */
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
-
- /*
- * If it's a queue or recno database, we must make sure to
- * treat the key as a recno rather than as a byte string.
- */
- if (dbp->type == DB_RECNO || dbp->type == DB_QUEUE) {
- result = _GetUInt32(interp, objv[2], &recno);
- if (result == TCL_OK) {
- key.data = &recno;
- key.size = sizeof(db_recno_t);
- } else
- return (result);
- } else {
- ret = _CopyObjBytes(interp, objv[2], &ktmp,
- &key.size, &freekey);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "db count");
- return (result);
- }
- key.data = ktmp;
- }
- _debug_check();
- ret = dbp->cursor(dbp, NULL, &dbc, 0);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db cursor");
- goto out;
- }
- /*
- * Move our cursor to the key.
- */
- ret = dbc->get(dbc, &key, &data, DB_SET);
- if (ret == DB_KEYEMPTY || ret == DB_NOTFOUND)
- count = 0;
- else {
- ret = dbc->count(dbc, &count, 0);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db c count");
- goto out;
- }
- }
- res = Tcl_NewWideIntObj((Tcl_WideInt)count);
- Tcl_SetObjResult(interp, res);
-
-out: if (ktmp != NULL && freekey)
- __os_free(dbp->env, ktmp);
- (void)dbc->close(dbc);
- return (result);
-}
-
-#ifdef CONFIG_TEST
-/*
- * tcl_DbKeyRange --
- */
-static int
-tcl_DbKeyRange(interp, objc, objv, dbp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
-{
- static const char *dbkeyropts[] = {
- "-txn",
- NULL
- };
- enum dbkeyropts {
- DBKEYR_TXN
- };
- DB_TXN *txn;
- DB_KEY_RANGE range;
- DBT key;
- DBTYPE type;
- Tcl_Obj *myobjv[3], *retlist;
- void *ktmp;
- db_recno_t recno;
- u_int32_t flag;
- int freekey, i, myobjc, optindex, result, ret;
- char *arg, msg[MSG_SIZE];
-
- ktmp = NULL;
- flag = 0;
- freekey = 0;
- result = TCL_OK;
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id? key");
- return (TCL_ERROR);
- }
-
- txn = NULL;
- for (i = 2; i < objc;) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbkeyropts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[i]);
- if (result == TCL_OK)
- return (result);
- result = TCL_OK;
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum dbkeyropts)optindex) {
- case DBKEYR_TXN:
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "KeyRange: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- }
- }
- if (result != TCL_OK)
- return (result);
- (void)dbp->get_type(dbp, &type);
- ret = 0;
- /*
- * Make sure we have a key.
- */
- if (i != (objc - 1)) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args? key");
- result = TCL_ERROR;
- goto out;
- }
- memset(&key, 0, sizeof(key));
- if (type == DB_RECNO || type == DB_QUEUE) {
- result = _GetUInt32(interp, objv[i], &recno);
- if (result == TCL_OK) {
- key.data = &recno;
- key.size = sizeof(db_recno_t);
- } else
- return (result);
- } else {
- ret = _CopyObjBytes(interp, objv[i++], &ktmp,
- &key.size, &freekey);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "db keyrange");
- return (result);
- }
- key.data = ktmp;
- }
- _debug_check();
- ret = dbp->key_range(dbp, txn, &key, &range, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db keyrange");
- if (result == TCL_ERROR)
- goto out;
-
- /*
- * If we succeeded, set up return list.
- */
- myobjc = 3;
- myobjv[0] = Tcl_NewDoubleObj(range.less);
- myobjv[1] = Tcl_NewDoubleObj(range.equal);
- myobjv[2] = Tcl_NewDoubleObj(range.greater);
- retlist = Tcl_NewListObj(myobjc, myobjv);
- if (result == TCL_OK)
- Tcl_SetObjResult(interp, retlist);
-
-out: if (ktmp != NULL && freekey)
- __os_free(dbp->env, ktmp);
- return (result);
-}
-#endif
-
-/*
- * tcl_DbTruncate --
- */
-static int
-tcl_DbTruncate(interp, objc, objv, dbp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
-{
- static const char *dbcuropts[] = {
- "-txn",
- NULL
- };
- enum dbcuropts {
- DBTRUNC_TXN
- };
- DB_TXN *txn;
- Tcl_Obj *res;
- u_int32_t count;
- int i, optindex, result, ret;
- char *arg, msg[MSG_SIZE];
-
- txn = NULL;
- result = TCL_OK;
-
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbcuropts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[i]);
- goto out;
- }
- i++;
- switch ((enum dbcuropts)optindex) {
- case DBTRUNC_TXN:
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Truncate: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- }
- if (result != TCL_OK)
- break;
- }
- if (result != TCL_OK)
- goto out;
-
- _debug_check();
- ret = dbp->truncate(dbp, txn, &count, 0);
- if (ret != 0)
- result = _ErrorSetup(interp, ret, "db truncate");
-
- else {
- res = Tcl_NewWideIntObj((Tcl_WideInt)count);
- Tcl_SetObjResult(interp, res);
- }
-out:
- return (result);
-}
-
-#ifdef CONFIG_TEST
-/*
- * tcl_DbCompact --
- */
-static int
-tcl_DbCompact(interp, objc, objv, dbp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
-{
- static const char *dbcuropts[] = {
- "-fillpercent",
- "-freespace",
- "-freeonly",
- "-pages",
- "-start",
- "-stop",
- "-timeout",
- "-txn",
- NULL
- };
- enum dbcuropts {
- DBREORG_FILLFACTOR,
- DBREORG_FREESPACE,
- DBREORG_FREEONLY,
- DBREORG_PAGES,
- DBREORG_START,
- DBREORG_STOP,
- DBREORG_TIMEOUT,
- DBREORG_TXN
- };
- DBTCL_INFO *ip;
- DBT *key, end, start, stop;
- DBTYPE type;
- DB_TXN *txn;
- Tcl_Obj *myobj, *retlist;
- db_recno_t recno, srecno;
- u_int32_t arg, fillfactor, flags, pages, timeout;
- char *carg, msg[MSG_SIZE];
- int freekey, i, optindex, result, ret;
- void *kp;
-
- flags = 0;
- result = TCL_OK;
- txn = NULL;
- (void)dbp->get_type(dbp, &type);
- memset(&start, 0, sizeof(start));
- memset(&stop, 0, sizeof(stop));
- memset(&end, 0, sizeof(end));
- ip = (DBTCL_INFO *)dbp->api_internal;
- fillfactor = pages = timeout = 0;
-
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbcuropts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[i]);
- goto out;
- }
- i++;
- switch ((enum dbcuropts)optindex) {
- case DBREORG_FILLFACTOR:
- if (i == objc) {
- Tcl_WrongNumArgs(interp,
- 2, objv, "?-fillfactor number?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &arg);
- if (result != TCL_OK)
- goto out;
- i++;
- fillfactor = arg;
- break;
- case DBREORG_FREESPACE:
- LF_SET(DB_FREE_SPACE);
- break;
-
- case DBREORG_FREEONLY:
- LF_SET(DB_FREELIST_ONLY);
- break;
-
- case DBREORG_PAGES:
- if (i == objc) {
- Tcl_WrongNumArgs(interp,
- 2, objv, "?-pages number?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &arg);
- if (result != TCL_OK)
- goto out;
- i++;
- pages = arg;
- break;
- case DBREORG_TIMEOUT:
- if (i == objc) {
- Tcl_WrongNumArgs(interp,
- 2, objv, "?-timeout number?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &arg);
- if (result != TCL_OK)
- goto out;
- i++;
- timeout = arg;
- break;
-
- case DBREORG_START:
- case DBREORG_STOP:
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 1, objv,
- "?-args? -start/stop key");
- result = TCL_ERROR;
- goto out;
- }
- if ((enum dbcuropts)optindex == DBREORG_START) {
- key = &start;
- key->data = &recno;
- } else {
- key = &stop;
- key->data = &srecno;
- }
- if (type == DB_RECNO || type == DB_QUEUE) {
- result = _GetUInt32(
- interp, objv[i], key->data);
- if (result == TCL_OK) {
- key->size = sizeof(db_recno_t);
- } else
- goto out;
- } else {
- ret = _CopyObjBytes(interp, objv[i],
- &key->data, &key->size, &freekey);
- if (ret != 0)
- goto err;
- if (freekey == 0) {
- if ((ret = __os_malloc(NULL,
- key->size, &kp)) != 0)
- goto err;
-
- memcpy(kp, key->data, key->size);
- key->data = kp;
- key->ulen = key->size;
- }
- }
- i++;
- break;
- case DBREORG_TXN:
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- carg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(carg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Compact: Invalid txn: %s\n", carg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- }
- if (result != TCL_OK)
- break;
- }
- if (result != TCL_OK)
- goto out;
-
- if (ip->i_cdata == NULL)
- if ((ret = __os_calloc(dbp->env,
- 1, sizeof(DB_COMPACT), &ip->i_cdata)) != 0) {
- Tcl_SetResult(interp,
- db_strerror(ret), TCL_STATIC);
- goto out;
- }
-
- ip->i_cdata->compact_fillpercent = fillfactor;
- ip->i_cdata->compact_timeout = timeout;
- ip->i_cdata->compact_pages = pages;
-
- _debug_check();
- ret = dbp->compact(dbp, txn, &start, &stop, ip->i_cdata, flags, &end);
- result = _ReturnSetup(interp, ret, DB_RETOK_DBCGET(ret), "dbp compact");
- if (result == TCL_ERROR)
- goto out;
-
- retlist = Tcl_NewListObj(0, NULL);
- if (ret != 0)
- goto out;
- if (type == DB_RECNO || type == DB_QUEUE) {
- if (end.size == 0)
- recno = 0;
- else
- recno = *((db_recno_t *)end.data);
- myobj = Tcl_NewWideIntObj((Tcl_WideInt)recno);
- } else
- myobj = Tcl_NewByteArrayObj(end.data, (int)end.size);
- result = Tcl_ListObjAppendElement(interp, retlist, myobj);
- if (result == TCL_OK)
- Tcl_SetObjResult(interp, retlist);
-
- if (0) {
-err: result = _ReturnSetup(interp,
- ret, DB_RETOK_DBCGET(ret), "dbc compact");
- }
-out:
- if (start.data != NULL && start.data != &recno)
- __os_free(NULL, start.data);
- if (stop.data != NULL && stop.data != &srecno)
- __os_free(NULL, stop.data);
- if (end.data != NULL)
- __os_free(NULL, end.data);
-
- return (result);
-}
-
-/*
- * tcl_DbCompactStat
- */
-static int
-tcl_DbCompactStat(interp, objc, objv, dbp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB *dbp; /* Database pointer */
-{
- DBTCL_INFO *ip;
-
- COMPQUIET(objc, 0);
- COMPQUIET(objv, NULL);
-
- ip = (DBTCL_INFO *)dbp->api_internal;
-
- return (tcl_CompactStat(interp, ip));
-}
-
-/*
- * PUBLIC: int tcl_CompactStat __P((Tcl_Interp *, DBTCL_INFO *));
- */
-int
-tcl_CompactStat(interp, ip)
- Tcl_Interp *interp; /* Interpreter */
- DBTCL_INFO *ip;
-{
- DB_COMPACT *rp;
- Tcl_Obj *res;
- int result;
- char msg[MSG_SIZE];
-
- result = TCL_OK;
- rp = NULL;
-
- _debug_check();
- if ((rp = ip->i_cdata) == NULL) {
- snprintf(msg, MSG_SIZE,
- "Compact stat: No stats available\n");
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- goto error;
- }
-
- res = Tcl_NewObj();
-
- MAKE_STAT_LIST("Pages freed", rp->compact_pages_free);
- MAKE_STAT_LIST("Pages truncated", rp->compact_pages_truncated);
- MAKE_STAT_LIST("Pages examined", rp->compact_pages_examine);
- MAKE_STAT_LIST("Levels removed", rp->compact_levels);
- MAKE_STAT_LIST("Deadlocks encountered", rp->compact_deadlock);
-
- Tcl_SetObjResult(interp, res);
-error:
- return (result);
-}
-#endif
diff --git a/tcl/tcl_db_pkg.c b/tcl/tcl_db_pkg.c
deleted file mode 100644
index 76543f4..0000000
--- a/tcl/tcl_db_pkg.c
+++ /dev/null
@@ -1,4398 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-
-#ifdef CONFIG_TEST
-#define DB_DBM_HSEARCH 1
-#endif
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/db_page.h"
-#include "dbinc/hash.h"
-#include "dbinc/tcl_db.h"
-
-/* XXX we must declare global data in just one place */
-DBTCL_GLOBAL __dbtcl_global;
-
-/*
- * Prototypes for procedures defined later in this file:
- */
-static int berkdb_Cmd __P((ClientData, Tcl_Interp *, int,
- Tcl_Obj * CONST*));
-static int bdb_EnvOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- DBTCL_INFO *, DB_ENV **));
-static int bdb_DbOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- DBTCL_INFO *, DB **));
-static int bdb_DbRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
-static int bdb_DbRename __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
-static int bdb_Version __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
-
-#ifdef HAVE_64BIT_TYPES
-static int bdb_SeqOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- DBTCL_INFO *, DB_SEQUENCE **));
-#endif
-
-#ifdef CONFIG_TEST
-static int bdb_DbUpgrade __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
-static int bdb_DbVerify __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- DBTCL_INFO *));
-static int bdb_GetConfig __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
-static int bdb_Handles __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
-static int bdb_MsgType __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
-
-static int tcl_bt_compare __P((DB *, const DBT *, const DBT *));
-static int tcl_compare_callback __P((DB *, const DBT *, const DBT *,
- Tcl_Obj *, char *));
-static void tcl_db_free __P((void *));
-static void * tcl_db_malloc __P((size_t));
-static void * tcl_db_realloc __P((void *, size_t));
-static int tcl_dup_compare __P((DB *, const DBT *, const DBT *));
-static u_int32_t tcl_h_hash __P((DB *, const void *, u_int32_t));
-static int tcl_isalive __P((DB_ENV *, pid_t, db_threadid_t, u_int32_t));
-static u_int32_t tcl_part_callback __P((DB *, DBT *));
-static int tcl_set_partition_dirs
- __P((Tcl_Interp *, DB *, Tcl_Obj *));
-static int tcl_set_partition_keys
- __P((Tcl_Interp *, DB *, Tcl_Obj *, DBT **));
-#endif
-
-int Db_tcl_Init __P((Tcl_Interp *));
-
-/*
- * Db_tcl_Init --
- *
- * This is a package initialization procedure, which is called by Tcl when
- * this package is to be added to an interpreter. The name is based on the
- * name of the shared library, currently libdb_tcl-X.Y.so, which Tcl uses
- * to determine the name of this function.
- */
-int
-Db_tcl_Init(interp)
- Tcl_Interp *interp; /* Interpreter in which the package is
- * to be made available. */
-{
- int code;
- char pkg[12];
-
- snprintf(pkg, sizeof(pkg), "%d.%d", DB_VERSION_MAJOR, DB_VERSION_MINOR);
- code = Tcl_PkgProvide(interp, "Db_tcl", pkg);
- if (code != TCL_OK)
- return (code);
-
- /*
- * Don't allow setuid/setgid scripts for the Tcl API because some Tcl
- * functions evaluate the arguments and could otherwise allow a user
- * to inject Tcl commands.
- */
-#if defined(HAVE_SETUID) && defined(HAVE_GETUID)
- (void)setuid(getuid());
-#endif
-#if defined(HAVE_SETGID) && defined(HAVE_GETGID)
- (void)setgid(getgid());
-#endif
-
- (void)Tcl_CreateObjCommand(interp,
- "berkdb", (Tcl_ObjCmdProc *)berkdb_Cmd, (ClientData)0, NULL);
- /*
- * Create shared global debugging variables
- */
- (void)Tcl_LinkVar(
- interp, "__debug_on", (char *)&__debug_on, TCL_LINK_INT);
- (void)Tcl_LinkVar(
- interp, "__debug_print", (char *)&__debug_print, TCL_LINK_INT);
- (void)Tcl_LinkVar(
- interp, "__debug_stop", (char *)&__debug_stop, TCL_LINK_INT);
- (void)Tcl_LinkVar(
- interp, "__debug_test", (char *)&__debug_test,
- TCL_LINK_INT);
- LIST_INIT(&__db_infohead);
- return (TCL_OK);
-}
-
-/*
- * berkdb_cmd --
- * Implements the "berkdb" command.
- * This command supports three sub commands:
- * berkdb version - Returns a list {major minor patch}
- * berkdb env - Creates a new DB_ENV and returns a binding
- * to a new command of the form dbenvX, where X is an
- * integer starting at 0 (dbenv0, dbenv1, ...)
- * berkdb open - Creates a new DB (optionally within
- * the given environment. Returns a binding to a new
- * command of the form dbX, where X is an integer
- * starting at 0 (db0, db1, ...)
- */
-static int
-berkdb_Cmd(notused, interp, objc, objv)
- ClientData notused; /* Not used. */
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *berkdbcmds[] = {
-#ifdef CONFIG_TEST
- "dbverify",
- "getconfig",
- "handles",
- "msgtype",
- "upgrade",
-#endif
- "dbremove",
- "dbrename",
- "env",
- "envremove",
- "open",
-#ifdef HAVE_64BIT_TYPES
- "sequence",
-#endif
- "version",
-#ifdef CONFIG_TEST
- /* All below are compatibility functions */
- "hcreate", "hsearch", "hdestroy",
- "dbminit", "fetch", "store",
- "delete", "firstkey", "nextkey",
- "ndbm_open", "dbmclose",
-#endif
- /* All below are convenience functions */
- "rand", "random_int", "srand",
- "debug_check",
- NULL
- };
- /*
- * All commands enums below ending in X are compatibility
- */
- enum berkdbcmds {
-#ifdef CONFIG_TEST
- BDB_DBVERIFY,
- BDB_GETCONFIG,
- BDB_HANDLES,
- BDB_MSGTYPE,
- BDB_UPGRADE,
-#endif
- BDB_DBREMOVE,
- BDB_DBRENAME,
- BDB_ENV,
- BDB_ENVREMOVE,
- BDB_OPEN,
-#ifdef HAVE_64BIT_TYPES
- BDB_SEQUENCE,
-#endif
- BDB_VERSION,
-#ifdef CONFIG_TEST
- BDB_HCREATEX, BDB_HSEARCHX, BDB_HDESTROYX,
- BDB_DBMINITX, BDB_FETCHX, BDB_STOREX,
- BDB_DELETEX, BDB_FIRSTKEYX, BDB_NEXTKEYX,
- BDB_NDBMOPENX, BDB_DBMCLOSEX,
-#endif
- BDB_RANDX, BDB_RAND_INTX, BDB_SRANDX,
- BDB_DBGCKX
- };
- static int env_id = 0;
- static int db_id = 0;
-#ifdef HAVE_64BIT_TYPES
- static int seq_id = 0;
-#endif
-
- DB *dbp;
-#ifdef HAVE_64BIT_TYPES
- DB_SEQUENCE *seq;
-#endif
-#ifdef CONFIG_TEST
- DBM *ndbmp;
- static int ndbm_id = 0;
-#endif
- DBTCL_INFO *ip;
- DB_ENV *dbenv;
- Tcl_Obj *res;
- int cmdindex, result;
- char newname[MSG_SIZE];
-
- COMPQUIET(notused, NULL);
-
- Tcl_ResetResult(interp);
- memset(newname, 0, MSG_SIZE);
- result = TCL_OK;
- if (objc <= 1) {
- Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs");
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the berkdbcmds
- * defined above.
- */
- if (Tcl_GetIndexFromObj(interp,
- objv[1], berkdbcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
- res = NULL;
- switch ((enum berkdbcmds)cmdindex) {
-#ifdef CONFIG_TEST
- case BDB_DBVERIFY:
- snprintf(newname, sizeof(newname), "db%d", db_id);
- ip = _NewInfo(interp, NULL, newname, I_DB);
- if (ip != NULL) {
- result = bdb_DbVerify(interp, objc, objv, ip);
- _DeleteInfo(ip);
- } else {
- Tcl_SetResult(interp, "Could not set up info",
- TCL_STATIC);
- result = TCL_ERROR;
- }
- break;
- case BDB_GETCONFIG:
- result = bdb_GetConfig(interp, objc, objv);
- break;
- case BDB_HANDLES:
- result = bdb_Handles(interp, objc, objv);
- break;
- case BDB_MSGTYPE:
- result = bdb_MsgType(interp, objc, objv);
- break;
- case BDB_UPGRADE:
- result = bdb_DbUpgrade(interp, objc, objv);
- break;
-#endif
- case BDB_VERSION:
- _debug_check();
- result = bdb_Version(interp, objc, objv);
- break;
- case BDB_ENV:
- snprintf(newname, sizeof(newname), "env%d", env_id);
- ip = _NewInfo(interp, NULL, newname, I_ENV);
- if (ip != NULL) {
- result = bdb_EnvOpen(interp, objc, objv, ip, &dbenv);
- if (result == TCL_OK && dbenv != NULL) {
- env_id++;
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)env_Cmd,
- (ClientData)dbenv, NULL);
- /* Use ip->i_name - newname is overwritten */
- res = NewStringObj(newname, strlen(newname));
- _SetInfoData(ip, dbenv);
- } else
- _DeleteInfo(ip);
- } else {
- Tcl_SetResult(interp, "Could not set up info",
- TCL_STATIC);
- result = TCL_ERROR;
- }
- break;
- case BDB_DBREMOVE:
- result = bdb_DbRemove(interp, objc, objv);
- break;
- case BDB_DBRENAME:
- result = bdb_DbRename(interp, objc, objv);
- break;
- case BDB_ENVREMOVE:
- result = tcl_EnvRemove(interp, objc, objv, NULL, NULL);
- break;
- case BDB_OPEN:
- snprintf(newname, sizeof(newname), "db%d", db_id);
- ip = _NewInfo(interp, NULL, newname, I_DB);
- if (ip != NULL) {
- result = bdb_DbOpen(interp, objc, objv, ip, &dbp);
- if (result == TCL_OK && dbp != NULL) {
- db_id++;
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)db_Cmd,
- (ClientData)dbp, NULL);
- /* Use ip->i_name - newname is overwritten */
- res = NewStringObj(newname, strlen(newname));
- _SetInfoData(ip, dbp);
- } else
- _DeleteInfo(ip);
- } else {
- Tcl_SetResult(interp, "Could not set up info",
- TCL_STATIC);
- result = TCL_ERROR;
- }
- break;
-#ifdef HAVE_64BIT_TYPES
- case BDB_SEQUENCE:
- snprintf(newname, sizeof(newname), "seq%d", seq_id);
- ip = _NewInfo(interp, NULL, newname, I_SEQ);
- if (ip != NULL) {
- result = bdb_SeqOpen(interp, objc, objv, ip, &seq);
- if (result == TCL_OK && seq != NULL) {
- seq_id++;
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)seq_Cmd,
- (ClientData)seq, NULL);
- /* Use ip->i_name - newname is overwritten */
- res = NewStringObj(newname, strlen(newname));
- _SetInfoData(ip, seq);
- } else
- _DeleteInfo(ip);
- } else {
- Tcl_SetResult(interp, "Could not set up info",
- TCL_STATIC);
- result = TCL_ERROR;
- }
- break;
-#endif
-#ifdef CONFIG_TEST
- case BDB_HCREATEX:
- case BDB_HSEARCHX:
- case BDB_HDESTROYX:
- result = bdb_HCommand(interp, objc, objv);
- break;
- case BDB_DBMINITX:
- case BDB_DBMCLOSEX:
- case BDB_FETCHX:
- case BDB_STOREX:
- case BDB_DELETEX:
- case BDB_FIRSTKEYX:
- case BDB_NEXTKEYX:
- result = bdb_DbmCommand(interp, objc, objv, DBTCL_DBM, NULL);
- break;
- case BDB_NDBMOPENX:
- snprintf(newname, sizeof(newname), "ndbm%d", ndbm_id);
- ip = _NewInfo(interp, NULL, newname, I_NDBM);
- if (ip != NULL) {
- result = bdb_NdbmOpen(interp, objc, objv, &ndbmp);
- if (result == TCL_OK) {
- ndbm_id++;
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)ndbm_Cmd,
- (ClientData)ndbmp, NULL);
- /* Use ip->i_name - newname is overwritten */
- res = NewStringObj(newname, strlen(newname));
- _SetInfoData(ip, ndbmp);
- } else
- _DeleteInfo(ip);
- } else {
- Tcl_SetResult(interp, "Could not set up info",
- TCL_STATIC);
- result = TCL_ERROR;
- }
- break;
-#endif
- case BDB_RANDX:
- case BDB_RAND_INTX:
- case BDB_SRANDX:
- result = bdb_RandCommand(interp, objc, objv);
- break;
- case BDB_DBGCKX:
- _debug_check();
- res = Tcl_NewIntObj(0);
- break;
- }
- /*
- * For each different arg call different function to create
- * new commands (or if version, get/return it).
- */
- if (result == TCL_OK && res != NULL)
- Tcl_SetObjResult(interp, res);
- return (result);
-}
-
-/*
- * bdb_EnvOpen -
- * Implements the environment open command.
- * There are many, many options to the open command.
- * Here is the general flow:
- *
- * 1. Call db_env_create to create the env handle.
- * 2. Parse args tracking options.
- * 3. Make any pre-open setup calls necessary.
- * 4. Call DB_ENV->open to open the env.
- * 5. Return env widget handle to user.
- */
-static int
-bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DBTCL_INFO *ip; /* Our internal info */
- DB_ENV **dbenvp; /* Environment pointer */
-{
- static const char *envopen[] = {
-#ifdef CONFIG_TEST
- "-alloc",
- "-auto_commit",
- "-cdb",
- "-cdb_alldb",
- "-client_timeout",
- "-event",
- "-failchk",
- "-isalive",
- "-lock",
- "-lock_conflict",
- "-lock_detect",
- "-lock_max_locks",
- "-lock_max_lockers",
- "-lock_max_objects",
- "-lock_partitions",
- "-lock_timeout",
- "-log",
- "-log_filemode",
- "-log_buffer",
- "-log_inmemory",
- "-log_max",
- "-log_regionmax",
- "-log_remove",
- "-mpool_max_openfd",
- "-mpool_max_write",
- "-mpool_mmap_size",
- "-mpool_nommap",
- "-multiversion",
- "-mutex_set_align",
- "-mutex_set_incr",
- "-mutex_set_max",
- "-mutex_set_tas_spins",
- "-overwrite",
- "-pagesize",
- "-register",
- "-reg_timeout",
- "-region_init",
- "-rep",
- "-rep_client",
- "-rep_inmem_files",
- "-rep_lease",
- "-rep_master",
- "-rep_transport",
- "-server",
- "-server_timeout",
- "-set_intermediate_dir_mode",
- "-snapshot",
- "-tablesize",
- "-thread",
- "-time_notgranted",
- "-txn_nowait",
- "-txn_timeout",
- "-txn_timestamp",
- "-verbose",
- "-wrnosync",
- "-zero_log",
-#endif
- "-add_dir",
- "-cachesize",
- "-cache_max",
- "-create",
- "-create_dir",
- "-data_dir",
- "-encryptaes",
- "-encryptany",
- "-errfile",
- "-errpfx",
- "-home",
- "-log_dir",
- "-mode",
- "-private",
- "-recover",
- "-recover_fatal",
- "-shm_key",
- "-system_mem",
- "-tmp_dir",
- "-txn",
- "-txn_max",
- "-use_environ",
- "-use_environ_root",
- NULL
- };
- /*
- * !!!
- * These have to be in the same order as the above,
- * which is close to but not quite alphabetical.
- */
- enum envopen {
-#ifdef CONFIG_TEST
- TCL_ENV_ALLOC,
- TCL_ENV_AUTO_COMMIT,
- TCL_ENV_CDB,
- TCL_ENV_CDB_ALLDB,
- TCL_ENV_CLIENT_TO,
- TCL_ENV_EVENT,
- TCL_ENV_FAILCHK,
- TCL_ENV_ISALIVE,
- TCL_ENV_LOCK,
- TCL_ENV_CONFLICT,
- TCL_ENV_DETECT,
- TCL_ENV_LOCK_MAX_LOCKS,
- TCL_ENV_LOCK_MAX_LOCKERS,
- TCL_ENV_LOCK_MAX_OBJECTS,
- TCL_ENV_LOCK_PARTITIONS,
- TCL_ENV_LOCK_TIMEOUT,
- TCL_ENV_LOG,
- TCL_ENV_LOG_FILEMODE,
- TCL_ENV_LOG_BUFFER,
- TCL_ENV_LOG_INMEMORY,
- TCL_ENV_LOG_MAX,
- TCL_ENV_LOG_REGIONMAX,
- TCL_ENV_LOG_REMOVE,
- TCL_ENV_MPOOL_MAX_OPENFD,
- TCL_ENV_MPOOL_MAX_WRITE,
- TCL_ENV_MPOOL_MMAP_SIZE,
- TCL_ENV_MPOOL_NOMMAP,
- TCL_ENV_MULTIVERSION,
- TCL_ENV_MUTSETALIGN,
- TCL_ENV_MUTSETINCR,
- TCL_ENV_MUTSETMAX,
- TCL_ENV_MUTSETTAS,
- TCL_ENV_OVERWRITE,
- TCL_ENV_PAGESIZE,
- TCL_ENV_REGISTER,
- TCL_ENV_REG_TIMEOUT,
- TCL_ENV_REGION_INIT,
- TCL_ENV_REP,
- TCL_ENV_REP_CLIENT,
- TCL_ENV_REP_INMEM_FILES,
- TCL_ENV_REP_LEASE,
- TCL_ENV_REP_MASTER,
- TCL_ENV_REP_TRANSPORT,
- TCL_ENV_SERVER,
- TCL_ENV_SERVER_TO,
- TCL_ENV_SET_INTERMEDIATE_DIR,
- TCL_ENV_SNAPSHOT,
- TCL_ENV_TABLESIZE,
- TCL_ENV_THREAD,
- TCL_ENV_TIME_NOTGRANTED,
- TCL_ENV_TXN_NOWAIT,
- TCL_ENV_TXN_TIMEOUT,
- TCL_ENV_TXN_TIME,
- TCL_ENV_VERBOSE,
- TCL_ENV_WRNOSYNC,
- TCL_ENV_ZEROLOG,
-#endif
- TCL_ENV_ADD_DIR,
- TCL_ENV_CACHESIZE,
- TCL_ENV_CACHE_MAX,
- TCL_ENV_CREATE,
- TCL_ENV_CREATE_DIR,
- TCL_ENV_DATA_DIR,
- TCL_ENV_ENCRYPT_AES,
- TCL_ENV_ENCRYPT_ANY,
- TCL_ENV_ERRFILE,
- TCL_ENV_ERRPFX,
- TCL_ENV_HOME,
- TCL_ENV_LOG_DIR,
- TCL_ENV_MODE,
- TCL_ENV_PRIVATE,
- TCL_ENV_RECOVER,
- TCL_ENV_RECOVER_FATAL,
- TCL_ENV_SHM_KEY,
- TCL_ENV_SYSTEM_MEM,
- TCL_ENV_TMP_DIR,
- TCL_ENV_TXN,
- TCL_ENV_TXN_MAX,
- TCL_ENV_USE_ENVIRON,
- TCL_ENV_USE_ENVIRON_ROOT
- };
- DB_ENV *dbenv;
- Tcl_Obj **myobjv;
- u_int32_t cr_flags, gbytes, bytes, logbufset, logmaxset;
- u_int32_t open_flags, rep_flags, set_flags, uintarg;
- int i, mode, myobjc, ncaches, optindex, result, ret;
- long client_to, server_to, shm;
- char *arg, *home, *passwd, *server;
-#ifdef CONFIG_TEST
- Tcl_Obj **myobjv1;
- time_t timestamp;
- long v;
- u_int32_t detect, time_flag;
- u_int8_t *conflicts;
- int intarg, intarg2, j, nmodes, temp;
-#endif
-
- result = TCL_OK;
- mode = 0;
- rep_flags = set_flags = cr_flags = 0;
- home = NULL;
-
- /*
- * XXX
- * If/when our Tcl interface becomes thread-safe, we should enable
- * DB_THREAD here in all cases. For now, we turn it on later in this
- * function, and only when we're in testing and we specify the
- * -thread flag, so that we can exercise MUTEX_THREAD_LOCK cases.
- *
- * In order to become truly thread-safe, we need to look at making sure
- * DBTCL_INFO structs are safe to share across threads (they're not
- * mutex-protected) before we declare the Tcl interface thread-safe.
- * Meanwhile, there's no strong reason to enable DB_THREAD when not
- * testing.
- */
- open_flags = 0;
- logmaxset = logbufset = 0;
-
- if (objc <= 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args?");
- return (TCL_ERROR);
- }
-
- /*
- * Server code must go before the call to db_env_create.
- */
- server = NULL;
- server_to = client_to = 0;
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i++], envopen, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- Tcl_ResetResult(interp);
- continue;
- }
-#ifdef CONFIG_TEST
- switch ((enum envopen)optindex) {
- case TCL_ENV_SERVER:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-server hostname");
- result = TCL_ERROR;
- break;
- }
- FLD_SET(cr_flags, DB_RPCCLIENT);
- server = Tcl_GetStringFromObj(objv[i++], NULL);
- break;
- case TCL_ENV_SERVER_TO:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-server_to secs");
- result = TCL_ERROR;
- break;
- }
- FLD_SET(cr_flags, DB_RPCCLIENT);
- result = Tcl_GetLongFromObj(interp, objv[i++],
- &server_to);
- break;
- case TCL_ENV_CLIENT_TO:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-client_to secs");
- result = TCL_ERROR;
- break;
- }
- FLD_SET(cr_flags, DB_RPCCLIENT);
- result = Tcl_GetLongFromObj(interp, objv[i++],
- &client_to);
- break;
- default:
- break;
- }
-#endif
- }
- if (result != TCL_OK)
- return (TCL_ERROR);
- if ((ret = db_env_create(&dbenv, cr_flags)) != 0)
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db_env_create"));
- *dbenvp = dbenv;
-
- /*
- * From here on we must 'goto error' in order to clean up the
- * dbenv from db_env_create.
- */
- dbenv->set_errpfx(dbenv, ip->i_name);
- dbenv->set_errcall(dbenv, _ErrorFunc);
- if (server != NULL &&
- (ret = dbenv->set_rpc_server(dbenv, NULL, server,
- client_to, server_to, 0)) != 0) {
- result = TCL_ERROR;
- goto error;
- }
-
- /* Hang our info pointer on the dbenv handle, so we can do callbacks. */
- dbenv->app_private = ip;
-
- /*
- * Get the command name index from the object based on the bdbcmds
- * defined above.
- */
- i = 2;
- while (i < objc) {
- Tcl_ResetResult(interp);
- if (Tcl_GetIndexFromObj(interp, objv[i], envopen, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[i]);
- goto error;
- }
- i++;
- switch ((enum envopen)optindex) {
-#ifdef CONFIG_TEST
- case TCL_ENV_SERVER:
- case TCL_ENV_SERVER_TO:
- case TCL_ENV_CLIENT_TO:
- /*
- * Already handled these, skip them and their arg.
- */
- i++;
- break;
- case TCL_ENV_ALLOC:
- /*
- * Use a Tcl-local alloc and free function so that
- * we're sure to test whether we use umalloc/ufree in
- * the right places.
- */
- (void)dbenv->set_alloc(dbenv,
- tcl_db_malloc, tcl_db_realloc, tcl_db_free);
- break;
- case TCL_ENV_AUTO_COMMIT:
- FLD_SET(set_flags, DB_AUTO_COMMIT);
- break;
- case TCL_ENV_CDB:
- FLD_SET(open_flags, DB_INIT_CDB | DB_INIT_MPOOL);
- break;
- case TCL_ENV_CDB_ALLDB:
- FLD_SET(set_flags, DB_CDB_ALLDB);
- break;
- case TCL_ENV_EVENT:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-event eventproc");
- result = TCL_ERROR;
- break;
- }
- result = tcl_EventNotify(interp, dbenv, objv[i++], ip);
- break;
- case TCL_ENV_FAILCHK:
- FLD_SET(open_flags, DB_FAILCHK);
- break;
- case TCL_ENV_ISALIVE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-isalive aliveproc");
- result = TCL_ERROR;
- break;
- }
-
- ip->i_isalive = objv[i++];
- Tcl_IncrRefCount(ip->i_isalive);
- _debug_check();
- /* Choose an arbitrary thread count, for testing. */
- if ((ret = dbenv->set_thread_count(dbenv, 5)) == 0)
- ret = dbenv->set_isalive(dbenv, tcl_isalive);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_isalive");
- break;
- case TCL_ENV_LOCK:
- FLD_SET(open_flags, DB_INIT_LOCK | DB_INIT_MPOOL);
- break;
- case TCL_ENV_CONFLICT:
- /*
- * Get conflict list. List is:
- * {nmodes {matrix}}
- *
- * Where matrix must be nmodes*nmodes big.
- * Set up conflicts array to pass.
- */
- result = Tcl_ListObjGetElements(interp, objv[i],
- &myobjc, &myobjv);
- if (result == TCL_OK)
- i++;
- else
- break;
- if (myobjc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-lock_conflict {nmodes {matrix}}?");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, myobjv[0], &nmodes);
- if (result != TCL_OK)
- break;
- result = Tcl_ListObjGetElements(interp, myobjv[1],
- &myobjc, &myobjv1);
- if (myobjc != (nmodes * nmodes)) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-lock_conflict {nmodes {matrix}}?");
- result = TCL_ERROR;
- break;
- }
-
- ret = __os_malloc(dbenv->env, sizeof(u_int8_t) *
- (size_t)nmodes * (size_t)nmodes, &conflicts);
- if (ret != 0) {
- result = TCL_ERROR;
- break;
- }
- for (j = 0; j < myobjc; j++) {
- result = Tcl_GetIntFromObj(interp, myobjv1[j],
- &temp);
- conflicts[j] = temp;
- if (result != TCL_OK) {
- __os_free(NULL, conflicts);
- break;
- }
- }
- _debug_check();
- ret = dbenv->set_lk_conflicts(dbenv,
- (u_int8_t *)conflicts, nmodes);
- __os_free(NULL, conflicts);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_lk_conflicts");
- break;
- case TCL_ENV_DETECT:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-lock_detect policy?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- if (strcmp(arg, "default") == 0)
- detect = DB_LOCK_DEFAULT;
- else if (strcmp(arg, "expire") == 0)
- detect = DB_LOCK_EXPIRE;
- else if (strcmp(arg, "maxlocks") == 0)
- detect = DB_LOCK_MAXLOCKS;
- else if (strcmp(arg, "maxwrites") == 0)
- detect = DB_LOCK_MAXWRITE;
- else if (strcmp(arg, "minlocks") == 0)
- detect = DB_LOCK_MINLOCKS;
- else if (strcmp(arg, "minwrites") == 0)
- detect = DB_LOCK_MINWRITE;
- else if (strcmp(arg, "oldest") == 0)
- detect = DB_LOCK_OLDEST;
- else if (strcmp(arg, "youngest") == 0)
- detect = DB_LOCK_YOUNGEST;
- else if (strcmp(arg, "random") == 0)
- detect = DB_LOCK_RANDOM;
- else {
- Tcl_AddErrorInfo(interp,
- "lock_detect: illegal policy");
- result = TCL_ERROR;
- break;
- }
- _debug_check();
- ret = dbenv->set_lk_detect(dbenv, detect);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "lock_detect");
- break;
- case TCL_ENV_LOCK_MAX_LOCKS:
- case TCL_ENV_LOCK_MAX_LOCKERS:
- case TCL_ENV_LOCK_MAX_OBJECTS:
- case TCL_ENV_LOCK_PARTITIONS:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-lock_max max?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- switch ((enum envopen)optindex) {
- case TCL_ENV_LOCK_MAX_LOCKS:
- ret = dbenv->set_lk_max_locks(dbenv,
- uintarg);
- break;
- case TCL_ENV_LOCK_MAX_LOCKERS:
- ret = dbenv->set_lk_max_lockers(dbenv,
- uintarg);
- break;
- case TCL_ENV_LOCK_MAX_OBJECTS:
- ret = dbenv->set_lk_max_objects(dbenv,
- uintarg);
- break;
- case TCL_ENV_LOCK_PARTITIONS:
- ret = dbenv->set_lk_partitions(dbenv,
- uintarg);
- break;
- default:
- break;
- }
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "lock_max");
- }
- break;
- case TCL_ENV_MUTSETALIGN:
- case TCL_ENV_MUTSETINCR:
- case TCL_ENV_MUTSETMAX:
- case TCL_ENV_MUTSETTAS:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-mutex_set val");
- result = TCL_ERROR;
- break;
- }
- intarg = 0;
- switch ((enum envopen)optindex) {
- case TCL_ENV_MUTSETALIGN:
- intarg = DBTCL_MUT_ALIGN;
- break;
- case TCL_ENV_MUTSETINCR:
- intarg = DBTCL_MUT_INCR;
- break;
- case TCL_ENV_MUTSETMAX:
- intarg = DBTCL_MUT_MAX;
- break;
- case TCL_ENV_MUTSETTAS:
- intarg = DBTCL_MUT_TAS;
- break;
- default:
- break;
- }
- result = tcl_MutSet(interp, objv[i++], dbenv, intarg);
- break;
- case TCL_ENV_TXN_NOWAIT:
- FLD_SET(set_flags, DB_TXN_NOWAIT);
- break;
- case TCL_ENV_TXN_TIME:
- case TCL_ENV_TXN_TIMEOUT:
- case TCL_ENV_LOCK_TIMEOUT:
- case TCL_ENV_REG_TIMEOUT:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-xxx_timeout time?");
- result = TCL_ERROR;
- break;
- }
-
- if ((result = Tcl_GetLongFromObj(
- interp, objv[i++], &v)) != TCL_OK)
- break;
- timestamp = (time_t)v;
-
- _debug_check();
- if ((enum envopen)optindex == TCL_ENV_TXN_TIME)
- ret =
- dbenv->set_tx_timestamp(dbenv, &timestamp);
- else {
- if ((enum envopen)optindex ==
- TCL_ENV_LOCK_TIMEOUT)
- time_flag = DB_SET_LOCK_TIMEOUT;
- else if ((enum envopen)optindex ==
- TCL_ENV_REG_TIMEOUT)
- time_flag = DB_SET_REG_TIMEOUT;
- else
- time_flag = DB_SET_TXN_TIMEOUT;
-
- ret = dbenv->set_timeout(dbenv,
- (db_timeout_t)timestamp, time_flag);
- }
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "txn_timestamp");
- break;
- case TCL_ENV_LOG:
- FLD_SET(open_flags, DB_INIT_LOG | DB_INIT_MPOOL);
- break;
- case TCL_ENV_LOG_BUFFER:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-log_buffer size?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = dbenv->set_lg_bsize(dbenv, uintarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "log_bsize");
- logbufset = 1;
- if (logmaxset) {
- _debug_check();
- ret = dbenv->set_lg_max(dbenv,
- logmaxset);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "log_max");
- logmaxset = 0;
- logbufset = 0;
- }
- }
- break;
- case TCL_ENV_LOG_FILEMODE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-log_filemode mode?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = dbenv->set_lg_filemode(dbenv,
- (int)uintarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "log_filemode");
- }
- break;
- case TCL_ENV_LOG_INMEMORY:
- ret =
- dbenv->log_set_config(dbenv, DB_LOG_IN_MEMORY, 1);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "log_inmemory");
- break;
- case TCL_ENV_LOG_MAX:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-log_max max?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK && logbufset) {
- _debug_check();
- ret = dbenv->set_lg_max(dbenv, uintarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "log_max");
- logbufset = 0;
- } else
- logmaxset = uintarg;
- break;
- case TCL_ENV_LOG_REGIONMAX:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-log_regionmax size?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = dbenv->set_lg_regionmax(dbenv, uintarg);
- result =
- _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "log_regionmax");
- }
- break;
- case TCL_ENV_LOG_REMOVE:
- ret =
- dbenv->log_set_config(dbenv, DB_LOG_AUTO_REMOVE, 1);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "log_remove");
- break;
- case TCL_ENV_MPOOL_MAX_OPENFD:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-mpool_max_openfd fd_count?");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, objv[i++], &intarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = dbenv->set_mp_max_openfd(dbenv, intarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "mpool_max_openfd");
- }
- break;
- case TCL_ENV_MPOOL_MAX_WRITE:
- result = Tcl_ListObjGetElements(interp, objv[i],
- &myobjc, &myobjv);
- if (result == TCL_OK)
- i++;
- else
- break;
- if (myobjc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-mpool_max_write {nwrite nsleep}?");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, myobjv[0], &intarg);
- if (result != TCL_OK)
- break;
- result = Tcl_GetIntFromObj(interp, myobjv[1], &intarg2);
- if (result != TCL_OK)
- break;
- _debug_check();
- ret = dbenv->set_mp_max_write(
- dbenv, intarg, (db_timeout_t)intarg2);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_mp_max_write");
- break;
- case TCL_ENV_MPOOL_MMAP_SIZE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-mpool_mmap_size size?");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, objv[i++], &intarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = dbenv->set_mp_mmapsize(dbenv,
- (size_t)intarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "mpool_mmap_size");
- }
- break;
- case TCL_ENV_MPOOL_NOMMAP:
- FLD_SET(set_flags, DB_NOMMAP);
- break;
- case TCL_ENV_MULTIVERSION:
- FLD_SET(set_flags, DB_MULTIVERSION);
- break;
- case TCL_ENV_OVERWRITE:
- FLD_SET(set_flags, DB_OVERWRITE);
- break;
- case TCL_ENV_PAGESIZE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-pagesize size?");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, objv[i++], &intarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = dbenv->set_mp_pagesize(dbenv,
- (u_int32_t)intarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "pagesize");
- }
- break;
- case TCL_ENV_TABLESIZE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-tablesize size?");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, objv[i++], &intarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = dbenv->set_mp_tablesize(dbenv,
- (u_int32_t)intarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "tablesize");
- }
- break;
- case TCL_ENV_REGISTER:
- FLD_SET(open_flags, DB_REGISTER);
- break;
- case TCL_ENV_REGION_INIT:
- _debug_check();
- ret = dbenv->set_flags(dbenv, DB_REGION_INIT, 1);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "region_init");
- break;
- case TCL_ENV_SET_INTERMEDIATE_DIR:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-set_intermediate_dir_mode mode?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- _debug_check();
- ret = dbenv->set_intermediate_dir_mode(dbenv, arg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_intermediate_dir_mode");
- break;
- case TCL_ENV_REP:
- FLD_SET(open_flags, DB_INIT_REP);
- break;
- case TCL_ENV_REP_CLIENT:
- rep_flags = DB_REP_CLIENT;
- FLD_SET(open_flags, DB_INIT_REP);
- break;
- case TCL_ENV_REP_MASTER:
- rep_flags = DB_REP_MASTER;
- FLD_SET(open_flags, DB_INIT_REP);
- break;
- case TCL_ENV_REP_INMEM_FILES:
- result = tcl_RepInmemFiles(interp,dbenv);
- if (result == TCL_OK)
- FLD_SET(open_flags, DB_INIT_REP);
- break;
- case TCL_ENV_REP_LEASE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-rep_lease {nsites timeout clockskew}");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_ListObjGetElements(interp, objv[i],
- &myobjc, &myobjv);
- if (result == TCL_OK)
- i++;
- else
- break;
- result = tcl_RepLease(interp, myobjc, myobjv, dbenv);
- if (result == TCL_OK)
- FLD_SET(open_flags, DB_INIT_REP);
- break;
- case TCL_ENV_REP_TRANSPORT:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-rep_transport {envid sendproc}");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_ListObjGetElements(interp, objv[i],
- &myobjc, &myobjv);
- if (result == TCL_OK)
- i++;
- else
- break;
- result = tcl_RepTransport(
- interp, myobjc, myobjv, dbenv, ip);
- if (result == TCL_OK)
- FLD_SET(open_flags, DB_INIT_REP);
- break;
- case TCL_ENV_SNAPSHOT:
- FLD_SET(set_flags, DB_TXN_SNAPSHOT);
- break;
- case TCL_ENV_THREAD:
- /* Enable DB_THREAD when specified in testing. */
- FLD_SET(open_flags, DB_THREAD);
- break;
- case TCL_ENV_TIME_NOTGRANTED:
- FLD_SET(set_flags, DB_TIME_NOTGRANTED);
- break;
- case TCL_ENV_VERBOSE:
- result = Tcl_ListObjGetElements(interp, objv[i],
- &myobjc, &myobjv);
- if (result == TCL_OK)
- i++;
- else
- break;
- if (myobjc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-verbose {which on|off}?");
- result = TCL_ERROR;
- break;
- }
- result = tcl_EnvVerbose(
- interp, dbenv, myobjv[0], myobjv[1]);
- break;
- case TCL_ENV_WRNOSYNC:
- FLD_SET(set_flags, DB_TXN_WRITE_NOSYNC);
- break;
- case TCL_ENV_ZEROLOG:
- if ((ret =
- dbenv->log_set_config(dbenv, DB_LOG_ZERO, 1)) != 0)
- return (
- _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_log_config"));
- break;
-#endif
- case TCL_ENV_TXN:
- FLD_SET(open_flags, DB_INIT_LOCK |
- DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN);
- /* Make sure we have an arg to check against! */
- while (i < objc) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (strcmp(arg, "nosync") == 0) {
- FLD_SET(set_flags, DB_TXN_NOSYNC);
- i++;
- } else if (strcmp(arg, "snapshot") == 0) {
- FLD_SET(set_flags, DB_TXN_SNAPSHOT);
- i++;
- } else
- break;
- }
- break;
- case TCL_ENV_CREATE:
- FLD_SET(open_flags, DB_CREATE | DB_INIT_MPOOL);
- break;
- case TCL_ENV_ENCRYPT_AES:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-encryptaes passwd?");
- result = TCL_ERROR;
- break;
- }
- passwd = Tcl_GetStringFromObj(objv[i++], NULL);
- _debug_check();
- ret = dbenv->set_encrypt(dbenv, passwd, DB_ENCRYPT_AES);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_encrypt");
- break;
- case TCL_ENV_ENCRYPT_ANY:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-encryptany passwd?");
- result = TCL_ERROR;
- break;
- }
- passwd = Tcl_GetStringFromObj(objv[i++], NULL);
- _debug_check();
- ret = dbenv->set_encrypt(dbenv, passwd, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_encrypt");
- break;
- case TCL_ENV_HOME:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-home dir?");
- result = TCL_ERROR;
- break;
- }
- home = Tcl_GetStringFromObj(objv[i++], NULL);
- break;
- case TCL_ENV_MODE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-mode mode?");
- result = TCL_ERROR;
- break;
- }
- /*
- * Don't need to check result here because
- * if TCL_ERROR, the error message is already
- * set up, and we'll bail out below. If ok,
- * the mode is set and we go on.
- */
- result = Tcl_GetIntFromObj(interp, objv[i++], &mode);
- break;
- case TCL_ENV_PRIVATE:
- FLD_SET(open_flags, DB_PRIVATE | DB_INIT_MPOOL);
- break;
- case TCL_ENV_RECOVER:
- FLD_SET(open_flags, DB_RECOVER);
- break;
- case TCL_ENV_RECOVER_FATAL:
- FLD_SET(open_flags, DB_RECOVER_FATAL);
- break;
- case TCL_ENV_SYSTEM_MEM:
- FLD_SET(open_flags, DB_SYSTEM_MEM);
- break;
- case TCL_ENV_USE_ENVIRON_ROOT:
- FLD_SET(open_flags, DB_USE_ENVIRON_ROOT);
- break;
- case TCL_ENV_USE_ENVIRON:
- FLD_SET(open_flags, DB_USE_ENVIRON);
- break;
- case TCL_ENV_CACHESIZE:
- result = Tcl_ListObjGetElements(interp, objv[i],
- &myobjc, &myobjv);
- if (result == TCL_OK)
- i++;
- else
- break;
- if (myobjc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-cachesize {gbytes bytes ncaches}?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, myobjv[0], &gbytes);
- if (result != TCL_OK)
- break;
- result = _GetUInt32(interp, myobjv[1], &bytes);
- if (result != TCL_OK)
- break;
- result = Tcl_GetIntFromObj(interp, myobjv[2], &ncaches);
- if (result != TCL_OK)
- break;
- _debug_check();
- ret = dbenv->set_cachesize(dbenv, gbytes, bytes,
- ncaches);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_cachesize");
- break;
- case TCL_ENV_CACHE_MAX:
- result = Tcl_ListObjGetElements(interp, objv[i],
- &myobjc, &myobjv);
- if (result == TCL_OK)
- i++;
- else
- break;
- if (myobjc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-cache_max {gbytes bytes}?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, myobjv[0], &gbytes);
- if (result != TCL_OK)
- break;
- result = _GetUInt32(interp, myobjv[1], &bytes);
- if (result != TCL_OK)
- break;
- _debug_check();
- ret = dbenv->set_cache_max(dbenv, gbytes, bytes);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_cache_max");
- break;
- case TCL_ENV_SHM_KEY:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-shm_key key?");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetLongFromObj(interp, objv[i++], &shm);
- if (result == TCL_OK) {
- _debug_check();
- ret = dbenv->set_shm_key(dbenv, shm);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "shm_key");
- }
- break;
- case TCL_ENV_TXN_MAX:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-txn_max max?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = dbenv->set_tx_max(dbenv, uintarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "txn_max");
- }
- break;
- case TCL_ENV_ERRFILE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-errfile file");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- tcl_EnvSetErrfile(interp, dbenv, ip, arg);
- break;
- case TCL_ENV_ERRPFX:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-errpfx prefix");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- _debug_check();
- result = tcl_EnvSetErrpfx(interp, dbenv, ip, arg);
- break;
- case TCL_ENV_DATA_DIR:
- case TCL_ENV_ADD_DIR:
- case TCL_ENV_CREATE_DIR:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-xxx_dir dir");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- _debug_check();
- switch ((enum envopen)optindex) {
- case TCL_ENV_DATA_DIR:
- ret = dbenv->set_data_dir(dbenv, arg);
- break;
- case TCL_ENV_ADD_DIR:
- ret = dbenv->add_data_dir(dbenv, arg);
- break;
- case TCL_ENV_CREATE_DIR:
- ret = dbenv->set_create_dir(dbenv, arg);
- break;
- default:
- break;
- }
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "xxx_dir");
- break;
- case TCL_ENV_LOG_DIR:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-log_dir dir");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- _debug_check();
- ret = dbenv->set_lg_dir(dbenv, arg);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_lg_dir");
- break;
- case TCL_ENV_TMP_DIR:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-tmp_dir dir");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- _debug_check();
- ret = dbenv->set_tmp_dir(dbenv, arg);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_tmp_dir");
- break;
- }
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- }
-
- /*
- * We have to check this here. We want to set the log buffer
- * size first, if it is specified. So if the user did so,
- * then we took care of it above. But, if we get out here and
- * logmaxset is non-zero, then they set the log_max without
- * resetting the log buffer size, so we now have to do the
- * call to set_lg_max, since we didn't do it above.
- */
- if (logmaxset) {
- _debug_check();
- ret = dbenv->set_lg_max(dbenv, (u_int32_t)logmaxset);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "log_max");
- }
-
- if (result != TCL_OK)
- goto error;
-
- if (set_flags) {
- ret = dbenv->set_flags(dbenv, set_flags, 1);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_flags");
- if (result == TCL_ERROR)
- goto error;
- /*
- * If we are successful, clear the result so that the
- * return from set_flags isn't part of the result.
- */
- Tcl_ResetResult(interp);
- }
- /*
- * When we get here, we have already parsed all of our args
- * and made all our calls to set up the environment. Everything
- * is okay so far, no errors, if we get here.
- *
- * Now open the environment.
- */
- _debug_check();
- ret = dbenv->open(dbenv, home, open_flags, mode);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "dbenv open");
-
- if (rep_flags != 0 && result == TCL_OK) {
- _debug_check();
- ret = dbenv->rep_start(dbenv, NULL, rep_flags);
- result = _ReturnSetup(interp,
- ret, DB_RETOK_STD(ret), "rep_start");
- }
-
-error: if (result == TCL_ERROR) {
- if (ip->i_err && ip->i_err != stdout && ip->i_err != stderr) {
- (void)fclose(ip->i_err);
- ip->i_err = NULL;
- }
- (void)dbenv->close(dbenv, 0);
- }
- return (result);
-}
-
-/*
- * bdb_DbOpen --
- * Implements the "db_create/db_open" command.
- * There are many, many options to the open command.
- * Here is the general flow:
- *
- * 0. Preparse args to determine if we have -env.
- * 1. Call db_create to create the db handle.
- * 2. Parse args tracking options.
- * 3. Make any pre-open setup calls necessary.
- * 4. Call DB->open to open the database.
- * 5. Return db widget handle to user.
- */
-static int
-bdb_DbOpen(interp, objc, objv, ip, dbp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DBTCL_INFO *ip; /* Our internal info */
- DB **dbp; /* DB handle */
-{
- static const char *bdbenvopen[] = {
- "-env", NULL
- };
- enum bdbenvopen {
- TCL_DB_ENV0
- };
- static const char *bdbopen[] = {
-#ifdef CONFIG_TEST
- "-btcompare",
- "-dupcompare",
- "-hashcompare",
- "-hashproc",
- "-lorder",
- "-minkey",
- "-nommap",
- "-notdurable",
- "-partition",
- "-partition_dirs",
- "-partition_callback",
- "-read_uncommitted",
- "-revsplitoff",
- "-test",
- "-thread",
-#endif
- "-auto_commit",
- "-btree",
- "-cachesize",
- "-chksum",
- "-compress",
- "-create",
- "-create_dir",
- "-delim",
- "-dup",
- "-dupsort",
- "-encrypt",
- "-encryptaes",
- "-encryptany",
- "-env",
- "-errfile",
- "-errpfx",
- "-excl",
- "-extent",
- "-ffactor",
- "-hash",
- "-inorder",
- "-len",
- "-maxsize",
- "-mode",
- "-multiversion",
- "-nelem",
- "-pad",
- "-pagesize",
- "-queue",
- "-rdonly",
- "-recno",
- "-recnum",
- "-renumber",
- "-snapshot",
- "-source",
- "-truncate",
- "-txn",
- "-unknown",
- "--",
- NULL
- };
- enum bdbopen {
-#ifdef CONFIG_TEST
- TCL_DB_BTCOMPARE,
- TCL_DB_DUPCOMPARE,
- TCL_DB_HASHCOMPARE,
- TCL_DB_HASHPROC,
- TCL_DB_LORDER,
- TCL_DB_MINKEY,
- TCL_DB_NOMMAP,
- TCL_DB_NOTDURABLE,
- TCL_DB_PARTITION,
- TCL_DB_PART_DIRS,
- TCL_DB_PART_CALLBACK,
- TCL_DB_READ_UNCOMMITTED,
- TCL_DB_REVSPLIT,
- TCL_DB_TEST,
- TCL_DB_THREAD,
-#endif
- TCL_DB_AUTO_COMMIT,
- TCL_DB_BTREE,
- TCL_DB_CACHESIZE,
- TCL_DB_CHKSUM,
- TCL_DB_COMPRESS,
- TCL_DB_CREATE,
- TCL_DB_CREATE_DIR,
- TCL_DB_DELIM,
- TCL_DB_DUP,
- TCL_DB_DUPSORT,
- TCL_DB_ENCRYPT,
- TCL_DB_ENCRYPT_AES,
- TCL_DB_ENCRYPT_ANY,
- TCL_DB_ENV,
- TCL_DB_ERRFILE,
- TCL_DB_ERRPFX,
- TCL_DB_EXCL,
- TCL_DB_EXTENT,
- TCL_DB_FFACTOR,
- TCL_DB_HASH,
- TCL_DB_INORDER,
- TCL_DB_LEN,
- TCL_DB_MAXSIZE,
- TCL_DB_MODE,
- TCL_DB_MULTIVERSION,
- TCL_DB_NELEM,
- TCL_DB_PAD,
- TCL_DB_PAGESIZE,
- TCL_DB_QUEUE,
- TCL_DB_RDONLY,
- TCL_DB_RECNO,
- TCL_DB_RECNUM,
- TCL_DB_RENUMBER,
- TCL_DB_SNAPSHOT,
- TCL_DB_SOURCE,
- TCL_DB_TRUNCATE,
- TCL_DB_TXN,
- TCL_DB_UNKNOWN,
- TCL_DB_ENDARG
- };
- DBT *keys;
- DBTCL_INFO *envip, *errip;
- DBTYPE type;
- DB_ENV *dbenv;
- DB_TXN *txn;
- ENV *env;
-
- Tcl_Obj **myobjv;
- u_int32_t gbytes, bytes, open_flags, set_flags, uintarg;
- int endarg, i, intarg, mode, myobjc, ncaches;
- int optindex, result, ret, set_err, set_pfx, subdblen;
- u_char *subdbtmp;
- char *arg, *db, *passwd, *subdb, msg[MSG_SIZE];
-
- type = DB_UNKNOWN;
- endarg = mode = set_err = set_flags = set_pfx = 0;
- result = TCL_OK;
- subdbtmp = NULL;
- keys = NULL;
- db = subdb = NULL;
-
- /*
- * XXX
- * If/when our Tcl interface becomes thread-safe, we should enable
- * DB_THREAD here in all cases. For now, we turn it on later in this
- * function, and only when we're in testing and we specify the
- * -thread flag, so that we can exercise MUTEX_THREAD_LOCK cases.
- *
- * In order to become truly thread-safe, we need to look at making sure
- * DBTCL_INFO structs are safe to share across threads (they're not
- * mutex-protected) before we declare the Tcl interface thread-safe.
- * Meanwhile, there's no strong reason to enable DB_THREAD when not
- * testing.
- */
- open_flags = 0;
-
- dbenv = NULL;
- txn = NULL;
- env = NULL;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args?");
- return (TCL_ERROR);
- }
-
- /*
- * We must first parse for the environment flag, since that
- * is needed for db_create. Then create the db handle.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i++], bdbenvopen,
- "option", TCL_EXACT, &optindex) != TCL_OK) {
- /*
- * Reset the result so we don't get
- * an errant error message if there is another error.
- */
- Tcl_ResetResult(interp);
- continue;
- }
- switch ((enum bdbenvopen)optindex) {
- case TCL_DB_ENV0:
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- dbenv = NAME_TO_ENV(arg);
- if (dbenv == NULL) {
- Tcl_SetResult(interp,
- "db open: illegal environment", TCL_STATIC);
- return (TCL_ERROR);
- }
- }
- break;
- }
-
- /*
- * Create the db handle before parsing the args
- * since we'll be modifying the database options as we parse.
- */
- ret = db_create(dbp, dbenv, 0);
- if (ret)
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db_create"));
-
- /* Hang our info pointer on the DB handle, so we can do callbacks. */
- (*dbp)->api_internal = ip;
-
- /*
- * XXX
- * Remove restriction if error handling not tied to env.
- *
- * The DB->set_err* functions overwrite the environment. So, if
- * we are using an env, don't overwrite it; if not using an env,
- * then configure error handling.
- */
- if (dbenv == NULL) {
- env = NULL;
- (*dbp)->set_errpfx((*dbp), ip->i_name);
- (*dbp)->set_errcall((*dbp), _ErrorFunc);
- } else
- env = dbenv->env;
-
- /*
- * If we are using an env, we keep track of err info in the env's ip.
- * Otherwise use the DB's ip.
- */
- envip = _PtrToInfo(dbenv); /* XXX */
- if (envip)
- errip = envip;
- else
- errip = ip;
-
- /*
- * Get the option name index from the object based on the args
- * defined above.
- */
- i = 2;
- while (i < objc) {
- Tcl_ResetResult(interp);
- if (Tcl_GetIndexFromObj(interp, objv[i], bdbopen, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto error;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum bdbopen)optindex) {
-#ifdef CONFIG_TEST
- case TCL_DB_BTCOMPARE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-btcompare compareproc");
- result = TCL_ERROR;
- break;
- }
-
- /*
- * Store the object containing the procedure name.
- * We don't need to crack it out now--we'll want
- * to bundle it up to pass into Tcl_EvalObjv anyway.
- * Tcl's object refcounting will--I hope--take care
- * of the memory management here.
- */
- ip->i_compare = objv[i++];
- Tcl_IncrRefCount(ip->i_compare);
- _debug_check();
- ret = (*dbp)->set_bt_compare(*dbp, tcl_bt_compare);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_bt_compare");
- break;
- case TCL_DB_DUPCOMPARE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-dupcompare compareproc");
- result = TCL_ERROR;
- break;
- }
-
- /*
- * Store the object containing the procedure name.
- * See TCL_DB_BTCOMPARE.
- */
- ip->i_dupcompare = objv[i++];
- Tcl_IncrRefCount(ip->i_dupcompare);
- _debug_check();
- ret = (*dbp)->set_dup_compare(*dbp, tcl_dup_compare);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_dup_compare");
- break;
- case TCL_DB_HASHCOMPARE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-hashcompare compareproc");
- result = TCL_ERROR;
- break;
- }
-
- /*
- * Store the object containing the procedure name.
- * We don't need to crack it out now--we'll want
- * to bundle it up to pass into Tcl_EvalObjv anyway.
- * Tcl's object refcounting will--I hope--take care
- * of the memory management here.
- */
- ip->i_compare = objv[i++];
- Tcl_IncrRefCount(ip->i_compare);
- _debug_check();
- ret = (*dbp)->set_h_compare(*dbp, tcl_bt_compare);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_h_compare");
- break;
- case TCL_DB_HASHPROC:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-hashproc hashproc");
- result = TCL_ERROR;
- break;
- }
-
- /*
- * Store the object containing the procedure name.
- * See TCL_DB_BTCOMPARE.
- */
- ip->i_hashproc = objv[i++];
- Tcl_IncrRefCount(ip->i_hashproc);
- _debug_check();
- ret = (*dbp)->set_h_hash(*dbp, tcl_h_hash);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_h_hash");
- break;
- case TCL_DB_LORDER:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-lorder 1234|4321");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, objv[i++], &intarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = (*dbp)->set_lorder(*dbp, intarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_lorder");
- }
- break;
- case TCL_DB_MINKEY:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-minkey minkey");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = (*dbp)->set_bt_minkey(*dbp, uintarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_bt_minkey");
- }
- break;
- case TCL_DB_NOMMAP:
- open_flags |= DB_NOMMAP;
- break;
- case TCL_DB_NOTDURABLE:
- set_flags |= DB_TXN_NOT_DURABLE;
- break;
- case TCL_DB_PART_CALLBACK:
- if (i + 1 >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-partition_callback numparts callback");
- result = TCL_ERROR;
- break;
- }
-
- /*
- * Store the object containing the procedure name.
- * See TCL_DB_BTCOMPARE.
- */
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result != TCL_OK)
- break;
- ip->i_part_callback = objv[i++];
- Tcl_IncrRefCount(ip->i_part_callback);
- _debug_check();
- ret = (*dbp)->set_partition(
- *dbp, uintarg, NULL, tcl_part_callback);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_partition_callback");
- break;
- case TCL_DB_PART_DIRS:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-partition {dir list}");
- result = TCL_ERROR;
- break;
- }
- ret = tcl_set_partition_dirs(interp, *dbp, objv[i++]);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_partition_dirs");
- break;
- case TCL_DB_PARTITION:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-partition {key list}");
- result = TCL_ERROR;
- break;
- }
- _debug_check();
- ret = tcl_set_partition_keys(interp,
- *dbp, objv[i++], &keys);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_partition_keys");
- break;
- case TCL_DB_READ_UNCOMMITTED:
- open_flags |= DB_READ_UNCOMMITTED;
- break;
- case TCL_DB_REVSPLIT:
- set_flags |= DB_REVSPLITOFF;
- break;
- case TCL_DB_TEST:
- ret = (*dbp)->set_h_hash(*dbp, __ham_test);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_h_hash");
- break;
- case TCL_DB_THREAD:
- /* Enable DB_THREAD when specified in testing. */
- open_flags |= DB_THREAD;
- break;
-#endif
- case TCL_DB_AUTO_COMMIT:
- open_flags |= DB_AUTO_COMMIT;
- break;
- case TCL_DB_ENV:
- /*
- * Already parsed this, skip it and the env pointer.
- */
- i++;
- continue;
- case TCL_DB_TXN:
- if (i > (objc - 1)) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Open: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- case TCL_DB_BTREE:
- if (type != DB_UNKNOWN) {
- Tcl_SetResult(interp,
- "Too many DB types specified", TCL_STATIC);
- result = TCL_ERROR;
- goto error;
- }
- type = DB_BTREE;
- break;
- case TCL_DB_HASH:
- if (type != DB_UNKNOWN) {
- Tcl_SetResult(interp,
- "Too many DB types specified", TCL_STATIC);
- result = TCL_ERROR;
- goto error;
- }
- type = DB_HASH;
- break;
- case TCL_DB_RECNO:
- if (type != DB_UNKNOWN) {
- Tcl_SetResult(interp,
- "Too many DB types specified", TCL_STATIC);
- result = TCL_ERROR;
- goto error;
- }
- type = DB_RECNO;
- break;
- case TCL_DB_QUEUE:
- if (type != DB_UNKNOWN) {
- Tcl_SetResult(interp,
- "Too many DB types specified", TCL_STATIC);
- result = TCL_ERROR;
- goto error;
- }
- type = DB_QUEUE;
- break;
- case TCL_DB_UNKNOWN:
- if (type != DB_UNKNOWN) {
- Tcl_SetResult(interp,
- "Too many DB types specified", TCL_STATIC);
- result = TCL_ERROR;
- goto error;
- }
- break;
- case TCL_DB_CREATE:
- open_flags |= DB_CREATE;
- break;
- case TCL_DB_CREATE_DIR:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-create_dir dir");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- _debug_check();
- ret = (*dbp)->set_create_dir(*dbp, arg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_create_dir");
- break;
- case TCL_DB_EXCL:
- open_flags |= DB_EXCL;
- break;
- case TCL_DB_RDONLY:
- open_flags |= DB_RDONLY;
- break;
- case TCL_DB_TRUNCATE:
- open_flags |= DB_TRUNCATE;
- break;
- case TCL_DB_MODE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-mode mode?");
- result = TCL_ERROR;
- break;
- }
- /*
- * Don't need to check result here because
- * if TCL_ERROR, the error message is already
- * set up, and we'll bail out below. If ok,
- * the mode is set and we go on.
- */
- result = Tcl_GetIntFromObj(interp, objv[i++], &mode);
- break;
- case TCL_DB_DUP:
- set_flags |= DB_DUP;
- break;
- case TCL_DB_DUPSORT:
- set_flags |= DB_DUPSORT;
- break;
- case TCL_DB_INORDER:
- set_flags |= DB_INORDER;
- break;
- case TCL_DB_RECNUM:
- set_flags |= DB_RECNUM;
- break;
- case TCL_DB_RENUMBER:
- set_flags |= DB_RENUMBER;
- break;
- case TCL_DB_SNAPSHOT:
- set_flags |= DB_SNAPSHOT;
- break;
- case TCL_DB_CHKSUM:
- set_flags |= DB_CHKSUM;
- break;
- case TCL_DB_ENCRYPT:
- set_flags |= DB_ENCRYPT;
- break;
- case TCL_DB_ENCRYPT_AES:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-encryptaes passwd?");
- result = TCL_ERROR;
- break;
- }
- passwd = Tcl_GetStringFromObj(objv[i++], NULL);
- _debug_check();
- ret = (*dbp)->set_encrypt(*dbp, passwd, DB_ENCRYPT_AES);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_encrypt");
- break;
- case TCL_DB_ENCRYPT_ANY:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-encryptany passwd?");
- result = TCL_ERROR;
- break;
- }
- passwd = Tcl_GetStringFromObj(objv[i++], NULL);
- _debug_check();
- ret = (*dbp)->set_encrypt(*dbp, passwd, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_encrypt");
- break;
- case TCL_DB_COMPRESS:
- ret = (*dbp)->set_bt_compress(*dbp, 0, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_bt_compress");
- break;
- case TCL_DB_FFACTOR:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-ffactor density");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = (*dbp)->set_h_ffactor(*dbp, uintarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_h_ffactor");
- }
- break;
- case TCL_DB_MULTIVERSION:
- open_flags |= DB_MULTIVERSION;
- break;
- case TCL_DB_NELEM:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-nelem nelem");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = (*dbp)->set_h_nelem(*dbp, uintarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_h_nelem");
- }
- break;
- case TCL_DB_DELIM:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-delim delim");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, objv[i++], &intarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = (*dbp)->set_re_delim(*dbp, intarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_re_delim");
- }
- break;
- case TCL_DB_LEN:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-len length");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = (*dbp)->set_re_len(*dbp, uintarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_re_len");
- }
- break;
- case TCL_DB_MAXSIZE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-len length");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = (*dbp)->mpf->set_maxsize(
- (*dbp)->mpf, 0, uintarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_maxsize");
- }
- break;
- case TCL_DB_PAD:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-pad pad");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, objv[i++], &intarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = (*dbp)->set_re_pad(*dbp, intarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_re_pad");
- }
- break;
- case TCL_DB_SOURCE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-source file");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- _debug_check();
- ret = (*dbp)->set_re_source(*dbp, arg);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_re_source");
- break;
- case TCL_DB_EXTENT:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-extent size");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = (*dbp)->set_q_extentsize(*dbp, uintarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_q_extentsize");
- }
- break;
- case TCL_DB_CACHESIZE:
- result = Tcl_ListObjGetElements(interp, objv[i++],
- &myobjc, &myobjv);
- if (result != TCL_OK)
- break;
- if (myobjc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-cachesize {gbytes bytes ncaches}?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, myobjv[0], &gbytes);
- if (result != TCL_OK)
- break;
- result = _GetUInt32(interp, myobjv[1], &bytes);
- if (result != TCL_OK)
- break;
- result = Tcl_GetIntFromObj(interp, myobjv[2], &ncaches);
- if (result != TCL_OK)
- break;
- _debug_check();
- ret = (*dbp)->set_cachesize(*dbp, gbytes, bytes,
- ncaches);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set_cachesize");
- break;
- case TCL_DB_PAGESIZE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-pagesize size?");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, objv[i++], &intarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = (*dbp)->set_pagesize(*dbp,
- (size_t)intarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "set pagesize");
- }
- break;
- case TCL_DB_ERRFILE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-errfile file");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- /*
- * If the user already set one, close it.
- */
- if (errip->i_err != NULL &&
- errip->i_err != stdout && errip->i_err != stderr)
- (void)fclose(errip->i_err);
- if (strcmp(arg, "/dev/stdout") == 0)
- errip->i_err = stdout;
- else if (strcmp(arg, "/dev/stderr") == 0)
- errip->i_err = stderr;
- else
- errip->i_err = fopen(arg, "a");
- if (errip->i_err != NULL) {
- _debug_check();
- (*dbp)->set_errfile(*dbp, errip->i_err);
- set_err = 1;
- }
- break;
- case TCL_DB_ERRPFX:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-errpfx prefix");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- /*
- * If the user already set one, free it.
- */
- if (errip->i_errpfx != NULL)
- __os_free(NULL, errip->i_errpfx);
- if ((ret = __os_strdup((*dbp)->env,
- arg, &errip->i_errpfx)) != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "__os_strdup");
- break;
- }
- if (errip->i_errpfx != NULL) {
- _debug_check();
- (*dbp)->set_errpfx(*dbp, errip->i_errpfx);
- set_pfx = 1;
- }
- break;
- case TCL_DB_ENDARG:
- endarg = 1;
- break;
- } /* switch */
-
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- if (endarg)
- break;
- }
- if (result != TCL_OK)
- goto error;
-
- /*
- * Any args we have left, (better be 0, 1 or 2 left) are
- * file names. If we have 0, then an in-memory db. If
- * there is 1, a db name, if 2 a db and subdb name.
- */
- if (i != objc) {
- /*
- * Dbs must be NULL terminated file names, but subdbs can
- * be anything. Use Strings for the db name and byte
- * arrays for the subdb.
- */
- db = Tcl_GetStringFromObj(objv[i++], NULL);
- if (strcmp(db, "") == 0)
- db = NULL;
- if (i != objc) {
- subdbtmp =
- Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
- if ((ret = __os_malloc(env,
- (size_t)subdblen + 1, &subdb)) != 0) {
- Tcl_SetResult(interp, db_strerror(ret),
- TCL_STATIC);
- return (0);
- }
- memcpy(subdb, subdbtmp, (size_t)subdblen);
- subdb[subdblen] = '\0';
- }
- }
- if (set_flags) {
- ret = (*dbp)->set_flags(*dbp, set_flags);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_flags");
- if (result == TCL_ERROR)
- goto error;
- /*
- * If we are successful, clear the result so that the
- * return from set_flags isn't part of the result.
- */
- Tcl_ResetResult(interp);
- }
-
- /*
- * When we get here, we have already parsed all of our args and made
- * all our calls to set up the database. Everything is okay so far,
- * no errors, if we get here.
- */
- _debug_check();
-
- /* Open the database. */
- ret = (*dbp)->open(*dbp, txn, db, subdb, type, open_flags, mode);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db open");
-
-error:
- if (keys != NULL)
- __os_free(NULL, keys);
- if (subdb)
- __os_free(env, subdb);
- if (result == TCL_ERROR) {
- (void)(*dbp)->close(*dbp, 0);
- /*
- * If we opened and set up the error file in the environment
- * on this open, but we failed for some other reason, clean
- * up and close the file.
- *
- * XXX when err stuff isn't tied to env, change to use ip,
- * instead of envip. Also, set_err is irrelevant when that
- * happens. It will just read:
- * if (ip->i_err)
- * fclose(ip->i_err);
- */
- if (set_err && errip && errip->i_err != NULL &&
- errip->i_err != stdout && errip->i_err != stderr) {
- (void)fclose(errip->i_err);
- errip->i_err = NULL;
- }
- if (set_pfx && errip && errip->i_errpfx != NULL) {
- __os_free(env, errip->i_errpfx);
- errip->i_errpfx = NULL;
- }
- *dbp = NULL;
- }
- return (result);
-}
-
-#ifdef HAVE_64BIT_TYPES
-/*
- * bdb_SeqOpen --
- * Implements the "Seq_create/Seq_open" command.
- */
-static int
-bdb_SeqOpen(interp, objc, objv, ip, seqp)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DBTCL_INFO *ip; /* Our internal info */
- DB_SEQUENCE **seqp; /* DB_SEQUENCE handle */
-{
- static const char *seqopen[] = {
- "-cachesize",
- "-create",
- "-inc",
- "-init",
- "-dec",
- "-max",
- "-min",
- "-thread",
- "-txn",
- "-wrap",
- "--",
- NULL
- } ;
- enum seqopen {
- TCL_SEQ_CACHESIZE,
- TCL_SEQ_CREATE,
- TCL_SEQ_INC,
- TCL_SEQ_INIT,
- TCL_SEQ_DEC,
- TCL_SEQ_MAX,
- TCL_SEQ_MIN,
- TCL_SEQ_THREAD,
- TCL_SEQ_TXN,
- TCL_SEQ_WRAP,
- TCL_SEQ_ENDARG
- };
- DB *dbp;
- DBT key;
- DBTYPE type;
- DB_TXN *txn;
- db_recno_t recno;
- db_seq_t min, max, value;
- Tcl_WideInt tcl_value;
- u_int32_t flags, oflags;
- int cache, endarg, i, optindex, result, ret, setrange, setvalue, v;
- char *arg, *db, msg[MSG_SIZE];
-
- COMPQUIET(ip, NULL);
- COMPQUIET(value, 0);
- *seqp = NULL;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args?");
- return (TCL_ERROR);
- }
-
- txn = NULL;
- endarg = 0;
- flags = oflags = 0;
- setrange = setvalue = 0;
- min = INT64_MIN;
- max = INT64_MAX;
- cache = 0;
-
- for (i = 2; i < objc;) {
- Tcl_ResetResult(interp);
- if (Tcl_GetIndexFromObj(interp, objv[i], seqopen, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto error;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- result = TCL_OK;
- switch ((enum seqopen)optindex) {
- case TCL_SEQ_CREATE:
- oflags |= DB_CREATE;
- break;
- case TCL_SEQ_INC:
- LF_SET(DB_SEQ_INC);
- break;
- case TCL_SEQ_CACHESIZE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-cachesize value?");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, objv[i++], &cache);
- break;
- case TCL_SEQ_INIT:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-init value?");
- result = TCL_ERROR;
- break;
- }
- result =
- Tcl_GetWideIntFromObj(
- interp, objv[i++], &tcl_value);
- value = tcl_value;
- setvalue = 1;
- break;
- case TCL_SEQ_DEC:
- LF_SET(DB_SEQ_DEC);
- break;
- case TCL_SEQ_MAX:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-max value?");
- result = TCL_ERROR;
- break;
- }
- if ((result =
- Tcl_GetWideIntFromObj(interp,
- objv[i++], &tcl_value)) != TCL_OK)
- goto error;
- max = tcl_value;
- setrange = 1;
- break;
- case TCL_SEQ_MIN:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-min value?");
- result = TCL_ERROR;
- break;
- }
- if ((result =
- Tcl_GetWideIntFromObj(interp,
- objv[i++], &tcl_value)) != TCL_OK)
- goto error;
- min = tcl_value;
- setrange = 1;
- break;
- case TCL_SEQ_THREAD:
- oflags |= DB_THREAD;
- break;
- case TCL_SEQ_TXN:
- if (i > (objc - 1)) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Sequence: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- case TCL_SEQ_WRAP:
- LF_SET(DB_SEQ_WRAP);
- break;
- case TCL_SEQ_ENDARG:
- endarg = 1;
- break;
- }
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- if (endarg)
- break;
- }
-
- if (objc - i != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args?");
- return (TCL_ERROR);
- }
- /*
- * The db must be a string but the sequence key may
- * be anything.
- */
- db = Tcl_GetStringFromObj(objv[i++], NULL);
- if ((dbp = NAME_TO_DB(db)) == NULL) {
- Tcl_SetResult(interp, "No such dbp", TCL_STATIC);
- return (TCL_ERROR);
- }
- (void)dbp->get_type(dbp, &type);
-
- if (type == DB_QUEUE || type == DB_RECNO) {
- result = _GetUInt32(interp, objv[i++], &recno);
- if (result != TCL_OK)
- return (result);
- DB_INIT_DBT(key, &recno, sizeof(recno));
- } else
- DB_INIT_DBT(key, Tcl_GetByteArrayFromObj(objv[i++], &v), v);
- ret = db_sequence_create(seqp, dbp, 0);
- if ((result = _ReturnSetup(interp,
- ret, DB_RETOK_STD(ret), "sequence create")) != TCL_OK) {
- *seqp = NULL;
- return (result);
- }
-
- ret = (*seqp)->set_flags(*seqp, flags);
- if ((result = _ReturnSetup(interp,
- ret, DB_RETOK_STD(ret), "sequence set_flags")) != TCL_OK)
- goto error;
- if (setrange) {
- ret = (*seqp)->set_range(*seqp, min, max);
- if ((result = _ReturnSetup(interp,
- ret, DB_RETOK_STD(ret), "sequence set_range")) != TCL_OK)
- goto error;
- }
- if (cache) {
- ret = (*seqp)->set_cachesize(*seqp, cache);
- if ((result = _ReturnSetup(interp,
- ret, DB_RETOK_STD(ret), "sequence cachesize")) != TCL_OK)
- goto error;
- }
- if (setvalue) {
- ret = (*seqp)->initial_value(*seqp, value);
- if ((result = _ReturnSetup(interp,
- ret, DB_RETOK_STD(ret), "sequence init")) != TCL_OK)
- goto error;
- }
- ret = (*seqp)->open(*seqp, txn, &key, oflags);
- if ((result = _ReturnSetup(interp,
- ret, DB_RETOK_STD(ret), "sequence open")) != TCL_OK)
- goto error;
-
- if (0) {
-error: if (*seqp != NULL)
- (void)(*seqp)->close(*seqp, 0);
- *seqp = NULL;
- }
- return (result);
-}
-#endif
-
-/*
- * bdb_DbRemove --
- * Implements the DB_ENV->remove and DB->remove command.
- */
-static int
-bdb_DbRemove(interp, objc, objv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *bdbrem[] = {
- "-auto_commit",
- "-encrypt",
- "-encryptaes",
- "-encryptany",
- "-env",
- "-txn",
- "--",
- NULL
- };
- enum bdbrem {
- TCL_DBREM_AUTOCOMMIT,
- TCL_DBREM_ENCRYPT,
- TCL_DBREM_ENCRYPT_AES,
- TCL_DBREM_ENCRYPT_ANY,
- TCL_DBREM_ENV,
- TCL_DBREM_TXN,
- TCL_DBREM_ENDARG
- };
- DB *dbp;
- DB_ENV *dbenv;
- DB_TXN *txn;
- ENV *env;
- u_int32_t enc_flag, iflags, set_flags;
- int endarg, i, optindex, result, ret, subdblen;
- u_char *subdbtmp;
- char *arg, *db, msg[MSG_SIZE], *passwd, *subdb;
-
- dbp = NULL;
- dbenv = NULL;
- txn = NULL;
- env = NULL;
- enc_flag = iflags = set_flags = 0;
- endarg = 0;
- result = TCL_OK;
- subdbtmp = NULL;
- db = passwd = subdb = NULL;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args? filename ?database?");
- return (TCL_ERROR);
- }
-
- /*
- * We must first parse for the environment flag, since that
- * is needed for db_create. Then create the db handle.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], bdbrem,
- "option", TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto error;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum bdbrem)optindex) {
- case TCL_DBREM_AUTOCOMMIT:
- iflags |= DB_AUTO_COMMIT;
- _debug_check();
- break;
- case TCL_DBREM_ENCRYPT:
- set_flags |= DB_ENCRYPT;
- _debug_check();
- break;
- case TCL_DBREM_ENCRYPT_AES:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-encryptaes passwd?");
- result = TCL_ERROR;
- break;
- }
- passwd = Tcl_GetStringFromObj(objv[i++], NULL);
- enc_flag = DB_ENCRYPT_AES;
- break;
- case TCL_DBREM_ENCRYPT_ANY:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-encryptany passwd?");
- result = TCL_ERROR;
- break;
- }
- passwd = Tcl_GetStringFromObj(objv[i++], NULL);
- enc_flag = 0;
- break;
- case TCL_DBREM_ENV:
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- dbenv = NAME_TO_ENV(arg);
- if (dbenv == NULL) {
- Tcl_SetResult(interp,
- "db remove: illegal environment",
- TCL_STATIC);
- return (TCL_ERROR);
- }
- env = dbenv->env;
- break;
- case TCL_DBREM_ENDARG:
- endarg = 1;
- break;
- case TCL_DBREM_TXN:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Put: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- }
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- if (endarg)
- break;
- }
- if (result != TCL_OK)
- goto error;
- /*
- * Any args we have left, (better be 1 or 2 left) are
- * file names. If there is 1, a db name, if 2 a db and subdb name.
- */
- if ((i != (objc - 1)) || (i != (objc - 2))) {
- /*
- * Dbs must be NULL terminated file names, but subdbs can
- * be anything. Use Strings for the db name and byte
- * arrays for the subdb.
- */
- db = Tcl_GetStringFromObj(objv[i++], NULL);
- if (strcmp(db, "") == 0)
- db = NULL;
- if (i != objc) {
- subdbtmp =
- Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
- if ((ret = __os_malloc(env, (size_t)subdblen + 1,
- &subdb)) != 0) { Tcl_SetResult(interp,
- db_strerror(ret), TCL_STATIC);
- return (0);
- }
- memcpy(subdb, subdbtmp, (size_t)subdblen);
- subdb[subdblen] = '\0';
- }
- } else {
- Tcl_WrongNumArgs(interp, 2, objv, "?args? filename ?database?");
- result = TCL_ERROR;
- goto error;
- }
- if (dbenv == NULL) {
- ret = db_create(&dbp, dbenv, 0);
- if (ret) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db_create");
- goto error;
- }
-
- /*
- * XXX
- * Remove restriction if error handling not tied to env.
- *
- * The DB->set_err* functions overwrite the environment. So, if
- * we are using an env, don't overwrite it; if not using an env,
- * then configure error handling.
- */
- dbp->set_errpfx(dbp, "DbRemove");
- dbp->set_errcall(dbp, _ErrorFunc);
-
- if (passwd != NULL) {
- ret = dbp->set_encrypt(dbp, passwd, enc_flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_encrypt");
- }
- if (set_flags != 0) {
- ret = dbp->set_flags(dbp, set_flags);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_flags");
- }
- }
-
- /*
- * The dbremove method is a destructor, NULL out the dbp.
- */
- _debug_check();
- if (dbp == NULL)
- ret = dbenv->dbremove(dbenv, txn, db, subdb, iflags);
- else
- ret = dbp->remove(dbp, db, subdb, 0);
-
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db remove");
- dbp = NULL;
-error:
- if (subdb)
- __os_free(env, subdb);
- if (result == TCL_ERROR && dbp != NULL)
- (void)dbp->close(dbp, 0);
- return (result);
-}
-
-/*
- * bdb_DbRename --
- * Implements the DB_ENV->dbrename and DB->rename commands.
- */
-static int
-bdb_DbRename(interp, objc, objv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *bdbmv[] = {
- "-auto_commit",
- "-encrypt",
- "-encryptaes",
- "-encryptany",
- "-env",
- "-txn",
- "--",
- NULL
- };
- enum bdbmv {
- TCL_DBMV_AUTOCOMMIT,
- TCL_DBMV_ENCRYPT,
- TCL_DBMV_ENCRYPT_AES,
- TCL_DBMV_ENCRYPT_ANY,
- TCL_DBMV_ENV,
- TCL_DBMV_TXN,
- TCL_DBMV_ENDARG
- };
- DB *dbp;
- DB_ENV *dbenv;
- DB_TXN *txn;
- ENV *env;
- u_int32_t enc_flag, iflags, set_flags;
- int endarg, i, newlen, optindex, result, ret, subdblen;
- u_char *subdbtmp;
- char *arg, *db, msg[MSG_SIZE], *newname, *passwd, *subdb;
-
- dbp = NULL;
- dbenv = NULL;
- txn = NULL;
- env = NULL;
- enc_flag = iflags = set_flags = 0;
- result = TCL_OK;
- endarg = 0;
- db = newname = passwd = subdb = NULL;
- subdbtmp = NULL;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp,
- 3, objv, "?args? filename ?database? ?newname?");
- return (TCL_ERROR);
- }
-
- /*
- * We must first parse for the environment flag, since that
- * is needed for db_create. Then create the db handle.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], bdbmv,
- "option", TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto error;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum bdbmv)optindex) {
- case TCL_DBMV_AUTOCOMMIT:
- iflags |= DB_AUTO_COMMIT;
- _debug_check();
- break;
- case TCL_DBMV_ENCRYPT:
- set_flags |= DB_ENCRYPT;
- _debug_check();
- break;
- case TCL_DBMV_ENCRYPT_AES:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-encryptaes passwd?");
- result = TCL_ERROR;
- break;
- }
- passwd = Tcl_GetStringFromObj(objv[i++], NULL);
- enc_flag = DB_ENCRYPT_AES;
- break;
- case TCL_DBMV_ENCRYPT_ANY:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-encryptany passwd?");
- result = TCL_ERROR;
- break;
- }
- passwd = Tcl_GetStringFromObj(objv[i++], NULL);
- enc_flag = 0;
- break;
- case TCL_DBMV_ENV:
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- dbenv = NAME_TO_ENV(arg);
- if (dbenv == NULL) {
- Tcl_SetResult(interp,
- "db rename: illegal environment",
- TCL_STATIC);
- return (TCL_ERROR);
- }
- env = dbenv->env;
- break;
- case TCL_DBMV_ENDARG:
- endarg = 1;
- break;
- case TCL_DBMV_TXN:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Put: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- }
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- if (endarg)
- break;
- }
- if (result != TCL_OK)
- goto error;
- /*
- * Any args we have left, (better be 2 or 3 left) are
- * file names. If there is 2, a file name, if 3 a file and db name.
- */
- if ((i != (objc - 2)) || (i != (objc - 3))) {
- /*
- * Dbs must be NULL terminated file names, but subdbs can
- * be anything. Use Strings for the db name and byte
- * arrays for the subdb.
- */
- db = Tcl_GetStringFromObj(objv[i++], NULL);
- if (strcmp(db, "") == 0)
- db = NULL;
- if (i == objc - 2) {
- subdbtmp =
- Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
- if ((ret = __os_malloc(env,
- (size_t)subdblen + 1, &subdb)) != 0) {
- Tcl_SetResult(interp,
- db_strerror(ret), TCL_STATIC);
- return (0);
- }
- memcpy(subdb, subdbtmp, (size_t)subdblen);
- subdb[subdblen] = '\0';
- }
- subdbtmp =
- Tcl_GetByteArrayFromObj(objv[i++], &newlen);
- if ((ret = __os_malloc(
- env, (size_t)newlen + 1, &newname)) != 0) {
- Tcl_SetResult(interp,
- db_strerror(ret), TCL_STATIC);
- return (0);
- }
- memcpy(newname, subdbtmp, (size_t)newlen);
- newname[newlen] = '\0';
- } else {
- Tcl_WrongNumArgs(
- interp, 3, objv, "?args? filename ?database? ?newname?");
- result = TCL_ERROR;
- goto error;
- }
- if (dbenv == NULL) {
- ret = db_create(&dbp, dbenv, 0);
- if (ret) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db_create");
- goto error;
- }
- /*
- * XXX
- * Remove restriction if error handling not tied to env.
- *
- * The DB->set_err* functions overwrite the environment. So, if
- * we are using an env, don't overwrite it; if not using an env,
- * then configure error handling.
- */
- dbp->set_errpfx(dbp, "DbRename");
- dbp->set_errcall(dbp, _ErrorFunc);
-
- if (passwd != NULL) {
- ret = dbp->set_encrypt(dbp, passwd, enc_flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_encrypt");
- }
- if (set_flags != 0) {
- ret = dbp->set_flags(dbp, set_flags);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_flags");
- }
- }
-
- /*
- * The dbrename method is a destructor, NULL out the dbp.
- */
- _debug_check();
- if (dbp == NULL)
- ret = dbenv->dbrename(dbenv, txn, db, subdb, newname, iflags);
- else
- ret = dbp->rename(dbp, db, subdb, newname, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db rename");
- dbp = NULL;
-error:
- if (subdb)
- __os_free(env, subdb);
- if (newname)
- __os_free(env, newname);
- if (result == TCL_ERROR && dbp != NULL)
- (void)dbp->close(dbp, 0);
- return (result);
-}
-
-#ifdef CONFIG_TEST
-/*
- * bdb_DbVerify --
- * Implements the DB->verify command.
- */
-static int
-bdb_DbVerify(interp, objc, objv, ip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DBTCL_INFO *ip; /* Our internal info */
-{
- static const char *bdbverify[] = {
- "-btcompare",
- "-dupcompare",
- "-hashcompare",
- "-hashproc",
-
- "-encrypt",
- "-encryptaes",
- "-encryptany",
- "-env",
- "-errfile",
- "-errpfx",
- "-noorderchk",
- "-orderchkonly",
- "-unref",
- "--",
- NULL
- };
- enum bdbvrfy {
- TCL_DBVRFY_BTCOMPARE,
- TCL_DBVRFY_DUPCOMPARE,
- TCL_DBVRFY_HASHCOMPARE,
- TCL_DBVRFY_HASHPROC,
-
- TCL_DBVRFY_ENCRYPT,
- TCL_DBVRFY_ENCRYPT_AES,
- TCL_DBVRFY_ENCRYPT_ANY,
- TCL_DBVRFY_ENV,
- TCL_DBVRFY_ERRFILE,
- TCL_DBVRFY_ERRPFX,
- TCL_DBVRFY_NOORDERCHK,
- TCL_DBVRFY_ORDERCHKONLY,
- TCL_DBVRFY_UNREF,
- TCL_DBVRFY_ENDARG
- };
- DB_ENV *dbenv;
- DB *dbp;
- FILE *errf;
- int (*bt_compare) __P((DB *, const DBT *, const DBT *));
- int (*dup_compare) __P((DB *, const DBT *, const DBT *));
- int (*h_compare) __P((DB *, const DBT *, const DBT *));
- u_int32_t (*h_hash)__P((DB *, const void *, u_int32_t));
- u_int32_t enc_flag, flags, set_flags;
- int endarg, i, optindex, result, ret, subdblen;
- char *arg, *db, *errpfx, *passwd, *subdb;
- u_char *subdbtmp;
-
- dbenv = NULL;
- dbp = NULL;
- passwd = NULL;
- result = TCL_OK;
- db = errpfx = subdb = NULL;
- errf = NULL;
- bt_compare = NULL;
- dup_compare = NULL;
- h_compare = NULL;
- h_hash = NULL;
- flags = endarg = 0;
- enc_flag = set_flags = 0;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args? filename");
- return (TCL_ERROR);
- }
-
- /*
- * We must first parse for the environment flag, since that
- * is needed for db_create. Then create the db handle.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], bdbverify,
- "option", TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto error;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum bdbvrfy)optindex) {
- case TCL_DBVRFY_BTCOMPARE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-btcompare compareproc");
- result = TCL_ERROR;
- break;
- }
-
- /*
- * Store the object containing the procedure name.
- * We don't need to crack it out now--we'll want
- * to bundle it up to pass into Tcl_EvalObjv anyway.
- * Tcl's object refcounting will--I hope--take care
- * of the memory management here.
- */
- ip->i_compare = objv[i++];
- Tcl_IncrRefCount(ip->i_compare);
- _debug_check();
- bt_compare = tcl_bt_compare;
- break;
- case TCL_DBVRFY_DUPCOMPARE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-dupcompare compareproc");
- result = TCL_ERROR;
- break;
- }
-
- /*
- * Store the object containing the procedure name.
- * See TCL_DBVRFY_BTCOMPARE.
- */
- ip->i_dupcompare = objv[i++];
- Tcl_IncrRefCount(ip->i_dupcompare);
- _debug_check();
- dup_compare = tcl_dup_compare;
- break;
- case TCL_DBVRFY_HASHCOMPARE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-hashcompare compareproc");
- result = TCL_ERROR;
- break;
- }
-
- /*
- * Store the object containing the procedure name.
- * We don't need to crack it out now--we'll want
- * to bundle it up to pass into Tcl_EvalObjv anyway.
- * Tcl's object refcounting will--I hope--take care
- * of the memory management here.
- */
- ip->i_compare = objv[i++];
- Tcl_IncrRefCount(ip->i_compare);
- _debug_check();
- h_compare = tcl_bt_compare;
- break;
- case TCL_DBVRFY_HASHPROC:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-hashproc hashproc");
- result = TCL_ERROR;
- break;
- }
-
- /*
- * Store the object containing the procedure name.
- * See TCL_DBVRFY_BTCOMPARE.
- */
- ip->i_hashproc = objv[i++];
- Tcl_IncrRefCount(ip->i_hashproc);
- _debug_check();
- h_hash = tcl_h_hash;
- break;
- case TCL_DBVRFY_ENCRYPT:
- set_flags |= DB_ENCRYPT;
- _debug_check();
- break;
- case TCL_DBVRFY_ENCRYPT_AES:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-encryptaes passwd?");
- result = TCL_ERROR;
- break;
- }
- passwd = Tcl_GetStringFromObj(objv[i++], NULL);
- enc_flag = DB_ENCRYPT_AES;
- break;
- case TCL_DBVRFY_ENCRYPT_ANY:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-encryptany passwd?");
- result = TCL_ERROR;
- break;
- }
- passwd = Tcl_GetStringFromObj(objv[i++], NULL);
- enc_flag = 0;
- break;
- case TCL_DBVRFY_ENV:
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- dbenv = NAME_TO_ENV(arg);
- if (dbenv == NULL) {
- Tcl_SetResult(interp,
- "db verify: illegal environment",
- TCL_STATIC);
- result = TCL_ERROR;
- break;
- }
- break;
- case TCL_DBVRFY_ERRFILE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-errfile file");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- /*
- * If the user already set one, close it.
- */
- if (errf != NULL && errf != stdout && errf != stderr)
- (void)fclose(errf);
- if (strcmp(arg, "/dev/stdout") == 0)
- errf = stdout;
- else if (strcmp(arg, "/dev/stderr") == 0)
- errf = stderr;
- else
- errf = fopen(arg, "a");
- break;
- case TCL_DBVRFY_ERRPFX:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-errpfx prefix");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- /*
- * If the user already set one, free it.
- */
- if (errpfx != NULL)
- __os_free(dbenv->env, errpfx);
- if ((ret = __os_strdup(NULL, arg, &errpfx)) != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "__os_strdup");
- break;
- }
- break;
- case TCL_DBVRFY_NOORDERCHK:
- flags |= DB_NOORDERCHK;
- break;
- case TCL_DBVRFY_ORDERCHKONLY:
- flags |= DB_ORDERCHKONLY;
- break;
- case TCL_DBVRFY_UNREF:
- flags |= DB_UNREF;
- break;
- case TCL_DBVRFY_ENDARG:
- endarg = 1;
- break;
- }
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- if (endarg)
- break;
- }
- if (result != TCL_OK)
- goto error;
- /*
- * The remaining arg is the db filename.
- */
- /*
- * Any args we have left, (better be 1 or 2 left) are
- * file names. If there is 1, a db name, if 2 a db and subdb name.
- */
- if (i != objc) {
- /*
- * Dbs must be NULL terminated file names, but subdbs can
- * be anything. Use Strings for the db name and byte
- * arrays for the subdb.
- */
- db = Tcl_GetStringFromObj(objv[i++], NULL);
- if (strcmp(db, "") == 0)
- db = NULL;
- if (i != objc) {
- subdbtmp =
- Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
- if ((ret = __os_malloc(dbenv->env,
- (size_t)subdblen + 1, &subdb)) != 0) {
- Tcl_SetResult(interp, db_strerror(ret),
- TCL_STATIC);
- return (0);
- }
- memcpy(subdb, subdbtmp, (size_t)subdblen);
- subdb[subdblen] = '\0';
- }
- } else {
- Tcl_WrongNumArgs(interp, 2, objv, "?args? filename");
- result = TCL_ERROR;
- goto error;
- }
-
- ret = db_create(&dbp, dbenv, 0);
- if (ret) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db_create");
- goto error;
- }
-
- /* Hang our info pointer on the DB handle, so we can do callbacks. */
- dbp->api_internal = ip;
-
- if (errf != NULL)
- dbp->set_errfile(dbp, errf);
- if (errpfx != NULL)
- dbp->set_errpfx(dbp, errpfx);
-
- if (passwd != NULL &&
- (ret = dbp->set_encrypt(dbp, passwd, enc_flag)) != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_encrypt");
- goto error;
- }
-
- if (set_flags != 0 &&
- (ret = dbp->set_flags(dbp, set_flags)) != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_flags");
- goto error;
- }
- if (bt_compare != NULL &&
- (ret = dbp->set_bt_compare(dbp, bt_compare)) != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_bt_compare");
- goto error;
- }
- if (dup_compare != NULL &&
- (ret = dbp->set_dup_compare(dbp, dup_compare)) != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_dup_compare");
- goto error;
- }
- if (h_compare != NULL &&
- (ret = dbp->set_h_compare(dbp, h_compare)) != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_h_compare");
- goto error;
- }
- if (h_hash != NULL &&
- (ret = dbp->set_h_hash(dbp, h_hash)) != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_h_hash");
- goto error;
- }
-
- /*
- * The verify method is a destructor, NULL out the dbp.
- */
- ret = dbp->verify(dbp, db, subdb, NULL, flags);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db verify");
- dbp = NULL;
-error:
- if (errf != NULL && errf != stdout && errf != stderr)
- (void)fclose(errf);
- if (errpfx != NULL)
- __os_free(dbenv->env, errpfx);
- if (dbp)
- (void)dbp->close(dbp, 0);
- return (result);
-}
-#endif
-
-/*
- * bdb_Version --
- * Implements the version command.
- */
-static int
-bdb_Version(interp, objc, objv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *bdbver[] = {
- "-string", NULL
- };
- enum bdbver {
- TCL_VERSTRING
- };
- int i, optindex, maj, min, patch, result, string, verobjc;
- char *arg, *v;
- Tcl_Obj *res, *verobjv[3];
-
- result = TCL_OK;
- string = 0;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args?");
- return (TCL_ERROR);
- }
-
- /*
- * We must first parse for the environment flag, since that
- * is needed for db_create. Then create the db handle.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], bdbver,
- "option", TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto error;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum bdbver)optindex) {
- case TCL_VERSTRING:
- string = 1;
- break;
- }
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- }
- if (result != TCL_OK)
- goto error;
-
- v = db_version(&maj, &min, &patch);
- if (string)
- res = NewStringObj(v, strlen(v));
- else {
- verobjc = 3;
- verobjv[0] = Tcl_NewIntObj(maj);
- verobjv[1] = Tcl_NewIntObj(min);
- verobjv[2] = Tcl_NewIntObj(patch);
- res = Tcl_NewListObj(verobjc, verobjv);
- }
- Tcl_SetObjResult(interp, res);
-error:
- return (result);
-}
-
-#ifdef CONFIG_TEST
-/*
- * bdb_GetConfig --
- * Implements the getconfig command.
- */
-#define ADD_CONFIG_NAME(name) \
- conf = NewStringObj(name, strlen(name)); \
- if (Tcl_ListObjAppendElement(interp, res, conf) != TCL_OK) \
- return (TCL_ERROR);
-
-static int
-bdb_GetConfig(interp, objc, objv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- Tcl_Obj *res, *conf;
-
- /*
- * No args. Error if we have some
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "");
- return (TCL_ERROR);
- }
- res = Tcl_NewListObj(0, NULL);
- conf = NULL;
-
- /*
- * This command conditionally adds strings in based on
- * how DB is configured so that the test suite can make
- * decisions based on that. For now only implement the
- * configuration pieces we need.
- */
-#ifdef DEBUG
- ADD_CONFIG_NAME("debug");
-#endif
-#ifdef DEBUG_ROP
- ADD_CONFIG_NAME("debug_rop");
-#endif
-#ifdef DEBUG_WOP
- ADD_CONFIG_NAME("debug_wop");
-#endif
-#ifdef DIAGNOSTIC
- ADD_CONFIG_NAME("diagnostic");
-#endif
-#ifdef HAVE_PARTITION
- ADD_CONFIG_NAME("partition");
-#endif
-#ifdef HAVE_HASH
- ADD_CONFIG_NAME("hash");
-#endif
-#ifdef HAVE_QUEUE
- ADD_CONFIG_NAME("queue");
-#endif
-#ifdef HAVE_REPLICATION
- ADD_CONFIG_NAME("rep");
-#endif
-#ifdef HAVE_REPLICATION_THREADS
- ADD_CONFIG_NAME("repmgr");
-#endif
-#ifdef HAVE_RPC
- ADD_CONFIG_NAME("rpc");
-#endif
-#ifdef HAVE_VERIFY
- ADD_CONFIG_NAME("verify");
-#endif
- Tcl_SetObjResult(interp, res);
- return (TCL_OK);
-}
-
-/*
- * bdb_Handles --
- * Implements the handles command.
- */
-static int
-bdb_Handles(interp, objc, objv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- DBTCL_INFO *p;
- Tcl_Obj *res, *handle;
-
- /*
- * No args. Error if we have some
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "");
- return (TCL_ERROR);
- }
- res = Tcl_NewListObj(0, NULL);
-
- LIST_FOREACH(p, &__db_infohead, entries) {
- handle = NewStringObj(p->i_name, strlen(p->i_name));
- if (Tcl_ListObjAppendElement(interp, res, handle) != TCL_OK)
- return (TCL_ERROR);
- }
- Tcl_SetObjResult(interp, res);
- return (TCL_OK);
-}
-
-/*
- * bdb_MsgType -
- * Implements the msgtype command.
- * Given a replication message return its message type name.
- */
-static int
-bdb_MsgType(interp, objc, objv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- __rep_control_args *rp;
- Tcl_Obj *msgname;
- u_int32_t len, msgtype, swaptype;
- int freerp, ret;
-
- /*
- * If the messages in rep.h change, this must change too!
- * Add "no_type" for 0 so that we directly index.
- */
- static const char *msgnames[] = {
- "no_type", "alive", "alive_req", "all_req",
- "bulk_log", "bulk_page",
- "dupmaster", "file", "file_fail", "file_req", "lease_grant",
- "log", "log_more", "log_req", "master_req", "newclient",
- "newfile", "newmaster", "newsite", "page",
- "page_fail", "page_more", "page_req",
- "rerequest", "startsync", "update", "update_req",
- "verify", "verify_fail", "verify_req",
- "vote1", "vote2", NULL
- };
-
- /*
- * 1 arg, the message. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, "msgtype msg");
- return (TCL_ERROR);
- }
-
- ret = _CopyObjBytes(interp, objv[2], &rp, &len, &freerp);
- if (ret != TCL_OK) {
- Tcl_SetResult(interp,
- "msgtype: bad control message", TCL_STATIC);
- return (TCL_ERROR);
- }
- swaptype = msgtype = rp->rectype;
- /*
- * We have no DB_ENV or ENV here. The message type may be
- * swapped. Get both and use the one that is in the message range.
- */
- M_32_SWAP(swaptype);
- if (msgtype > REP_MAX_MSG && swaptype <= REP_MAX_MSG)
- msgtype = swaptype;
- msgname = NewStringObj(msgnames[msgtype], strlen(msgnames[msgtype]));
- Tcl_SetObjResult(interp, msgname);
- if (rp != NULL && freerp)
- __os_free(NULL, rp);
- return (TCL_OK);
-}
-
-/*
- * bdb_DbUpgrade --
- * Implements the DB->upgrade command.
- */
-static int
-bdb_DbUpgrade(interp, objc, objv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *bdbupg[] = {
- "-dupsort", "-env", "--", NULL
- };
- enum bdbupg {
- TCL_DBUPG_DUPSORT,
- TCL_DBUPG_ENV,
- TCL_DBUPG_ENDARG
- };
- DB_ENV *dbenv;
- DB *dbp;
- u_int32_t flags;
- int endarg, i, optindex, result, ret;
- char *arg, *db;
-
- dbenv = NULL;
- dbp = NULL;
- result = TCL_OK;
- db = NULL;
- flags = endarg = 0;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args? filename");
- return (TCL_ERROR);
- }
-
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], bdbupg,
- "option", TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto error;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum bdbupg)optindex) {
- case TCL_DBUPG_DUPSORT:
- flags |= DB_DUPSORT;
- break;
- case TCL_DBUPG_ENV:
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- dbenv = NAME_TO_ENV(arg);
- if (dbenv == NULL) {
- Tcl_SetResult(interp,
- "db upgrade: illegal environment",
- TCL_STATIC);
- return (TCL_ERROR);
- }
- break;
- case TCL_DBUPG_ENDARG:
- endarg = 1;
- break;
- }
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- if (endarg)
- break;
- }
- if (result != TCL_OK)
- goto error;
- /*
- * The remaining arg is the db filename.
- */
- if (i == (objc - 1))
- db = Tcl_GetStringFromObj(objv[i++], NULL);
- else {
- Tcl_WrongNumArgs(interp, 2, objv, "?args? filename");
- result = TCL_ERROR;
- goto error;
- }
- ret = db_create(&dbp, dbenv, 0);
- if (ret) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db_create");
- goto error;
- }
-
- /*
- * XXX
- * Remove restriction if error handling not tied to env.
- *
- * The DB->set_err* functions overwrite the environment. So, if
- * we are using an env, don't overwrite it; if not using an env,
- * then configure error handling.
- */
- if (dbenv == NULL) {
- dbp->set_errpfx(dbp, "DbUpgrade");
- dbp->set_errcall(dbp, _ErrorFunc);
- }
- ret = dbp->upgrade(dbp, db, flags);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db upgrade");
-error:
- if (dbp)
- (void)dbp->close(dbp, 0);
- return (result);
-}
-
-/*
- * tcl_bt_compare and tcl_dup_compare --
- * These two are basically identical internally, so may as well
- * share code. The only differences are the name used in error
- * reporting and the Tcl_Obj representing their respective procs.
- */
-static int
-tcl_bt_compare(dbp, dbta, dbtb)
- DB *dbp;
- const DBT *dbta, *dbtb;
-{
- return (tcl_compare_callback(dbp, dbta, dbtb,
- ((DBTCL_INFO *)dbp->api_internal)->i_compare, "bt_compare"));
-}
-
-static int
-tcl_dup_compare(dbp, dbta, dbtb)
- DB *dbp;
- const DBT *dbta, *dbtb;
-{
- return (tcl_compare_callback(dbp, dbta, dbtb,
- ((DBTCL_INFO *)dbp->api_internal)->i_dupcompare, "dup_compare"));
-}
-
-/*
- * tcl_compare_callback --
- * Tcl callback for set_bt_compare and set_dup_compare. What this
- * function does is stuff the data fields of the two DBTs into Tcl ByteArray
- * objects, then call the procedure stored in ip->i_compare on the two
- * objects. Then we return that procedure's result as the comparison.
- */
-static int
-tcl_compare_callback(dbp, dbta, dbtb, procobj, errname)
- DB *dbp;
- const DBT *dbta, *dbtb;
- Tcl_Obj *procobj;
- char *errname;
-{
- DBTCL_INFO *ip;
- Tcl_Interp *interp;
- Tcl_Obj *a, *b, *resobj, *objv[3];
- int result, cmp;
-
- ip = (DBTCL_INFO *)dbp->api_internal;
- interp = ip->i_interp;
- objv[0] = procobj;
-
- /*
- * Create two ByteArray objects, with the two data we've been passed.
- * This will involve a copy, which is unpleasantly slow, but there's
- * little we can do to avoid this (I think).
- */
- a = Tcl_NewByteArrayObj(dbta->data, (int)dbta->size);
- Tcl_IncrRefCount(a);
- b = Tcl_NewByteArrayObj(dbtb->data, (int)dbtb->size);
- Tcl_IncrRefCount(b);
-
- objv[1] = a;
- objv[2] = b;
-
- result = Tcl_EvalObjv(interp, 3, objv, 0);
- if (result != TCL_OK) {
- /*
- * XXX
- * If this or the next Tcl call fails, we're doomed.
- * There's no way to return an error from comparison functions,
- * no way to determine what the correct sort order is, and
- * so no way to avoid corrupting the database if we proceed.
- * We could play some games stashing return values on the
- * DB handle, but it's not worth the trouble--no one with
- * any sense is going to be using this other than for testing,
- * and failure typically means that the bt_compare proc
- * had a syntax error in it or something similarly dumb.
- *
- * So, drop core. If we're not running with diagnostic
- * mode, panic--and always return a negative number. :-)
- */
-panic: __db_errx(dbp->env, "Tcl %s callback failed", errname);
- return (__env_panic(dbp->env, DB_RUNRECOVERY));
- }
-
- resobj = Tcl_GetObjResult(interp);
- result = Tcl_GetIntFromObj(interp, resobj, &cmp);
- if (result != TCL_OK)
- goto panic;
-
- Tcl_DecrRefCount(a);
- Tcl_DecrRefCount(b);
- return (cmp);
-}
-
-/*
- * tcl_h_hash --
- * Tcl callback for the hashing function. See tcl_compare_callback--
- * this works much the same way, only we're given a buffer and a length
- * instead of two DBTs.
- */
-static u_int32_t
-tcl_h_hash(dbp, buf, len)
- DB *dbp;
- const void *buf;
- u_int32_t len;
-{
- DBTCL_INFO *ip;
- Tcl_Interp *interp;
- Tcl_Obj *objv[2];
- int result, hval;
-
- ip = (DBTCL_INFO *)dbp->api_internal;
- interp = ip->i_interp;
- objv[0] = ip->i_hashproc;
-
- /*
- * Create a ByteArray for the buffer.
- */
- objv[1] = Tcl_NewByteArrayObj((void *)buf, (int)len);
- Tcl_IncrRefCount(objv[1]);
- result = Tcl_EvalObjv(interp, 2, objv, 0);
- if (result != TCL_OK)
- goto panic;
-
- result = Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &hval);
- if (result != TCL_OK)
- goto panic;
-
- Tcl_DecrRefCount(objv[1]);
- return ((u_int32_t)hval);
-
-panic: __db_errx(dbp->env, "Tcl h_hash callback failed");
-
- (void)__env_panic(dbp->env, DB_RUNRECOVERY);
- return (0);
-}
-
-static int
-tcl_isalive(dbenv, pid, tid, flags)
- DB_ENV *dbenv;
- pid_t pid;
- db_threadid_t tid;
- u_int32_t flags;
-{
- ENV *env;
- DBTCL_INFO *ip;
- Tcl_Interp *interp;
- Tcl_Obj *objv[2];
- pid_t mypid;
- db_threadid_t mytid;
- int answer, result;
-
- __os_id(dbenv, &mypid, &mytid);
- if (mypid == pid && (LF_ISSET(DB_MUTEX_PROCESS_ONLY) ||
- mytid == tid))
- return (1);
- /*
- * We only support the PROCESS_ONLY case for now, because that seems
- * easiest, and that's all we need for our tests for the moment.
- */
- if (!LF_ISSET(DB_MUTEX_PROCESS_ONLY))
- return (1);
-
- ip = (DBTCL_INFO *)dbenv->app_private;
- interp = ip->i_interp;
- objv[0] = ip->i_isalive;
-
- objv[1] = Tcl_NewLongObj((long)pid);
- Tcl_IncrRefCount(objv[1]);
-
- result = Tcl_EvalObjv(interp, 2, objv, 0);
- if (result != TCL_OK)
- goto panic;
- Tcl_DecrRefCount(objv[1]);
- result = Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &answer);
- if (result != TCL_OK)
- goto panic;
-
- return (answer);
-
-panic:
- env = dbenv->env;
- __db_errx(env, "Tcl isalive callback failed: %s",
- Tcl_GetStringResult(interp));
-
- (void)__env_panic(env, DB_RUNRECOVERY);
- return (0);
-}
-
-/*
- * tcl_part_callback --
- */
-static u_int32_t
-tcl_part_callback(dbp, data)
- DB *dbp;
- DBT *data;
-{
- DBTCL_INFO *ip;
- Tcl_Interp *interp;
- Tcl_Obj *objv[2];
- int result, hval;
-
- ip = (DBTCL_INFO *)dbp->api_internal;
- interp = ip->i_interp;
- objv[0] = ip->i_part_callback;
-
- objv[1] = Tcl_NewByteArrayObj(data->data, (int)data->size);
- Tcl_IncrRefCount(objv[1]);
-
- result = Tcl_EvalObjv(interp, 2, objv, 0);
- if (result != TCL_OK)
- goto panic;
-
- result = Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &hval);
- if (result != TCL_OK)
- goto panic;
-
- Tcl_DecrRefCount(objv[1]);
- return ((u_int32_t)hval);
-
-panic: __db_errx(dbp->env, "Tcl part_callback callback failed");
-
- (void)__env_panic(dbp->env, DB_RUNRECOVERY);
- return (0);
-}
-
-/*
- * tcl_rep_send --
- * Replication send callback.
- *
- * PUBLIC: int tcl_rep_send __P((DB_ENV *,
- * PUBLIC: const DBT *, const DBT *, const DB_LSN *, int, u_int32_t));
- */
-int
-tcl_rep_send(dbenv, control, rec, lsnp, eid, flags)
- DB_ENV *dbenv;
- const DBT *control, *rec;
- const DB_LSN *lsnp;
- int eid;
- u_int32_t flags;
-{
-#define TCLDB_SENDITEMS 7
-#define TCLDB_MAXREPFLAGS 32
- DBTCL_INFO *ip;
- Tcl_Interp *interp;
- Tcl_Obj *control_o, *eid_o, *flags_o, *lsn_o, *origobj, *rec_o;
- Tcl_Obj *lsnobj[2], *myobjv[TCLDB_MAXREPFLAGS], *objv[TCLDB_SENDITEMS];
- Tcl_Obj *resobj;
- int i, myobjc, result, ret;
-
- ip = (DBTCL_INFO *)dbenv->app_private;
- interp = ip->i_interp;
- objv[0] = ip->i_rep_send;
-
- control_o = Tcl_NewByteArrayObj(control->data, (int)control->size);
- Tcl_IncrRefCount(control_o);
-
- rec_o = Tcl_NewByteArrayObj(rec->data, (int)rec->size);
- Tcl_IncrRefCount(rec_o);
-
- eid_o = Tcl_NewIntObj(eid);
- Tcl_IncrRefCount(eid_o);
-
- myobjv[myobjc = 0] = NULL;
- if (flags == 0)
- myobjv[myobjc++] = NewStringObj("none", strlen("none"));
- if (LF_ISSET(DB_REP_ANYWHERE))
- myobjv[myobjc++] = NewStringObj("any", strlen("any"));
- if (LF_ISSET(DB_REP_NOBUFFER))
- myobjv[myobjc++] = NewStringObj("nobuffer", strlen("nobuffer"));
- if (LF_ISSET(DB_REP_PERMANENT))
- myobjv[myobjc++] = NewStringObj("perm", strlen("perm"));
- if (LF_ISSET(DB_REP_REREQUEST))
- myobjv[myobjc++] =
- NewStringObj("rerequest", strlen("rerequest"));
- /*
- * If we're given an unrecognized flag send "unknown".
- */
- if (myobjc == 0)
- myobjv[myobjc++] = NewStringObj("unknown", strlen("unknown"));
- for (i = 0; i < myobjc; i++)
- Tcl_IncrRefCount(myobjv[i]);
- flags_o = Tcl_NewListObj(myobjc, myobjv);
- Tcl_IncrRefCount(flags_o);
-
- lsnobj[0] = Tcl_NewLongObj((long)lsnp->file);
- Tcl_IncrRefCount(lsnobj[0]);
- lsnobj[1] = Tcl_NewLongObj((long)lsnp->offset);
- Tcl_IncrRefCount(lsnobj[1]);
- lsn_o = Tcl_NewListObj(2, lsnobj);
- Tcl_IncrRefCount(lsn_o);
-
- objv[1] = control_o;
- objv[2] = rec_o;
- objv[3] = ip->i_rep_eid; /* From ID */
- objv[4] = eid_o; /* To ID */
- objv[5] = flags_o; /* Flags */
- objv[6] = lsn_o; /* LSN */
-
- /*
- * We really want to return the original result to the
- * user. So, save the result obj here, and then after
- * we've taken care of the Tcl_EvalObjv, set the result
- * back to this original result.
- */
- origobj = Tcl_GetObjResult(interp);
- Tcl_IncrRefCount(origobj);
- result = Tcl_EvalObjv(interp, TCLDB_SENDITEMS, objv, 0);
- if (result != TCL_OK) {
- /*
- * XXX
- * This probably isn't the right error behavior, but
- * this error should only happen if the Tcl callback is
- * somehow invalid, which is a fatal scripting bug.
- */
-err: __db_errx(dbenv->env,
- "Tcl rep_send failure: %s", Tcl_GetStringResult(interp));
- return (EINVAL);
- }
-
- resobj = Tcl_GetObjResult(interp);
- result = Tcl_GetIntFromObj(interp, resobj, &ret);
- if (result != TCL_OK)
- goto err;
-
- Tcl_SetObjResult(interp, origobj);
- Tcl_DecrRefCount(origobj);
- Tcl_DecrRefCount(control_o);
- Tcl_DecrRefCount(rec_o);
- Tcl_DecrRefCount(eid_o);
- for (i = 0; i < myobjc; i++)
- Tcl_DecrRefCount(myobjv[i]);
- Tcl_DecrRefCount(flags_o);
- Tcl_DecrRefCount(lsnobj[0]);
- Tcl_DecrRefCount(lsnobj[1]);
- Tcl_DecrRefCount(lsn_o);
-
- return (ret);
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_db_malloc, tcl_db_realloc, tcl_db_free --
- * Tcl-local malloc, realloc, and free functions to use for user data
- * to exercise umalloc/urealloc/ufree. Allocate the memory as a Tcl object
- * so we're sure to exacerbate and catch any shared-library issues.
- */
-static void *
-tcl_db_malloc(size)
- size_t size;
-{
- Tcl_Obj *obj;
- void *buf;
-
- obj = Tcl_NewObj();
- if (obj == NULL)
- return (NULL);
- Tcl_IncrRefCount(obj);
-
- Tcl_SetObjLength(obj, (int)(size + sizeof(Tcl_Obj *)));
- buf = Tcl_GetString(obj);
- memcpy(buf, &obj, sizeof(&obj));
-
- buf = (Tcl_Obj **)buf + 1;
- return (buf);
-}
-
-static void *
-tcl_db_realloc(ptr, size)
- void *ptr;
- size_t size;
-{
- Tcl_Obj *obj;
-
- if (ptr == NULL)
- return (tcl_db_malloc(size));
-
- obj = *(Tcl_Obj **)((Tcl_Obj **)ptr - 1);
- Tcl_SetObjLength(obj, (int)(size + sizeof(Tcl_Obj *)));
-
- ptr = Tcl_GetString(obj);
- memcpy(ptr, &obj, sizeof(&obj));
-
- ptr = (Tcl_Obj **)ptr + 1;
- return (ptr);
-}
-
-static void
-tcl_db_free(ptr)
- void *ptr;
-{
- Tcl_Obj *obj;
-
- obj = *(Tcl_Obj **)((Tcl_Obj **)ptr - 1);
- Tcl_DecrRefCount(obj);
-}
-
-static int
-tcl_set_partition_keys(interp, dbp, obj, keyp)
- Tcl_Interp *interp;
- DB *dbp;
- Tcl_Obj *obj;
- DBT **keyp;
-{
- DBT *keys, *kp;
- Tcl_Obj **obj_list;
- u_int32_t i, count;
- int ret;
-
- *keyp = NULL;
- if ((ret = Tcl_ListObjGetElements(interp,
- obj, (int *)&count, &obj_list)) != TCL_OK)
- return (EINVAL);
-
- if ((ret = __os_calloc(NULL, count, sizeof(DBT), &keys)) != 0)
- return (ret);
-
- *keyp = keys;
-
- kp = keys;
- for (i = 0; i < count; i++, kp++)
- kp->data = Tcl_GetStringFromObj(obj_list[i], (int*)&kp->size);
-
- if ((ret = dbp->set_partition(dbp,
- (u_int32_t)count + 1, keys, NULL)) != 0)
- return (ret);
-
- return (0);
-}
-
-static int
-tcl_set_partition_dirs(interp, dbp, obj)
- Tcl_Interp *interp;
- DB *dbp;
- Tcl_Obj *obj;
-{
- char **dp, **dirs;
- Tcl_Obj **obj_list;
- u_int32_t i, count;
- int ret;
-
- if ((ret = Tcl_ListObjGetElements(interp,
- obj, (int*)&count, &obj_list)) != TCL_OK)
- return (EINVAL);
-
- if ((ret = __os_calloc(NULL, count + 1, sizeof(char *), &dirs)) != 0)
- return (ret);
-
- dp = dirs;
- for (i = 0; i < count; i++, dp++)
- *dp = Tcl_GetStringFromObj(obj_list[i], NULL);
-
- if ((ret = dbp->set_partition_dirs(dbp, (const char **)dirs)) != 0)
- return (ret);
-
- __os_free(NULL, dirs);
-
- return (0);
-}
-#endif
diff --git a/tcl/tcl_dbcursor.c b/tcl/tcl_dbcursor.c
deleted file mode 100644
index 9b943ba..0000000
--- a/tcl/tcl_dbcursor.c
+++ /dev/null
@@ -1,1056 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/tcl_db.h"
-
-/*
- * Prototypes for procedures defined later in this file:
- */
-static int tcl_DbcDup __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *));
-static int tcl_DbcCompare __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *));
-static int tcl_DbcGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *, int));
-static int tcl_DbcPut __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *));
-
-/*
- * PUBLIC: int dbc_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
- *
- * dbc_cmd --
- * Implements the cursor command.
- */
-int
-dbc_Cmd(clientData, interp, objc, objv)
- ClientData clientData; /* Cursor handle */
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *dbccmds[] = {
-#ifdef CONFIG_TEST
- "pget",
-#endif
- "close",
- "cmp",
- "del",
- "dup",
- "get",
- "put",
- NULL
- };
- enum dbccmds {
-#ifdef CONFIG_TEST
- DBCPGET,
-#endif
- DBCCLOSE,
- DBCCOMPARE,
- DBCDELETE,
- DBCDUP,
- DBCGET,
- DBCPUT
- };
- DBC *dbc;
- DBTCL_INFO *dbip;
- int cmdindex, result, ret;
-
- Tcl_ResetResult(interp);
- dbc = (DBC *)clientData;
- dbip = _PtrToInfo((void *)dbc);
- result = TCL_OK;
-
- if (objc <= 1) {
- Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs");
- return (TCL_ERROR);
- }
- if (dbc == NULL) {
- Tcl_SetResult(interp, "NULL dbc pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (dbip == NULL) {
- Tcl_SetResult(interp, "NULL dbc info pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the berkdbcmds
- * defined above.
- */
- if (Tcl_GetIndexFromObj(interp, objv[1], dbccmds, "command",
- TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
- switch ((enum dbccmds)cmdindex) {
-#ifdef CONFIG_TEST
- case DBCPGET:
- result = tcl_DbcGet(interp, objc, objv, dbc, 1);
- break;
-#endif
- case DBCCLOSE:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbc->close(dbc);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "dbc close");
- if (result == TCL_OK) {
- (void)Tcl_DeleteCommand(interp, dbip->i_name);
- _DeleteInfo(dbip);
- }
- break;
- case DBCCOMPARE:
- if (objc > 3) {
- Tcl_WrongNumArgs(interp, 3, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- result = tcl_DbcCompare(interp, objc, objv, dbc);
- break;
- case DBCDELETE:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbc->del(dbc, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_DBCDEL(ret),
- "dbc delete");
- break;
- case DBCDUP:
- result = tcl_DbcDup(interp, objc, objv, dbc);
- break;
- case DBCGET:
- result = tcl_DbcGet(interp, objc, objv, dbc, 0);
- break;
- case DBCPUT:
- result = tcl_DbcPut(interp, objc, objv, dbc);
- break;
- }
- return (result);
-}
-
-/*
- * tcl_DbcPut --
- */
-static int
-tcl_DbcPut(interp, objc, objv, dbc)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DBC *dbc; /* Cursor pointer */
-{
- static const char *dbcutopts[] = {
-#ifdef CONFIG_TEST
- "-nodupdata",
-#endif
- "-after",
- "-before",
- "-current",
- "-keyfirst",
- "-keylast",
- "-overwritedup",
- "-partial",
- NULL
- };
- enum dbcutopts {
-#ifdef CONFIG_TEST
- DBCPUT_NODUPDATA,
-#endif
- DBCPUT_AFTER,
- DBCPUT_BEFORE,
- DBCPUT_CURRENT,
- DBCPUT_KEYFIRST,
- DBCPUT_KEYLAST,
- DBCPUT_OVERWRITE_DUP,
- DBCPUT_PART
- };
- DB *thisdbp;
- DBT key, data;
- DBTCL_INFO *dbcip, *dbip;
- DBTYPE type;
- Tcl_Obj **elemv, *res;
- void *dtmp, *ktmp;
- db_recno_t recno;
- u_int32_t flag;
- int elemc, freekey, freedata, i, optindex, result, ret;
-
- COMPQUIET(dtmp, NULL);
- COMPQUIET(ktmp, NULL);
-
- result = TCL_OK;
- flag = 0;
- freekey = freedata = 0;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-args? ?key?");
- return (TCL_ERROR);
- }
-
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
-
- /*
- * Get the command name index from the object based on the options
- * defined above.
- */
- i = 2;
- while (i < (objc - 1)) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbcutopts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- /*
- * Reset the result so we don't get
- * an errant error message if there is another error.
- */
- if (IS_HELP(objv[i]) == TCL_OK) {
- result = TCL_OK;
- goto out;
- }
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum dbcutopts)optindex) {
-#ifdef CONFIG_TEST
- case DBCPUT_NODUPDATA:
- FLAG_CHECK(flag);
- flag = DB_NODUPDATA;
- break;
-#endif
- case DBCPUT_AFTER:
- FLAG_CHECK(flag);
- flag = DB_AFTER;
- break;
- case DBCPUT_BEFORE:
- FLAG_CHECK(flag);
- flag = DB_BEFORE;
- break;
- case DBCPUT_CURRENT:
- FLAG_CHECK(flag);
- flag = DB_CURRENT;
- break;
- case DBCPUT_KEYFIRST:
- FLAG_CHECK(flag);
- flag = DB_KEYFIRST;
- break;
- case DBCPUT_KEYLAST:
- FLAG_CHECK(flag);
- flag = DB_KEYLAST;
- break;
- case DBCPUT_OVERWRITE_DUP:
- FLAG_CHECK(flag);
- flag = DB_OVERWRITE_DUP;
- break;
- case DBCPUT_PART:
- if (i > (objc - 2)) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-partial {offset length}?");
- result = TCL_ERROR;
- break;
- }
- /*
- * Get sublist as {offset length}
- */
- result = Tcl_ListObjGetElements(interp, objv[i++],
- &elemc, &elemv);
- if (elemc != 2) {
- Tcl_SetResult(interp,
- "List must be {offset length}", TCL_STATIC);
- result = TCL_ERROR;
- break;
- }
- data.flags |= DB_DBT_PARTIAL;
- result = _GetUInt32(interp, elemv[0], &data.doff);
- if (result != TCL_OK)
- break;
- result = _GetUInt32(interp, elemv[1], &data.dlen);
- /*
- * NOTE: We don't check result here because all we'd
- * do is break anyway, and we are doing that. If you
- * add code here, you WILL need to add the check
- * for result. (See the check for save.doff, a few
- * lines above and copy that.)
- */
- }
- if (result != TCL_OK)
- break;
- }
- if (result != TCL_OK)
- goto out;
-
- /*
- * We need to determine if we are a recno database or not. If we are,
- * then key.data is a recno, not a string.
- */
- dbcip = _PtrToInfo(dbc);
- if (dbcip == NULL)
- type = DB_UNKNOWN;
- else {
- dbip = dbcip->i_parent;
- if (dbip == NULL) {
- Tcl_SetResult(interp, "Cursor without parent database",
- TCL_STATIC);
- result = TCL_ERROR;
- return (result);
- }
- thisdbp = dbip->i_dbp;
- (void)thisdbp->get_type(thisdbp, &type);
- }
- /*
- * When we get here, we better have:
- * 1 arg if -after, -before or -current
- * 2 args in all other cases
- */
- if (flag == DB_AFTER || flag == DB_BEFORE || flag == DB_CURRENT) {
- if (i != (objc - 1)) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-args? data");
- result = TCL_ERROR;
- goto out;
- }
- /*
- * We want to get the key back, so we need to set
- * up the location to get it back in.
- */
- if (type == DB_RECNO || type == DB_QUEUE) {
- recno = 0;
- key.data = &recno;
- key.size = sizeof(db_recno_t);
- }
- } else {
- if (i != (objc - 2)) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-args? key data");
- result = TCL_ERROR;
- goto out;
- }
- if (type == DB_RECNO || type == DB_QUEUE) {
- result = _GetUInt32(interp, objv[objc-2], &recno);
- if (result == TCL_OK) {
- key.data = &recno;
- key.size = sizeof(db_recno_t);
- } else
- return (result);
- } else {
- ret = _CopyObjBytes(interp, objv[objc-2], &ktmp,
- &key.size, &freekey);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBCPUT(ret), "dbc put");
- return (result);
- }
- key.data = ktmp;
- }
- }
- ret = _CopyObjBytes(interp, objv[objc-1], &dtmp,
- &data.size, &freedata);
- data.data = dtmp;
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBCPUT(ret), "dbc put");
- goto out;
- }
- _debug_check();
- ret = dbc->put(dbc, &key, &data, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_DBCPUT(ret),
- "dbc put");
- if (ret == 0 &&
- (flag == DB_AFTER || flag == DB_BEFORE) && type == DB_RECNO) {
- res = Tcl_NewWideIntObj((Tcl_WideInt)*(db_recno_t *)key.data);
- Tcl_SetObjResult(interp, res);
- }
-out:
- if (freedata)
- __os_free(NULL, dtmp);
- if (freekey)
- __os_free(NULL, ktmp);
- return (result);
-}
-
-/*
- * tcl_dbc_get --
- */
-static int
-tcl_DbcGet(interp, objc, objv, dbc, ispget)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DBC *dbc; /* Cursor pointer */
- int ispget; /* 1 for pget, 0 for get */
-{
- static const char *dbcgetopts[] = {
-#ifdef CONFIG_TEST
- "-data_buf_size",
- "-get_both_range",
- "-key_buf_size",
- "-multi",
- "-multi_key",
- "-nolease",
- "-read_committed",
- "-read_uncommitted",
-#endif
- "-current",
- "-first",
- "-get_both",
- "-get_recno",
- "-join_item",
- "-last",
- "-next",
- "-nextdup",
- "-nextnodup",
- "-partial",
- "-prev",
- "-prevdup",
- "-prevnodup",
- "-rmw",
- "-set",
- "-set_range",
- "-set_recno",
- NULL
- };
- enum dbcgetopts {
-#ifdef CONFIG_TEST
- DBCGET_DATA_BUF_SIZE,
- DBCGET_BOTH_RANGE,
- DBCGET_KEY_BUF_SIZE,
- DBCGET_MULTI,
- DBCGET_MULTI_KEY,
- DBCGET_NOLEASE,
- DBCGET_READ_COMMITTED,
- DBCGET_READ_UNCOMMITTED,
-#endif
- DBCGET_CURRENT,
- DBCGET_FIRST,
- DBCGET_BOTH,
- DBCGET_RECNO,
- DBCGET_JOIN,
- DBCGET_LAST,
- DBCGET_NEXT,
- DBCGET_NEXTDUP,
- DBCGET_NEXTNODUP,
- DBCGET_PART,
- DBCGET_PREV,
- DBCGET_PREVDUP,
- DBCGET_PREVNODUP,
- DBCGET_RMW,
- DBCGET_SET,
- DBCGET_SETRANGE,
- DBCGET_SETRECNO
- };
- DB *thisdbp;
- DBT key, data, pdata;
- DBTCL_INFO *dbcip, *dbip;
- DBTYPE ptype, type;
- Tcl_Obj **elemv, *myobj, *retlist;
- void *dtmp, *ktmp;
- db_recno_t precno, recno;
- u_int32_t flag, op;
- int elemc, freekey, freedata, i, optindex, result, ret;
-#ifdef CONFIG_TEST
- int data_buf_size, key_buf_size;
-
- data_buf_size = key_buf_size = 0;
-#endif
- COMPQUIET(dtmp, NULL);
- COMPQUIET(ktmp, NULL);
-
- result = TCL_OK;
- flag = 0;
- freekey = freedata = 0;
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- memset(&pdata, 0, sizeof(DBT));
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-args? ?key?");
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the options
- * defined above.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbcgetopts,
- "option", TCL_EXACT, &optindex) != TCL_OK) {
- /*
- * Reset the result so we don't get
- * an errant error message if there is another error.
- */
- if (IS_HELP(objv[i]) == TCL_OK) {
- result = TCL_OK;
- goto out;
- }
- Tcl_ResetResult(interp);
- break;
- }
- i++;
-
-#define FLAG_CHECK2_STDARG \
- (DB_RMW | DB_MULTIPLE | DB_MULTIPLE_KEY | DB_IGNORE_LEASE | \
- DB_READ_UNCOMMITTED | DB_READ_COMMITTED)
-
- switch ((enum dbcgetopts)optindex) {
-#ifdef CONFIG_TEST
- case DBCGET_DATA_BUF_SIZE:
- result =
- Tcl_GetIntFromObj(interp, objv[i], &data_buf_size);
- if (result != TCL_OK)
- goto out;
- i++;
- break;
- case DBCGET_BOTH_RANGE:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_GET_BOTH_RANGE;
- break;
- case DBCGET_KEY_BUF_SIZE:
- result =
- Tcl_GetIntFromObj(interp, objv[i], &key_buf_size);
- if (result != TCL_OK)
- goto out;
- i++;
- break;
- case DBCGET_MULTI:
- flag |= DB_MULTIPLE;
- result =
- Tcl_GetIntFromObj(interp, objv[i], &data_buf_size);
- if (result != TCL_OK)
- goto out;
- i++;
- break;
- case DBCGET_MULTI_KEY:
- flag |= DB_MULTIPLE_KEY;
- result =
- Tcl_GetIntFromObj(interp, objv[i], &data_buf_size);
- if (result != TCL_OK)
- goto out;
- i++;
- break;
- case DBCGET_NOLEASE:
- flag |= DB_IGNORE_LEASE;
- break;
- case DBCGET_READ_COMMITTED:
- flag |= DB_READ_COMMITTED;
- break;
- case DBCGET_READ_UNCOMMITTED:
- flag |= DB_READ_UNCOMMITTED;
- break;
-#endif
- case DBCGET_RMW:
- flag |= DB_RMW;
- break;
- case DBCGET_CURRENT:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_CURRENT;
- break;
- case DBCGET_FIRST:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_FIRST;
- break;
- case DBCGET_LAST:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_LAST;
- break;
- case DBCGET_NEXT:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_NEXT;
- break;
- case DBCGET_PREV:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_PREV;
- break;
- case DBCGET_PREVDUP:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_PREV_DUP;
- break;
- case DBCGET_PREVNODUP:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_PREV_NODUP;
- break;
- case DBCGET_NEXTNODUP:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_NEXT_NODUP;
- break;
- case DBCGET_NEXTDUP:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_NEXT_DUP;
- break;
- case DBCGET_BOTH:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_GET_BOTH;
- break;
- case DBCGET_RECNO:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_GET_RECNO;
- break;
- case DBCGET_JOIN:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_JOIN_ITEM;
- break;
- case DBCGET_SET:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_SET;
- break;
- case DBCGET_SETRANGE:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_SET_RANGE;
- break;
- case DBCGET_SETRECNO:
- FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
- flag |= DB_SET_RECNO;
- break;
- case DBCGET_PART:
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-partial {offset length}?");
- result = TCL_ERROR;
- break;
- }
- /*
- * Get sublist as {offset length}
- */
- result = Tcl_ListObjGetElements(interp, objv[i++],
- &elemc, &elemv);
- if (elemc != 2) {
- Tcl_SetResult(interp,
- "List must be {offset length}", TCL_STATIC);
- result = TCL_ERROR;
- break;
- }
- data.flags |= DB_DBT_PARTIAL;
- result = _GetUInt32(interp, elemv[0], &data.doff);
- if (result != TCL_OK)
- break;
- result = _GetUInt32(interp, elemv[1], &data.dlen);
- /*
- * NOTE: We don't check result here because all we'd
- * do is break anyway, and we are doing that. If you
- * add code here, you WILL need to add the check
- * for result. (See the check for save.doff, a few
- * lines above and copy that.)
- */
- break;
- }
- if (result != TCL_OK)
- break;
- }
- if (result != TCL_OK)
- goto out;
-
- /*
- * We need to determine if we are a recno database
- * or not. If we are, then key.data is a recno, not
- * a string.
- */
- dbcip = _PtrToInfo(dbc);
- if (dbcip == NULL) {
- type = DB_UNKNOWN;
- ptype = DB_UNKNOWN;
- } else {
- dbip = dbcip->i_parent;
- if (dbip == NULL) {
- Tcl_SetResult(interp, "Cursor without parent database",
- TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- }
- thisdbp = dbip->i_dbp;
- (void)thisdbp->get_type(thisdbp, &type);
- if (ispget && thisdbp->s_primary != NULL)
- (void)thisdbp->
- s_primary->get_type(thisdbp->s_primary, &ptype);
- else
- ptype = DB_UNKNOWN;
- }
- /*
- * When we get here, we better have:
- * 2 args, key and data if GET_BOTH/GET_BOTH_RANGE was specified.
- * 1 arg if -set, -set_range or -set_recno
- * 0 in all other cases.
- */
- op = flag & DB_OPFLAGS_MASK;
- switch (op) {
- case DB_GET_BOTH:
-#ifdef CONFIG_TEST
- case DB_GET_BOTH_RANGE:
-#endif
- if (i != (objc - 2)) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-args? -get_both key data");
- result = TCL_ERROR;
- goto out;
- } else {
- if (type == DB_RECNO || type == DB_QUEUE) {
- result = _GetUInt32(
- interp, objv[objc-2], &recno);
- if (result == TCL_OK) {
- key.data = &recno;
- key.size = sizeof(db_recno_t);
- } else
- goto out;
- } else {
- /*
- * Some get calls (SET_*) can change the
- * key pointers. So, we need to store
- * the allocated key space in a tmp.
- */
- ret = _CopyObjBytes(interp, objv[objc-2],
- &ktmp, &key.size, &freekey);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBCGET(ret), "dbc get");
- return (result);
- }
- key.data = ktmp;
- }
- if (ptype == DB_RECNO || ptype == DB_QUEUE) {
- result = _GetUInt32(
- interp, objv[objc-1], &precno);
- if (result == TCL_OK) {
- data.data = &precno;
- data.size = sizeof(db_recno_t);
- } else
- goto out;
- } else {
- ret = _CopyObjBytes(interp, objv[objc-1],
- &dtmp, &data.size, &freedata);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBCGET(ret), "dbc get");
- goto out;
- }
- data.data = dtmp;
- }
- }
- break;
- case DB_SET:
- case DB_SET_RANGE:
- case DB_SET_RECNO:
- if (i != (objc - 1)) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-args? key");
- result = TCL_ERROR;
- goto out;
- }
-#ifdef CONFIG_TEST
- if (data_buf_size != 0) {
- (void)__os_malloc(
- NULL, (size_t)data_buf_size, &data.data);
- data.ulen = (u_int32_t)data_buf_size;
- data.flags |= DB_DBT_USERMEM;
- } else
-#endif
- data.flags |= DB_DBT_MALLOC;
- if (op == DB_SET_RECNO ||
- type == DB_RECNO || type == DB_QUEUE) {
- result = _GetUInt32(interp, objv[objc - 1], &recno);
- key.data = &recno;
- key.size = sizeof(db_recno_t);
- } else {
- /*
- * Some get calls (SET_*) can change the
- * key pointers. So, we need to store
- * the allocated key space in a tmp.
- */
- ret = _CopyObjBytes(interp, objv[objc-1],
- &ktmp, &key.size, &freekey);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_DBCGET(ret), "dbc get");
- return (result);
- }
- key.data = ktmp;
- }
- break;
- default:
- if (i != objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-args?");
- result = TCL_ERROR;
- goto out;
- }
-#ifdef CONFIG_TEST
- if (key_buf_size != 0) {
- (void)__os_malloc(
- NULL, (size_t)key_buf_size, &key.data);
- key.ulen = (u_int32_t)key_buf_size;
- key.flags |= DB_DBT_USERMEM;
- } else
-#endif
- key.flags |= DB_DBT_MALLOC;
-#ifdef CONFIG_TEST
- if (data_buf_size != 0) {
- (void)__os_malloc(
- NULL, (size_t)data_buf_size, &data.data);
- data.ulen = (u_int32_t)data_buf_size;
- data.flags |= DB_DBT_USERMEM;
- } else
-#endif
- data.flags |= DB_DBT_MALLOC;
- }
-
- _debug_check();
- if (ispget) {
- F_SET(&pdata, DB_DBT_MALLOC);
- ret = dbc->pget(dbc, &key, &data, &pdata, flag);
- } else
- ret = dbc->get(dbc, &key, &data, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_DBCGET(ret), "dbc get");
- if (result == TCL_ERROR)
- goto out;
-
- retlist = Tcl_NewListObj(0, NULL);
- if (ret != 0)
- goto out1;
- if (op == DB_GET_RECNO) {
- recno = *((db_recno_t *)data.data);
- myobj = Tcl_NewWideIntObj((Tcl_WideInt)recno);
- result = Tcl_ListObjAppendElement(interp, retlist, myobj);
- } else {
- if (flag & (DB_MULTIPLE|DB_MULTIPLE_KEY))
- result = _SetMultiList(interp,
- retlist, &key, &data, type, flag);
- else if ((type == DB_RECNO || type == DB_QUEUE) &&
- key.data != NULL) {
- if (ispget)
- result = _Set3DBTList(interp, retlist, &key, 1,
- &data,
- (ptype == DB_RECNO || ptype == DB_QUEUE),
- &pdata);
- else
- result = _SetListRecnoElem(interp, retlist,
- *(db_recno_t *)key.data,
- data.data, data.size);
- } else {
- if (ispget)
- result = _Set3DBTList(interp, retlist, &key, 0,
- &data,
- (ptype == DB_RECNO || ptype == DB_QUEUE),
- &pdata);
- else
- result = _SetListElem(interp, retlist,
- key.data, key.size, data.data, data.size);
- }
- }
-out1:
- if (result == TCL_OK)
- Tcl_SetObjResult(interp, retlist);
- /*
- * If DB_DBT_MALLOC is set we need to free if DB allocated anything.
- * If DB_DBT_USERMEM is set we need to free it because
- * we allocated it (for data_buf_size/key_buf_size). That
- * allocation does not apply to the pdata DBT.
- */
-out:
- if (key.data != NULL && F_ISSET(&key, DB_DBT_MALLOC))
- __os_ufree(dbc->env, key.data);
- if (key.data != NULL && F_ISSET(&key, DB_DBT_USERMEM))
- __os_free(dbc->env, key.data);
- if (data.data != NULL && F_ISSET(&data, DB_DBT_MALLOC))
- __os_ufree(dbc->env, data.data);
- if (data.data != NULL && F_ISSET(&data, DB_DBT_USERMEM))
- __os_free(dbc->env, data.data);
- if (pdata.data != NULL && F_ISSET(&pdata, DB_DBT_MALLOC))
- __os_ufree(dbc->env, pdata.data);
- if (freedata)
- __os_free(NULL, dtmp);
- if (freekey)
- __os_free(NULL, ktmp);
- return (result);
-
-}
-
-/*
- * tcl_DbcCompare --
- */
-static int
-tcl_DbcCompare(interp, objc, objv, dbc)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DBC *dbc; /* Cursor pointer */
-{
- DBC *odbc;
- DBTCL_INFO *dbcip, *dbip;
- Tcl_Obj *res;
- int cmp_res, result, ret;
- char *arg, msg[MSG_SIZE];
-
- result = TCL_OK;
- res = NULL;
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, "?-args?");
- return (TCL_ERROR);
- }
-
- dbcip = _PtrToInfo(dbc);
- if (dbcip == NULL) {
- Tcl_SetResult(interp, "Cursor without info structure",
- TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- } else {
- dbip = dbcip->i_parent;
- if (dbip == NULL) {
- Tcl_SetResult(interp, "Cursor without parent database",
- TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- }
- }
- /*
- * When we get here, we better have:
- * 2 args one DBC and an int address for the result
- */
- arg = Tcl_GetStringFromObj(objv[2], NULL);
- odbc = NAME_TO_DBC(arg);
- if (odbc == NULL) {
- snprintf(msg, MSG_SIZE,
- "Cmp: Invalid cursor: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- goto out;
- }
-
- ret = dbc->cmp(dbc, odbc, &cmp_res, 0);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "dbc cmp");
- return (result);
- }
- res = Tcl_NewIntObj(cmp_res);
- Tcl_SetObjResult(interp, res);
-out:
- return (result);
-
-}
-
-/*
- * tcl_DbcDup --
- */
-static int
-tcl_DbcDup(interp, objc, objv, dbc)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DBC *dbc; /* Cursor pointer */
-{
- static const char *dbcdupopts[] = {
- "-position",
- NULL
- };
- enum dbcdupopts {
- DBCDUP_POS
- };
- DBC *newdbc;
- DBTCL_INFO *dbcip, *newdbcip, *dbip;
- Tcl_Obj *res;
- u_int32_t flag;
- int i, optindex, result, ret;
- char newname[MSG_SIZE];
-
- result = TCL_OK;
- flag = 0;
- res = NULL;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-args?");
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the options
- * defined above.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], dbcdupopts,
- "option", TCL_EXACT, &optindex) != TCL_OK) {
- /*
- * Reset the result so we don't get
- * an errant error message if there is another error.
- */
- if (IS_HELP(objv[i]) == TCL_OK) {
- result = TCL_OK;
- goto out;
- }
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum dbcdupopts)optindex) {
- case DBCDUP_POS:
- flag = DB_POSITION;
- break;
- }
- if (result != TCL_OK)
- break;
- }
- if (result != TCL_OK)
- goto out;
-
- /*
- * We need to determine if we are a recno database
- * or not. If we are, then key.data is a recno, not
- * a string.
- */
- dbcip = _PtrToInfo(dbc);
- if (dbcip == NULL) {
- Tcl_SetResult(interp, "Cursor without info structure",
- TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- } else {
- dbip = dbcip->i_parent;
- if (dbip == NULL) {
- Tcl_SetResult(interp, "Cursor without parent database",
- TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- }
- }
- /*
- * Now duplicate the cursor. If successful, we need to create
- * a new cursor command.
- */
- snprintf(newname, sizeof(newname),
- "%s.c%d", dbip->i_name, dbip->i_dbdbcid);
- newdbcip = _NewInfo(interp, NULL, newname, I_DBC);
- if (newdbcip != NULL) {
- ret = dbc->dup(dbc, &newdbc, flag);
- if (ret == 0) {
- dbip->i_dbdbcid++;
- newdbcip->i_parent = dbip;
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)dbc_Cmd,
- (ClientData)newdbc, NULL);
- res = NewStringObj(newname, strlen(newname));
- _SetInfoData(newdbcip, newdbc);
- Tcl_SetObjResult(interp, res);
- } else {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db dup");
- _DeleteInfo(newdbcip);
- }
- } else {
- Tcl_SetResult(interp, "Could not set up info", TCL_STATIC);
- result = TCL_ERROR;
- }
-out:
- return (result);
-
-}
diff --git a/tcl/tcl_env.c b/tcl/tcl_env.c
deleted file mode 100644
index 15d7b70..0000000
--- a/tcl/tcl_env.c
+++ /dev/null
@@ -1,2670 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/lock.h"
-#include "dbinc/txn.h"
-#include "dbinc/tcl_db.h"
-
-/*
- * Prototypes for procedures defined later in this file:
- */
-static void _EnvInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
-static int env_DbRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-static int env_DbRename __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-static int env_GetFlags __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-static int env_GetOpenFlag
- __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-static int env_GetLockDetect
- __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-static int env_GetTimeout __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-static int env_GetVerbose __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-
-/*
- * PUBLIC: int env_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
- *
- * env_Cmd --
- * Implements the "env" command.
- */
-int
-env_Cmd(clientData, interp, objc, objv)
- ClientData clientData; /* Env handle */
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *envcmds[] = {
-#ifdef CONFIG_TEST
- "attributes",
- "errfile",
- "errpfx",
- "event",
- "failchk",
- "id_reset",
- "lock_detect",
- "lock_id",
- "lock_id_free",
- "lock_id_set",
- "lock_get",
- "lock_stat",
- "lock_timeout",
- "lock_vec",
- "log_archive",
- "log_compare",
- "log_config",
- "log_cursor",
- "log_file",
- "log_flush",
- "log_get",
- "log_get_config",
- "log_put",
- "log_stat",
- "lsn_reset",
- "mpool",
- "mpool_stat",
- "mpool_sync",
- "mpool_trickle",
- "mutex",
- "mutex_free",
- "mutex_get_align",
- "mutex_get_incr",
- "mutex_get_max",
- "mutex_get_tas_spins",
- "mutex_lock",
- "mutex_set_tas_spins",
- "mutex_stat",
- "mutex_unlock",
- "rep_config",
- "rep_elect",
- "rep_flush",
- "rep_get_clockskew",
- "rep_get_config",
- "rep_get_limit",
- "rep_get_nsites",
- "rep_get_request",
- "rep_get_timeout",
- "rep_lease",
- "rep_limit",
- "rep_process_message",
- "rep_request",
- "rep_start",
- "rep_stat",
- "rep_sync",
- "rep_transport",
- "repmgr",
- "repmgr_site_list",
- "repmgr_stat",
- "rpcid",
- "set_flags",
- "test",
- "txn_id_set",
- "txn_recover",
- "txn_stat",
- "txn_timeout",
- "verbose",
-#endif
- "cdsgroup",
- "close",
- "dbremove",
- "dbrename",
- "get_cachesize",
- "get_cache_max",
- "get_data_dirs",
- "get_encrypt_flags",
- "get_errpfx",
- "get_flags",
- "get_home",
- "get_lg_bsize",
- "get_lg_dir",
- "get_lg_filemode",
- "get_lg_max",
- "get_lg_regionmax",
- "get_lk_detect",
- "get_lk_max_lockers",
- "get_lk_max_locks",
- "get_lk_max_objects",
- "get_mp_max_openfd",
- "get_mp_max_write",
- "get_mp_mmapsize",
- "get_open_flags",
- "get_shm_key",
- "get_tas_spins",
- "get_timeout",
- "get_tmp_dir",
- "get_tx_max",
- "get_tx_timestamp",
- "get_verbose",
- "resize_cache",
- "set_data_dir",
- "txn",
- "txn_checkpoint",
- NULL
- };
- enum envcmds {
-#ifdef CONFIG_TEST
- ENVATTR,
- ENVERRFILE,
- ENVERRPFX,
- ENVEVENT,
- ENVFAILCHK,
- ENVIDRESET,
- ENVLKDETECT,
- ENVLKID,
- ENVLKFREEID,
- ENVLKSETID,
- ENVLKGET,
- ENVLKSTAT,
- ENVLKTIMEOUT,
- ENVLKVEC,
- ENVLOGARCH,
- ENVLOGCMP,
- ENVLOGCONFIG,
- ENVLOGCURSOR,
- ENVLOGFILE,
- ENVLOGFLUSH,
- ENVLOGGET,
- ENVLOGGETCONFIG,
- ENVLOGPUT,
- ENVLOGSTAT,
- ENVLSNRESET,
- ENVMP,
- ENVMPSTAT,
- ENVMPSYNC,
- ENVTRICKLE,
- ENVMUTEX,
- ENVMUTFREE,
- ENVMUTGETALIGN,
- ENVMUTGETINCR,
- ENVMUTGETMAX,
- ENVMUTGETTASSPINS,
- ENVMUTLOCK,
- ENVMUTSETTASSPINS,
- ENVMUTSTAT,
- ENVMUTUNLOCK,
- ENVREPCONFIG,
- ENVREPELECT,
- ENVREPFLUSH,
- ENVREPGETCLOCKSKEW,
- ENVREPGETCONFIG,
- ENVREPGETLIMIT,
- ENVREPGETNSITES,
- ENVREPGETREQUEST,
- ENVREPGETTIMEOUT,
- ENVREPLEASE,
- ENVREPLIMIT,
- ENVREPPROCMESS,
- ENVREPREQUEST,
- ENVREPSTART,
- ENVREPSTAT,
- ENVREPSYNC,
- ENVREPTRANSPORT,
- ENVREPMGR,
- ENVREPMGRSITELIST,
- ENVREPMGRSTAT,
- ENVRPCID,
- ENVSETFLAGS,
- ENVTEST,
- ENVTXNSETID,
- ENVTXNRECOVER,
- ENVTXNSTAT,
- ENVTXNTIMEOUT,
- ENVVERB,
-#endif
- ENVCDSGROUP,
- ENVCLOSE,
- ENVDBREMOVE,
- ENVDBRENAME,
- ENVGETCACHESIZE,
- ENVGETCACHEMAX,
- ENVGETDATADIRS,
- ENVGETENCRYPTFLAGS,
- ENVGETERRPFX,
- ENVGETFLAGS,
- ENVGETHOME,
- ENVGETLGBSIZE,
- ENVGETLGDIR,
- ENVGETLGFILEMODE,
- ENVGETLGMAX,
- ENVGETLGREGIONMAX,
- ENVGETLKDETECT,
- ENVGETLKMAXLOCKERS,
- ENVGETLKMAXLOCKS,
- ENVGETLKMAXOBJECTS,
- ENVGETMPMAXOPENFD,
- ENVGETMPMAXWRITE,
- ENVGETMPMMAPSIZE,
- ENVGETOPENFLAG,
- ENVGETSHMKEY,
- ENVGETTASSPINS,
- ENVGETTIMEOUT,
- ENVGETTMPDIR,
- ENVGETTXMAX,
- ENVGETTXTIMESTAMP,
- ENVGETVERBOSE,
- ENVRESIZECACHE,
- ENVSETDATADIR,
- ENVTXN,
- ENVTXNCKP
- };
- DBTCL_INFO *envip;
- DB_ENV *dbenv;
- Tcl_Obj **listobjv, *myobjv[3], *res;
- db_timeout_t timeout;
- size_t size;
- time_t timeval;
- u_int32_t bytes, gbytes, value;
- long shm_key;
- int cmdindex, i, intvalue, listobjc, ncache, result, ret;
- const char *strval, **dirs;
- char *strarg, newname[MSG_SIZE];
-#ifdef CONFIG_TEST
- DBTCL_INFO *logcip;
- DB_LOGC *logc;
- u_int32_t lockid;
- long newval, otherval;
-#endif
-
- Tcl_ResetResult(interp);
- dbenv = (DB_ENV *)clientData;
- envip = _PtrToInfo((void *)dbenv);
- result = TCL_OK;
- memset(newname, 0, MSG_SIZE);
-
- if (objc <= 1) {
- Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs");
- return (TCL_ERROR);
- }
- if (dbenv == NULL) {
- Tcl_SetResult(interp, "NULL env pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (envip == NULL) {
- Tcl_SetResult(interp, "NULL env info pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the berkdbcmds
- * defined above.
- */
- if (Tcl_GetIndexFromObj(interp, objv[1], envcmds, "command",
- TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
- res = NULL;
- switch ((enum envcmds)cmdindex) {
-#ifdef CONFIG_TEST
- case ENVEVENT:
- /*
- * Two args for this. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- result = tcl_EventNotify(interp, dbenv, objv[2], envip);
- break;
- case ENVFAILCHK:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbenv->failchk(dbenv, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "failchk");
- break;
- case ENVIDRESET:
- result = tcl_EnvIdReset(interp, objc, objv, dbenv);
- break;
- case ENVLSNRESET:
- result = tcl_EnvLsnReset(interp, objc, objv, dbenv);
- break;
- case ENVLKDETECT:
- result = tcl_LockDetect(interp, objc, objv, dbenv);
- break;
- case ENVLKSTAT:
- result = tcl_LockStat(interp, objc, objv, dbenv);
- break;
- case ENVLKTIMEOUT:
- result = tcl_LockTimeout(interp, objc, objv, dbenv);
- break;
- case ENVLKID:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbenv->lock_id(dbenv, &lockid);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "lock_id");
- if (result == TCL_OK)
- res = Tcl_NewWideIntObj((Tcl_WideInt)lockid);
- break;
- case ENVLKFREEID:
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, NULL);
- return (TCL_ERROR);
- }
- result = Tcl_GetLongFromObj(interp, objv[2], &newval);
- if (result != TCL_OK)
- return (result);
- ret = dbenv->lock_id_free(dbenv, (u_int32_t)newval);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "lock id_free");
- break;
- case ENVLKSETID:
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 4, objv, "current max");
- return (TCL_ERROR);
- }
- result = Tcl_GetLongFromObj(interp, objv[2], &newval);
- if (result != TCL_OK)
- return (result);
- result = Tcl_GetLongFromObj(interp, objv[3], &otherval);
- if (result != TCL_OK)
- return (result);
- ret = __lock_id_set(dbenv->env,
- (u_int32_t)newval, (u_int32_t)otherval);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "lock id_free");
- break;
- case ENVLKGET:
- result = tcl_LockGet(interp, objc, objv, dbenv);
- break;
- case ENVLKVEC:
- result = tcl_LockVec(interp, objc, objv, dbenv);
- break;
- case ENVLOGARCH:
- result = tcl_LogArchive(interp, objc, objv, dbenv);
- break;
- case ENVLOGCMP:
- result = tcl_LogCompare(interp, objc, objv);
- break;
- case ENVLOGCONFIG:
- /*
- * Two args for this. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- result = tcl_LogConfig(interp, dbenv, objv[2]);
- break;
- case ENVLOGCURSOR:
- snprintf(newname, sizeof(newname),
- "%s.logc%d", envip->i_name, envip->i_envlogcid);
- logcip = _NewInfo(interp, NULL, newname, I_LOGC);
- if (logcip != NULL) {
- ret = dbenv->log_cursor(dbenv, &logc, 0);
- if (ret == 0) {
- result = TCL_OK;
- envip->i_envlogcid++;
- /*
- * We do NOT want to set i_parent to
- * envip here because log cursors are
- * not "tied" to the env. That is, they
- * are NOT closed if the env is closed.
- */
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)logc_Cmd,
- (ClientData)logc, NULL);
- res = NewStringObj(newname, strlen(newname));
- _SetInfoData(logcip, logc);
- } else {
- _DeleteInfo(logcip);
- result = _ErrorSetup(interp, ret, "log cursor");
- }
- } else {
- Tcl_SetResult(interp,
- "Could not set up info", TCL_STATIC);
- result = TCL_ERROR;
- }
- break;
- case ENVLOGFILE:
- result = tcl_LogFile(interp, objc, objv, dbenv);
- break;
- case ENVLOGFLUSH:
- result = tcl_LogFlush(interp, objc, objv, dbenv);
- break;
- case ENVLOGGET:
- result = tcl_LogGet(interp, objc, objv, dbenv);
- break;
- case ENVLOGGETCONFIG:
- /*
- * Two args for this. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- result = tcl_LogGetConfig(interp, dbenv, objv[2]);
- break;
- case ENVLOGPUT:
- result = tcl_LogPut(interp, objc, objv, dbenv);
- break;
- case ENVLOGSTAT:
- result = tcl_LogStat(interp, objc, objv, dbenv);
- break;
- case ENVMPSTAT:
- result = tcl_MpStat(interp, objc, objv, dbenv);
- break;
- case ENVMPSYNC:
- result = tcl_MpSync(interp, objc, objv, dbenv);
- break;
- case ENVTRICKLE:
- result = tcl_MpTrickle(interp, objc, objv, dbenv);
- break;
- case ENVMP:
- result = tcl_Mp(interp, objc, objv, dbenv, envip);
- break;
- case ENVMUTEX:
- result = tcl_Mutex(interp, objc, objv, dbenv);
- break;
- case ENVMUTFREE:
- result = tcl_MutFree(interp, objc, objv, dbenv);
- break;
- case ENVMUTGETALIGN:
- result = tcl_MutGet(interp, dbenv, DBTCL_MUT_ALIGN);
- break;
- case ENVMUTGETINCR:
- result = tcl_MutGet(interp, dbenv, DBTCL_MUT_INCR);
- break;
- case ENVMUTGETMAX:
- result = tcl_MutGet(interp, dbenv, DBTCL_MUT_MAX);
- break;
- case ENVMUTGETTASSPINS:
- result = tcl_MutGet(interp, dbenv, DBTCL_MUT_TAS);
- break;
- case ENVMUTLOCK:
- result = tcl_MutLock(interp, objc, objv, dbenv);
- break;
- case ENVMUTSETTASSPINS:
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- result = tcl_MutSet(interp, objv[2], dbenv, DBTCL_MUT_TAS);
- break;
- case ENVMUTSTAT:
- result = tcl_MutStat(interp, objc, objv, dbenv);
- break;
- case ENVMUTUNLOCK:
- result = tcl_MutUnlock(interp, objc, objv, dbenv);
- break;
- case ENVREPCONFIG:
- /*
- * Two args for this. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- result = tcl_RepConfig(interp, dbenv, objv[2]);
- break;
- case ENVREPELECT:
- result = tcl_RepElect(interp, objc, objv, dbenv);
- break;
- case ENVREPFLUSH:
- result = tcl_RepFlush(interp, objc, objv, dbenv);
- break;
- case ENVREPGETCLOCKSKEW:
- result = tcl_RepGetTwo(interp, dbenv, DBTCL_GETCLOCK);
- break;
- case ENVREPGETCONFIG:
- /*
- * Two args for this. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- result = tcl_RepGetConfig(interp, dbenv, objv[2]);
- break;
- case ENVREPGETLIMIT:
- result = tcl_RepGetTwo(interp, dbenv, DBTCL_GETLIMIT);
- break;
- case ENVREPGETNSITES:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->rep_get_nsites(dbenv, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_get_nsites")) == TCL_OK)
- res = Tcl_NewLongObj((long)value);
- break;
- case ENVREPGETREQUEST:
- result = tcl_RepGetTwo(interp, dbenv, DBTCL_GETREQ);
- break;
- case ENVREPGETTIMEOUT:
- /*
- * Two args for this. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- result = tcl_RepGetTimeout(interp, dbenv, objv[2]);
- break;
- case ENVREPLEASE:
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- result = Tcl_ListObjGetElements(interp, objv[2],
- &listobjc, &listobjv);
- if (result == TCL_OK)
- result = tcl_RepLease(interp,
- listobjc, listobjv, dbenv);
- break;
- case ENVREPLIMIT:
- result = tcl_RepLimit(interp, objc, objv, dbenv);
- break;
- case ENVREPPROCMESS:
- result = tcl_RepProcessMessage(interp, objc, objv, dbenv);
- break;
- case ENVREPREQUEST:
- result = tcl_RepRequest(interp, objc, objv, dbenv);
- break;
- case ENVREPSTART:
- result = tcl_RepStart(interp, objc, objv, dbenv);
- break;
- case ENVREPSTAT:
- result = tcl_RepStat(interp, objc, objv, dbenv);
- break;
- case ENVREPSYNC:
- result = tcl_RepSync(interp, objc, objv, dbenv);
- break;
- case ENVREPTRANSPORT:
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- result = Tcl_ListObjGetElements(interp, objv[2],
- &listobjc, &listobjv);
- if (result == TCL_OK)
- result = tcl_RepTransport(interp,
- listobjc, listobjv, dbenv, envip);
- break;
- case ENVREPMGR:
- result = tcl_RepMgr(interp, objc, objv, dbenv);
- break;
- case ENVREPMGRSITELIST:
- result = tcl_RepMgrSiteList(interp, objc, objv, dbenv);
- break;
- case ENVREPMGRSTAT:
- result = tcl_RepMgrStat(interp, objc, objv, dbenv);
- break;
- case ENVRPCID:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- /*
- * !!! Retrieve the client ID from the dbp handle directly.
- * This is for testing purposes only. It is BDB-private data.
- */
- res = Tcl_NewLongObj((long)dbenv->cl_id);
- break;
- case ENVTXNSETID:
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 4, objv, "current max");
- return (TCL_ERROR);
- }
- result = Tcl_GetLongFromObj(interp, objv[2], &newval);
- if (result != TCL_OK)
- return (result);
- result = Tcl_GetLongFromObj(interp, objv[3], &otherval);
- if (result != TCL_OK)
- return (result);
- ret = __txn_id_set(dbenv->env,
- (u_int32_t)newval, (u_int32_t)otherval);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "txn setid");
- break;
- case ENVTXNRECOVER:
- result = tcl_TxnRecover(interp, objc, objv, dbenv, envip);
- break;
- case ENVTXNSTAT:
- result = tcl_TxnStat(interp, objc, objv, dbenv);
- break;
- case ENVTXNTIMEOUT:
- result = tcl_TxnTimeout(interp, objc, objv, dbenv);
- break;
- case ENVATTR:
- result = tcl_EnvAttr(interp, objc, objv, dbenv);
- break;
- case ENVERRFILE:
- /*
- * One args for this. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "errfile");
- return (TCL_ERROR);
- }
- strarg = Tcl_GetStringFromObj(objv[2], NULL);
- tcl_EnvSetErrfile(interp, dbenv, envip, strarg);
- result = TCL_OK;
- break;
- case ENVERRPFX:
- /*
- * One args for this. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "pfx");
- return (TCL_ERROR);
- }
- strarg = Tcl_GetStringFromObj(objv[2], NULL);
- result = tcl_EnvSetErrpfx(interp, dbenv, envip, strarg);
- break;
- case ENVSETFLAGS:
- /*
- * Two args for this. Error if different.
- */
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "which on|off");
- return (TCL_ERROR);
- }
- result = tcl_EnvSetFlags(interp, dbenv, objv[2], objv[3]);
- break;
- case ENVTEST:
- result = tcl_EnvTest(interp, objc, objv, dbenv);
- break;
- case ENVVERB:
- /*
- * Two args for this. Error if different.
- */
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- result = tcl_EnvVerbose(interp, dbenv, objv[2], objv[3]);
- break;
-#endif
- case ENVCDSGROUP:
- result = tcl_CDSGroup(interp, objc, objv, dbenv, envip);
- break;
- case ENVCLOSE:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- /*
- * Any transactions will be aborted, and an mpools
- * closed automatically. We must delete any txn
- * and mp widgets we have here too for this env.
- * NOTE: envip is freed when we come back from
- * this function. Set it to NULL to make sure no
- * one tries to use it later.
- */
- _debug_check();
- ret = dbenv->close(dbenv, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env close");
- _EnvInfoDelete(interp, envip);
- envip = NULL;
- break;
- case ENVDBREMOVE:
- result = env_DbRemove(interp, objc, objv, dbenv);
- break;
- case ENVDBRENAME:
- result = env_DbRename(interp, objc, objv, dbenv);
- break;
- case ENVGETCACHESIZE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_cachesize(dbenv, &gbytes, &bytes, &ncache);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_cachesize")) == TCL_OK) {
- myobjv[0] = Tcl_NewLongObj((long)gbytes);
- myobjv[1] = Tcl_NewLongObj((long)bytes);
- myobjv[2] = Tcl_NewLongObj((long)ncache);
- res = Tcl_NewListObj(3, myobjv);
- }
- break;
- case ENVGETCACHEMAX:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_cache_max(dbenv, &gbytes, &bytes);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_cache_max")) == TCL_OK) {
- myobjv[0] = Tcl_NewLongObj((long)gbytes);
- myobjv[1] = Tcl_NewLongObj((long)bytes);
- res = Tcl_NewListObj(2, myobjv);
- }
- break;
- case ENVGETDATADIRS:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_data_dirs(dbenv, &dirs);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_data_dirs")) == TCL_OK) {
- res = Tcl_NewListObj(0, NULL);
- for (i = 0; result == TCL_OK && dirs[i] != NULL; i++)
- result = Tcl_ListObjAppendElement(interp, res,
- NewStringObj(dirs[i], strlen(dirs[i])));
- }
- break;
- case ENVGETENCRYPTFLAGS:
- result = tcl_EnvGetEncryptFlags(interp, objc, objv, dbenv);
- break;
- case ENVGETERRPFX:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- dbenv->get_errpfx(dbenv, &strval);
- res = NewStringObj(strval, strlen(strval));
- break;
- case ENVGETFLAGS:
- result = env_GetFlags(interp, objc, objv, dbenv);
- break;
- case ENVGETHOME:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_home(dbenv, &strval);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_home")) == TCL_OK)
- res = NewStringObj(strval, strlen(strval));
- break;
- case ENVGETLGBSIZE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_lg_bsize(dbenv, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_lg_bsize")) == TCL_OK)
- res = Tcl_NewLongObj((long)value);
- break;
- case ENVGETLGDIR:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_lg_dir(dbenv, &strval);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_lg_dir")) == TCL_OK)
- res = NewStringObj(strval, strlen(strval));
- break;
- case ENVGETLGFILEMODE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_lg_filemode(dbenv, &intvalue);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_lg_filemode")) == TCL_OK)
- res = Tcl_NewLongObj((long)intvalue);
- break;
- case ENVGETLGMAX:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_lg_max(dbenv, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_lg_max")) == TCL_OK)
- res = Tcl_NewLongObj((long)value);
- break;
- case ENVGETLGREGIONMAX:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_lg_regionmax(dbenv, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_lg_regionmax")) == TCL_OK)
- res = Tcl_NewLongObj((long)value);
- break;
- case ENVGETLKDETECT:
- result = env_GetLockDetect(interp, objc, objv, dbenv);
- break;
- case ENVGETLKMAXLOCKERS:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_lk_max_lockers(dbenv, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_lk_max_lockers")) == TCL_OK)
- res = Tcl_NewLongObj((long)value);
- break;
- case ENVGETLKMAXLOCKS:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_lk_max_locks(dbenv, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_lk_max_locks")) == TCL_OK)
- res = Tcl_NewLongObj((long)value);
- break;
- case ENVGETLKMAXOBJECTS:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_lk_max_objects(dbenv, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_lk_max_objects")) == TCL_OK)
- res = Tcl_NewLongObj((long)value);
- break;
- case ENVGETMPMAXOPENFD:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_mp_max_openfd(dbenv, &intvalue);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_mp_max_openfd")) == TCL_OK)
- res = Tcl_NewIntObj(intvalue);
- break;
- case ENVGETMPMAXWRITE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_mp_max_write(dbenv, &intvalue, &timeout);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_mp_max_write")) == TCL_OK) {
- myobjv[0] = Tcl_NewIntObj(intvalue);
- myobjv[1] = Tcl_NewIntObj((int)timeout);
- res = Tcl_NewListObj(2, myobjv);
- }
- break;
- case ENVGETMPMMAPSIZE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_mp_mmapsize(dbenv, &size);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_mp_mmapsize")) == TCL_OK)
- res = Tcl_NewLongObj((long)size);
- break;
- case ENVGETOPENFLAG:
- result = env_GetOpenFlag(interp, objc, objv, dbenv);
- break;
- case ENVGETSHMKEY:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_shm_key(dbenv, &shm_key);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env shm_key")) == TCL_OK)
- res = Tcl_NewLongObj(shm_key);
- break;
- case ENVGETTASSPINS:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->mutex_get_tas_spins(dbenv, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_tas_spins")) == TCL_OK)
- res = Tcl_NewLongObj((long)value);
- break;
- case ENVGETTIMEOUT:
- result = env_GetTimeout(interp, objc, objv, dbenv);
- break;
- case ENVGETTMPDIR:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_tmp_dir(dbenv, &strval);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_tmp_dir")) == TCL_OK)
- res = NewStringObj(strval, strlen(strval));
- break;
- case ENVGETTXMAX:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_tx_max(dbenv, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_tx_max")) == TCL_OK)
- res = Tcl_NewLongObj((long)value);
- break;
- case ENVGETTXTIMESTAMP:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_tx_timestamp(dbenv, &timeval);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_tx_timestamp")) == TCL_OK)
- res = Tcl_NewLongObj((long)timeval);
- break;
- case ENVGETVERBOSE:
- result = env_GetVerbose(interp, objc, objv, dbenv);
- break;
- case ENVRESIZECACHE:
- if ((result = Tcl_ListObjGetElements(
- interp, objv[2], &listobjc, &listobjv)) != TCL_OK)
- break;
- if (objc != 3 || listobjc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-resize_cache {gbytes bytes}?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, listobjv[0], &gbytes);
- if (result != TCL_OK)
- break;
- result = _GetUInt32(interp, listobjv[1], &bytes);
- if (result != TCL_OK)
- break;
- ret = dbenv->set_cachesize(dbenv, gbytes, bytes, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "resize_cache");
- break;
- case ENVSETDATADIR:
- /*
- * One args for this. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "pfx");
- return (TCL_ERROR);
- }
- strarg = Tcl_GetStringFromObj(objv[2], NULL);
- ret = dbenv->set_data_dir(dbenv, strarg);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env set data dir"));
- case ENVTXN:
- result = tcl_Txn(interp, objc, objv, dbenv, envip);
- break;
- case ENVTXNCKP:
- result = tcl_TxnCheckpoint(interp, objc, objv, dbenv);
- break;
- }
- /*
- * Only set result if we have a res. Otherwise, lower
- * functions have already done so.
- */
- if (result == TCL_OK && res)
- Tcl_SetObjResult(interp, res);
- return (result);
-}
-
-/*
- * PUBLIC: int tcl_EnvRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- * PUBLIC: DB_ENV *, DBTCL_INFO *));
- *
- * tcl_EnvRemove --
- */
-int
-tcl_EnvRemove(interp, objc, objv, dbenv, envip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Env pointer */
- DBTCL_INFO *envip; /* Info pointer */
-{
- static const char *envremopts[] = {
-#ifdef CONFIG_TEST
- "-overwrite",
- "-server",
-#endif
- "-data_dir",
- "-encryptaes",
- "-encryptany",
- "-force",
- "-home",
- "-log_dir",
- "-tmp_dir",
- "-use_environ",
- "-use_environ_root",
- NULL
- };
- enum envremopts {
-#ifdef CONFIG_TEST
- ENVREM_OVERWRITE,
- ENVREM_SERVER,
-#endif
- ENVREM_DATADIR,
- ENVREM_ENCRYPT_AES,
- ENVREM_ENCRYPT_ANY,
- ENVREM_FORCE,
- ENVREM_HOME,
- ENVREM_LOGDIR,
- ENVREM_TMPDIR,
- ENVREM_USE_ENVIRON,
- ENVREM_USE_ENVIRON_ROOT
- };
- u_int32_t cflag, enc_flag, flag, forceflag, sflag;
- int i, optindex, result, ret;
- char *datadir, *home, *logdir, *passwd, *server, *tmpdir;
-
- result = TCL_OK;
- cflag = flag = forceflag = sflag = 0;
- home = NULL;
- passwd = NULL;
- datadir = logdir = tmpdir = NULL;
- server = NULL;
- enc_flag = 0;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args?");
- return (TCL_ERROR);
- }
-
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], envremopts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[i]);
- goto error;
- }
- i++;
- switch ((enum envremopts)optindex) {
-#ifdef CONFIG_TEST
- case ENVREM_SERVER:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-server name?");
- result = TCL_ERROR;
- break;
- }
- server = Tcl_GetStringFromObj(objv[i++], NULL);
- cflag = DB_RPCCLIENT;
- break;
-#endif
- case ENVREM_ENCRYPT_AES:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-encryptaes passwd?");
- result = TCL_ERROR;
- break;
- }
- passwd = Tcl_GetStringFromObj(objv[i++], NULL);
- enc_flag = DB_ENCRYPT_AES;
- break;
- case ENVREM_ENCRYPT_ANY:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-encryptany passwd?");
- result = TCL_ERROR;
- break;
- }
- passwd = Tcl_GetStringFromObj(objv[i++], NULL);
- enc_flag = 0;
- break;
- case ENVREM_FORCE:
- forceflag |= DB_FORCE;
- break;
- case ENVREM_HOME:
- /* Make sure we have an arg to check against! */
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-home dir?");
- result = TCL_ERROR;
- break;
- }
- home = Tcl_GetStringFromObj(objv[i++], NULL);
- break;
-#ifdef CONFIG_TEST
- case ENVREM_OVERWRITE:
- sflag |= DB_OVERWRITE;
- break;
-#endif
- case ENVREM_USE_ENVIRON:
- flag |= DB_USE_ENVIRON;
- break;
- case ENVREM_USE_ENVIRON_ROOT:
- flag |= DB_USE_ENVIRON_ROOT;
- break;
- case ENVREM_DATADIR:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-data_dir dir");
- result = TCL_ERROR;
- break;
- }
- datadir = Tcl_GetStringFromObj(objv[i++], NULL);
- break;
- case ENVREM_LOGDIR:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-log_dir dir");
- result = TCL_ERROR;
- break;
- }
- logdir = Tcl_GetStringFromObj(objv[i++], NULL);
- break;
- case ENVREM_TMPDIR:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-tmp_dir dir");
- result = TCL_ERROR;
- break;
- }
- tmpdir = Tcl_GetStringFromObj(objv[i++], NULL);
- break;
- }
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- }
-
- /*
- * If dbenv is NULL, we don't have an open env and we need to open
- * one of the user. Don't bother with the info stuff.
- */
- if (dbenv == NULL) {
- if ((ret = db_env_create(&dbenv, cflag)) != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db_env_create");
- goto error;
- }
- if (server != NULL) {
- _debug_check();
- ret = dbenv->set_rpc_server(
- dbenv, NULL, server, 0, 0, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_rpc_server");
- if (result != TCL_OK)
- goto error;
- }
- if (datadir != NULL) {
- _debug_check();
- ret = dbenv->set_data_dir(dbenv, datadir);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_data_dir");
- if (result != TCL_OK)
- goto error;
- }
- if (logdir != NULL) {
- _debug_check();
- ret = dbenv->set_lg_dir(dbenv, logdir);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_log_dir");
- if (result != TCL_OK)
- goto error;
- }
- if (tmpdir != NULL) {
- _debug_check();
- ret = dbenv->set_tmp_dir(dbenv, tmpdir);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_tmp_dir");
- if (result != TCL_OK)
- goto error;
- }
- if (passwd != NULL) {
- ret = dbenv->set_encrypt(dbenv, passwd, enc_flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_encrypt");
- }
- if (sflag != 0 &&
- (ret = dbenv->set_flags(dbenv, sflag, 1)) != 0) {
- _debug_check();
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_flags");
- if (result != TCL_OK)
- goto error;
- }
- dbenv->set_errpfx(dbenv, "EnvRemove");
- dbenv->set_errcall(dbenv, _ErrorFunc);
- } else {
- /*
- * We have to clean up any info associated with this env,
- * regardless of the result of the remove so do it first.
- * NOTE: envip is freed when we come back from this function.
- */
- _EnvInfoDelete(interp, envip);
- envip = NULL;
- }
-
- flag |= forceflag;
- /*
- * When we get here we have parsed all the args. Now remove
- * the environment.
- */
- _debug_check();
- ret = dbenv->remove(dbenv, home, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env remove");
-error:
- return (result);
-}
-
-static void
-_EnvInfoDelete(interp, envip)
- Tcl_Interp *interp; /* Tcl Interpreter */
- DBTCL_INFO *envip; /* Info for env */
-{
- DBTCL_INFO *nextp, *p;
-
- /*
- * Before we can delete the environment info, we must close
- * any open subsystems in this env. We will:
- * 1. Abort any transactions (which aborts any nested txns).
- * 2. Close any mpools (which will put any pages itself).
- * 3. Put any locks and close log cursors.
- * 4. Close the error file.
- */
- for (p = LIST_FIRST(&__db_infohead); p != NULL; p = nextp) {
- /*
- * Check if this info structure "belongs" to this
- * env. If so, remove its commands and info structure.
- * We do not close/abort/whatever here, because we
- * don't want to replicate DB behavior.
- *
- * NOTE: Only those types that can nest need to be
- * itemized in the switch below. That is txns and mps.
- * Other types like log cursors and locks will just
- * get cleaned up here.
- */
- if (p->i_parent == envip) {
- switch (p->i_type) {
- case I_TXN:
- _TxnInfoDelete(interp, p);
- break;
- case I_MP:
- _MpInfoDelete(interp, p);
- break;
- case I_DB:
- case I_DBC:
- case I_ENV:
- case I_LOCK:
- case I_LOGC:
- case I_NDBM:
- case I_PG:
- case I_SEQ:
- Tcl_SetResult(interp,
- "_EnvInfoDelete: bad info type",
- TCL_STATIC);
- break;
- }
- nextp = LIST_NEXT(p, entries);
- (void)Tcl_DeleteCommand(interp, p->i_name);
- _DeleteInfo(p);
- } else
- nextp = LIST_NEXT(p, entries);
- }
- (void)Tcl_DeleteCommand(interp, envip->i_name);
- _DeleteInfo(envip);
-}
-
-#ifdef CONFIG_TEST
-/*
- * PUBLIC: int tcl_EnvIdReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- * PUBLIC: DB_ENV *));
- *
- * tcl_EnvIdReset --
- * Implements the ENV->fileid_reset command.
- */
-int
-tcl_EnvIdReset(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* arg count */
- Tcl_Obj * CONST* objv; /* args */
- DB_ENV *dbenv; /* Database pointer */
-{
- static const char *idwhich[] = {
- "-encrypt",
- NULL
- };
- enum idwhich {
- IDENCRYPT
- };
- int enc, i, result, ret;
- u_int32_t flags;
- char *file;
-
- result = TCL_OK;
- flags = 0;
- i = 2;
- Tcl_SetResult(interp, "0", TCL_STATIC);
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-encrypt? filename");
- return (TCL_ERROR);
- } else if (objc > 3) {
- /*
- * If there is an arg, make sure it is the right one.
- */
- if (Tcl_GetIndexFromObj(interp, objv[2], idwhich, "option",
- TCL_EXACT, &enc) != TCL_OK)
- return (IS_HELP(objv[2]));
- switch ((enum idwhich)enc) {
- case IDENCRYPT:
- flags |= DB_ENCRYPT;
- break;
- }
- i = 3;
- }
- file = Tcl_GetStringFromObj(objv[i], NULL);
- ret = dbenv->fileid_reset(dbenv, file, flags);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "fileid reset");
- return (result);
-}
-
-/*
- * PUBLIC: int tcl_EnvLsnReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- * PUBLIC: DB_ENV *));
- *
- * tcl_EnvLsnReset --
- * Implements the ENV->lsn_reset command.
- */
-int
-tcl_EnvLsnReset(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* arg count */
- Tcl_Obj * CONST* objv; /* args */
- DB_ENV *dbenv; /* Database pointer */
-{
- static const char *lsnwhich[] = {
- "-encrypt",
- NULL
- };
- enum lsnwhich {
- IDENCRYPT
- };
- int enc, i, result, ret;
- u_int32_t flags;
- char *file;
-
- result = TCL_OK;
- flags = 0;
- i = 2;
- Tcl_SetResult(interp, "0", TCL_STATIC);
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-encrypt? filename");
- return (TCL_ERROR);
- } else if (objc > 3) {
- /*
- * If there is an arg, make sure it is the right one.
- */
- if (Tcl_GetIndexFromObj(interp, objv[2], lsnwhich, "option",
- TCL_EXACT, &enc) != TCL_OK)
- return (IS_HELP(objv[2]));
-
- switch ((enum lsnwhich)enc) {
- case IDENCRYPT:
- flags |= DB_ENCRYPT;
- break;
- }
- i = 3;
- }
- file = Tcl_GetStringFromObj(objv[i], NULL);
- ret = dbenv->lsn_reset(dbenv, file, flags);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "lsn reset");
- return (result);
-}
-
-/*
- * PUBLIC: int tcl_EnvVerbose __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *,
- * PUBLIC: Tcl_Obj *));
- *
- * tcl_EnvVerbose --
- */
-int
-tcl_EnvVerbose(interp, dbenv, which, onoff)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Env pointer */
- Tcl_Obj *which; /* Which subsystem */
- Tcl_Obj *onoff; /* On or off */
-{
- static const char *verbwhich[] = {
- "deadlock",
- "fileops",
- "fileops_all",
- "recovery",
- "register",
- "rep",
- "rep_elect",
- "rep_lease",
- "rep_misc",
- "rep_msgs",
- "rep_sync",
- "rep_test",
- "repmgr_connfail",
- "repmgr_misc",
- "wait",
- NULL
- };
- enum verbwhich {
- ENVVERB_DEADLOCK,
- ENVVERB_FILEOPS,
- ENVVERB_FILEOPS_ALL,
- ENVVERB_RECOVERY,
- ENVVERB_REGISTER,
- ENVVERB_REPLICATION,
- ENVVERB_REP_ELECT,
- ENVVERB_REP_LEASE,
- ENVVERB_REP_MISC,
- ENVVERB_REP_MSGS,
- ENVVERB_REP_SYNC,
- ENVVERB_REP_TEST,
- ENVVERB_REPMGR_CONNFAIL,
- ENVVERB_REPMGR_MISC,
- ENVVERB_WAITSFOR
- };
- static const char *verbonoff[] = {
- "off",
- "on",
- NULL
- };
- enum verbonoff {
- ENVVERB_OFF,
- ENVVERB_ON
- };
- int on, optindex, ret;
- u_int32_t wh;
-
- if (Tcl_GetIndexFromObj(interp, which, verbwhich, "option",
- TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(which));
-
- switch ((enum verbwhich)optindex) {
- case ENVVERB_DEADLOCK:
- wh = DB_VERB_DEADLOCK;
- break;
- case ENVVERB_FILEOPS:
- wh = DB_VERB_FILEOPS;
- break;
- case ENVVERB_FILEOPS_ALL:
- wh = DB_VERB_FILEOPS_ALL;
- break;
- case ENVVERB_RECOVERY:
- wh = DB_VERB_RECOVERY;
- break;
- case ENVVERB_REGISTER:
- wh = DB_VERB_REGISTER;
- break;
- case ENVVERB_REPLICATION:
- wh = DB_VERB_REPLICATION;
- break;
- case ENVVERB_REP_ELECT:
- wh = DB_VERB_REP_ELECT;
- break;
- case ENVVERB_REP_LEASE:
- wh = DB_VERB_REP_LEASE;
- break;
- case ENVVERB_REP_MISC:
- wh = DB_VERB_REP_MISC;
- break;
- case ENVVERB_REP_MSGS:
- wh = DB_VERB_REP_MSGS;
- break;
- case ENVVERB_REP_SYNC:
- wh = DB_VERB_REP_SYNC;
- break;
- case ENVVERB_REP_TEST:
- wh = DB_VERB_REP_TEST;
- break;
- case ENVVERB_REPMGR_CONNFAIL:
- wh = DB_VERB_REPMGR_CONNFAIL;
- break;
- case ENVVERB_REPMGR_MISC:
- wh = DB_VERB_REPMGR_MISC;
- break;
- case ENVVERB_WAITSFOR:
- wh = DB_VERB_WAITSFOR;
- break;
- default:
- return (TCL_ERROR);
- }
- if (Tcl_GetIndexFromObj(interp, onoff, verbonoff, "option",
- TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(onoff));
- switch ((enum verbonoff)optindex) {
- case ENVVERB_OFF:
- on = 0;
- break;
- case ENVVERB_ON:
- on = 1;
- break;
- default:
- return (TCL_ERROR);
- }
- ret = dbenv->set_verbose(dbenv, wh, on);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env set verbose"));
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * PUBLIC: int tcl_EnvAttr __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
- *
- * tcl_EnvAttr --
- * Return a list of the env's attributes
- */
-int
-tcl_EnvAttr(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Env pointer */
-{
- ENV *env;
- Tcl_Obj *myobj, *retlist;
- int result;
-
- env = dbenv->env;
- result = TCL_OK;
-
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- retlist = Tcl_NewListObj(0, NULL);
- /*
- * XXX
- * We peek at the ENV to determine what subsystems we have available
- * in this environment.
- */
- myobj = NewStringObj("-home", strlen("-home"));
- if ((result = Tcl_ListObjAppendElement(interp,
- retlist, myobj)) != TCL_OK)
- goto err;
- myobj = NewStringObj(env->db_home, strlen(env->db_home));
- if ((result = Tcl_ListObjAppendElement(interp,
- retlist, myobj)) != TCL_OK)
- goto err;
- if (CDB_LOCKING(env)) {
- myobj = NewStringObj("-cdb", strlen("-cdb"));
- if ((result = Tcl_ListObjAppendElement(interp,
- retlist, myobj)) != TCL_OK)
- goto err;
- }
- if (CRYPTO_ON(env)) {
- myobj = NewStringObj("-crypto", strlen("-crypto"));
- if ((result = Tcl_ListObjAppendElement(interp,
- retlist, myobj)) != TCL_OK)
- goto err;
- }
- if (LOCKING_ON(env)) {
- myobj = NewStringObj("-lock", strlen("-lock"));
- if ((result = Tcl_ListObjAppendElement(interp,
- retlist, myobj)) != TCL_OK)
- goto err;
- }
- if (LOGGING_ON(env)) {
- myobj = NewStringObj("-log", strlen("-log"));
- if ((result = Tcl_ListObjAppendElement(interp,
- retlist, myobj)) != TCL_OK)
- goto err;
- }
- if (MPOOL_ON(env)) {
- myobj = NewStringObj("-mpool", strlen("-mpool"));
- if ((result = Tcl_ListObjAppendElement(interp,
- retlist, myobj)) != TCL_OK)
- goto err;
- }
- if (RPC_ON(dbenv)) {
- myobj = NewStringObj("-rpc", strlen("-rpc"));
- if ((result = Tcl_ListObjAppendElement(interp,
- retlist, myobj)) != TCL_OK)
- goto err;
- }
- if (REP_ON(env)) {
- myobj = NewStringObj("-rep", strlen("-rep"));
- if ((result = Tcl_ListObjAppendElement(interp,
- retlist, myobj)) != TCL_OK)
- goto err;
- }
- if (TXN_ON(env)) {
- myobj = NewStringObj("-txn", strlen("-txn"));
- if ((result = Tcl_ListObjAppendElement(interp,
- retlist, myobj)) != TCL_OK)
- goto err;
- }
- Tcl_SetObjResult(interp, retlist);
-err:
- return (result);
-}
-
-/*
- * tcl_EventNotify --
- * Call DB_ENV->set_event_notify().
- *
- * PUBLIC: int tcl_EventNotify __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *,
- * PUBLIC: DBTCL_INFO *));
- *
- * Note that this normally can/should be achieved as an argument to
- * berkdb env, but we need to test changing the event function on
- * the fly.
- */
-int
-tcl_EventNotify(interp, dbenv, eobj, ip)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv;
- Tcl_Obj *eobj; /* The event proc */
- DBTCL_INFO *ip;
-{
- int ret;
-
- /*
- * We don't need to crack the event procedure out now.
- */
- /*
- * If we're replacing an existing event proc, decrement it now.
- */
- if (ip->i_event != NULL) {
- Tcl_DecrRefCount(ip->i_event);
- }
- ip->i_event = eobj;
- Tcl_IncrRefCount(ip->i_event);
- _debug_check();
- ret = dbenv->set_event_notify(dbenv, _EventFunc);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env event"));
-}
-
-/*
- * PUBLIC: int tcl_EnvSetFlags __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *,
- * PUBLIC: Tcl_Obj *));
- *
- * tcl_EnvSetFlags --
- * Set flags in an env.
- */
-int
-tcl_EnvSetFlags(interp, dbenv, which, onoff)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Env pointer */
- Tcl_Obj *which; /* Which subsystem */
- Tcl_Obj *onoff; /* On or off */
-{
- static const char *sfwhich[] = {
- "-auto_commit",
- "-direct_db",
- "-multiversion",
- "-nolock",
- "-nommap",
- "-nopanic",
- "-nosync",
- "-overwrite",
- "-panic",
- "-wrnosync",
- NULL
- };
- enum sfwhich {
- ENVSF_AUTOCOMMIT,
- ENVSF_DIRECTDB,
- ENVSF_MULTIVERSION,
- ENVSF_NOLOCK,
- ENVSF_NOMMAP,
- ENVSF_NOPANIC,
- ENVSF_NOSYNC,
- ENVSF_OVERWRITE,
- ENVSF_PANIC,
- ENVSF_WRNOSYNC
- };
- static const char *sfonoff[] = {
- "off",
- "on",
- NULL
- };
- enum sfonoff {
- ENVSF_OFF,
- ENVSF_ON
- };
- int on, optindex, ret;
- u_int32_t wh;
-
- if (Tcl_GetIndexFromObj(interp, which, sfwhich, "option",
- TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(which));
-
- switch ((enum sfwhich)optindex) {
- case ENVSF_AUTOCOMMIT:
- wh = DB_AUTO_COMMIT;
- break;
- case ENVSF_DIRECTDB:
- wh = DB_DIRECT_DB;
- break;
- case ENVSF_MULTIVERSION:
- wh = DB_MULTIVERSION;
- break;
- case ENVSF_NOLOCK:
- wh = DB_NOLOCKING;
- break;
- case ENVSF_NOMMAP:
- wh = DB_NOMMAP;
- break;
- case ENVSF_NOSYNC:
- wh = DB_TXN_NOSYNC;
- break;
- case ENVSF_NOPANIC:
- wh = DB_NOPANIC;
- break;
- case ENVSF_PANIC:
- wh = DB_PANIC_ENVIRONMENT;
- break;
- case ENVSF_OVERWRITE:
- wh = DB_OVERWRITE;
- break;
- case ENVSF_WRNOSYNC:
- wh = DB_TXN_WRITE_NOSYNC;
- break;
- default:
- return (TCL_ERROR);
- }
- if (Tcl_GetIndexFromObj(interp, onoff, sfonoff, "option",
- TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(onoff));
- switch ((enum sfonoff)optindex) {
- case ENVSF_OFF:
- on = 0;
- break;
- case ENVSF_ON:
- on = 1;
- break;
- default:
- return (TCL_ERROR);
- }
- ret = dbenv->set_flags(dbenv, wh, on);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env set flags"));
-}
-
-/*
- * tcl_EnvTest --
- * The "$env test ..." command is a sort of catch-all for any sort of
- * desired test hook manipulation. The "abort", "check" and "copy" subcommands
- * all set one or another certain location in the DB_ENV handle to a specific
- * value. (In the case of "check", the value is an integer passed in with the
- * command itself. For the other two, the "value" is a predefined enum
- * constant, specified by name.)
- * The "$env test force ..." subcommand invokes other, more arbitrary
- * manipulations.
- * Although these functions may not all seem closely related, putting them
- * all under the name "test" has the aesthetic appeal of keeping the rest of the
- * API clean.
- *
- * PUBLIC: int tcl_EnvTest __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_EnvTest(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Env pointer */
-{
- static const char *envtestcmd[] = {
- "abort",
- "check",
- "copy",
- "force",
- NULL
- };
- enum envtestcmd {
- ENVTEST_ABORT,
- ENVTEST_CHECK,
- ENVTEST_COPY,
- ENVTEST_FORCE
- };
- static const char *envtestat[] = {
- "electinit",
- "electvote1",
- "none",
- "predestroy",
- "preopen",
- "postdestroy",
- "postlog",
- "postlogmeta",
- "postopen",
- "postsync",
- "subdb_lock",
- NULL
- };
- enum envtestat {
- ENVTEST_ELECTINIT,
- ENVTEST_ELECTVOTE1,
- ENVTEST_NONE,
- ENVTEST_PREDESTROY,
- ENVTEST_PREOPEN,
- ENVTEST_POSTDESTROY,
- ENVTEST_POSTLOG,
- ENVTEST_POSTLOGMETA,
- ENVTEST_POSTOPEN,
- ENVTEST_POSTSYNC,
- ENVTEST_SUBDB_LOCKS
- };
- static const char *envtestforce[] = {
- "noarchive_timeout",
- NULL
- };
- enum envtestforce {
- ENVTEST_NOARCHIVE_TIMEOUT
- };
- ENV *env;
- int *loc, optindex, result, testval;
-
- env = dbenv->env;
- result = TCL_OK;
- loc = NULL;
-
- if (objc != 4) {
- Tcl_WrongNumArgs(interp,
- 2, objv, "abort|check|copy|force <args>");
- return (TCL_ERROR);
- }
-
- /*
- * This must be the "check", "copy" or "abort" portion of the command.
- */
- if (Tcl_GetIndexFromObj(interp, objv[2], envtestcmd, "command",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[2]);
- return (result);
- }
- switch ((enum envtestcmd)optindex) {
- case ENVTEST_ABORT:
- loc = &env->test_abort;
- break;
- case ENVTEST_CHECK:
- loc = &env->test_check;
- if (Tcl_GetIntFromObj(interp, objv[3], &testval) != TCL_OK) {
- result = IS_HELP(objv[3]);
- return (result);
- }
- goto done;
- case ENVTEST_COPY:
- loc = &env->test_copy;
- break;
- case ENVTEST_FORCE:
- if (Tcl_GetIndexFromObj(interp, objv[3], envtestforce, "arg",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[3]);
- return (result);
- }
- /*
- * In the future we might add more, and then we'd use a switch
- * statement.
- */
- DB_ASSERT(env,
- (enum envtestforce)optindex == ENVTEST_NOARCHIVE_TIMEOUT);
- return (tcl_RepNoarchiveTimeout(interp, dbenv));
- default:
- Tcl_SetResult(interp, "Illegal store location", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- /*
- * This must be the location portion of the command.
- */
- if (Tcl_GetIndexFromObj(interp, objv[3], envtestat, "location",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[3]);
- return (result);
- }
- switch ((enum envtestat)optindex) {
- case ENVTEST_ELECTINIT:
- DB_ASSERT(env, loc == &env->test_abort);
- testval = DB_TEST_ELECTINIT;
- break;
- case ENVTEST_ELECTVOTE1:
- DB_ASSERT(env, loc == &env->test_abort);
- testval = DB_TEST_ELECTVOTE1;
- break;
- case ENVTEST_NONE:
- testval = 0;
- break;
- case ENVTEST_PREOPEN:
- testval = DB_TEST_PREOPEN;
- break;
- case ENVTEST_PREDESTROY:
- testval = DB_TEST_PREDESTROY;
- break;
- case ENVTEST_POSTLOG:
- testval = DB_TEST_POSTLOG;
- break;
- case ENVTEST_POSTLOGMETA:
- testval = DB_TEST_POSTLOGMETA;
- break;
- case ENVTEST_POSTOPEN:
- testval = DB_TEST_POSTOPEN;
- break;
- case ENVTEST_POSTDESTROY:
- testval = DB_TEST_POSTDESTROY;
- break;
- case ENVTEST_POSTSYNC:
- testval = DB_TEST_POSTSYNC;
- break;
- case ENVTEST_SUBDB_LOCKS:
- DB_ASSERT(env, loc == &env->test_abort);
- testval = DB_TEST_SUBDB_LOCKS;
- break;
- default:
- Tcl_SetResult(interp, "Illegal test location", TCL_STATIC);
- return (TCL_ERROR);
- }
-done:
- *loc = testval;
- Tcl_SetResult(interp, "0", TCL_STATIC);
- return (result);
-}
-#endif
-
-/*
- * env_DbRemove --
- * Implements the ENV->dbremove command.
- */
-static int
-env_DbRemove(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
-{
- static const char *envdbrem[] = {
- "-auto_commit",
- "-notdurable",
- "-txn",
- "--",
- NULL
- };
- enum envdbrem {
- TCL_EDBREM_COMMIT,
- TCL_EDBREM_NOTDURABLE,
- TCL_EDBREM_TXN,
- TCL_EDBREM_ENDARG
- };
- DB_TXN *txn;
- u_int32_t flag;
- int endarg, i, optindex, result, ret, subdblen;
- u_char *subdbtmp;
- char *arg, *db, *subdb, msg[MSG_SIZE];
-
- txn = NULL;
- result = TCL_OK;
- subdbtmp = NULL;
- db = subdb = NULL;
- endarg = 0;
- flag = 0;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args? filename ?database?");
- return (TCL_ERROR);
- }
-
- /*
- * We must first parse for the environment flag, since that
- * is needed for db_create. Then create the db handle.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], envdbrem,
- "option", TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto error;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum envdbrem)optindex) {
- case TCL_EDBREM_COMMIT:
- flag |= DB_AUTO_COMMIT;
- break;
- case TCL_EDBREM_TXN:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "env dbremove: Invalid txn %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- return (TCL_ERROR);
- }
- break;
- case TCL_EDBREM_ENDARG:
- endarg = 1;
- break;
- case TCL_EDBREM_NOTDURABLE:
- flag |= DB_TXN_NOT_DURABLE;
- break;
- }
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- if (endarg)
- break;
- }
- if (result != TCL_OK)
- goto error;
- /*
- * Any args we have left, (better be 1 or 2 left) are
- * file names. If there is 1, a db name, if 2 a db and subdb name.
- */
- if ((i != (objc - 1)) || (i != (objc - 2))) {
- /*
- * Dbs must be NULL terminated file names, but subdbs can
- * be anything. Use Strings for the db name and byte
- * arrays for the subdb.
- */
- db = Tcl_GetStringFromObj(objv[i++], NULL);
- if (strcmp(db, "") == 0)
- db = NULL;
- if (i != objc) {
- subdbtmp =
- Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
- if ((ret = __os_malloc(
- dbenv->env, (size_t)subdblen + 1, &subdb)) != 0) {
- Tcl_SetResult(interp,
- db_strerror(ret), TCL_STATIC);
- return (0);
- }
- memcpy(subdb, subdbtmp, (size_t)subdblen);
- subdb[subdblen] = '\0';
- }
- } else {
- Tcl_WrongNumArgs(interp, 2, objv, "?args? filename ?database?");
- result = TCL_ERROR;
- goto error;
- }
- ret = dbenv->dbremove(dbenv, txn, db, subdb, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env dbremove");
-error:
- if (subdb)
- __os_free(dbenv->env, subdb);
- return (result);
-}
-
-/*
- * env_DbRename --
- * Implements the ENV->dbrename command.
- */
-static int
-env_DbRename(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
-{
- static const char *envdbmv[] = {
- "-auto_commit",
- "-txn",
- "--",
- NULL
- };
- enum envdbmv {
- TCL_EDBMV_COMMIT,
- TCL_EDBMV_TXN,
- TCL_EDBMV_ENDARG
- };
- DB_TXN *txn;
- u_int32_t flag;
- int endarg, i, newlen, optindex, result, ret, subdblen;
- u_char *subdbtmp;
- char *arg, *db, *newname, *subdb, msg[MSG_SIZE];
-
- txn = NULL;
- result = TCL_OK;
- subdbtmp = NULL;
- db = newname = subdb = NULL;
- endarg = 0;
- flag = 0;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 3, objv,
- "?args? filename ?database? ?newname?");
- return (TCL_ERROR);
- }
-
- /*
- * We must first parse for the environment flag, since that
- * is needed for db_create. Then create the db handle.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], envdbmv,
- "option", TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto error;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum envdbmv)optindex) {
- case TCL_EDBMV_COMMIT:
- flag |= DB_AUTO_COMMIT;
- break;
- case TCL_EDBMV_TXN:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "env dbrename: Invalid txn %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- return (TCL_ERROR);
- }
- break;
- case TCL_EDBMV_ENDARG:
- endarg = 1;
- break;
- }
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- if (endarg)
- break;
- }
- if (result != TCL_OK)
- goto error;
- /*
- * Any args we have left, (better be 2 or 3 left) are
- * file names. If there is 2, a db name, if 3 a db and subdb name.
- */
- if ((i != (objc - 2)) || (i != (objc - 3))) {
- /*
- * Dbs must be NULL terminated file names, but subdbs can
- * be anything. Use Strings for the db name and byte
- * arrays for the subdb.
- */
- db = Tcl_GetStringFromObj(objv[i++], NULL);
- if (strcmp(db, "") == 0)
- db = NULL;
- if (i == objc - 2) {
- subdbtmp =
- Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
- if ((ret = __os_malloc(
- dbenv->env, (size_t)subdblen + 1, &subdb)) != 0) {
- Tcl_SetResult(interp,
- db_strerror(ret), TCL_STATIC);
- return (0);
- }
- memcpy(subdb, subdbtmp, (size_t)subdblen);
- subdb[subdblen] = '\0';
- }
- subdbtmp = Tcl_GetByteArrayFromObj(objv[i++], &newlen);
- if ((ret = __os_malloc(
- dbenv->env, (size_t)newlen + 1, &newname)) != 0) {
- Tcl_SetResult(interp,
- db_strerror(ret), TCL_STATIC);
- return (0);
- }
- memcpy(newname, subdbtmp, (size_t)newlen);
- newname[newlen] = '\0';
- } else {
- Tcl_WrongNumArgs(interp, 3, objv,
- "?args? filename ?database? ?newname?");
- result = TCL_ERROR;
- goto error;
- }
- ret = dbenv->dbrename(dbenv, txn, db, subdb, newname, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env dbrename");
-error:
- if (subdb)
- __os_free(dbenv->env, subdb);
- if (newname)
- __os_free(dbenv->env, newname);
- return (result);
-}
-
-/*
- * env_GetFlags --
- * Implements the ENV->get_flags command.
- */
-static int
-env_GetFlags(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
-{
- int i, ret, result;
- u_int32_t flags;
- char buf[512];
- Tcl_Obj *res;
-
- static const struct {
- u_int32_t flag;
- char *arg;
- } open_flags[] = {
- { DB_AUTO_COMMIT, "-auto_commit" },
- { DB_CDB_ALLDB, "-cdb_alldb" },
- { DB_DIRECT_DB, "-direct_db" },
- { DB_MULTIVERSION, "-multiversion" },
- { DB_NOLOCKING, "-nolock" },
- { DB_NOMMAP, "-nommap" },
- { DB_NOPANIC, "-nopanic" },
- { DB_OVERWRITE, "-overwrite" },
- { DB_PANIC_ENVIRONMENT, "-panic" },
- { DB_REGION_INIT, "-region_init" },
- { DB_TXN_NOSYNC, "-nosync" },
- { DB_TXN_WRITE_NOSYNC, "-wrnosync" },
- { DB_YIELDCPU, "-yield" },
- { 0, NULL }
- };
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
-
- ret = dbenv->get_flags(dbenv, &flags);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_flags")) == TCL_OK) {
- buf[0] = '\0';
-
- for (i = 0; open_flags[i].flag != 0; i++)
- if (LF_ISSET(open_flags[i].flag)) {
- if (strlen(buf) > 0)
- (void)strncat(buf, " ", sizeof(buf));
- (void)strncat(
- buf, open_flags[i].arg, sizeof(buf));
- }
-
- res = NewStringObj(buf, strlen(buf));
- Tcl_SetObjResult(interp, res);
- }
-
- return (result);
-}
-
-/*
- * env_GetOpenFlag --
- * Implements the ENV->get_open_flags command.
- */
-static int
-env_GetOpenFlag(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
-{
- int i, ret, result;
- u_int32_t flags;
- char buf[512];
- Tcl_Obj *res;
-
- static const struct {
- u_int32_t flag;
- char *arg;
- } open_flags[] = {
- { DB_CREATE, "-create" },
- { DB_FAILCHK, "-failchk" },
- { DB_INIT_CDB, "-cdb" },
- { DB_INIT_LOCK, "-lock" },
- { DB_INIT_LOG, "-log" },
- { DB_INIT_MPOOL, "-mpool" },
- { DB_INIT_REP, "-rep" },
- { DB_INIT_TXN, "-txn" },
- { DB_LOCKDOWN, "-lockdown" },
- { DB_PRIVATE, "-private" },
- { DB_RECOVER, "-recover" },
- { DB_RECOVER_FATAL, "-recover_fatal" },
- { DB_REGISTER, "-register" },
- { DB_FAILCHK, "-failchk" },
- { DB_SYSTEM_MEM, "-system_mem" },
- { DB_THREAD, "-thread" },
- { DB_USE_ENVIRON, "-use_environ" },
- { DB_USE_ENVIRON_ROOT, "-use_environ_root" },
- { 0, NULL }
- };
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
-
- ret = dbenv->get_open_flags(dbenv, &flags);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_open_flags")) == TCL_OK) {
- buf[0] = '\0';
-
- for (i = 0; open_flags[i].flag != 0; i++)
- if (LF_ISSET(open_flags[i].flag)) {
- if (strlen(buf) > 0)
- (void)strncat(buf, " ", sizeof(buf));
- (void)strncat(
- buf, open_flags[i].arg, sizeof(buf));
- }
-
- res = NewStringObj(buf, strlen(buf));
- Tcl_SetObjResult(interp, res);
- }
-
- return (result);
-}
-
-/*
- * PUBLIC: int tcl_EnvGetEncryptFlags __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- * PUBLIC: DB_ENV *));
- *
- * tcl_EnvGetEncryptFlags --
- * Implements the ENV->get_encrypt_flags command.
- */
-int
-tcl_EnvGetEncryptFlags(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Database pointer */
-{
- int i, ret, result;
- u_int32_t flags;
- char buf[512];
- Tcl_Obj *res;
-
- static const struct {
- u_int32_t flag;
- char *arg;
- } encrypt_flags[] = {
- { DB_ENCRYPT_AES, "-encryptaes" },
- { 0, NULL }
- };
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
-
- ret = dbenv->get_encrypt_flags(dbenv, &flags);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_encrypt_flags")) == TCL_OK) {
- buf[0] = '\0';
-
- for (i = 0; encrypt_flags[i].flag != 0; i++)
- if (LF_ISSET(encrypt_flags[i].flag)) {
- if (strlen(buf) > 0)
- (void)strncat(buf, " ", sizeof(buf));
- (void)strncat(
- buf, encrypt_flags[i].arg, sizeof(buf));
- }
-
- res = NewStringObj(buf, strlen(buf));
- Tcl_SetObjResult(interp, res);
- }
-
- return (result);
-}
-
-/*
- * env_GetLockDetect --
- * Implements the ENV->get_lk_detect command.
- */
-static int
-env_GetLockDetect(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
-{
- int i, ret, result;
- u_int32_t lk_detect;
- const char *answer;
- Tcl_Obj *res;
- static const struct {
- u_int32_t flag;
- char *name;
- } lk_detect_returns[] = {
- { DB_LOCK_DEFAULT, "default" },
- { DB_LOCK_EXPIRE, "expire" },
- { DB_LOCK_MAXLOCKS, "maxlocks" },
- { DB_LOCK_MAXWRITE, "maxwrite" },
- { DB_LOCK_MINLOCKS, "minlocks" },
- { DB_LOCK_MINWRITE, "minwrite" },
- { DB_LOCK_OLDEST, "oldest" },
- { DB_LOCK_RANDOM, "random" },
- { DB_LOCK_YOUNGEST, "youngest" },
- { 0, NULL }
- };
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = dbenv->get_lk_detect(dbenv, &lk_detect);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_lk_detect")) == TCL_OK) {
- answer = "unknown";
- for (i = 0; lk_detect_returns[i].flag != 0; i++)
- if (lk_detect == lk_detect_returns[i].flag)
- answer = lk_detect_returns[i].name;
-
- res = NewStringObj(answer, strlen(answer));
- Tcl_SetObjResult(interp, res);
- }
-
- return (result);
-}
-
-/*
- * env_GetTimeout --
- * Implements the ENV->get_timeout command.
- */
-static int
-env_GetTimeout(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
-{
- static const struct {
- u_int32_t flag;
- char *arg;
- } timeout_flags[] = {
- { DB_SET_LOCK_TIMEOUT, "lock" },
- { DB_SET_REG_TIMEOUT, "reg" },
- { DB_SET_TXN_TIMEOUT, "txn" },
- { 0, NULL }
- };
- Tcl_Obj *res;
- db_timeout_t timeout;
- u_int32_t which;
- int i, ret, result;
- const char *arg;
-
- COMPQUIET(timeout, 0);
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
-
- arg = Tcl_GetStringFromObj(objv[2], NULL);
- which = 0;
- for (i = 0; timeout_flags[i].flag != 0; i++)
- if (strcmp(arg, timeout_flags[i].arg) == 0)
- which = timeout_flags[i].flag;
- if (which == 0) {
- ret = EINVAL;
- goto err;
- }
-
- ret = dbenv->get_timeout(dbenv, &timeout, which);
-err: if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_timeout")) == TCL_OK) {
- res = Tcl_NewLongObj((long)timeout);
- Tcl_SetObjResult(interp, res);
- }
-
- return (result);
-}
-
-/*
- * env_GetVerbose --
- * Implements the ENV->get_open_flags command.
- */
-static int
-env_GetVerbose(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
-{
- static const struct {
- u_int32_t flag;
- char *arg;
- } verbose_flags[] = {
- { DB_VERB_DEADLOCK, "deadlock" },
- { DB_VERB_FILEOPS, "fileops" },
- { DB_VERB_FILEOPS_ALL, "fileops_all" },
- { DB_VERB_RECOVERY, "recovery" },
- { DB_VERB_REGISTER, "register" },
- { DB_VERB_REPLICATION, "rep" },
- { DB_VERB_REP_ELECT, "rep_elect" },
- { DB_VERB_REP_LEASE, "rep_lease" },
- { DB_VERB_REP_MISC, "rep_misc" },
- { DB_VERB_REP_MSGS, "rep_msgs" },
- { DB_VERB_REP_SYNC, "rep_sync" },
- { DB_VERB_REP_TEST, "rep_test" },
- { DB_VERB_REPMGR_CONNFAIL, "repmgr_connfail" },
- { DB_VERB_REPMGR_MISC, "repmgr_misc" },
- { DB_VERB_WAITSFOR, "wait" },
- { 0, NULL }
- };
- Tcl_Obj *res;
- u_int32_t which;
- int i, onoff, ret, result;
- const char *arg, *answer;
-
- COMPQUIET(onoff, 0);
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
-
- arg = Tcl_GetStringFromObj(objv[2], NULL);
- which = 0;
- for (i = 0; verbose_flags[i].flag != 0; i++)
- if (strcmp(arg, verbose_flags[i].arg) == 0)
- which = verbose_flags[i].flag;
- if (which == 0) {
- ret = EINVAL;
- goto err;
- }
-
- ret = dbenv->get_verbose(dbenv, which, &onoff);
-err: if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_verbose")) == 0) {
- answer = onoff ? "on" : "off";
- res = NewStringObj(answer, strlen(answer));
- Tcl_SetObjResult(interp, res);
- }
-
- return (result);
-}
-
-/*
- * PUBLIC: void tcl_EnvSetErrfile __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *,
- * PUBLIC: char *));
- *
- * tcl_EnvSetErrfile --
- * Implements the ENV->set_errfile command.
- */
-void
-tcl_EnvSetErrfile(interp, dbenv, ip, errf)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Database pointer */
- DBTCL_INFO *ip; /* Our internal info */
- char *errf;
-{
- COMPQUIET(interp, NULL);
- /*
- * If the user already set one, free it.
- */
- if (ip->i_err != NULL && ip->i_err != stdout &&
- ip->i_err != stderr)
- (void)fclose(ip->i_err);
- if (strcmp(errf, "/dev/stdout") == 0)
- ip->i_err = stdout;
- else if (strcmp(errf, "/dev/stderr") == 0)
- ip->i_err = stderr;
- else
- ip->i_err = fopen(errf, "a");
- if (ip->i_err != NULL)
- dbenv->set_errfile(dbenv, ip->i_err);
-}
-
-/*
- * PUBLIC: int tcl_EnvSetErrpfx __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *,
- * PUBLIC: char *));
- *
- * tcl_EnvSetErrpfx --
- * Implements the ENV->set_errpfx command.
- */
-int
-tcl_EnvSetErrpfx(interp, dbenv, ip, pfx)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Database pointer */
- DBTCL_INFO *ip; /* Our internal info */
- char *pfx;
-{
- int result, ret;
-
- /*
- * Assume success. The only thing that can fail is
- * the __os_strdup.
- */
- result = TCL_OK;
- Tcl_SetResult(interp, "0", TCL_STATIC);
- /*
- * If the user already set one, free it.
- */
- if (ip->i_errpfx != NULL)
- __os_free(dbenv->env, ip->i_errpfx);
- if ((ret = __os_strdup(dbenv->env, pfx, &ip->i_errpfx)) != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "__os_strdup");
- ip->i_errpfx = NULL;
- }
- if (ip->i_errpfx != NULL)
- dbenv->set_errpfx(dbenv, ip->i_errpfx);
- return (result);
-}
diff --git a/tcl/tcl_internal.c b/tcl/tcl_internal.c
deleted file mode 100644
index d5a3e99..0000000
--- a/tcl/tcl_internal.c
+++ /dev/null
@@ -1,817 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/tcl_db.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_am.h"
-
-/*
- *
- * internal.c --
- *
- * This file contains internal functions we need to maintain
- * state for our Tcl interface.
- *
- * NOTE: This all uses a linear linked list. If we end up with
- * too many info structs such that this is a performance hit, it
- * should be redone using hashes or a list per type. The assumption
- * is that the user won't have more than a few dozen info structs
- * in operation at any given point in time. Even a complicated
- * application with a few environments, nested transactions, locking,
- * and several databases open, using cursors should not have a
- * negative performance impact, in terms of searching the list to
- * get/manipulate the info structure.
- */
-
-#define GLOB_CHAR(c) ((c) == '*' || (c) == '?')
-
-/*
- * PUBLIC: DBTCL_INFO *_NewInfo __P((Tcl_Interp *,
- * PUBLIC: void *, char *, enum INFOTYPE));
- *
- * _NewInfo --
- *
- * This function will create a new info structure and fill it in
- * with the name and pointer, id and type.
- */
-DBTCL_INFO *
-_NewInfo(interp, anyp, name, type)
- Tcl_Interp *interp;
- void *anyp;
- char *name;
- enum INFOTYPE type;
-{
- DBTCL_INFO *p;
- int ret;
-
- if ((ret = __os_calloc(NULL, sizeof(DBTCL_INFO), 1, &p)) != 0) {
- Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC);
- return (NULL);
- }
-
- if ((ret = __os_strdup(NULL, name, &p->i_name)) != 0) {
- Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC);
- __os_free(NULL, p);
- return (NULL);
- }
- p->i_interp = interp;
- p->i_anyp = anyp;
- p->i_type = type;
-
- LIST_INSERT_HEAD(&__db_infohead, p, entries);
- return (p);
-}
-
-/*
- * PUBLIC: void *_NameToPtr __P((CONST char *));
- */
-void *
-_NameToPtr(name)
- CONST char *name;
-{
- DBTCL_INFO *p;
-
- LIST_FOREACH(p, &__db_infohead, entries)
- if (strcmp(name, p->i_name) == 0)
- return (p->i_anyp);
- return (NULL);
-}
-
-/*
- * PUBLIC: DBTCL_INFO *_PtrToInfo __P((CONST void *));
- */
-DBTCL_INFO *
-_PtrToInfo(ptr)
- CONST void *ptr;
-{
- DBTCL_INFO *p;
-
- LIST_FOREACH(p, &__db_infohead, entries)
- if (p->i_anyp == ptr)
- return (p);
- return (NULL);
-}
-
-/*
- * PUBLIC: DBTCL_INFO *_NameToInfo __P((CONST char *));
- */
-DBTCL_INFO *
-_NameToInfo(name)
- CONST char *name;
-{
- DBTCL_INFO *p;
-
- LIST_FOREACH(p, &__db_infohead, entries)
- if (strcmp(name, p->i_name) == 0)
- return (p);
- return (NULL);
-}
-
-/*
- * PUBLIC: void _SetInfoData __P((DBTCL_INFO *, void *));
- */
-void
-_SetInfoData(p, data)
- DBTCL_INFO *p;
- void *data;
-{
- if (p == NULL)
- return;
- p->i_anyp = data;
- return;
-}
-
-/*
- * PUBLIC: void _DeleteInfo __P((DBTCL_INFO *));
- */
-void
-_DeleteInfo(p)
- DBTCL_INFO *p;
-{
- if (p == NULL)
- return;
- LIST_REMOVE(p, entries);
- if (p->i_lockobj.data != NULL)
- __os_free(NULL, p->i_lockobj.data);
- if (p->i_err != NULL && p->i_err != stderr && p->i_err != stdout) {
- (void)fclose(p->i_err);
- p->i_err = NULL;
- }
- if (p->i_errpfx != NULL)
- __os_free(NULL, p->i_errpfx);
- if (p->i_compare != NULL) {
- Tcl_DecrRefCount(p->i_compare);
- }
- if (p->i_dupcompare != NULL) {
- Tcl_DecrRefCount(p->i_dupcompare);
- }
- if (p->i_hashproc != NULL) {
- Tcl_DecrRefCount(p->i_hashproc);
- }
- if (p->i_part_callback != NULL) {
- Tcl_DecrRefCount(p->i_part_callback);
- }
- if (p->i_second_call != NULL) {
- Tcl_DecrRefCount(p->i_second_call);
- }
- if (p->i_rep_eid != NULL) {
- Tcl_DecrRefCount(p->i_rep_eid);
- }
- if (p->i_rep_send != NULL) {
- Tcl_DecrRefCount(p->i_rep_send);
- }
- if (p->i_event != NULL) {
- Tcl_DecrRefCount(p->i_event);
- }
- __os_free(NULL, p->i_name);
- __os_free(NULL, p);
-
- return;
-}
-
-/*
- * PUBLIC: int _SetListElem __P((Tcl_Interp *,
- * PUBLIC: Tcl_Obj *, void *, u_int32_t, void *, u_int32_t));
- */
-int
-_SetListElem(interp, list, elem1, e1cnt, elem2, e2cnt)
- Tcl_Interp *interp;
- Tcl_Obj *list;
- void *elem1, *elem2;
- u_int32_t e1cnt, e2cnt;
-{
- Tcl_Obj *myobjv[2], *thislist;
- int myobjc;
-
- myobjc = 2;
- myobjv[0] = Tcl_NewByteArrayObj((u_char *)elem1, (int)e1cnt);
- myobjv[1] = Tcl_NewByteArrayObj((u_char *)elem2, (int)e2cnt);
- thislist = Tcl_NewListObj(myobjc, myobjv);
- if (thislist == NULL)
- return (TCL_ERROR);
- return (Tcl_ListObjAppendElement(interp, list, thislist));
-
-}
-
-/*
- * PUBLIC: int _SetListElemInt __P((Tcl_Interp *, Tcl_Obj *, void *, long));
- */
-int
-_SetListElemInt(interp, list, elem1, elem2)
- Tcl_Interp *interp;
- Tcl_Obj *list;
- void *elem1;
- long elem2;
-{
- Tcl_Obj *myobjv[2], *thislist;
- int myobjc;
-
- myobjc = 2;
- myobjv[0] =
- Tcl_NewByteArrayObj((u_char *)elem1, (int)strlen((char *)elem1));
- myobjv[1] = Tcl_NewLongObj(elem2);
- thislist = Tcl_NewListObj(myobjc, myobjv);
- if (thislist == NULL)
- return (TCL_ERROR);
- return (Tcl_ListObjAppendElement(interp, list, thislist));
-}
-
-/*
- * Don't compile this code if we don't have sequences compiled into the DB
- * library, it's likely because we don't have a 64-bit type, and trying to
- * use int64_t is going to result in syntax errors.
- */
-#ifdef HAVE_64BIT_TYPES
-/*
- * PUBLIC: int _SetListElemWideInt __P((Tcl_Interp *,
- * PUBLIC: Tcl_Obj *, void *, int64_t));
- */
-int
-_SetListElemWideInt(interp, list, elem1, elem2)
- Tcl_Interp *interp;
- Tcl_Obj *list;
- void *elem1;
- int64_t elem2;
-{
- Tcl_Obj *myobjv[2], *thislist;
- int myobjc;
-
- myobjc = 2;
- myobjv[0] =
- Tcl_NewByteArrayObj((u_char *)elem1, (int)strlen((char *)elem1));
- myobjv[1] = Tcl_NewWideIntObj(elem2);
- thislist = Tcl_NewListObj(myobjc, myobjv);
- if (thislist == NULL)
- return (TCL_ERROR);
- return (Tcl_ListObjAppendElement(interp, list, thislist));
-}
-#endif /* HAVE_64BIT_TYPES */
-
-/*
- * PUBLIC: int _SetListRecnoElem __P((Tcl_Interp *, Tcl_Obj *,
- * PUBLIC: db_recno_t, u_char *, u_int32_t));
- */
-int
-_SetListRecnoElem(interp, list, elem1, elem2, e2size)
- Tcl_Interp *interp;
- Tcl_Obj *list;
- db_recno_t elem1;
- u_char *elem2;
- u_int32_t e2size;
-{
- Tcl_Obj *myobjv[2], *thislist;
- int myobjc;
-
- myobjc = 2;
- myobjv[0] = Tcl_NewWideIntObj((Tcl_WideInt)elem1);
- myobjv[1] = Tcl_NewByteArrayObj(elem2, (int)e2size);
- thislist = Tcl_NewListObj(myobjc, myobjv);
- if (thislist == NULL)
- return (TCL_ERROR);
- return (Tcl_ListObjAppendElement(interp, list, thislist));
-
-}
-
-/*
- * _Set3DBTList --
- * This is really analogous to both _SetListElem and
- * _SetListRecnoElem--it's used for three-DBT lists returned by
- * DB->pget and DBC->pget(). We'd need a family of four functions
- * to handle all the recno/non-recno cases, however, so we make
- * this a little more aware of the internals and do the logic inside.
- *
- * XXX
- * One of these days all these functions should probably be cleaned up
- * to eliminate redundancy and bring them into the standard DB
- * function namespace.
- *
- * PUBLIC: int _Set3DBTList __P((Tcl_Interp *, Tcl_Obj *, DBT *, int,
- * PUBLIC: DBT *, int, DBT *));
- */
-int
-_Set3DBTList(interp, list, elem1, is1recno, elem2, is2recno, elem3)
- Tcl_Interp *interp;
- Tcl_Obj *list;
- DBT *elem1, *elem2, *elem3;
- int is1recno, is2recno;
-{
-
- Tcl_Obj *myobjv[3], *thislist;
-
- if (is1recno)
- myobjv[0] = Tcl_NewWideIntObj(
- (Tcl_WideInt)*(db_recno_t *)elem1->data);
- else
- myobjv[0] = Tcl_NewByteArrayObj(
- (u_char *)elem1->data, (int)elem1->size);
-
- if (is2recno)
- myobjv[1] = Tcl_NewWideIntObj(
- (Tcl_WideInt)*(db_recno_t *)elem2->data);
- else
- myobjv[1] = Tcl_NewByteArrayObj(
- (u_char *)elem2->data, (int)elem2->size);
-
- myobjv[2] = Tcl_NewByteArrayObj(
- (u_char *)elem3->data, (int)elem3->size);
-
- thislist = Tcl_NewListObj(3, myobjv);
-
- if (thislist == NULL)
- return (TCL_ERROR);
- return (Tcl_ListObjAppendElement(interp, list, thislist));
-}
-
-/*
- * _SetMultiList -- build a list for return from multiple get.
- *
- * PUBLIC: int _SetMultiList __P((Tcl_Interp *,
- * PUBLIC: Tcl_Obj *, DBT *, DBT*, DBTYPE, u_int32_t));
- */
-int
-_SetMultiList(interp, list, key, data, type, flag)
- Tcl_Interp *interp;
- Tcl_Obj *list;
- DBT *key, *data;
- DBTYPE type;
- u_int32_t flag;
-{
- db_recno_t recno;
- u_int32_t dlen, klen;
- int result;
- void *pointer, *dp, *kp;
-
- recno = 0;
- dlen = 0;
- kp = NULL;
-
- DB_MULTIPLE_INIT(pointer, data);
- result = TCL_OK;
-
- if (type == DB_RECNO || type == DB_QUEUE)
- recno = *(db_recno_t *) key->data;
- else
- kp = key->data;
- klen = key->size;
- do {
- if (flag & DB_MULTIPLE_KEY) {
- if (type == DB_RECNO || type == DB_QUEUE)
- DB_MULTIPLE_RECNO_NEXT(pointer,
- data, recno, dp, dlen);
- else
- DB_MULTIPLE_KEY_NEXT(pointer,
- data, kp, klen, dp, dlen);
- } else
- DB_MULTIPLE_NEXT(pointer, data, dp, dlen);
-
- if (pointer == NULL)
- break;
-
- if (type == DB_RECNO || type == DB_QUEUE) {
- result =
- _SetListRecnoElem(interp, list, recno, dp, dlen);
- recno++;
- /* Wrap around and skip zero. */
- if (recno == 0)
- recno++;
- } else
- result = _SetListElem(interp, list, kp, klen, dp, dlen);
- } while (result == TCL_OK);
-
- return (result);
-}
-/*
- * PUBLIC: int _GetGlobPrefix __P((char *, char **));
- */
-int
-_GetGlobPrefix(pattern, prefix)
- char *pattern;
- char **prefix;
-{
- int i, j;
- char *p;
-
- /*
- * Duplicate it, we get enough space and most of the work is done.
- */
- if (__os_strdup(NULL, pattern, prefix) != 0)
- return (1);
-
- p = *prefix;
- for (i = 0, j = 0; p[i] && !GLOB_CHAR(p[i]); i++, j++)
- /*
- * Check for an escaped character and adjust
- */
- if (p[i] == '\\' && p[i+1]) {
- p[j] = p[i+1];
- i++;
- } else
- p[j] = p[i];
- p[j] = 0;
- return (0);
-}
-
-/*
- * PUBLIC: int _ReturnSetup __P((Tcl_Interp *, int, int, char *));
- */
-int
-_ReturnSetup(interp, ret, ok, errmsg)
- Tcl_Interp *interp;
- int ret, ok;
- char *errmsg;
-{
- char *msg;
-
- if (ret > 0)
- return (_ErrorSetup(interp, ret, errmsg));
-
- /*
- * We either have success or a DB error. If a DB error, set up the
- * string. We return an error if not one of the errors we catch.
- * If anyone wants to reset the result to return anything different,
- * then the calling function is responsible for doing so via
- * Tcl_ResetResult or another Tcl_SetObjResult.
- */
- if (ret == 0) {
- Tcl_SetResult(interp, "0", TCL_STATIC);
- return (TCL_OK);
- }
-
- msg = db_strerror(ret);
- Tcl_AppendResult(interp, msg, NULL);
-
- if (ok)
- return (TCL_OK);
- else {
- Tcl_SetErrorCode(interp, "BerkeleyDB", msg, NULL);
- return (TCL_ERROR);
- }
-}
-
-/*
- * PUBLIC: int _ErrorSetup __P((Tcl_Interp *, int, char *));
- */
-int
-_ErrorSetup(interp, ret, errmsg)
- Tcl_Interp *interp;
- int ret;
- char *errmsg;
-{
- Tcl_SetErrno(ret);
- Tcl_AppendResult(interp, errmsg, ":", Tcl_PosixError(interp), NULL);
- return (TCL_ERROR);
-}
-
-/*
- * PUBLIC: void _ErrorFunc __P((const DB_ENV *, CONST char *, const char *));
- */
-void
-_ErrorFunc(dbenv, pfx, msg)
- const DB_ENV *dbenv;
- CONST char *pfx;
- const char *msg;
-{
- DBTCL_INFO *p;
- Tcl_Interp *interp;
- size_t size;
- char *err;
-
- COMPQUIET(dbenv, NULL);
-
- p = _NameToInfo(pfx);
- if (p == NULL)
- return;
- interp = p->i_interp;
-
- size = strlen(pfx) + strlen(msg) + 4;
- /*
- * If we cannot allocate enough to put together the prefix
- * and message then give them just the message.
- */
- if (__os_malloc(NULL, size, &err) != 0) {
- Tcl_AddErrorInfo(interp, msg);
- Tcl_AppendResult(interp, msg, "\n", NULL);
- return;
- }
- snprintf(err, size, "%s: %s", pfx, msg);
- Tcl_AddErrorInfo(interp, err);
- Tcl_AppendResult(interp, err, "\n", NULL);
- __os_free(NULL, err);
- return;
-}
-
-/*
- * PUBLIC: void _EventFunc __P((DB_ENV *, u_int32_t, void *));
- */
-void
-_EventFunc(dbenv, event, info)
- DB_ENV *dbenv;
- u_int32_t event;
- void *info;
-{
-#define TCLDB_EVENTITEMS 2 /* Event name and any info */
-#define TCLDB_SENDEVENT 3 /* Event Tcl proc, env name, event objects. */
- DBTCL_INFO *ip;
- Tcl_Interp *interp;
- Tcl_Obj *event_o, *origobj;
- Tcl_Obj *myobjv[TCLDB_EVENTITEMS], *objv[TCLDB_SENDEVENT];
- int i, myobjc, result;
-
- ip = (DBTCL_INFO *)dbenv->app_private;
- interp = ip->i_interp;
- if (ip->i_event == NULL)
- return;
- objv[0] = ip->i_event;
- objv[1] = NewStringObj(ip->i_name, strlen(ip->i_name));
-
- /*
- * Most events don't have additional info. Assume none
- * and handle individually those that do.
- */
- myobjv[1] = NULL;
- myobjc = 1;
- switch (event) {
- case DB_EVENT_PANIC:
- /*
- * Info is the original error code.
- */
- myobjv[0] = NewStringObj("panic", strlen("panic"));
- myobjv[myobjc++] = Tcl_NewIntObj(*(int *)info);
- break;
- case DB_EVENT_REP_CLIENT:
- myobjv[0] = NewStringObj("rep_client", strlen("rep_client"));
- break;
- case DB_EVENT_REP_ELECTED:
- myobjv[0] = NewStringObj("elected", strlen("elected"));
- break;
- case DB_EVENT_REP_MASTER:
- myobjv[0] = NewStringObj("rep_master", strlen("rep_master"));
- break;
- case DB_EVENT_REP_NEWMASTER:
- /*
- * Info is the EID of the new master.
- */
- myobjv[0] = NewStringObj("newmaster", strlen("newmaster"));
- myobjv[myobjc++] = Tcl_NewIntObj(*(int *)info);
- break;
- case DB_EVENT_REP_PERM_FAILED:
- myobjv[0] = NewStringObj("perm_failed", strlen("perm_failed"));
- break;
- case DB_EVENT_REP_STARTUPDONE:
- myobjv[0] = NewStringObj("startupdone", strlen("startupdone"));
- break;
- case DB_EVENT_WRITE_FAILED:
- myobjv[0] =
- NewStringObj("write_failed", strlen("write_failed"));
- break;
- default:
- __db_errx(dbenv->env, "Tcl unknown event %lu", (u_long)event);
- return;
- }
-
- for (i = 0; i < myobjc; i++)
- Tcl_IncrRefCount(myobjv[i]);
-
- event_o = Tcl_NewListObj(myobjc, myobjv);
- Tcl_IncrRefCount(event_o);
- objv[2] = event_o;
-
- /*
- * We really want to return the original result to the
- * user. So, save the result obj here, and then after
- * we've taken care of the Tcl_EvalObjv, set the result
- * back to this original result.
- */
- origobj = Tcl_GetObjResult(interp);
- Tcl_IncrRefCount(origobj);
- result = Tcl_EvalObjv(interp, TCLDB_SENDEVENT, objv, 0);
- if (result != TCL_OK) {
- /*
- * XXX
- * This probably isn't the right error behavior, but
- * this error should only happen if the Tcl callback is
- * somehow invalid, which is a fatal scripting bug.
- * The event handler is a void function so we either
- * just return or abort.
- * For now, abort.
- */
- __db_errx(dbenv->env, "Tcl event failure");
- __os_abort(dbenv->env);
- }
-
- Tcl_SetObjResult(interp, origobj);
- Tcl_DecrRefCount(origobj);
- for (i = 0; i < myobjc; i++)
- Tcl_DecrRefCount(myobjv[i]);
- Tcl_DecrRefCount(event_o);
-
- return;
-}
-
-#define INVALID_LSNMSG "Invalid LSN with %d parts. Should have 2.\n"
-
-/*
- * PUBLIC: int _GetLsn __P((Tcl_Interp *, Tcl_Obj *, DB_LSN *));
- */
-int
-_GetLsn(interp, obj, lsn)
- Tcl_Interp *interp;
- Tcl_Obj *obj;
- DB_LSN *lsn;
-{
- Tcl_Obj **myobjv;
- char msg[MSG_SIZE];
- int myobjc, result;
- u_int32_t tmp;
-
- result = Tcl_ListObjGetElements(interp, obj, &myobjc, &myobjv);
- if (result == TCL_ERROR)
- return (result);
- if (myobjc != 2) {
- result = TCL_ERROR;
- snprintf(msg, MSG_SIZE, INVALID_LSNMSG, myobjc);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- return (result);
- }
- result = _GetUInt32(interp, myobjv[0], &tmp);
- if (result == TCL_ERROR)
- return (result);
- lsn->file = tmp;
- result = _GetUInt32(interp, myobjv[1], &tmp);
- lsn->offset = tmp;
- return (result);
-}
-
-/*
- * _GetUInt32 --
- * Get a u_int32_t from a Tcl object. Tcl_GetIntFromObj does the
- * right thing most of the time, but on machines where a long is 8 bytes
- * and an int is 4 bytes, it errors on integers between the maximum
- * int32_t and the maximum u_int32_t. This is correct, but we generally
- * want a u_int32_t in the end anyway, so we use Tcl_GetLongFromObj and do
- * the bounds checking ourselves.
- *
- * This code looks much like Tcl_GetIntFromObj, only with a different
- * bounds check. It's essentially Tcl_GetUnsignedIntFromObj, which
- * unfortunately doesn't exist.
- *
- * PUBLIC: int _GetUInt32 __P((Tcl_Interp *, Tcl_Obj *, u_int32_t *));
- */
-int
-_GetUInt32(interp, obj, resp)
- Tcl_Interp *interp;
- Tcl_Obj *obj;
- u_int32_t *resp;
-{
- int result;
- long ltmp;
-
- result = Tcl_GetLongFromObj(interp, obj, &ltmp);
- if (result != TCL_OK)
- return (result);
-
- if ((unsigned long)ltmp != (u_int32_t)ltmp) {
- if (interp != NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "integer value too large for u_int32_t", -1);
- }
- return (TCL_ERROR);
- }
-
- *resp = (u_int32_t)ltmp;
- return (TCL_OK);
-}
-
-/*
- * _GetFlagsList --
- * Get a new Tcl object, containing a list of the string values
- * associated with a particular set of flag values.
- *
- * PUBLIC: Tcl_Obj *_GetFlagsList __P((Tcl_Interp *, u_int32_t, const FN *));
- */
-Tcl_Obj *
-_GetFlagsList(interp, flags, fnp)
- Tcl_Interp *interp;
- u_int32_t flags;
- const FN *fnp;
-{
- Tcl_Obj *newlist, *newobj;
- int result;
-
- newlist = Tcl_NewObj();
-
- /*
- * If the Berkeley DB library wasn't compiled with statistics, then
- * we may get a NULL reference.
- */
- if (fnp == NULL)
- return (newlist);
-
- /*
- * Append a Tcl_Obj containing each pertinent flag string to the
- * specified Tcl list.
- */
- for (; fnp->mask != 0; ++fnp)
- if (LF_ISSET(fnp->mask)) {
- newobj = NewStringObj(fnp->name, strlen(fnp->name));
- result =
- Tcl_ListObjAppendElement(interp, newlist, newobj);
-
- /*
- * Tcl_ListObjAppendElement is defined to return TCL_OK
- * unless newlist isn't actually a list (or convertible
- * into one). If this is the case, we screwed up badly
- * somehow.
- */
- DB_ASSERT(NULL, result == TCL_OK);
- }
-
- return (newlist);
-}
-
-int __debug_stop, __debug_on, __debug_print, __debug_test;
-
-/*
- * PUBLIC: void _debug_check __P((void));
- */
-void
-_debug_check()
-{
- if (__debug_on == 0)
- return;
-
- if (__debug_print != 0) {
- printf("\r%7d:", __debug_on);
- (void)fflush(stdout);
- }
- if (__debug_on++ == __debug_test || __debug_stop)
- __db_loadme();
-}
-
-/*
- * XXX
- * Tcl 8.1+ Tcl_GetByteArrayFromObj/Tcl_GetIntFromObj bug.
- *
- * There is a bug in Tcl 8.1+ and byte arrays in that if it happens
- * to use an object as both a byte array and something else like
- * an int, and you've done a Tcl_GetByteArrayFromObj, then you
- * do a Tcl_GetIntFromObj, your memory is deleted.
- *
- * Workaround is for all byte arrays we want to use, if it can be
- * represented as an integer, we copy it so that we don't lose the
- * memory.
- */
-/*
- * PUBLIC: int _CopyObjBytes __P((Tcl_Interp *, Tcl_Obj *obj, void *,
- * PUBLIC: u_int32_t *, int *));
- */
-int
-_CopyObjBytes(interp, obj, newp, sizep, freep)
- Tcl_Interp *interp;
- Tcl_Obj *obj;
- void *newp;
- u_int32_t *sizep;
- int *freep;
-{
- void *tmp, *new;
- int i, len, ret;
-
- /*
- * If the object is not an int, then just return the byte
- * array because it won't be transformed out from under us.
- * If it is a number, we need to copy it.
- */
- *freep = 0;
- ret = Tcl_GetIntFromObj(interp, obj, &i);
- tmp = Tcl_GetByteArrayFromObj(obj, &len);
- *sizep = (u_int32_t)len;
- if (ret == TCL_ERROR) {
- Tcl_ResetResult(interp);
- *(void **)newp = tmp;
- return (0);
- }
-
- /*
- * If we get here, we have an integer that might be reused
- * at some other point so we cannot count on GetByteArray
- * keeping our pointer valid.
- */
- if ((ret = __os_malloc(NULL, (size_t)len, &new)) != 0)
- return (ret);
- memcpy(new, tmp, (size_t)len);
- *(void **)newp = new;
- *freep = 1;
- return (0);
-}
diff --git a/tcl/tcl_lock.c b/tcl/tcl_lock.c
deleted file mode 100644
index 03b1bed..0000000
--- a/tcl/tcl_lock.c
+++ /dev/null
@@ -1,775 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/tcl_db.h"
-
-/*
- * Prototypes for procedures defined later in this file:
- */
-#ifdef CONFIG_TEST
-static int lock_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-static int _LockMode __P((Tcl_Interp *, Tcl_Obj *, db_lockmode_t *));
-static int _GetThisLock __P((Tcl_Interp *, DB_ENV *, u_int32_t,
- u_int32_t, DBT *, db_lockmode_t, char *));
-static void _LockPutInfo __P((Tcl_Interp *, db_lockop_t, DB_LOCK *,
- u_int32_t, DBT *));
-
-/*
- * tcl_LockDetect --
- *
- * PUBLIC: int tcl_LockDetect __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_LockDetect(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- static const char *ldopts[] = {
- "default",
- "expire",
- "maxlocks",
- "maxwrites",
- "minlocks",
- "minwrites",
- "oldest",
- "random",
- "youngest",
- NULL
- };
- enum ldopts {
- LD_DEFAULT,
- LD_EXPIRE,
- LD_MAXLOCKS,
- LD_MAXWRITES,
- LD_MINLOCKS,
- LD_MINWRITES,
- LD_OLDEST,
- LD_RANDOM,
- LD_YOUNGEST
- };
- u_int32_t flag, policy;
- int i, optindex, result, ret;
-
- result = TCL_OK;
- flag = policy = 0;
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i],
- ldopts, "option", TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(objv[i]));
- i++;
- switch ((enum ldopts)optindex) {
- case LD_DEFAULT:
- FLAG_CHECK(policy);
- policy = DB_LOCK_DEFAULT;
- break;
- case LD_EXPIRE:
- FLAG_CHECK(policy);
- policy = DB_LOCK_EXPIRE;
- break;
- case LD_MAXLOCKS:
- FLAG_CHECK(policy);
- policy = DB_LOCK_MAXLOCKS;
- break;
- case LD_MAXWRITES:
- FLAG_CHECK(policy);
- policy = DB_LOCK_MAXWRITE;
- break;
- case LD_MINLOCKS:
- FLAG_CHECK(policy);
- policy = DB_LOCK_MINLOCKS;
- break;
- case LD_MINWRITES:
- FLAG_CHECK(policy);
- policy = DB_LOCK_MINWRITE;
- break;
- case LD_OLDEST:
- FLAG_CHECK(policy);
- policy = DB_LOCK_OLDEST;
- break;
- case LD_RANDOM:
- FLAG_CHECK(policy);
- policy = DB_LOCK_RANDOM;
- break;
- case LD_YOUNGEST:
- FLAG_CHECK(policy);
- policy = DB_LOCK_YOUNGEST;
- break;
- }
- }
-
- _debug_check();
- ret = dbenv->lock_detect(dbenv, flag, policy, NULL);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "lock detect");
- return (result);
-}
-
-/*
- * tcl_LockGet --
- *
- * PUBLIC: int tcl_LockGet __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_LockGet(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- static const char *lgopts[] = {
- "-nowait",
- NULL
- };
- enum lgopts {
- LGNOWAIT
- };
- DBT obj;
- Tcl_Obj *res;
- void *otmp;
- db_lockmode_t mode;
- u_int32_t flag, lockid;
- int freeobj, optindex, result, ret;
- char newname[MSG_SIZE];
-
- result = TCL_OK;
- freeobj = 0;
- memset(newname, 0, MSG_SIZE);
- if (objc != 5 && objc != 6) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-nowait? mode id obj");
- return (TCL_ERROR);
- }
- /*
- * Work back from required args.
- * Last arg is obj.
- * Second last is lock id.
- * Third last is lock mode.
- */
- memset(&obj, 0, sizeof(obj));
-
- if ((result =
- _GetUInt32(interp, objv[objc-2], &lockid)) != TCL_OK)
- return (result);
-
- ret = _CopyObjBytes(interp, objv[objc-1], &otmp,
- &obj.size, &freeobj);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "lock get");
- return (result);
- }
- obj.data = otmp;
- if ((result = _LockMode(interp, objv[(objc - 3)], &mode)) != TCL_OK)
- goto out;
-
- /*
- * Any left over arg is the flag.
- */
- flag = 0;
- if (objc == 6) {
- if (Tcl_GetIndexFromObj(interp, objv[(objc - 4)],
- lgopts, "option", TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(objv[(objc - 4)]));
- switch ((enum lgopts)optindex) {
- case LGNOWAIT:
- flag |= DB_LOCK_NOWAIT;
- break;
- }
- }
-
- result = _GetThisLock(interp, dbenv, lockid, flag, &obj, mode, newname);
- if (result == TCL_OK) {
- res = NewStringObj(newname, strlen(newname));
- Tcl_SetObjResult(interp, res);
- }
-out:
- if (freeobj)
- __os_free(dbenv->env, otmp);
- return (result);
-}
-
-/*
- * tcl_LockStat --
- *
- * PUBLIC: int tcl_LockStat __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_LockStat(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- DB_LOCK_STAT *sp;
- Tcl_Obj *res;
- int result, ret;
-
- result = TCL_OK;
- /*
- * No args for this. Error if there are some.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbenv->lock_stat(dbenv, &sp, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "lock stat");
- if (result == TCL_ERROR)
- return (result);
- /*
- * Have our stats, now construct the name value
- * list pairs and free up the memory.
- */
- res = Tcl_NewObj();
-#ifdef HAVE_STATISTICS
- /*
- * MAKE_STAT_LIST assumes 'res' and 'error' label.
- */
- MAKE_STAT_LIST("Region size", sp->st_regsize);
- MAKE_STAT_LIST("Last allocated locker ID", sp->st_id);
- MAKE_STAT_LIST("Current maximum unused locker ID", sp->st_cur_maxid);
- MAKE_STAT_LIST("Maximum locks", sp->st_maxlocks);
- MAKE_STAT_LIST("Maximum lockers", sp->st_maxlockers);
- MAKE_STAT_LIST("Maximum objects", sp->st_maxobjects);
- MAKE_STAT_LIST("Lock modes", sp->st_nmodes);
- MAKE_STAT_LIST("Number of lock table partitions", sp->st_partitions);
- MAKE_STAT_LIST("Current number of locks", sp->st_nlocks);
- MAKE_STAT_LIST("Maximum number of locks so far", sp->st_maxnlocks);
- MAKE_STAT_LIST("Maximum number of locks in any hash bucket",
- sp->st_maxhlocks);
- MAKE_WSTAT_LIST("Maximum number of lock steals for an empty partition",
- sp->st_locksteals);
- MAKE_WSTAT_LIST("Maximum number lock steals in any partition",
- sp->st_maxlsteals);
- MAKE_STAT_LIST("Current number of lockers", sp->st_nlockers);
- MAKE_STAT_LIST("Maximum number of lockers so far", sp->st_maxnlockers);
- MAKE_STAT_LIST("Current number of objects", sp->st_nobjects);
- MAKE_STAT_LIST("Maximum number of objects so far", sp->st_maxnobjects);
- MAKE_STAT_LIST("Maximum number of objects in any hash bucket",
- sp->st_maxhobjects);
- MAKE_WSTAT_LIST("Maximum number of object steals for an empty partition",
- sp->st_objectsteals);
- MAKE_WSTAT_LIST("Maximum number object steals in any partition",
- sp->st_maxosteals);
- MAKE_WSTAT_LIST("Lock requests", sp->st_nrequests);
- MAKE_WSTAT_LIST("Lock releases", sp->st_nreleases);
- MAKE_WSTAT_LIST("Lock upgrades", sp->st_nupgrade);
- MAKE_WSTAT_LIST("Lock downgrades", sp->st_ndowngrade);
- MAKE_STAT_LIST("Number of conflicted locks for which we waited",
- sp->st_lock_wait);
- MAKE_STAT_LIST("Number of conflicted locks for which we did not wait",
- sp->st_lock_nowait);
- MAKE_WSTAT_LIST("Deadlocks detected", sp->st_ndeadlocks);
- MAKE_WSTAT_LIST("Number of region lock waits", sp->st_region_wait);
- MAKE_WSTAT_LIST("Number of region lock nowaits", sp->st_region_nowait);
- MAKE_WSTAT_LIST("Number of object allocation waits", sp->st_objs_wait);
- MAKE_STAT_LIST("Number of object allocation nowaits",
- sp->st_objs_nowait);
- MAKE_STAT_LIST("Number of locker allocation waits",
- sp->st_lockers_wait);
- MAKE_STAT_LIST("Number of locker allocation nowaits",
- sp->st_lockers_nowait);
- MAKE_WSTAT_LIST("Maximum hash bucket length", sp->st_hash_len);
- MAKE_STAT_LIST("Lock timeout value", sp->st_locktimeout);
- MAKE_WSTAT_LIST("Number of lock timeouts", sp->st_nlocktimeouts);
- MAKE_STAT_LIST("Transaction timeout value", sp->st_txntimeout);
- MAKE_WSTAT_LIST("Number of transaction timeouts", sp->st_ntxntimeouts);
- MAKE_WSTAT_LIST("Number lock partition mutex waits", sp->st_part_wait);
- MAKE_STAT_LIST("Number lock partition mutex nowaits",
- sp->st_part_nowait);
- MAKE_STAT_LIST("Maximum number waits on any lock partition mutex",
- sp->st_part_max_wait);
- MAKE_STAT_LIST("Maximum number nowaits on any lock partition mutex",
- sp->st_part_max_nowait);
-#endif
- Tcl_SetObjResult(interp, res);
-error:
- __os_ufree(dbenv->env, sp);
- return (result);
-}
-
-/*
- * tcl_LockTimeout --
- *
- * PUBLIC: int tcl_LockTimeout __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_LockTimeout(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- long timeout;
- int result, ret;
-
- /*
- * One arg, the timeout.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?timeout?");
- return (TCL_ERROR);
- }
- result = Tcl_GetLongFromObj(interp, objv[2], &timeout);
- if (result != TCL_OK)
- return (result);
- _debug_check();
- ret = dbenv->set_timeout(dbenv, (u_int32_t)timeout,
- DB_SET_LOCK_TIMEOUT);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "lock timeout");
- return (result);
-}
-
-/*
- * lock_Cmd --
- * Implements the "lock" widget.
- */
-static int
-lock_Cmd(clientData, interp, objc, objv)
- ClientData clientData; /* Lock handle */
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *lkcmds[] = {
- "put",
- NULL
- };
- enum lkcmds {
- LKPUT
- };
- DB_ENV *dbenv;
- DB_LOCK *lock;
- DBTCL_INFO *lkip;
- int cmdindex, result, ret;
-
- Tcl_ResetResult(interp);
- lock = (DB_LOCK *)clientData;
- lkip = _PtrToInfo((void *)lock);
- result = TCL_OK;
-
- if (lock == NULL) {
- Tcl_SetResult(interp, "NULL lock", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (lkip == NULL) {
- Tcl_SetResult(interp, "NULL lock info pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- dbenv = NAME_TO_ENV(lkip->i_parent->i_name);
- /*
- * No args for this. Error if there are some.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- /*
- * Get the command name index from the object based on the dbcmds
- * defined above.
- */
- if (Tcl_GetIndexFromObj(interp,
- objv[1], lkcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
-
- switch ((enum lkcmds)cmdindex) {
- case LKPUT:
- _debug_check();
- ret = dbenv->lock_put(dbenv, lock);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "lock put");
- (void)Tcl_DeleteCommand(interp, lkip->i_name);
- _DeleteInfo(lkip);
- __os_free(dbenv->env, lock);
- break;
- }
- return (result);
-}
-
-/*
- * tcl_LockVec --
- *
- * PUBLIC: int tcl_LockVec __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_LockVec(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* environment pointer */
-{
- static const char *lvopts[] = {
- "-nowait",
- NULL
- };
- enum lvopts {
- LVNOWAIT
- };
- static const char *lkops[] = {
- "get",
- "put",
- "put_all",
- "put_obj",
- "timeout",
- NULL
- };
- enum lkops {
- LKGET,
- LKPUT,
- LKPUTALL,
- LKPUTOBJ,
- LKTIMEOUT
- };
-
- DB_LOCK *lock;
- DB_LOCKREQ list;
- DBT obj;
- Tcl_Obj **myobjv, *res, *thisop;
- void *otmp;
- u_int32_t flag, lockid;
- int freeobj, i, myobjc, optindex, result, ret;
- char *lockname, msg[MSG_SIZE], newname[MSG_SIZE];
-
- result = TCL_OK;
- memset(newname, 0, MSG_SIZE);
- memset(&list, 0, sizeof(DB_LOCKREQ));
- flag = 0;
- freeobj = 0;
- otmp = NULL;
-
- /*
- * If -nowait is given, it MUST be first arg.
- */
- if (Tcl_GetIndexFromObj(interp, objv[2],
- lvopts, "option", TCL_EXACT, &optindex) == TCL_OK) {
- switch ((enum lvopts)optindex) {
- case LVNOWAIT:
- flag |= DB_LOCK_NOWAIT;
- break;
- }
- i = 3;
- } else {
- if (IS_HELP(objv[2]) == TCL_OK)
- return (TCL_OK);
- Tcl_ResetResult(interp);
- i = 2;
- }
-
- /*
- * Our next arg MUST be the locker ID.
- */
- result = _GetUInt32(interp, objv[i++], &lockid);
- if (result != TCL_OK)
- return (result);
-
- /*
- * All other remaining args are operation tuples.
- * Go through sequentially to decode, execute and build
- * up list of return values.
- */
- res = Tcl_NewListObj(0, NULL);
- while (i < objc) {
- /*
- * Get the list of the tuple.
- */
- lock = NULL;
- result = Tcl_ListObjGetElements(interp, objv[i],
- &myobjc, &myobjv);
- if (result == TCL_OK)
- i++;
- else
- break;
- /*
- * First we will set up the list of requests.
- * We will make a "second pass" after we get back
- * the results from the lock_vec call to create
- * the return list.
- */
- if (Tcl_GetIndexFromObj(interp, myobjv[0],
- lkops, "option", TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(myobjv[0]);
- goto error;
- }
- switch ((enum lkops)optindex) {
- case LKGET:
- if (myobjc != 3) {
- Tcl_WrongNumArgs(interp, 1, myobjv,
- "{get obj mode}");
- result = TCL_ERROR;
- goto error;
- }
- result = _LockMode(interp, myobjv[2], &list.mode);
- if (result != TCL_OK)
- goto error;
- ret = _CopyObjBytes(interp, myobjv[1], &otmp,
- &obj.size, &freeobj);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "lock vec");
- return (result);
- }
- obj.data = otmp;
- ret = _GetThisLock(interp, dbenv, lockid, flag,
- &obj, list.mode, newname);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "lock vec");
- thisop = Tcl_NewIntObj(ret);
- (void)Tcl_ListObjAppendElement(interp, res,
- thisop);
- goto error;
- }
- thisop = NewStringObj(newname, strlen(newname));
- (void)Tcl_ListObjAppendElement(interp, res, thisop);
- if (freeobj && otmp != NULL) {
- __os_free(dbenv->env, otmp);
- freeobj = 0;
- }
- continue;
- case LKPUT:
- if (myobjc != 2) {
- Tcl_WrongNumArgs(interp, 1, myobjv,
- "{put lock}");
- result = TCL_ERROR;
- goto error;
- }
- list.op = DB_LOCK_PUT;
- lockname = Tcl_GetStringFromObj(myobjv[1], NULL);
- lock = NAME_TO_LOCK(lockname);
- if (lock == NULL) {
- snprintf(msg, MSG_SIZE, "Invalid lock: %s\n",
- lockname);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- goto error;
- }
- list.lock = *lock;
- break;
- case LKPUTALL:
- if (myobjc != 1) {
- Tcl_WrongNumArgs(interp, 1, myobjv,
- "{put_all}");
- result = TCL_ERROR;
- goto error;
- }
- list.op = DB_LOCK_PUT_ALL;
- break;
- case LKPUTOBJ:
- if (myobjc != 2) {
- Tcl_WrongNumArgs(interp, 1, myobjv,
- "{put_obj obj}");
- result = TCL_ERROR;
- goto error;
- }
- list.op = DB_LOCK_PUT_OBJ;
- ret = _CopyObjBytes(interp, myobjv[1], &otmp,
- &obj.size, &freeobj);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "lock vec");
- return (result);
- }
- obj.data = otmp;
- list.obj = &obj;
- break;
- case LKTIMEOUT:
- list.op = DB_LOCK_TIMEOUT;
- break;
-
- }
- /*
- * We get here, we have set up our request, now call
- * lock_vec.
- */
- _debug_check();
- ret = dbenv->lock_vec(dbenv, lockid, flag, &list, 1, NULL);
- /*
- * Now deal with whether or not the operation succeeded.
- * Get's were done above, all these are only puts.
- */
- thisop = Tcl_NewIntObj(ret);
- result = Tcl_ListObjAppendElement(interp, res, thisop);
- if (ret != 0 && result == TCL_OK)
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "lock put");
- if (freeobj && otmp != NULL) {
- __os_free(dbenv->env, otmp);
- freeobj = 0;
- }
- /*
- * We did a put of some kind. Since we did that,
- * we have to delete the commands associated with
- * any of the locks we just put.
- */
- _LockPutInfo(interp, list.op, lock, lockid, &obj);
- }
-
- if (result == TCL_OK && res)
- Tcl_SetObjResult(interp, res);
-error:
- return (result);
-}
-
-static int
-_LockMode(interp, obj, mode)
- Tcl_Interp *interp;
- Tcl_Obj *obj;
- db_lockmode_t *mode;
-{
- static const char *lkmode[] = {
- "ng",
- "read",
- "write",
- "iwrite",
- "iread",
- "iwr",
- NULL
- };
- enum lkmode {
- LK_NG,
- LK_READ,
- LK_WRITE,
- LK_IWRITE,
- LK_IREAD,
- LK_IWR
- };
- int optindex;
-
- if (Tcl_GetIndexFromObj(interp, obj, lkmode, "option",
- TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(obj));
- switch ((enum lkmode)optindex) {
- case LK_NG:
- *mode = DB_LOCK_NG;
- break;
- case LK_READ:
- *mode = DB_LOCK_READ;
- break;
- case LK_WRITE:
- *mode = DB_LOCK_WRITE;
- break;
- case LK_IREAD:
- *mode = DB_LOCK_IREAD;
- break;
- case LK_IWRITE:
- *mode = DB_LOCK_IWRITE;
- break;
- case LK_IWR:
- *mode = DB_LOCK_IWR;
- break;
- }
- return (TCL_OK);
-}
-
-static void
-_LockPutInfo(interp, op, lock, lockid, objp)
- Tcl_Interp *interp;
- db_lockop_t op;
- DB_LOCK *lock;
- u_int32_t lockid;
- DBT *objp;
-{
- DBTCL_INFO *p, *nextp;
- int found;
-
- for (p = LIST_FIRST(&__db_infohead); p != NULL; p = nextp) {
- found = 0;
- nextp = LIST_NEXT(p, entries);
- if ((op == DB_LOCK_PUT && (p->i_lock == lock)) ||
- (op == DB_LOCK_PUT_ALL && p->i_locker == lockid) ||
- (op == DB_LOCK_PUT_OBJ && p->i_lockobj.data &&
- memcmp(p->i_lockobj.data, objp->data, objp->size) == 0))
- found = 1;
- if (found) {
- (void)Tcl_DeleteCommand(interp, p->i_name);
- __os_free(NULL, p->i_lock);
- _DeleteInfo(p);
- }
- }
-}
-
-static int
-_GetThisLock(interp, dbenv, lockid, flag, objp, mode, newname)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Env handle */
- u_int32_t lockid; /* Locker ID */
- u_int32_t flag; /* Lock flag */
- DBT *objp; /* Object to lock */
- db_lockmode_t mode; /* Lock mode */
- char *newname; /* New command name */
-{
- DBTCL_INFO *envip, *ip;
- DB_LOCK *lock;
- int result, ret;
-
- result = TCL_OK;
- envip = _PtrToInfo((void *)dbenv);
- if (envip == NULL) {
- Tcl_SetResult(interp, "Could not find env info\n", TCL_STATIC);
- return (TCL_ERROR);
- }
- snprintf(newname, MSG_SIZE, "%s.lock%d",
- envip->i_name, envip->i_envlockid);
- ip = _NewInfo(interp, NULL, newname, I_LOCK);
- if (ip == NULL) {
- Tcl_SetResult(interp, "Could not set up info",
- TCL_STATIC);
- return (TCL_ERROR);
- }
- ret = __os_malloc(dbenv->env, sizeof(DB_LOCK), &lock);
- if (ret != 0) {
- Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbenv->lock_get(dbenv, lockid, flag, objp, mode, lock);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "lock get");
- if (result == TCL_ERROR) {
- __os_free(dbenv->env, lock);
- _DeleteInfo(ip);
- return (result);
- }
- /*
- * Success. Set up return. Set up new info
- * and command widget for this lock.
- */
- ret = __os_malloc(dbenv->env, objp->size, &ip->i_lockobj.data);
- if (ret != 0) {
- Tcl_SetResult(interp, "Could not duplicate obj",
- TCL_STATIC);
- (void)dbenv->lock_put(dbenv, lock);
- __os_free(dbenv->env, lock);
- _DeleteInfo(ip);
- result = TCL_ERROR;
- goto error;
- }
- memcpy(ip->i_lockobj.data, objp->data, objp->size);
- ip->i_lockobj.size = objp->size;
- envip->i_envlockid++;
- ip->i_parent = envip;
- ip->i_locker = lockid;
- _SetInfoData(ip, lock);
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)lock_Cmd, (ClientData)lock, NULL);
-error:
- return (result);
-}
-#endif
diff --git a/tcl/tcl_log.c b/tcl/tcl_log.c
deleted file mode 100644
index 3b77208..0000000
--- a/tcl/tcl_log.c
+++ /dev/null
@@ -1,770 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/log.h"
-#include "dbinc/tcl_db.h"
-
-#ifdef CONFIG_TEST
-static int tcl_LogcGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_LOGC *));
-
-/*
- * tcl_LogArchive --
- *
- * PUBLIC: int tcl_LogArchive __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_LogArchive(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- static const char *archopts[] = {
- "-arch_abs", "-arch_data", "-arch_log", "-arch_remove",
- NULL
- };
- enum archopts {
- ARCH_ABS, ARCH_DATA, ARCH_LOG, ARCH_REMOVE
- };
- Tcl_Obj *fileobj, *res;
- u_int32_t flag;
- int i, optindex, result, ret;
- char **file, **list;
-
- result = TCL_OK;
- flag = 0;
- /*
- * Get the flag index from the object based on the options
- * defined above.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i],
- archopts, "option", TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(objv[i]));
- i++;
- switch ((enum archopts)optindex) {
- case ARCH_ABS:
- flag |= DB_ARCH_ABS;
- break;
- case ARCH_DATA:
- flag |= DB_ARCH_DATA;
- break;
- case ARCH_LOG:
- flag |= DB_ARCH_LOG;
- break;
- case ARCH_REMOVE:
- flag |= DB_ARCH_REMOVE;
- break;
- }
- }
- _debug_check();
- list = NULL;
- ret = dbenv->log_archive(dbenv, &list, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "log archive");
- if (result == TCL_OK) {
- res = Tcl_NewListObj(0, NULL);
- for (file = list; file != NULL && *file != NULL; file++) {
- fileobj = NewStringObj(*file, strlen(*file));
- result = Tcl_ListObjAppendElement(interp, res, fileobj);
- if (result != TCL_OK)
- break;
- }
- Tcl_SetObjResult(interp, res);
- }
- if (list != NULL)
- __os_ufree(dbenv->env, list);
- return (result);
-}
-
-/*
- * tcl_LogCompare --
- *
- * PUBLIC: int tcl_LogCompare __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*));
- */
-int
-tcl_LogCompare(interp, objc, objv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- DB_LSN lsn0, lsn1;
- Tcl_Obj *res;
- int result, ret;
-
- result = TCL_OK;
- /*
- * No flags, must be 4 args.
- */
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "lsn1 lsn2");
- return (TCL_ERROR);
- }
-
- result = _GetLsn(interp, objv[2], &lsn0);
- if (result == TCL_ERROR)
- return (result);
- result = _GetLsn(interp, objv[3], &lsn1);
- if (result == TCL_ERROR)
- return (result);
-
- _debug_check();
- ret = log_compare(&lsn0, &lsn1);
- res = Tcl_NewIntObj(ret);
- Tcl_SetObjResult(interp, res);
- return (result);
-}
-
-/*
- * tcl_LogFile --
- *
- * PUBLIC: int tcl_LogFile __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_LogFile(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- DB_LSN lsn;
- Tcl_Obj *res;
- size_t len;
- int result, ret;
- char *name;
-
- result = TCL_OK;
- /*
- * No flags, must be 3 args.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "lsn");
- return (TCL_ERROR);
- }
-
- result = _GetLsn(interp, objv[2], &lsn);
- if (result == TCL_ERROR)
- return (result);
-
- len = MSG_SIZE;
- ret = ENOMEM;
- name = NULL;
- while (ret == ENOMEM) {
- if (name != NULL)
- __os_free(dbenv->env, name);
- ret = __os_malloc(dbenv->env, len, &name);
- if (ret != 0) {
- Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC);
- break;
- }
- _debug_check();
- ret = dbenv->log_file(dbenv, &lsn, name, len);
- len *= 2;
- }
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "log_file");
- if (ret == 0) {
- res = NewStringObj(name, strlen(name));
- Tcl_SetObjResult(interp, res);
- }
-
- if (name != NULL)
- __os_free(dbenv->env, name);
-
- return (result);
-}
-
-/*
- * tcl_LogFlush --
- *
- * PUBLIC: int tcl_LogFlush __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_LogFlush(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- DB_LSN lsn, *lsnp;
- int result, ret;
-
- result = TCL_OK;
- /*
- * No flags, must be 2 or 3 args.
- */
- if (objc > 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?lsn?");
- return (TCL_ERROR);
- }
-
- if (objc == 3) {
- lsnp = &lsn;
- result = _GetLsn(interp, objv[2], &lsn);
- if (result == TCL_ERROR)
- return (result);
- } else
- lsnp = NULL;
-
- _debug_check();
- ret = dbenv->log_flush(dbenv, lsnp);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "log_flush");
- return (result);
-}
-
-/*
- * tcl_LogGet --
- *
- * PUBLIC: int tcl_LogGet __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_LogGet(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
-
- COMPQUIET(objv, NULL);
- COMPQUIET(objc, 0);
- COMPQUIET(dbenv, NULL);
-
- Tcl_SetResult(interp, "FAIL: log_get deprecated\n", TCL_STATIC);
- return (TCL_ERROR);
-}
-
-/*
- * tcl_LogPut --
- *
- * PUBLIC: int tcl_LogPut __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_LogPut(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- static const char *logputopts[] = {
- "-flush",
- NULL
- };
- enum logputopts {
- LOGPUT_FLUSH
- };
- DB_LSN lsn;
- DBT data;
- Tcl_Obj *intobj, *res;
- void *dtmp;
- u_int32_t flag;
- int freedata, optindex, result, ret;
-
- result = TCL_OK;
- flag = 0;
- freedata = 0;
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-args? record");
- return (TCL_ERROR);
- }
-
- /*
- * Data/record must be the last arg.
- */
- memset(&data, 0, sizeof(data));
- ret = _CopyObjBytes(interp, objv[objc-1], &dtmp,
- &data.size, &freedata);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "log put");
- return (result);
- }
- data.data = dtmp;
-
- /*
- * Get the command name index from the object based on the options
- * defined above.
- */
- if (objc == 4) {
- if (Tcl_GetIndexFromObj(interp, objv[2],
- logputopts, "option", TCL_EXACT, &optindex) != TCL_OK) {
- return (IS_HELP(objv[2]));
- }
- switch ((enum logputopts)optindex) {
- case LOGPUT_FLUSH:
- flag = DB_FLUSH;
- break;
- }
- }
-
- if (result == TCL_ERROR)
- return (result);
-
- _debug_check();
- ret = dbenv->log_put(dbenv, &lsn, &data, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "log_put");
- if (result == TCL_ERROR)
- return (result);
- res = Tcl_NewListObj(0, NULL);
- intobj = Tcl_NewWideIntObj((Tcl_WideInt)lsn.file);
- result = Tcl_ListObjAppendElement(interp, res, intobj);
- intobj = Tcl_NewWideIntObj((Tcl_WideInt)lsn.offset);
- result = Tcl_ListObjAppendElement(interp, res, intobj);
- Tcl_SetObjResult(interp, res);
- if (freedata)
- __os_free(NULL, dtmp);
- return (result);
-}
-/*
- * tcl_LogStat --
- *
- * PUBLIC: int tcl_LogStat __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_LogStat(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- DB_LOG_STAT *sp;
- Tcl_Obj *res;
- int result, ret;
-
- result = TCL_OK;
- /*
- * No args for this. Error if there are some.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbenv->log_stat(dbenv, &sp, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "log stat");
- if (result == TCL_ERROR)
- return (result);
-
- /*
- * Have our stats, now construct the name value
- * list pairs and free up the memory.
- */
- res = Tcl_NewObj();
- /*
- * MAKE_STAT_LIST assumes 'res' and 'error' label.
- */
-#ifdef HAVE_STATISTICS
- MAKE_STAT_LIST("Magic", sp->st_magic);
- MAKE_STAT_LIST("Log file Version", sp->st_version);
- MAKE_STAT_LIST("Region size", sp->st_regsize);
- MAKE_STAT_LIST("Log file mode", sp->st_mode);
- MAKE_STAT_LIST("Log record cache size", sp->st_lg_bsize);
- MAKE_STAT_LIST("Current log file size", sp->st_lg_size);
- MAKE_WSTAT_LIST("Log file records written", sp->st_record);
- MAKE_STAT_LIST("Mbytes written", sp->st_w_mbytes);
- MAKE_STAT_LIST("Bytes written (over Mb)", sp->st_w_bytes);
- MAKE_STAT_LIST("Mbytes written since checkpoint", sp->st_wc_mbytes);
- MAKE_STAT_LIST("Bytes written (over Mb) since checkpoint",
- sp->st_wc_bytes);
- MAKE_WSTAT_LIST("Times log written", sp->st_wcount);
- MAKE_STAT_LIST("Times log written because cache filled up",
- sp->st_wcount_fill);
- MAKE_WSTAT_LIST("Times log read from disk", sp->st_rcount);
- MAKE_WSTAT_LIST("Times log flushed to disk", sp->st_scount);
- MAKE_STAT_LIST("Current log file number", sp->st_cur_file);
- MAKE_STAT_LIST("Current log file offset", sp->st_cur_offset);
- MAKE_STAT_LIST("On-disk log file number", sp->st_disk_file);
- MAKE_STAT_LIST("On-disk log file offset", sp->st_disk_offset);
- MAKE_STAT_LIST("Max commits in a log flush", sp->st_maxcommitperflush);
- MAKE_STAT_LIST("Min commits in a log flush", sp->st_mincommitperflush);
- MAKE_WSTAT_LIST("Number of region lock waits", sp->st_region_wait);
- MAKE_WSTAT_LIST("Number of region lock nowaits", sp->st_region_nowait);
-#endif
- Tcl_SetObjResult(interp, res);
-error:
- __os_ufree(dbenv->env, sp);
- return (result);
-}
-
-/*
- * logc_Cmd --
- * Implements the log cursor command.
- *
- * PUBLIC: int logc_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
- */
-int
-logc_Cmd(clientData, interp, objc, objv)
- ClientData clientData; /* Cursor handle */
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *logccmds[] = {
- "close",
- "get",
- "version",
- NULL
- };
- enum logccmds {
- LOGCCLOSE,
- LOGCGET,
- LOGCVERSION
- };
- DB_LOGC *logc;
- DBTCL_INFO *logcip;
- Tcl_Obj *res;
- u_int32_t version;
- int cmdindex, result, ret;
-
- Tcl_ResetResult(interp);
- logc = (DB_LOGC *)clientData;
- logcip = _PtrToInfo((void *)logc);
- result = TCL_OK;
-
- if (objc <= 1) {
- Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs");
- return (TCL_ERROR);
- }
- if (logc == NULL) {
- Tcl_SetResult(interp, "NULL logc pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (logcip == NULL) {
- Tcl_SetResult(interp, "NULL logc info pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the berkdbcmds
- * defined above.
- */
- if (Tcl_GetIndexFromObj(interp, objv[1], logccmds, "command",
- TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
- switch ((enum logccmds)cmdindex) {
- case LOGCCLOSE:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = logc->close(logc, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "logc close");
- if (result == TCL_OK) {
- (void)Tcl_DeleteCommand(interp, logcip->i_name);
- _DeleteInfo(logcip);
- }
- break;
- case LOGCGET:
- result = tcl_LogcGet(interp, objc, objv, logc);
- break;
- case LOGCVERSION:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = logc->version(logc, &version, 0);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "logc version")) == TCL_OK) {
- res = Tcl_NewIntObj((int)version);
- Tcl_SetObjResult(interp, res);
- }
- break;
- }
-
- return (result);
-}
-
-static int
-tcl_LogcGet(interp, objc, objv, logc)
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj * CONST *objv;
- DB_LOGC *logc;
-{
- static const char *logcgetopts[] = {
- "-current",
- "-first",
- "-last",
- "-next",
- "-prev",
- "-set",
- NULL
- };
- enum logcgetopts {
- LOGCGET_CURRENT,
- LOGCGET_FIRST,
- LOGCGET_LAST,
- LOGCGET_NEXT,
- LOGCGET_PREV,
- LOGCGET_SET
- };
- DB_LSN lsn;
- DBT data;
- Tcl_Obj *dataobj, *lsnlist, *myobjv[2], *res;
- u_int32_t flag;
- int i, myobjc, optindex, result, ret;
-
- result = TCL_OK;
- res = NULL;
- flag = 0;
-
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-args? lsn");
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the options
- * defined above.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i],
- logcgetopts, "option", TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(objv[i]));
- i++;
- switch ((enum logcgetopts)optindex) {
- case LOGCGET_CURRENT:
- FLAG_CHECK(flag);
- flag |= DB_CURRENT;
- break;
- case LOGCGET_FIRST:
- FLAG_CHECK(flag);
- flag |= DB_FIRST;
- break;
- case LOGCGET_LAST:
- FLAG_CHECK(flag);
- flag |= DB_LAST;
- break;
- case LOGCGET_NEXT:
- FLAG_CHECK(flag);
- flag |= DB_NEXT;
- break;
- case LOGCGET_PREV:
- FLAG_CHECK(flag);
- flag |= DB_PREV;
- break;
- case LOGCGET_SET:
- FLAG_CHECK(flag);
- flag |= DB_SET;
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-set lsn?");
- result = TCL_ERROR;
- break;
- }
- result = _GetLsn(interp, objv[i++], &lsn);
- break;
- }
- }
-
- if (result == TCL_ERROR)
- return (result);
-
- memset(&data, 0, sizeof(data));
-
- _debug_check();
- ret = logc->get(logc, &lsn, &data, flag);
-
- res = Tcl_NewListObj(0, NULL);
- if (res == NULL)
- goto memerr;
-
- if (ret == 0) {
- /*
- * Success. Set up return list as {LSN data} where LSN
- * is a sublist {file offset}.
- */
- myobjc = 2;
- myobjv[0] = Tcl_NewWideIntObj((Tcl_WideInt)lsn.file);
- myobjv[1] = Tcl_NewWideIntObj((Tcl_WideInt)lsn.offset);
- lsnlist = Tcl_NewListObj(myobjc, myobjv);
- if (lsnlist == NULL)
- goto memerr;
-
- result = Tcl_ListObjAppendElement(interp, res, lsnlist);
- dataobj = NewStringObj(data.data, data.size);
- if (dataobj == NULL) {
- goto memerr;
- }
- result = Tcl_ListObjAppendElement(interp, res, dataobj);
- } else
- result = _ReturnSetup(interp, ret, DB_RETOK_LGGET(ret),
- "DB_LOGC->get");
-
- Tcl_SetObjResult(interp, res);
-
- if (0) {
-memerr: if (res != NULL) {
- Tcl_DecrRefCount(res);
- }
- Tcl_SetResult(interp, "allocation failed", TCL_STATIC);
- }
-
- return (result);
-}
-
-static const char *confwhich[] = {
- "autoremove",
- "direct",
- "dsync",
- "inmemory",
- "zero",
- NULL
-};
-enum logwhich {
- LOGCONF_AUTO,
- LOGCONF_DIRECT,
- LOGCONF_DSYNC,
- LOGCONF_INMEMORY,
- LOGCONF_ZERO
-};
-
-/*
- * tcl_LogConfig --
- * Call DB_ENV->rep_set_config().
- *
- * PUBLIC: int tcl_LogConfig
- * PUBLIC: __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *));
- */
-int
-tcl_LogConfig(interp, dbenv, list)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Environment pointer */
- Tcl_Obj *list; /* {which on|off} */
-{
- static const char *confonoff[] = {
- "off",
- "on",
- NULL
- };
- enum confonoff {
- LOGCONF_OFF,
- LOGCONF_ON
- };
- Tcl_Obj **myobjv, *onoff, *which;
- int myobjc, on, optindex, result, ret;
- u_int32_t wh;
-
- result = Tcl_ListObjGetElements(interp, list, &myobjc, &myobjv);
- if (myobjc != 2)
- Tcl_WrongNumArgs(interp, 2, myobjv, "?{which onoff}?");
- which = myobjv[0];
- onoff = myobjv[1];
- if (result != TCL_OK)
- return (result);
- if (Tcl_GetIndexFromObj(interp, which, confwhich, "option",
- TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(which));
-
- switch ((enum logwhich)optindex) {
- case LOGCONF_AUTO:
- wh = DB_LOG_AUTO_REMOVE;
- break;
- case LOGCONF_DIRECT:
- wh = DB_LOG_DIRECT;
- break;
- case LOGCONF_DSYNC:
- wh = DB_LOG_DSYNC;
- break;
- case LOGCONF_INMEMORY:
- wh = DB_LOG_IN_MEMORY;
- break;
- case LOGCONF_ZERO:
- wh = DB_LOG_ZERO;
- break;
- default:
- return (TCL_ERROR);
- }
- if (Tcl_GetIndexFromObj(interp, onoff, confonoff, "option",
- TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(onoff));
- switch ((enum confonoff)optindex) {
- case LOGCONF_OFF:
- on = 0;
- break;
- case LOGCONF_ON:
- on = 1;
- break;
- default:
- return (TCL_ERROR);
- }
- ret = dbenv->log_set_config(dbenv, wh, on);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_config"));
-}
-
-/*
- * tcl_LogGetConfig --
- * Call DB_ENV->rep_get_config().
- *
- * PUBLIC: int tcl_LogGetConfig
- * PUBLIC: __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *));
- */
-int
-tcl_LogGetConfig(interp, dbenv, which)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Environment pointer */
- Tcl_Obj *which; /* which flag */
-{
- Tcl_Obj *res;
- int on, optindex, result, ret;
- u_int32_t wh;
-
- if (Tcl_GetIndexFromObj(interp, which, confwhich, "option",
- TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(which));
-
- res = NULL;
- switch ((enum logwhich)optindex) {
- case LOGCONF_AUTO:
- wh = DB_LOG_AUTO_REMOVE;
- break;
- case LOGCONF_DIRECT:
- wh = DB_LOG_DIRECT;
- break;
- case LOGCONF_DSYNC:
- wh = DB_LOG_DSYNC;
- break;
- case LOGCONF_INMEMORY:
- wh = DB_LOG_IN_MEMORY;
- break;
- case LOGCONF_ZERO:
- wh = DB_LOG_ZERO;
- break;
- default:
- return (TCL_ERROR);
- }
- ret = dbenv->log_get_config(dbenv, wh, &on);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env log_config")) == TCL_OK) {
- res = Tcl_NewIntObj(on);
- Tcl_SetObjResult(interp, res);
- }
- return (result);
-}
-#endif
diff --git a/tcl/tcl_mp.c b/tcl/tcl_mp.c
deleted file mode 100644
index 5c6488f..0000000
--- a/tcl/tcl_mp.c
+++ /dev/null
@@ -1,939 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/tcl_db.h"
-
-/*
- * Prototypes for procedures defined later in this file:
- */
-#ifdef CONFIG_TEST
-static int mp_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-static int pg_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-static int tcl_MpGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- DB_MPOOLFILE *, DBTCL_INFO *));
-static int tcl_Pg __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- void *, DB_MPOOLFILE *, DBTCL_INFO *));
-static int tcl_PgInit __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- void *, DBTCL_INFO *));
-static int tcl_PgIsset __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- void *, DBTCL_INFO *));
-#endif
-
-/*
- * _MpInfoDelete --
- * Removes "sub" mp page info structures that are children
- * of this mp.
- *
- * PUBLIC: void _MpInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
- */
-void
-_MpInfoDelete(interp, mpip)
- Tcl_Interp *interp; /* Interpreter */
- DBTCL_INFO *mpip; /* Info for mp */
-{
- DBTCL_INFO *nextp, *p;
-
- for (p = LIST_FIRST(&__db_infohead); p != NULL; p = nextp) {
- /*
- * Check if this info structure "belongs" to this
- * mp. Remove its commands and info structure.
- */
- nextp = LIST_NEXT(p, entries);
- if (p->i_parent == mpip && p->i_type == I_PG) {
- (void)Tcl_DeleteCommand(interp, p->i_name);
- _DeleteInfo(p);
- }
- }
-}
-
-#ifdef CONFIG_TEST
-/*
- * tcl_MpSync --
- *
- * PUBLIC: int tcl_MpSync __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_MpSync(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
-
- DB_LSN lsn, *lsnp;
- int result, ret;
-
- result = TCL_OK;
- lsnp = NULL;
- /*
- * No flags, must be 3 args.
- */
- if (objc == 3) {
- result = _GetLsn(interp, objv[2], &lsn);
- if (result == TCL_ERROR)
- return (result);
- lsnp = &lsn;
- }
- else if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "lsn");
- return (TCL_ERROR);
- }
-
- _debug_check();
- ret = dbenv->memp_sync(dbenv, lsnp);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "memp sync"));
-}
-
-/*
- * tcl_MpTrickle --
- *
- * PUBLIC: int tcl_MpTrickle __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_MpTrickle(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
-
- Tcl_Obj *res;
- int pages, percent, result, ret;
-
- result = TCL_OK;
- /*
- * No flags, must be 3 args.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "percent");
- return (TCL_ERROR);
- }
-
- result = Tcl_GetIntFromObj(interp, objv[2], &percent);
- if (result == TCL_ERROR)
- return (result);
-
- _debug_check();
- ret = dbenv->memp_trickle(dbenv, percent, &pages);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "memp trickle");
- if (result == TCL_ERROR)
- return (result);
-
- res = Tcl_NewIntObj(pages);
- Tcl_SetObjResult(interp, res);
- return (result);
-
-}
-
-/*
- * tcl_Mp --
- *
- * PUBLIC: int tcl_Mp __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
- */
-int
-tcl_Mp(interp, objc, objv, dbenv, envip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
- DBTCL_INFO *envip; /* Info pointer */
-{
- static const char *mpopts[] = {
- "-create",
- "-mode",
- "-multiversion",
- "-nommap",
- "-pagesize",
- "-rdonly",
- NULL
- };
- enum mpopts {
- MPCREATE,
- MPMODE,
- MPMULTIVERSION,
- MPNOMMAP,
- MPPAGE,
- MPRDONLY
- };
- DBTCL_INFO *ip;
- DB_MPOOLFILE *mpf;
- Tcl_Obj *res;
- u_int32_t flag;
- int i, pgsize, mode, optindex, result, ret;
- char *file, newname[MSG_SIZE];
-
- result = TCL_OK;
- i = 2;
- flag = 0;
- mode = 0;
- pgsize = 0;
- memset(newname, 0, MSG_SIZE);
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i],
- mpopts, "option", TCL_EXACT, &optindex) != TCL_OK) {
- /*
- * Reset the result so we don't get an errant
- * error message if there is another error.
- * This arg is the file name.
- */
- if (IS_HELP(objv[i]) == TCL_OK)
- return (TCL_OK);
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum mpopts)optindex) {
- case MPCREATE:
- flag |= DB_CREATE;
- break;
- case MPMODE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-mode mode?");
- result = TCL_ERROR;
- break;
- }
- /*
- * Don't need to check result here because
- * if TCL_ERROR, the error message is already
- * set up, and we'll bail out below. If ok,
- * the mode is set and we go on.
- */
- result = Tcl_GetIntFromObj(interp, objv[i++], &mode);
- break;
- case MPMULTIVERSION:
- flag |= DB_MULTIVERSION;
- break;
- case MPNOMMAP:
- flag |= DB_NOMMAP;
- break;
- case MPPAGE:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-pagesize size?");
- result = TCL_ERROR;
- break;
- }
- /*
- * Don't need to check result here because
- * if TCL_ERROR, the error message is already
- * set up, and we'll bail out below. If ok,
- * the mode is set and we go on.
- */
- result = Tcl_GetIntFromObj(interp, objv[i++], &pgsize);
- break;
- case MPRDONLY:
- flag |= DB_RDONLY;
- break;
- }
- if (result != TCL_OK)
- goto error;
- }
- /*
- * Any left over arg is a file name. It better be the last arg.
- */
- file = NULL;
- if (i != objc) {
- if (i != objc - 1) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args? ?file?");
- result = TCL_ERROR;
- goto error;
- }
- file = Tcl_GetStringFromObj(objv[i++], NULL);
- }
-
- snprintf(newname, sizeof(newname), "%s.mp%d",
- envip->i_name, envip->i_envmpid);
- ip = _NewInfo(interp, NULL, newname, I_MP);
- if (ip == NULL) {
- Tcl_SetResult(interp, "Could not set up info",
- TCL_STATIC);
- return (TCL_ERROR);
- }
-
- _debug_check();
- if ((ret = dbenv->memp_fcreate(dbenv, &mpf, 0)) != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "mpool");
- _DeleteInfo(ip);
- goto error;
- }
-
- /*
- * XXX
- * Interface doesn't currently support DB_MPOOLFILE configuration.
- */
- if ((ret = mpf->open(mpf, file, flag, mode, (size_t)pgsize)) != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "mpool");
- _DeleteInfo(ip);
-
- (void)mpf->close(mpf, 0);
- goto error;
- }
-
- /*
- * Success. Set up return. Set up new info and command widget for
- * this mpool.
- */
- envip->i_envmpid++;
- ip->i_parent = envip;
- ip->i_pgsz = pgsize;
- _SetInfoData(ip, mpf);
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)mp_Cmd, (ClientData)mpf, NULL);
- res = NewStringObj(newname, strlen(newname));
- Tcl_SetObjResult(interp, res);
-
-error:
- return (result);
-}
-
-/*
- * tcl_MpStat --
- *
- * PUBLIC: int tcl_MpStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_MpStat(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- DB_MPOOL_FSTAT **fsp, **savefsp;
- DB_MPOOL_STAT *sp;
- int result;
- int ret;
- Tcl_Obj *res;
- Tcl_Obj *res1;
-
- result = TCL_OK;
- savefsp = NULL;
- /*
- * No args for this. Error if there are some.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbenv->memp_stat(dbenv, &sp, &fsp, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "memp stat");
- if (result == TCL_ERROR)
- return (result);
-
- /*
- * Have our stats, now construct the name value
- * list pairs and free up the memory.
- */
- res = Tcl_NewObj();
-#ifdef HAVE_STATISTICS
- /*
- * MAKE_STAT_LIST assumes 'res' and 'error' label.
- */
- MAKE_STAT_LIST("Cache size (gbytes)", sp->st_gbytes);
- MAKE_STAT_LIST("Cache size (bytes)", sp->st_bytes);
- MAKE_STAT_LIST("Number of caches", sp->st_ncache);
- MAKE_STAT_LIST("Maximum number of caches", sp->st_max_ncache);
- MAKE_STAT_LIST("Region size", sp->st_regsize);
- MAKE_STAT_LIST("Maximum memory-mapped file size", sp->st_mmapsize);
- MAKE_STAT_LIST("Maximum open file descriptors", sp->st_maxopenfd);
- MAKE_STAT_LIST("Maximum sequential buffer writes", sp->st_maxwrite);
- MAKE_STAT_LIST(
- "Sleep after writing maximum buffers", sp->st_maxwrite_sleep);
- MAKE_STAT_LIST("Pages mapped into address space", sp->st_map);
- MAKE_WSTAT_LIST("Cache hits", sp->st_cache_hit);
- MAKE_WSTAT_LIST("Cache misses", sp->st_cache_miss);
- MAKE_WSTAT_LIST("Pages created", sp->st_page_create);
- MAKE_WSTAT_LIST("Pages read in", sp->st_page_in);
- MAKE_WSTAT_LIST("Pages written", sp->st_page_out);
- MAKE_WSTAT_LIST("Clean page evictions", sp->st_ro_evict);
- MAKE_WSTAT_LIST("Dirty page evictions", sp->st_rw_evict);
- MAKE_WSTAT_LIST("Dirty pages trickled", sp->st_page_trickle);
- MAKE_STAT_LIST("Cached pages", sp->st_pages);
- MAKE_WSTAT_LIST("Cached clean pages", sp->st_page_clean);
- MAKE_WSTAT_LIST("Cached dirty pages", sp->st_page_dirty);
- MAKE_WSTAT_LIST("Hash buckets", sp->st_hash_buckets);
- MAKE_WSTAT_LIST("Default pagesize", sp->st_pagesize);
- MAKE_WSTAT_LIST("Hash lookups", sp->st_hash_searches);
- MAKE_WSTAT_LIST("Longest hash chain found", sp->st_hash_longest);
- MAKE_WSTAT_LIST("Hash elements examined", sp->st_hash_examined);
- MAKE_WSTAT_LIST("Number of hash bucket nowaits", sp->st_hash_nowait);
- MAKE_WSTAT_LIST("Number of hash bucket waits", sp->st_hash_wait);
- MAKE_STAT_LIST("Maximum number of hash bucket nowaits",
- sp->st_hash_max_nowait);
- MAKE_STAT_LIST("Maximum number of hash bucket waits",
- sp->st_hash_max_wait);
- MAKE_WSTAT_LIST("Number of region lock nowaits", sp->st_region_nowait);
- MAKE_WSTAT_LIST("Number of region lock waits", sp->st_region_wait);
- MAKE_WSTAT_LIST("Buffers frozen", sp->st_mvcc_frozen);
- MAKE_WSTAT_LIST("Buffers thawed", sp->st_mvcc_thawed);
- MAKE_WSTAT_LIST("Frozen buffers freed", sp->st_mvcc_freed);
- MAKE_WSTAT_LIST("Page allocations", sp->st_alloc);
- MAKE_STAT_LIST("Buckets examined during allocation",
- sp->st_alloc_buckets);
- MAKE_STAT_LIST("Maximum buckets examined during allocation",
- sp->st_alloc_max_buckets);
- MAKE_WSTAT_LIST("Pages examined during allocation", sp->st_alloc_pages);
- MAKE_STAT_LIST("Maximum pages examined during allocation",
- sp->st_alloc_max_pages);
- MAKE_WSTAT_LIST("Threads waiting on buffer I/O", sp->st_io_wait);
- MAKE_WSTAT_LIST("Number of syncs interrupted", sp->st_sync_interrupted);
-
- /*
- * Save global stat list as res1. The MAKE_STAT_LIST
- * macro assumes 'res' so we'll use that to build up
- * our per-file sublist.
- */
- res1 = res;
- for (savefsp = fsp; fsp != NULL && *fsp != NULL; fsp++) {
- res = Tcl_NewObj();
- MAKE_STAT_STRLIST("File Name", (*fsp)->file_name);
- MAKE_STAT_LIST("Page size", (*fsp)->st_pagesize);
- MAKE_STAT_LIST("Pages mapped into address space",
- (*fsp)->st_map);
- MAKE_WSTAT_LIST("Cache hits", (*fsp)->st_cache_hit);
- MAKE_WSTAT_LIST("Cache misses", (*fsp)->st_cache_miss);
- MAKE_WSTAT_LIST("Pages created", (*fsp)->st_page_create);
- MAKE_WSTAT_LIST("Pages read in", (*fsp)->st_page_in);
- MAKE_WSTAT_LIST("Pages written", (*fsp)->st_page_out);
- /*
- * Now that we have a complete "per-file" stat list, append
- * that to the other list.
- */
- result = Tcl_ListObjAppendElement(interp, res1, res);
- if (result != TCL_OK)
- goto error;
- }
-#endif
- Tcl_SetObjResult(interp, res1);
-error:
- __os_ufree(dbenv->env, sp);
- if (savefsp != NULL)
- __os_ufree(dbenv->env, savefsp);
- return (result);
-}
-
-/*
- * mp_Cmd --
- * Implements the "mp" widget.
- */
-static int
-mp_Cmd(clientData, interp, objc, objv)
- ClientData clientData; /* Mp handle */
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *mpcmds[] = {
- "close",
- "fsync",
- "get",
- "get_clear_len",
- "get_fileid",
- "get_ftype",
- "get_lsn_offset",
- "get_pgcookie",
- NULL
- };
- enum mpcmds {
- MPCLOSE,
- MPFSYNC,
- MPGET,
- MPGETCLEARLEN,
- MPGETFILEID,
- MPGETFTYPE,
- MPGETLSNOFFSET,
- MPGETPGCOOKIE
- };
- DB_MPOOLFILE *mp;
- int cmdindex, ftype, length, result, ret;
- DBTCL_INFO *mpip;
- Tcl_Obj *res;
- char *obj_name;
- u_int32_t value;
- int32_t intval;
- u_int8_t fileid[DB_FILE_ID_LEN];
- DBT cookie;
-
- Tcl_ResetResult(interp);
- mp = (DB_MPOOLFILE *)clientData;
- obj_name = Tcl_GetStringFromObj(objv[0], &length);
- mpip = _NameToInfo(obj_name);
- result = TCL_OK;
-
- if (mp == NULL) {
- Tcl_SetResult(interp, "NULL mp pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (mpip == NULL) {
- Tcl_SetResult(interp, "NULL mp info pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the dbcmds
- * defined above.
- */
- if (Tcl_GetIndexFromObj(interp,
- objv[1], mpcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
-
- res = NULL;
- switch ((enum mpcmds)cmdindex) {
- case MPCLOSE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = mp->close(mp, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "mp close");
- _MpInfoDelete(interp, mpip);
- (void)Tcl_DeleteCommand(interp, mpip->i_name);
- _DeleteInfo(mpip);
- break;
- case MPFSYNC:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = mp->sync(mp);
- res = Tcl_NewIntObj(ret);
- break;
- case MPGET:
- result = tcl_MpGet(interp, objc, objv, mp, mpip);
- break;
- case MPGETCLEARLEN:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = mp->get_clear_len(mp, &value);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "mp get_clear_len")) == TCL_OK)
- res = Tcl_NewIntObj((int)value);
- break;
- case MPGETFILEID:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = mp->get_fileid(mp, fileid);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "mp get_fileid")) == TCL_OK)
- res = NewStringObj((char *)fileid, DB_FILE_ID_LEN);
- break;
- case MPGETFTYPE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = mp->get_ftype(mp, &ftype);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "mp get_ftype")) == TCL_OK)
- res = Tcl_NewIntObj(ftype);
- break;
- case MPGETLSNOFFSET:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = mp->get_lsn_offset(mp, &intval);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "mp get_lsn_offset")) == TCL_OK)
- res = Tcl_NewIntObj(intval);
- break;
- case MPGETPGCOOKIE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- memset(&cookie, 0, sizeof(DBT));
- ret = mp->get_pgcookie(mp, &cookie);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "mp get_pgcookie")) == TCL_OK)
- res = Tcl_NewByteArrayObj((u_char *)cookie.data,
- (int)cookie.size);
- break;
- }
- /*
- * Only set result if we have a res. Otherwise, lower
- * functions have already done so.
- */
- if (result == TCL_OK && res)
- Tcl_SetObjResult(interp, res);
- return (result);
-}
-
-/*
- * tcl_MpGet --
- */
-static int
-tcl_MpGet(interp, objc, objv, mp, mpip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_MPOOLFILE *mp; /* mp pointer */
- DBTCL_INFO *mpip; /* mp info pointer */
-{
- static const char *mpget[] = {
- "-create",
- "-dirty",
- "-last",
- "-new",
- "-txn",
- NULL
- };
- enum mpget {
- MPGET_CREATE,
- MPGET_DIRTY,
- MPGET_LAST,
- MPGET_NEW,
- MPGET_TXN
- };
-
- DBTCL_INFO *ip;
- Tcl_Obj *res;
- DB_TXN *txn;
- db_pgno_t pgno;
- u_int32_t flag;
- int i, ipgno, optindex, result, ret;
- char *arg, msg[MSG_SIZE], newname[MSG_SIZE];
- void *page;
-
- txn = NULL;
- result = TCL_OK;
- memset(newname, 0, MSG_SIZE);
- i = 2;
- flag = 0;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i],
- mpget, "option", TCL_EXACT, &optindex) != TCL_OK) {
- /*
- * Reset the result so we don't get an errant
- * error message if there is another error.
- * This arg is the page number.
- */
- if (IS_HELP(objv[i]) == TCL_OK)
- return (TCL_OK);
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum mpget)optindex) {
- case MPGET_CREATE:
- flag |= DB_MPOOL_CREATE;
- break;
- case MPGET_DIRTY:
- flag |= DB_MPOOL_DIRTY;
- break;
- case MPGET_LAST:
- flag |= DB_MPOOL_LAST;
- break;
- case MPGET_NEW:
- flag |= DB_MPOOL_NEW;
- break;
- case MPGET_TXN:
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "mpool get: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- }
- if (result != TCL_OK)
- goto error;
- }
- /*
- * Any left over arg is a page number. It better be the last arg.
- */
- ipgno = 0;
- if (i != objc) {
- if (i != objc - 1) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args? ?pgno?");
- result = TCL_ERROR;
- goto error;
- }
- result = Tcl_GetIntFromObj(interp, objv[i++], &ipgno);
- if (result != TCL_OK)
- goto error;
- }
-
- snprintf(newname, sizeof(newname), "%s.pg%d",
- mpip->i_name, mpip->i_mppgid);
- ip = _NewInfo(interp, NULL, newname, I_PG);
- if (ip == NULL) {
- Tcl_SetResult(interp, "Could not set up info",
- TCL_STATIC);
- return (TCL_ERROR);
- }
- _debug_check();
- pgno = (db_pgno_t)ipgno;
- ret = mp->get(mp, &pgno, NULL, flag, &page);
- result = _ReturnSetup(interp, ret, DB_RETOK_MPGET(ret), "mpool get");
- if (result == TCL_ERROR)
- _DeleteInfo(ip);
- else {
- /*
- * Success. Set up return. Set up new info
- * and command widget for this mpool.
- */
- mpip->i_mppgid++;
- ip->i_parent = mpip;
- ip->i_pgno = pgno;
- ip->i_pgsz = mpip->i_pgsz;
- _SetInfoData(ip, page);
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)pg_Cmd, (ClientData)page, NULL);
- res = NewStringObj(newname, strlen(newname));
- Tcl_SetObjResult(interp, res);
- }
-error:
- return (result);
-}
-
-/*
- * pg_Cmd --
- * Implements the "pg" widget.
- */
-static int
-pg_Cmd(clientData, interp, objc, objv)
- ClientData clientData; /* Page handle */
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *pgcmds[] = {
- "init",
- "is_setto",
- "pgnum",
- "pgsize",
- "put",
- NULL
- };
- enum pgcmds {
- PGINIT,
- PGISSET,
- PGNUM,
- PGSIZE,
- PGPUT
- };
- DB_MPOOLFILE *mp;
- int cmdindex, length, result;
- char *obj_name;
- void *page;
- DBTCL_INFO *pgip;
- Tcl_Obj *res;
-
- Tcl_ResetResult(interp);
- page = (void *)clientData;
- obj_name = Tcl_GetStringFromObj(objv[0], &length);
- pgip = _NameToInfo(obj_name);
- mp = NAME_TO_MP(pgip->i_parent->i_name);
- result = TCL_OK;
-
- if (page == NULL) {
- Tcl_SetResult(interp, "NULL page pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (mp == NULL) {
- Tcl_SetResult(interp, "NULL mp pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (pgip == NULL) {
- Tcl_SetResult(interp, "NULL page info pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the dbcmds
- * defined above.
- */
- if (Tcl_GetIndexFromObj(interp,
- objv[1], pgcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
-
- res = NULL;
- switch ((enum pgcmds)cmdindex) {
- case PGNUM:
- res = Tcl_NewWideIntObj((Tcl_WideInt)pgip->i_pgno);
- break;
- case PGSIZE:
- res = Tcl_NewWideIntObj((Tcl_WideInt)pgip->i_pgsz);
- break;
- case PGPUT:
- result = tcl_Pg(interp, objc, objv, page, mp, pgip);
- break;
- case PGINIT:
- result = tcl_PgInit(interp, objc, objv, page, pgip);
- break;
- case PGISSET:
- result = tcl_PgIsset(interp, objc, objv, page, pgip);
- break;
- }
-
- /*
- * Only set result if we have a res. Otherwise, lower
- * functions have already done so.
- */
- if (result == TCL_OK && res != NULL)
- Tcl_SetObjResult(interp, res);
- return (result);
-}
-
-static int
-tcl_Pg(interp, objc, objv, page, mp, pgip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- void *page; /* Page pointer */
- DB_MPOOLFILE *mp; /* Mpool pointer */
- DBTCL_INFO *pgip; /* Info pointer */
-{
- static const char *pgopt[] = {
- "-discard",
- NULL
- };
- enum pgopt {
- PGDISCARD
- };
- u_int32_t flag;
- int i, optindex, result, ret;
-
- result = TCL_OK;
- i = 2;
- flag = 0;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i],
- pgopt, "option", TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(objv[i]));
- i++;
- switch ((enum pgopt)optindex) {
- case PGDISCARD:
- flag |= DB_MPOOL_DISCARD;
- break;
- }
- }
-
- _debug_check();
- ret = mp->put(mp, page, DB_PRIORITY_UNCHANGED, flag);
-
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "page");
-
- (void)Tcl_DeleteCommand(interp, pgip->i_name);
- _DeleteInfo(pgip);
- return (result);
-}
-
-static int
-tcl_PgInit(interp, objc, objv, page, pgip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- void *page; /* Page pointer */
- DBTCL_INFO *pgip; /* Info pointer */
-{
- Tcl_Obj *res;
- long *p, *endp, newval;
- int length, pgsz, result;
- u_char *s;
-
- result = TCL_OK;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "val");
- return (TCL_ERROR);
- }
-
- pgsz = pgip->i_pgsz;
- result = Tcl_GetLongFromObj(interp, objv[2], &newval);
- if (result != TCL_OK) {
- s = Tcl_GetByteArrayFromObj(objv[2], &length);
- if (s == NULL)
- return (TCL_ERROR);
- memcpy(page, s, (size_t)((length < pgsz) ? length : pgsz));
- result = TCL_OK;
- } else {
- p = (long *)page;
- for (endp = p + ((u_int)pgsz / sizeof(long)); p < endp; p++)
- *p = newval;
- }
- res = Tcl_NewIntObj(0);
- Tcl_SetObjResult(interp, res);
- return (result);
-}
-
-static int
-tcl_PgIsset(interp, objc, objv, page, pgip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- void *page; /* Page pointer */
- DBTCL_INFO *pgip; /* Info pointer */
-{
- Tcl_Obj *res;
- long *p, *endp, newval;
- int length, pgsz, result;
- u_char *s;
-
- result = TCL_OK;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "val");
- return (TCL_ERROR);
- }
-
- pgsz = pgip->i_pgsz;
- result = Tcl_GetLongFromObj(interp, objv[2], &newval);
- if (result != TCL_OK) {
- if ((s = Tcl_GetByteArrayFromObj(objv[2], &length)) == NULL)
- return (TCL_ERROR);
- result = TCL_OK;
-
- if (memcmp(page, s,
- (size_t)((length < pgsz) ? length : pgsz)) != 0) {
- res = Tcl_NewIntObj(0);
- Tcl_SetObjResult(interp, res);
- return (result);
- }
- } else {
- p = (long *)page;
- /*
- * If any value is not the same, return 0 (is not set to
- * this value). Otherwise, if we finish the loop, we return 1
- * (is set to this value).
- */
- for (endp = p + ((u_int)pgsz / sizeof(long)); p < endp; p++)
- if (*p != newval) {
- res = Tcl_NewIntObj(0);
- Tcl_SetObjResult(interp, res);
- return (result);
- }
- }
-
- res = Tcl_NewIntObj(1);
- Tcl_SetObjResult(interp, res);
- return (result);
-}
-#endif
diff --git a/tcl/tcl_mutex.c b/tcl/tcl_mutex.c
deleted file mode 100644
index c05b208..0000000
--- a/tcl/tcl_mutex.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 2004-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/tcl_db.h"
-
-#ifdef CONFIG_TEST
-/*
- * PUBLIC: int tcl_Mutex __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- * PUBLIC: DB_ENV *));
- *
- * tcl_Mutex --
- * Implements dbenv->mutex_alloc method.
- */
-int
-tcl_Mutex(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment */
-{
- static const char *which[] = {
- "-process_only",
- "-self_block",
- NULL
- };
- enum which {
- PROCONLY,
- SELFBLOCK
- };
- int arg, i, result, ret;
- u_int32_t flags;
- db_mutex_t indx;
- Tcl_Obj *res;
-
- result = TCL_OK;
- flags = 0;
- Tcl_ResetResult(interp);
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "-proccess_only | -self_block");
- return (TCL_ERROR);
- }
-
- i = 2;
- while (i < objc) {
- /*
- * If there is an arg, make sure it is the right one.
- */
- if (Tcl_GetIndexFromObj(interp, objv[i], which, "option",
- TCL_EXACT, &arg) != TCL_OK)
- return (IS_HELP(objv[i]));
- i++;
- switch ((enum which)arg) {
- case PROCONLY:
- flags |= DB_MUTEX_PROCESS_ONLY;
- break;
- case SELFBLOCK:
- flags |= DB_MUTEX_SELF_BLOCK;
- break;
- }
- }
- res = NULL;
- ret = dbenv->mutex_alloc(dbenv, flags, &indx);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "mutex_alloc");
- Tcl_SetResult(interp, "allocation failed", TCL_STATIC);
- } else {
- res = Tcl_NewWideIntObj((Tcl_WideInt)indx);
- Tcl_SetObjResult(interp, res);
- }
- return (result);
-}
-
-/*
- * PUBLIC: int tcl_MutFree __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- * PUBLIC: DB_ENV *));
- *
- * tcl_MutFree --
- * Implements dbenv->mutex_free method.
- */
-int
-tcl_MutFree(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment */
-{
- int result, ret;
- db_mutex_t indx;
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, "mutexid");
- return (TCL_ERROR);
- }
- if ((result = _GetUInt32(interp, objv[2], &indx)) != TCL_OK)
- return (result);
- ret = dbenv->mutex_free(dbenv, indx);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env mutex_free"));
-}
-
-/*
- * PUBLIC: int tcl_MutGet __P((Tcl_Interp *, DB_ENV *, int));
- *
- * tcl_MutGet --
- * Implements dbenv->mutex_get_* methods.
- */
-int
-tcl_MutGet(interp, dbenv, op)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Environment */
- int op; /* Which item to get */
-{
- Tcl_Obj *res;
- u_int32_t val;
- int result, ret;
-
- res = NULL;
- val = 0;
- ret = 0;
-
- switch (op) {
- case DBTCL_MUT_ALIGN:
- ret = dbenv->mutex_get_align(dbenv, &val);
- break;
- case DBTCL_MUT_INCR:
- ret = dbenv->mutex_get_increment(dbenv, &val);
- break;
- case DBTCL_MUT_MAX:
- ret = dbenv->mutex_get_max(dbenv, &val);
- break;
- case DBTCL_MUT_TAS:
- ret = dbenv->mutex_get_tas_spins(dbenv, &val);
- break;
- default:
- return (TCL_ERROR);
- }
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "mutex_get")) == TCL_OK) {
- res = Tcl_NewLongObj((long)val);
- Tcl_SetObjResult(interp, res);
- }
- return (result);
-}
-
-/*
- * PUBLIC: int tcl_MutLock __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- * PUBLIC: DB_ENV *));
- *
- * tcl_MutLock --
- * Implements dbenv->mutex_lock method.
- */
-int
-tcl_MutLock(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment */
-{
- int result, ret;
- db_mutex_t indx;
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, "mutexid");
- return (TCL_ERROR);
- }
- if ((result = _GetUInt32(interp, objv[2], &indx)) != TCL_OK)
- return (result);
- ret = dbenv->mutex_lock(dbenv, indx);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env mutex_lock"));
-}
-
-/*
- * PUBLIC: int tcl_MutSet __P((Tcl_Interp *, Tcl_Obj *,
- * PUBLIC: DB_ENV *, int));
- *
- * tcl_MutSet --
- * Implements dbenv->mutex_set methods.
- */
-int
-tcl_MutSet(interp, obj, dbenv, op)
- Tcl_Interp *interp; /* Interpreter */
- Tcl_Obj *obj; /* The argument object */
- DB_ENV *dbenv; /* Environment */
- int op; /* Which item to set */
-{
- int result, ret;
- u_int32_t val;
-
- if ((result = _GetUInt32(interp, obj, &val)) != TCL_OK)
- return (result);
- switch (op) {
- case DBTCL_MUT_ALIGN:
- ret = dbenv->mutex_set_align(dbenv, val);
- break;
- case DBTCL_MUT_INCR:
- ret = dbenv->mutex_set_increment(dbenv, val);
- break;
- case DBTCL_MUT_MAX:
- ret = dbenv->mutex_set_max(dbenv, val);
- break;
- case DBTCL_MUT_TAS:
- ret = dbenv->mutex_set_tas_spins(dbenv, val);
- break;
- default:
- return (TCL_ERROR);
- }
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env mutex_set"));
-}
-
-/*
- * PUBLIC: int tcl_MutStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- * PUBLIC: DB_ENV *));
- *
- * tcl_MutStat --
- * Implements dbenv->mutex_stat method.
- */
-int
-tcl_MutStat(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment */
-{
- DB_MUTEX_STAT *sp;
- Tcl_Obj *res;
- u_int32_t flag;
- int result, ret;
- char *arg;
-
- result = TCL_OK;
- flag = 0;
-
- if (objc > 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-clear?");
- return (TCL_ERROR);
- }
-
- if (objc == 3) {
- arg = Tcl_GetStringFromObj(objv[2], NULL);
- if (strcmp(arg, "-clear") == 0)
- flag = DB_STAT_CLEAR;
- else {
- Tcl_SetResult(interp,
- "db stat: unknown arg", TCL_STATIC);
- return (TCL_ERROR);
- }
- }
-
- _debug_check();
- ret = dbenv->mutex_stat(dbenv, &sp, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "mutex stat");
- if (result == TCL_ERROR)
- return (result);
-
- res = Tcl_NewObj();
- MAKE_STAT_LIST("Mutex align", sp->st_mutex_align);
- MAKE_STAT_LIST("Mutex TAS spins", sp->st_mutex_tas_spins);
- MAKE_STAT_LIST("Mutex count", sp->st_mutex_cnt);
- MAKE_STAT_LIST("Free mutexes", sp->st_mutex_free);
- MAKE_STAT_LIST("Mutexes in use", sp->st_mutex_inuse);
- MAKE_STAT_LIST("Max in use", sp->st_mutex_inuse_max);
- MAKE_STAT_LIST("Mutex region size", sp->st_regsize);
- MAKE_WSTAT_LIST("Number of region waits", sp->st_region_wait);
- MAKE_WSTAT_LIST("Number of region no waits", sp->st_region_nowait);
- Tcl_SetObjResult(interp, res);
-
- /*
- * The 'error' label is used by the MAKE_STAT_LIST macro.
- * Therefore we cannot remove it, and also we know that
- * sp is allocated at that time.
- */
-error: __os_ufree(dbenv->env, sp);
- return (result);
-}
-
-/*
- * PUBLIC: int tcl_MutUnlock __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- * PUBLIC: DB_ENV *));
- *
- * tcl_MutUnlock --
- * Implements dbenv->mutex_unlock method.
- */
-int
-tcl_MutUnlock(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment */
-{
- int result, ret;
- db_mutex_t indx;
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, "mutexid");
- return (TCL_ERROR);
- }
- if ((result = _GetUInt32(interp, objv[2], &indx)) != TCL_OK)
- return (result);
- ret = dbenv->mutex_unlock(dbenv, indx);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env mutex_unlock"));
-}
-#endif
diff --git a/tcl/tcl_rep.c b/tcl/tcl_rep.c
deleted file mode 100644
index 37619fd..0000000
--- a/tcl/tcl_rep.c
+++ /dev/null
@@ -1,1426 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/tcl_db.h"
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepConfig --
- * Call DB_ENV->rep_set_config().
- *
- * PUBLIC: int tcl_RepConfig
- * PUBLIC: __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *));
- */
-int
-tcl_RepConfig(interp, dbenv, list)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Environment pointer */
- Tcl_Obj *list; /* {which on|off} */
-{
- static const char *confwhich[] = {
- "bulk",
- "delayclient",
- "mgr2sitestrict",
- "noautoinit",
- "nowait",
- NULL
- };
- enum confwhich {
- REPCONF_BULK,
- REPCONF_DELAYCLIENT,
- REPCONF_MGR2SITESTRICT,
- REPCONF_NOAUTOINIT,
- REPCONF_NOWAIT
- };
- static const char *confonoff[] = {
- "off",
- "on",
- NULL
- };
- enum confonoff {
- REPCONF_OFF,
- REPCONF_ON
- };
- Tcl_Obj **myobjv, *onoff, *which;
- int myobjc, on, optindex, result, ret;
- u_int32_t wh;
-
- result = Tcl_ListObjGetElements(interp, list, &myobjc, &myobjv);
- which = myobjv[0];
- onoff = myobjv[1];
- if (result != TCL_OK)
- return (result);
- if (Tcl_GetIndexFromObj(interp, which, confwhich, "option",
- TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(which));
-
- switch ((enum confwhich)optindex) {
- case REPCONF_NOAUTOINIT:
- wh = DB_REP_CONF_NOAUTOINIT;
- break;
- case REPCONF_BULK:
- wh = DB_REP_CONF_BULK;
- break;
- case REPCONF_DELAYCLIENT:
- wh = DB_REP_CONF_DELAYCLIENT;
- break;
- case REPCONF_MGR2SITESTRICT:
- wh = DB_REPMGR_CONF_2SITE_STRICT;
- break;
- case REPCONF_NOWAIT:
- wh = DB_REP_CONF_NOWAIT;
- break;
- default:
- return (TCL_ERROR);
- }
- if (Tcl_GetIndexFromObj(interp, onoff, confonoff, "option",
- TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(onoff));
- switch ((enum confonoff)optindex) {
- case REPCONF_OFF:
- on = 0;
- break;
- case REPCONF_ON:
- on = 1;
- break;
- default:
- return (TCL_ERROR);
- }
- ret = dbenv->rep_set_config(dbenv, wh, on);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_config"));
-}
-
-/*
- * tcl_RepGetTwo --
- * Call replication getters that return 2 values.
- *
- * PUBLIC: int tcl_RepGetTwo
- * PUBLIC: __P((Tcl_Interp *, DB_ENV *, int));
- */
-int
-tcl_RepGetTwo(interp, dbenv, op)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Environment pointer */
- int op; /* which getter */
-{
- Tcl_Obj *myobjv[2], *res;
- u_int32_t val1, val2;
- int myobjc, result, ret;
-
- ret = 0;
- val1 = val2 = 0;
- switch (op) {
- case DBTCL_GETCLOCK:
- ret = dbenv->rep_get_clockskew(dbenv, &val1, &val2);
- break;
- case DBTCL_GETLIMIT:
- ret = dbenv->rep_get_limit(dbenv, &val1, &val2);
- break;
- case DBTCL_GETREQ:
- ret = dbenv->rep_get_request(dbenv, &val1, &val2);
- break;
- default:
- return (TCL_ERROR);
- }
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_get")) == TCL_OK) {
- myobjc = 2;
- myobjv[0] = Tcl_NewLongObj((long)val1);
- myobjv[1] = Tcl_NewLongObj((long)val2);
- res = Tcl_NewListObj(myobjc, myobjv);
- Tcl_SetObjResult(interp, res);
- }
- return (result);
-}
-
-/*
- * tcl_RepGetConfig --
- *
- * PUBLIC: int tcl_RepGetConfig
- * PUBLIC: __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *));
- */
-int
-tcl_RepGetConfig(interp, dbenv, which)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Environment pointer */
- Tcl_Obj *which; /* which flag */
-{
- static const char *confwhich[] = {
- "bulk",
- "delayclient",
- "inmem_files",
- "lease",
- "mgr2sitestrict",
- "noautoinit",
- "nowait",
- NULL
- };
- enum confwhich {
- REPGCONF_BULK,
- REPGCONF_DELAYCLIENT,
- REPGCONF_INMEM_FILES,
- REPGCONF_LEASE,
- REPGCONF_MGR2SITESTRICT,
- REPGCONF_NOAUTOINIT,
- REPGCONF_NOWAIT
- };
- Tcl_Obj *res;
- int on, optindex, result, ret;
- u_int32_t wh;
-
- if (Tcl_GetIndexFromObj(interp, which, confwhich, "option",
- TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(which));
-
- res = NULL;
- switch ((enum confwhich)optindex) {
- case REPGCONF_BULK:
- wh = DB_REP_CONF_BULK;
- break;
- case REPGCONF_DELAYCLIENT:
- wh = DB_REP_CONF_DELAYCLIENT;
- break;
- case REPGCONF_INMEM_FILES:
- wh = DB_REP_CONF_INMEM;
- break;
- case REPGCONF_LEASE:
- wh = DB_REP_CONF_LEASE;
- break;
- case REPGCONF_MGR2SITESTRICT:
- wh = DB_REPMGR_CONF_2SITE_STRICT;
- break;
- case REPGCONF_NOAUTOINIT:
- wh = DB_REP_CONF_NOAUTOINIT;
- break;
- case REPGCONF_NOWAIT:
- wh = DB_REP_CONF_NOWAIT;
- break;
- default:
- return (TCL_ERROR);
- }
- ret = dbenv->rep_get_config(dbenv, wh, &on);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_config")) == TCL_OK) {
- res = Tcl_NewIntObj(on);
- Tcl_SetObjResult(interp, res);
- }
- return (result);
-}
-
-/*
- * tcl_RepGetTimeout --
- * Get various replication timeout values.
- *
- * PUBLIC: int tcl_RepGetTimeout
- * PUBLIC: __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *));
- */
-int
-tcl_RepGetTimeout(interp, dbenv, which)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Environment pointer */
- Tcl_Obj *which; /* which flag */
-{
- static const char *towhich[] = {
- "ack",
- "checkpoint_delay",
- "connection_retry",
- "election",
- "election_retry",
- "full_election",
- "heartbeat_monitor",
- "heartbeat_send",
- "lease",
- NULL
- };
- enum towhich {
- REPGTO_ACK,
- REPGTO_CKP,
- REPGTO_CONN,
- REPGTO_ELECT,
- REPGTO_ELECT_RETRY,
- REPGTO_FULL,
- REPGTO_HB_MON,
- REPGTO_HB_SEND,
- REPGTO_LEASE
- };
- Tcl_Obj *res;
- int optindex, result, ret, wh;
- u_int32_t to;
-
- if (Tcl_GetIndexFromObj(interp, which, towhich, "option",
- TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(which));
-
- res = NULL;
- switch ((enum towhich)optindex) {
- case REPGTO_ACK:
- wh = DB_REP_ACK_TIMEOUT;
- break;
- case REPGTO_CKP:
- wh = DB_REP_CHECKPOINT_DELAY;
- break;
- case REPGTO_CONN:
- wh = DB_REP_CONNECTION_RETRY;
- break;
- case REPGTO_ELECT:
- wh = DB_REP_ELECTION_TIMEOUT;
- break;
- case REPGTO_ELECT_RETRY:
- wh = DB_REP_ELECTION_RETRY;
- break;
- case REPGTO_FULL:
- wh = DB_REP_FULL_ELECTION_TIMEOUT;
- break;
- case REPGTO_HB_MON:
- wh = DB_REP_HEARTBEAT_MONITOR;
- break;
- case REPGTO_HB_SEND:
- wh = DB_REP_HEARTBEAT_SEND;
- break;
- case REPGTO_LEASE:
- wh = DB_REP_LEASE_TIMEOUT;
- break;
- default:
- return (TCL_ERROR);
- }
- ret = dbenv->rep_get_timeout(dbenv, wh, &to);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_config")) == TCL_OK) {
- res = Tcl_NewLongObj((long)to);
- Tcl_SetObjResult(interp, res);
- }
- return (result);
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepElect --
- * Call DB_ENV->rep_elect().
- *
- * PUBLIC: int tcl_RepElect
- * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
- */
-int
-tcl_RepElect(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- int result, ret;
- u_int32_t full_timeout, nsites, nvotes, pri, timeout;
-
- if (objc != 6 && objc != 7) {
- Tcl_WrongNumArgs(interp, 6, objv,
- "nsites nvotes pri timeout [full_timeout]");
- return (TCL_ERROR);
- }
-
- if ((result = _GetUInt32(interp, objv[2], &nsites)) != TCL_OK)
- return (result);
- if ((result = _GetUInt32(interp, objv[3], &nvotes)) != TCL_OK)
- return (result);
- if ((result = _GetUInt32(interp, objv[4], &pri)) != TCL_OK)
- return (result);
- if ((result = _GetUInt32(interp, objv[5], &timeout)) != TCL_OK)
- return (result);
- full_timeout = 0;
- if (objc == 7)
- if ((result = _GetUInt32(interp, objv[6], &full_timeout))
- != TCL_OK)
- return (result);
-
- _debug_check();
-
- if ((ret = dbenv->rep_set_priority(dbenv, pri)) != 0)
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_elect (rep_set_priority)"));
- if ((ret = dbenv->rep_set_timeout(dbenv, DB_REP_ELECTION_TIMEOUT,
- timeout)) != 0)
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_elect (rep_set_timeout)"));
-
- if (full_timeout != 0 && (ret = dbenv->rep_set_timeout(dbenv,
- DB_REP_FULL_ELECTION_TIMEOUT, full_timeout)) != 0)
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_elect (rep_set_timeout)"));
-
- ret = dbenv->rep_elect(dbenv, nsites, nvotes, 0);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env rep_elect"));
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepFlush --
- * Call DB_ENV->rep_flush().
- *
- * PUBLIC: int tcl_RepFlush
- * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
- */
-int
-tcl_RepFlush(interp, objc, objv, dbenv)
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
- DB_ENV *dbenv;
-{
- int ret;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "");
- return TCL_ERROR;
- }
-
- _debug_check();
- ret = dbenv->rep_flush(dbenv);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env rep_flush"));
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepSync --
- * Call DB_ENV->rep_sync().
- *
- * PUBLIC: int tcl_RepSync
- * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
- */
-int
-tcl_RepSync(interp, objc, objv, dbenv)
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
- DB_ENV *dbenv;
-{
- int ret;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "");
- return TCL_ERROR;
- }
-
- _debug_check();
- ret = dbenv->rep_sync(dbenv, 0);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env rep_sync"));
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepLease --
- * Call DB_ENV->rep_set_lease().
- *
- * PUBLIC: int tcl_RepLease __P((Tcl_Interp *, int, Tcl_Obj * CONST *,
- * PUBLIC: DB_ENV *));
- */
-int
-tcl_RepLease(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
-{
- u_int32_t clock_fast, clock_slow, nsites, timeout;
- int result, ret;
-
- COMPQUIET(clock_fast, 0);
- COMPQUIET(clock_slow, 0);
-
- if (objc != 4 && objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "{nsites timeout fast slow}");
- return (TCL_ERROR);
- }
-
- if ((result = _GetUInt32(interp, objv[0], &nsites)) != TCL_OK)
- return (result);
- if ((result = _GetUInt32(interp, objv[1], &timeout)) != TCL_OK)
- return (result);
- if (objc == 4) {
- if ((result = _GetUInt32(interp, objv[2], &clock_fast))
- != TCL_OK)
- return (result);
- if ((result = _GetUInt32(interp, objv[3], &clock_slow))
- != TCL_OK)
- return (result);
- }
- ret = dbenv->rep_set_nsites(dbenv, nsites);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "rep_set_nsites");
- if (result != TCL_OK)
- return (result);
- ret = dbenv->rep_set_timeout(dbenv, DB_REP_LEASE_TIMEOUT,
- (db_timeout_t)timeout);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "rep_set_timeout");
- ret = dbenv->rep_set_config(dbenv, DB_REP_CONF_LEASE, 1);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "rep_set_config");
- if (result != TCL_OK)
- return (result);
- if (objc == 4)
- ret = dbenv->rep_set_clockskew(dbenv, clock_fast, clock_slow);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_set_lease"));
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepInmemFiles --
- * Set in-memory replication, which must be done before opening
- * environment.
- *
- * PUBLIC: int tcl_RepInmemFiles __P((Tcl_Interp *, DB_ENV *));
- */
-int
-tcl_RepInmemFiles(interp, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv;
-{
- int ret;
-
- ret = dbenv->rep_set_config(dbenv, DB_REP_CONF_INMEM, 1);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "rep_set_config"));
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepLimit --
- * Call DB_ENV->rep_set_limit().
- *
- * PUBLIC: int tcl_RepLimit
- * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
- */
-int
-tcl_RepLimit(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- int result, ret;
- u_int32_t bytes, gbytes;
-
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 4, objv, "gbytes bytes");
- return (TCL_ERROR);
- }
-
- if ((result = _GetUInt32(interp, objv[2], &gbytes)) != TCL_OK)
- return (result);
- if ((result = _GetUInt32(interp, objv[3], &bytes)) != TCL_OK)
- return (result);
-
- _debug_check();
- if ((ret = dbenv->rep_set_limit(dbenv, gbytes, bytes)) != 0)
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env set_rep_limit"));
-
- return (_ReturnSetup(interp,
- ret, DB_RETOK_STD(ret), "env set_rep_limit"));
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepRequest --
- * Call DB_ENV->rep_set_request().
- *
- * PUBLIC: int tcl_RepRequest
- * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
- */
-int
-tcl_RepRequest(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- int result, ret;
- long min, max;
-
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 4, objv, "min max");
- return (TCL_ERROR);
- }
-
- if ((result = Tcl_GetLongFromObj(interp, objv[2], &min)) != TCL_OK)
- return (result);
- if ((result = Tcl_GetLongFromObj(interp, objv[3], &max)) != TCL_OK)
- return (result);
-
- _debug_check();
- if ((ret = dbenv->rep_set_request(dbenv, (db_timeout_t)min,
- (db_timeout_t)max)) != 0)
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_request"));
-
- return (_ReturnSetup(interp,
- ret, DB_RETOK_STD(ret), "env rep_request"));
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepNoarchiveTimeout --
- * Reset the master update timer, to allow immediate log archiving.
- *
- * PUBLIC: int tcl_RepNoarchiveTimeout
- * PUBLIC: __P((Tcl_Interp *, DB_ENV *));
- */
-int
-tcl_RepNoarchiveTimeout(interp, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- DB_ENV *dbenv; /* Environment pointer */
-{
- ENV *env;
- REGENV *renv;
- REGINFO *infop;
-
- env = dbenv->env;
-
- _debug_check();
- infop = env->reginfo;
- renv = infop->primary;
- REP_SYSTEM_LOCK(env);
- F_CLR(renv, DB_REGENV_REPLOCKED);
- renv->op_timestamp = 0;
- REP_SYSTEM_UNLOCK(env);
-
- return (_ReturnSetup(interp,
- 0, DB_RETOK_STD(0), "env test force noarchive_timeout"));
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepTransport --
- * Call DB_ENV->rep_set_transport().
- *
- * PUBLIC: int tcl_RepTransport __P((Tcl_Interp *, int, Tcl_Obj * CONST *,
- * PUBLIC: DB_ENV *, DBTCL_INFO *));
- *
- * Note that this normally can/should be achieved as an argument to
- * berkdb env, but we need to test changing the transport function on
- * the fly.
- */
-int
-tcl_RepTransport(interp, objc, objv, dbenv, ip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
- DBTCL_INFO *ip;
-{
- int intarg, result, ret;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "{id transport_func");
- return (TCL_ERROR);
- }
-
- /*
- * Store the objects containing the machine ID
- * and the procedure name. We don't need to crack
- * the send procedure out now, but we do convert the
- * machine ID to an int, since rep_set_transport needs
- * it. Even so, it'll be easier later to deal with
- * the Tcl_Obj *, so we save that, not the int.
- *
- * Note that we Tcl_IncrRefCount both objects
- * independently; Tcl is free to discard the list
- * that they're bundled into.
- */
-
- /*
- * Check that the machine ID is an int. Note that
- * we do want to use GetIntFromObj; the machine
- * ID is explicitly an int, not a u_int32_t.
- */
- if (ip->i_rep_eid != NULL) {
- Tcl_DecrRefCount(ip->i_rep_eid);
- }
- ip->i_rep_eid = objv[0];
- Tcl_IncrRefCount(ip->i_rep_eid);
- result = Tcl_GetIntFromObj(interp,
- ip->i_rep_eid, &intarg);
- if (result != TCL_OK)
- return (result);
-
- if (ip->i_rep_send != NULL) {
- Tcl_DecrRefCount(ip->i_rep_send);
- }
- ip->i_rep_send = objv[1];
- Tcl_IncrRefCount(ip->i_rep_send);
- _debug_check();
- ret = dbenv->rep_set_transport(dbenv, intarg, tcl_rep_send);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_transport"));
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepStart --
- * Call DB_ENV->rep_start().
- *
- * PUBLIC: int tcl_RepStart
- * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
- *
- * Note that this normally can/should be achieved as an argument to
- * berkdb env, but we need to test forcible upgrading of clients, which
- * involves calling this on an open environment handle.
- */
-int
-tcl_RepStart(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
-{
- static const char *tclrpstrt[] = {
- "-client",
- "-master",
- NULL
- };
- enum tclrpstrt {
- TCL_RPSTRT_CLIENT,
- TCL_RPSTRT_MASTER
- };
- char *arg;
- int i, optindex, ret;
- u_int32_t flag;
-
- flag = 0;
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, "[-master/-client]");
- return (TCL_ERROR);
- }
-
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i], tclrpstrt,
- "option", TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-')
- return (IS_HELP(objv[i]));
- else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum tclrpstrt)optindex) {
- case TCL_RPSTRT_CLIENT:
- flag = DB_REP_CLIENT;
- break;
- case TCL_RPSTRT_MASTER:
- flag = DB_REP_MASTER;
- break;
- }
- }
-
- _debug_check();
- ret = dbenv->rep_start(dbenv, NULL, flag);
- return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env rep_start"));
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepProcessMessage --
- * Call DB_ENV->rep_process_message().
- *
- * PUBLIC: int tcl_RepProcessMessage
- * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
- */
-int
-tcl_RepProcessMessage(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- DBT control, rec;
- DB_LSN permlsn;
- Tcl_Obj *lsnlist, *myobjv[2], *res;
- void *ctmp, *rtmp;
- char *msg;
- int eid;
- int freectl, freerec, myobjc, result, ret;
-
- if (objc != 5) {
- Tcl_WrongNumArgs(interp, 5, objv, "id control rec");
- return (TCL_ERROR);
- }
- freectl = freerec = 0;
-
- memset(&control, 0, sizeof(control));
- memset(&rec, 0, sizeof(rec));
-
- if ((result = Tcl_GetIntFromObj(interp, objv[2], &eid)) != TCL_OK)
- return (result);
-
- ret = _CopyObjBytes(interp, objv[3], &ctmp,
- &control.size, &freectl);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_REPPMSG(ret), "rep_proc_msg");
- return (result);
- }
- control.data = ctmp;
- ret = _CopyObjBytes(interp, objv[4], &rtmp,
- &rec.size, &freerec);
- if (ret != 0) {
- result = _ReturnSetup(interp, ret,
- DB_RETOK_REPPMSG(ret), "rep_proc_msg");
- goto out;
- }
- rec.data = rtmp;
- _debug_check();
- ret = dbenv->rep_process_message(dbenv, &control, &rec, eid, &permlsn);
- /*
- * !!!
- * The TCL API diverges from the C++/Java APIs here. For us, it
- * is OK to get DUPMASTER and HOLDELECTION for testing purposes.
- */
- result = _ReturnSetup(interp, ret,
- DB_RETOK_REPPMSG(ret) || ret == DB_REP_DUPMASTER ||
- ret == DB_REP_HOLDELECTION,
- "env rep_process_message");
-
- if (result != TCL_OK)
- goto out;
-
- /*
- * We have a valid return. We need to return a variety of information.
- * It will be one of the following:
- * {0 0} - Make a 0 return a list for consistent return structure.
- * {DUPMASTER 0} - DUPMASTER, no other info needed.
- * {HOLDELECTION 0} - HOLDELECTION, no other info needed.
- * {NEWMASTER #} - NEWMASTER and its ID.
- * {NEWSITE 0} - NEWSITE, no other info needed.
- * {IGNORE {LSN list}} - IGNORE and this msg's LSN.
- * {ISPERM {LSN list}} - ISPERM and the perm LSN.
- * {NOTPERM {LSN list}} - NOTPERM and this msg's LSN.
- */
- myobjc = 2;
- switch (ret) {
- case 0:
- myobjv[0] = Tcl_NewIntObj(0);
- myobjv[1] = Tcl_NewIntObj(0);
- break;
- case DB_REP_DUPMASTER:
- myobjv[0] = Tcl_NewByteArrayObj(
- (u_char *)"DUPMASTER", (int)strlen("DUPMASTER"));
- myobjv[1] = Tcl_NewIntObj(0);
- break;
- case DB_REP_HOLDELECTION:
- myobjv[0] = Tcl_NewByteArrayObj(
- (u_char *)"HOLDELECTION", (int)strlen("HOLDELECTION"));
- myobjv[1] = Tcl_NewIntObj(0);
- break;
- case DB_REP_IGNORE:
- myobjv[0] = Tcl_NewLongObj((long)permlsn.file);
- myobjv[1] = Tcl_NewLongObj((long)permlsn.offset);
- lsnlist = Tcl_NewListObj(myobjc, myobjv);
- myobjv[0] = Tcl_NewByteArrayObj(
- (u_char *)"IGNORE", (int)strlen("IGNORE"));
- myobjv[1] = lsnlist;
- break;
- case DB_REP_ISPERM:
- myobjv[0] = Tcl_NewLongObj((long)permlsn.file);
- myobjv[1] = Tcl_NewLongObj((long)permlsn.offset);
- lsnlist = Tcl_NewListObj(myobjc, myobjv);
- myobjv[0] = Tcl_NewByteArrayObj(
- (u_char *)"ISPERM", (int)strlen("ISPERM"));
- myobjv[1] = lsnlist;
- break;
- case DB_REP_NEWSITE:
- myobjv[0] = Tcl_NewByteArrayObj(
- (u_char *)"NEWSITE", (int)strlen("NEWSITE"));
- myobjv[1] = Tcl_NewIntObj(0);
- break;
- case DB_REP_NOTPERM:
- myobjv[0] = Tcl_NewLongObj((long)permlsn.file);
- myobjv[1] = Tcl_NewLongObj((long)permlsn.offset);
- lsnlist = Tcl_NewListObj(myobjc, myobjv);
- myobjv[0] = Tcl_NewByteArrayObj(
- (u_char *)"NOTPERM", (int)strlen("NOTPERM"));
- myobjv[1] = lsnlist;
- break;
- default:
- msg = db_strerror(ret);
- Tcl_AppendResult(interp, msg, NULL);
- Tcl_SetErrorCode(interp, "BerkeleyDB", msg, NULL);
- result = TCL_ERROR;
- goto out;
- }
- res = Tcl_NewListObj(myobjc, myobjv);
- if (res != NULL)
- Tcl_SetObjResult(interp, res);
-out:
- if (freectl)
- __os_free(NULL, ctmp);
- if (freerec)
- __os_free(NULL, rtmp);
-
- return (result);
-}
-#endif
-
-#ifdef CONFIG_TEST
-/*
- * tcl_RepStat --
- * Call DB_ENV->rep_stat().
- *
- * PUBLIC: int tcl_RepStat
- * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
- */
-int
-tcl_RepStat(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
-{
- DB_REP_STAT *sp;
- Tcl_Obj *myobjv[2], *res, *thislist, *lsnlist;
- u_int32_t flag;
- int myobjc, result, ret;
- char *arg, *role;
-
- flag = 0;
- result = TCL_OK;
-
- if (objc > 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- if (objc == 3) {
- arg = Tcl_GetStringFromObj(objv[2], NULL);
- if (strcmp(arg, "-clear") == 0)
- flag = DB_STAT_CLEAR;
- else {
- Tcl_SetResult(interp,
- "db stat: unknown arg", TCL_STATIC);
- return (TCL_ERROR);
- }
- }
-
- _debug_check();
- ret = dbenv->rep_stat(dbenv, &sp, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "rep stat");
- if (result == TCL_ERROR)
- return (result);
-
- /*
- * Have our stats, now construct the name value
- * list pairs and free up the memory.
- */
- res = Tcl_NewObj();
-#ifdef HAVE_STATISTICS
- /*
- * MAKE_STAT_* assumes 'res' and 'error' label.
- */
- if (sp->st_status == DB_REP_MASTER)
- role = "master";
- else if (sp->st_status == DB_REP_CLIENT)
- role = "client";
- else
- role = "none";
- MAKE_STAT_STRLIST("Role", role);
-
- MAKE_STAT_LSN("Next LSN expected", &sp->st_next_lsn);
- MAKE_STAT_LSN("First missed LSN", &sp->st_waiting_lsn);
- MAKE_STAT_LSN("Maximum permanent LSN", &sp->st_max_perm_lsn);
- MAKE_WSTAT_LIST("Bulk buffer fills", sp->st_bulk_fills);
- MAKE_WSTAT_LIST("Bulk buffer overflows", sp->st_bulk_overflows);
- MAKE_WSTAT_LIST("Bulk records stored", sp->st_bulk_records);
- MAKE_WSTAT_LIST("Bulk buffer transfers", sp->st_bulk_transfers);
- MAKE_WSTAT_LIST("Client service requests", sp->st_client_svc_req);
- MAKE_WSTAT_LIST("Client service req misses", sp->st_client_svc_miss);
- MAKE_WSTAT_LIST("Client rerequests", sp->st_client_rerequests);
- MAKE_STAT_LIST("Duplicate master conditions", sp->st_dupmasters);
- MAKE_STAT_LIST("Environment ID", sp->st_env_id);
- MAKE_STAT_LIST("Environment priority", sp->st_env_priority);
- MAKE_STAT_LIST("Generation number", sp->st_gen);
- MAKE_STAT_LIST("Election generation number", sp->st_egen);
- MAKE_STAT_LIST("Startup complete", sp->st_startup_complete);
- MAKE_WSTAT_LIST("Duplicate log records received", sp->st_log_duplicated);
- MAKE_WSTAT_LIST("Current log records queued", sp->st_log_queued);
- MAKE_WSTAT_LIST("Maximum log records queued", sp->st_log_queued_max);
- MAKE_WSTAT_LIST("Total log records queued", sp->st_log_queued_total);
- MAKE_WSTAT_LIST("Log records received", sp->st_log_records);
- MAKE_WSTAT_LIST("Log records requested", sp->st_log_requested);
- MAKE_STAT_LIST("Master environment ID", sp->st_master);
- MAKE_WSTAT_LIST("Master changes", sp->st_master_changes);
- MAKE_STAT_LIST("Messages with bad generation number",
- sp->st_msgs_badgen);
- MAKE_WSTAT_LIST("Messages processed", sp->st_msgs_processed);
- MAKE_WSTAT_LIST("Messages ignored for recovery", sp->st_msgs_recover);
- MAKE_WSTAT_LIST("Message send failures", sp->st_msgs_send_failures);
- MAKE_WSTAT_LIST("Messages sent", sp->st_msgs_sent);
- MAKE_WSTAT_LIST("New site messages", sp->st_newsites);
- MAKE_STAT_LIST("Number of sites in replication group", sp->st_nsites);
- MAKE_WSTAT_LIST("Transmission limited", sp->st_nthrottles);
- MAKE_WSTAT_LIST("Outdated conditions", sp->st_outdated);
- MAKE_WSTAT_LIST("Transactions applied", sp->st_txns_applied);
- MAKE_STAT_LIST("Next page expected", sp->st_next_pg);
- MAKE_WSTAT_LIST("First missed page", sp->st_waiting_pg);
- MAKE_WSTAT_LIST("Duplicate pages received", sp->st_pg_duplicated);
- MAKE_WSTAT_LIST("Pages received", sp->st_pg_records);
- MAKE_WSTAT_LIST("Pages requested", sp->st_pg_requested);
- MAKE_WSTAT_LIST("Elections held", sp->st_elections);
- MAKE_WSTAT_LIST("Elections won", sp->st_elections_won);
- MAKE_STAT_LIST("Election phase", sp->st_election_status);
- MAKE_STAT_LIST("Election winner", sp->st_election_cur_winner);
- MAKE_STAT_LIST("Election generation number", sp->st_election_gen);
- MAKE_STAT_LSN("Election max LSN", &sp->st_election_lsn);
- MAKE_STAT_LIST("Election sites", sp->st_election_nsites);
- MAKE_STAT_LIST("Election nvotes", sp->st_election_nvotes);
- MAKE_STAT_LIST("Election priority", sp->st_election_priority);
- MAKE_STAT_LIST("Election tiebreaker", sp->st_election_tiebreaker);
- MAKE_STAT_LIST("Election votes", sp->st_election_votes);
- MAKE_STAT_LIST("Election seconds", sp->st_election_sec);
- MAKE_STAT_LIST("Election usecs", sp->st_election_usec);
- MAKE_STAT_LIST("Start-sync operations delayed",
- sp->st_startsync_delayed);
- MAKE_STAT_LIST("Maximum lease seconds", sp->st_max_lease_sec);
- MAKE_STAT_LIST("Maximum lease usecs", sp->st_max_lease_usec);
- MAKE_STAT_LIST("File fail cleanups done", sp->st_filefail_cleanups);
-#endif
-
- Tcl_SetObjResult(interp, res);
-error:
- __os_ufree(dbenv->env, sp);
- return (result);
-}
-
-/*
- * tcl_RepMgr --
- * Configure and start the Replication Manager.
- *
- * PUBLIC: int tcl_RepMgr
- * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
- */
-int
-tcl_RepMgr(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- static const char *rmgr[] = {
- "-ack",
- "-local",
- "-msgth",
- "-nsites",
- "-pri",
- "-remote",
- "-start",
- "-timeout",
- NULL
- };
- enum rmgr {
- RMGR_ACK,
- RMGR_LOCAL,
- RMGR_MSGTH,
- RMGR_NSITES,
- RMGR_PRI,
- RMGR_REMOTE,
- RMGR_START,
- RMGR_TIMEOUT
- };
- Tcl_Obj **myobjv;
- long to;
- int ack, i, myobjc, optindex, result, ret, totype;
- u_int32_t msgth, remote_flag, start_flag, uintarg;
- char *arg;
-
- result = TCL_OK;
- ack = ret = totype = 0;
- msgth = 1;
- remote_flag = start_flag = 0;
-
- if (objc <= 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?args?");
- return (TCL_ERROR);
- }
- /*
- * Get the command name index from the object based on the bdbcmds
- * defined above.
- */
- i = 2;
- while (i < objc) {
- Tcl_ResetResult(interp);
- if (Tcl_GetIndexFromObj(interp, objv[i], rmgr, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- result = IS_HELP(objv[i]);
- goto error;
- }
- i++;
- switch ((enum rmgr)optindex) {
- case RMGR_ACK:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-ack policy?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- if (strcmp(arg, "all") == 0)
- ack = DB_REPMGR_ACKS_ALL;
- else if (strcmp(arg, "allpeers") == 0)
- ack = DB_REPMGR_ACKS_ALL_PEERS;
- else if (strcmp(arg, "none") == 0)
- ack = DB_REPMGR_ACKS_NONE;
- else if (strcmp(arg, "one") == 0)
- ack = DB_REPMGR_ACKS_ONE;
- else if (strcmp(arg, "onepeer") == 0)
- ack = DB_REPMGR_ACKS_ONE_PEER;
- else if (strcmp(arg, "quorum") == 0)
- ack = DB_REPMGR_ACKS_QUORUM;
- else {
- Tcl_AddErrorInfo(interp,
- "ack: illegal policy");
- result = TCL_ERROR;
- break;
- }
- _debug_check();
- ret = dbenv->repmgr_set_ack_policy(dbenv, ack);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "ack");
- break;
- case RMGR_LOCAL:
- result = Tcl_ListObjGetElements(interp, objv[i],
- &myobjc, &myobjv);
- if (result == TCL_OK)
- i++;
- else
- break;
- if (myobjc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-local {host port}?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(myobjv[0], NULL);
- if ((result = _GetUInt32(interp, myobjv[1], &uintarg))
- != TCL_OK)
- break;
- _debug_check();
- /*
- * No flags for now.
- */
- ret = dbenv->repmgr_set_local_site(dbenv,
- arg, uintarg, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "repmgr_set_local_site");
- break;
- case RMGR_MSGTH:
- if (i >= objc) {
- Tcl_WrongNumArgs(
- interp, 2, objv, "?-msgth nth?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &msgth);
- break;
- case RMGR_NSITES:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-nsites num_sites?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = dbenv->
- rep_set_nsites(dbenv, uintarg);
- }
- break;
- case RMGR_PRI:
- if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-pri priority?");
- result = TCL_ERROR;
- break;
- }
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK) {
- _debug_check();
- ret = dbenv->
- rep_set_priority(dbenv, uintarg);
- }
- break;
- case RMGR_REMOTE:
- result = Tcl_ListObjGetElements(interp, objv[i],
- &myobjc, &myobjv);
- if (result == TCL_OK)
- i++;
- else
- break;
- if (myobjc != 2 && myobjc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-remote {host port [peer]}?");
- result = TCL_ERROR;
- break;
- }
- /*
- * Get the flag first so we can reuse 'arg'.
- */
- if (myobjc == 3) {
- arg = Tcl_GetStringFromObj(myobjv[2], NULL);
- if (strcmp(arg, "peer") == 0)
- remote_flag = DB_REPMGR_PEER;
- else {
- Tcl_AddErrorInfo(interp,
- "remote: illegal flag");
- result = TCL_ERROR;
- break;
- }
- }
- arg = Tcl_GetStringFromObj(myobjv[0], NULL);
- if ((result = _GetUInt32(interp, myobjv[1], &uintarg))
- != TCL_OK)
- break;
- _debug_check();
- ret = dbenv->repmgr_add_remote_site(dbenv,
- arg, uintarg, NULL, remote_flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "repmgr_add_remote_site");
- break;
- case RMGR_START:
- if (i >= objc) {
- Tcl_WrongNumArgs(
- interp, 2, objv, "?-start state?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- if (strcmp(arg, "master") == 0)
- start_flag = DB_REP_MASTER;
- else if (strcmp(arg, "client") == 0)
- start_flag = DB_REP_CLIENT;
- else if (strcmp(arg, "elect") == 0)
- start_flag = DB_REP_ELECTION;
- else {
- Tcl_AddErrorInfo(
- interp, "start: illegal state");
- result = TCL_ERROR;
- break;
- }
- /*
- * Some config functions need to be called
- * before repmgr_start. So finish parsing all
- * the args and call repmgr_start at the end.
- */
- break;
- case RMGR_TIMEOUT:
- result = Tcl_ListObjGetElements(interp, objv[i],
- &myobjc, &myobjv);
- if (result == TCL_OK)
- i++;
- else
- break;
- if (myobjc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-timeout {type to}?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(myobjv[0], NULL);
- if (strcmp(arg, "ack") == 0)
- totype = DB_REP_ACK_TIMEOUT;
- else if (strcmp(arg, "conn_retry") == 0)
- totype = DB_REP_CONNECTION_RETRY;
- else if (strcmp(arg, "elect") == 0)
- totype = DB_REP_ELECTION_TIMEOUT;
- else if (strcmp(arg, "elect_retry") == 0)
- totype = DB_REP_ELECTION_RETRY;
- else if (strcmp(arg, "heartbeat_monitor") == 0)
- totype = DB_REP_HEARTBEAT_MONITOR;
- else if (strcmp(arg, "heartbeat_send") == 0)
- totype = DB_REP_HEARTBEAT_SEND;
- else {
- Tcl_AddErrorInfo(interp,
- "timeout: illegal type");
- result = TCL_ERROR;
- break;
- }
- if ((result = Tcl_GetLongFromObj(
- interp, myobjv[1], &to)) != TCL_OK)
- break;
- _debug_check();
- ret = dbenv->rep_set_timeout(dbenv, totype,
- (db_timeout_t)to);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "rep_set_timeout");
- break;
- }
- /*
- * If, at any time, parsing the args we get an error,
- * bail out and return.
- */
- if (result != TCL_OK)
- goto error;
- }
- /*
- * Only call repmgr_start if needed. The user may use this
- * call just to reconfigure, change policy, etc.
- */
- if (start_flag != 0 && result == TCL_OK) {
- _debug_check();
- ret = dbenv->repmgr_start(dbenv, (int)msgth, start_flag);
- result = _ReturnSetup(
- interp, ret, DB_RETOK_REPMGR_START(ret), "repmgr_start");
- }
-error:
- return (result);
-}
-
-/*
- * tcl_RepMgrSiteList --
- * Call DB_ENV->repmgr_site_list().
- *
- * PUBLIC: int tcl_RepMgrSiteList
- * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
- */
-int
-tcl_RepMgrSiteList(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
-{
- DB_REPMGR_SITE *sp;
- Tcl_Obj *myobjv[4], *res, *thislist;
- u_int count, i;
- char *st;
- int myobjc, result, ret;
-
- result = TCL_OK;
-
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
-
- _debug_check();
- ret = dbenv->repmgr_site_list(dbenv, &count, &sp);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "repmgr sitelist");
- if (result == TCL_ERROR)
- return (result);
-
- /*
- * Have our sites, now construct the {eid host port status}
- * tuples and free up the memory.
- */
- res = Tcl_NewObj();
-
- for (i = 0; i < count; ++i) {
- /*
- * MAKE_SITE_LIST assumes 'res' and 'error' label.
- */
- if (sp[i].status == DB_REPMGR_CONNECTED)
- st = "connected";
- else if (sp[i].status == DB_REPMGR_DISCONNECTED)
- st = "disconnected";
- else
- st = "unknown";
- MAKE_SITE_LIST(sp[i].eid, sp[i].host, sp[i].port, st);
- }
-
- Tcl_SetObjResult(interp, res);
-error:
- __os_ufree(dbenv->env, sp);
- return (result);
-}
-
-/*
- * tcl_RepMgrStat --
- * Call DB_ENV->repmgr_stat().
- *
- * PUBLIC: int tcl_RepMgrStat
- * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
- */
-int
-tcl_RepMgrStat(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv;
-{
- DB_REPMGR_STAT *sp;
- Tcl_Obj *res;
- u_int32_t flag;
- int result, ret;
- char *arg;
-
- flag = 0;
- result = TCL_OK;
-
- if (objc > 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- if (objc == 3) {
- arg = Tcl_GetStringFromObj(objv[2], NULL);
- if (strcmp(arg, "-clear") == 0)
- flag = DB_STAT_CLEAR;
- else {
- Tcl_SetResult(interp,
- "db stat: unknown arg", TCL_STATIC);
- return (TCL_ERROR);
- }
- }
-
- _debug_check();
- ret = dbenv->repmgr_stat(dbenv, &sp, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "repmgr stat");
- if (result == TCL_ERROR)
- return (result);
-
- /*
- * Have our stats, now construct the name value
- * list pairs and free up the memory.
- */
- res = Tcl_NewObj();
-#ifdef HAVE_STATISTICS
- /*
- * MAKE_STAT_* assumes 'res' and 'error' label.
- */
- MAKE_WSTAT_LIST("Acknowledgement failures", sp->st_perm_failed);
- MAKE_WSTAT_LIST("Messages delayed", sp->st_msgs_queued);
- MAKE_WSTAT_LIST("Messages discarded", sp->st_msgs_dropped);
- MAKE_WSTAT_LIST("Connections dropped", sp->st_connection_drop);
- MAKE_WSTAT_LIST("Failed re-connects", sp->st_connect_fail);
-#endif
-
- Tcl_SetObjResult(interp, res);
-error:
- __os_ufree(dbenv->env, sp);
- return (result);
-}
-#endif
diff --git a/tcl/tcl_seq.c b/tcl/tcl_seq.c
deleted file mode 100644
index dc35e22..0000000
--- a/tcl/tcl_seq.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 2004-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-#ifdef HAVE_64BIT_TYPES
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/tcl_db.h"
-#include "dbinc_auto/sequence_ext.h"
-
-/*
- * Prototypes for procedures defined later in this file:
- */
-static int tcl_SeqClose __P((Tcl_Interp *,
- int, Tcl_Obj * CONST*, DB_SEQUENCE *, DBTCL_INFO *));
-static int tcl_SeqGet __P((Tcl_Interp *,
- int, Tcl_Obj * CONST*, DB_SEQUENCE *));
-static int tcl_SeqRemove __P((Tcl_Interp *,
- int, Tcl_Obj * CONST*, DB_SEQUENCE *, DBTCL_INFO *));
-static int tcl_SeqStat __P((Tcl_Interp *,
- int, Tcl_Obj * CONST*, DB_SEQUENCE *));
-static int tcl_SeqGetFlags __P((Tcl_Interp *,
- int, Tcl_Obj * CONST*, DB_SEQUENCE *));
-
-/*
- *
- * PUBLIC: int seq_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
- *
- * seq_Cmd --
- * Implements the "seq" widget.
- */
-int
-seq_Cmd(clientData, interp, objc, objv)
- ClientData clientData; /* SEQ handle */
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *seqcmds[] = {
- "close",
- "get",
- "get_cachesize",
- "get_db",
- "get_flags",
- "get_key",
- "get_range",
- "remove",
- "stat",
- NULL
- };
- enum seqcmds {
- SEQCLOSE,
- SEQGET,
- SEQGETCACHESIZE,
- SEQGETDB,
- SEQGETFLAGS,
- SEQGETKEY,
- SEQGETRANGE,
- SEQREMOVE,
- SEQSTAT
- };
- DB *dbp;
- DBT key;
- DBTCL_INFO *dbip, *ip;
- DB_SEQUENCE *seq;
- Tcl_Obj *myobjv[2], *res;
- db_seq_t min, max;
- int cmdindex, ncache, result, ret;
-
- Tcl_ResetResult(interp);
- seq = (DB_SEQUENCE *)clientData;
- result = TCL_OK;
- dbip = NULL;
- if (objc <= 1) {
- Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs");
- return (TCL_ERROR);
- }
- if (seq == NULL) {
- Tcl_SetResult(interp, "NULL sequence pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- ip = _PtrToInfo((void *)seq);
- if (ip == NULL) {
- Tcl_SetResult(interp, "NULL info pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the dbcmds
- * defined above.
- */
- if (Tcl_GetIndexFromObj(interp,
- objv[1], seqcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
-
- res = NULL;
- switch ((enum seqcmds)cmdindex) {
- case SEQGETRANGE:
- ret = seq->get_range(seq, &min, &max);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "sequence get_range")) == TCL_OK) {
- myobjv[0] = Tcl_NewWideIntObj(min);
- myobjv[1] = Tcl_NewWideIntObj(max);
- res = Tcl_NewListObj(2, myobjv);
- }
- break;
- case SEQCLOSE:
- result = tcl_SeqClose(interp, objc, objv, seq, ip);
- break;
- case SEQREMOVE:
- result = tcl_SeqRemove(interp, objc, objv, seq, ip);
- break;
- case SEQGET:
- result = tcl_SeqGet(interp, objc, objv, seq);
- break;
- case SEQSTAT:
- result = tcl_SeqStat(interp, objc, objv, seq);
- break;
- case SEQGETCACHESIZE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = seq->get_cachesize(seq, &ncache);
- if ((result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "sequence get_cachesize")) == TCL_OK)
- res = Tcl_NewIntObj(ncache);
- break;
- case SEQGETDB:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = seq->get_db(seq, &dbp);
- if (ret == 0 && (dbip = _PtrToInfo((void *)dbp)) == NULL) {
- Tcl_SetResult(interp,
- "NULL db info pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- if ((result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "sequence get_db")) == TCL_OK)
- res = NewStringObj(dbip->i_name, strlen(dbip->i_name));
- break;
- case SEQGETKEY:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- ret = seq->get_key(seq, &key);
- if ((result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "sequence get_key")) == TCL_OK)
- res = Tcl_NewByteArrayObj(
- (u_char *)key.data, (int)key.size);
- break;
- case SEQGETFLAGS:
- result = tcl_SeqGetFlags(interp, objc, objv, seq);
- break;
- }
-
- /*
- * Only set result if we have a res. Otherwise, lower functions have
- * already done so.
- */
- if (result == TCL_OK && res)
- Tcl_SetObjResult(interp, res);
- return (result);
-}
-
-/*
- * tcl_db_stat --
- */
-static int
-tcl_SeqStat(interp, objc, objv, seq)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_SEQUENCE *seq; /* Database pointer */
-{
- DB_SEQUENCE_STAT *sp;
- u_int32_t flag;
- Tcl_Obj *res, *flaglist, *myobjv[2];
- int result, ret;
- char *arg;
-
- result = TCL_OK;
- flag = 0;
-
- if (objc > 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-clear?");
- return (TCL_ERROR);
- }
-
- if (objc == 3) {
- arg = Tcl_GetStringFromObj(objv[2], NULL);
- if (strcmp(arg, "-clear") == 0)
- flag = DB_STAT_CLEAR;
- else {
- Tcl_SetResult(interp,
- "db stat: unknown arg", TCL_STATIC);
- return (TCL_ERROR);
- }
- }
-
- _debug_check();
- ret = seq->stat(seq, &sp, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db stat");
- if (result == TCL_ERROR)
- return (result);
-
- res = Tcl_NewObj();
- MAKE_WSTAT_LIST("Wait", sp->st_wait);
- MAKE_WSTAT_LIST("No wait", sp->st_nowait);
- MAKE_WSTAT_LIST("Current", sp->st_current);
- MAKE_WSTAT_LIST("Cached", sp->st_value);
- MAKE_WSTAT_LIST("Max Cached", sp->st_last_value);
- MAKE_WSTAT_LIST("Min", sp->st_min);
- MAKE_WSTAT_LIST("Max", sp->st_max);
- MAKE_STAT_LIST("Cache size", sp->st_cache_size);
- /*
- * Construct a {name {flag1 flag2 ... flagN}} list for the
- * seq flags.
- */
- myobjv[0] = NewStringObj("Flags", strlen("Flags"));
- myobjv[1] =
- _GetFlagsList(interp, sp->st_flags, __db_get_seq_flags_fn());
- flaglist = Tcl_NewListObj(2, myobjv);
- if (flaglist == NULL) {
- result = TCL_ERROR;
- goto error;
- }
- if ((result =
- Tcl_ListObjAppendElement(interp, res, flaglist)) != TCL_OK)
- goto error;
-
- Tcl_SetObjResult(interp, res);
-
-error: __os_ufree(seq->seq_dbp->env, sp);
- return (result);
-}
-
-/*
- * tcl_db_close --
- */
-static int
-tcl_SeqClose(interp, objc, objv, seq, ip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_SEQUENCE *seq; /* Database pointer */
- DBTCL_INFO *ip; /* Info pointer */
-{
- int result, ret;
-
- result = TCL_OK;
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "");
- return (TCL_ERROR);
- }
-
- _DeleteInfo(ip);
- _debug_check();
-
- ret = seq->close(seq, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "sequence close");
- return (result);
-}
-
-/*
- * tcl_SeqGet --
- */
-static int
-tcl_SeqGet(interp, objc, objv, seq)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_SEQUENCE *seq; /* Sequence pointer */
-{
- static const char *seqgetopts[] = {
- "-nosync",
- "-txn",
- NULL
- };
- enum seqgetopts {
- SEQGET_NOSYNC,
- SEQGET_TXN
- };
- DB_TXN *txn;
- Tcl_Obj *res;
- db_seq_t value;
- u_int32_t aflag, delta;
- int i, end, optindex, result, ret;
- char *arg, msg[MSG_SIZE];
-
- result = TCL_OK;
- txn = NULL;
- aflag = 0;
-
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-args? delta");
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the options
- * defined above.
- */
- i = 2;
- end = objc;
- while (i < end) {
- if (Tcl_GetIndexFromObj(interp, objv[i], seqgetopts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto out;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum seqgetopts)optindex) {
- case SEQGET_NOSYNC:
- aflag |= DB_TXN_NOSYNC;
- break;
- case SEQGET_TXN:
- if (i >= end) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Get: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- } /* switch */
- if (result != TCL_OK)
- break;
- }
- if (result != TCL_OK)
- goto out;
-
- if (i != objc - 1) {
- Tcl_SetResult(interp,
- "Wrong number of key/data given\n", TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- }
-
- if ((result = _GetUInt32(interp, objv[objc - 1], &delta)) != TCL_OK)
- goto out;
-
- ret = seq->get(seq, txn, (int32_t)delta, &value, aflag);
- result = _ReturnSetup(interp, ret, DB_RETOK_DBGET(ret), "sequence get");
- if (ret == 0) {
- res = Tcl_NewWideIntObj((Tcl_WideInt)value);
- Tcl_SetObjResult(interp, res);
- }
-out:
- return (result);
-}
-/*
- */
-static int
-tcl_SeqRemove(interp, objc, objv, seq, ip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_SEQUENCE *seq; /* Sequence pointer */
- DBTCL_INFO *ip; /* Info pointer */
-{
- static const char *seqgetopts[] = {
- "-nosync",
- "-txn",
- NULL
- };
- enum seqgetopts {
- SEQGET_NOSYNC,
- SEQGET_TXN
- };
- DB_TXN *txn;
- u_int32_t aflag;
- int i, end, optindex, result, ret;
- char *arg, msg[MSG_SIZE];
-
- result = TCL_OK;
- txn = NULL;
- aflag = 0;
-
- _DeleteInfo(ip);
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-args?");
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the options
- * defined above.
- */
- i = 2;
- end = objc;
- while (i < end) {
- if (Tcl_GetIndexFromObj(interp, objv[i], seqgetopts, "option",
- TCL_EXACT, &optindex) != TCL_OK) {
- arg = Tcl_GetStringFromObj(objv[i], NULL);
- if (arg[0] == '-') {
- result = IS_HELP(objv[i]);
- goto out;
- } else
- Tcl_ResetResult(interp);
- break;
- }
- i++;
- switch ((enum seqgetopts)optindex) {
- case SEQGET_NOSYNC:
- aflag |= DB_TXN_NOSYNC;
- break;
- case SEQGET_TXN:
- if (i >= end) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- txn = NAME_TO_TXN(arg);
- if (txn == NULL) {
- snprintf(msg, MSG_SIZE,
- "Remove: Invalid txn: %s\n", arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- result = TCL_ERROR;
- }
- break;
- } /* switch */
- if (result != TCL_OK)
- break;
- }
- if (result != TCL_OK)
- goto out;
-
- ret = seq->remove(seq, txn, aflag);
- result = _ReturnSetup(interp,
- ret, DB_RETOK_DBGET(ret), "sequence remove");
-out:
- return (result);
-}
-
-/*
- * tcl_SeqGetFlags --
- */
-static int
-tcl_SeqGetFlags(interp, objc, objv, seq)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_SEQUENCE *seq; /* Sequence pointer */
-{
- int i, ret, result;
- u_int32_t flags;
- char buf[512];
- Tcl_Obj *res;
-
- static const struct {
- u_int32_t flag;
- char *arg;
- } seq_flags[] = {
- { DB_SEQ_INC, "-inc" },
- { DB_SEQ_DEC, "-dec" },
- { DB_SEQ_WRAP, "-wrap" },
- { 0, NULL }
- };
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
-
- ret = seq->get_flags(seq, &flags);
- if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_flags")) == TCL_OK) {
- buf[0] = '\0';
-
- for (i = 0; seq_flags[i].flag != 0; i++)
- if (LF_ISSET(seq_flags[i].flag)) {
- if (strlen(buf) > 0)
- (void)strncat(buf, " ", sizeof(buf));
- (void)strncat(
- buf, seq_flags[i].arg, sizeof(buf));
- }
-
- res = NewStringObj(buf, strlen(buf));
- Tcl_SetObjResult(interp, res);
- }
-
- return (result);
-}
-#endif /* HAVE_64BIT_TYPES */
diff --git a/tcl/tcl_txn.c b/tcl/tcl_txn.c
deleted file mode 100644
index 850ff02..0000000
--- a/tcl/tcl_txn.c
+++ /dev/null
@@ -1,778 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/tcl_db.h"
-
-static int tcl_TxnCommit __P((Tcl_Interp *,
- int, Tcl_Obj * CONST *, DB_TXN *, DBTCL_INFO *));
-static int txn_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST *));
-
-/*
- * _TxnInfoDelete --
- * Removes nested txn info structures that are children
- * of this txn.
- * RECURSIVE: Transactions can be arbitrarily nested, so we
- * must recurse down until we get them all.
- *
- * PUBLIC: void _TxnInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
- */
-void
-_TxnInfoDelete(interp, txnip)
- Tcl_Interp *interp; /* Interpreter */
- DBTCL_INFO *txnip; /* Info for txn */
-{
- DBTCL_INFO *nextp, *p;
-
- for (p = LIST_FIRST(&__db_infohead); p != NULL; p = nextp) {
- /*
- * Check if this info structure "belongs" to this
- * txn. Remove its commands and info structure.
- */
- nextp = LIST_NEXT(p, entries);
- if (p->i_parent == txnip && p->i_type == I_TXN) {
- _TxnInfoDelete(interp, p);
- (void)Tcl_DeleteCommand(interp, p->i_name);
- _DeleteInfo(p);
- }
- }
-}
-
-/*
- * tcl_TxnCheckpoint --
- *
- * PUBLIC: int tcl_TxnCheckpoint __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_TxnCheckpoint(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- static const char *txnckpopts[] = {
- "-force",
- "-kbyte",
- "-min",
- NULL
- };
- enum txnckpopts {
- TXNCKP_FORCE,
- TXNCKP_KB,
- TXNCKP_MIN
- };
- u_int32_t flags;
- int i, kb, min, optindex, result, ret;
-
- result = TCL_OK;
- flags = 0;
- kb = min = 0;
-
- /*
- * Get the flag index from the object based on the options
- * defined above.
- */
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i],
- txnckpopts, "option", TCL_EXACT, &optindex) != TCL_OK) {
- return (IS_HELP(objv[i]));
- }
- i++;
- switch ((enum txnckpopts)optindex) {
- case TXNCKP_FORCE:
- flags = DB_FORCE;
- break;
- case TXNCKP_KB:
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-kbyte kb?");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, objv[i++], &kb);
- break;
- case TXNCKP_MIN:
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-min min?");
- result = TCL_ERROR;
- break;
- }
- result = Tcl_GetIntFromObj(interp, objv[i++], &min);
- break;
- }
- }
- _debug_check();
- ret = dbenv->txn_checkpoint(dbenv, (u_int32_t)kb, (u_int32_t)min,
- flags);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "txn checkpoint");
- return (result);
-}
-
-/*
- * tcl_Txn --
- *
- * PUBLIC: int tcl_Txn __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
- */
-int
-tcl_Txn(interp, objc, objv, dbenv, envip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
- DBTCL_INFO *envip; /* Info pointer */
-{
- static const char *txnopts[] = {
-#ifdef CONFIG_TEST
- "-lock_timeout",
- "-read_committed",
- "-read_uncommitted",
- "-txn_timeout",
- "-txn_wait",
-#endif
- "-nosync",
- "-nowait",
- "-parent",
- "-snapshot",
- "-sync",
- "-wrnosync",
- NULL
- };
- enum txnopts {
-#ifdef CONFIG_TEST
- TXNLOCK_TIMEOUT,
- TXNREAD_COMMITTED,
- TXNREAD_UNCOMMITTED,
- TXNTIMEOUT,
- TXNWAIT,
-#endif
- TXNNOSYNC,
- TXNNOWAIT,
- TXNPARENT,
- TXNSNAPSHOT,
- TXNSYNC,
- TXNWRNOSYNC
- };
- DBTCL_INFO *ip;
- DB_TXN *parent;
- DB_TXN *txn;
- Tcl_Obj *res;
- u_int32_t flag;
- int i, optindex, result, ret;
- char *arg, msg[MSG_SIZE], newname[MSG_SIZE];
-#ifdef CONFIG_TEST
- db_timeout_t lk_time, tx_time;
- u_int32_t lk_timeflag, tx_timeflag;
-#endif
-
- result = TCL_OK;
- memset(newname, 0, MSG_SIZE);
-
- parent = NULL;
- flag = 0;
-#ifdef CONFIG_TEST
- COMPQUIET(tx_time, 0);
- COMPQUIET(lk_time, 0);
- lk_timeflag = tx_timeflag = 0;
-#endif
- i = 2;
- while (i < objc) {
- if (Tcl_GetIndexFromObj(interp, objv[i],
- txnopts, "option", TCL_EXACT, &optindex) != TCL_OK) {
- return (IS_HELP(objv[i]));
- }
- i++;
- switch ((enum txnopts)optindex) {
-#ifdef CONFIG_TEST
- case TXNLOCK_TIMEOUT:
- lk_timeflag = DB_SET_LOCK_TIMEOUT;
- goto get_timeout;
- case TXNTIMEOUT:
- tx_timeflag = DB_SET_TXN_TIMEOUT;
-get_timeout: if (i >= objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-txn_timestamp time?");
- return (TCL_ERROR);
- }
- result = Tcl_GetLongFromObj(interp, objv[i++], (long *)
- ((enum txnopts)optindex == TXNLOCK_TIMEOUT ?
- &lk_time : &tx_time));
- if (result != TCL_OK)
- return (TCL_ERROR);
- break;
- case TXNREAD_COMMITTED:
- flag |= DB_READ_COMMITTED;
- break;
- case TXNREAD_UNCOMMITTED:
- flag |= DB_READ_UNCOMMITTED;
- break;
- case TXNWAIT:
- flag |= DB_TXN_WAIT;
- break;
-#endif
- case TXNNOSYNC:
- flag |= DB_TXN_NOSYNC;
- break;
- case TXNNOWAIT:
- flag |= DB_TXN_NOWAIT;
- break;
- case TXNPARENT:
- if (i == objc) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-parent txn?");
- result = TCL_ERROR;
- break;
- }
- arg = Tcl_GetStringFromObj(objv[i++], NULL);
- parent = NAME_TO_TXN(arg);
- if (parent == NULL) {
- snprintf(msg, MSG_SIZE,
- "Invalid parent txn: %s\n",
- arg);
- Tcl_SetResult(interp, msg, TCL_VOLATILE);
- return (TCL_ERROR);
- }
- break;
- case TXNSNAPSHOT:
- flag |= DB_TXN_SNAPSHOT;
- break;
- case TXNSYNC:
- flag |= DB_TXN_SYNC;
- break;
- case TXNWRNOSYNC:
- flag |= DB_TXN_WRITE_NOSYNC;
- break;
- }
- }
- snprintf(newname, sizeof(newname), "%s.txn%d",
- envip->i_name, envip->i_envtxnid);
- ip = _NewInfo(interp, NULL, newname, I_TXN);
- if (ip == NULL) {
- Tcl_SetResult(interp, "Could not set up info",
- TCL_STATIC);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbenv->txn_begin(dbenv, parent, &txn, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "txn");
- if (result == TCL_ERROR)
- _DeleteInfo(ip);
- else {
- /*
- * Success. Set up return. Set up new info
- * and command widget for this txn.
- */
- envip->i_envtxnid++;
- if (parent)
- ip->i_parent = _PtrToInfo(parent);
- else
- ip->i_parent = envip;
- _SetInfoData(ip, txn);
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)txn_Cmd, (ClientData)txn, NULL);
- res = NewStringObj(newname, strlen(newname));
- Tcl_SetObjResult(interp, res);
-#ifdef CONFIG_TEST
- if (tx_timeflag != 0) {
- ret = txn->set_timeout(txn, tx_time, tx_timeflag);
- if (ret != 0) {
- result =
- _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_timeout");
- _DeleteInfo(ip);
- }
- }
- if (lk_timeflag != 0) {
- ret = txn->set_timeout(txn, lk_time, lk_timeflag);
- if (ret != 0) {
- result =
- _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_timeout");
- _DeleteInfo(ip);
- }
- }
-#endif
- }
- return (result);
-}
-
-/*
- * tcl_CDSGroup --
- *
- * PUBLIC: int tcl_CDSGroup __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
- */
-int
-tcl_CDSGroup(interp, objc, objv, dbenv, envip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
- DBTCL_INFO *envip; /* Info pointer */
-{
- DBTCL_INFO *ip;
- DB_TXN *txn;
- Tcl_Obj *res;
- int result, ret;
- char newname[MSG_SIZE];
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "env cdsgroup");
- return (TCL_ERROR);
- }
-
- result = TCL_OK;
- memset(newname, 0, MSG_SIZE);
-
- snprintf(newname, sizeof(newname), "%s.txn%d",
- envip->i_name, envip->i_envtxnid);
- ip = _NewInfo(interp, NULL, newname, I_TXN);
- if (ip == NULL) {
- Tcl_SetResult(interp, "Could not set up info",
- TCL_STATIC);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbenv->cdsgroup_begin(dbenv, &txn);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "cdsgroup");
- if (result == TCL_ERROR)
- _DeleteInfo(ip);
- else {
- /*
- * Success. Set up return. Set up new info
- * and command widget for this txn.
- */
- envip->i_envtxnid++;
- ip->i_parent = envip;
- _SetInfoData(ip, txn);
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)txn_Cmd, (ClientData)txn, NULL);
- res = NewStringObj(newname, strlen(newname));
- Tcl_SetObjResult(interp, res);
- }
- return (result);
-}
-
-/*
- * tcl_TxnStat --
- *
- * PUBLIC: int tcl_TxnStat __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_TxnStat(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- DBTCL_INFO *ip;
- DB_TXN_ACTIVE *p;
- DB_TXN_STAT *sp;
- Tcl_Obj *myobjv[2], *res, *thislist, *lsnlist;
- u_int32_t i;
- int myobjc, result, ret;
-
- result = TCL_OK;
- /*
- * No args for this. Error if there are some.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbenv->txn_stat(dbenv, &sp, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "txn stat");
- if (result == TCL_ERROR)
- return (result);
-
- /*
- * Have our stats, now construct the name value
- * list pairs and free up the memory.
- */
- res = Tcl_NewObj();
- /*
- * MAKE_STAT_LIST assumes 'res' and 'error' label.
- */
-#ifdef HAVE_STATISTICS
- MAKE_STAT_LIST("Region size", sp->st_regsize);
- MAKE_STAT_LSN("LSN of last checkpoint", &sp->st_last_ckp);
- MAKE_STAT_LIST("Time of last checkpoint", sp->st_time_ckp);
- MAKE_STAT_LIST("Last txn ID allocated", sp->st_last_txnid);
- MAKE_STAT_LIST("Maximum txns", sp->st_maxtxns);
- MAKE_WSTAT_LIST("Number aborted txns", sp->st_naborts);
- MAKE_WSTAT_LIST("Number txns begun", sp->st_nbegins);
- MAKE_WSTAT_LIST("Number committed txns", sp->st_ncommits);
- MAKE_STAT_LIST("Number active txns", sp->st_nactive);
- MAKE_STAT_LIST("Number of snapshot txns", sp->st_nsnapshot);
- MAKE_STAT_LIST("Number restored txns", sp->st_nrestores);
- MAKE_STAT_LIST("Maximum active txns", sp->st_maxnactive);
- MAKE_STAT_LIST("Maximum snapshot txns", sp->st_maxnsnapshot);
- MAKE_WSTAT_LIST("Number of region lock waits", sp->st_region_wait);
- MAKE_WSTAT_LIST("Number of region lock nowaits", sp->st_region_nowait);
- for (i = 0, p = sp->st_txnarray; i < sp->st_nactive; i++, p++)
- LIST_FOREACH(ip, &__db_infohead, entries) {
- if (ip->i_type != I_TXN)
- continue;
- if (ip->i_type == I_TXN &&
- (ip->i_txnp->id(ip->i_txnp) == p->txnid)) {
- MAKE_STAT_LSN(ip->i_name, &p->lsn);
- if (p->parentid != 0)
- MAKE_STAT_STRLIST("Parent",
- ip->i_parent->i_name);
- else
- MAKE_STAT_LIST("Parent", 0);
- break;
- }
- }
-#endif
- Tcl_SetObjResult(interp, res);
-error:
- __os_ufree(dbenv->env, sp);
- return (result);
-}
-
-/*
- * tcl_TxnTimeout --
- *
- * PUBLIC: int tcl_TxnTimeout __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
- */
-int
-tcl_TxnTimeout(interp, objc, objv, dbenv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
-{
- long timeout;
- int result, ret;
-
- /*
- * One arg, the timeout.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?timeout?");
- return (TCL_ERROR);
- }
- result = Tcl_GetLongFromObj(interp, objv[2], &timeout);
- if (result != TCL_OK)
- return (result);
- _debug_check();
- ret = dbenv->set_timeout(dbenv, (u_int32_t)timeout, DB_SET_TXN_TIMEOUT);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "lock timeout");
- return (result);
-}
-
-/*
- * txn_Cmd --
- * Implements the "txn" widget.
- */
-static int
-txn_Cmd(clientData, interp, objc, objv)
- ClientData clientData; /* Txn handle */
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *txncmds[] = {
-#ifdef CONFIG_TEST
- "discard",
- "getname",
- "id",
- "prepare",
- "setname",
-#endif
- "abort",
- "commit",
- "getname",
- "setname",
- NULL
- };
- enum txncmds {
-#ifdef CONFIG_TEST
- TXNDISCARD,
- TXNGETNAME,
- TXNID,
- TXNPREPARE,
- TXNSETNAME,
-#endif
- TXNABORT,
- TXNCOMMIT
- };
- DBTCL_INFO *txnip;
- DB_TXN *txnp;
- Tcl_Obj *res;
- int cmdindex, result, ret;
-#ifdef CONFIG_TEST
- u_int8_t *gid, garray[DB_GID_SIZE];
- int length;
- const char *name;
-#endif
-
- Tcl_ResetResult(interp);
- txnp = (DB_TXN *)clientData;
- txnip = _PtrToInfo((void *)txnp);
- result = TCL_OK;
- if (txnp == NULL) {
- Tcl_SetResult(interp, "NULL txn pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (txnip == NULL) {
- Tcl_SetResult(interp, "NULL txn info pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the dbcmds
- * defined above.
- */
- if (Tcl_GetIndexFromObj(interp,
- objv[1], txncmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
-
- res = NULL;
- switch ((enum txncmds)cmdindex) {
-#ifdef CONFIG_TEST
- case TXNDISCARD:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = txnp->discard(txnp, 0);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "txn discard");
- _TxnInfoDelete(interp, txnip);
- (void)Tcl_DeleteCommand(interp, txnip->i_name);
- _DeleteInfo(txnip);
- break;
- case TXNID:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- res = Tcl_NewIntObj((int)txnp->id(txnp));
- break;
- case TXNPREPARE:
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- gid = (u_int8_t *)Tcl_GetByteArrayFromObj(objv[2], &length);
- memcpy(garray, gid, (size_t)length);
- ret = txnp->prepare(txnp, garray);
- /*
- * !!!
- * DB_TXN->prepare commits all outstanding children. But it
- * does NOT destroy the current txn handle. So, we must call
- * _TxnInfoDelete to recursively remove all nested txn handles,
- * we do not call _DeleteInfo on ourselves.
- */
- _TxnInfoDelete(interp, txnip);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "txn prepare");
- break;
- case TXNGETNAME:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = txnp->get_name(txnp, &name);
- if ((result = _ReturnSetup(
- interp, ret, DB_RETOK_STD(ret), "txn getname")) == TCL_OK)
- res = NewStringObj(name, strlen(name));
- break;
- case TXNSETNAME:
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "name");
- return (TCL_ERROR);
- }
- _debug_check();
- ret = txnp->set_name(txnp, Tcl_GetStringFromObj(objv[2], NULL));
- result =
- _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "setname");
- break;
-#endif
- case TXNABORT:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = txnp->abort(txnp);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "txn abort");
- _TxnInfoDelete(interp, txnip);
- (void)Tcl_DeleteCommand(interp, txnip->i_name);
- _DeleteInfo(txnip);
- break;
- case TXNCOMMIT:
- result = tcl_TxnCommit(interp, objc, objv, txnp, txnip);
- _TxnInfoDelete(interp, txnip);
- (void)Tcl_DeleteCommand(interp, txnip->i_name);
- _DeleteInfo(txnip);
- break;
- }
- /*
- * Only set result if we have a res. Otherwise, lower
- * functions have already done so.
- */
- if (result == TCL_OK && res)
- Tcl_SetObjResult(interp, res);
- return (result);
-}
-
-static int
-tcl_TxnCommit(interp, objc, objv, txnp, txnip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_TXN *txnp; /* Transaction pointer */
- DBTCL_INFO *txnip; /* Info pointer */
-{
- static const char *commitopt[] = {
- "-nosync",
- "-sync",
- "-wrnosync",
- NULL
- };
- enum commitopt {
- COMNOSYNC,
- COMSYNC,
- COMWRNOSYNC
- };
- u_int32_t flag;
- int optindex, result, ret;
-
- COMPQUIET(txnip, NULL);
-
- result = TCL_OK;
- flag = 0;
- if (objc != 2 && objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- if (objc == 3) {
- if (Tcl_GetIndexFromObj(interp, objv[2], commitopt,
- "option", TCL_EXACT, &optindex) != TCL_OK)
- return (IS_HELP(objv[2]));
- switch ((enum commitopt)optindex) {
- case COMSYNC:
- flag = DB_TXN_SYNC;
- break;
- case COMNOSYNC:
- flag = DB_TXN_NOSYNC;
- break;
- case COMWRNOSYNC:
- flag = DB_TXN_WRITE_NOSYNC;
- break;
- }
- }
-
- _debug_check();
- ret = txnp->commit(txnp, flag);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "txn commit");
- return (result);
-}
-
-#ifdef CONFIG_TEST
-/*
- * tcl_TxnRecover --
- *
- * PUBLIC: int tcl_TxnRecover __P((Tcl_Interp *, int,
- * PUBLIC: Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
- */
-int
-tcl_TxnRecover(interp, objc, objv, dbenv, envip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *dbenv; /* Environment pointer */
- DBTCL_INFO *envip; /* Info pointer */
-{
-#define DO_PREPLIST(count) \
-for (i = 0; i < count; i++) { \
- snprintf(newname, sizeof(newname), "%s.txn%d", \
- envip->i_name, envip->i_envtxnid); \
- ip = _NewInfo(interp, NULL, newname, I_TXN); \
- if (ip == NULL) { \
- Tcl_SetResult(interp, "Could not set up info", \
- TCL_STATIC); \
- return (TCL_ERROR); \
- } \
- envip->i_envtxnid++; \
- ip->i_parent = envip; \
- p = &prep[i]; \
- _SetInfoData(ip, p->txn); \
- (void)Tcl_CreateObjCommand(interp, newname, \
- (Tcl_ObjCmdProc *)txn_Cmd, (ClientData)p->txn, NULL); \
- result = _SetListElem(interp, res, newname, \
- (u_int32_t)strlen(newname), p->gid, DB_GID_SIZE); \
- if (result != TCL_OK) \
- goto error; \
-}
-
- DBTCL_INFO *ip;
- DB_PREPLIST prep[DBTCL_PREP], *p;
- Tcl_Obj *res;
- u_int32_t count, i;
- int result, ret;
- char newname[MSG_SIZE];
-
- result = TCL_OK;
- /*
- * No args for this. Error if there are some.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbenv->txn_recover(dbenv, prep, DBTCL_PREP, &count, DB_FIRST);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "txn recover");
- if (result == TCL_ERROR)
- return (result);
- res = Tcl_NewObj();
- DO_PREPLIST(count);
-
- /*
- * If count returned is the maximum size we have, then there
- * might be more. Keep going until we get them all.
- */
- while (count == DBTCL_PREP) {
- ret = dbenv->txn_recover(
- dbenv, prep, DBTCL_PREP, &count, DB_NEXT);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "txn recover");
- if (result == TCL_ERROR)
- return (result);
- DO_PREPLIST(count);
- }
- Tcl_SetObjResult(interp, res);
-error:
- return (result);
-}
-#endif
diff --git a/tcl/tcl_util.c b/tcl/tcl_util.c
deleted file mode 100644
index addf56a..0000000
--- a/tcl/tcl_util.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2009 Oracle. All rights reserved.
- *
- * $Id$
- */
-
-#include "db_config.h"
-
-#include "db_int.h"
-#ifdef HAVE_SYSTEM_INCLUDE_FILES
-#include <tcl.h>
-#endif
-#include "dbinc/tcl_db.h"
-
-/*
- * bdb_RandCommand --
- * Implements rand* functions.
- *
- * PUBLIC: int bdb_RandCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
- */
-int
-bdb_RandCommand(interp, objc, objv)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *rcmds[] = {
- "rand", "random_int", "srand",
- NULL
- };
- enum rcmds {
- RRAND, RRAND_INT, RSRAND
- };
- Tcl_Obj *res;
- int cmdindex, hi, lo, result, ret;
-
- result = TCL_OK;
- /*
- * Get the command name index from the object based on the cmds
- * defined above. This SHOULD NOT fail because we already checked
- * in the 'berkdb' command.
- */
- if (Tcl_GetIndexFromObj(interp,
- objv[1], rcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
-
- res = NULL;
- switch ((enum rcmds)cmdindex) {
- case RRAND:
- /*
- * Must be 0 args. Error if different.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
-#ifdef HAVE_RANDOM
- ret = random();
-#else
- ret = rand();
-#endif
- res = Tcl_NewIntObj(ret);
- break;
- case RRAND_INT:
- /*
- * Must be 4 args. Error if different.
- */
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "lo hi");
- return (TCL_ERROR);
- }
- if ((result =
- Tcl_GetIntFromObj(interp, objv[2], &lo)) != TCL_OK)
- return (result);
- if ((result =
- Tcl_GetIntFromObj(interp, objv[3], &hi)) != TCL_OK)
- return (result);
- if (lo < 0 || hi < 0) {
- Tcl_SetResult(interp,
- "Range value less than 0", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- _debug_check();
-#ifdef HAVE_RANDOM
- ret = lo + random() % ((hi - lo) + 1);
-#else
- ret = lo + rand() % ((hi - lo) + 1);
-#endif
- res = Tcl_NewIntObj(ret);
- break;
- case RSRAND:
- /*
- * Must be 1 arg. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "seed");
- return (TCL_ERROR);
- }
- if ((result =
- Tcl_GetIntFromObj(interp, objv[2], &lo)) == TCL_OK) {
-#ifdef HAVE_RANDOM
- srandom((u_int)lo);
-#else
- srand((u_int)lo);
-#endif
- res = Tcl_NewIntObj(0);
- }
- break;
- }
-
- /*
- * Only set result if we have a res. Otherwise, lower functions have
- * already done so.
- */
- if (result == TCL_OK && res)
- Tcl_SetObjResult(interp, res);
- return (result);
-}