1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-26 01:44:06 +03:00
Files
mariadb/storage/bdb/tcl/tcl_db_pkg.c
unknown 47d10d0eca Import BDB 4.3.28
storage/bdb/LICENSE:
  Import db-4.3.28
storage/bdb/btree/bt_compare.c:
  Import db-4.3.28
storage/bdb/btree/bt_conv.c:
  Import db-4.3.28
storage/bdb/btree/bt_curadj.c:
  Import db-4.3.28
storage/bdb/btree/bt_cursor.c:
  Import db-4.3.28
storage/bdb/btree/bt_delete.c:
  Import db-4.3.28
storage/bdb/btree/bt_method.c:
  Import db-4.3.28
storage/bdb/btree/bt_open.c:
  Import db-4.3.28
storage/bdb/btree/bt_put.c:
  Import db-4.3.28
storage/bdb/btree/bt_rec.c:
  Import db-4.3.28
storage/bdb/btree/bt_reclaim.c:
  Import db-4.3.28
storage/bdb/btree/bt_recno.c:
  Import db-4.3.28
storage/bdb/btree/bt_rsearch.c:
  Import db-4.3.28
storage/bdb/btree/bt_search.c:
  Import db-4.3.28
storage/bdb/btree/bt_split.c:
  Import db-4.3.28
storage/bdb/btree/bt_stat.c:
  Import db-4.3.28
storage/bdb/btree/bt_upgrade.c:
  Import db-4.3.28
storage/bdb/btree/bt_verify.c:
  Import db-4.3.28
storage/bdb/btree/btree.src:
  Import db-4.3.28
storage/bdb/build_win32/Berkeley_DB.dsw:
  Import db-4.3.28
storage/bdb/build_win32/app_dsp.src:
  Import db-4.3.28
storage/bdb/build_win32/db_test.src:
  Import db-4.3.28
storage/bdb/build_win32/dbkill.cpp:
  Import db-4.3.28
storage/bdb/build_win32/dynamic_dsp.src:
  Import db-4.3.28
storage/bdb/build_win32/java_dsp.src:
  Import db-4.3.28
storage/bdb/build_win32/libdb_tcl.def:
  Import db-4.3.28
storage/bdb/build_win32/libdbrc.src:
  Import db-4.3.28
storage/bdb/build_win32/static_dsp.src:
  Import db-4.3.28
storage/bdb/build_win32/tcl_dsp.src:
  Import db-4.3.28
storage/bdb/clib/getcwd.c:
  Import db-4.3.28
storage/bdb/clib/getopt.c:
  Import db-4.3.28
storage/bdb/clib/memcmp.c:
  Import db-4.3.28
storage/bdb/clib/memmove.c:
  Import db-4.3.28
storage/bdb/clib/raise.c:
  Import db-4.3.28
storage/bdb/clib/snprintf.c:
  Import db-4.3.28
storage/bdb/clib/strcasecmp.c:
  Import db-4.3.28
storage/bdb/clib/strdup.c:
  Import db-4.3.28
storage/bdb/clib/strerror.c:
  Import db-4.3.28
storage/bdb/common/db_byteorder.c:
  Import db-4.3.28
storage/bdb/common/db_err.c:
  Import db-4.3.28
storage/bdb/common/db_getlong.c:
  Import db-4.3.28
storage/bdb/common/db_idspace.c:
  Import db-4.3.28
storage/bdb/common/db_log2.c:
  Import db-4.3.28
storage/bdb/common/util_arg.c:
  Import db-4.3.28
storage/bdb/common/util_cache.c:
  Import db-4.3.28
storage/bdb/common/util_log.c:
  Import db-4.3.28
storage/bdb/common/util_sig.c:
  Import db-4.3.28
storage/bdb/cxx/cxx_db.cpp:
  Import db-4.3.28
storage/bdb/cxx/cxx_dbc.cpp:
  Import db-4.3.28
storage/bdb/cxx/cxx_dbt.cpp:
  Import db-4.3.28
storage/bdb/cxx/cxx_env.cpp:
  Import db-4.3.28
storage/bdb/cxx/cxx_except.cpp:
  Import db-4.3.28
storage/bdb/cxx/cxx_lock.cpp:
  Import db-4.3.28
storage/bdb/cxx/cxx_logc.cpp:
  Import db-4.3.28
storage/bdb/cxx/cxx_mpool.cpp:
  Import db-4.3.28
storage/bdb/cxx/cxx_txn.cpp:
  Import db-4.3.28
storage/bdb/db/crdel.src:
  Import db-4.3.28
storage/bdb/db/crdel_rec.c:
  Import db-4.3.28
storage/bdb/db/db.c:
  Import db-4.3.28
storage/bdb/db/db.src:
  Import db-4.3.28
storage/bdb/db/db_am.c:
  Import db-4.3.28
storage/bdb/db/db_cam.c:
  Import db-4.3.28
storage/bdb/db/db_conv.c:
  Import db-4.3.28
storage/bdb/db/db_dispatch.c:
  Import db-4.3.28
storage/bdb/db/db_dup.c:
  Import db-4.3.28
storage/bdb/db/db_iface.c:
  Import db-4.3.28
storage/bdb/db/db_join.c:
  Import db-4.3.28
storage/bdb/db/db_meta.c:
  Import db-4.3.28
storage/bdb/db/db_method.c:
  Import db-4.3.28
storage/bdb/db/db_open.c:
  Import db-4.3.28
storage/bdb/db/db_overflow.c:
  Import db-4.3.28
storage/bdb/db/db_pr.c:
  Import db-4.3.28
storage/bdb/db/db_rec.c:
  Import db-4.3.28
storage/bdb/db/db_reclaim.c:
  Import db-4.3.28
storage/bdb/db/db_remove.c:
  Import db-4.3.28
storage/bdb/db/db_rename.c:
  Import db-4.3.28
storage/bdb/db/db_ret.c:
  Import db-4.3.28
storage/bdb/db/db_truncate.c:
  Import db-4.3.28
storage/bdb/db/db_upg.c:
  Import db-4.3.28
storage/bdb/db/db_upg_opd.c:
  Import db-4.3.28
storage/bdb/db/db_vrfy.c:
  Import db-4.3.28
storage/bdb/db/db_vrfyutil.c:
  Import db-4.3.28
storage/bdb/db185/db185.c:
  Import db-4.3.28
storage/bdb/db185/db185_int.in:
  Import db-4.3.28
storage/bdb/db_archive/db_archive.c:
  Import db-4.3.28
storage/bdb/db_checkpoint/db_checkpoint.c:
  Import db-4.3.28
storage/bdb/db_deadlock/db_deadlock.c:
  Import db-4.3.28
storage/bdb/db_dump/db_dump.c:
  Import db-4.3.28
storage/bdb/db_dump185/db_dump185.c:
  Import db-4.3.28
storage/bdb/db_load/db_load.c:
  Import db-4.3.28
storage/bdb/db_printlog/README:
  Import db-4.3.28
storage/bdb/db_printlog/db_printlog.c:
  Import db-4.3.28
storage/bdb/db_printlog/dbname.awk:
  Import db-4.3.28
storage/bdb/db_printlog/rectype.awk:
  Import db-4.3.28
storage/bdb/db_printlog/status.awk:
  Import db-4.3.28
storage/bdb/db_recover/db_recover.c:
  Import db-4.3.28
storage/bdb/db_stat/db_stat.c:
  Import db-4.3.28
storage/bdb/db_upgrade/db_upgrade.c:
  Import db-4.3.28
storage/bdb/db_verify/db_verify.c:
  Import db-4.3.28
storage/bdb/dbinc/btree.h:
  Import db-4.3.28
storage/bdb/dbinc/crypto.h:
  Import db-4.3.28
storage/bdb/dbinc/cxx_int.h:
  Import db-4.3.28
storage/bdb/dbinc/db.in:
  Import db-4.3.28
storage/bdb/dbinc/db_185.in:
  Import db-4.3.28
storage/bdb/dbinc/db_am.h:
  Import db-4.3.28
storage/bdb/dbinc/db_cxx.in:
  Import db-4.3.28
storage/bdb/dbinc/db_dispatch.h:
  Import db-4.3.28
storage/bdb/dbinc/db_int.in:
  Import db-4.3.28
storage/bdb/dbinc/db_join.h:
  Import db-4.3.28
storage/bdb/dbinc/db_page.h:
  Import db-4.3.28
storage/bdb/dbinc/db_server_int.h:
  Import db-4.3.28
storage/bdb/dbinc/db_shash.h:
  Import db-4.3.28
storage/bdb/dbinc/db_swap.h:
  Import db-4.3.28
storage/bdb/dbinc/db_upgrade.h:
  Import db-4.3.28
storage/bdb/dbinc/db_verify.h:
  Import db-4.3.28
storage/bdb/dbinc/debug.h:
  Import db-4.3.28
storage/bdb/dbinc/fop.h:
  Import db-4.3.28
storage/bdb/dbinc/globals.h:
  Import db-4.3.28
storage/bdb/dbinc/hash.h:
  Import db-4.3.28
storage/bdb/dbinc/hmac.h:
  Import db-4.3.28
storage/bdb/dbinc/lock.h:
  Import db-4.3.28
storage/bdb/dbinc/log.h:
  Import db-4.3.28
storage/bdb/dbinc/mp.h:
  Import db-4.3.28
storage/bdb/dbinc/mutex.h:
  Import db-4.3.28
storage/bdb/dbinc/os.h:
  Import db-4.3.28
storage/bdb/dbinc/qam.h:
  Import db-4.3.28
storage/bdb/dbinc/queue.h:
  Import db-4.3.28
storage/bdb/dbinc/region.h:
  Import db-4.3.28
storage/bdb/dbinc/rep.h:
  Import db-4.3.28
storage/bdb/dbinc/shqueue.h:
  Import db-4.3.28
storage/bdb/dbinc/tcl_db.h:
  Import db-4.3.28
storage/bdb/dbinc/txn.h:
  Import db-4.3.28
storage/bdb/dbinc/xa.h:
  Import db-4.3.28
storage/bdb/dbm/dbm.c:
  Import db-4.3.28
storage/bdb/dbreg/dbreg.c:
  Import db-4.3.28
storage/bdb/dbreg/dbreg.src:
  Import db-4.3.28
storage/bdb/dbreg/dbreg_rec.c:
  Import db-4.3.28
storage/bdb/dbreg/dbreg_util.c:
  Import db-4.3.28
storage/bdb/dist/Makefile.in:
  Import db-4.3.28
storage/bdb/dist/RELEASE:
  Import db-4.3.28
storage/bdb/dist/aclocal/config.ac:
  Import db-4.3.28
storage/bdb/dist/aclocal/libtool.ac:
  Import db-4.3.28
storage/bdb/dist/aclocal/mutex.ac:
  Import db-4.3.28
storage/bdb/dist/aclocal/options.ac:
  Import db-4.3.28
storage/bdb/dist/aclocal/programs.ac:
  Import db-4.3.28
storage/bdb/dist/aclocal/sosuffix.ac:
  Import db-4.3.28
storage/bdb/dist/aclocal/tcl.ac:
  Import db-4.3.28
storage/bdb/dist/aclocal/types.ac:
  Import db-4.3.28
storage/bdb/dist/aclocal_java/ac_jni_include_dirs.ac:
  Import db-4.3.28
storage/bdb/dist/aclocal_java/ac_prog_java.ac:
  Import db-4.3.28
storage/bdb/dist/buildrel:
  Import db-4.3.28
storage/bdb/dist/configure.ac:
  Import db-4.3.28
storage/bdb/dist/gen_inc.awk:
  Import db-4.3.28
storage/bdb/dist/gen_rec.awk:
  Import db-4.3.28
storage/bdb/dist/gen_rpc.awk:
  Import db-4.3.28
storage/bdb/dist/ltmain.sh:
  Import db-4.3.28
storage/bdb/dist/pubdef.in:
  Import db-4.3.28
storage/bdb/dist/srcfiles.in:
  Import db-4.3.28
storage/bdb/dist/vx_2.0/BerkeleyDB.wpj:
  Import db-4.3.28
storage/bdb/dist/vx_2.0/wpj.in:
  Import db-4.3.28
storage/bdb/dist/vx_config.in:
  Import db-4.3.28
storage/bdb/dist/vx_setup/CONFIG.in:
  Import db-4.3.28
storage/bdb/dist/vx_setup/LICENSE.TXT:
  Import db-4.3.28
storage/bdb/dist/vx_setup/vx_allfile.in:
  Import db-4.3.28
storage/bdb/dist/vx_setup/vx_demofile.in:
  Import db-4.3.28
storage/bdb/dist/win_config.in:
  Import db-4.3.28
storage/bdb/dist/win_exports.in:
  Import db-4.3.28
storage/bdb/env/db_salloc.c:
  Import db-4.3.28
storage/bdb/env/db_shash.c:
  Import db-4.3.28
storage/bdb/env/env_file.c:
  Import db-4.3.28
storage/bdb/env/env_method.c:
  Import db-4.3.28
storage/bdb/env/env_open.c:
  Import db-4.3.28
storage/bdb/env/env_recover.c:
  Import db-4.3.28
storage/bdb/env/env_region.c:
  Import db-4.3.28
storage/bdb/fileops/fileops.src:
  Import db-4.3.28
storage/bdb/fileops/fop_basic.c:
  Import db-4.3.28
storage/bdb/fileops/fop_rec.c:
  Import db-4.3.28
storage/bdb/fileops/fop_util.c:
  Import db-4.3.28
storage/bdb/hash/hash.c:
  Import db-4.3.28
storage/bdb/hash/hash.src:
  Import db-4.3.28
storage/bdb/hash/hash_conv.c:
  Import db-4.3.28
storage/bdb/hash/hash_dup.c:
  Import db-4.3.28
storage/bdb/hash/hash_func.c:
  Import db-4.3.28
storage/bdb/hash/hash_meta.c:
  Import db-4.3.28
storage/bdb/hash/hash_method.c:
  Import db-4.3.28
storage/bdb/hash/hash_open.c:
  Import db-4.3.28
storage/bdb/hash/hash_page.c:
  Import db-4.3.28
storage/bdb/hash/hash_rec.c:
  Import db-4.3.28
storage/bdb/hash/hash_reclaim.c:
  Import db-4.3.28
storage/bdb/hash/hash_stat.c:
  Import db-4.3.28
storage/bdb/hash/hash_upgrade.c:
  Import db-4.3.28
storage/bdb/hash/hash_verify.c:
  Import db-4.3.28
storage/bdb/hmac/hmac.c:
  Import db-4.3.28
storage/bdb/hmac/sha1.c:
  Import db-4.3.28
storage/bdb/hsearch/hsearch.c:
  Import db-4.3.28
storage/bdb/lock/lock.c:
  Import db-4.3.28
storage/bdb/lock/lock_deadlock.c:
  Import db-4.3.28
storage/bdb/lock/lock_method.c:
  Import db-4.3.28
storage/bdb/lock/lock_region.c:
  Import db-4.3.28
storage/bdb/lock/lock_stat.c:
  Import db-4.3.28
storage/bdb/lock/lock_util.c:
  Import db-4.3.28
storage/bdb/log/log.c:
  Import db-4.3.28
storage/bdb/log/log_archive.c:
  Import db-4.3.28
storage/bdb/log/log_compare.c:
  Import db-4.3.28
storage/bdb/log/log_get.c:
  Import db-4.3.28
storage/bdb/log/log_method.c:
  Import db-4.3.28
storage/bdb/log/log_put.c:
  Import db-4.3.28
storage/bdb/mp/mp_alloc.c:
  Import db-4.3.28
storage/bdb/mp/mp_bh.c:
  Import db-4.3.28
storage/bdb/mp/mp_fget.c:
  Import db-4.3.28
storage/bdb/mp/mp_fopen.c:
  Import db-4.3.28
storage/bdb/mp/mp_fput.c:
  Import db-4.3.28
storage/bdb/mp/mp_fset.c:
  Import db-4.3.28
storage/bdb/mp/mp_method.c:
  Import db-4.3.28
storage/bdb/mp/mp_region.c:
  Import db-4.3.28
storage/bdb/mp/mp_register.c:
  Import db-4.3.28
storage/bdb/mp/mp_stat.c:
  Import db-4.3.28
storage/bdb/mp/mp_sync.c:
  Import db-4.3.28
storage/bdb/mp/mp_trickle.c:
  Import db-4.3.28
storage/bdb/mutex/mut_fcntl.c:
  Import db-4.3.28
storage/bdb/mutex/mut_pthread.c:
  Import db-4.3.28
storage/bdb/mutex/mut_tas.c:
  Import db-4.3.28
storage/bdb/mutex/mut_win32.c:
  Import db-4.3.28
storage/bdb/mutex/mutex.c:
  Import db-4.3.28
storage/bdb/mutex/tm.c:
  Import db-4.3.28
storage/bdb/mutex/uts4_cc.s:
  Import db-4.3.28
storage/bdb/os/os_abs.c:
  Import db-4.3.28
storage/bdb/os/os_alloc.c:
  Import db-4.3.28
storage/bdb/os/os_clock.c:
  Import db-4.3.28
storage/bdb/os/os_config.c:
  Import db-4.3.28
storage/bdb/os/os_dir.c:
  Import db-4.3.28
storage/bdb/os/os_errno.c:
  Import db-4.3.28
storage/bdb/os/os_fid.c:
  Import db-4.3.28
storage/bdb/os/os_fsync.c:
  Import db-4.3.28
storage/bdb/os/os_handle.c:
  Import db-4.3.28
storage/bdb/os/os_id.c:
  Import db-4.3.28
storage/bdb/os/os_map.c:
  Import db-4.3.28
storage/bdb/os/os_method.c:
  Import db-4.3.28
storage/bdb/os/os_oflags.c:
  Import db-4.3.28
storage/bdb/os/os_open.c:
  Import db-4.3.28
storage/bdb/os/os_region.c:
  Import db-4.3.28
storage/bdb/os/os_rename.c:
  Import db-4.3.28
storage/bdb/os/os_root.c:
  Import db-4.3.28
storage/bdb/os/os_rpath.c:
  Import db-4.3.28
storage/bdb/os/os_rw.c:
  Import db-4.3.28
storage/bdb/os/os_seek.c:
  Import db-4.3.28
storage/bdb/os/os_sleep.c:
  Import db-4.3.28
storage/bdb/os/os_spin.c:
  Import db-4.3.28
storage/bdb/os/os_stat.c:
  Import db-4.3.28
storage/bdb/os/os_tmpdir.c:
  Import db-4.3.28
storage/bdb/os/os_unlink.c:
  Import db-4.3.28
storage/bdb/os_vxworks/os_vx_abs.c:
  Import db-4.3.28
storage/bdb/os_vxworks/os_vx_config.c:
  Import db-4.3.28
storage/bdb/os_vxworks/os_vx_map.c:
  Import db-4.3.28
storage/bdb/os_win32/os_abs.c:
  Import db-4.3.28
storage/bdb/os_win32/os_clock.c:
  Import db-4.3.28
storage/bdb/os_win32/os_config.c:
  Import db-4.3.28
storage/bdb/os_win32/os_dir.c:
  Import db-4.3.28
storage/bdb/os_win32/os_errno.c:
  Import db-4.3.28
storage/bdb/os_win32/os_fid.c:
  Import db-4.3.28
storage/bdb/os_win32/os_fsync.c:
  Import db-4.3.28
storage/bdb/os_win32/os_handle.c:
  Import db-4.3.28
storage/bdb/os_win32/os_map.c:
  Import db-4.3.28
storage/bdb/os_win32/os_open.c:
  Import db-4.3.28
storage/bdb/os_win32/os_rename.c:
  Import db-4.3.28
storage/bdb/os_win32/os_rw.c:
  Import db-4.3.28
storage/bdb/os_win32/os_seek.c:
  Import db-4.3.28
storage/bdb/os_win32/os_sleep.c:
  Import db-4.3.28
storage/bdb/os_win32/os_spin.c:
  Import db-4.3.28
storage/bdb/os_win32/os_stat.c:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/BerkeleyDB.pm:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/BerkeleyDB.pod.P:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/BerkeleyDB.pod:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/BerkeleyDB.xs:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/Changes:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/MANIFEST:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/Makefile.PL:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/README:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/config.in:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/constants.h:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/mkconsts:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/patches/5.004:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/ppport.h:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/scan:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/btree.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/destroy.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/env.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/filter.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/hash.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/join.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/mldbm.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/queue.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/recno.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/strict.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/subdb.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/txn.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/util.pm:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/typemap:
  Import db-4.3.28
storage/bdb/perl/DB_File/Changes:
  Import db-4.3.28
storage/bdb/perl/DB_File/DB_File.pm:
  Import db-4.3.28
storage/bdb/perl/DB_File/DB_File.xs:
  Import db-4.3.28
storage/bdb/perl/DB_File/MANIFEST:
  Import db-4.3.28
storage/bdb/perl/DB_File/Makefile.PL:
  Import db-4.3.28
storage/bdb/perl/DB_File/README:
  Import db-4.3.28
storage/bdb/perl/DB_File/dbinfo:
  Import db-4.3.28
storage/bdb/perl/DB_File/patches/5.004:
  Import db-4.3.28
storage/bdb/perl/DB_File/ppport.h:
  Import db-4.3.28
storage/bdb/perl/DB_File/t/db-btree.t:
  Import db-4.3.28
storage/bdb/perl/DB_File/t/db-hash.t:
  Import db-4.3.28
storage/bdb/perl/DB_File/t/db-recno.t:
  Import db-4.3.28
storage/bdb/perl/DB_File/typemap:
  Import db-4.3.28
storage/bdb/qam/qam.c:
  Import db-4.3.28
storage/bdb/qam/qam.src:
  Import db-4.3.28
storage/bdb/qam/qam_conv.c:
  Import db-4.3.28
storage/bdb/qam/qam_files.c:
  Import db-4.3.28
storage/bdb/qam/qam_method.c:
  Import db-4.3.28
storage/bdb/qam/qam_open.c:
  Import db-4.3.28
storage/bdb/qam/qam_rec.c:
  Import db-4.3.28
storage/bdb/qam/qam_stat.c:
  Import db-4.3.28
storage/bdb/qam/qam_upgrade.c:
  Import db-4.3.28
storage/bdb/qam/qam_verify.c:
  Import db-4.3.28
storage/bdb/rep/rep_method.c:
  Import db-4.3.28
storage/bdb/rep/rep_record.c:
  Import db-4.3.28
storage/bdb/rep/rep_region.c:
  Import db-4.3.28
storage/bdb/rep/rep_util.c:
  Import db-4.3.28
storage/bdb/rpc_client/client.c:
  Import db-4.3.28
storage/bdb/rpc_client/gen_client_ret.c:
  Import db-4.3.28
storage/bdb/rpc_server/c/db_server_util.c:
  Import db-4.3.28
storage/bdb/rpc_server/cxx/db_server_cxxproc.cpp:
  Import db-4.3.28
storage/bdb/rpc_server/cxx/db_server_cxxutil.cpp:
  Import db-4.3.28
storage/bdb/rpc_server/java/FreeList.java:
  Import db-4.3.28
storage/bdb/rpc_server/java/LocalIterator.java:
  Import db-4.3.28
storage/bdb/rpc_server/java/README:
  Import db-4.3.28
storage/bdb/rpc_server/java/RpcDb.java:
  Import db-4.3.28
storage/bdb/rpc_server/java/RpcDbEnv.java:
  Import db-4.3.28
storage/bdb/rpc_server/java/RpcDbTxn.java:
  Import db-4.3.28
storage/bdb/rpc_server/java/RpcDbc.java:
  Import db-4.3.28
storage/bdb/rpc_server/java/Timer.java:
  Import db-4.3.28
storage/bdb/rpc_server/java/gen/__db_open_reply.java:
  Import db-4.3.28
storage/bdb/rpc_server/java/gen/__db_stat_msg.java:
  Import db-4.3.28
storage/bdb/rpc_server/java/gen/db_server.java:
  Import db-4.3.28
storage/bdb/rpc_server/java/s_jrpcgen:
  Import db-4.3.28
storage/bdb/rpc_server/rpc.src:
  Import db-4.3.28
storage/bdb/tcl/docs/db.html:
  Import db-4.3.28
storage/bdb/tcl/docs/env.html:
  Import db-4.3.28
storage/bdb/tcl/docs/historic.html:
  Import db-4.3.28
storage/bdb/tcl/docs/index.html:
  Import db-4.3.28
storage/bdb/tcl/docs/library.html:
  Import db-4.3.28
storage/bdb/tcl/docs/lock.html:
  Import db-4.3.28
storage/bdb/tcl/docs/log.html:
  Import db-4.3.28
storage/bdb/tcl/docs/mpool.html:
  Import db-4.3.28
storage/bdb/tcl/docs/rep.html:
  Import db-4.3.28
storage/bdb/tcl/docs/test.html:
  Import db-4.3.28
storage/bdb/tcl/docs/txn.html:
  Import db-4.3.28
storage/bdb/tcl/tcl_compat.c:
  Import db-4.3.28
storage/bdb/tcl/tcl_db.c:
  Import db-4.3.28
storage/bdb/tcl/tcl_db_pkg.c:
  Import db-4.3.28
storage/bdb/tcl/tcl_dbcursor.c:
  Import db-4.3.28
storage/bdb/tcl/tcl_env.c:
  Import db-4.3.28
storage/bdb/tcl/tcl_internal.c:
  Import db-4.3.28
storage/bdb/tcl/tcl_lock.c:
  Import db-4.3.28
storage/bdb/tcl/tcl_log.c:
  Import db-4.3.28
storage/bdb/tcl/tcl_mp.c:
  Import db-4.3.28
storage/bdb/tcl/tcl_rep.c:
  Import db-4.3.28
storage/bdb/tcl/tcl_txn.c:
  Import db-4.3.28
storage/bdb/tcl/tcl_util.c:
  Import db-4.3.28
storage/bdb/test/archive.tcl:
  Import db-4.3.28
storage/bdb/test/bigfile001.tcl:
  Import db-4.3.28
storage/bdb/test/bigfile002.tcl:
  Import db-4.3.28
storage/bdb/test/byteorder.tcl:
  Import db-4.3.28
storage/bdb/test/conscript.tcl:
  Import db-4.3.28
storage/bdb/test/dbm.tcl:
  Import db-4.3.28
storage/bdb/test/dbscript.tcl:
  Import db-4.3.28
storage/bdb/test/ddoyscript.tcl:
  Import db-4.3.28
storage/bdb/test/ddscript.tcl:
  Import db-4.3.28
storage/bdb/test/dead001.tcl:
  Import db-4.3.28
storage/bdb/test/dead002.tcl:
  Import db-4.3.28
storage/bdb/test/dead003.tcl:
  Import db-4.3.28
storage/bdb/test/dead004.tcl:
  Import db-4.3.28
storage/bdb/test/dead005.tcl:
  Import db-4.3.28
storage/bdb/test/dead006.tcl:
  Import db-4.3.28
storage/bdb/test/dead007.tcl:
  Import db-4.3.28
storage/bdb/test/env001.tcl:
  Import db-4.3.28
storage/bdb/test/env002.tcl:
  Import db-4.3.28
storage/bdb/test/env003.tcl:
  Import db-4.3.28
storage/bdb/test/env004.tcl:
  Import db-4.3.28
storage/bdb/test/env005.tcl:
  Import db-4.3.28
storage/bdb/test/env006.tcl:
  Import db-4.3.28
storage/bdb/test/env007.tcl:
  Import db-4.3.28
storage/bdb/test/env008.tcl:
  Import db-4.3.28
storage/bdb/test/env009.tcl:
  Import db-4.3.28
storage/bdb/test/env010.tcl:
  Import db-4.3.28
storage/bdb/test/env011.tcl:
  Import db-4.3.28
storage/bdb/test/hsearch.tcl:
  Import db-4.3.28
storage/bdb/test/join.tcl:
  Import db-4.3.28
storage/bdb/test/lock001.tcl:
  Import db-4.3.28
storage/bdb/test/lock002.tcl:
  Import db-4.3.28
storage/bdb/test/lock003.tcl:
  Import db-4.3.28
storage/bdb/test/lock004.tcl:
  Import db-4.3.28
storage/bdb/test/lock005.tcl:
  Import db-4.3.28
storage/bdb/test/lockscript.tcl:
  Import db-4.3.28
storage/bdb/test/log001.tcl:
  Import db-4.3.28
storage/bdb/test/log002.tcl:
  Import db-4.3.28
storage/bdb/test/log003.tcl:
  Import db-4.3.28
storage/bdb/test/log004.tcl:
  Import db-4.3.28
storage/bdb/test/log005.tcl:
  Import db-4.3.28
storage/bdb/test/logtrack.tcl:
  Import db-4.3.28
storage/bdb/test/mdbscript.tcl:
  Import db-4.3.28
storage/bdb/test/memp001.tcl:
  Import db-4.3.28
storage/bdb/test/memp002.tcl:
  Import db-4.3.28
storage/bdb/test/memp003.tcl:
  Import db-4.3.28
storage/bdb/test/mpoolscript.tcl:
  Import db-4.3.28
storage/bdb/test/mutex001.tcl:
  Import db-4.3.28
storage/bdb/test/mutex002.tcl:
  Import db-4.3.28
storage/bdb/test/mutex003.tcl:
  Import db-4.3.28
storage/bdb/test/mutexscript.tcl:
  Import db-4.3.28
storage/bdb/test/ndbm.tcl:
  Import db-4.3.28
storage/bdb/test/parallel.tcl:
  Import db-4.3.28
storage/bdb/test/recd001.tcl:
  Import db-4.3.28
storage/bdb/test/recd002.tcl:
  Import db-4.3.28
storage/bdb/test/recd003.tcl:
  Import db-4.3.28
storage/bdb/test/recd004.tcl:
  Import db-4.3.28
storage/bdb/test/recd005.tcl:
  Import db-4.3.28
storage/bdb/test/recd006.tcl:
  Import db-4.3.28
storage/bdb/test/recd007.tcl:
  Import db-4.3.28
storage/bdb/test/recd008.tcl:
  Import db-4.3.28
storage/bdb/test/recd009.tcl:
  Import db-4.3.28
storage/bdb/test/recd010.tcl:
  Import db-4.3.28
storage/bdb/test/recd011.tcl:
  Import db-4.3.28
storage/bdb/test/recd012.tcl:
  Import db-4.3.28
storage/bdb/test/recd013.tcl:
  Import db-4.3.28
storage/bdb/test/recd014.tcl:
  Import db-4.3.28
storage/bdb/test/recd015.tcl:
  Import db-4.3.28
storage/bdb/test/recd016.tcl:
  Import db-4.3.28
storage/bdb/test/recd017.tcl:
  Import db-4.3.28
storage/bdb/test/recd018.tcl:
  Import db-4.3.28
storage/bdb/test/recd019.tcl:
  Import db-4.3.28
storage/bdb/test/recd020.tcl:
  Import db-4.3.28
storage/bdb/test/recd15scr.tcl:
  Import db-4.3.28
storage/bdb/test/recdscript.tcl:
  Import db-4.3.28
storage/bdb/test/rep001.tcl:
  Import db-4.3.28
storage/bdb/test/rep002.tcl:
  Import db-4.3.28
storage/bdb/test/rep003.tcl:
  Import db-4.3.28
storage/bdb/test/rep005.tcl:
  Import db-4.3.28
storage/bdb/test/reputils.tcl:
  Import db-4.3.28
storage/bdb/test/rpc001.tcl:
  Import db-4.3.28
storage/bdb/test/rpc002.tcl:
  Import db-4.3.28
storage/bdb/test/rpc003.tcl:
  Import db-4.3.28
storage/bdb/test/rpc004.tcl:
  Import db-4.3.28
storage/bdb/test/rpc005.tcl:
  Import db-4.3.28
storage/bdb/test/rsrc001.tcl:
  Import db-4.3.28
storage/bdb/test/rsrc002.tcl:
  Import db-4.3.28
storage/bdb/test/rsrc003.tcl:
  Import db-4.3.28
storage/bdb/test/rsrc004.tcl:
  Import db-4.3.28
storage/bdb/test/scr001/chk.code:
  Import db-4.3.28
storage/bdb/test/scr003/chk.define:
  Import db-4.3.28
storage/bdb/test/scr004/chk.javafiles:
  Import db-4.3.28
storage/bdb/test/scr005/chk.nl:
  Import db-4.3.28
storage/bdb/test/scr006/chk.offt:
  Import db-4.3.28
storage/bdb/test/scr007/chk.proto:
  Import db-4.3.28
storage/bdb/test/scr008/chk.pubdef:
  Import db-4.3.28
storage/bdb/test/scr009/chk.srcfiles:
  Import db-4.3.28
storage/bdb/test/scr010/chk.str:
  Import db-4.3.28
storage/bdb/test/scr010/spell.ok:
  Import db-4.3.28
storage/bdb/test/scr011/chk.tags:
  Import db-4.3.28
storage/bdb/test/scr012/chk.vx_code:
  Import db-4.3.28
storage/bdb/test/scr013/chk.stats:
  Import db-4.3.28
storage/bdb/test/scr015/TestConstruct01.cpp:
  Import db-4.3.28
storage/bdb/test/scr015/TestConstruct01.testerr:
  Import db-4.3.28
storage/bdb/test/scr015/TestGetSetMethods.cpp:
  Import db-4.3.28
storage/bdb/test/scr015/TestKeyRange.cpp:
  Import db-4.3.28
storage/bdb/test/scr015/TestLogc.cpp:
  Import db-4.3.28
storage/bdb/test/scr015/TestSimpleAccess.cpp:
  Import db-4.3.28
storage/bdb/test/scr015/TestTruncate.cpp:
  Import db-4.3.28
storage/bdb/test/scr015/chk.cxxtests:
  Import db-4.3.28
storage/bdb/test/scr016/CallbackTest.java:
  Import db-4.3.28
storage/bdb/test/scr016/CallbackTest.testout:
  Import db-4.3.28
storage/bdb/test/scr016/TestAppendRecno.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestAssociate.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestClosedDb.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestClosedDb.testout:
  Import db-4.3.28
storage/bdb/test/scr016/TestConstruct01.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestConstruct01.testout:
  Import db-4.3.28
storage/bdb/test/scr016/TestConstruct02.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestDbtFlags.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestGetSetMethods.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestKeyRange.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestLockVec.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestLogc.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestOpenEmpty.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestOpenEmpty.testerr:
  Import db-4.3.28
storage/bdb/test/scr016/TestReplication.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestRpcServer.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestSameDbt.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestSimpleAccess.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestStat.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestStat.testout:
  Import db-4.3.28
storage/bdb/test/scr016/TestTruncate.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestTruncate.testout:
  Import db-4.3.28
storage/bdb/test/scr016/TestUtil.java:
  Import db-4.3.28
storage/bdb/test/scr016/TestXAServlet.java:
  Import db-4.3.28
storage/bdb/test/scr016/chk.javatests:
  Import db-4.3.28
storage/bdb/test/scr016/ignore:
  Import db-4.3.28
storage/bdb/test/scr016/testone:
  Import db-4.3.28
storage/bdb/test/scr017/chk.db185:
  Import db-4.3.28
storage/bdb/test/scr019/chk.include:
  Import db-4.3.28
storage/bdb/test/scr020/chk.inc:
  Import db-4.3.28
storage/bdb/test/scr021/chk.flags:
  Import db-4.3.28
storage/bdb/test/scr022/chk.rr:
  Import db-4.3.28
storage/bdb/test/sdb001.tcl:
  Import db-4.3.28
storage/bdb/test/sdb002.tcl:
  Import db-4.3.28
storage/bdb/test/sdb003.tcl:
  Import db-4.3.28
storage/bdb/test/sdb004.tcl:
  Import db-4.3.28
storage/bdb/test/sdb005.tcl:
  Import db-4.3.28
storage/bdb/test/sdb006.tcl:
  Import db-4.3.28
storage/bdb/test/sdb007.tcl:
  Import db-4.3.28
storage/bdb/test/sdb008.tcl:
  Import db-4.3.28
storage/bdb/test/sdb009.tcl:
  Import db-4.3.28
storage/bdb/test/sdb010.tcl:
  Import db-4.3.28
storage/bdb/test/sdb011.tcl:
  Import db-4.3.28
storage/bdb/test/sdb012.tcl:
  Import db-4.3.28
storage/bdb/test/sdbscript.tcl:
  Import db-4.3.28
storage/bdb/test/sdbtest001.tcl:
  Import db-4.3.28
storage/bdb/test/sdbtest002.tcl:
  Import db-4.3.28
storage/bdb/test/sdbutils.tcl:
  Import db-4.3.28
storage/bdb/test/sec001.tcl:
  Import db-4.3.28
storage/bdb/test/sec002.tcl:
  Import db-4.3.28
storage/bdb/test/shelltest.tcl:
  Import db-4.3.28
storage/bdb/test/si001.tcl:
  Import db-4.3.28
storage/bdb/test/si002.tcl:
  Import db-4.3.28
storage/bdb/test/si003.tcl:
  Import db-4.3.28
storage/bdb/test/si004.tcl:
  Import db-4.3.28
storage/bdb/test/si005.tcl:
  Import db-4.3.28
storage/bdb/test/sysscript.tcl:
  Import db-4.3.28
storage/bdb/test/test.tcl:
  Import db-4.3.28
storage/bdb/test/test001.tcl:
  Import db-4.3.28
storage/bdb/test/test002.tcl:
  Import db-4.3.28
storage/bdb/test/test003.tcl:
  Import db-4.3.28
storage/bdb/test/test004.tcl:
  Import db-4.3.28
storage/bdb/test/test005.tcl:
  Import db-4.3.28
storage/bdb/test/test006.tcl:
  Import db-4.3.28
storage/bdb/test/test007.tcl:
  Import db-4.3.28
storage/bdb/test/test008.tcl:
  Import db-4.3.28
storage/bdb/test/test009.tcl:
  Import db-4.3.28
storage/bdb/test/test010.tcl:
  Import db-4.3.28
storage/bdb/test/test011.tcl:
  Import db-4.3.28
storage/bdb/test/test012.tcl:
  Import db-4.3.28
storage/bdb/test/test013.tcl:
  Import db-4.3.28
storage/bdb/test/test014.tcl:
  Import db-4.3.28
storage/bdb/test/test015.tcl:
  Import db-4.3.28
storage/bdb/test/test016.tcl:
  Import db-4.3.28
storage/bdb/test/test017.tcl:
  Import db-4.3.28
storage/bdb/test/test018.tcl:
  Import db-4.3.28
storage/bdb/test/test019.tcl:
  Import db-4.3.28
storage/bdb/test/test020.tcl:
  Import db-4.3.28
storage/bdb/test/test021.tcl:
  Import db-4.3.28
storage/bdb/test/test022.tcl:
  Import db-4.3.28
storage/bdb/test/test023.tcl:
  Import db-4.3.28
storage/bdb/test/test024.tcl:
  Import db-4.3.28
storage/bdb/test/test025.tcl:
  Import db-4.3.28
storage/bdb/test/test026.tcl:
  Import db-4.3.28
storage/bdb/test/test027.tcl:
  Import db-4.3.28
storage/bdb/test/test028.tcl:
  Import db-4.3.28
storage/bdb/test/test029.tcl:
  Import db-4.3.28
storage/bdb/test/test030.tcl:
  Import db-4.3.28
storage/bdb/test/test031.tcl:
  Import db-4.3.28
storage/bdb/test/test032.tcl:
  Import db-4.3.28
storage/bdb/test/test033.tcl:
  Import db-4.3.28
storage/bdb/test/test034.tcl:
  Import db-4.3.28
storage/bdb/test/test035.tcl:
  Import db-4.3.28
storage/bdb/test/test036.tcl:
  Import db-4.3.28
storage/bdb/test/test037.tcl:
  Import db-4.3.28
storage/bdb/test/test038.tcl:
  Import db-4.3.28
storage/bdb/test/test039.tcl:
  Import db-4.3.28
storage/bdb/test/test040.tcl:
  Import db-4.3.28
storage/bdb/test/test041.tcl:
  Import db-4.3.28
storage/bdb/test/test042.tcl:
  Import db-4.3.28
storage/bdb/test/test043.tcl:
  Import db-4.3.28
storage/bdb/test/test044.tcl:
  Import db-4.3.28
storage/bdb/test/test045.tcl:
  Import db-4.3.28
storage/bdb/test/test046.tcl:
  Import db-4.3.28
storage/bdb/test/test047.tcl:
  Import db-4.3.28
storage/bdb/test/test048.tcl:
  Import db-4.3.28
storage/bdb/test/test049.tcl:
  Import db-4.3.28
storage/bdb/test/test050.tcl:
  Import db-4.3.28
storage/bdb/test/test051.tcl:
  Import db-4.3.28
storage/bdb/test/test052.tcl:
  Import db-4.3.28
storage/bdb/test/test053.tcl:
  Import db-4.3.28
storage/bdb/test/test054.tcl:
  Import db-4.3.28
storage/bdb/test/test055.tcl:
  Import db-4.3.28
storage/bdb/test/test056.tcl:
  Import db-4.3.28
storage/bdb/test/test057.tcl:
  Import db-4.3.28
storage/bdb/test/test058.tcl:
  Import db-4.3.28
storage/bdb/test/test059.tcl:
  Import db-4.3.28
storage/bdb/test/test060.tcl:
  Import db-4.3.28
storage/bdb/test/test061.tcl:
  Import db-4.3.28
storage/bdb/test/test062.tcl:
  Import db-4.3.28
storage/bdb/test/test063.tcl:
  Import db-4.3.28
storage/bdb/test/test064.tcl:
  Import db-4.3.28
storage/bdb/test/test065.tcl:
  Import db-4.3.28
storage/bdb/test/test066.tcl:
  Import db-4.3.28
storage/bdb/test/test067.tcl:
  Import db-4.3.28
storage/bdb/test/test068.tcl:
  Import db-4.3.28
storage/bdb/test/test069.tcl:
  Import db-4.3.28
storage/bdb/test/test070.tcl:
  Import db-4.3.28
storage/bdb/test/test071.tcl:
  Import db-4.3.28
storage/bdb/test/test072.tcl:
  Import db-4.3.28
storage/bdb/test/test073.tcl:
  Import db-4.3.28
storage/bdb/test/test074.tcl:
  Import db-4.3.28
storage/bdb/test/test076.tcl:
  Import db-4.3.28
storage/bdb/test/test077.tcl:
  Import db-4.3.28
storage/bdb/test/test078.tcl:
  Import db-4.3.28
storage/bdb/test/test079.tcl:
  Import db-4.3.28
storage/bdb/test/test081.tcl:
  Import db-4.3.28
storage/bdb/test/test082.tcl:
  Import db-4.3.28
storage/bdb/test/test083.tcl:
  Import db-4.3.28
storage/bdb/test/test084.tcl:
  Import db-4.3.28
storage/bdb/test/test085.tcl:
  Import db-4.3.28
storage/bdb/test/test086.tcl:
  Import db-4.3.28
storage/bdb/test/test087.tcl:
  Import db-4.3.28
storage/bdb/test/test088.tcl:
  Import db-4.3.28
storage/bdb/test/test089.tcl:
  Import db-4.3.28
storage/bdb/test/test090.tcl:
  Import db-4.3.28
storage/bdb/test/test091.tcl:
  Import db-4.3.28
storage/bdb/test/test092.tcl:
  Import db-4.3.28
storage/bdb/test/test093.tcl:
  Import db-4.3.28
storage/bdb/test/test094.tcl:
  Import db-4.3.28
storage/bdb/test/test095.tcl:
  Import db-4.3.28
storage/bdb/test/test096.tcl:
  Import db-4.3.28
storage/bdb/test/test097.tcl:
  Import db-4.3.28
storage/bdb/test/test098.tcl:
  Import db-4.3.28
storage/bdb/test/test099.tcl:
  Import db-4.3.28
storage/bdb/test/test100.tcl:
  Import db-4.3.28
storage/bdb/test/test101.tcl:
  Import db-4.3.28
storage/bdb/test/testparams.tcl:
  Import db-4.3.28
storage/bdb/test/testutils.tcl:
  Import db-4.3.28
storage/bdb/test/txn001.tcl:
  Import db-4.3.28
storage/bdb/test/txn002.tcl:
  Import db-4.3.28
storage/bdb/test/txn003.tcl:
  Import db-4.3.28
storage/bdb/test/txn004.tcl:
  Import db-4.3.28
storage/bdb/test/txn005.tcl:
  Import db-4.3.28
storage/bdb/test/txn006.tcl:
  Import db-4.3.28
storage/bdb/test/txn007.tcl:
  Import db-4.3.28
storage/bdb/test/txn008.tcl:
  Import db-4.3.28
storage/bdb/test/txn009.tcl:
  Import db-4.3.28
storage/bdb/test/txnscript.tcl:
  Import db-4.3.28
storage/bdb/test/update.tcl:
  Import db-4.3.28
storage/bdb/test/upgrade.tcl:
  Import db-4.3.28
storage/bdb/test/wrap.tcl:
  Import db-4.3.28
storage/bdb/txn/txn.c:
  Import db-4.3.28
storage/bdb/txn/txn.src:
  Import db-4.3.28
storage/bdb/txn/txn_method.c:
  Import db-4.3.28
storage/bdb/txn/txn_rec.c:
  Import db-4.3.28
storage/bdb/txn/txn_recover.c:
  Import db-4.3.28
storage/bdb/txn/txn_region.c:
  Import db-4.3.28
storage/bdb/txn/txn_stat.c:
  Import db-4.3.28
storage/bdb/txn/txn_util.c:
  Import db-4.3.28
storage/bdb/xa/xa.c:
  Import db-4.3.28
storage/bdb/xa/xa_db.c:
  Import db-4.3.28
storage/bdb/xa/xa_map.c:
  Import db-4.3.28
storage/bdb/clib/strtol.c:
  Import db-4.3.28
storage/bdb/clib/strtoul.c:
  Import db-4.3.28
storage/bdb/common/crypto_stub.c:
  Import db-4.3.28
storage/bdb/crypto/aes_method.c:
  Import db-4.3.28
storage/bdb/crypto/crypto.c:
  Import db-4.3.28
storage/bdb/crypto/crypto.html:
  Import db-4.3.28
storage/bdb/crypto/mersenne/mt19937db.c:
  Import db-4.3.28
storage/bdb/crypto/rijndael/rijndael-alg-fst.c:
  Import db-4.3.28
storage/bdb/crypto/rijndael/rijndael-alg-fst.h:
  Import db-4.3.28
storage/bdb/crypto/rijndael/rijndael-api-fst.c:
  Import db-4.3.28
storage/bdb/crypto/rijndael/rijndael-api-fst.h:
  Import db-4.3.28
storage/bdb/cxx/cxx_multi.cpp:
  Import db-4.3.28
storage/bdb/cxx/cxx_seq.cpp:
  Import db-4.3.28
storage/bdb/db/db_ovfl_vrfy.c:
  Import db-4.3.28
storage/bdb/db/db_setid.c:
  Import db-4.3.28
storage/bdb/db/db_setlsn.c:
  Import db-4.3.28
storage/bdb/db/db_stati.c:
  Import db-4.3.28
storage/bdb/db/db_vrfy_stub.c:
  Import db-4.3.28
storage/bdb/db_stat/dd.sh:
  Import db-4.3.28
storage/bdb/dbreg/dbreg_stat.c:
  Import db-4.3.28
storage/bdb/dist/aclocal/rpc.ac:
  Import db-4.3.28
storage/bdb/dist/aclocal/sequence.ac:
  Import db-4.3.28
storage/bdb/dist/config.hin:
  Import db-4.3.28
storage/bdb/dist/s_java_const:
  Import db-4.3.28
storage/bdb/dist/s_java_stat:
  Import db-4.3.28
storage/bdb/dist/s_java_swig:
  Import db-4.3.28
storage/bdb/dist/s_je2db:
  Import db-4.3.28
storage/bdb/dist/s_winmsi:
  Import db-4.3.28
storage/bdb/dist/template/db_server_proc:
  Import db-4.3.28
storage/bdb/dist/template/gen_client_ret:
  Import db-4.3.28
storage/bdb/dist/template/rec_btree:
  Import db-4.3.28
storage/bdb/dist/template/rec_crdel:
  Import db-4.3.28
storage/bdb/dist/template/rec_dbreg:
  Import db-4.3.28
storage/bdb/dist/template/rec_db:
  Import db-4.3.28
storage/bdb/dist/template/rec_fileops:
  Import db-4.3.28
storage/bdb/dist/template/rec_hash:
  Import db-4.3.28
storage/bdb/dist/template/rec_qam:
  Import db-4.3.28
storage/bdb/dist/template/rec_rep:
  Import db-4.3.28
storage/bdb/dist/template/rec_txn:
  Import db-4.3.28
storage/bdb/dist/vx_2.0/BerkeleyDBsmall.wpj:
  Import db-4.3.28
storage/bdb/dist/vx_2.2/BerkeleyDB.wpj:
  Import db-4.3.28
storage/bdb/dist/vx_2.2/BerkeleyDBsmall.wpj:
  Import db-4.3.28
storage/bdb/dist/vx_2.2/wpj.in:
  Import db-4.3.28
storage/bdb/dist/win_db.in:
  Import db-4.3.28
storage/bdb/dist/winmsi/dbcorewix.in:
  Import db-4.3.28
storage/bdb/dist/winmsi/dbvarsbat.in:
  Import db-4.3.28
storage/bdb/dist/winmsi/dbwix.m4:
  Import db-4.3.28
storage/bdb/dist/winmsi/environment.in:
  Import db-4.3.28
storage/bdb/dist/winmsi/features.in:
  Import db-4.3.28
storage/bdb/dist/winmsi/files.in:
  Import db-4.3.28
storage/bdb/dist/winmsi/images/caticon.ibd:
  Import db-4.3.28
storage/bdb/dist/winmsi/images/foldernew.ibd:
  Import db-4.3.28
storage/bdb/dist/winmsi/images/folderup.ibd:
  Import db-4.3.28
storage/bdb/dist/winmsi/images/sleepycat.jpg:
  Import db-4.3.28
storage/bdb/dist/winmsi/images/topstripe.ibd:
  Import db-4.3.28
storage/bdb/dist/winmsi/images/webicon.ico:
  Import db-4.3.28
storage/bdb/dist/winmsi/links.in:
  Import db-4.3.28
storage/bdb/dist/winmsi/s_winmsi.fcn:
  Import db-4.3.28
storage/bdb/dist/winmsi/winbuild.bat:
  Import db-4.3.28
storage/bdb/env/env_stat.c:
  Import db-4.3.28
storage/bdb/hash/hash_stub.c:
  Import db-4.3.28
storage/bdb/lock/lock_id.c:
  Import db-4.3.28
storage/bdb/lock/lock_list.c:
  Import db-4.3.28
storage/bdb/lock/lock_timer.c:
  Import db-4.3.28
storage/bdb/log/log_stat.c:
  Import db-4.3.28
storage/bdb/mp/mp_fmethod.c:
  Import db-4.3.28
storage/bdb/os/os_truncate.c:
  Import db-4.3.28
storage/bdb/os_win32/os_truncate.c:
  Import db-4.3.28
storage/bdb/os_win32/os_unlink.c:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/META.yml:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/cds.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/encrypt.t:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/t/pod.t:
  Import db-4.3.28
storage/bdb/perl/DB_File/META.yml:
  Import db-4.3.28
storage/bdb/qam/qam_stub.c:
  Import db-4.3.28
storage/bdb/rep/rep.src:
  Import db-4.3.28
storage/bdb/rep/rep_backup.c:
  Import db-4.3.28
storage/bdb/rep/rep_stat.c:
  Import db-4.3.28
storage/bdb/rep/rep_stub.c:
  Import db-4.3.28
storage/bdb/rpc_client/gen_client.c:
  Import db-4.3.28
storage/bdb/rpc_server/c/db_server_proc.c:
  Import db-4.3.28
storage/bdb/rpc_server/c/gen_db_server.c:
  Import db-4.3.28
storage/bdb/rpc_server/db_server.x:
  Import db-4.3.28
storage/bdb/sequence/seq_stat.c:
  Import db-4.3.28
storage/bdb/sequence/sequence.c:
  Import db-4.3.28
storage/bdb/tcl/tcl_seq.c:
  Import db-4.3.28
storage/bdb/dist/config.guess:
  Import db-4.3.28
storage/bdb/dist/config.sub:
  Import db-4.3.28
storage/bdb/dist/s_all:
  Import db-4.3.28
storage/bdb/dist/s_config:
  Import db-4.3.28
storage/bdb/dist/s_crypto:
  Import db-4.3.28
storage/bdb/dist/s_include:
  Import db-4.3.28
storage/bdb/dist/s_java:
  Import db-4.3.28
storage/bdb/dist/s_perm:
  Import db-4.3.28
storage/bdb/dist/s_readme:
  Import db-4.3.28
storage/bdb/dist/s_recover:
  Import db-4.3.28
storage/bdb/dist/s_rpc:
  Import db-4.3.28
storage/bdb/dist/s_symlink:
  Import db-4.3.28
storage/bdb/dist/s_tags:
  Import db-4.3.28
storage/bdb/dist/s_test:
  Import db-4.3.28
storage/bdb/dist/s_vxworks:
  Import db-4.3.28
storage/bdb/dist/s_win32_dsp:
  Import db-4.3.28
storage/bdb/dist/s_win32:
  Import db-4.3.28
storage/bdb/perl/BerkeleyDB/dbinfo:
  Import db-4.3.28
2005-07-20 15:48:22 -07:00

3600 lines
86 KiB
C

/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1999-2004
* Sleepycat Software. All rights reserved.
*
* $Id: tcl_db_pkg.c,v 11.190 2004/10/27 16:48:32 bostic Exp $
*/
#include "db_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <tcl.h>
#endif
#ifdef CONFIG_TEST
#define DB_DBM_HSEARCH 1
#endif
#include "db_int.h"
#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*));
static int bdb_SeqOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
DBTCL_INFO *, DB_SEQUENCE **));
#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*));
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_rep_send __P((DB_ENV *,
const DBT *, const DBT *, const DB_LSN *, int, u_int32_t));
#endif
/*
* 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);
(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",
"handles",
"msgtype",
"upgrade",
#endif
"dbremove",
"dbrename",
"env",
"envremove",
"open",
#ifdef HAVE_SEQUENCE
"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_HANDLES,
BDB_MSGTYPE,
BDB_UPGRADE,
#endif
BDB_DBREMOVE,
BDB_DBRENAME,
BDB_ENV,
BDB_ENVREMOVE,
BDB_OPEN,
#ifdef HAVE_SEQUENCE
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_SEQUENCE
static int seq_id = 0;
#endif
DB *dbp;
#ifdef HAVE_SEQUENCE
DB_SEQUENCE *seq;
#endif
#ifdef CONFIG_TEST
DBM *ndbmp;
static int ndbm_id = 0;
#endif
DBTCL_INFO *ip;
DB_ENV *envp;
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:
result = bdb_DbVerify(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, &envp);
if (result == TCL_OK && envp != NULL) {
env_id++;
(void)Tcl_CreateObjCommand(interp, newname,
(Tcl_ObjCmdProc *)env_Cmd,
(ClientData)envp, NULL);
/* Use ip->i_name - newname is overwritten */
res = NewStringObj(newname, strlen(newname));
_SetInfoData(ip, envp);
} 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_SEQUENCE
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, env)
Tcl_Interp *interp; /* Interpreter */
int objc; /* How many arguments? */
Tcl_Obj *CONST objv[]; /* The argument objects */
DBTCL_INFO *ip; /* Our internal info */
DB_ENV **env; /* Environment pointer */
{
static const char *envopen[] = {
#ifdef CONFIG_TEST
"-alloc",
"-auto_commit",
"-cdb",
"-cdb_alldb",
"-client_timeout",
"-lock",
"-lock_conflict",
"-lock_detect",
"-lock_max",
"-lock_max_locks",
"-lock_max_lockers",
"-lock_max_objects",
"-lock_timeout",
"-log",
"-log_buffer",
"-log_inmemory",
"-log_max",
"-log_regionmax",
"-log_remove",
"-mpool_max_openfd",
"-mpool_max_write",
"-mpool_mmap_size",
"-mpool_nommap",
"-overwrite",
"-region_init",
"-rep_client",
"-rep_master",
"-rep_transport",
"-server",
"-server_timeout",
"-set_intermediate_dir",
"-thread",
"-time_notgranted",
"-txn_timeout",
"-txn_timestamp",
"-verbose",
"-wrnosync",
#endif
"-cachesize",
"-create",
"-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
ENV_ALLOC,
ENV_AUTO_COMMIT,
ENV_CDB,
ENV_CDB_ALLDB,
ENV_CLIENT_TO,
ENV_LOCK,
ENV_CONFLICT,
ENV_DETECT,
ENV_LOCK_MAX,
ENV_LOCK_MAX_LOCKS,
ENV_LOCK_MAX_LOCKERS,
ENV_LOCK_MAX_OBJECTS,
ENV_LOCK_TIMEOUT,
ENV_LOG,
ENV_LOG_BUFFER,
ENV_LOG_INMEMORY,
ENV_LOG_MAX,
ENV_LOG_REGIONMAX,
ENV_LOG_REMOVE,
ENV_MPOOL_MAX_OPENFD,
ENV_MPOOL_MAX_WRITE,
ENV_MPOOL_MMAP_SIZE,
ENV_MPOOL_NOMMAP,
ENV_OVERWRITE,
ENV_REGION_INIT,
ENV_REP_CLIENT,
ENV_REP_MASTER,
ENV_REP_TRANSPORT,
ENV_SERVER,
ENV_SERVER_TO,
ENV_SET_INTERMEDIATE_DIR,
ENV_THREAD,
ENV_TIME_NOTGRANTED,
ENV_TXN_TIMEOUT,
ENV_TXN_TIME,
ENV_VERBOSE,
ENV_WRNOSYNC,
#endif
ENV_CACHESIZE,
ENV_CREATE,
ENV_DATA_DIR,
ENV_ENCRYPT_AES,
ENV_ENCRYPT_ANY,
ENV_ERRFILE,
ENV_ERRPFX,
ENV_HOME,
ENV_LOG_DIR,
ENV_MODE,
ENV_PRIVATE,
ENV_RECOVER,
ENV_RECOVER_FATAL,
ENV_SHM_KEY,
ENV_SYSTEM_MEM,
ENV_TMP_DIR,
ENV_TXN,
ENV_TXN_MAX,
ENV_USE_ENVIRON,
ENV_USE_ENVIRON_ROOT
};
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;
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 = DB_JOINENV;
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 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 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 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);
ret = db_env_create(env, cr_flags);
if (ret)
return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"db_env_create"));
/*
* From here on we must 'goto error' in order to clean up the
* env from db_env_create.
*/
if (server != NULL) {
(*env)->set_errpfx((*env), ip->i_name);
(*env)->set_errcall((*env), _ErrorFunc);
if ((ret = (*env)->set_rpc_server((*env), NULL, server,
client_to, server_to, 0)) != 0) {
result = TCL_ERROR;
goto error;
}
} else {
/*
* Create the environment handle before parsing the args
* since we'll be modifying the environment as we parse.
*/
(*env)->set_errpfx((*env), ip->i_name);
(*env)->set_errcall((*env), _ErrorFunc);
}
/* Hang our info pointer on the env handle, so we can do callbacks. */
(*env)->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 ENV_SERVER:
case ENV_SERVER_TO:
case ENV_CLIENT_TO:
/*
* Already handled these, skip them and their arg.
*/
i++;
break;
case 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)(*env)->set_alloc(*env,
tcl_db_malloc, tcl_db_realloc, tcl_db_free);
break;
case ENV_AUTO_COMMIT:
FLD_SET(set_flags, DB_AUTO_COMMIT);
break;
case ENV_CDB:
FLD_SET(open_flags, DB_INIT_CDB | DB_INIT_MPOOL);
FLD_CLR(open_flags, DB_JOINENV);
break;
case ENV_CDB_ALLDB:
FLD_SET(set_flags, DB_CDB_ALLDB);
break;
case ENV_LOCK:
FLD_SET(open_flags, DB_INIT_LOCK | DB_INIT_MPOOL);
FLD_CLR(open_flags, DB_JOINENV);
break;
case 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(*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 = (*env)->set_lk_conflicts(*env,
(u_int8_t *)conflicts, nmodes);
__os_free(NULL, conflicts);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_lk_conflicts");
break;
case 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 = (*env)->set_lk_detect(*env, detect);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"lock_detect");
break;
case ENV_LOCK_MAX:
case ENV_LOCK_MAX_LOCKS:
case ENV_LOCK_MAX_LOCKERS:
case ENV_LOCK_MAX_OBJECTS:
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 ENV_LOCK_MAX:
ret = (*env)->set_lk_max(*env,
uintarg);
break;
case ENV_LOCK_MAX_LOCKS:
ret = (*env)->set_lk_max_locks(*env,
uintarg);
break;
case ENV_LOCK_MAX_LOCKERS:
ret = (*env)->set_lk_max_lockers(*env,
uintarg);
break;
case ENV_LOCK_MAX_OBJECTS:
ret = (*env)->set_lk_max_objects(*env,
uintarg);
break;
default:
break;
}
result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "lock_max");
}
break;
case ENV_TXN_TIME:
case ENV_TXN_TIMEOUT:
case ENV_LOCK_TIMEOUT:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
"?-txn_timestamp 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 == ENV_TXN_TIME)
ret =
(*env)->set_tx_timestamp(*env, &timestamp);
else
ret = (*env)->set_timeout(*env,
(db_timeout_t)timestamp,
(enum envopen)optindex == ENV_TXN_TIMEOUT ?
DB_SET_TXN_TIMEOUT : DB_SET_LOCK_TIMEOUT);
result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "txn_timestamp");
break;
case ENV_LOG:
FLD_SET(open_flags, DB_INIT_LOG | DB_INIT_MPOOL);
FLD_CLR(open_flags, DB_JOINENV);
break;
case 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 = (*env)->set_lg_bsize(*env, uintarg);
result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "log_bsize");
logbufset = 1;
if (logmaxset) {
_debug_check();
ret = (*env)->set_lg_max(*env,
logmaxset);
result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "log_max");
logmaxset = 0;
logbufset = 0;
}
}
break;
case ENV_LOG_INMEMORY:
FLD_SET(set_flags, DB_LOG_INMEMORY);
break;
case 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 = (*env)->set_lg_max(*env, uintarg);
result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "log_max");
logbufset = 0;
} else
logmaxset = uintarg;
break;
case 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 = (*env)->set_lg_regionmax(*env, uintarg);
result =
_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"log_regionmax");
}
break;
case ENV_LOG_REMOVE:
FLD_SET(set_flags, DB_LOG_AUTOREMOVE);
break;
case 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 = (*env)->set_mp_max_openfd(*env, intarg);
result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "mpool_max_openfd");
}
break;
case 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 = (*env)->set_mp_max_write(*env, intarg, intarg2);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_mp_max_write");
break;
case 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 = (*env)->set_mp_mmapsize(*env,
(size_t)intarg);
result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "mpool_mmap_size");
}
break;
case ENV_MPOOL_NOMMAP:
FLD_SET(set_flags, DB_NOMMAP);
break;
case ENV_OVERWRITE:
FLD_SET(set_flags, DB_OVERWRITE);
break;
case ENV_REGION_INIT:
_debug_check();
ret = (*env)->set_flags(*env, DB_REGION_INIT, 1);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"region_init");
break;
case ENV_SET_INTERMEDIATE_DIR:
if (i >= objc) {
Tcl_WrongNumArgs(interp,
2, objv, "?-set_intermediate_dir mode?");
result = TCL_ERROR;
break;
}
result = Tcl_GetIntFromObj(interp, objv[i++], &intarg);
if (result == TCL_OK) {
_debug_check();
ret = (*env)->
set_intermediate_dir(*env, intarg, 0);
result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "set_intermediate_dir");
}
break;
case ENV_REP_CLIENT:
rep_flags = DB_REP_CLIENT;
FLD_SET(open_flags, DB_INIT_REP);
break;
case ENV_REP_MASTER:
rep_flags = DB_REP_MASTER;
FLD_SET(open_flags, DB_INIT_REP);
break;
case ENV_REP_TRANSPORT:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
"-rep_transport {envid sendproc}");
result = TCL_ERROR;
break;
}
/*
* 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 set_rep_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.
*/
result = Tcl_ListObjGetElements(interp, objv[i++],
&myobjc, &myobjv);
if (myobjc != 2) {
Tcl_SetResult(interp,
"List must be {envid sendproc}",
TCL_STATIC);
result = TCL_ERROR;
break;
}
FLD_SET(open_flags, DB_INIT_REP);
/*
* 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.
*/
ip->i_rep_eid = myobjv[0];
Tcl_IncrRefCount(ip->i_rep_eid);
result = Tcl_GetIntFromObj(interp,
ip->i_rep_eid, &intarg);
if (result != TCL_OK)
break;
ip->i_rep_send = myobjv[1];
Tcl_IncrRefCount(ip->i_rep_send);
_debug_check();
ret = (*env)->set_rep_transport(*env,
intarg, tcl_rep_send);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_rep_transport");
break;
case ENV_THREAD:
/* Enable DB_THREAD when specified in testing. */
FLD_SET(open_flags, DB_THREAD);
break;
case ENV_TIME_NOTGRANTED:
FLD_SET(set_flags, DB_TIME_NOTGRANTED);
break;
case 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, *env,
myobjv[0], myobjv[1]);
break;
case ENV_WRNOSYNC:
FLD_SET(set_flags, DB_TXN_WRITE_NOSYNC);
break;
#endif
case ENV_TXN:
FLD_SET(open_flags, DB_INIT_LOCK |
DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN);
FLD_CLR(open_flags, DB_JOINENV);
/* Make sure we have an arg to check against! */
if (i < objc) {
arg = Tcl_GetStringFromObj(objv[i], NULL);
if (strcmp(arg, "nosync") == 0) {
FLD_SET(set_flags, DB_TXN_NOSYNC);
i++;
}
}
break;
case ENV_CREATE:
FLD_SET(open_flags, DB_CREATE | DB_INIT_MPOOL);
FLD_CLR(open_flags, DB_JOINENV);
break;
case 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 = (*env)->set_encrypt(*env, passwd, DB_ENCRYPT_AES);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_encrypt");
break;
case 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 = (*env)->set_encrypt(*env, passwd, 0);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_encrypt");
break;
case 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 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 ENV_PRIVATE:
FLD_SET(open_flags, DB_PRIVATE | DB_INIT_MPOOL);
FLD_CLR(open_flags, DB_JOINENV);
break;
case ENV_RECOVER:
FLD_SET(open_flags, DB_RECOVER);
break;
case ENV_RECOVER_FATAL:
FLD_SET(open_flags, DB_RECOVER_FATAL);
break;
case ENV_SYSTEM_MEM:
FLD_SET(open_flags, DB_SYSTEM_MEM);
break;
case ENV_USE_ENVIRON_ROOT:
FLD_SET(open_flags, DB_USE_ENVIRON_ROOT);
break;
case ENV_USE_ENVIRON:
FLD_SET(open_flags, DB_USE_ENVIRON);
break;
case 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 = (*env)->set_cachesize(*env, gbytes, bytes,
ncaches);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_cachesize");
break;
case 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 = (*env)->set_shm_key(*env, shm);
result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "shm_key");
}
break;
case 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 = (*env)->set_tx_max(*env, uintarg);
result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "txn_max");
}
break;
case 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, *env, ip, arg);
break;
case 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, *env, ip, arg);
break;
case ENV_DATA_DIR:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
"-data_dir dir");
result = TCL_ERROR;
break;
}
arg = Tcl_GetStringFromObj(objv[i++], NULL);
_debug_check();
ret = (*env)->set_data_dir(*env, arg);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_data_dir");
break;
case 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 = (*env)->set_lg_dir(*env, arg);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_lg_dir");
break;
case 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 = (*env)->set_tmp_dir(*env, 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 = (*env)->set_lg_max(*env, (u_int32_t)logmaxset);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"log_max");
}
if (result != TCL_OK)
goto error;
if (set_flags) {
ret = (*env)->set_flags(*env, 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 = (*env)->open(*env, home, open_flags, mode);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env open");
if (rep_flags != 0 && result == TCL_OK) {
_debug_check();
ret = (*env)->rep_start(*env, 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)(*env)->close(*env, 0);
*env = NULL;
}
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",
"-dirty",
"-dupcompare",
"-hashproc",
"-lorder",
"-minkey",
"-nommap",
"-notdurable",
"-revsplitoff",
"-test",
"-thread",
#endif
"-auto_commit",
"-btree",
"-cachesize",
"-chksum",
"-create",
"-delim",
"-dup",
"-dupsort",
"-encrypt",
"-encryptaes",
"-encryptany",
"-env",
"-errfile",
"-errpfx",
"-excl",
"-extent",
"-ffactor",
"-hash",
"-inorder",
"-len",
"-maxsize",
"-mode",
"-nelem",
"-pad",
"-pagesize",
"-queue",
"-rdonly",
"-recno",
"-recnum",
"-renumber",
"-snapshot",
"-source",
"-truncate",
"-txn",
"-unknown",
"--",
NULL
};
enum bdbopen {
#ifdef CONFIG_TEST
TCL_DB_BTCOMPARE,
TCL_DB_DIRTY,
TCL_DB_DUPCOMPARE,
TCL_DB_HASHPROC,
TCL_DB_LORDER,
TCL_DB_MINKEY,
TCL_DB_NOMMAP,
TCL_DB_NOTDURABLE,
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_CREATE,
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_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
};
DBTCL_INFO *envip, *errip;
DB_TXN *txn;
DBTYPE type;
DB_ENV *envp;
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;
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;
envp = NULL;
txn = 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);
envp = NAME_TO_ENV(arg);
if (envp == 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, envp, 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 when err stuff is not tied to env.
*
* The DB->set_err* functions actually overwrite in the
* environment. So, if we are explicitly using an env,
* don't overwrite what we have already set up. If we are
* not using one, then we set up since we get a private
* default env.
*/
/* XXX - remove this conditional if/when err is not tied to env */
if (envp == NULL) {
(*dbp)->set_errpfx((*dbp), ip->i_name);
(*dbp)->set_errcall((*dbp), _ErrorFunc);
}
envip = _PtrToInfo(envp); /* XXX */
/*
* If we are using an env, we keep track of err info in the env's ip.
* Otherwise use the DB's ip.
*/
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_btcompare = objv[i++];
Tcl_IncrRefCount(ip->i_btcompare);
_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_DIRTY:
open_flags |= DB_DIRTY_READ;
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_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_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_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_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_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_re_len");
}
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)->dbenv,
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 (i != objc) {
subdbtmp =
Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
if ((ret = __os_malloc(envp,
(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 (subdb)
__os_free(envp, 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(envp, errip->i_errpfx);
errip->i_errpfx = NULL;
}
*dbp = NULL;
}
return (result);
}
#ifdef HAVE_SEQUENCE
/*
* 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[] = {
"-auto_commit",
"-cachesize",
"-create",
"-inc",
"-init",
"-dec",
"-max",
"-min",
"-txn",
"-wrap",
"--",
NULL
} ;
enum seqopen {
TCL_SEQ_AUTO_COMMIT,
TCL_SEQ_CACHESIZE,
TCL_SEQ_CREATE,
TCL_SEQ_INC,
TCL_SEQ_INIT,
TCL_SEQ_DEC,
TCL_SEQ_MAX,
TCL_SEQ_MIN,
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;
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);
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_AUTO_COMMIT:
oflags |= DB_AUTO_COMMIT;
break;
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++], &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++], &max)) != TCL_OK)
goto error;
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++], &min)) != TCL_OK)
goto error;
setrange = 1;
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);
memset(&key, 0, sizeof(key));
if (type == DB_QUEUE || type == DB_RECNO) {
result = _GetUInt32(interp, objv[i++], &recno);
if (result != TCL_OK)
return (result);
key.data = &recno;
key.size = sizeof(recno);
} else {
key.data = Tcl_GetByteArrayFromObj(objv[i++], &v);
key.size = (u_int32_t)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: (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 *envp;
DB_TXN *txn;
int endarg, i, optindex, result, ret, subdblen;
u_int32_t enc_flag, iflags, set_flags;
u_char *subdbtmp;
char *arg, *db, msg[MSG_SIZE], *passwd, *subdb;
db = subdb = NULL;
dbp = NULL;
endarg = 0;
envp = NULL;
iflags = enc_flag = set_flags = 0;
passwd = NULL;
result = TCL_OK;
subdbtmp = NULL;
txn = 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);
envp = NAME_TO_ENV(arg);
if (envp == NULL) {
Tcl_SetResult(interp,
"db remove: illegal environment",
TCL_STATIC);
return (TCL_ERROR);
}
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 (i != objc) {
subdbtmp =
Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
if ((ret = __os_malloc(envp, (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 (envp == NULL) {
ret = db_create(&dbp, envp, 0);
if (ret) {
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"db_create");
goto error;
}
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 = envp->dbremove(envp, 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(envp, 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 *envp;
DB_TXN *txn;
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;
db = newname = subdb = NULL;
dbp = NULL;
endarg = 0;
envp = NULL;
iflags = enc_flag = set_flags = 0;
passwd = NULL;
result = TCL_OK;
subdbtmp = NULL;
txn = 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);
envp = NAME_TO_ENV(arg);
if (envp == NULL) {
Tcl_SetResult(interp,
"db rename: illegal environment",
TCL_STATIC);
return (TCL_ERROR);
}
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 (i == objc - 2) {
subdbtmp =
Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
if ((ret = __os_malloc(envp, (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(envp, (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 (envp == NULL) {
ret = db_create(&dbp, envp, 0);
if (ret) {
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"db_create");
goto error;
}
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 = envp->dbrename(envp, 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(envp, subdb);
if (newname)
__os_free(envp, 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)
Tcl_Interp *interp; /* Interpreter */
int objc; /* How many arguments? */
Tcl_Obj *CONST objv[]; /* The argument objects */
{
static const char *bdbverify[] = {
"-encrypt",
"-encryptaes",
"-encryptany",
"-env",
"-errfile",
"-errpfx",
"-unref",
"--",
NULL
};
enum bdbvrfy {
TCL_DBVRFY_ENCRYPT,
TCL_DBVRFY_ENCRYPT_AES,
TCL_DBVRFY_ENCRYPT_ANY,
TCL_DBVRFY_ENV,
TCL_DBVRFY_ERRFILE,
TCL_DBVRFY_ERRPFX,
TCL_DBVRFY_UNREF,
TCL_DBVRFY_ENDARG
};
DB_ENV *envp;
DB *dbp;
FILE *errf;
u_int32_t enc_flag, flags, set_flags;
int endarg, i, optindex, result, ret;
char *arg, *db, *errpfx, *passwd;
envp = NULL;
dbp = NULL;
passwd = NULL;
result = TCL_OK;
db = errpfx = NULL;
errf = 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_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);
envp = NAME_TO_ENV(arg);
if (envp == 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(envp, errpfx);
if ((ret = __os_strdup(NULL, arg, &errpfx)) != 0) {
result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "__os_strdup");
break;
}
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.
*/
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, envp, 0);
if (ret) {
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"db_create");
goto error;
}
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");
}
if (errf != NULL)
dbp->set_errfile(dbp, errf);
if (errpfx != NULL)
dbp->set_errpfx(dbp, errpfx);
/*
* The verify method is a destructor, NULL out the dbp.
*/
ret = dbp->verify(dbp, db, NULL, 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(envp, 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_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);
for (p = LIST_FIRST(&__db_infohead); p != NULL;
p = LIST_NEXT(p, 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 *rp;
Tcl_Obj *msgname;
u_int32_t len, msgtype;
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",
"dupmaster", "file", "file_fail", "file_req", "log",
"log_more", "log_req", "master_req", "newclient",
"newfile", "newmaster", "newsite", "page",
"page_fail", "page_req", "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], (void **)&rp, &len, &freerp);
if (ret != TCL_OK) {
Tcl_SetResult(interp,
"msgtype: bad control message", TCL_STATIC);
return (TCL_ERROR);
}
msgtype = rp->rectype;
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 *envp;
DB *dbp;
u_int32_t flags;
int endarg, i, optindex, result, ret;
char *arg, *db;
envp = 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);
envp = NAME_TO_ENV(arg);
if (envp == 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, envp, 0);
if (ret) {
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"db_create");
goto error;
}
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_btcompare, "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_btcompare 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_err(dbp->dbenv, "Tcl %s callback failed", errname);
DB_ASSERT(0);
return (__db_panic(dbp->dbenv, 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: /*
* We drop core on error, in diagnostic mode. See the comment in
* tcl_compare_callback.
*/
__db_err(dbp->dbenv, "Tcl h_hash callback failed");
(void)__db_panic(dbp->dbenv, DB_RUNRECOVERY);
DB_ASSERT(0);
/* NOTREACHED */
return (0);
}
/*
* tcl_rep_send --
* Replication send callback.
*/
static 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
DBTCL_INFO *ip;
Tcl_Interp *interp;
Tcl_Obj *control_o, *eid_o, *flags_o, *lsn_o, *origobj, *rec_o;
Tcl_Obj *myobjv[2], *resobj, *objv[TCLDB_SENDITEMS];
int 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);
if (LF_ISSET(DB_REP_PERMANENT))
flags_o = NewStringObj("perm", strlen("perm"));
else if (LF_ISSET(DB_REP_NOBUFFER))
flags_o = NewStringObj("nobuffer", strlen("nobuffer"));
else
flags_o = NewStringObj("none", strlen("none"));
Tcl_IncrRefCount(flags_o);
myobjc = 2;
myobjv[0] = Tcl_NewLongObj((long)lsnp->file);
myobjv[1] = Tcl_NewLongObj((long)lsnp->offset);
lsn_o = Tcl_NewListObj(myobjc, myobjv);
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_err(dbenv, "Tcl rep_send failure");
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);
Tcl_DecrRefCount(flags_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);
}
#endif